mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 14:31:26 +00:00
Merge branch 'staging' of github.com:mbliznikova/pixelfed into staging
This commit is contained in:
commit
3425821b55
23 changed files with 41 additions and 18 deletions
|
@ -40,6 +40,9 @@
|
||||||
- Update ApiV1Dot1Controller, allow iar rate limits to be configurable ([28a80803](https://github.com/pixelfed/pixelfed/commit/28a80803))
|
- Update ApiV1Dot1Controller, allow iar rate limits to be configurable ([28a80803](https://github.com/pixelfed/pixelfed/commit/28a80803))
|
||||||
- Update ApiV1Dot1Controller, add domain to iar redirect ([1f82d47c](https://github.com/pixelfed/pixelfed/commit/1f82d47c))
|
- Update ApiV1Dot1Controller, add domain to iar redirect ([1f82d47c](https://github.com/pixelfed/pixelfed/commit/1f82d47c))
|
||||||
- Update ApiV1Dot1Controller, add configurable app confirm rate limit ttl ([4c6a0719](https://github.com/pixelfed/pixelfed/commit/4c6a0719))
|
- Update ApiV1Dot1Controller, add configurable app confirm rate limit ttl ([4c6a0719](https://github.com/pixelfed/pixelfed/commit/4c6a0719))
|
||||||
|
- Update LikePipeline, dispatch to feed queue. Fixes ([#4723](https://github.com/pixelfed/pixelfed/issues/4723)) ([da510089](https://github.com/pixelfed/pixelfed/commit/da510089))
|
||||||
|
- Update AccountImport ([5a2d7e3e](https://github.com/pixelfed/pixelfed/commit/5a2d7e3e))
|
||||||
|
- Update ImportPostController, fix IG bug with missing spaces between hashtags ([9c24157a](https://github.com/pixelfed/pixelfed/commit/9c24157a))
|
||||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||||
|
|
||||||
## [v0.11.9 (2023-08-21)](https://github.com/pixelfed/pixelfed/compare/v0.11.8...v0.11.9)
|
## [v0.11.9 (2023-08-21)](https://github.com/pixelfed/pixelfed/compare/v0.11.8...v0.11.9)
|
||||||
|
|
|
@ -83,6 +83,17 @@ class ImportPostController extends Controller
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function formatHashtags($val = false)
|
||||||
|
{
|
||||||
|
if(!$val || !strlen($val)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedHashtagRegex = '/#\w+(?=#)/';
|
||||||
|
|
||||||
|
return preg_replace($groupedHashtagRegex, '$0 ', $val);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
abort_unless(config('import.instagram.enabled'), 404);
|
abort_unless(config('import.instagram.enabled'), 404);
|
||||||
|
@ -128,11 +139,11 @@ class ImportPostController extends Controller
|
||||||
$ip->media = $c->map(function($m) {
|
$ip->media = $c->map(function($m) {
|
||||||
return [
|
return [
|
||||||
'uri' => $m['uri'],
|
'uri' => $m['uri'],
|
||||||
'title' => $m['title'],
|
'title' => $this->formatHashtags($m['title']),
|
||||||
'creation_timestamp' => $m['creation_timestamp']
|
'creation_timestamp' => $m['creation_timestamp']
|
||||||
];
|
];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
$ip->caption = $c->count() > 1 ? $file['title'] : $ip->media[0]['title'];
|
$ip->caption = $c->count() > 1 ? $this->formatHashtags($file['title']) : $this->formatHashtags($ip->media[0]['title']);
|
||||||
$ip->filename = last(explode('/', $ip->media[0]['uri']));
|
$ip->filename = last(explode('/', $ip->media[0]['uri']));
|
||||||
$ip->metadata = $c->map(function($m) {
|
$ip->metadata = $c->map(function($m) {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -193,7 +193,7 @@ class InboxValidator implements ShouldQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = Http::timeout(20)->withHeaders([
|
$res = Http::withOptions(['allow_redirects' => false])->timeout(20)->withHeaders([
|
||||||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||||
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
|
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
|
||||||
])->get($actor->remote_url);
|
])->get($actor->remote_url);
|
||||||
|
|
|
@ -173,7 +173,7 @@ class InboxWorker implements ShouldQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = Http::timeout(20)->withHeaders([
|
$res = Http::withOptions(['allow_redirects' => false])->timeout(20)->withHeaders([
|
||||||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||||
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
|
'User-Agent' => 'PixelfedBot v0.1 - https://pixelfed.org',
|
||||||
])->get($actor->remote_url);
|
])->get($actor->remote_url);
|
||||||
|
|
|
@ -90,7 +90,7 @@ class StatusRemoteUpdatePipeline implements ShouldQueue
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$nm->each(function($n, $key) use($status) {
|
$nm->each(function($n, $key) use($status) {
|
||||||
$res = Http::retry(3, 100, throw: false)->head($n['url']);
|
$res = Http::withOptions(['allow_redirects' => false])->retry(3, 100, throw: false)->head($n['url']);
|
||||||
|
|
||||||
if(!$res->successful()) {
|
if(!$res->successful()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ActivityPubFetchService
|
||||||
$headers['User-Agent'] = 'PixelFedBot/1.0.0 (Pixelfed/'.config('pixelfed.version').'; +'.config('app.url').')';
|
$headers['User-Agent'] = 'PixelFedBot/1.0.0 (Pixelfed/'.config('pixelfed.version').'; +'.config('app.url').')';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = Http::withHeaders($headers)
|
$res = Http::withOptions(['allow_redirects' => false])->withHeaders($headers)
|
||||||
->timeout(30)
|
->timeout(30)
|
||||||
->connectTimeout(5)
|
->connectTimeout(5)
|
||||||
->retry(3, 500)
|
->retry(3, 500)
|
||||||
|
|
BIN
public/js/account-import.js
vendored
BIN
public/js/account-import.js
vendored
Binary file not shown.
BIN
public/js/collections.js
vendored
BIN
public/js/collections.js
vendored
Binary file not shown.
BIN
public/js/compose.chunk.10e7f993dcc726f9.js
vendored
Normal file
BIN
public/js/compose.chunk.10e7f993dcc726f9.js
vendored
Normal file
Binary file not shown.
BIN
public/js/compose.chunk.965eab35620423e5.js
vendored
BIN
public/js/compose.chunk.965eab35620423e5.js
vendored
Binary file not shown.
BIN
public/js/compose.js
vendored
BIN
public/js/compose.js
vendored
Binary file not shown.
BIN
public/js/manifest.js
vendored
BIN
public/js/manifest.js
vendored
Binary file not shown.
BIN
public/js/post.chunk.23fc9e82d4fadc83.js
vendored
Normal file
BIN
public/js/post.chunk.23fc9e82d4fadc83.js
vendored
Normal file
Binary file not shown.
BIN
public/js/post.chunk.74f8b1d1954f5d01.js
vendored
BIN
public/js/post.chunk.74f8b1d1954f5d01.js
vendored
Binary file not shown.
Binary file not shown.
|
@ -348,8 +348,18 @@
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
|
|
||||||
filterPostMeta(media) {
|
async fixFacebookEncoding(string) {
|
||||||
let json = JSON.parse(media);
|
// Facebook and Instagram are encoding UTF8 characters in a weird way in their json
|
||||||
|
// here is a good explanation what's going wrong https://sorashi.github.io/fix-facebook-json-archive-encoding
|
||||||
|
// See https://github.com/pixelfed/pixelfed/pull/4726 for more info
|
||||||
|
const replaced = string.replace(/\\u00([a-f0-9]{2})/g, (x) => String.fromCharCode(parseInt(x.slice(2), 16)));
|
||||||
|
const buffer = Array.from(replaced, (c) => c.charCodeAt(0));
|
||||||
|
return new TextDecoder().decode(new Uint8Array(buffer));
|
||||||
|
},
|
||||||
|
|
||||||
|
async filterPostMeta(media) {
|
||||||
|
let fbfix = await this.fixFacebookEncoding(media);
|
||||||
|
let json = JSON.parse(fbfix);
|
||||||
let res = json.filter(j => {
|
let res = json.filter(j => {
|
||||||
let ids = j.media.map(m => m.uri).filter(m => {
|
let ids = j.media.map(m => m.uri).filter(m => {
|
||||||
if(this.config.allow_video_posts == true) {
|
if(this.config.allow_video_posts == true) {
|
||||||
|
@ -396,12 +406,14 @@
|
||||||
this.filterPostMeta(media);
|
this.filterPostMeta(media);
|
||||||
|
|
||||||
let imgs = await Promise.all(entries.filter(entry => {
|
let imgs = await Promise.all(entries.filter(entry => {
|
||||||
return entry.filename.startsWith('media/posts/') && (entry.filename.endsWith('.png') || entry.filename.endsWith('.jpg') || entry.filename.endsWith('.mp4'));
|
return (entry.filename.startsWith('media/posts/') || entry.filename.startsWith('media/other/')) && (entry.filename.endsWith('.png') || entry.filename.endsWith('.jpg') || entry.filename.endsWith('.mp4'));
|
||||||
})
|
})
|
||||||
.map(async entry => {
|
.map(async entry => {
|
||||||
if(
|
if(
|
||||||
entry.filename.startsWith('media/posts/') &&
|
|
||||||
(
|
(
|
||||||
|
entry.filename.startsWith('media/posts/') ||
|
||||||
|
entry.filename.startsWith('media/other/')
|
||||||
|
) && (
|
||||||
entry.filename.endsWith('.png') ||
|
entry.filename.endsWith('.png') ||
|
||||||
entry.filename.endsWith('.jpg') ||
|
entry.filename.endsWith('.jpg') ||
|
||||||
entry.filename.endsWith('.mp4')
|
entry.filename.endsWith('.mp4')
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
Liked by
|
Liked by
|
||||||
<span v-if="status.favourites_count == 1 && status.favourited == true" class="font-weight-bold">me</span>
|
<span v-if="status.favourites_count == 1 && status.favourited == true" class="font-weight-bold">me</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<router-link :to="'/i/web/profile/' + status.liked_by.id" class="primary font-weight-bold"">@{{ status.liked_by.username}}</router-link>
|
<router-link :to="'/i/web/profile/' + status.liked_by.id" class="primary font-weight-bold">{{ status.liked_by.username}}</router-link>
|
||||||
<span v-if="status.liked_by.others || status.favourites_count > 1">
|
<span v-if="status.liked_by.others || status.favourites_count > 1">
|
||||||
and <a href="#" class="primary font-weight-bold" @click.prevent="showLikes()">{{ count(status.favourites_count - 1) }} others</a>
|
and <a href="#" class="primary font-weight-bold" @click.prevent="showLikes()">{{ count(status.favourites_count - 1) }} others</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
:href="profile.url"
|
:href="profile.url"
|
||||||
@click.prevent="goToProfile()"
|
@click.prevent="goToProfile()"
|
||||||
v-html="getDisplayName()">
|
v-html="getDisplayName()">
|
||||||
{{ profile.display_name ? profile.display_name : profile.username }}
|
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<div v-for="(m, index) in cameraRollMedia" :class="[index == 0 ? 'col-12 p-0' : 'col-3 p-0']">
|
<div v-for="(m, index) in cameraRollMedia" :class="[index == 0 ? 'col-12 p-0' : 'col-3 p-0']">
|
||||||
<div class="card info-overlay p-0 rounded-0 shadow-none border">
|
<div class="card info-overlay p-0 rounded-0 shadow-none border">
|
||||||
<div class="square">
|
<div class="square">
|
||||||
<img class="square-content" :src="m.preview_url"></img>
|
<img class="square-content" :src="m.preview_url" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -238,7 +238,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="tabIndex === 'Share'" class="col-12 col-md-8 bg-dark mt-3 py-2 rounded" key="0">
|
<div v-else-if="tabIndex === 'Share'" class="col-12 col-md-8 bg-dark mt-3 py-2 rounded" key="3">
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<p class="text-muted">Portfolio URL</p>
|
<p class="text-muted">Portfolio URL</p>
|
||||||
<p class="lead mb-0"><a :href="settings.url">{{ settings.url }}</a></p>
|
<p class="lead mb-0"><a :href="settings.url">{{ settings.url }}</a></p>
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="composeText" class="reply-options" v-model="visibility">
|
<div v-if="composeText" class="reply-options">
|
||||||
<select class="form-control form-control-sm rounded-pill font-weight-bold">
|
<select class="form-control form-control-sm rounded-pill font-weight-bold" v-model="visibility">
|
||||||
<option value="public">Public</option>
|
<option value="public">Public</option>
|
||||||
<option value="private">Followers Only</option>
|
<option value="private">Followers Only</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<div class="pl-2 d-flex align-items-top">
|
<div class="pl-2 d-flex align-items-top">
|
||||||
<a class="username font-weight-bold text-dark text-decoration-none text-break" v-bind:href="profileUrl(status)" v-html="statusCardUsernameFormat(status)">
|
<a class="username font-weight-bold text-dark text-decoration-none text-break" v-bind:href="profileUrl(status)" v-html="statusCardUsernameFormat(status)">
|
||||||
Loading...
|
|
||||||
</a>
|
</a>
|
||||||
<span class="px-1 text-lighter">
|
<span class="px-1 text-lighter">
|
||||||
·
|
·
|
||||||
|
@ -61,7 +60,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="pl-2">
|
<div class="pl-2">
|
||||||
<a class="username font-weight-bold text-dark text-decoration-none text-break" v-bind:href="profileUrl(status)" v-html="statusCardUsernameFormat(status)">
|
<a class="username font-weight-bold text-dark text-decoration-none text-break" v-bind:href="profileUrl(status)" v-html="statusCardUsernameFormat(status)">
|
||||||
Loading...
|
|
||||||
</a>
|
</a>
|
||||||
<span v-if="status.account.is_admin" class="fa-stack" title="Admin Account" data-toggle="tooltip" style="height:1em; line-height:1em; max-width:19px;">
|
<span v-if="status.account.is_admin" class="fa-stack" title="Admin Account" data-toggle="tooltip" style="height:1em; line-height:1em; max-width:19px;">
|
||||||
<i class="fas fa-certificate text-danger fa-stack-1x"></i>
|
<i class="fas fa-certificate text-danger fa-stack-1x"></i>
|
||||||
|
|
Loading…
Reference in a new issue