Merge branch 'staging' of github.com:pixelfed/pixelfed into jippi-fork

This commit is contained in:
Christian Winther 2024-03-07 19:43:30 +00:00
commit 091de696c2
11 changed files with 518 additions and 491 deletions

View file

@ -5,6 +5,11 @@
### Updates
- Update SoftwareUpdateService, add command to refresh latest versions ([632f2cb6](https://github.com/pixelfed/pixelfed/commit/632f2cb6))
- Update Post.vue, fix cache bug ([3a27e637](https://github.com/pixelfed/pixelfed/commit/3a27e637))
- Update StatusHashtagService, use more efficient cached count ([592c8412](https://github.com/pixelfed/pixelfed/commit/592c8412))
- Update DiscoverController, handle discover hashtag redirects ([18382e8a](https://github.com/pixelfed/pixelfed/commit/18382e8a))
- Update ApiV1Controller, use admin filter service ([94503a1c](https://github.com/pixelfed/pixelfed/commit/94503a1c))
- Update SearchApiV2Service, use more efficient query ([cee618e8](https://github.com/pixelfed/pixelfed/commit/cee618e8))
- ([](https://github.com/pixelfed/pixelfed/commit/))
## [v0.11.13 (2024-03-05)](https://github.com/pixelfed/pixelfed/compare/v0.11.12...v0.11.13)

View file

@ -37,6 +37,7 @@ use App\Models\Conversation;
use App\Notification;
use App\Profile;
use App\Services\AccountService;
use App\Services\AdminShadowFilterService;
use App\Services\BookmarkService;
use App\Services\BouncerService;
use App\Services\CollectionService;
@ -2648,7 +2649,7 @@ class ApiV1Controller extends Controller
$domainBlocks = UserFilterService::domainBlocks($user->profile_id);
$hideNsfw = config('instance.hide_nsfw_on_public_feeds');
$amin = SnowflakeService::byDate(now()->subDays(config('federation.network_timeline_days_falloff')));
$asf = AdminShadowFilterService::getHideFromPublicFeedsList();
if ($local && $remote) {
$feed = Status::select(
'id',
@ -2824,6 +2825,21 @@ class ApiV1Controller extends Controller
return ! in_array($domain, $domainBlocks);
})
->filter(function ($s) use ($asf, $user) {
if (! $asf || count($asf) === 0) {
return true;
}
if (in_array($s['account']['id'], $asf)) {
if ($user->profile_id == $s['account']['id']) {
return true;
}
return false;
}
return true;
})
->take($limit)
->values();

View file

@ -2,48 +2,47 @@
namespace App\Http\Controllers;
use App\{
DiscoverCategory,
Follower,
Hashtag,
HashtagFollow,
Instance,
Like,
Profile,
Status,
StatusHashtag,
UserFilter
};
use Auth, DB, Cache;
use Illuminate\Http\Request;
use App\Hashtag;
use App\Instance;
use App\Like;
use App\Services\BookmarkService;
use App\Services\ConfigCacheService;
use App\Services\HashtagService;
use App\Services\LikeService;
use App\Services\ReblogService;
use App\Services\StatusHashtagService;
use App\Services\SnowflakeService;
use App\Services\StatusHashtagService;
use App\Services\StatusService;
use App\Services\TrendingHashtagService;
use App\Services\UserFilterService;
use App\Status;
use Auth;
use Cache;
use DB;
use Illuminate\Http\Request;
class DiscoverController extends Controller
{
public function home(Request $request)
{
abort_if(! Auth::check() && config('instance.discover.public') == false, 403);
return view('discover.home');
}
public function showTags(Request $request, $hashtag)
{
if ($request->user()) {
return redirect('/i/web/hashtag/'.$hashtag.'?src=pd');
}
abort_if(! config('instance.discover.tags.is_public') && ! Auth::check(), 403);
$tag = Hashtag::whereName($hashtag)
->orWhere('slug', $hashtag)
->where('is_banned', '!=', true)
->firstOrFail();
$tagCount = StatusHashtagService::count($tag->id);
$tagCount = $tag->cached_count ?? 0;
return view('discover.tags.show', compact('tag', 'tagCount'));
}
@ -54,7 +53,7 @@ class DiscoverController extends Controller
$this->validate($request, [
'hashtag' => 'required|string|min:1|max:124',
'page' => 'nullable|integer|min:1|max:' . ($user ? 29 : 3)
'page' => 'nullable|integer|min:1|max:'.($user ? 29 : 3),
]);
$page = $request->input('page') ?? '1';
@ -75,7 +74,7 @@ class DiscoverController extends Controller
}
$res['hashtag'] = [
'name' => $hashtag->name,
'url' => $hashtag->url()
'url' => $hashtag->url(),
];
if ($user) {
$tags = StatusHashtagService::get($hashtag->id, $page, $end);
@ -84,18 +83,21 @@ class DiscoverController extends Controller
$tag['status']['favourited'] = (bool) LikeService::liked($user->profile_id, $tag['status']['id']);
$tag['status']['reblogged'] = (bool) ReblogService::get($user->profile_id, $tag['status']['id']);
$tag['status']['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $tag['status']['id']);
return $tag;
})
->filter(function ($tag) {
if (! StatusService::get($tag['status']['id'])) {
return false;
}
return true;
})
->values();
} else {
if ($page != 1) {
$res['tags'] = [];
return $res;
}
$key = 'discover:tags:public_feed:'.$hashtag->id.':page:'.$page;
@ -105,6 +107,7 @@ class DiscoverController extends Controller
if (! $tag['status']['local']) {
return false;
}
return true;
})
->values();
@ -114,10 +117,12 @@ class DiscoverController extends Controller
if (! StatusService::get($tag['status']['id'])) {
return false;
}
return true;
})
->values();
}
return $res;
}
@ -144,12 +149,13 @@ class DiscoverController extends Controller
$ttls = [
1 => 1500,
31 => 14400,
365 => 86400
365 => 86400,
];
$key = ':api:discover:trending:v2.12:range:'.$days;
$ids = Cache::remember($key, $ttls[$days], function () use ($days) {
$min_id = SnowflakeService::byDate(now()->subDays($days));
return DB::table('statuses')
->select(
'id',
@ -165,7 +171,7 @@ class DiscoverController extends Controller
->whereIn('type', [
'photo',
'photo:album',
'video'
'video',
])
->whereIsNsfw(false)
->orderBy('likes_count', 'desc')
@ -192,6 +198,7 @@ class DiscoverController extends Controller
abort_if(! $request->user(), 403);
$res = TrendingHashtagService::getTrending();
return $res;
}
@ -236,6 +243,7 @@ class DiscoverController extends Controller
->map(function ($id) {
$status = StatusService::get($id, false);
$status['favourited'] = true;
return $status;
})
->filter(function ($post) {
@ -277,6 +285,7 @@ class DiscoverController extends Controller
if ($cc) {
return is_string($cc) ? json_decode($cc, true) : $cc;
}
return [
'hashtags' => [
'enabled' => false,
@ -293,8 +302,8 @@ class DiscoverController extends Controller
'server' => [
'enabled' => false,
'mode' => 'allowlist',
'domains' => []
]
'domains' => [],
],
];
}
@ -321,12 +330,14 @@ class DiscoverController extends Controller
return $post && isset($post['account']);
})
->values();
return $res;
}
public function enabledFeatures(Request $request)
{
abort_if(! $request->user(), 404);
return $this->config();
}
@ -355,6 +366,7 @@ class DiscoverController extends Controller
if (! Instance::whereDomain($domain)->exists()) {
return false;
}
return true;
});
$parts = array_slice($parts, 0, 10);
@ -362,6 +374,7 @@ class DiscoverController extends Controller
$res['server']['domains'] = $d;
}
ConfigCacheService::put('config.discover.features', json_encode($res));
return $res;
}
}

View file

@ -2,28 +2,26 @@
namespace App\Services;
use Cache;
use Illuminate\Support\Facades\Redis;
use App\{Hashtag, Profile, Status};
use App\Hashtag;
use App\Profile;
use App\Status;
use App\Transformer\Api\AccountTransformer;
use App\Transformer\Api\StatusTransformer;
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Util\ActivityPub\Helpers;
use Illuminate\Support\Str;
use App\Services\AccountService;
use App\Services\HashtagService;
use App\Services\StatusService;
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
class SearchApiV2Service
{
private $query;
static $mastodonMode = false;
public static $mastodonMode = false;
public static function query($query, $mastodonMode = false)
{
self::$mastodonMode = $mastodonMode;
return (new self)->run($query);
}
@ -45,21 +43,21 @@ class SearchApiV2Service
return [
'accounts' => $this->accounts(),
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
break;
case 'hashtags':
return [
'accounts' => [],
'hashtags' => $this->hashtags(),
'statuses' => []
'statuses' => [],
];
break;
case 'statuses':
return [
'accounts' => [],
'hashtags' => [],
'statuses' => $this->statuses()
'statuses' => $this->statuses(),
];
break;
}
@ -69,14 +67,14 @@ class SearchApiV2Service
return [
'accounts' => [],
'hashtags' => [],
'statuses' => $this->statusesById()
'statuses' => $this->statusesById(),
];
}
return [
'accounts' => $this->accounts(),
'hashtags' => $this->hashtags(),
'statuses' => $this->statuses()
'statuses' => $this->statuses(),
];
}
@ -134,31 +132,31 @@ class SearchApiV2Service
$q = $this->query->input('q');
$limit = $this->query->input('limit') ?? 20;
$offset = $this->query->input('offset') ?? 0;
$query = Str::startsWith($q, '#') ? '%' . substr($q, 1) . '%' : '%' . $q . '%';
$query = Str::startsWith($q, '#') ? substr($q, 1).'%' : $q;
$operator = config('database.default') === 'pgsql' ? 'ilike' : 'like';
return Hashtag::where('name', $operator, $query)
->orWhere('slug', $operator, $query)
->where(function($q) {
return $q->where('can_search', true)
->orWhereNull('can_search');
})
->orderByDesc('cached_count')
->offset($offset)
->limit($limit)
->get()
->filter(function ($tag) {
return $tag->can_search != false;
})
->map(function ($tag) use ($mastodonMode) {
$res = [
'name' => $tag->name,
'url' => $tag->url()
'url' => $tag->url(),
];
if (! $mastodonMode) {
$res['history'] = [];
$res['count'] = HashtagService::count($tag->id);
$res['count'] = $tag->cached_count ?? 0;
}
return $res;
});
})
->values();
}
protected function statuses()
@ -194,6 +192,7 @@ class SearchApiV2Service
}
if (substr($query, 0, 1) === '@' && ! Str::contains($query, '.')) {
$default['accounts'] = $this->accounts(substr($query, 1));
return $default;
}
if (Helpers::validateLocalUrl($query)) {
@ -221,6 +220,7 @@ class SearchApiV2Service
return $default;
}
$default['accounts'][] = $res;
return $default;
} else {
return $default;
@ -239,6 +239,7 @@ class SearchApiV2Service
return $default;
}
$default['accounts'][] = $res;
return $default;
} else {
return $default;
@ -252,6 +253,7 @@ class SearchApiV2Service
}
if (in_array($s['visibility'], ['public', 'unlisted'])) {
$default['statuses'][] = $s;
return $default;
}
}
@ -286,6 +288,7 @@ class SearchApiV2Service
return $default;
}
$default['statuses'][] = $note;
return $default;
break;
@ -300,6 +303,7 @@ class SearchApiV2Service
$default['accounts'][] = $mastodonMode ?
AccountService::getMastodon($obj['id'], true) :
AccountService::get($obj['id'], true);
return $default;
break;
@ -333,14 +337,14 @@ class SearchApiV2Service
return [
'accounts' => [],
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
}
$res = [
'accounts' => [],
'hashtags' => [],
'statuses' => [$status]
'statuses' => [$status],
];
return $res;
@ -359,17 +363,18 @@ class SearchApiV2Service
return [
'accounts' => [],
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
}
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
return [
'accounts' => [$fractal->createData($resource)->toArray()],
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
}
@ -384,18 +389,18 @@ class SearchApiV2Service
return [
'accounts' => [],
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
}
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
return [
'accounts' => [$fractal->createData($resource)->toArray()],
'hashtags' => [],
'statuses' => []
'statuses' => [],
];
}
}

View file

@ -2,17 +2,15 @@
namespace App\Services;
use Cache;
use Illuminate\Support\Facades\Redis;
use App\{Status, StatusHashtag};
use App\Transformer\Api\StatusHashtagTransformer;
use App\Hashtag;
use App\Status;
use App\StatusHashtag;
use App\Transformer\Api\HashtagTransformer;
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
class StatusHashtagService {
class StatusHashtagService
{
const CACHE_KEY = 'pf:services:status-hashtag:collection:';
public static function get($id, $page = 1, $stop = 9)
@ -55,6 +53,7 @@ class StatusHashtagService {
foreach ($ids as $key) {
self::set($id, $key);
}
return $ids;
}
@ -70,11 +69,12 @@ class StatusHashtagService {
public static function count($id)
{
$key = 'pf:services:status-hashtag:count:' . $id;
$ttl = now()->addMinutes(5);
return Cache::remember($key, $ttl, function() use($id) {
return StatusHashtag::whereHashtagId($id)->has('media')->count();
});
$cc = Hashtag::find($id);
if (! $cc) {
return 0;
}
return $cc->cached_count ?? 0;
}
public static function getStatus($statusId, $hashtagId)
@ -92,6 +92,7 @@ class StatusHashtagService {
$fractal = new Fractal\Manager();
$fractal->setSerializer(new ArraySerializer());
$resource = new Fractal\Resource\Collection($status->hashtags, new HashtagTransformer());
return $fractal->createData($resource)->toArray();
}
}

BIN
public/js/manifest.js vendored

Binary file not shown.

Binary file not shown.

BIN
public/js/post.chunk.9184101a2b809af1.js vendored Normal file

Binary file not shown.

Binary file not shown.

View file

@ -171,7 +171,7 @@
}
},
beforeMount() {
created() {
this.init();
},
@ -181,20 +181,7 @@
methods: {
init() {
if(this.cachedStatus && this.cachedProfile) {
this.post = this.cachedStatus;
this.media = this.post.media_attachments;
this.profile = this.post.account;
this.user = this.cachedProfile;
if(this.post.in_reply_to_id) {
this.fetchReply();
} else {
this.isReply = false;
this.fetchRelationship();
}
} else {
this.fetchSelf();
}
},
fetchSelf() {