From 1c6e9155145edbaa56b9fc26d3539cc0f1b6c9e8 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 9 May 2021 12:59:23 +0000
Subject: [PATCH] Media is now supported as well

---
 doc/API-Mastodon.md                     |  1 +
 src/Factory/Api/Mastodon/Attachment.php | 35 ++++++++++++++
 src/Module/Api/Mastodon/Media.php       | 62 +++++++++++++++++++++++++
 static/routes.config.php                |  8 ++--
 4 files changed, 102 insertions(+), 4 deletions(-)
 create mode 100644 src/Module/Api/Mastodon/Media.php

diff --git a/doc/API-Mastodon.md b/doc/API-Mastodon.md
index 2efa9a9ffa..7f5b55797a 100644
--- a/doc/API-Mastodon.md
+++ b/doc/API-Mastodon.md
@@ -47,6 +47,7 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
 - [`GET /api/v1/lists`](https://docs.joinmastodon.org/methods/timelines/lists/)
 - [`GET /api/v1/lists/:id`](https://docs.joinmastodon.org/methods/timelines/lists/)
 - [`GET /api/v1/lists/:id/accounts`](https://docs.joinmastodon.org/methods/timelines/lists/)
+- [`GET /api/v1/media/:id`](https://docs.joinmastodon.org/methods/statuses/media/)
 - [`GET /api/v1/mutes`](https://docs.joinmastodon.org/methods/accounts/mutes/)
 - [`GET /api/v1/notifications`](https://docs.joinmastodon.org/methods/notifications/)
 - [`GET /api/v1/notifications/:id`](https://docs.joinmastodon.org/methods/notifications/)
diff --git a/src/Factory/Api/Mastodon/Attachment.php b/src/Factory/Api/Mastodon/Attachment.php
index 893b4c9f95..7ac45f354e 100644
--- a/src/Factory/Api/Mastodon/Attachment.php
+++ b/src/Factory/Api/Mastodon/Attachment.php
@@ -23,9 +23,12 @@ namespace Friendica\Factory\Api\Mastodon;
 
 use Friendica\App\BaseURL;
 use Friendica\BaseFactory;
+use Friendica\DI;
+use Friendica\Model\Photo;
 use Friendica\Network\HTTPException;
 use Friendica\Model\Post;
 use Friendica\Repository\ProfileField;
+use Friendica\Util\Images;
 use Friendica\Util\Proxy;
 use Psr\Log\LoggerInterface;
 
@@ -93,4 +96,36 @@ class Attachment extends BaseFactory
 
 		return $attachments;
 	}
+
+	/**
+	 * @param int $id id of the photo
+	 * @return array
+	 * @throws HTTPException\InternalServerErrorException
+	 * @throws \ImagickException
+	 */
+	public function createFromPhoto(int $id)
+	{
+		$photo = Photo::selectFirst(['resource-id', 'uid', 'id', 'title', 'type'], ['id' => $id]);
+		if (empty($photo)) {
+			return null;
+		}
+
+		$attachment = ['id' => $photo['id'], 'description' => $photo['title']];
+
+		$phototypes = Images::supportedTypes();
+		$ext = $phototypes[$photo['type']];
+
+		$url = DI::baseUrl() . '/photo/' . $photo['resource-id'] . '-0.' . $ext;
+
+		$preview = Photo::selectFirst(['scale'], ["`resource-id` = ? AND `uid` = ? AND `scale` > ?", $photo['resource-id'], $photo['uid'], 0], ['order' => ['scale']]);
+		if (empty($scale)) {
+			$preview_url = DI::baseUrl() . '/photo/' . $photo['resource-id'] . '-' . $preview['scale'] . '.' . $ext;
+		} else {
+			$preview_url = '';
+		}
+
+
+		$object = new \Friendica\Object\Api\Mastodon\Attachment($attachment, 'image', $url, $preview_url, '');
+		return $object->toArray();
+	}
 }
diff --git a/src/Module/Api/Mastodon/Media.php b/src/Module/Api/Mastodon/Media.php
new file mode 100644
index 0000000000..c5fb82a248
--- /dev/null
+++ b/src/Module/Api/Mastodon/Media.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\Api\Mastodon;
+
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Notification;
+use Friendica\Model\Photo;
+use Friendica\Module\BaseApi;
+
+/**
+ * @see https://docs.joinmastodon.org/methods/statuses/media/
+ */
+class Media extends BaseApi
+{
+	public static function put(array $parameters = [])
+	{
+		self::unsupported('put');
+	}
+
+	/**
+	 * @param array $parameters
+	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+	 */
+	public static function rawContent(array $parameters = [])
+	{
+		self::login();
+		$uid = self::getCurrentUserID();
+
+		if (empty($parameters['id'])) {
+			DI::mstdnError()->RecordNotFound();
+		}
+
+		$id = $parameters['id'];
+		if (!Photo::exists(['id' => $id, 'uid' => $uid])) {
+			DI::mstdnError()->RecordNotFound();
+		}
+
+		System::jsonExit(DI::mstdnAttachment()->createFromPhoto($id));
+	}
+}
diff --git a/static/routes.config.php b/static/routes.config.php
index e00a7f0e34..a21ff336da 100644
--- a/static/routes.config.php
+++ b/static/routes.config.php
@@ -90,9 +90,9 @@ return [
 			'/apps/verify_credentials'           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]],
 			'/blocks'                            => [Module\Api\Mastodon\Blocks::class,                   [R::GET         ]],
 			'/bookmarks'                         => [Module\Api\Mastodon\Bookmarks::class,                [R::GET         ]],
-			'/conversations'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // @todo
-			'/conversations/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]],
-			'/conversations/{id:\d+}/read'       => [Module\Api\Mastodon\Unimplemented::class,            [R::POST        ]],
+			'/conversations'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET         ]], // not implemented
+			'/conversations/{id:\d+}'            => [Module\Api\Mastodon\Unimplemented::class,            [R::DELETE      ]], // not implemented
+			'/conversations/{id:\d+}/read'       => [Module\Api\Mastodon\Unimplemented::class,            [R::POST        ]], // not implemented
 			'/custom_emojis'                     => [Module\Api\Mastodon\CustomEmojis::class,             [R::GET         ]],
 			'/domain_blocks'                     => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST, R::DELETE]], // not implemented
 			'/directory'                         => [Module\Api\Mastodon\Directory::class,                [R::GET         ]],
@@ -113,7 +113,7 @@ return [
 			'/lists/{id:\d+}/accounts'           => [Module\Api\Mastodon\Lists\Accounts::class,           [R::GET, R::POST, R::DELETE]],
 			'/markers'                           => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::POST]], // not implemented
 			'/media'                             => [Module\Api\Mastodon\Unimplemented::class,            [        R::POST]],
-			'/media/{id:\d+}'                    => [Module\Api\Mastodon\Unimplemented::class,            [R::GET, R::PUT]], // @todo
+			'/media/{id:\d+}'                    => [Module\Api\Mastodon\Media::class,                    [R::GET, R::PUT]],
 			'/mutes'                             => [Module\Api\Mastodon\Mutes::class,                    [R::GET         ]],
 			'/notifications'                     => [Module\Api\Mastodon\Notifications::class,            [R::GET         ]],
 			'/notifications/{id:\d+}'            => [Module\Api\Mastodon\Notifications::class,            [R::GET         ]],
-- 
2.39.5