use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
+use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Post;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
+use Friendica\Object\Image;
use Friendica\Protocol\Activity;
use Friendica\Protocol\Relay;
use Friendica\Util\DateTimeFormat;
const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes
const BLUESKY_HOST = 'https://bsky.app'; // Hard wired until Bluesky will run on multiple systems
+const BLUESKY_IMAGE_SIZE = [1000000, 500000, 100000, 50000];
function bluesky_install()
{
if ($key == count($msg['parts']) - 1) {
$record = bluesky_add_embed($uid, $msg, $record);
+ if (empty($record)) {
+ if (Worker::getRetrial() < 3) {
+ Worker::defer();
+ }
+ return;
+ }
}
$post = [
$parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post);
if (empty($parent)) {
+ if ($part == 0) {
+ Worker::defer();
+ }
return;
}
Logger::debug('Posting done', ['return' => $parent]);
// Remove all hashtag and mention links
$body = preg_replace("/([#@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $body);
+ $body = BBCode::expandVideoLinks($body);
$urls = [];
// Search for pure links
if (($msg['type'] != 'link') && !empty($msg['images'])) {
$images = [];
foreach ($msg['images'] as $image) {
- $photo = Photo::selectFirst(['resource-id'], ['id' => $image['id']]);
- $photo = Photo::selectFirst([], ["`resource-id` = ? AND `scale` > ?", $photo['resource-id'], 0], ['order' => ['scale']]);
+ if (count($images) == 4) {
+ continue;
+ }
+ $photo = Photo::selectFirst([], ['id' => $image['id']]);
$blob = bluesky_upload_blob($uid, $photo);
- if (!empty($blob) && count($images) < 4) {
- $images[] = ['alt' => $image['description'] ?? '', 'image' => $blob];
+ if (empty($blob)) {
+ return [];
}
+ $images[] = ['alt' => $image['description'] ?? '', 'image' => $blob];
}
if (!empty($images)) {
$record['embed'] = ['$type' => 'app.bsky.embed.images', 'images' => $images];
'$type' => 'app.bsky.embed.external',
'external' => [
'uri' => $msg['url'],
- 'title' => $msg['title'],
- 'description' => $msg['description'],
+ 'title' => $msg['title'] ?? '',
+ 'description' => $msg['description'] ?? '',
]
];
if (!empty($msg['image'])) {
function bluesky_upload_blob(int $uid, array $photo): ?stdClass
{
+ $retrial = Worker::getRetrial();
$content = Photo::getImageForPhoto($photo);
+
+ $picture = new Image($content, $photo['type']);
+ $height = $picture->getHeight();
+ $width = $picture->getWidth();
+ $size = strlen($content);
+
+ $picture = Photo::resizeToFileSize($picture, BLUESKY_IMAGE_SIZE[$retrial]);
+ $new_height = $picture->getHeight();
+ $new_width = $picture->getWidth();
+ $content = $picture->asString();
+ $new_size = strlen($content);
+
+ Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
+
$data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]);
if (empty($data)) {
+ Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
return null;
}
- Logger::debug('Uploaded blob', ['return' => $data]);
+ Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
return $data->blob;
}
$data = Item::insert($item);
Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]);
} else {
- Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $$item['thr-parent'], 'uri' => $uri]);
+ Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]);
}
break;
$uri = bluesky_get_uri($embed->record);
$shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => $item['uid']]);
if (empty($shared)) {
+ if (empty($embed->record->value)) {
+ Logger::info('Record has got no value', ['record' => $embed->record]);
+ break;
+ }
$shared = bluesky_get_header($embed->record, $uri, 0, $fetch_uid);
$shared = bluesky_get_content($shared, $embed->record->value, $uri, $item['uid'], $level);
if (!empty($shared)) {
function bluesky_get_uri(stdClass $post): string
{
+ if (empty($post->cid)) {
+ Logger::info('Invalid URI', ['post' => $post, 'callstack' => System::callstack(10, 0, true)]);
+ return '';
+ }
return $post->uri . ':' . $post->cid;
}
if (++$level > 100) {
Logger::info('Recursion level too deep', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]);
// When the level is too deep we will fallback to the parent uri.
- // Allthough the threading won't be correct, we at least had stored all posts and won't try again
+ // Allthough the threading won't be correct, we at least had stored all posts and won't try again
return $fallback;
}
Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]);
return $fallback;
}
-
- Logger::debug('Reply count', ['replies' => $data->thread->post->replyCount, 'level' => $level, 'uid' => $uid, 'uri' => $uri]);
+
+ Logger::debug('Reply count', ['replies' => $data->thread->post->replyCount, 'level' => $level, 'uid' => $uid, 'uri' => $uri]);
if ($causer != 0) {
$cdata = Contact::getPublicAndUserContactID($causer, $uid);
}
return json_decode($curlResult->getBody());
-}
\ No newline at end of file
+}