TransformImports.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Media;
  4. use App\Models\ImportPost;
  5. use App\Profile;
  6. use App\Services\AccountService;
  7. use App\Services\ImportService;
  8. use App\Services\MediaPathService;
  9. use App\Status;
  10. use Illuminate\Console\Command;
  11. use Illuminate\Database\QueryException;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Support\Str;
  14. use Storage;
  15. class TransformImports extends Command
  16. {
  17. /**
  18. * The name and signature of the console command.
  19. *
  20. * @var string
  21. */
  22. protected $signature = 'app:transform-imports';
  23. /**
  24. * The console command description.
  25. *
  26. * @var string
  27. */
  28. protected $description = 'Transform imports into statuses';
  29. /**
  30. * Execute the console command.
  31. */
  32. public function handle()
  33. {
  34. if (! config('import.instagram.enabled')) {
  35. return;
  36. }
  37. $ips = ImportPost::whereNull('status_id')->where('skip_missing_media', '!=', true)->take(1500)->get();
  38. if (! $ips->count()) {
  39. return;
  40. }
  41. foreach ($ips as $ip) {
  42. $id = $ip->user_id;
  43. $pid = $ip->profile_id;
  44. $profile = Profile::find($pid);
  45. if (! $profile) {
  46. $ip->skip_missing_media = true;
  47. $ip->save();
  48. continue;
  49. }
  50. $exists = ImportPost::whereUserId($id)
  51. ->whereNotNull('status_id')
  52. ->where('filename', $ip->filename)
  53. ->where('creation_year', $ip->creation_year)
  54. ->where('creation_month', $ip->creation_month)
  55. ->where('creation_day', $ip->creation_day)
  56. ->exists();
  57. if ($exists == true) {
  58. $ip->skip_missing_media = true;
  59. $ip->save();
  60. continue;
  61. }
  62. if ($id > 999999) {
  63. $ip->skip_missing_media = true;
  64. $ip->save();
  65. continue;
  66. }
  67. if ($ip->creation_year < 9 || $ip->creation_year > (int) now()->addYear()->format('y')) {
  68. $ip->skip_missing_media = true;
  69. $ip->save();
  70. continue;
  71. }
  72. if ($ip->creation_month < 1 || $ip->creation_month > 12) {
  73. $ip->skip_missing_media = true;
  74. $ip->save();
  75. continue;
  76. }
  77. if ($ip->creation_day < 1 || $ip->creation_day > 31) {
  78. $ip->skip_missing_media = true;
  79. $ip->save();
  80. continue;
  81. }
  82. if (Storage::exists('imports/'.$id.'/'.$ip->filename) === false) {
  83. ImportService::clearAttempts($profile->id);
  84. ImportService::getPostCount($profile->id, true);
  85. $ip->skip_missing_media = true;
  86. $ip->save();
  87. continue;
  88. }
  89. $missingMedia = false;
  90. foreach ($ip->media as $ipm) {
  91. $fileName = last(explode('/', $ipm['uri']));
  92. $og = 'imports/'.$id.'/'.$fileName;
  93. if (! Storage::exists($og)) {
  94. $missingMedia = true;
  95. }
  96. }
  97. if ($missingMedia === true) {
  98. $ip->skip_missing_media = true;
  99. $ip->save();
  100. continue;
  101. }
  102. $caption = $ip->caption ?? '';
  103. $mediaRecords = [];
  104. foreach ($ip->media as $ipm) {
  105. $fileName = last(explode('/', $ipm['uri']));
  106. $ext = last(explode('.', $fileName));
  107. $basePath = MediaPathService::get($profile);
  108. $og = 'imports/'.$id.'/'.$fileName;
  109. if (! Storage::exists($og)) {
  110. $ip->skip_missing_media = true;
  111. $ip->save();
  112. continue 2;
  113. }
  114. $size = Storage::size($og);
  115. $mime = Storage::mimeType($og);
  116. $newFile = Str::random(40).'.'.$ext;
  117. $np = $basePath.'/'.$newFile;
  118. Storage::move($og, $np);
  119. $mediaRecords[] = [
  120. 'media_path' => $np,
  121. 'mime' => $mime,
  122. 'size' => $size,
  123. ];
  124. }
  125. try {
  126. DB::transaction(function () use ($ip, $profile, $id, $pid, $caption, $mediaRecords) {
  127. $uniqueIdData = ImportService::getUniqueCreationId(
  128. $id,
  129. $ip->creation_year,
  130. $ip->creation_month,
  131. $ip->creation_day,
  132. $ip->id
  133. );
  134. if (! $uniqueIdData) {
  135. throw new \Exception("Could not generate unique creation_id for ImportPost ID {$ip->id}");
  136. }
  137. $statusId = $uniqueIdData['status_id'];
  138. $status = new Status;
  139. $status->profile_id = $pid;
  140. $status->caption = $caption;
  141. $status->type = $ip->post_type;
  142. $status->scope = 'public';
  143. $status->visibility = 'public';
  144. $status->id = $statusId;
  145. $status->created_at = now()->parse($ip->creation_date);
  146. $status->saveQuietly();
  147. foreach ($mediaRecords as $mediaData) {
  148. $media = new Media;
  149. $media->profile_id = $pid;
  150. $media->user_id = $id;
  151. $media->status_id = $status->id;
  152. $media->media_path = $mediaData['media_path'];
  153. $media->mime = $mediaData['mime'];
  154. $media->size = $mediaData['size'];
  155. $media->save();
  156. }
  157. $ip->status_id = $status->id;
  158. $ip->creation_id = $uniqueIdData['incr'];
  159. if ($uniqueIdData['year'] !== $ip->creation_year ||
  160. $uniqueIdData['month'] !== $ip->creation_month ||
  161. $uniqueIdData['day'] !== $ip->creation_day) {
  162. $ip->creation_year = $uniqueIdData['year'];
  163. $ip->creation_month = $uniqueIdData['month'];
  164. $ip->creation_day = $uniqueIdData['day'];
  165. $this->info("Date shifted for ImportPost ID {$ip->id} to {$uniqueIdData['year']}-{$uniqueIdData['month']}-{$uniqueIdData['day']}");
  166. }
  167. $ip->save();
  168. $profile->status_count = $profile->status_count + 1;
  169. $profile->save();
  170. });
  171. AccountService::del($profile->id);
  172. ImportService::clearAttempts($profile->id);
  173. ImportService::getPostCount($profile->id, true);
  174. } catch (QueryException $e) {
  175. $this->error("Database error for ImportPost ID {$ip->id}: ".$e->getMessage());
  176. $ip->skip_missing_media = true;
  177. $ip->save();
  178. foreach ($mediaRecords as $mediaData) {
  179. if (Storage::exists($mediaData['media_path'])) {
  180. Storage::delete($mediaData['media_path']);
  181. }
  182. }
  183. continue;
  184. } catch (\Exception $e) {
  185. $this->error("Error processing ImportPost ID {$ip->id}: ".$e->getMessage());
  186. $ip->skip_missing_media = true;
  187. $ip->save();
  188. foreach ($mediaRecords as $mediaData) {
  189. if (Storage::exists($mediaData['media_path'])) {
  190. Storage::delete($mediaData['media_path']);
  191. }
  192. }
  193. continue;
  194. }
  195. }
  196. }
  197. }