StatusRemoteUpdatePipeline.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace App\Jobs\StatusPipeline;
  3. use Illuminate\Bus\Queueable;
  4. use Illuminate\Contracts\Queue\ShouldBeUnique;
  5. use Illuminate\Contracts\Queue\ShouldQueue;
  6. use Illuminate\Foundation\Bus\Dispatchable;
  7. use Illuminate\Queue\InteractsWithQueue;
  8. use Illuminate\Queue\SerializesModels;
  9. use App\Media;
  10. use App\ModLog;
  11. use App\Profile;
  12. use App\Status;
  13. use App\Models\StatusEdit;
  14. use App\Services\StatusService;
  15. use Purify;
  16. class StatusRemoteUpdatePipeline implements ShouldQueue
  17. {
  18. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  19. public $activity;
  20. /**
  21. * Create a new job instance.
  22. */
  23. public function __construct($activity)
  24. {
  25. $this->activity = $activity;
  26. }
  27. /**
  28. * Execute the job.
  29. */
  30. public function handle(): void
  31. {
  32. $ts = (string) microtime(true);
  33. \Log::info('AP:inbox Update:Job invoked ' . $ts);
  34. $activity = $this->activity;
  35. $status = Status::with('media')->whereObjectUrl($activity['id'])->first();
  36. if(!$status) {
  37. \Log::info('AP:inbox Update:Job notFound ' . $ts . ' activity: ' . $activity);
  38. return;
  39. }
  40. $this->createPreviousEdit($status);
  41. $this->updateMedia($status, $activity);
  42. $this->updateImmediateAttributes($status, $activity);
  43. $this->createEdit($status, $activity);
  44. }
  45. protected function createPreviousEdit($status)
  46. {
  47. if(!$status->edits()->count()) {
  48. StatusEdit::create([
  49. 'status_id' => $status->id,
  50. 'profile_id' => $status->profile_id,
  51. 'caption' => $status->caption,
  52. 'spoiler_text' => $status->cw_summary,
  53. 'is_nsfw' => $status->is_nsfw,
  54. 'ordered_media_attachment_ids' => $status->media()->orderBy('order')->pluck('id')->toArray(),
  55. 'created_at' => $status->created_at
  56. ]);
  57. }
  58. }
  59. protected function updateMedia($status, $activity)
  60. {
  61. if(!isset($activity['attachment'])) {
  62. return;
  63. }
  64. $ogm = $status->media->count() ? $status->media()->orderBy('order')->get() : collect([]);
  65. $nm = collect($activity['attachment'])->filter(function($nm) {
  66. return isset(
  67. $nm['type'],
  68. $nm['mediaType'],
  69. $nm['url']
  70. ) &&
  71. in_array($nm['type'], ['Document', 'Image', 'Video']) &&
  72. in_array($nm['mediaType'], explode(',', config('pixelfed.media_types')));
  73. });
  74. // Skip when no media
  75. if(!$ogm->count() && !$nm->count()) {
  76. return;
  77. }
  78. Media::whereProfileId($status->profile_id)
  79. ->whereStatusId($status->id)
  80. ->update([
  81. 'status_id' => null
  82. ]);
  83. $nm->each(function($n, $key) use($status) {
  84. $m = new Media;
  85. $m->status_id = $status->id;
  86. $m->profile_id = $status->profile_id;
  87. $m->remote_media = true;
  88. $m->media_path = $n['url'];
  89. $m->caption = isset($n['name']) && !empty($n['name']) ? Purify::clean($n['name']) : null;
  90. $m->remote_url = $n['url'];
  91. $m->width = isset($n['width']) && !empty($n['width']) ? $n['width'] : null;
  92. $m->height = isset($n['height']) && !empty($n['height']) ? $n['height'] : null;
  93. $m->skip_optimize = true;
  94. $m->order = $key + 1;
  95. $m->save();
  96. });
  97. }
  98. protected function updateImmediateAttributes($status, $activity)
  99. {
  100. if(isset($activity['content'])) {
  101. $status->caption = strip_tags($activity['content']);
  102. $status->rendered = Purify::clean($activity['content']);
  103. }
  104. if(isset($activity['sensitive'])) {
  105. if((bool) $activity['sensitive'] == false) {
  106. $status->is_nsfw = false;
  107. $exists = ModLog::whereObjectType('App\Status::class')
  108. ->whereObjectId($status->id)
  109. ->whereAction('admin.status.moderate')
  110. ->exists();
  111. if($exists == true) {
  112. $status->is_nsfw = true;
  113. }
  114. $profile = Profile::find($status->profile_id);
  115. if(!$profile || $profile->cw == true) {
  116. $status->is_nsfw = true;
  117. }
  118. } else {
  119. $status->is_nsfw = true;
  120. }
  121. }
  122. if(isset($activity['summary'])) {
  123. $status->cw_summary = Purify::clean($activity['summary']);
  124. } else {
  125. $status->cw_summary = null;
  126. }
  127. $status->edited_at = now();
  128. $status->save();
  129. StatusService::del($status->id);
  130. }
  131. protected function createEdit($status, $activity)
  132. {
  133. $cleaned = isset($activity['content']) ? Purify::clean($activity['content']) : null;
  134. $spoiler_text = isset($activity['summary']) ? Purify::clean($attributes['summary']) : null;
  135. $sensitive = isset($activity['sensitive']) ? $activity['sensitive'] : null;
  136. $mids = $status->media()->count() ? $status->media()->orderBy('order')->pluck('id')->toArray() : null;
  137. StatusEdit::create([
  138. 'status_id' => $status->id,
  139. 'profile_id' => $status->profile_id,
  140. 'caption' => $cleaned,
  141. 'spoiler_text' => $spoiler_text,
  142. 'is_nsfw' => $sensitive,
  143. 'ordered_media_attachment_ids' => $mids
  144. ]);
  145. }
  146. }