pixelfed/app/Http/Controllers/Settings/ExportSettings.php

262 lines
8 KiB
PHP
Raw Normal View History

2019-04-24 19:32:23 +00:00
<?php
namespace App\Http\Controllers\Settings;
2019-04-25 03:08:35 +00:00
use App\Status;
use App\Transformer\ActivityPub\ProfileTransformer;
use App\Transformer\Api\StatusTransformer as StatusApiTransformer;
2019-04-24 19:32:23 +00:00
use App\UserFilter;
use Auth;
use Cache;
2019-04-24 19:32:23 +00:00
use Illuminate\Http\Request;
2019-04-24 19:50:47 +00:00
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
use Storage;
2019-04-24 19:32:23 +00:00
trait ExportSettings
{
private const CHUNK_SIZE = 1000;
private const STORAGE_BASE = 'user_exports';
public function __construct()
{
$this->middleware('auth');
}
2019-04-24 19:32:23 +00:00
public function dataExport()
{
return view('settings.dataexport');
}
2019-04-24 19:50:47 +00:00
public function exportAccount()
{
$profile = Auth::user()->profile;
$fractal = new Fractal\Manager;
$fractal->setSerializer(new ArraySerializer);
$resource = new Fractal\Resource\Item($profile, new ProfileTransformer);
$data = $fractal->createData($resource)->toArray();
return response()->streamDownload(function () use ($data) {
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}, 'account.json', [
'Content-Type' => 'application/json',
]);
2019-04-24 19:50:47 +00:00
}
2019-04-24 19:32:23 +00:00
public function exportFollowing()
{
$profile = Auth::user()->profile;
$userId = Auth::id();
$userExportPath = 'user_exports/'.$userId;
$filename = 'pixelfed-following.json';
$tempPath = $userExportPath.'/'.$filename;
if (! Storage::exists($userExportPath)) {
Storage::makeDirectory($userExportPath);
}
try {
Storage::put($tempPath, '[');
$profile->following()
->chunk(1000, function ($following) use ($tempPath) {
$urls = $following->map(function ($follow) {
return $follow->url();
});
$json = json_encode($urls,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE
);
$json = trim($json, '[]');
if (Storage::size($tempPath) > 1) {
$json = ','.$json;
}
Storage::append($tempPath, $json);
});
Storage::append($tempPath, ']');
return response()->stream(
function () use ($tempPath) {
$handle = fopen(Storage::path($tempPath), 'rb');
while (! feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
Storage::delete($tempPath);
},
200,
[
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename="pixelfed-following.json"',
]
);
} catch (\Exception $e) {
if (Storage::exists($tempPath)) {
Storage::delete($tempPath);
}
throw $e;
}
2019-04-24 19:32:23 +00:00
}
public function exportFollowers()
{
$profile = Auth::user()->profile;
$userId = Auth::id();
$userExportPath = 'user_exports/'.$userId;
$filename = 'pixelfed-followers.json';
$tempPath = $userExportPath.'/'.$filename;
if (! Storage::exists($userExportPath)) {
Storage::makeDirectory($userExportPath);
}
try {
Storage::put($tempPath, '[');
$profile->followers()
->chunk(1000, function ($followers) use ($tempPath) {
$urls = $followers->map(function ($follower) {
return $follower->url();
});
$json = json_encode($urls,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE
);
$json = trim($json, '[]');
if (Storage::size($tempPath) > 1) {
$json = ','.$json;
}
Storage::append($tempPath, $json);
});
Storage::append($tempPath, ']');
return response()->stream(
function () use ($tempPath) {
$handle = fopen(Storage::path($tempPath), 'rb');
while (! feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
Storage::delete($tempPath);
},
200,
[
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename="pixelfed-followers.json"',
]
);
} catch (\Exception $e) {
if (Storage::exists($tempPath)) {
Storage::delete($tempPath);
}
throw $e;
}
2019-04-24 19:32:23 +00:00
}
public function exportMuteBlockList()
{
$profile = Auth::user()->profile;
$exists = UserFilter::select('id')
->whereUserId($profile->id)
->exists();
if (! $exists) {
2019-04-24 19:32:23 +00:00
return redirect()->back();
}
$data = Cache::remember('account:export:profile:muteblocklist:'.Auth::user()->profile->id, now()->addMinutes(60), function () use ($profile) {
2019-04-24 19:32:23 +00:00
return json_encode([
'muted' => $profile->mutedProfileUrls(),
'blocked' => $profile->blockedProfileUrls(),
2019-04-24 19:32:23 +00:00
], JSON_PRETTY_PRINT);
});
return response()->streamDownload(function () use ($data) {
2019-04-24 19:32:23 +00:00
echo $data;
2019-04-24 23:37:27 +00:00
}, 'muted-and-blocked-accounts.json', [
'Content-Type' => 'application/json',
]);
2019-04-24 19:32:23 +00:00
}
2019-04-25 03:08:35 +00:00
public function exportStatuses(Request $request)
{
$profile = Auth::user()->profile;
$userId = Auth::id();
$userExportPath = self::STORAGE_BASE.'/'.$userId;
$filename = 'pixelfed-statuses.json';
$tempPath = $userExportPath.'/'.$filename;
if (! Storage::exists($userExportPath)) {
Storage::makeDirectory($userExportPath);
}
Storage::put($tempPath, '[');
$fractal = new Fractal\Manager;
$fractal->setSerializer(new ArraySerializer);
try {
Status::whereProfileId($profile->id)
->chunk(self::CHUNK_SIZE, function ($statuses) use ($fractal, $tempPath) {
$resource = new Fractal\Resource\Collection($statuses, new StatusApiTransformer);
$data = $fractal->createData($resource)->toArray();
$json = json_encode($data,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE
);
2019-04-25 03:08:35 +00:00
$json = trim($json, '[]');
if (Storage::size($tempPath) > 1) {
$json = ','.$json;
}
Storage::append($tempPath, $json);
});
Storage::append($tempPath, ']');
return response()->stream(
function () use ($tempPath) {
$handle = fopen(Storage::path($tempPath), 'rb');
while (! feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
Storage::delete($tempPath);
},
200,
[
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename="pixelfed-statuses.json"',
]
);
} catch (\Exception $e) {
if (Storage::exists($tempPath)) {
Storage::delete($tempPath);
}
throw $e;
}
}
}