Adding and removing of pictures via API is now possible

This commit is contained in:
Michael 2023-02-28 06:19:19 +00:00
父節點 a56d2f2eb8
當前提交 98aed4dde3
共有 3 個文件被更改,包括 101 次插入37 次删除

查看文件

@ -41,7 +41,7 @@ class StatusSource extends BaseFactory
$post = Post::selectFirst(['uri-id', 'raw-body', 'body', 'title'], ['uri-id' => $uriId, 'uid' => [0, $uid]]);
$spoiler_text = $post['title'] ?: BBCode::toPlaintext(BBCode::getAbstract($post['body'], Protocol::ACTIVITYPUB));
$body = BBCode::toMarkdown($post['body']);
$body = BBCode::toMarkdown(Post\Media::removeFromEndOfBody($post['body']));
return new \Friendica\Object\Api\Mastodon\StatusSource($post['uri-id'], $body, $spoiler_text);
}

查看文件

@ -721,7 +721,7 @@ class Media
*
* @param int $uri_id URI id
* @param array $types Media types
* @return bool Whether media attachment exists
* @return bool result of deletion
* @throws \Exception
*/
public static function deleteByURIId(int $uri_id, array $types = []): bool
@ -735,6 +735,18 @@ class Media
return DBA::delete('post-media', $condition);
}
/**
* Delete media by id
*
* @param int $id media id
* @return bool result of deletion
* @throws \Exception
*/
public static function deleteById(int $id): bool
{
return DBA::delete('post-media', ['id' => $id]);
}
/**
* Split the attachment media in the three segments "visual", "link" and "additional"
*

查看文件

@ -50,6 +50,7 @@ class Statuses extends BaseApi
$request = $this->getRequest([
'status' => '', // Text content of the status. If media_ids is provided, this becomes optional. Attaching a poll is optional while status is provided.
'media_ids' => [], // Array of Attachment ids to be attached as media. If provided, status becomes optional, and poll cannot be used.
'in_reply_to_id' => 0, // ID of the status being replied to, if status is a reply
'spoiler_text' => '', // Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field.
'language' => '', // ISO 639 language code for this status.
@ -65,7 +66,7 @@ class Statuses extends BaseApi
'origin' => true,
];
$post = Post::selectFirst(['uri-id', 'id'], $condition);
$post = Post::selectFirst(['uri-id', 'id', 'uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid'], $condition);
if (empty($post['id'])) {
throw new HTTPException\NotFoundException('Item with URI ID ' . $this->parameters['id'] . ' not found for user ' . $uid . '.');
}
@ -85,6 +86,44 @@ class Statuses extends BaseApi
}
}
if (!empty($request['media_ids'])) {
/*
The provided ids in the request value consists of these two sources:
- The id in the "photo" table for newly uploaded media
- The id in the "post-media" table for already attached media
Because of this we have to add all media that isn't already attached.
Also we have to delete all media that isn't provided anymore.
There is a possible situation where the newly uploaded media
could have the same id as an existing, but deleted media.
We can't do anything about this, but the probability for this is extremely low.
*/
$media_ids = [];
$existing_media = array_column(Post\Media::getByURIId($post['uri-id'], [Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::IMAGE]), 'id');
foreach ($request['media_ids'] as $media) {
if (!in_array($media, $existing_media)) {
$media_ids[] = $media;
}
}
foreach ($existing_media as $media) {
if (!in_array($media, $request['media_ids'])) {
Post\Media::deleteById($media);
}
}
$item = $this->storeMediaIds($media_ids, array_merge($post, $item));
foreach ($item['attachments'] as $attachment) {
$attachment['uri-id'] = $post['uri-id'];
Post\Media::insert($attachment);
}
unset($item['attachments']);
}
Item::update($item, ['id' => $post['id']]);
Item::updateDisplayCache($post['uri-id']);
@ -222,40 +261,7 @@ class Statuses extends BaseApi
$item = DI::contentItem()->expandTags($item, $request['visibility'] == 'direct');
if (!empty($request['media_ids'])) {
$item['object-type'] = Activity\ObjectType::IMAGE;
$item['post-type'] = Item::PT_IMAGE;
$item['attachments'] = [];
foreach ($request['media_ids'] as $id) {
$media = DBA::toArray(DBA::p("SELECT `resource-id`, `scale`, `type`, `desc`, `filename`, `datasize`, `width`, `height` FROM `photo`
WHERE `resource-id` IN (SELECT `resource-id` FROM `photo` WHERE `id` = ?) AND `photo`.`uid` = ?
ORDER BY `photo`.`width` DESC LIMIT 2", $id, $uid));
if (empty($media)) {
continue;
}
Photo::setPermissionForRessource($media[0]['resource-id'], $uid, $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
$ressources[] = $media[0]['resource-id'];
$phototypes = Images::supportedTypes();
$ext = $phototypes[$media[0]['type']];
$attachment = ['type' => Post\Media::IMAGE, 'mimetype' => $media[0]['type'],
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
'size' => $media[0]['datasize'],
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
'description' => $media[0]['desc'] ?? '',
'width' => $media[0]['width'],
'height' => $media[0]['height']];
if (count($media) > 1) {
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
$attachment['preview-width'] = $media[1]['width'];
$attachment['preview-height'] = $media[1]['height'];
}
$item['attachments'][] = $attachment;
}
$item = $this->storeMediaIds($request['media_ids'], $item);
}
if (!empty($request['scheduled_at'])) {
@ -322,4 +328,50 @@ class Statuses extends BaseApi
return 'API';
}
}
/**
* Store provided media ids in the item array and adjust permissions
*
* @param array $media_ids
* @param array $item
* @return array
*/
private function storeMediaIds(array $media_ids, array $item): array
{
$item['object-type'] = Activity\ObjectType::IMAGE;
$item['post-type'] = Item::PT_IMAGE;
$item['attachments'] = [];
foreach ($media_ids as $id) {
$media = DBA::toArray(DBA::p("SELECT `resource-id`, `scale`, `type`, `desc`, `filename`, `datasize`, `width`, `height` FROM `photo`
WHERE `resource-id` IN (SELECT `resource-id` FROM `photo` WHERE `id` = ?) AND `photo`.`uid` = ?
ORDER BY `photo`.`width` DESC LIMIT 2", $id, $item['uid']));
if (empty($media)) {
continue;
}
Photo::setPermissionForRessource($media[0]['resource-id'], $item['uid'], $item['allow_cid'], $item['allow_gid'], $item['deny_cid'], $item['deny_gid']);
$ressources[] = $media[0]['resource-id'];
$phototypes = Images::supportedTypes();
$ext = $phototypes[$media[0]['type']];
$attachment = ['type' => Post\Media::IMAGE, 'mimetype' => $media[0]['type'],
'url' => DI::baseUrl() . '/photo/' . $media[0]['resource-id'] . '-' . $media[0]['scale'] . '.' . $ext,
'size' => $media[0]['datasize'],
'name' => $media[0]['filename'] ?: $media[0]['resource-id'],
'description' => $media[0]['desc'] ?? '',
'width' => $media[0]['width'],
'height' => $media[0]['height']];
if (count($media) > 1) {
$attachment['preview'] = DI::baseUrl() . '/photo/' . $media[1]['resource-id'] . '-' . $media[1]['scale'] . '.' . $ext;
$attachment['preview-width'] = $media[1]['width'];
$attachment['preview-height'] = $media[1]['height'];
}
$item['attachments'][] = $attachment;
}
return $item;
}
}