2018-12-21 12:45:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\MatsuriHime;
|
|
|
|
|
|
|
|
use Guzzle;
|
|
|
|
use Carbon\Carbon;
|
|
|
|
use DB;
|
|
|
|
use Cache;
|
|
|
|
use App\Rank;
|
|
|
|
|
|
|
|
class Election
|
|
|
|
{
|
2019-01-02 19:18:53 +00:00
|
|
|
public const nuke_threshold = 2500;
|
2018-12-21 12:45:08 +00:00
|
|
|
public static function getDramaNames() {
|
|
|
|
if(!Cache::has('drama_names')) {
|
|
|
|
$response = Guzzle::get("https://api.matsurihi.me/mltd/v1/election")->getBody()->getContents();
|
|
|
|
$dramas = json_decode($response);
|
|
|
|
$dramas = $dramas->dramas;
|
|
|
|
$drama_list = [];
|
|
|
|
foreach($dramas as $drama) {
|
|
|
|
$drama_roles = [];
|
|
|
|
foreach($drama->roles as $role) {
|
|
|
|
$drama_list[$role->name] = $drama->name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Cache::forever('drama_names',$drama_list);
|
|
|
|
}
|
|
|
|
return Cache::get('drama_names');
|
|
|
|
}
|
|
|
|
public static function getRanking() {
|
|
|
|
$response = Guzzle::get("https://api.matsurihi.me/mltd/v1/election/current");
|
|
|
|
return json_decode($response->getBody()->getContents());
|
|
|
|
}
|
|
|
|
public static function createSnapshot() {
|
|
|
|
$rankings = Election::getRanking();
|
|
|
|
$hasSnapshot = true;
|
|
|
|
DB::beginTransaction();
|
|
|
|
foreach($rankings as $ladder) {
|
2019-01-02 19:18:53 +00:00
|
|
|
$existingSnapshot = Cache::get('snap_time_'.$ladder->name);
|
|
|
|
if(!isset($existingSnapshot) || $existingSnapshot->lt(Carbon::parse($ladder->summaryTime)) ) {
|
|
|
|
$hasSnapshot = false;
|
2018-12-22 03:47:09 +00:00
|
|
|
$idols = [];
|
2018-12-21 12:45:08 +00:00
|
|
|
foreach($ladder->data[0] as $data) {
|
|
|
|
$rank = new Rank();
|
|
|
|
$rank->role = $ladder->name;
|
|
|
|
$rank->character = $data->idol_name;
|
2018-12-22 03:47:09 +00:00
|
|
|
$idols[] = $data->idol_name;
|
2018-12-21 12:45:08 +00:00
|
|
|
$rank->score = $data->score;
|
|
|
|
$rank->summary_time = Carbon::parse($ladder->summaryTime);
|
|
|
|
$rank->save();
|
|
|
|
}
|
2018-12-22 03:47:09 +00:00
|
|
|
$remnant_idols = Rank::where('role',$ladder->name)->whereNotIn('character',$idols)->orderBy('summary_time','desc')->get()->groupBy('character');
|
|
|
|
foreach($remnant_idols as $remnant_char => $remnant) {
|
|
|
|
$rank = new Rank();
|
|
|
|
$rank->role = $ladder->name;
|
|
|
|
$rank->character = $remnant_char;
|
|
|
|
$rank->score = $remnant->first()->score;
|
|
|
|
$rank->summary_time = Carbon::parse($ladder->summaryTime);
|
|
|
|
$rank->save();
|
|
|
|
}
|
2019-01-02 19:18:53 +00:00
|
|
|
Cache::forever('snap_time_'.$ladder->name,Carbon::parse($ladder->summaryTime));
|
|
|
|
Cache::forever('snap_time',Carbon::parse($ladder->summaryTime));
|
2018-12-21 12:45:08 +00:00
|
|
|
} else {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DB::commit();
|
2019-01-02 19:18:53 +00:00
|
|
|
if(!$hasSnapshot) {
|
|
|
|
$snap_time = Cache::get('snap_time');
|
|
|
|
$end_date = $snap_time->toDateTimeString();
|
|
|
|
$start_date = $snap_time->subMinutes(24*60)->toDateTimeString();
|
|
|
|
Election::generateChartPointsDate($start_date,$end_date);
|
|
|
|
Election::incrementNukeData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static function generateChartPointsDate($start_date,$end_date) {
|
|
|
|
if(Cache::has('timepoints_'.$start_date.'-'.$end_date)) return $start_date.'-'.$end_date;
|
|
|
|
$ranks = Rank::where('summary_time','>=',$start_date)->where('summary_time','<=',$end_date)->orderBy('summary_time')->get();
|
|
|
|
$timepoints = $ranks->pluck('summary_time')->unique();
|
|
|
|
$ranks = $ranks->groupBy('role');
|
|
|
|
Cache::forever('timepoints_'.$start_date.'-'.$end_date,$timepoints);
|
|
|
|
$timelabels = [];
|
|
|
|
foreach($timepoints as $timepoint) {
|
|
|
|
$timelabels[] = $timepoint->toDateTimeString();
|
|
|
|
}
|
|
|
|
$timelabels = collect($timelabels);
|
|
|
|
Cache::forever('timelabels_'.$start_date.'-'.$end_date,$timelabels);
|
|
|
|
$timepoints_count = $timepoints->count();
|
|
|
|
$globalDataPoints = [];
|
|
|
|
foreach($ranks as $roleName => $roleRank) {
|
|
|
|
$dataPoints = [];
|
|
|
|
$ladder = $roleRank->groupBy('character')->sortByDesc(function($rank,$key) {
|
|
|
|
return $rank->last()->score;
|
|
|
|
});
|
|
|
|
foreach($ladder as $character => $rank) {
|
|
|
|
$standing = $rank->pluck('score')->take($timepoints_count)->values();
|
|
|
|
$standing = $standing->pad(-$timepoints_count,(int)0)->values();
|
|
|
|
$dataPoints[$character] = $standing;
|
|
|
|
if(!array_key_exists($character,$globalDataPoints)) $globalDataPoints[$character] = $standing->values();
|
|
|
|
else {
|
|
|
|
$scores = $standing->values();
|
|
|
|
\Log::error($globalDataPoints[$character]->count().' vs '.$standing->count().' the jury is '.$timepoints_count);
|
|
|
|
$globalDataPoints[$character]->transform(function($item,$index) use ($scores) {
|
|
|
|
return $item+$scores[$index];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$dataPoints = collect($dataPoints)->take(10);
|
|
|
|
Cache::forever('data_'.$roleName.'_'.$start_date.'-'.$end_date,$dataPoints);
|
|
|
|
}
|
|
|
|
$globalDataPoints = collect($globalDataPoints);
|
|
|
|
$globalDataPoints = $globalDataPoints->sortByDesc(function($item, $key) {
|
|
|
|
return $item->last();
|
|
|
|
});
|
|
|
|
$globalDataPoints = $globalDataPoints->take(10);
|
|
|
|
Cache::forever('data_global_'.$start_date.'-'.$end_date,$globalDataPoints);
|
|
|
|
return $start_date.'-'.$end_date;
|
2018-12-22 03:47:09 +00:00
|
|
|
}
|
|
|
|
public static function generateChartPointsNew() {
|
2019-01-02 19:18:53 +00:00
|
|
|
$ranks = Rank::orderBy('summary_time')->get();
|
|
|
|
$timepoints = $ranks->pluck('summary_time')->unique();
|
|
|
|
$ranks = $ranks->groupBy('role');
|
2018-12-22 03:47:09 +00:00
|
|
|
Cache::forever('timepoints',$timepoints);
|
2019-01-02 19:18:53 +00:00
|
|
|
$timelabels = [];
|
|
|
|
foreach($timepoints as $timepoint) {
|
|
|
|
$timelabels[] = $timepoint->toDateTimeString();
|
|
|
|
}
|
|
|
|
$timelabels = collect($timelabels);
|
|
|
|
Cache::forever('timelabels',$timelabels);
|
|
|
|
$timepoints_count = $timepoints->count();
|
|
|
|
$globalDataPoints = [];
|
2018-12-22 03:47:09 +00:00
|
|
|
foreach($ranks as $roleName => $roleRank) {
|
|
|
|
$dataPoints = [];
|
2019-01-02 19:18:53 +00:00
|
|
|
$ladder = $roleRank->groupBy('character')->sortByDesc(function($rank,$key) {
|
|
|
|
return $rank->last()->score;
|
|
|
|
});
|
2018-12-22 03:47:09 +00:00
|
|
|
foreach($ladder as $character => $rank) {
|
2019-01-02 19:18:53 +00:00
|
|
|
$standing = $rank->pluck('score');
|
|
|
|
$standing = $standing->pad(-$timepoints_count,(int)0);
|
|
|
|
$dataPoints[$character] = $standing;
|
|
|
|
if(!array_key_exists($character,$globalDataPoints)) $globalDataPoints[$character] = $standing->pluck('score');
|
|
|
|
else {
|
|
|
|
$scores = $standing->pluck('score');
|
|
|
|
$globalDataPoints[$character]->transform(function($item,$index) use ($scores) {
|
|
|
|
return $item+$scores[$index];
|
|
|
|
});
|
|
|
|
}
|
2018-12-22 03:47:09 +00:00
|
|
|
}
|
2019-01-02 19:18:53 +00:00
|
|
|
$dataPoints = collect($dataPoints)->take(10);
|
2018-12-22 03:47:09 +00:00
|
|
|
Cache::forever('data_'.$roleName,$dataPoints);
|
|
|
|
}
|
2019-01-02 19:18:53 +00:00
|
|
|
$globalDataPoints = collect($globalDataPoints);
|
|
|
|
$globalDataPoints = $globalDataPoints->sortByDesc(function($item, $key) {
|
|
|
|
return $item->last();
|
|
|
|
});
|
|
|
|
$globalDataPoints = $globalDataPoints->take(10);
|
|
|
|
Cache::forever('data_global',$globalDataPoints);
|
2018-12-22 03:47:09 +00:00
|
|
|
}
|
2019-01-02 19:18:53 +00:00
|
|
|
public static function incrementNukeData() {
|
|
|
|
$nukes = Cache::get('nukes');
|
|
|
|
$dramaNames = Election::getDramaNames();
|
|
|
|
$ranks = collect(Cache::get('drama_names'))->keys();
|
|
|
|
$firstPoint = Cache::get('snap_time');
|
|
|
|
foreach($ranks as $role) {
|
|
|
|
$ladder = Rank::where('role',$role)->orderBy('summary_time','desc')->get()->groupBy('character')->take(2);
|
|
|
|
foreach($ladder as $character => $points) {
|
|
|
|
$future_point = $points[0];
|
|
|
|
$point = $points[1] ?? null;
|
|
|
|
$future_point_score = $future_point->score;
|
|
|
|
$point_score = 0;
|
|
|
|
if($point) {
|
|
|
|
$point_score = $point->score;
|
|
|
|
if($future_point_score - $point_score >= Election::nuke_threshold) {
|
|
|
|
\Log::error($role.$character.$point->summary_time);
|
|
|
|
$nuke = [
|
|
|
|
'code' => $role.$character.$point->summary_time,
|
|
|
|
'drama' => $dramaNames[$role],
|
|
|
|
'role' => $role,
|
|
|
|
'character' => $character,
|
|
|
|
'nuke_time_start' => $point->summary_time,
|
|
|
|
'nuke_time_end' => $future_point->summary_time,
|
|
|
|
'nuke_pts' => $future_point_score - $point_score,
|
|
|
|
];
|
|
|
|
$nukes[] = $nuke;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$collect = collect($nukes)->sortBy('nuke_time_start')->reverse();
|
|
|
|
Cache::forever('nukes',$collect);
|
|
|
|
}
|
|
|
|
public static function generateNukeData() {
|
|
|
|
$dramaNames = Election::getDramaNames();
|
|
|
|
$nukes = [];
|
|
|
|
$ranks = Rank::orderBy('summary_time')->get()->groupBy('role');
|
|
|
|
$firstPoint = $ranks->first()->first()->summary_time;
|
|
|
|
foreach($ranks as $role => $ladder) {
|
|
|
|
$ladder = $ladder->groupBy('character');
|
|
|
|
foreach($ladder as $character => $points) {
|
|
|
|
$count = $points->count();
|
|
|
|
foreach($points as $index => $future_point) {
|
|
|
|
$point = null;
|
|
|
|
if(($index-1) >= 0) $point = $points[$index-1];
|
|
|
|
if(isset($future_point)) {
|
|
|
|
$future_point_score = $future_point->score;
|
|
|
|
$point_score = $point->score ?? 0;
|
|
|
|
if($future_point_score - $point_score >= Election::nuke_threshold && !$future_point->summary_time->eq($firstPoint)) {
|
|
|
|
\Log::error($role.$character.($point ? $point->summary_time : $future_point->summary_time->subMinutes(5)));
|
|
|
|
$nuke = [
|
|
|
|
'code' => $role.$character.$future_point->summary_time,
|
|
|
|
'role' => $role,
|
|
|
|
'drama' => $dramaNames[$role],
|
|
|
|
'character' => $character,
|
|
|
|
'nuke_time_start' => ($point ? $point->summary_time : $future_point->summary_time->subMinutes(5)),
|
|
|
|
'nuke_time_end' => $future_point->summary_time,
|
|
|
|
'nuke_pts' => $future_point_score - $point_score,
|
|
|
|
];
|
|
|
|
$nukes[] = $nuke;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Cache::forever('nukes',collect($nukes)->sortBy('nuke_time_start')->reverse());
|
2018-12-21 12:45:08 +00:00
|
|
|
}
|
|
|
|
}
|