SyncController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php
  2. namespace app\commands;
  3. use app\models\Descarga;
  4. use yii\console\Controller;
  5. use yii\console\ExitCode;
  6. use yii\db\Query;
  7. use yii\helpers\ArrayHelper;
  8. class SyncController extends Controller {
  9. public $limite = 5;
  10. public $pagina = 1;
  11. public $ciudad = null;
  12. public $estacion = null;
  13. public $fi = null;
  14. public $ff = null;
  15. public $pc = null;
  16. public function options($actionID) {
  17. return [
  18. 'pagina',
  19. 'limite',
  20. 'ciudad',
  21. 'estacion',
  22. 'fi',
  23. 'ff',
  24. 'pc'
  25. ];
  26. }
  27. public function actionIndex() {
  28. if($this->pagina < 1) {
  29. $this->pagina = 1;
  30. }
  31. $ciudades = (new Query())
  32. ->select(["idCiudad"])
  33. ->distinct()
  34. ->from("box")
  35. ->innerJoin("CiudadEstacion", "box.id = {{CiudadEstacion}}.[[idCiudad]]")
  36. ->innerJoin("Estacion", "{{Estacion}}.id = {{CiudadEstacion}}.[[idEstacion]]")
  37. ->andWhere([
  38. "{{CiudadEstacion}}.monitoreable" => true,
  39. "box.activo" => true,
  40. ])
  41. ->andWhere("[[idGrupo]] is not null")
  42. ->limit($this->limite)
  43. ->offset($this->limite * ($this->pagina - 1))
  44. ->orderBy(["idCiudad" => SORT_ASC])
  45. ->column();
  46. return $this->descarga($ciudades);
  47. }
  48. public function descarga($ciudadesIds = []) {
  49. $estados = [
  50. 'AGUASCALIENTES' => 'AGU',
  51. 'BAJA CALIFORNIA' => 'BCN',
  52. 'BAJA CALIFORNIA SUR' => 'BCS',
  53. 'CAMPECHE' => 'CAM',
  54. 'CHIAPAS' => 'CHP',
  55. 'CHIHUAHUA' => 'CHH',
  56. 'CIUDAD DE MÉXICO' => 'CMX',
  57. 'COAHUILA' => 'COA',
  58. 'COLIMA' => 'COL',
  59. 'DURANGO' => 'DUR',
  60. 'GUANAJUATO' => 'GUA',
  61. 'GUERRERO' => 'GRO',
  62. 'HIDALGO' => 'HID',
  63. 'JALISCO' => 'JAL',
  64. 'MEXICO' => 'MEX',
  65. 'MICHOACAN' => 'MIC',
  66. 'MORELOS' => 'MOR',
  67. 'NAYARIT' => 'NAY',
  68. 'NUEVO LEON' => 'NLE',
  69. 'OAXACA' => 'OAX',
  70. 'PUEBLA' => 'PUE',
  71. 'QUERETARO' => 'QUE',
  72. 'QUINTANA ROO' => 'ROO',
  73. 'SAN LUIS POTOSI' => 'SLP',
  74. 'SINALOA' => 'SIN',
  75. 'SONORA' => 'SON',
  76. 'TABASCO' => 'TAB',
  77. 'TAMAULIPAS' => 'TAM',
  78. 'TLAXCALA' => 'TLA',
  79. 'VERACRUZ' => 'VER',
  80. 'YUCATAN' => 'YUC',
  81. 'ZACATECAS' => 'ZAC'
  82. ];
  83. $limite = 500;
  84. $order = SORT_ASC;
  85. $orderUltimo = SORT_DESC; // Siempre tiene que ser el contrario de order
  86. $ciudadEstacion = (new Query())
  87. ->select(["idCiudad", "idEstacion", "clave"])
  88. ->from("box")
  89. ->innerJoin("CiudadEstacion", "box.id = {{CiudadEstacion}}.[[idCiudad]]")
  90. ->innerJoin("Estacion", "{{Estacion}}.id = {{CiudadEstacion}}.[[idEstacion]]")
  91. ->andWhere([
  92. "monitoreable" => true,
  93. "box.activo" => true,
  94. "idCiudad" => $ciudadesIds
  95. ])
  96. ->andWhere("[[idGrupo]] is not null")
  97. ->all();
  98. $idCiudades = ArrayHelper::getColumn($ciudadEstacion, "idCiudad");
  99. $ciudades = (new Query())
  100. ->select(["id", "nombre", "idEstado", "timezone", "tipo"])
  101. ->from("box")
  102. ->where(["id" => $idCiudades])
  103. ->indexBy("id")
  104. ->all();
  105. $idEstaciones = ArrayHelper::getColumn($ciudadEstacion, "idEstacion");
  106. $estaciones = (new Query())
  107. ->select(["id", "clave", "siglas", "frecuencia", "descripcion"])
  108. ->from("Estacion")
  109. ->andWhere(["id" => $idEstaciones])
  110. ->indexBy("clave")
  111. ->all();
  112. while(true) {
  113. foreach($ciudadEstacion as $ce) {
  114. $inicio = time();
  115. $archivos = (new Query())
  116. ->select("hash, box, station, filename, [[timestamp]] at time zone box.timezone as timestamp")
  117. ->from("file")
  118. ->innerJoin("box", "box.id = file.box")
  119. ->andWhere([">=", "[[timestamp]] at time zone box.timezone", '2021-12-01 00:00:00'])
  120. // ->andWhere(["<=", "[[timestamp]] at time zone box.timezone", '2021-10-01 00:00:00'])
  121. ->andWhere([
  122. "box" => $ce["idCiudad"],
  123. "station" => $ce["clave"]
  124. ])
  125. ->limit($limite)
  126. ->orderBy(["timestamp" => $order]);
  127. $ultimo = (new Query())
  128. ->select("fecha")
  129. ->from("Descarga")
  130. ->andWhere([
  131. "ciudad" => $ce["idCiudad"],
  132. "estacion" => $ce["clave"]
  133. ])
  134. ->andWhere([">=", "fecha", '2021-12-01 00:00:00'])
  135. ->orderBy(["fecha" => $orderUltimo])
  136. ->limit(1);
  137. $this->stdout("{Ultimo query: {$ultimo->createCommand()->getRawSql()}\n");
  138. $ultimo = $ultimo->scalar();
  139. $this->stdout("Ultimo: {$ultimo}\n");
  140. if($ultimo) {
  141. if($order === SORT_DESC) {
  142. $archivos->andWhere(["<=", "timestamp", $ultimo]);
  143. } else {
  144. $archivos->andWhere([">=", "timestamp", $ultimo]);
  145. }
  146. }
  147. $this->stdout("Archivos query: {$archivos->createCommand()->getRawSql()}\n");
  148. /*
  149. $sql = $archivos->createCommand()->getRawSql();
  150. $this->stdout("{$sql}\n");
  151. // $this->stdout("ultimo: {$ultimo}\n");
  152. // */
  153. $count = 0;
  154. foreach($archivos->each() as $archivo) {
  155. $modelo = new Descarga();
  156. $modelo->hash = $archivo["hash"];
  157. $modelo->estacion = $archivo["station"];
  158. $modelo->archivo = $archivo["filename"];
  159. $modelo->ciudad = $archivo["box"];
  160. $modelo->pc = null;
  161. $modelo->fecha = $archivo["timestamp"];
  162. $modelo->descargado = false;
  163. $modelo->nombre = basename($archivo["filename"]);
  164. $ciudad = $ciudades[$archivo["box"]];
  165. $estacion = $estaciones[$archivo["station"]];
  166. $fecha = \DateTime::createFromFormat("Y-m-d H:i:s", $archivo["timestamp"]);
  167. $siglas = explode("-", $estacion["siglas"]);
  168. $tipo = "";
  169. $senal = $siglas[0];
  170. if(isset($siglas[1])) {
  171. $tipo = $siglas[1];
  172. }
  173. if($tipo === "") {
  174. if($ciudad["tipo"] === "tv") {
  175. $tipo = "TDT";
  176. } elseif ($ciudad["tipo"] === "radio") {
  177. $tipo = "FM";
  178. } else {
  179. $tipo = "AM";
  180. }
  181. }
  182. $nombreCiudad = $ciudad["idEstado"];
  183. if($tipo === "AM") {
  184. $desc = explode(",", $estacion["descripcion"]);
  185. $nombreCiudad = $estacion["descripcion"];
  186. if(isset($desc[1])) {
  187. $nombreCiudad = $desc[1];
  188. }
  189. }
  190. if(isset($estados[$nombreCiudad])) {
  191. $nombreCiudad = $estados[$nombreCiudad];
  192. }
  193. $nombreCiudad = str_replace(" ", "_", trim($nombreCiudad));
  194. $y = $fecha->format("Y");
  195. $m = $fecha->format("m");
  196. $d = $fecha->format("d");
  197. $modelo->ruta = "{$y}/{$tipo}/{$nombreCiudad}/{$senal}/{$m}/{$d}";
  198. try {
  199. if(!$modelo->save()) {
  200. $errores = json_encode($modelo->getFirstErrors());
  201. $this->stdout("Error al guardar {$modelo->hash} {$errores}\n");
  202. }
  203. } catch(\Exception $e) {
  204. $this->stdout("Error al guardar {$modelo->hash}\n");
  205. }
  206. $count++;
  207. }
  208. // */
  209. $seg = time() - $inicio;
  210. $this->stdout("[{$ce["idCiudad"]}][{$ce["clave"]}] {$count} registros insertados en {$seg} segundos\n");
  211. }
  212. $this->stdout("Durmiendo 10 segundos...\n");
  213. sleep(10);
  214. }
  215. return ExitCode::OK;
  216. }
  217. public function actionPorEstacion() {
  218. $estados = [
  219. 'AGUASCALIENTES' => 'AGU',
  220. 'BAJA CALIFORNIA' => 'BCN',
  221. 'BAJA CALIFORNIA SUR' => 'BCS',
  222. 'CAMPECHE' => 'CAM',
  223. 'CHIAPAS' => 'CHP',
  224. 'CHIHUAHUA' => 'CHH',
  225. 'CIUDAD DE MÉXICO' => 'CMX',
  226. 'COAHUILA' => 'COA',
  227. 'COLIMA' => 'COL',
  228. 'DURANGO' => 'DUR',
  229. 'GUANAJUATO' => 'GUA',
  230. 'GUERRERO' => 'GRO',
  231. 'HIDALGO' => 'HID',
  232. 'JALISCO' => 'JAL',
  233. 'MEXICO' => 'MEX',
  234. 'MICHOACAN' => 'MIC',
  235. 'MORELOS' => 'MOR',
  236. 'NAYARIT' => 'NAY',
  237. 'NUEVO LEON' => 'NLE',
  238. 'OAXACA' => 'OAX',
  239. 'PUEBLA' => 'PUE',
  240. 'QUERETARO' => 'QUE',
  241. 'QUINTANA ROO' => 'ROO',
  242. 'SAN LUIS POTOSI' => 'SLP',
  243. 'SINALOA' => 'SIN',
  244. 'SONORA' => 'SON',
  245. 'TABASCO' => 'TAB',
  246. 'TAMAULIPAS' => 'TAM',
  247. 'TLAXCALA' => 'TLA',
  248. 'VERACRUZ' => 'VER',
  249. 'YUCATAN' => 'YUC',
  250. 'ZACATECAS' => 'ZAC'
  251. ];
  252. $order = SORT_ASC;
  253. $_estaciones = explode(",", $this->estacion);
  254. $ciudades = (new Query())
  255. ->select(["id", "nombre", "idEstado", "timezone", "tipo"])
  256. ->from("box")
  257. ->where(["id" => $this->ciudad])
  258. ->indexBy("id")
  259. ->all();
  260. $estaciones = (new Query())
  261. ->select(["id", "clave", "siglas", "frecuencia", "descripcion"])
  262. ->from("Estacion")
  263. ->andWhere(["clave" => $_estaciones])
  264. ->indexBy("clave")
  265. ->all();
  266. $inicio = time();
  267. $archivos = (new Query())
  268. ->select("hash, box, station, filename, [[timestamp]] at time zone box.timezone as timestamp")
  269. ->from("file")
  270. ->innerJoin("box", "box.id = file.box")
  271. ->andWhere([">=", "[[timestamp]] at time zone box.timezone", $this->fi])
  272. ->andWhere(["<=", "[[timestamp]] at time zone box.timezone", $this->ff])
  273. ->andWhere([
  274. "box" => $this->ciudad,
  275. "station" => $_estaciones
  276. ])
  277. ->orderBy(["timestamp" => $order]);
  278. $count = 0;
  279. foreach($archivos->each() as $archivo) {
  280. $modelo = new Descarga();
  281. $modelo->hash = $archivo["hash"];
  282. $modelo->estacion = $archivo["station"];
  283. $modelo->archivo = $archivo["filename"];
  284. $modelo->ciudad = $archivo["box"];
  285. $modelo->pc = null;
  286. if($this->pc !== null) {
  287. $modelo->pc = $this->pc;
  288. }
  289. $modelo->fecha = $archivo["timestamp"];
  290. $modelo->descargado = false;
  291. $modelo->nombre = basename($archivo["filename"]);
  292. $ciudad = $ciudades[$archivo["box"]];
  293. $estacion = $estaciones[$archivo["station"]];
  294. $fecha = \DateTime::createFromFormat("Y-m-d H:i:s", $archivo["timestamp"]);
  295. $siglas = explode("-", $estacion["siglas"]);
  296. $tipo = "";
  297. $senal = $siglas[0];
  298. if(isset($siglas[1])) {
  299. $tipo = $siglas[1];
  300. }
  301. if($tipo === "") {
  302. if($ciudad["tipo"] === "tv") {
  303. $tipo = "TDT";
  304. } elseif ($ciudad["tipo"] === "radio") {
  305. $tipo = "FM";
  306. } else {
  307. $tipo = "AM";
  308. }
  309. }
  310. $nombreCiudad = $ciudad["idEstado"];
  311. if($tipo === "AM") {
  312. $desc = explode(",", $estacion["descripcion"]);
  313. $nombreCiudad = $estacion["descripcion"];
  314. if(isset($desc[1])) {
  315. $nombreCiudad = $desc[1];
  316. }
  317. }
  318. if(isset($estados[$nombreCiudad])) {
  319. $nombreCiudad = $estados[$nombreCiudad];
  320. }
  321. $nombreCiudad = str_replace(" ", "_", trim($nombreCiudad));
  322. $y = $fecha->format("Y");
  323. $m = $fecha->format("m");
  324. $d = $fecha->format("d");
  325. $modelo->ruta = "{$y}/{$tipo}/{$nombreCiudad}/{$senal}/{$m}/{$d}";
  326. try {
  327. if(!$modelo->save()) {
  328. $errores = json_encode($modelo->getFirstErrors());
  329. $this->stdout("Error al guardar {$modelo->hash} {$errores}\n");
  330. }
  331. $this->stdout("{$modelo->hash} {$modelo->estacion} {$modelo->archivo}\n");
  332. } catch(\Exception $e) {
  333. $this->stdout("Error al guardar {$modelo->hash}\n");
  334. }
  335. $count++;
  336. }
  337. $vuelta = $inicio - time();
  338. $this->stdout("Vuelta: {$vuelta}\n");
  339. return ExitCode::OK;
  340. }
  341. }