コード例 #1
0
ファイル: BatchUpload.php プロジェクト: JCQS04/myimouto
 public function run()
 {
     Rails::systemExit()->register(function () {
         if (!$this->finished) {
             $this->active = false;
             $this->data->success = false;
             $this->data->error = "Couldn't finish successfuly";
             $this->save();
         }
     });
     # Ugly: set the current user ID to the one set in the batch, so history entries
     # will be created as that user.
     // $old_thread_user = Thread::current["danbooru-user"];
     // $old_thread_user_id = Thread::current["danbooru-user_id"];
     // $old_ip_addr = Thread::current["danbooru-ip_addr"];
     // Thread::current["danbooru-user"] = User::find_by_id(self.user_id)
     // Thread::current["danbooru-user_id"] = $this->user_id
     // Thread::current["danbooru-ip_addr"] = $this->ip
     $this->active = true;
     $this->save();
     $post = Post::create(['source' => $this->url, 'tags' => $this->tags, 'updater_user_id' => $this->user_id, 'updater_ip_addr' => $this->ip, 'user_id' => $this->user_id, 'ip_addr' => $this->ip, 'status' => "active"]);
     if ($post->errors()->blank()) {
         if (CONFIG()->dupe_check_on_upload && $post->image() && !$post->parent_id) {
             $options = ['services' => SimilarImages::get_services("local"), 'type' => 'post', 'source' => $post];
             $res = SimilarImages::similar_images($options);
             if (!empty($res['posts'])) {
                 $post->tags = $post->tags() . " possible_duplicate";
                 $post->save();
             }
         }
         $this->data->success = true;
         $this->data->post_id = $post->id;
     } elseif ($post->errors()->on('md5')) {
         // $p = $post->errors();
         $p = Post::where(['md5' => $post->md5])->first();
         $this->data->success = false;
         $this->data->error = "Post already exists";
         $this->data->post_id = $p->id;
     } else {
         // p $post.errors
         $this->data->success = false;
         $this->data->error = $post->errors()->fullMessages(", ");
     }
     if ($this->data->success) {
         $this->status = 'finished';
     } else {
         $this->status = 'error';
     }
     $this->active = false;
     $this->save();
     $this->finished = true;
     // Thread::current["danbooru-user"] = old_thread_user
     // Thread::current["danbooru-user_id"] = old_thread_user_id
     // Thread::current["danbooru-ip_addr"] = old_ip_addr
 }
コード例 #2
0
ファイル: JobTask.php プロジェクト: JCQS04/myimouto
 public function execute_external_data_search()
 {
     # current_user will be needed to save post history.
     # Set the first admin as current user.
     User::set_current_user(User::where('level = ?', CONFIG()->user_levels['Admin'])->first());
     if (empty($this->data->last_post_id)) {
         $this->data->last_post_id = 0;
     }
     $post_id = $this->data->last_post_id + 1;
     $config = array_merge(['servers' => [], 'interval' => 3, 'source' => true, 'merge_tags' => true, 'limit' => 100, 'set_rating' => false, 'exclude_tags' => [], 'similarity' => 90], CONFIG()->external_data_search_config);
     $limit = $config['limit'];
     $interval = $config['interval'];
     $search_options = ['type' => 'post', 'data_search' => true, 'services' => $config['servers'], 'threshold' => $config['similarity']];
     $post_count = !$limit ? -1 : 0;
     while ($post_count < $limit) {
         if (!($post = Post::where('id >= ? AND status != "deleted"', $post_id)->order('id ASC')->first())) {
             break;
         }
         $search_options['source'] = $post;
         $new_tags = [];
         $source = null;
         $external_posts = SimilarImages::similar_images($search_options)['posts_external'];
         $rating_set = false;
         foreach ($external_posts as $ep) {
             if (!$rating_set && $config['set_rating'] && $ep->rating) {
                 $post->rating = $ep->rating;
                 $rating_set = true;
             }
             if ($config['source'] && !$source && $ep->source) {
                 $source = $ep->source;
             }
             $new_tags = array_merge($new_tags, explode(' ', $ep->tags));
         }
         # Exclude tags.
         $new_tags = array_diff($new_tags, $config['exclude_tags']);
         if ($config['merge_tags']) {
             $new_tags = array_merge($new_tags, $post->tags);
         }
         $new_tags = array_filter(array_unique($new_tags));
         $post->new_tags = $new_tags;
         if ($source) {
         }
         $post->source = $source;
         $post->save();
         if ($limit) {
             $post_count++;
         }
         $this->update_data(['last_post_id' => $post->id]);
         $post_id = $post->id + 1;
         if ($config['interval']) {
             sleep($config['interval']);
         }
     }
 }
コード例 #3
0
ファイル: PostController.php プロジェクト: JCQS04/myimouto
 public function similar()
 {
     $params = array_merge(['file' => null, 'url' => null, 'id' => $this->params()->id, 'search_id' => null, 'services' => null, 'threshold' => null, 'forcegray' => null, 'initial' => null, 'width' => null, 'height' => null], $this->params()->toArray());
     if (!empty($params['data_search']) && !current_user()->is_mod_or_higher()) {
         unset($params['data_search']);
     }
     if (!SimilarImages::valid_saved_search($params['search_id'])) {
         $params['search_id'] = null;
     }
     if (!empty($params['width'])) {
         $params['width'] = (int) $params['width'];
     }
     if (!empty($params['height'])) {
         $params['height'] = (int) $params['height'];
     }
     $this->initial = $params['initial'];
     if ($this->initial && !$params['services']) {
         $params['services'] = "local";
     }
     $this->services = SimilarImages::get_services($params['services']);
     if ($this->params()->id) {
         $this->compared_post = Post::find($this->params()->id);
     } else {
         $this->compared_post = new Post();
     }
     $this->errors = null;
     $this->posts = Post::emptyCollection();
     $this->similar = [];
     $similarity = [];
     if ($this->compared_post && $this->compared_post->is_deleted()) {
         $this->respond_to_error("Post deleted", ['post#show', 'id' => $this->params()->id, 'tag_title' => $this->compared_post->tag_title()]);
         return;
     }
     # We can do these kinds of searches:
     #
     # File: Search from a specified file.    The image is saved locally with an ID, and sent
     # as a file to the search servers.
     #
     # URL: search from a remote URL.    The URL is downloaded, and then treated as a :file
     # search.    This way, changing options doesn't repeatedly download the remote image,
     # and it removes a layer of abstraction when an error happens during download
     # compared to having the search server download it.
     #
     # Post ID: Search from a post ID.    The preview image is sent as a URL.
     #
     # Search ID: Search using an image uploaded with a previous File search, using
     # the search MD5 created.    We're not allowed to repopulate filename fields in the
     # user's browser, so we can't re-submit the form as a file search when changing search
     # parameters.    Instead, we hide the search ID in the form, and use it to recall the
     # file from before.    These files are expired after a while; we check for expired files
     # when doing later searches, so we don't need a cron job.
     $search = function (array $params) {
         $options = array_merge($params, ['services' => $this->services]);
         # Check search_id first, so options links that include it will use it.    If the
         # user searches with the actual form, search_id will be cleared on submission.
         if (!empty($params['search_id'])) {
             $file_path = SimilarImages::find_saved_search($params['search_id']);
             if (!$file_path) {
                 # The file was probably purged.    Delete :search_id before redirecting, so the
                 # error doesn't loop.
                 // unset($params.delete(:search_id)
                 return ['errors' => ['error' => "Search expired"]];
             }
         } elseif (!empty($params['url']) || !empty($_FILES['file']['tmp_name'])) {
             # Save the file locally.
             try {
                 if (!empty($params['url'])) {
                     $file = Danbooru::http_get_streaming($params['url']);
                     $search = SimilarImages::save_search($file);
                 } else {
                     # file
                     $file = file_get_contents($_FILES['file']['tmp_name']);
                     $search = SimilarImages::save_search($file);
                     $options['type'] = 'file';
                 }
             } catch (Moebooru\Exception\ResizeErrorException $e) {
                 return ['errors' => ['error' => $e->getMessage()]];
             } catch (Danbooru\Exception\ExceptionInterface $e) {
                 return ['errors' => ['error' => $e->getMessage()]];
             }
             // } rescue Timeout::Error => e
             // return { :errors => { :error => "Download timed out" } }
             // end
             $file_path = $search['file_path'];
             # Set :search_id in params for generated URLs that point back here.
             $params['search_id'] = $search['search_id'];
             # The :width and :height params specify the size of the original image, for display
             # in the results.    The user can specify them; if not specified, fill it in.
             empty($params['width']) && ($params['width'] = $search['original_width']);
             empty($params['height']) && ($params['height'] = $search['original_height']);
         } elseif (!empty($params['id'])) {
             $options['source'] = $this->compared_post;
             $options['type'] = 'post';
         }
         if (!empty($params['search_id'])) {
             $options['source'] = $file_path;
             $options['source_filename'] = $params['search_id'];
             $options['source_thumb'] = "/data/search/" . $params['search_id'];
             $options['type'] = 'file';
         }
         $options['width'] = $params['width'];
         $options['height'] = $params['height'];
         if ($options['type'] == 'file') {
             SimilarImages::cull_old_searches();
         }
         return SimilarImages::similar_images($options);
     };
     $this->searched = false;
     if ($this->params()->url || $this->params()->id || !empty($_FILES['file']) && empty($_FILES['file']['error']) || !empty($this->params()->search_id)) {
         $res = $search($params);
         # Error when no service was selected and/or local search isn't supported
         if (is_string($res['errors'])) {
             $this->notice($res['errors']);
         } else {
             $this->errors = !empty($res['errors']) ? $res['errors'] : [];
             $this->searched = true;
             $this->search_id = $this->params()->search_id;
             # Never pass :file on through generated URLs.
             $params['file'] = null;
         }
     } else {
         $res = [];
         $this->errors = [];
     }
     if ($res && $this->searched) {
         !empty($res['posts']) && ($this->posts = $res['posts']);
         $this->similar = $res;
         !empty($res['similarity']) && ($similarity = $res['similarity']);
     }
     if ($this->request()->format() == "json" || $this->request()->format() == "xml") {
         if (!empty($this->errors['error'])) {
             $this->respond_to_error($this->errors['error'], ['#index'], ['status' => 503]);
             return;
         }
         if (!$this->searched) {
             $this->respond_to_error("no search supplied", ['#index'], ['status' => 503]);
             return;
         }
     }
     $this->respondTo(['html' => function () use($similarity, $res) {
         if ($this->initial && !$this->posts->any()) {
             // flash.keep
             $this->redirectTo(['post#show', 'id' => $this->params()->id, 'tag_title' => $this->compared_post->tag_title()]);
             return;
         }
         if (!empty($this->errors['error'])) {
             $this->notice($this->errors['error']);
         }
         if ($this->searched) {
             !empty($res['posts_external']) && $this->posts->merge($res['posts_external']);
             $this->posts->sort(function ($a, $b) use($similarity) {
                 $aid = spl_object_hash($a);
                 $bid = spl_object_hash($b);
                 if ($similarity[$aid] == $similarity[$bid]) {
                     return 0;
                 } elseif ($similarity[$aid] > $similarity[$bid]) {
                     return 1;
                 }
                 return -1;
             });
             # Add the original post to the start of the list.
             if (!empty($res['source'])) {
                 $this->posts[] = $res['source'];
             } elseif (!empty($res['external_source'])) {
                 $this->posts[] = $res['external_source'];
             }
         }
     }, 'json' => function () use($res) {
         foreach ($this->posts as $post) {
             $post->similarity = $res['similarity'][spl_object_hash($post)];
         }
         if (!empty($res['posts_external'])) {
             foreach ($res['posts_external'] as $post) {
                 $post->similarity = $res['similarity'][spl_object_hash($post)];
             }
             $this->posts->merge($res['posts_external']);
         }
         $api_data = ['posts' => $this->posts, 'search_id' => $this->params()->search_id];
         if (!empty($res['source'])) {
             $api_data['source'] = $res['source'];
         } elseif (!empty($res['external_source'])) {
             $api_data['source'] = $res['external_source'];
         } else {
             $api_data['source'] = '';
         }
         if (!empty($res['errors'])) {
             $api_data['error'] = [];
             foreach ($res['errors'] as $server => $error) {
                 $services = !empty($error['services']) ? implode(', ', $error['services']) : array();
                 $api_data['error'][] = ['server' => $server, 'message' => $error['message'], 'services' => $services];
             }
         }
         $this->respond_to_success('', [], ['api' => $api_data]);
     }]);
     $this->params = $params;
 }