]> _ Git - tortuga-home.git/commitdiff
.
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 25 Mar 2026 10:24:13 +0000 (11:24 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 25 Mar 2026 10:24:13 +0000 (11:24 +0100)
14 files changed:
.idea/sqldialects.xml
.idea/workspace.xml
scripts/freeboxapi.php [deleted file]
scripts/freeboxchannel.php [deleted file]
scripts/homeconnect.php [deleted file]
scripts/lib/freebox.php [deleted file]
scripts/lib/ical.php [deleted file]
scripts/lib/klarstein.php [deleted file]
scripts/lib/kodi.php [deleted file]
scripts/lib/lib.php
scripts/lib/omxplay.php [deleted file]
scripts/lib/scenes.php
scripts/lib/switchbot.php [deleted file]
scripts/lib/tmdb.php [deleted file]

index 69d7fa5f43d14ae37d14c07c29b0b6cd3cf5b1a1..56782cab2a40d3f1192d91ef10f76f0e8f452171 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="SqlDialectMappings">
-    <file url="file://$PROJECT_DIR$/scripts/lib/kodi.php" dialect="GenericSQL" />
     <file url="PROJECT" dialect="MySQL" />
   </component>
 </project>
\ No newline at end of file
index d9cac2ef4f473431d708205ccb246f820d9d3c76..414ff1415ab847289007429edca7b10750dd673a 100644 (file)
@@ -5,10 +5,17 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" id="352ce63a-b52a-41a2-979b-becda7920939" name="Default" comment=".">
-      <change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.local.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/sqldialects.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sqldialects.xml" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/js/home.js" beforeDir="false" afterPath="$PROJECT_DIR$/js/home.js" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/scripts/lib/weatherstation.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/weatherstation.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/freebox.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/ical.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/klarstein.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/kodi.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/lib.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/lib.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/omxplay.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/scenes.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/scenes.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/switchbot.php" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/tmdb.php" beforeDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
       <workItem from="1772365933816" duration="4000" />
       <workItem from="1772370387714" duration="7090000" />
       <workItem from="1773390371781" duration="506000" />
-      <workItem from="1774028822942" duration="23000" />
+      <workItem from="1774028822942" duration="792000" />
+      <workItem from="1774430967346" duration="2946000" />
     </task>
     <task id="LOCAL-00502" summary=".">
       <created>1641726946298</created>
       <option name="project" value="LOCAL" />
       <updated>1687259667913</updated>
     </task>
-    <option name="localTasksCounter" value="632" />
+    <option name="localTasksCounter" value="633" />
     <servers />
   </component>
   <component name="TypeScriptGeneratedFilesManager">
diff --git a/scripts/freeboxapi.php b/scripts/freeboxapi.php
deleted file mode 100644 (file)
index baa2c3c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-require_once "import.php";
-if ($_GET['action'] == 'resetWifi') {
-    freeboxResetWifi();
-    netgearWifiExtReboot();
-} else if ($_GET['action'] == 'auth') {
-    die(freeboxAuthorizeApp());
-} else if ($_GET['action'] === 'magnets') {
-    freeboxWatchMagnets();
-}
\ No newline at end of file
diff --git a/scripts/freeboxchannel.php b/scripts/freeboxchannel.php
deleted file mode 100644 (file)
index 271e6cf..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-require_once "import.php";
-freeboxChannel($_GET['channel']);
diff --git a/scripts/homeconnect.php b/scripts/homeconnect.php
deleted file mode 100644 (file)
index 4522c55..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-require_once "import.php";
-echo '<pre>';
-hc_setpower_state('Machine à café',true);
\ No newline at end of file
diff --git a/scripts/lib/freebox.php b/scripts/lib/freebox.php
deleted file mode 100644 (file)
index 681c9c2..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-use alphayax\freebox\utils\rest\RestAuth;
-
-const FREEBOX_APP_ID = 'fr.enhydra.tortuga.home';
-const FREEBOX_APP_NAME = 'Tortuga Home';
-const FREEBOX_APP_VERSION = '0.0.2';
-
-function freeboxAuthorizeApp()
-{
-    unlink('app_token');
-    $freeboxAPI = new \alphayax\freebox\utils\Application(FREEBOX_APP_ID, FREEBOX_APP_NAME, FREEBOX_APP_VERSION);
-    $freeboxAPI->authorize();
-    $freeboxAPI->openSession();
-    return $freeboxAPI->getAppToken();
-}
-
-function getFreeboxAPIInstance()
-{
-    global $freeboxAPI;
-    if (!isset($freeboxAPI)) {
-        $freeboxAPI = new \alphayax\freebox\utils\Application(FREEBOX_APP_ID, FREEBOX_APP_NAME, FREEBOX_APP_VERSION);
-        $freeboxAPI->setAppToken('afcd7pJHR6fef3QNlBUysKWSpr5Axe1pTKa7+p9YGjYwGKYBP87xcnYE/hV+FYCb');
-        $freeboxAPI->openSession();
-    }
-    return $freeboxAPI;
-}
-
-function freeboxResetWifi()
-{
-    ignore_user_abort(true);
-
-    $wifi = new alphayax\freebox\api\v3\services\config\WiFi\Config(getFreeboxAPIInstance());
-    $wifi->setConfiguration(new \alphayax\freebox\api\v3\models\WiFi\GlobalConfig(['enabled' => false]));
-
-    sleep(5);
-    $wifi->setConfiguration(new \alphayax\freebox\api\v3\models\WiFi\GlobalConfig(['enabled' => true]));
-}
-
-function freeboxAddMagnet($url)
-{
-    echo $url;
-    $download = new alphayax\freebox\api\v3\services\download\Download(getFreeboxAPIInstance());
-    $download->addFromUrl($url);
-}
-
-function freeboxWOL($mac, $password = '')
-{
-    $freebox = getFreeboxAPIInstance();
-    $rest = new RestAuth($freebox->getFreeboxApiHost() . '/api/v4/lan/wol/pub/');
-    $rest->setSessionToken($freebox->getSessionToken());
-    $rest->POST(['mac' => $mac, 'password' => $password]);
-}
-
-function freeboxWatchMagnets()
-{
-//    $dir = '/nas/Téléchargements/Watch';
-//    $dr = opendir($dir);
-//    while ($f = readdir($dr)) {
-//        if ($f == '.' || $f == '..' || !stristr($f, '.magnet')) {
-//            continue;
-//        }
-//        try {
-//            $file = $dir . '/' . $f;
-//            freeboxAddMagnet(file_get_contents($file));
-//            unlink($file);
-//        } catch (Exception $e) {
-//            if (stristr($e->getMessage(), '(exists)')) {
-//                unlink($file);
-//            }
-//            echo $e->getMessage();
-//        }
-//    }
-}
\ No newline at end of file
diff --git a/scripts/lib/ical.php b/scripts/lib/ical.php
deleted file mode 100644 (file)
index 3adf328..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-set_include_path(get_include_path() . ':/usr/share/awl/inc');
-require_once ROOT . '/lib/caldav-client-v2.php';
-
-
-$calendarServer = 'https://nextcloud.home.tortuga.enhydra.fr';
-$calendarBase = '/remote.php/dav/calendars/vincent@enhydra.fr/';
-
-/**
- * @return CalDAVClient
- */
-function icalClient()
-{
-    global $calendarServer, $calendarBase;
-    $res = new CalDAVClient($calendarServer . $calendarBase, 'vincent@enhydra.fr', '4zJZ6hbT6xwyL4oE3JEA');
-    //$res->SetDebug(true);
-    $res->SetDepth('1');
-    return $res;
-}
-
-/**
- * @param $cal string
- * @param $start DateTime|null
- * @param $end DateTime|null
- * @return array
- */
-function searchIcalEvent($cal, $start = null, $end = null)
-{
-    global $calendarBase;
-
-    $client = icalClient();
-    $client->SetCalendar($calendarBase . '/' . trim($cal, '/') . '/');
-    $events = $client->GetEvents(getIcalTimestamp($start), getIcalTimestamp($end));
-    $res = [];
-    foreach ($events as $event) {
-
-        $lines = explode("\n", $event['data']);
-        $data = [];
-        foreach ($lines as $line) {
-            $line = trim($line);
-            if (!$line) {
-                continue;
-            }
-            list($k, $v) = explode(':', $line);
-            $data[$k] = $v;
-        }
-        $event['data'] = $data;
-        $res[] = $event;
-    }
-    return $res;
-}
-
-/**
- * @param $cal string
- * @param $day DateTime|null
- * @return array
- */
-function searchICalEventDay($cal, $day = null)
-{
-    $start = $day;
-    $end = clone $day;
-
-    $start->setTime(6, 0, 0);
-    $end->setTime(18, 0, 0);
-
-    return searchIcalEvent($cal, $start, $end);
-}
-
-/**
- * @param $date DateTime|null
- * @return string
- */
-function getIcalTimestamp($date = null)
-{
-    if (null === $date) {
-        $date = new DateTime('now');
-    }
-    $date->setTimezone(new DateTimeZone('GMT'));
-    return $date->format('Ymd') . 'T' . $date->format('His') . 'Z';
-}
\ No newline at end of file
diff --git a/scripts/lib/klarstein.php b/scripts/lib/klarstein.php
deleted file mode 100644 (file)
index b3d9bbc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/scripts/lib/kodi.php b/scripts/lib/kodi.php
deleted file mode 100644 (file)
index ae2bcaa..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-$kodiClients = [];
-$kodiIP = ['salon' => '192.168.13.40', 'bureau' => '192.168.13.41', 'avion' => '192.168.13.5', 'cuisine' => '192.168.13.31', 'sdb' => '192.168.13.32'];
-$_tvshowallstatus = null;
-$_koditotmdb = null;
-
-function getKodiDBConnection() {
-       return @mysqli_connect('192.168.13.7', "root", "4xNkxCDAyWrp5VVthtgS", "MyVideos121", 3307);
-}
-
-function kodiGetAllKodiToTmdb($force = false) {
-       global $_koditotmdb;
-       if ($force || null === $_koditotmdb) {
-               try {
-                       $_koditotmdb = connectRedis()->igbget('kodi.koditotmdb');
-               } catch (Exception $e) {
-                       $_koditotmdb = false;
-               }
-
-               if ($force || $_koditotmdb === false) {
-                       $_koditotmdb = [];
-                       $con = getKodiDBConnection();
-                       if(!$con){
-                               return [];
-                       }
-                       $result = mysqli_query($con, "SELECT media_id,value FROM uniqueid WHERE `type`='tmdb'");
-                       while ($r = $result->fetch_assoc()) {
-                               $_koditotmdb[$r['media_id']] = $r['value'];
-                       }
-                       connectRedis()->igbsetex('kodi.koditotmdb', 7200, $_koditotmdb);
-               }
-       }
-       return $_koditotmdb;
-}
-
-function kodiGetTVShowAllStatus($force = false) {
-       global $_tvshowallstatus;
-
-       if ($force || null === $_tvshowallstatus) {
-               try {
-                       $_tvshowallstatus = connectRedis()->igbget('kodi.tvshow.status');
-               } catch (Exception $e) {
-                       $_tvshowallstatus = false;
-               }
-
-               if ($force || $_tvshowallstatus === false) {
-                       $con = getKodiDBConnection();
-                       if(!$con){
-                               return [];
-                       }
-                       $result = mysqli_query($con, 'SELECT idShow,totalCount,watchedcount FROM tvshow_view');
-                       if (!$result) {
-                               print_r(mysqli_error_list($con));
-                       }
-                       $_tvshowallstatus = [];
-                       while ($r = $result->fetch_assoc()) {
-                               if ($r['watchedcount'] == null || !$r['watchedcount']) {
-                                       $wc = 0;
-                               } else {
-                                       $wc = (int)$r['watchedcount'];
-                               }
-
-                               if ($r['totalCount'] == null || !$r['totalCount']) {
-                                       $tc = 0;
-                               } else {
-                                       $tc = (int)$r['totalCount'];
-                               }
-
-                               if ($tc === 0) {
-                                       $status = 3;
-                               } else if ($wc >= $tc) {
-                                       $status = 2;
-                               } else if ($wc == 0) {
-                                       $status = 1;
-                               } else if ($wc < $tc) {
-                                       $status = 0;
-                               }
-                               $_tvshowallstatus[kodiToTMDB($r['idShow'])] = $status;
-                       }
-                       connectRedis()->igbsetex('kodi.tvshow.status', 7200, $_tvshowallstatus);
-               }
-       }
-       return $_tvshowallstatus;
-}
-
-function kodiGetTVShowStatus($id) {
-       $allstatus = kodiGetTVShowAllStatus();
-       return $allstatus[$id] ?? 2;
-}
-
-function kodiToTMDB($id) {
-       $all = kodiGetAllKodiToTmdb();
-       return $all[$id] ?? null;
-}
-
-function kodiSyncPlayedStatus() {
-       $con = getKodiDBConnection();
-       if(!$con){
-               return;
-       }
-
-       $seen = connectRedis()->igbget('mediaseen');
-       $seenChanged = false;
-
-       $useen = [];
-
-       foreach ($seen as $item => $true) {
-               $useen[_normalizeSeenFile($item)] = true;
-       }
-
-       connectRedis()->igbset('mediaseen', $useen);
-       $seen = $useen;
-
-       $result = mysqli_query($con, 'SELECT * FROM path');
-       $paths = [];
-       while ($path = $result->fetch_assoc()) {
-               $p = _normalizeSeenFile($path['strPath']);
-
-               $paths[$path['idPath']] = $p;
-       }
-
-       $result = mysqli_query($con, 'SELECT * FROM files');
-       $files = [];
-       $playCounts = [];
-       while ($file = $result->fetch_assoc()) {
-               if (!isset($paths[$file['idPath']])) {
-                       continue;
-               }
-               $filename = $paths[$file['idPath']] . $file['strFilename'];
-               $files[$filename] = $file['idFile'];
-               $playCounts[$filename] = $file['playCount'];
-               if (null !== $file['playCount'] && !isset($seen[$filename])) {
-                       $seen[$filename] = true;
-                       $seenChanged = true;
-               }
-       }
-
-       // Update seen if needed
-       if ($seenChanged) {
-               echo 'seen changed' . "<br>";
-               connectRedis()->igbset('mediaseen', $seen);
-       }
-       // Update kodi database
-       foreach ($seen as $file => $s) {
-               $file = str_replace('//', '/', $file);
-               $e = explode('.', $file);
-               $ext = array_pop($e);
-               array_push($e, 'x264');
-               array_push($e, $ext);
-               $x264 = implode('.', $e);
-
-               foreach ([$file, $x264] as $f) {
-                       if (!array_key_exists($f, $playCounts) || ($playCounts[$f] && $playCounts[$f] >= 0)) {
-                               continue;
-                       }
-                       $fileId = $files[$f];
-                       mysqli_query($con, 'UPDATE files SET playCount=1,lastPlayed=NOW() WHERE idFile=' . $fileId);
-               }
-       }
-}
-
-function _normalizeSeenFile($p) {
-       $p = str_replace('nfs://192.168.13.3/', '/', $p);
-       $p = str_replace(NAS_ROOT, '/volume1/Share/', $p);
-       $p = str_replace(NAS_PWD_ROOT, '/volume1/Share/', $p);
-       $p = str_replace('smb://Share:dcfyjbcyckwydtgufjx@192.168.13.4/Share//', '/volume1/Share/', $p);
-       $p = str_replace('smb://nas.home.tortuga.enhydra.fr/1.42.6-25556/', '/volume1/Share/', $p);
-       $p = str_replace('.x264.', '.', $p);
-       return $p;
-}
-
-function tmdbToKodiId($tmdbId, $type = 'tvshow') {
-       $con=getKodiDBConnection();
-       if(!$con){
-               return false;
-       }
-       $result = mysqli_query($con, 'SELECT `media_id` FROM `uniqueid` WHERE `value`="' . $tmdbId . '" AND `type`="tmdb"');
-       while ($r = $result->fetch_assoc()) {
-               return $r['media_id'];
-       }
-}
-
-function kodiOpenTVShow($device, $tmdbId, $season = 1, $episode = 1) {
-       global $kodiIP;
-
-       $ip = $kodiIP[$device];
-       $json = '{"jsonrpc":"2.0","id":"1","method":"GUI.ActivateWindow","params":["videos",["videodb://tvshows/titles/' . tmdbToKodiId($tmdbId) . '/' . $season . '","return"]]}';
-       `curl 'http://$ip:8754/jsonrpc' --data-raw '$json'`;
-}
\ No newline at end of file
index 95762e285c7bd3e632c84b0af9661e99705775bd..9866f4fefe755559d8a7a70a5b32825c604fb586 100644 (file)
@@ -15,11 +15,8 @@ require_once ROOT . '/scripts/lib/hue.php';
 require_once ROOT . '/scripts/lib/harmony.php';
 require_once ROOT . '/scripts/lib/scenes.php';
 require_once ROOT . '/scripts/lib/squeezebox.php';
-require_once ROOT . '/scripts/lib/freebox.php';
 require_once ROOT . '/scripts/lib/jarvis.php';
 require_once ROOT . '/scripts/lib/mediarasp.php';
-require_once ROOT . '/scripts/lib/netgearwifiext.php';
-require_once ROOT . '/scripts/lib/tmdb.php';
 require_once ROOT . '/scripts/lib/http.php';
 require_once ROOT . '/scripts/lib/pc.php';
 require_once ROOT . '/scripts/lib/time.php';
@@ -42,12 +39,8 @@ require_once ROOT . '/scripts/lib/router.php';
 require_once ROOT . '/scripts/lib/denon.php';
 require_once ROOT . '/scripts/lib/proc.php';
 require_once ROOT . '/scripts/lib/shield.php';
-require_once ROOT . '/scripts/lib/kodi.php';
 require_once ROOT . '/scripts/lib/climacell.php';
 require_once ROOT . '/scripts/lib/wol.php';
-require_once ROOT . '/scripts/lib/switchbot.php';
-require_once ROOT . '/scripts/lib/ical.php';
-require_once ROOT . '/scripts/lib/klarstein.php';
 require_once ROOT . '/scripts/lib/windows.php';
 
 
diff --git a/scripts/lib/omxplay.php b/scripts/lib/omxplay.php
deleted file mode 100644 (file)
index 819245b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-function omxplayTV($url, $device = null)
-{
-    setPlaying('omxtv', $device);
-}
\ No newline at end of file
index da71e55f9533fabc150fb419365dd3760e72a60c..20425462c0b6cb20e3b058efbce169cec4b2f085 100644 (file)
@@ -887,8 +887,13 @@ function execScene($name, $fromUserAction = false, $transitionTime = null)
 {
     global $scenes;
 
+    if(!isset($scenes[$name])) {
+        haAction('script.'.str_replace('/','_',$name));
+        return;
+    }
     $scene = $scenes[$name];
 
+
     profile('Exec scene ' . $name . '/' . $fromUserAction, __FILE__, __LINE__);
 
     $e = explode('/', $name);
diff --git a/scripts/lib/switchbot.php b/scripts/lib/switchbot.php
deleted file mode 100644 (file)
index 031d354..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-function switchbot($device, $command = 'press', $rpi = 'sdb') {
-       $res = '';
-       for ($i = 0; $i <= 60; $i++) {
-               //        $res = sshCommand('/docker/switchbot/run ' . $device . ' ' . $command, $rpi, true, true);
-               //        if (stristr($res['output'], 'Command execution successful')) {
-               //            break;
-               //        }
-               //        sleep(5);
-       }
-       return $res;
-}
-
-function hotwaterAutoMode($mode, $force = false) {
-       $mode = $mode ? '1' : '0';
-       setState('hotwater_auto_mode', $mode);
-       if ($mode) {
-               hotwaterCheckMode($force);
-       }
-}
-
-function hotwaterCheckMode($force = false) {
-       if (getState('hotwater_auto_mode', '1') == '0') {
-               return;
-       }
-
-       $jerome = isJerome(true, $force);
-       $vincent = isVincent($force);
-
-       $h = date('G');
-       $isWeek = isWeekDay();
-
-       $maxLevel = '2';
-
-       $ecomode = (int)getState('ecomode', '0');
-
-       if (!isVincent($force)) {
-               $hot = '1';
-       } else {
-               if (getSqueezePlayerStatus('Salle de bains')) {
-                       $hot = $maxLevel;
-               } else {
-                       if (isJerome()) {
-                               $weekColdHours = [0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 23];
-                               if ($ecomode == 0) {
-                                       $hot = ($isWeek && in_array($h, $weekColdHours)) ? '0' : '1';
-                               } else if ($ecomode == 1) {
-                                       $hot = ($isWeek && $h >= 6 && $h <= 7) ? '1' : '0';
-                               } else if ($ecomode == 2) {
-                                       $hot = '0';
-                               }
-                       } else {
-                               $hot = '0';
-                       }
-               }
-       }
-       echo "\n\n" . 'V:' . $vincent . '/J:' . $jerome . '/H:' . $h . '/WD:' . $isWeek . '/W:' . $hot . "\n\n";
-       hotwater($hot);
-}
-
-function hotwater($newState) {
-       set_time_limit(300);
-       // 0 : OFF
-       // 1 : ECO
-       // 2 : MAX
-
-       echo getState('hotwater_auto_mode', '1') . '::' . getState('hotwater_change', '0') . '::' . getState('hotwater', '1');
-       $changing = getState('hotwater_change', '0');
-       $limit = time() - 300;
-       if ($changing > $limit) {
-               return 'changing';
-       }
-
-       $device = 'C1:F7:66:5E:A2:CF';
-       $state = getState('hotwater', '1');
-       if ($newState == $state) {
-               setState('hotwater_change', '0');
-               return 'no state change';
-       }
-       $clicks = (3 + $newState - $state) % 3;
-       setState('hotwater_change', time());
-
-       $res = '';
-       for ($i = 0; $i < $clicks; $i++) {
-               $res .= ' one click - ';
-               $res .= print_r(switchbot($device, 'press', 'sdb'));
-               if ($i < $clicks - 1) {
-                       sleep(2);
-               }
-       }
-       setState('hotwater', $newState);
-       setState('hotwater_change', '0');
-       return $res;
-}
-
-function isWeekDay() {
-       $d = date('N');
-       return $d < 6;
-}
-
-function isWeekEnd() {
-       return !isWeekDay();
-}
-
-function isVincent($force = false) {
-       return remember('vincent_in_paris', 3600, function () {
-               return _isVincent();
-       }, true, $force);
-}
-
-function _isVincent() {
-       $today = new DateTime('now');
-       $events = searchIcalEventDay('dplacements-jrme', $today);
-       foreach ($events as $event) {
-               if (stristr($event['data']['SUMMARY'], '(V)')) {
-                       return false;
-               }
-       }
-       return true;
-}
-
-function isJerome($strict = true, $force = false) {
-       $key = 'jerome_in_paris' . ($strict ? '' : '_1');
-
-       return remember($key, 3600, function () use ($strict) {
-               return _isJerome($strict);
-       }, true, $force);
-}
-
-function _isJerome($strict = true) {
-       $today = new DateTime('now');
-       $yesterday = new DateTime('now');
-       $yesterday->sub(new DateInterval('P1D'));
-       $tomorrow = new DateTime('now');
-       $tomorrow->add(new DateInterval('P1D'));
-
-       $dates = $strict ? [$yesterday, $today, $tomorrow] : [$today];
-
-       foreach ($dates as $date) {
-               $events = searchIcalEventDay('dplacements-jrme', $date);
-               $count = 0;
-               foreach ($events as $event) {
-                       if (stristr($event['data']['SUMMARY'], '(V)')) {
-                               continue;
-                       }
-                       $count++;
-               }
-               if (!$count) {
-                       return true;
-               }
-       }
-       return false;
-}
\ No newline at end of file
diff --git a/scripts/lib/tmdb.php b/scripts/lib/tmdb.php
deleted file mode 100644 (file)
index bdc3839..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-<?php
-
-use Tmdb\ApiToken;
-use Tmdb\Client;
-
-$tmdbclient = null;
-
-/**
- * @return Client
- */
-function getTmbdClient()
-{
-    global $tmdbclient;
-    if (null === $tmdbclient) {
-        $token = new ApiToken('319e5e721cf55cc1ffa3faa2f600be64');
-        $tmdbclient = new Client($token);
-    }
-    return $tmdbclient;
-}
-
-function getTVShows()
-{
-    return _getTVShows();
-}
-
-function _getMediaRecentAdded($force = false)
-{
-    if ($force) {
-        global $directories;
-
-        $res = ['shortcuts' => [], 'subs' => []];
-        $res['shortcuts']['size'] = 'poster';
-        $res['shortcuts'][] = ['label' => 'Ajoutés récemment', 'type' => 'back'];
-
-        $tvlibrary = new tvShowLibrary($directories);
-        $tv = $tvlibrary->getRecents();
-
-        $molibrary = new moviesLibrary($directories);
-        $movies = $molibrary->getRecents();
-
-        $medias = array_merge($tv, $movies);
-        usort($medias, function ($a, $b) {
-            return $b['mtime'] - $a['mtime'];
-        });
-
-        foreach ($medias as $media) {
-            if ($media['type'] == 'tvshow') {
-                $tvlibrary->shortcut($media, 'recent-', $res);
-            } else if ($media['type'] == 'movie') {
-                $molibrary->shortcut($media, 'recent-', $res['shortcuts']);
-            }
-        }
-
-        connectRedis()->igbset('medialibrary.mediarecent', $res);
-        return $res;
-    }
-    $res = connectRedis()->igbget('medialibrary.mediarecent');
-    if ($res === false) {
-        return _getMediaRecentAdded(true);
-    }
-    return $res;
-}
-
-function getMediaRecentAdded()
-{
-    return _getMediaRecentAdded();
-}
-
-function _getTVShows($force = false, $forceapi = false)
-{
-    if ($force) {
-        global $directories;
-        $library = new tvShowLibrary($directories, $forceapi);
-        $res = $library->getShortcuts();
-        connectRedis()->igbsetex('medialibrary.tvshows', 1800, $res);
-        return $res;
-    }
-    $res = connectRedis()->igbget('medialibrary.tvshows');
-    if ($res === false) {
-        return _getTVShows(true);
-    }
-    return $res;
-}
-
-function getMovies()
-{
-    return _getMovies();
-}
-
-function _getMovies($force = false, $forceapi = false)
-{
-    if ($force) {
-        global $directories;
-        $library = new moviesLibrary($directories, $forceapi);
-        $res = $library->getShortcuts();
-        connectRedis()->igbsetex('medialibrary.movies', 1800, $res);
-        return $res;
-    }
-    $res = connectRedis()->igbget('medialibrary.movies');
-    if ($res === false) {
-        return _getMovies(true);
-    }
-    return $res;
-}
-
-function tmdbToTvdb($tmdbid)
-{
-    $cacheKey = 'tmdb_to_tvdb_' . $tmdbid;
-    $cached = getState($cacheKey, null);
-    if (null === $cached) {
-        $client = getTmbdClient();
-        $find = $client->getTvApi();
-        $data = $find->getExternalIds($tmdbid);
-        $cached = $data['tvdb_id'];
-        setState($cacheKey, $cached);
-    }
-    return $cached;
-}
-
-function mb_strcasecmp($str1, $str2, $encoding = null)
-{
-    if (null === $encoding) {
-        $encoding = mb_internal_encoding();
-    }
-    return strcmp(mb_strtoupper($str1, $encoding), mb_strtoupper($str2, $encoding));
-}
-
-class tvShowLibrary extends mediaLibrary
-{
-
-    protected $tvShows = [];
-    protected $force = false;
-    protected $tmdbclient;
-    protected $find;
-
-    public function __construct($directories, $force = false)
-    {
-        $this->force = $force;
-
-        $this->tmdbclient = getTmbdClient();
-        $this->find = $this->tmdbclient->getFindApi();
-
-        foreach ($directories as $directory) {
-            if ($directory['context'] != 'tvshow') {
-                continue;
-            }
-            $d = '/volume1/Share/Videos/' . $directory['dir'];
-            if (!file_exists($d) || !is_dir($d)) {
-                continue;
-            }
-            $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($d));
-            foreach ($it as $f) {
-                /** @var $f SplFileInfo */
-                if ($f->getFilename() == '.tmbd.id') {
-                    @rename($f->getPathname(), str_replace('.tmbd.id', '.tmdb.id', $f->getPathname()));
-                    continue;
-                }
-                if ($f->isDir() && !file_exists($f->getPath() . '/.tmdb.id') && strpos($f->getPath(), '.tt') !== false) {
-                    $e = explode('.', $f->getPath());
-                    $last = array_pop($e);
-                    $r = $this->find->findBy($last, ['external_source' => 'imdb_id']);
-
-                    foreach ($r['tv_results'] as $tv_result) {
-                        if (isset($tv_result['id'])) {
-                            file_put_contents($f->getPath() . '/.tmdb.id', $tv_result['id']);
-                            break;
-                        }
-                    }
-                    continue;
-                }
-                if ($f->isDir() || strpos($f->getFilename(), '.tmdb.id') === false) {
-                    continue;
-                }
-
-                $file = str_replace('.tmdb.id', '', $f->getPathname());
-
-                $id = file_get_contents($f->getPathname() . '');
-                $data = $this->getTVShowByID($id);
-                $edate = explode('-', $data['last_air_date']);
-                $mtime = gmmktime(12, 0, 0, $edate[1], $edate[2], $edate[0]);
-
-                if (file_exists($file . '.netflix')) {
-                    $dir = 'netflix:' . file_get_contents($file . '.netflix');
-                } else {
-                    $dir = file_exists($file) && is_file($file) ? file_get_contents($file) : $f->getPath();
-                }
-
-                $data = $this->getTVShowByID($id);
-                $this->tvShows[] = ['type' => 'tvshow', 'dir' => $dir, 'data' => $data, 'id' => $id, 'mtime' => $mtime, 'status' => $data['kodi_status']];
-            }
-        }
-
-        usort($this->tvShows, [$this, '_sortTVByName']);
-    }
-
-    public function getTVShowByID($id)
-    {
-        if (!$this->force) {
-            try {
-                $res = connectRedis()->igbget('tmdb.tv.' . $id);
-            } catch (Exception $e) {
-                $res = false;
-            }
-        } else {
-            $res = false;
-        }
-
-        if ($res === false) {
-            if (!hasNetwork()) {
-                return null;
-            }
-            $client = getTmbdClient();
-
-            try {
-                $res = $client->getTvApi()->getTvshow($id, ['language' => 'fr-FR']);
-                connectRedis()->igbsetex('tmdb.tv.' . $id, 259200, $res);
-            } catch (Exception $e) {
-                echo $e->getMessage();
-                return null;
-            }
-
-        }
-
-        $res = $this->addKodiStatus($id, $res);
-        return $res;
-    }
-
-    public function addKodiStatus($id, $tv)
-    {
-        $tv['kodi_status'] = kodiGetTVShowStatus($id);
-        return $tv;
-    }
-
-    protected function _sortTVByName($a, $b)
-    {
-        return mb_strcasecmp($a['data']['name'], $b['data']['name']);
-    }
-
-    public function getShortcuts()
-    {
-
-        $res = ['shortcuts' => [], 'subs' => []];
-        $res['shortcuts']['size'] = 'poster';
-        $res['shortcuts'][] = ['label' => 'Séries TV', 'type' => 'back'];
-
-        $status = [0 => 'En cours', 1 => 'A voir', 2 => 'Vue', 3 => 'A venir'];
-        foreach ($status as $s => $label) {
-            $res['shortcuts'][] = ['label' => $label, 'type' => 'separator'];
-            foreach ($this->tvShows as $tvShow) {
-                if ($tvShow['status'] != $s) {
-                    continue;
-                }
-                $this->shortcut($tvShow, '', $res);
-            }
-        }
-
-        return $res;
-    }
-
-    public function shortcut($tvShow, $prefix, &$res)
-    {
-        global $videoExt;
-
-        set_time_limit(10);
-
-        $e = explode(':', $tvShow['dir']);
-        if ($e[0] === 'netflix') {
-            $res['shortcuts'][] = ['label' => $tvShow['data']['name'], 'type' => 'netflix', 'url' => '/scripts/netflix.php?id=' . $e[1], 'poster' => $this->_poster($tvShow['data']['poster_path'])];
-            return;
-        }
-
-        $subname = $prefix . 'tvshow-' . $tvShow['id'];
-        $res['shortcuts'][] = ['label' => $tvShow['data']['name'], 'type' => 'sub', 'sub' => $subname, 'poster' => $this->_poster($tvShow['data']['poster_path'])];
-
-        $res['subs']['sub-' . $subname] = ['size' => 'poster'];
-        $res['subs']['sub-' . $subname][] = ['label' => $tvShow['data']['name'], 'type' => 'back'];
-
-        $seasons = $tvShow['data']['seasons'];
-
-        if (isset($seasons[0]['season_number']) && !$seasons[0]['season_number']) {
-            $s = array_shift($seasons);
-            array_push($seasons, $s);
-        }
-
-        foreach ($seasons as $season) {
-            $closed = false;
-            $missing = false;
-            $ns = $this->_n($season['season_number'], 's');
-            if ($season['season_number'] == 0) {
-                if (file_exists($tvShow['dir'] . '/S00')) {
-                    $dir = $tvShow['dir'] . '/S00';
-                } else {
-                    $dir = $tvShow['dir'] . '/Specials';
-                }
-                $closed = true;
-            } else {
-                $dir = $tvShow['dir'] . '/' . $ns;
-            }
-
-            if ($season['episode_count'] <= 0) {
-                continue;
-            }
-
-            $accordionId = 'acc_' . sha1($subname . '--' . $ns);
-            $res['subs']['sub-' . $subname][] = ['label' => $ns, 'type' => 'accordion', 'id' => $accordionId, 'closed' => accordionClosed($accordionId)];
-            for ($i = 1; $i <= $season['episode_count']; $i++) {
-                $es = $this->_n($i, 'e');
-                $exists = false;
-                $base = $dir . '/' . $es . '.';
-                $bases = $dir . '/' . $ns . $es . '.';
-                foreach ($videoExt as $ext) {
-                    $f = $base . $ext;
-                    $fs = $bases . $ext;
-                    if (file_exists($f)) {
-                        $exists = $f;
-                        break;
-                    }
-                    if (file_exists($fs)) {
-                        $exists = $fs;
-                    }
-                }
-
-                if ($exists) {
-                    $path = $this->_path($exists);
-                    $res['subs']['sub-' . $subname][] = ['label' => $es, 'type' => 'media', 'srt' => hasSRT($path), 'seen' => $this->_seen($path), 'path' => $path];
-                } else {
-                    $res['subs']['sub-' . $subname][] = ['label' => $es, 'type' => 'missing'];
-                }
-
-            }
-
-            $res['subs']['sub-' . $subname][] = ['type' => 'accordion-end'];
-        }
-    }
-
-    protected function _n($number, $letter)
-    {
-        if ($number < 10) {
-            $number = "0" . $number;
-        }
-        return mb_strtoupper($letter) . $number;
-    }
-
-    public function getTVShows()
-    {
-        return $this->tvShows;
-    }
-
-    public function getRecents()
-    {
-        $m = [];
-        foreach ($this->tvShows as $k => $show) {
-            if (!isset($show['status']) || $show['status'] >= 2) {
-                continue;
-            }
-            $m[$k] = $show;
-        }
-        usort($m, function ($a, $b) {
-            return $b['mtime'] - $a['mtime'];
-        });
-        return array_slice($m, 0, 20);
-    }
-}
-
-class mediaLibrary
-{
-    protected static $_seen = null;
-
-    protected function _path($p)
-    {
-//        $e = explode('.', $p);
-//        $ext = array_pop($e);
-//
-//        array_push($e, 'x264');
-//        array_push($e, $ext);
-//        $x264 = implode('.', $e);
-//        if (file_exists($x264)) {
-//            $p = $x264;
-//        }
-        return str_replace('/volume1/Share', '', $p);
-    }
-
-    protected function _seen($p)
-    {
-        if (null === self::$_seen) {
-            self::$_seen = connectRedis()->igbget('mediaseen');
-            if (!is_array(self::$_seen)) {
-                self::$_seen = [];
-            }
-        }
-        return isset(self::$_seen['/volume1/Share' . $p]);
-
-    }
-
-    protected function dirfilemtime($dirName, $doRecursive)
-    {
-        $d = dir($dirName);
-        $lastModified = 0;
-        if ($d !== false) {
-            while ($entry = $d->read()) {
-                if ($entry != "." && $entry != "..") {
-                    if (!is_dir($dirName . "/" . $entry) && file_exists($dirName . "/" . $entry)) {
-                        $currentModified = filemtime($dirName . "/" . $entry);
-                    } else if ($doRecursive && is_dir($dirName . "/" . $entry)) {
-                        $currentModified = $this->dirfilemtime($dirName . "/" . $entry, true);
-                    }
-                    if (isset($currentModified) && $currentModified > $lastModified) {
-                        $lastModified = $currentModified;
-                    }
-                }
-            }
-            $d->close();
-            return $lastModified;
-        }
-        return $lastModified;
-    }
-
-    public function _poster($path, $alt = '')
-    {
-        if (null === $path || $path === '') {
-            if ($alt === '') {
-                return '';
-            }
-            return cacheMedia('/volume1/Share/' . $alt);
-        } else {
-            return cacheMedia('https://image.tmdb.org/t/p/w500' . $path);
-        }
-    }
-}
-
-class moviesLibrary extends mediaLibrary
-{
-    protected $movies = [];
-    protected $force = false;
-
-    public function __construct($directories, $force = false)
-    {
-        $this->force = $force;
-
-        foreach ($directories as $directory) {
-            if ($directory['context'] != 'movie') {
-                continue;
-            }
-            $d = '/volume1/Share/Videos/' . $directory['dir'];
-            if (!file_exists($d) || !is_dir($d)) {
-                continue;
-            }
-            $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($d));
-            foreach ($it as $f) {
-                /** @var $f SplFileInfo */
-                if ($f->isDir() || !stristr($f->getFilename(), '.tmdb.id')) {
-                    continue;
-                }
-                $id = file_get_contents($f->getPathname());
-                if ($id == 'unknwown') {
-                    continue;
-                }
-                $path = str_replace('.tmdb.id', '', $f->getPathname());
-                if (!file_exists($path)) {
-                    unlink($f->getPathname());
-                    continue;
-                }
-                $mtime = 0;
-                if (file_exists($path)) {
-                    $mtime = filemtime($path);
-                }
-                $this->movies[] = ['type' => 'movie', 'data' => $this->getMovieByID($id), 'path' => $path, 'mtime' => $mtime];
-            }
-            usort($this->movies, array($this, '_orderMovies'));
-        }
-
-    }
-
-    public function getRecents()
-    {
-        $m = $this->movies;
-        usort($m, function ($a, $b) {
-            return $b['mtime'] - $a['mtime'];
-        });
-        return array_slice($m, 0, 60);
-    }
-
-    function getShortcuts()
-    {
-        $lists = [
-            ['label' => 'Par titre', 'id' => 'alpha', 'list' => $this->getAlphaShortcuts()],
-            ['label' => 'Par genre', 'id' => 'genre', 'list' => $this->getGenreShortcuts()],
-            ['label' => 'Par langue', 'id' => 'language', 'list' => $this->getLanguagesShortcuts()],
-            ['label' => 'Par année', 'id' => 'year', 'list' => $this->getYearsShortcuts()],
-        ];
-
-        $res = ['shortcuts' => [['label' => 'Films', 'type' => 'back']], 'subs' => []];
-
-        foreach ($lists as $list) {
-            $res['shortcuts'][] = ['label' => $list['label'], 'type' => 'sub', 'sub' => 'movies-' . $list['id']];
-            $res['subs']['sub-movies-' . $list['id']] = $list['list']['shortcuts'];
-            $res['subs'] = array_merge($res['subs'], $list['list']['subs']);
-        }
-
-        return $res;
-    }
-
-    public function getAlphaShortcuts()
-    {
-        $letters = [];
-        foreach (str_split('#ABCDEFGHIJKLMNOPQRSTUVWXYZ') as $l) {
-            $letters[$l] = [];
-        }
-
-        foreach ($this->movies as $movie) {
-            $firstLetters = $this->_firstLetters([$movie['data']['title'], $movie['data']['original_title']]);
-            foreach ($firstLetters as $firstLetter) {
-                if (!isset($letters[$firstLetter])) {
-                    continue;
-                }
-                $letters[$firstLetter][] = $movie;
-            }
-        }
-        return $this->_makeSub($letters, 'movies-alpha-', 'Films par titre', 'poster');
-    }
-
-    protected function _firstLetters($titles)
-    {
-        $res = [];
-        $allTitles = [];
-        foreach ($titles as $title) {
-            $title = mb_strtolower($title);
-            $title = $this->remove_accents($title);
-            $title = trim($title, '\' ');
-            $allTitles[] = $title;
-            $allTitles[] = $this->_removeMeanlessWords($title);
-        }
-
-        $allTitles = array_unique($allTitles);
-        foreach ($allTitles as $title) {
-            $letter = mb_substr($title, 0, 1);
-            $letter = mb_strtoupper($letter);
-            $letter = preg_replace('|\d|', '#', $letter);
-            $res[] = $letter;
-        }
-
-        return array_unique($res);
-    }
-
-    protected function _removeMeanlessWords($title)
-    {
-        $remove = ['un', 'une', 'le', 'la', 'l', 'the', 'a', 'der', 'die', 'das', 'ein', 'el', 'una'];
-        $e = preg_split('/(\s|\')/', mb_strtolower($title));
-        $res = [];
-        foreach ($e as $item) {
-            if (!in_array($item, $remove)) {
-                $res[] = $item;
-            }
-        }
-        return implode(' ', $res);
-    }
-
-    protected function remove_accents($string)
-    {
-        if (!preg_match('/[\x80-\xff]/', $string))
-            return $string;
-
-        $chars = array(
-            // Decompositions for Latin-1 Supplement
-            chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A',
-            chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
-            chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
-            chr(195) . chr(135) => 'C', chr(195) . chr(136) => 'E',
-            chr(195) . chr(137) => 'E', chr(195) . chr(138) => 'E',
-            chr(195) . chr(139) => 'E', chr(195) . chr(140) => 'I',
-            chr(195) . chr(141) => 'I', chr(195) . chr(142) => 'I',
-            chr(195) . chr(143) => 'I', chr(195) . chr(145) => 'N',
-            chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
-            chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
-            chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
-            chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
-            chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
-            chr(195) . chr(159) => 's', chr(195) . chr(160) => 'a',
-            chr(195) . chr(161) => 'a', chr(195) . chr(162) => 'a',
-            chr(195) . chr(163) => 'a', chr(195) . chr(164) => 'a',
-            chr(195) . chr(165) => 'a', chr(195) . chr(167) => 'c',
-            chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
-            chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
-            chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
-            chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
-            chr(195) . chr(177) => 'n', chr(195) . chr(178) => 'o',
-            chr(195) . chr(179) => 'o', chr(195) . chr(180) => 'o',
-            chr(195) . chr(181) => 'o', chr(195) . chr(182) => 'o',
-            chr(195) . chr(182) => 'o', chr(195) . chr(185) => 'u',
-            chr(195) . chr(186) => 'u', chr(195) . chr(187) => 'u',
-            chr(195) . chr(188) => 'u', chr(195) . chr(189) => 'y',
-            chr(195) . chr(191) => 'y',
-            // Decompositions for Latin Extended-A
-            chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
-            chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
-            chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
-            chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
-            chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
-            chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
-            chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
-            chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
-            chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
-            chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
-            chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
-            chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
-            chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
-            chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
-            chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
-            chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
-            chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
-            chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
-            chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
-            chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
-            chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
-            chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
-            chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
-            chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
-            chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
-            chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
-            chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
-            chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
-            chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
-            chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
-            chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
-            chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
-            chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
-            chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
-            chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
-            chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
-            chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
-            chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
-            chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
-            chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
-            chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
-            chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
-            chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
-            chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
-            chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
-            chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
-            chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
-            chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
-            chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
-            chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
-            chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
-            chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
-            chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
-            chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
-            chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
-            chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
-            chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
-            chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
-            chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
-            chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
-            chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
-            chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
-            chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
-            chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's'
-        );
-
-        $string = strtr($string, $chars);
-
-        return $string;
-    }
-
-    protected function _makeSub($list, $subbase, $parentName, $size = null)
-    {
-        $res = ['shortcuts' => [], 'subs' => []];
-
-        if (null !== $size) {
-            $res['shortcuts']['size'] = 'poster';
-        }
-        $res['shortcuts'][] = ['label' => $parentName, 'type' => 'back'];
-        foreach ($list as $key => $movies) {
-            $subkey = $subbase . md5($key);
-            $res['shortcuts'][] = ['label' => $key, 'type' => 'sub', 'sub' => $subkey];
-            $res['subs']['sub-' . $subkey] = $this->_makeShortcuts($movies, $key);
-        }
-        return $res;
-    }
-
-    protected function _makeShortcuts($movies, $key)
-    {
-        $res = ['size' => 'poster'];
-        $res[] = ['label' => $key, 'type' => 'back'];
-        foreach ($movies as $movie) {
-            $this->shortcut($movie, '', $res);
-        }
-        return $res;
-    }
-
-    public function shortcut($movie, $prefix, &$res)
-    {
-        $path = $this->_path($movie['path']);
-        $res[] = ['label' => $movie['data']['title'], 'type' => 'media', 'seen' => $this->_seen($path), 'srt' => hasSRT($path), 'path' => $path, 'poster' => $this->_poster($movie['data']['poster_path'], dirname($path) . '/poster.jpg')];
-    }
-
-
-    public function _orderMovies($a, $b)
-    {
-        return mb_strcasecmp($a['data']['title'], $b['data']['title']);
-    }
-
-    public function getGenreShortcuts()
-    {
-        $genres = [];
-        if (is_array($this->movies)) {
-            foreach ($this->movies as $movie) {
-
-                foreach ($movie['data']['genres'] as $genre) {
-                    if (!isset($genres[$genre['name']])) {
-                        $genres[$genre['name']] = [];
-                    }
-                    $genres[$genre['name']][] = $movie;
-                }
-            }
-        }
-        ksort($genres);
-
-        return $this->_makeSub($genres, 'movies-genre-', 'Films par genre');
-
-    }
-
-    public function getLanguagesShortcuts()
-    {
-        $languages = [];
-        foreach ($this->movies as $movie) {
-
-            $lang = mb_strtolower(Zend_Locale::getTranslation($movie['data']['original_language'], 'language', 'fr-FR'));
-            if (!isset($languages[$lang])) {
-                $languages[$lang] = [];
-            }
-            $languages[$lang][] = $movie;
-        }
-        ksort($languages);
-
-        return $this->_makeSub($languages, 'movies-language-', 'Films par langue');
-    }
-
-    public function getYearsShortcuts()
-    {
-        $years = [];
-        foreach ($this->movies as $movie) {
-            $e = explode('-', $movie['data']['release_date']);
-            $year = $e[0];
-            if (!isset($years[$year])) {
-                $years[$year] = [];
-            }
-            $years[$year][] = $movie;
-        }
-        krsort($years);
-
-        return $this->_makeSub($years, 'movies-year-', 'Films par année');
-    }
-
-
-    public function getMovieByID($id)
-    {
-        if (!$this->force) {
-            $res = connectRedis()->igbget('tmdb.movie.' . $id);
-        } else {
-            $res = false;
-        }
-        if ($res === false) {
-            if (!hasNetwork()) {
-                return null;
-            }
-            $client = getTmbdClient();
-            try {
-                $movie = $client->getMoviesApi()->getMovie($id, ['language' => 'fr-FR']);
-                connectRedis()->igbsetex('tmdb.movie.' . $id, 259200, $movie);
-                return $movie;
-            } catch (Exception $e) {
-                return null;
-            }
-        }
-        return $res;
-    }
-}
-
-
-function parseMoviesLibrary()
-{
-    global $directories, $videoExt;
-    $d='/volume1/Share/Videos/' . $directories['Films']['dir'];
-    if(!file_exists($d) || !is_dir($d)){
-        return;
-    }
-    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($d));
-    $moviesExtensions = $videoExt;
-    $tmdbclient = getTmbdClient();
-    $search = $tmdbclient->getSearchApi();
-    $find = $tmdbclient->getFindApi();
-
-    $i = 0;
-
-    foreach ($it as $f) {
-        /* @var $f SplFileInfo */
-        if ($f->isDir()) {
-            continue;
-        }
-
-        if ($f->getExtension() == 'id' && file_get_contents($f->getPathname()) == 'unknwown') {
-            echo $f->getPathname() . "\n";
-        }
-
-        if (!in_array($f->getExtension(), $moviesExtensions)) {
-            continue;
-        }
-
-        if (stristr($f->getPathname(), '.x264.')) {
-            continue;
-        }
-
-        $tmdbfile = $f->getPathname() . '.tmdb.id';
-        if (!file_exists($tmdbfile) || file_get_contents($tmdbfile) == 'unknwown') {
-            $_basename = $f->getBasename('.' . $f->getExtension());
-            $basename = str_replace('.', ' ', $_basename);
-            $params = [];
-            $e = explode('.', $_basename);
-            $last = array_pop($e);
-            echo $basename . ':' . $last;
-
-            if (strpos($last, 'tt') === 0) {
-                $f = $find->findBy($last, ['external_source' => 'imdb_id']);
-                foreach ($f['movie_results'] as $movie_result) {
-                    if (isset($movie_result['id'])) {
-                        $tmdbid = $movie_result['id'];
-                    }
-                }
-                echo $tmdbid;
-            } else {
-                $s = $search->searchMovies($basename);
-                if ($s['total_results'] == 0) {
-                    $tmdbid = 'unknwown';
-                } else {
-                    $results = $s['results'];
-                    foreach ($results as $result) {
-                        if (isset($result['id'])) {
-                            $tmdbid = $result['id'];
-                        }
-                    }
-                }
-            }
-
-            file_put_contents($tmdbfile, $tmdbid);
-            $i++;
-        }
-    }
-}
\ No newline at end of file