1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* AnimeDb package. |
4
|
|
|
* |
5
|
|
|
* @author Peter Gribanov <[email protected]> |
6
|
|
|
* @copyright Copyright (c) 2011, Peter Gribanov |
7
|
|
|
* @license http://opensource.org/licenses/GPL-3.0 GPL v3 |
8
|
|
|
*/ |
9
|
|
|
namespace AnimeDb\Bundle\AniDbFillerBundle\Command; |
10
|
|
|
|
11
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
12
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
13
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
14
|
|
|
use Symfony\Component\Filesystem\Filesystem; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Update list of titles from AniDB.net. |
18
|
|
|
*/ |
19
|
|
|
class UpdateTitlesCommand extends ContainerAwareCommand |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* @var int |
23
|
|
|
*/ |
24
|
|
|
const CACHE_LIFE_TIME = 86400; |
25
|
|
|
|
26
|
|
|
protected function configure() |
27
|
|
|
{ |
28
|
|
|
$this->setName('animedb:update-titles') |
29
|
|
|
->setDescription('Update list of titles from AniDB.net'); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @param InputInterface $input |
34
|
|
|
* @param OutputInterface $output |
35
|
|
|
* |
36
|
|
|
* @return int |
37
|
|
|
*/ |
38
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
39
|
|
|
{ |
40
|
|
|
$now = time(); |
41
|
|
|
$file_csv = $this->getContainer()->getParameter('kernel.cache_dir').'/'. |
42
|
|
|
$this->getContainer()->getParameter('anime_db.ani_db.titles_db'); |
43
|
|
|
|
44
|
|
|
if (!file_exists($file_csv) || filemtime($file_csv) + self::CACHE_LIFE_TIME < $now) { |
45
|
|
|
try { |
46
|
|
|
$file = $this->getOriginDb($output, $now); |
47
|
|
|
} catch (\Exception $e) { |
48
|
|
|
$output->writeln(sprintf('<error>AniDB list titles is not downloaded: %s</error>', $e->getMessage())); |
49
|
|
|
|
50
|
|
|
return 0; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
$output->writeln('Start assembling database'); |
54
|
|
|
|
55
|
|
|
// clear list titles and add unified title |
56
|
|
|
$fp = gzopen($file, 'r'); |
57
|
|
|
$fp_csv = gzopen($file_csv, 'w'); |
58
|
|
|
while (!gzeof($fp)) { |
59
|
|
|
$line = trim(gzgets($fp, 4096)); |
60
|
|
|
// ignore comments |
61
|
|
|
if ($line[0] == '#') { |
62
|
|
|
continue; |
63
|
|
|
} |
64
|
|
|
list($aid, $type, $lang, $title) = explode('|', $line); |
65
|
|
|
$lang = substr($lang, 0, 2); |
66
|
|
|
// ignore not supported locales |
67
|
|
|
if ($lang == 'x-') { |
68
|
|
|
continue; |
69
|
|
|
} |
70
|
|
|
gzwrite($fp_csv, $aid.'|'.$type.'|'.$lang.'|'.$this->getUnifiedTitle($title).'|'.$title."\n"); |
71
|
|
|
} |
72
|
|
|
gzclose($fp); |
73
|
|
|
gzclose($fp_csv); |
74
|
|
|
touch($file, $now); |
75
|
|
|
touch($file_csv, $now); |
76
|
|
|
|
77
|
|
|
$output->writeln('The titles database is updated'); |
78
|
|
|
} else { |
79
|
|
|
$output->writeln('Update is not needed'); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
return 0; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Get original db file. |
87
|
|
|
* |
88
|
|
|
* Download the original db if need and cache it in a system temp dir |
89
|
|
|
* |
90
|
|
|
* @throws \InvalidArgumentException |
91
|
|
|
* @throws \RuntimeException |
92
|
|
|
* |
93
|
|
|
* @param OutputInterface $output |
94
|
|
|
* @param int $now |
95
|
|
|
* |
96
|
|
|
* @return string |
97
|
|
|
*/ |
98
|
|
|
protected function getOriginDb(OutputInterface $output, $now) |
99
|
|
|
{ |
100
|
|
|
$url = $this->getContainer()->getParameter('anime_db.ani_db.import_titles'); |
101
|
|
|
|
102
|
|
|
if (($path = parse_url($url, PHP_URL_PATH)) === false) { |
103
|
|
|
throw new \InvalidArgumentException('Failed parse URL: '.$url); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/* @var Filesystem $fs */ |
107
|
|
|
$fs = $this->getContainer()->get('filesystem'); |
108
|
|
|
$filename = sys_get_temp_dir().'/'.pathinfo($path, PATHINFO_BASENAME); |
109
|
|
|
|
110
|
|
|
if (!$fs->exists($filename) || filemtime($filename) + self::CACHE_LIFE_TIME < $now) { |
111
|
|
|
/* @var $downloader \AnimeDb\Bundle\AppBundle\Service\Downloader */ |
112
|
|
|
$downloader = $this->getContainer()->get('anime_db.downloader'); |
113
|
|
|
$tmp = tempnam(sys_get_temp_dir(), 'ani_db_titles'); |
114
|
|
|
if (!$downloader->download($url, $tmp, true)) { |
115
|
|
|
$fs->remove($tmp); |
116
|
|
|
throw new \RuntimeException('Failed to download the titles database'); |
117
|
|
|
} |
118
|
|
|
$fs->rename($tmp, $filename, true); |
119
|
|
|
$output->writeln('The titles database is loaded'); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return $filename; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @param string $title |
127
|
|
|
* |
128
|
|
|
* @return string |
129
|
|
|
*/ |
130
|
|
View Code Duplication |
protected function getUnifiedTitle($title) |
|
|
|
|
131
|
|
|
{ |
132
|
|
|
$title = mb_strtolower($title, 'utf8'); |
133
|
|
|
$title = preg_replace('/\W+/u', ' ', $title); |
134
|
|
|
|
135
|
|
|
return trim($title); |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.