Update IG Import

To support non-local fs
pull/6198/head
Daniel Supernault 1 month ago
parent 03d01d296f
commit 76b5601a01
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -46,6 +46,9 @@ class TransformImports extends Command
return;
}
$localFs = config('filesystems.default') === 'local';
$disk = $localFs ? Storage::disk('local') : Storage::disk(config('filesystems.default'));
foreach ($ips as $ip) {
$id = $ip->user_id;
$pid = $ip->profile_id;
@ -97,7 +100,7 @@ class TransformImports extends Command
continue;
}
if (Storage::exists('imports/'.$id.'/'.$ip->filename) === false) {
if ($disk->exists('imports/'.$id.'/'.$ip->filename) === false) {
ImportService::clearAttempts($profile->id);
ImportService::getPostCount($profile->id, true);
$ip->skip_missing_media = true;
@ -110,7 +113,7 @@ class TransformImports extends Command
foreach ($ip->media as $ipm) {
$fileName = last(explode('/', $ipm['uri']));
$og = 'imports/'.$id.'/'.$fileName;
if (! Storage::exists($og)) {
if (! $disk->exists($og)) {
$missingMedia = true;
}
}
@ -130,17 +133,17 @@ class TransformImports extends Command
$ext = last(explode('.', $fileName));
$basePath = MediaPathService::get($profile);
$og = 'imports/'.$id.'/'.$fileName;
if (! Storage::exists($og)) {
if (! $disk->exists($og)) {
$ip->skip_missing_media = true;
$ip->save();
continue 2;
}
$size = Storage::size($og);
$mime = Storage::mimeType($og);
$size = $disk->size($og);
$mime = $disk->mimeType($og);
$newFile = Str::random(40).'.'.$ext;
$np = $basePath.'/'.$newFile;
Storage::move($og, $np);
$disk->move($og, $np);
$mediaRecords[] = [
'media_path' => $np,
@ -216,8 +219,8 @@ class TransformImports extends Command
$ip->save();
foreach ($mediaRecords as $mediaData) {
if (Storage::exists($mediaData['media_path'])) {
Storage::delete($mediaData['media_path']);
if ($disk->exists($mediaData['media_path'])) {
$disk->delete($mediaData['media_path']);
}
}
@ -228,8 +231,8 @@ class TransformImports extends Command
$ip->save();
foreach ($mediaRecords as $mediaData) {
if (Storage::exists($mediaData['media_path'])) {
Storage::delete($mediaData['media_path']);
if ($disk->exists($mediaData['media_path'])) {
$disk->delete($mediaData['media_path']);
}
}

@ -2,13 +2,12 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Follower;
use App\Http\Resources\ImportStatus;
use App\Models\ImportPost;
use App\Services\ImportService;
use App\Services\StatusService;
use App\Http\Resources\ImportStatus;
use App\Follower;
use App\User;
use Illuminate\Http\Request;
class ImportPostController extends Controller
{
@ -38,7 +37,7 @@ class ImportPostController extends Controller
'min_follower_count' => config('import.instagram.permissions.min_follower_count'),
],
'allowed' => $this->checkPermissions($request, false)
'allowed' => $this->checkPermissions($request, false),
];
}
@ -87,7 +86,7 @@ class ImportPostController extends Controller
public function formatHashtags($val = false)
{
if(!$val || !strlen($val)) {
if (! $val || ! strlen($val)) {
return null;
}
@ -106,25 +105,27 @@ class ImportPostController extends Controller
$successCount = 0;
$errors = [];
foreach($request->input('files') as $file) {
foreach ($request->input('files') as $file) {
try {
$media = $file['media'];
$c = collect($media);
$firstUri = isset($media[0]['uri']) ? $media[0]['uri'] : '';
$postHash = hash('sha256', $c->toJson() . $firstUri);
$postHash = hash('sha256', $c->toJson().$firstUri);
$exists = ImportPost::where('user_id', $uid)
->where('post_hash', $postHash)
->exists();
if ($exists) {
$errors[] = "Duplicate post detected. Skipping...";
$errors[] = 'Duplicate post detected. Skipping...';
continue;
}
$exts = $c->map(function($m) {
$exts = $c->map(function ($m) {
$fn = last(explode('/', $m['uri']));
return last(explode('.', $fn));
});
@ -138,11 +139,11 @@ class ImportPostController extends Controller
$ip->post_type = $postType;
$ip->media_count = $c->count();
$ip->media = $c->map(function($m) {
$ip->media = $c->map(function ($m) {
return [
'uri' => $m['uri'],
'title' => $this->formatHashtags($m['title'] ?? ''),
'creation_timestamp' => $m['creation_timestamp'] ?? null
'creation_timestamp' => $m['creation_timestamp'] ?? null,
];
})->toArray();
@ -153,10 +154,10 @@ class ImportPostController extends Controller
$originalFilename = last(explode('/', $ip->media[0]['uri'] ?? ''));
$ip->filename = $this->sanitizeFilename($originalFilename);
$ip->metadata = $c->map(function($m) {
$ip->metadata = $c->map(function ($m) {
return [
'uri' => $m['uri'],
'media_metadata' => isset($m['media_metadata']) ? $m['media_metadata'] : null
'media_metadata' => isset($m['media_metadata']) ? $m['media_metadata'] : null,
];
})->toArray();
@ -183,15 +184,16 @@ class ImportPostController extends Controller
ImportService::getPostCount($pid, true);
} catch (\Exception $e) {
$errors[] = $e->getMessage();
\Log::error('Import error: ' . $e->getMessage());
\Log::error('Import error: '.$e->getMessage());
continue;
}
}
return [
'success' => true,
'msg' => 'Successfully imported ' . $successCount . ' posts',
'errors' => $errors
'msg' => 'Successfully imported '.$successCount.' posts',
'errors' => $errors,
];
}
@ -211,7 +213,7 @@ class ImportPostController extends Controller
$allowedMimeTypes[] = 'video/mp4';
}
$mimes = 'mimetypes:' . implode(',', $allowedMimeTypes);
$mimes = 'mimetypes:'.implode(',', $allowedMimeTypes);
$this->validate($request, [
'file' => 'required|array|max:10',
@ -219,28 +221,30 @@ class ImportPostController extends Controller
'required',
'file',
$mimes,
'max:' . config_cache('pixelfed.max_photo_size')
]
'max:'.config_cache('pixelfed.max_photo_size'),
],
]);
foreach($request->file('file') as $file) {
$localFs = config('filesystems.default') === 'local';
$disk = $localFs ? 'local' : config('filesystems.default');
foreach ($request->file('file') as $file) {
$extension = $file->getClientOriginalExtension();
$originalName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = preg_replace('/[^a-zA-Z0-9_.-]/', '_', $originalName);
$fileName = $safeFilename . '.' . $extension;
$fileName = $safeFilename.'.'.$extension;
$file->storeAs('imports/' . $request->user()->id . '/', $fileName);
$file->storeAs('imports/'.$request->user()->id.'/', $fileName, $disk);
}
ImportService::getImportedFiles($request->user()->profile_id, true);
return [
'msg' => 'Success'
'msg' => 'Success',
];
}
private function determinePostType($exts)
{
if ($exts->count() > 1) {
@ -262,7 +266,7 @@ class ImportPostController extends Controller
if (in_array($ext, ['jpg', 'jpeg', 'png', 'webp'])) {
return 'photo';
} else if (in_array($ext, ['mp4'])) {
} elseif (in_array($ext, ['mp4'])) {
return 'video';
} else {
return 'photo';
@ -277,19 +281,20 @@ class ImportPostController extends Controller
$originalName = implode('.', $parts);
$safeFilename = preg_replace('/[^a-zA-Z0-9_.-]/', '_', $originalName);
return $safeFilename . '.' . $extension;
return $safeFilename.'.'.$extension;
}
protected function checkPermissions($request, $abortOnFail = true)
{
$user = $request->user();
if($abortOnFail) {
if ($abortOnFail) {
abort_unless(config('import.instagram.enabled'), 404);
}
if($user->is_admin) {
if(!$abortOnFail) {
if ($user->is_admin) {
if (! $abortOnFail) {
return true;
} else {
return;
@ -298,96 +303,96 @@ class ImportPostController extends Controller
$admin = User::whereIsAdmin(true)->first();
if(config('import.instagram.permissions.admins_only')) {
if($abortOnFail) {
if (config('import.instagram.permissions.admins_only')) {
if ($abortOnFail) {
abort_unless($user->is_admin, 404, 'Only admins can use this feature.');
} else {
if(!$user->is_admin) {
if (! $user->is_admin) {
return false;
}
}
}
if(config('import.instagram.permissions.admin_follows_only')) {
if (config('import.instagram.permissions.admin_follows_only')) {
$exists = Follower::whereProfileId($admin->profile_id)
->whereFollowingId($user->profile_id)
->exists();
if($abortOnFail) {
->whereFollowingId($user->profile_id)
->exists();
if ($abortOnFail) {
abort_unless(
$exists,
404,
'Only admins, and accounts they follow can use this feature'
);
} else {
if(!$exists) {
if (! $exists) {
return false;
}
}
}
if(config('import.instagram.permissions.min_account_age')) {
if (config('import.instagram.permissions.min_account_age')) {
$res = $user->created_at->lt(
now()->subDays(config('import.instagram.permissions.min_account_age'))
);
if($abortOnFail) {
if ($abortOnFail) {
abort_unless(
$res,
404,
'Your account is too new to use this feature'
);
} else {
if(!$res) {
if (! $res) {
return false;
}
}
}
if(config('import.instagram.permissions.min_follower_count')) {
if (config('import.instagram.permissions.min_follower_count')) {
$res = Follower::whereFollowingId($user->profile_id)->count() >= config('import.instagram.permissions.min_follower_count');
if($abortOnFail) {
if ($abortOnFail) {
abort_unless(
$res,
404,
'You don\'t have enough followers to use this feature'
);
} else {
if(!$res) {
if (! $res) {
return false;
}
}
}
if(intval(config('import.instagram.limits.max_posts')) > 0) {
if (intval(config('import.instagram.limits.max_posts')) > 0) {
$res = ImportService::getPostCount($user->profile_id) >= intval(config('import.instagram.limits.max_posts'));
if($abortOnFail) {
if ($abortOnFail) {
abort_if(
$res,
404,
'You have reached the limit of post imports and cannot import any more posts'
);
} else {
if($res) {
if ($res) {
return false;
}
}
}
if(intval(config('import.instagram.limits.max_attempts')) > 0) {
if (intval(config('import.instagram.limits.max_attempts')) > 0) {
$res = ImportService::getAttempts($user->profile_id) >= intval(config('import.instagram.limits.max_attempts'));
if($abortOnFail) {
if ($abortOnFail) {
abort_if(
$res,
404,
'You have reached the limit of post import attempts and cannot import any more posts'
);
} else {
if($res) {
if ($res) {
return false;
}
}
}
if(!$abortOnFail) {
if (! $abortOnFail) {
return true;
}
}

Loading…
Cancel
Save