2013-10-27 01:06:58 +02:00
|
|
|
<?php
|
|
|
|
class JobTask extends Rails\ActiveRecord\Base
|
|
|
|
{
|
|
|
|
protected $data;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
static public function execute_once()
|
|
|
|
{
|
|
|
|
foreach (self::where('status = "pending" AND task_type IN (?)', CONFIG()->active_job_tasks)->order("id desc")->take() as $task) {
|
|
|
|
$task->execute();
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function pretty_data()
|
|
|
|
{
|
|
|
|
switch ($this->task_type) {
|
|
|
|
case "mass_tag_edit":
|
|
|
|
$start = $this->data["start_tags"];
|
|
|
|
$result = $this->data["result_tags"];
|
|
|
|
$user = User::find_name($this->data["updater_id"]);
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
return "start: ".$start.", result: ".$result.", user: ".$user;
|
|
|
|
break;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
case "approve_tag_alias":
|
|
|
|
$ta = TagAlias::where('id', $this->data->id)->first();
|
|
|
|
if (!$ta) {
|
|
|
|
Rails::log()->warning(sprintf("Tag alias #%s couldn't be found for job task #%s. Destroying job task.", $this->data->id, $this->id));
|
|
|
|
$this->destroy();
|
|
|
|
return "Error - Tag alias doesn't exist";
|
|
|
|
}
|
|
|
|
return "start: " . $ta->name . ", result: " . $ta->alias_name();
|
|
|
|
break;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
case "approve_tag_implication":
|
|
|
|
$ti = TagImplication::where('id', $this->data->id)->first();
|
|
|
|
if (!$ti) {
|
|
|
|
Rails::log()->warning(sprintf("Tag implication #%s couldn't be found for job task #%s. Destroying job task.", $this->data->id, $this->id));
|
|
|
|
$this->destroy();
|
|
|
|
return "Error - Tag implication doesn't exist";
|
|
|
|
}
|
|
|
|
return "start: " . $ti->predicate->name . ", result: " . $ti->consequent->name;
|
|
|
|
break;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2014-01-12 13:05:06 +01:00
|
|
|
case "calculate_tag_subscriptions":
|
2016-07-30 20:45:57 +02:00
|
|
|
if (CONFIG()->tag_subscription_delay && isset($this->data->last_run)) {
|
|
|
|
$nextRun = date('Y-m-d H:i:s', strtotime('+' . CONFIG()->tag_subscription_delay, strtotime($this->data->last_run)));
|
|
|
|
} else {
|
|
|
|
$nextRun = 'imminent';
|
|
|
|
}
|
|
|
|
|
|
|
|
$lastRun = (isset($this->data->last_run) ? $this->data->last_run : 'never');
|
|
|
|
|
|
|
|
return "last run: " . $lastRun . '; next run: ' . $nextRun;
|
2013-10-27 01:06:58 +02:00
|
|
|
|
|
|
|
// case "upload_posts_to_mirrors"
|
|
|
|
// ret = ""
|
|
|
|
// if data["post_id"]
|
|
|
|
// ret << "uploading post_id #{data["post_id"]}"
|
|
|
|
// elsif data["left"]
|
|
|
|
// ret << "sleeping"
|
|
|
|
// else
|
|
|
|
// ret << "idle"
|
|
|
|
// end
|
|
|
|
// ret << (" (%i left) " % data["left"]) if data["left"]
|
|
|
|
// ret
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
case "periodic_maintenance":
|
|
|
|
if ($this->status == "processing")
|
|
|
|
return !empty($this->data->step) ? $this->data->step : 'unknown';
|
|
|
|
elseif ($this->status != "error") {
|
|
|
|
$next_run = (!empty($this->data->next_run) ? strtotime($this->data->next_run) : 0) - time();
|
|
|
|
$next_run_in_minutes = $next_run / 60;
|
|
|
|
if ($next_run_in_minutes > 0)
|
|
|
|
$eta = "next run in ".round($next_run_in_minutes / 60.0)." hours";
|
|
|
|
else
|
|
|
|
$eta = "next run imminent";
|
|
|
|
return "sleeping (".$eta.")";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "external_data_search":
|
|
|
|
return 'last updated post id: ' . (isset($this->data->last_post_id) ? $this->data->last_post_id : '(none)');
|
|
|
|
break;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
case "upload_batch_posts":
|
|
|
|
if ($this->status == "pending")
|
|
|
|
return "idle";
|
|
|
|
elseif ($this->status == "processing") {
|
|
|
|
$user = User::find_name($this->data->user_id);
|
|
|
|
return "uploading " . $this->data->url . " for " . $user;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
// case "update_post_frames"
|
|
|
|
// if status == "pending" then
|
|
|
|
// return "idle"
|
|
|
|
// elsif status == "processing" then
|
|
|
|
// return data["status"]
|
|
|
|
// end
|
|
|
|
// end
|
|
|
|
}
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function execute()
|
|
|
|
{
|
|
|
|
if ($this->repeat_count > 0)
|
|
|
|
$count = $this->repeat_count - 1;
|
|
|
|
else
|
|
|
|
$count = $this->repeat_count;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
Rails::systemExit()->register(function(){
|
|
|
|
if ($this->status == 'processing')
|
|
|
|
$this->updateAttribute('status', 'pending');
|
|
|
|
}, 'job_task');
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
try {
|
|
|
|
$this->updateAttribute('status', "processing");
|
|
|
|
$task_method = 'execute_'.$this->task_type;
|
|
|
|
$this->$task_method();
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($count == 0)
|
|
|
|
$this->updateAttribute('status', "finished");
|
2016-07-30 07:16:24 +02:00
|
|
|
else {
|
|
|
|
// This is necessary due to a bug with Rails that won't clear changed attributes,
|
|
|
|
// so when 'status' is changed back to 'pending', the system will think the attribute
|
|
|
|
// is being reversed to its previous value, and will remove it from the changedAttributes,
|
|
|
|
// array, therefore the new value 'pending' won't be set and will stay as 'processing'.
|
|
|
|
$this->clearChangedAttributes();
|
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$this->updateAttributes(array('status' => "pending", 'repeat_count' => $count));
|
2016-07-30 07:16:24 +02:00
|
|
|
}
|
2013-10-27 01:06:58 +02:00
|
|
|
} catch (Exception $x) {
|
|
|
|
$text = "";
|
|
|
|
$text .= "Error executing job: " . $this->task_type . "\n";
|
|
|
|
$text .= " \n";
|
|
|
|
$text .= $x->getTraceAsString();
|
|
|
|
Rails::log()->warning($text);
|
|
|
|
|
|
|
|
$this->updateAttributes(['status' => "error", 'status_message' => get_class($x) . ': ' . $x->getMessage()]);
|
|
|
|
throw $x;
|
|
|
|
}
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function execute_periodic_maintenance()
|
|
|
|
{
|
|
|
|
if (!empty($this->data->next_run) && $this->data->next_run > time('Y-m-d H:i:s'))
|
|
|
|
return;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$this->update_data(array("step" => "recalculating post count"));
|
|
|
|
Post::recalculate_row_count();
|
|
|
|
$this->update_data(array("step" => "recalculating tag post counts"));
|
|
|
|
Tag::recalculate_post_count();
|
|
|
|
$this->update_data(array("step" => "purging old tags"));
|
|
|
|
Tag::purge_tags();
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$next_run = strtotime('+6 hours');
|
|
|
|
$this->update_data(array("next_run" => date('Y-m-d H:i:s', $next_run), "step" => null));
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
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());
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if (empty($this->data->last_post_id))
|
|
|
|
$this->data->last_post_id = 0;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$post_id = $this->data->last_post_id + 1;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$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);
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$limit = $config['limit'];
|
|
|
|
$interval = $config['interval'];
|
|
|
|
$search_options = [
|
|
|
|
'type' => 'post',
|
|
|
|
'data_search' => true,
|
|
|
|
'services' => $config['servers'],
|
|
|
|
'threshold' => $config['similarity']
|
|
|
|
];
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$post_count = !$limit ? -1 : 0;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
while ($post_count < $limit) {
|
|
|
|
if (!$post = Post::where('id >= ? AND status != "deleted"', $post_id)->order('id ASC')->first()) {
|
|
|
|
break;
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$search_options['source'] = $post;
|
|
|
|
$new_tags = [];
|
|
|
|
$source = null;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$external_posts = SimilarImages::similar_images($search_options)['posts_external'];
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$rating_set = false;
|
|
|
|
foreach ($external_posts as $ep) {
|
|
|
|
if (!$rating_set && $config['set_rating'] && $ep->rating) {
|
|
|
|
$post->rating = $ep->rating;
|
|
|
|
$rating_set = true;
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($config['source'] && !$source && $ep->source) {
|
|
|
|
$source = $ep->source;
|
|
|
|
}
|
|
|
|
$new_tags = array_merge($new_tags, explode(' ', $ep->tags));
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
# Exclude tags.
|
|
|
|
$new_tags = array_diff($new_tags, $config['exclude_tags']);
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($config['merge_tags']) {
|
|
|
|
$new_tags = array_merge($new_tags, $post->tags);
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$new_tags = array_filter(array_unique($new_tags));
|
|
|
|
$post->new_tags = $new_tags;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($source); {
|
|
|
|
$post->source = $source;
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$post->save();
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($limit) {
|
|
|
|
$post_count++;
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
$this->update_data(['last_post_id' => $post->id]);
|
|
|
|
$post_id = $post->id + 1;
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
if ($config['interval']) {
|
|
|
|
sleep($config['interval']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function execute_upload_batch_posts()
|
|
|
|
{
|
|
|
|
$upload = BatchUpload::where("status = 'pending'")->order("id ASC")->first();
|
|
|
|
if (!$upload)
|
|
|
|
return;
|
|
|
|
|
|
|
|
$this->updateAttributes(['data' => ['id' => $upload->id, 'user_id' => $upload->user_id, 'url' => $upload->url]]);
|
|
|
|
$upload->run();
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function execute_approve_tag_alias()
|
|
|
|
{
|
|
|
|
$ta = TagAlias::find($this->data->id);
|
|
|
|
$updater_id = $this->data->updater_id;
|
|
|
|
$updater_ip_addr = $this->data->updater_ip_addr;
|
|
|
|
$ta->approve($updater_id, $updater_ip_addr);
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function execute_approve_tag_implication()
|
|
|
|
{
|
|
|
|
$ti = TagImplication::find($this->data->id);
|
|
|
|
$updater_id = $this->data->updater_id;
|
|
|
|
$updater_ip_addr = $this->data->updater_ip_addr;
|
|
|
|
$ti->approve($updater_id, $updater_ip_addr);
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2014-01-12 13:05:06 +01:00
|
|
|
public function execute_calculate_tag_subscriptions()
|
|
|
|
{
|
2016-07-30 20:45:57 +02:00
|
|
|
if (CONFIG()->tag_subscription_delay) {
|
|
|
|
if (Rails::cache()->read("delay-tag-sub-calc")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Rails::cache()->write("delay-tag-sub-calc", 1, ['expires_in' => CONFIG()->tag_subscription_delay]);
|
2014-01-12 13:05:06 +01:00
|
|
|
}
|
2016-07-30 20:45:57 +02:00
|
|
|
|
2014-01-12 13:05:06 +01:00
|
|
|
TagSubscription::process_all();
|
2016-07-30 20:45:57 +02:00
|
|
|
|
|
|
|
$this->updateAttributes(['data' => ['last_run' => date('Y-m-d H:i:s')]]);
|
2014-01-12 13:05:06 +01:00
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
protected function init()
|
|
|
|
{
|
|
|
|
$this->setData($this->data_as_json ? json_decode($this->data_as_json) : new stdClass());
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
|
2013-10-27 01:06:58 +02:00
|
|
|
public function setData($data)
|
|
|
|
{
|
|
|
|
$this->data_as_json = json_encode($data);
|
|
|
|
$this->data = (object)$data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function update_data($data)
|
|
|
|
{
|
|
|
|
$data = array_merge((array)$this->data, $data);
|
|
|
|
$this->updateAttributes(array('data' => $data));
|
|
|
|
}
|
2016-07-30 07:16:24 +02:00
|
|
|
}
|