diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Console/Commands/ScrapeFile.php | 2 | ||||
-rw-r--r-- | app/Console/Commands/ScrapeUrlFile.php | 71 | ||||
-rw-r--r-- | app/Console/Commands/ScrapeYoutube.php | 13 | ||||
-rw-r--r-- | app/Console/Commands/SyncVideos.php | 98 | ||||
-rw-r--r-- | app/Console/Commands/TestTor.php | 65 | ||||
-rw-r--r-- | app/Rugby/Concerns/Matchable.php | 93 | ||||
-rw-r--r-- | app/Rugby/Model/Match.php | 25 | ||||
-rw-r--r-- | app/Rugby/Model/Team.php | 16 | ||||
-rw-r--r-- | app/Rugby/Model/Tournament.php | 20 | ||||
-rw-r--r-- | app/Rugby/Model/Video.php | 34 | ||||
-rw-r--r-- | app/Youtube/Service.php | 21 |
11 files changed, 441 insertions, 17 deletions
diff --git a/app/Console/Commands/ScrapeFile.php b/app/Console/Commands/ScrapeFile.php index 4cfef90..45beda9 100644 --- a/app/Console/Commands/ScrapeFile.php +++ b/app/Console/Commands/ScrapeFile.php @@ -49,7 +49,7 @@ class ScrapeFile extends Command $raw_data = Storage::disk('local')->get($filename); - $service = new Service(new SixnationsrugbyAdapter($raw_data, 'Six Nations')); + $service = new Service(new SixnationsrugbyAdapter($raw_data, 'Six Nations ' . explode('-', explode('.txt', $filename)[0])[1])); $service->save(); diff --git a/app/Console/Commands/ScrapeUrlFile.php b/app/Console/Commands/ScrapeUrlFile.php new file mode 100644 index 0000000..f4f114b --- /dev/null +++ b/app/Console/Commands/ScrapeUrlFile.php @@ -0,0 +1,71 @@ +<?php + +namespace App\Console\Commands; + +use App\Rugby\Model\Video; +use App\Youtube\Service; +use Illuminate\Console\Command; +use Illuminate\Support\Facades\Storage; + +class ScrapeUrlFile extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'scrape:urls { filename } { format }'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Scrape a youtube for videos'; + + /** + * Create a new command instance. + * + * @return void + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $filename = $this->argument('filename'); + $format = $this->argument('format'); + + $urls = include Storage::disk('local')->path($filename); + + foreach ($urls as $url) { + $service = new Service($url, $this->output); + + if ($format == 'video') { + $service->downloadVideo('video'); + } elseif ($format == 'audio') { + $service->downloadAudio('audio'); + } + + $video_model = Video::create( + [ + 'path' => $service->getFullPath() + ] + ); + + $this->info('Download of ' . $service->getTitle() . ' complete!'); + } + + + + return Command::SUCCESS; + } + +} diff --git a/app/Console/Commands/ScrapeYoutube.php b/app/Console/Commands/ScrapeYoutube.php index ce64d3f..de620d4 100644 --- a/app/Console/Commands/ScrapeYoutube.php +++ b/app/Console/Commands/ScrapeYoutube.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Rugby\Model\Video; use App\Youtube\Service; use Illuminate\Console\Command; @@ -44,12 +45,18 @@ class ScrapeYoutube extends Command $service = new Service($url, $this->output); if ($format == 'video') { - $video = $service->downloadVideo('video'); + $service->downloadVideo('video'); } elseif ($format == 'audio') { - $video = $service->downloadAudio('audio'); + $service->downloadAudio('audio'); } - $this->info('Download of ' . $video->getTitle() . ' complete!'); + $video_model = Video::create( + [ + 'path' => $service->getFullPath() + ] + ); + + $this->info('Download of ' . $service->getTitle() . ' complete!'); return Command::SUCCESS; } diff --git a/app/Console/Commands/SyncVideos.php b/app/Console/Commands/SyncVideos.php new file mode 100644 index 0000000..d29436d --- /dev/null +++ b/app/Console/Commands/SyncVideos.php @@ -0,0 +1,98 @@ +<?php + +namespace App\Console\Commands; + +use App\Rugby\Model; +use App\Youtube\Service; +use Illuminate\Console\Command; +use Illuminate\Support\Facades\Storage; + +class SyncVideos extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'sync:videos'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Sync downloaded videos with existing matches'; + + /** + * Create a new command instance. + * + * @return void + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $videos = Model\Video::whereNull('match_id')->get(); + + foreach ($videos as $video) { + $filename = $video->getFilename(); + + $tournaments = Model\Tournament::all()->filter( + function ($object) use ($filename) { + return $object->isMatch($filename); + } + ); + + $tournament_ids = $tournaments->pluck('id'); + + $teams = Model\Team::all()->filter( + function ($object) use ($filename) { + return $object->isMatch($filename); + } + ); + + $team_ids = $teams->pluck('name')->toArray(); + + $matches = $tournaments->first()->matches; + + foreach ($matches as $match) { + if (in_array($match->homeTeam()->first()->name, $team_ids)) { + if (in_array($match->awayTeam()->first()->name, $team_ids)) { + $match->videos()->save($video); + Storage::disk('local')->move( + 'youtube/video/' . $video->getFilename(), + 'public/matches/' . $video->getFilename() + ); + } + } + } + } + + // $service = new Service($url, $this->output); + // + // if ($format == 'video') { + // $service->downloadVideo('video'); + // } elseif ($format == 'audio') { + // $service->downloadAudio('audio'); + // } + // + // $video_model = Video::create( + // [ + // 'path' => $service->getFullPath() + // ] + // ); + // + // $this->info('Download of ' . $service->getTitle() . ' complete!'); + + return Command::SUCCESS; + } + +} diff --git a/app/Console/Commands/TestTor.php b/app/Console/Commands/TestTor.php new file mode 100644 index 0000000..87f0050 --- /dev/null +++ b/app/Console/Commands/TestTor.php @@ -0,0 +1,65 @@ +<?php + +namespace App\Console\Commands; + +use Illuminate\Console\Command; +use Illuminate\Support\Facades\Http; + +class TestTor extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'test:tor { onion }'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Testing tor'; + + /** + * Create a new command instance. + * + * @return void + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $url = $this->argument('onion'); + + $response = Http::get($url); + dd($response->body()); + + // $url = 'http://jhiwjjlqpyawmpjx.onion/'; // Note the addition of a semicolon. + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:9150"); // Note the address here is just `IP:port`, not an HTTP URL. + curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); // Note use of `CURLPROXY_SOCKS5_HOSTNAME`. + $this->info("about to run"); + $output = curl_exec($ch); + $this->info("run"); + + $curl_error = curl_error($ch); + curl_close($ch); + + print_r($output); + print_r($curl_error); + + return Command::SUCCESS; + } + +} diff --git a/app/Rugby/Concerns/Matchable.php b/app/Rugby/Concerns/Matchable.php new file mode 100644 index 0000000..b0c512c --- /dev/null +++ b/app/Rugby/Concerns/Matchable.php @@ -0,0 +1,93 @@ +<?php + +namespace App\Rugby\Concerns; + +trait Matchable +{ + public function matchableFilters() + { + + } + + public function isMatch(string $search): bool + { + $filters = $this->matchableFilters(); + + if (is_array($filters)) { + $filters = collect($filters); + } + + foreach ($filters as $filter) { + $match = $this->matchArray($filter[1], explode(' ', $search), $filter[0]); + + if (!$match) { + return false; + } + } + + return true; + } + + public function matchString(string $needle, string $type, string $hay): bool + { + if ($type == 'date') { + if (!$this->isDate($needle)) { + dd('Matchable `' . $hay . '` is not a date'); + }; + + if (!$this->isDate($hay)) { + return false; + }; + + return $this->getYear($hay) == $this->getYear($needle); + } + + return $hay == $needle; + } + + public function matchArray(string $needle, array $haystack, string $type): bool + { + foreach ($haystack as $hay) { + $result = $this->matchString($needle, $type, $hay); + + if ($result) { + return true; + } + } + + return false; + } + + public function isDate(string $value): bool + { + $patterns = [ + "/\d{2}\-\d{2}\-\d{4}/", + "/\d{2}\_\d{2}\_\d{4}/", + "/\d{2}\/\d{2}\/\d{4}/", + "/\d{4}/", + ]; + + foreach ($patterns as $pattern) { + if (preg_match($pattern, $value, $matches)) { + return true; + } + } + + return false; + } + + public function getYear(string $value): string + { + $patterns = [ + "/\d{4}/" + ]; + + foreach ($patterns as $pattern) { + if (preg_match($pattern, $value, $matches)) { + return $matches[0]; + } + } + + return false; + } +} diff --git a/app/Rugby/Model/Match.php b/app/Rugby/Model/Match.php index 5447ef5..58a3dd9 100644 --- a/app/Rugby/Model/Match.php +++ b/app/Rugby/Model/Match.php @@ -2,19 +2,13 @@ namespace App\Rugby\Model; -use App\Rugby\Model\Team; -use App\Rugby\Model\Tournament; -use App\Rugby\Model\Venue; - use Illuminate\Database\Eloquent\Model; class Match extends Model { protected $table = 'matches'; - protected $casts = ['date' => 'datetime:Y-m-d']; - - protected $fillable = ['score', 'half_score', 'referee', 'date']; + protected $fillable = ['score', 'half_score', 'referee', 'date']; public function teams() { @@ -42,6 +36,17 @@ class Match extends Model return (new \Carbon\Carbon($this->date))->format('M d Y'); } + public function getVideoUrl() + { + $video = $this->videos()->first(); + + if (! $video) { + return ''; + } + + return $video->getUrl(); + } + public function homeTeam() { return $this->teams()->wherePivot('is_home', '=', true); @@ -56,4 +61,10 @@ class Match extends Model { return $this->belongsToMany(Tournament::class, 'match_tournament'); } + + public function videos() + { + return $this->hasMany(Video::class, 'match_id'); + } + } diff --git a/app/Rugby/Model/Team.php b/app/Rugby/Model/Team.php index 2582f33..2dbfea6 100644 --- a/app/Rugby/Model/Team.php +++ b/app/Rugby/Model/Team.php @@ -2,12 +2,15 @@ namespace App\Rugby\Model; +use App\Rugby\Concerns\Matchable; use Illuminate\Database\Eloquent\Model; use App\Rugby\Model\Match; class Team extends Model { + use Matchable; + protected $table = 'teams'; protected $fillable = ['name']; @@ -31,4 +34,17 @@ class Team extends Model { return $this->name ?: ''; } + + public function matchableFilters() + { + $name_parts = collect(explode(' ', $this->name)); + + $out = $name_parts->map( + function ($value) { + return ['string', $value]; + } + ); + + return $out; + } } diff --git a/app/Rugby/Model/Tournament.php b/app/Rugby/Model/Tournament.php index 64d9a45..3ab6352 100644 --- a/app/Rugby/Model/Tournament.php +++ b/app/Rugby/Model/Tournament.php @@ -2,16 +2,36 @@ namespace App\Rugby\Model; +use App\Rugby\Concerns\Matchable; use App\Rugby\Model\Match; use Illuminate\Database\Eloquent\Model; class Tournament extends Model { + use Matchable; + protected $table = 'tournaments'; protected $fillable = ['name']; + public function matchableFilters() + { + $name_parts = collect(explode(' ', $this->name)); + + $out = $name_parts->map( + function ($value) { + if ($this->isDate($value)) { + return ['date', $value]; + } + + return ['string', $value]; + } + ); + + return $out; + } + public function matches() { return $this->belongsToMany(Match::class); diff --git a/app/Rugby/Model/Video.php b/app/Rugby/Model/Video.php new file mode 100644 index 0000000..2182b65 --- /dev/null +++ b/app/Rugby/Model/Video.php @@ -0,0 +1,34 @@ +<?php + +namespace App\Rugby\Model; + +use App\Rugby\Model\Match; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Storage; + +class Video extends Model +{ + protected $table = 'videos'; + protected $casts = ['date' => 'datetime:Y-m-d']; + protected $fillable = ['path']; + + public function match() + { + return $this->belongsTo(Match::class); + } + + public function getFilename(): string + { + $parts = explode('/', $this->path); + + return $parts[count($parts) - 1]; + } + + public function getUrl(): string + { + return asset('storage/matches/' . $this->getFilename()); + // return Storage::disk('local')->url( + // 'matches/' . $this->getFilename() + // ); + } +} diff --git a/app/Youtube/Service.php b/app/Youtube/Service.php index 090020e..862a27a 100644 --- a/app/Youtube/Service.php +++ b/app/Youtube/Service.php @@ -15,6 +15,7 @@ class Service protected $url; protected $progressBar; protected $running = false; + protected $video; public function __construct(string $url, $output = null) { @@ -37,15 +38,13 @@ class Service public function downloadVideo(string $path) { $this->path = $path; - - return $this->download($this->getVideoOptions()); + $this->download($this->getVideoOptions()); } public function downloadAudio(string $path) { $this->path = $path; - - return $this->download($thjis->getAudioOptions()); + $this->download($thjis->getAudioOptions()); } protected function download(array $options) @@ -81,7 +80,7 @@ class Service 'youtube/video/' . $video->getFilename() ); - return $video; + $this->video = $video; // $video->getFile(); // \SplFileInfo instance of downloaded file } catch (NotFoundException $e) { @@ -99,6 +98,16 @@ class Service } } + public function getTitle(): string + { + return $this->video->getTitle(); + } + + public function getFullPath(): string + { + return $this->getStoragePath() . '/' . $this->video->getFilename(); + } + protected function formatBytes(string $bytes) { $units = [ @@ -134,7 +143,7 @@ class Service return [ 'prefer-free-formats' => true, 'no-overwrites' => true, - // 'skip-download' => true + 'skip-download' => true ]; } |