From af28aecf216bfd1a95b998f2a7180311a3d1a495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20van=20L=C3=BCck?= Date: Sun, 4 Dec 2022 22:54:27 +0100 Subject: [PATCH 1/5] Add a command to import emoji archives --- app/Console/Commands/ImportEmojis.php | 110 ++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 app/Console/Commands/ImportEmojis.php diff --git a/app/Console/Commands/ImportEmojis.php b/app/Console/Commands/ImportEmojis.php new file mode 100644 index 00000000..09f5480a --- /dev/null +++ b/app/Console/Commands/ImportEmojis.php @@ -0,0 +1,110 @@ +argument('path'); + + if (!file_exists($path) || !mime_content_type($path) == 'application/x-tar') { + $this->error('Path does not exist or is not a tarfile'); + return Command::FAILURE; + } + + $imported = 0; + $skipped = 0; + $failed = 0; + + $tar = new \PharData($path); + $tar->decompress(); + + foreach (new \RecursiveIteratorIterator($tar) as $entry) { + $this->line("Processing {$entry->getFilename()}"); + if (!$entry->isFile() || !$this->isImage($entry)) { + $failed++; + continue; + } + + $filename = pathinfo($entry->getFilename(), PATHINFO_FILENAME); + $extension = pathinfo($entry->getFilename(), PATHINFO_EXTENSION); + + // Skip macOS shadow files + if (str_starts_with($filename, '._')) { + continue; + } + + $shortcode = implode('', [ + $this->option('prefix'), + $filename, + $this->option('suffix'), + ]); + + $customEmoji = CustomEmoji::whereShortcode($shortcode)->first(); + + if ($customEmoji && !$this->option('overwrite')) { + $skipped++; + continue; + } + + $emoji = $customEmoji ?? new CustomEmoji(); + $emoji->shortcode = $shortcode; + $emoji->domain = config('pixelfed.domain.app'); + $emoji->disabled = $this->option('disabled'); + $emoji->save(); + + $fileName = $emoji->id . '.' . $extension; + Storage::putFileAs('public/emoji', $entry->getPathname(), $fileName); + $emoji->media_path = 'emoji/' . $fileName; + $emoji->save(); + $imported++; + Cache::forget('pf:custom_emoji'); + } + + $this->line("Imported: {$imported}"); + $this->line("Skipped: {$skipped}"); + $this->line("Failed: {$failed}"); + + //delete file + unlink(str_replace('.tar.gz', '.tar', $path)); + + return Command::SUCCESS; + } + + private function isImage($file) + { + $image = getimagesize($file->getPathname()); + return $image !== false; + } +} From c96bcd559df3ba8b6fae65cfee2e71d3b7184fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20van=20L=C3=BCck?= Date: Thu, 8 Dec 2022 21:10:10 +0100 Subject: [PATCH 2/5] Check imported emojis for mimetype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nils van Lück --- app/Console/Commands/ImportEmojis.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/ImportEmojis.php b/app/Console/Commands/ImportEmojis.php index 09f5480a..77a0c29a 100644 --- a/app/Console/Commands/ImportEmojis.php +++ b/app/Console/Commands/ImportEmojis.php @@ -52,7 +52,7 @@ class ImportEmojis extends Command foreach (new \RecursiveIteratorIterator($tar) as $entry) { $this->line("Processing {$entry->getFilename()}"); - if (!$entry->isFile() || !$this->isImage($entry)) { + if (!$entry->isFile() || !$this->isImage($entry) || !$this->isEmoji($entry->getPathname())) { $failed++; continue; } @@ -107,4 +107,12 @@ class ImportEmojis extends Command $image = getimagesize($file->getPathname()); return $image !== false; } + + private function isEmoji($filename) + { + $allowedMimeTypes = ['image/png', 'image/jpeg', 'image/webp']; + $mimeType = mime_content_type($filename); + + return in_array($mimeType, $allowedMimeTypes); + } } From 312bc0668518a4e653a24009c58ee3f68f93f091 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 11 Dec 2022 15:09:29 +1030 Subject: [PATCH 3/5] Update NotificationCard.vue --- resources/assets/js/components/NotificationCard.vue | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/assets/js/components/NotificationCard.vue b/resources/assets/js/components/NotificationCard.vue index b2230cbc..d0452035 100644 --- a/resources/assets/js/components/NotificationCard.vue +++ b/resources/assets/js/components/NotificationCard.vue @@ -34,7 +34,16 @@

- {{n.account.local == false ? '@':''}}{{truncate(n.account.username)}} commented on your post. + {{n.account.local == false ? '@':''}}{{truncate(n.account.username)}} commented on your + + post. + + + + + + post. +

From 031290d9873f51084387d176f1444d2b5f105d60 Mon Sep 17 00:00:00 2001 From: Shlee Date: Mon, 12 Dec 2022 00:31:34 +1030 Subject: [PATCH 4/5] Update NotificationCard.vue --- resources/assets/js/components/NotificationCard.vue | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/assets/js/components/NotificationCard.vue b/resources/assets/js/components/NotificationCard.vue index d0452035..5c6eb6da 100644 --- a/resources/assets/js/components/NotificationCard.vue +++ b/resources/assets/js/components/NotificationCard.vue @@ -73,7 +73,16 @@

- {{n.account.local == false ? '@':''}}{{truncate(n.account.username)}} shared your post. + {{n.account.local == false ? '@':''}}{{truncate(n.account.username)}} shared your + + post. + + + + + + post. +

From bca248499417963d3e859b46de88fe9ca1aba3d0 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 3 Jan 2024 04:11:29 -0700 Subject: [PATCH 5/5] Update Webfinger util, add avatar entity. Fixes #1629 --- app/Util/Webfinger/Webfinger.php | 91 +++++++++++++++++++------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/app/Util/Webfinger/Webfinger.php b/app/Util/Webfinger/Webfinger.php index 87910333..c900358e 100644 --- a/app/Util/Webfinger/Webfinger.php +++ b/app/Util/Webfinger/Webfinger.php @@ -4,43 +4,60 @@ namespace App\Util\Webfinger; class Webfinger { - protected $user; - protected $subject; - protected $aliases; - protected $links; + protected $user; + protected $subject; + protected $aliases; + protected $links; - public function __construct($user) - { - $this->subject = 'acct:'.$user->username.'@'.parse_url(config('app.url'), PHP_URL_HOST); - $this->aliases = [ - $user->url(), - $user->permalink(), - ]; - $this->links = [ - [ - 'rel' => 'http://webfinger.net/rel/profile-page', - 'type' => 'text/html', - 'href' => $user->url(), - ], - [ - 'rel' => 'http://schemas.google.com/g/2010#updates-from', - 'type' => 'application/atom+xml', - 'href' => $user->permalink('.atom'), - ], - [ - 'rel' => 'self', - 'type' => 'application/activity+json', - 'href' => $user->permalink(), - ], - ]; - } + public function __construct($user) + { + $avatar = $user ? $user->avatarUrl() : url('/storage/avatars/default.jpg'); + $avatarPath = parse_url($avatar, PHP_URL_PATH); + $extension = pathinfo($avatarPath, PATHINFO_EXTENSION); + $mimeTypes = [ + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'svg' => 'image/svg', + ]; + $avatarType = $mimeTypes[$extension] ?? 'application/octet-stream'; - public function generate() - { - return [ - 'subject' => $this->subject, - 'aliases' => $this->aliases, - 'links' => $this->links, - ]; - } + $this->subject = 'acct:'.$user->username.'@'.parse_url(config('app.url'), PHP_URL_HOST); + $this->aliases = [ + $user->url(), + $user->permalink(), + ]; + $this->links = [ + [ + 'rel' => 'http://webfinger.net/rel/profile-page', + 'type' => 'text/html', + 'href' => $user->url(), + ], + [ + 'rel' => 'http://schemas.google.com/g/2010#updates-from', + 'type' => 'application/atom+xml', + 'href' => $user->permalink('.atom'), + ], + [ + 'rel' => 'self', + 'type' => 'application/activity+json', + 'href' => $user->permalink(), + ], + [ + 'rel' => 'http://webfinger.net/rel/avatar', + 'type' => $avatarType, + 'href' => $avatar, + ], + ]; + } + + public function generate() + { + return [ + 'subject' => $this->subject, + 'aliases' => $this->aliases, + 'links' => $this->links, + ]; + } }