Exemple #1
0
 public function processMpdDatabasefile()
 {
     $this->jobPhase = 1;
     $app = \Slim\Slim::getInstance();
     $this->beginJob(array('msg' => $app->ll->str('importer.processing.mpdfile')), __FUNCTION__);
     // check if mpd_db_file exists
     if (is_file($app->config['mpd']['dbfile']) == FALSE || is_readable($app->config['mpd']['dbfile']) === FALSE) {
         $msg = $app->ll->str('error.mpd.dbfile', array($app->config['mpd']['dbfile']));
         cliLog($msg, 1, 'red', TRUE);
         $this->finishJob(array('msg' => $msg));
         $app->stop();
     }
     # TODO: check if mpd-database file is plaintext or gzipped or sqlite
     # TODO: processing mpd-sqlite db or gzipped db
     $this->updateJob(array('msg' => $app->ll->str('importer.collecting.mysqlitems')));
     // get timestamps of all tracks and directories from mysql database
     $fileTimestampsMysql = array();
     $directoryTimestampsMysql = array();
     // get all existing track-ids to determine orphans
     $deadMysqlFiles = array();
     $query = "SELECT id, relativePathHash, relativeDirectoryPathHash, filemtime, directoryMtime FROM rawtagdata;";
     $result = $app->db->query($query);
     while ($record = $result->fetch_assoc()) {
         $deadMysqlFiles[$record['relativePathHash']] = $record['id'];
         $fileTimestampsMysql[$record['relativePathHash']] = $record['filemtime'];
         // get the oldest directory timestamp stored in rawtagdata
         if (isset($directoryTimestampsMysql[$record['relativeDirectoryPathHash']]) === FALSE) {
             $directoryTimestampsMysql[$record['relativeDirectoryPathHash']] = 9999999999;
         }
         if ($record['directoryMtime'] < $directoryTimestampsMysql[$record['relativeDirectoryPathHash']]) {
             $directoryTimestampsMysql[$record['relativeDirectoryPathHash']] = $record['directoryMtime'];
         }
     }
     $dbFilePath = $app->config['mpd']['dbfile'];
     $this->updateJob(array('msg' => $app->ll->str('importer.testdbfile')));
     // check if we have a plaintext or gzipped mpd-databasefile
     $isBinary = testBinary($dbFilePath);
     if ($isBinary === TRUE) {
         $this->updateJob(array('msg' => $app->ll->str('importer.gunzipdbfile')));
         // decompress databasefile
         $bufferSize = 4096;
         // read 4kb at a time (raising this value may increase performance)
         $outFileName = APP_ROOT . 'cache/mpd-database-plaintext';
         // Open our files (in binary mode)
         $inFile = gzopen($app->config['mpd']['dbfile'], 'rb');
         $outFile = fopen($outFileName, 'wb');
         // Keep repeating until the end of the input file
         while (!gzeof($inFile)) {
             // Read buffer-size bytes
             // Both fwrite and gzread and binary-safe
             fwrite($outFile, gzread($inFile, $bufferSize));
         }
         // Files are done, close files
         fclose($outFile);
         gzclose($inFile);
         $dbFilePath = $outFileName;
     }
     $dbfile = explode("\n", file_get_contents($dbFilePath));
     $currentDirectory = "";
     $currentSong = "";
     $currentPlaylist = "";
     $currentSection = "";
     $dirs = array();
     //$songs = array();
     //$playlists = array();
     $dircount = 0;
     $unmodifiedFiles = 0;
     $level = -1;
     $opendirs = array();
     // set initial attributes
     $mtime = 0;
     $time = 0;
     $artist = '';
     $title = '';
     $track = '';
     $album = '';
     $date = '';
     $genre = '';
     $mtimeDirectory = 0;
     foreach ($dbfile as $line) {
         if (trim($line) === "") {
             continue;
             // skip empty lines
         }
         $attr = explode(": ", $line, 2);
         array_map('trim', $attr);
         if (count($attr === 1)) {
             switch ($attr[0]) {
                 case 'info_begin':
                     break;
                 case 'info_end':
                     break;
                 case 'playlist_end':
                     // TODO: what to do with playlists fetched by mpd-database???
                     //$playlists[] = $currentDirectory . DS . $currentPlaylist;
                     $currentPlaylist = "";
                     $currentSection = "";
                     break;
                 case 'song_end':
                     $this->itemCountChecked++;
                     // single music files directly in mpd-musicdir-root must not get a leading slash
                     $dirRelativePath = $currentDirectory === '' ? '' : $currentDirectory . DS;
                     $directoryHash = getFilePathHash($dirRelativePath);
                     // further we have to read directory-modified-time manually because there is no info
                     // about mpd-root-directory in mpd-database-file
                     $mtimeDirectory = $currentDirectory === '' ? filemtime($app->config['mpd']['musicdir']) : $mtimeDirectory;
                     $trackRelativePath = $dirRelativePath . $currentSong;
                     $trackHash = getFilePathHash($trackRelativePath);
                     $this->updateJob(array('msg' => 'processed ' . $this->itemCountChecked . ' files', 'currentfile' => $currentDirectory . DS . $currentSong, 'deadfiles' => count($deadMysqlFiles), 'unmodified_files' => $unmodifiedFiles));
                     $insertOrUpdateRawtagData = FALSE;
                     // compare timestamps of mysql-database-entry(rawtagdata) and mpddatabase
                     if (isset($fileTimestampsMysql[$trackHash]) === FALSE) {
                         cliLog('mpd-file does not exist in rawtagdata: ' . $trackRelativePath, 5);
                         $insertOrUpdateRawtagData = TRUE;
                     } else {
                         if ($mtime > $fileTimestampsMysql[$trackHash]) {
                             cliLog('mpd-file timestamp is newer: ' . $trackRelativePath, 5);
                             $insertOrUpdateRawtagData = TRUE;
                         }
                     }
                     if (isset($directoryTimestampsMysql[$directoryHash]) === FALSE) {
                         cliLog('mpd-directory does not exist in rawtagdata: ' . $dirRelativePath, 5);
                         $insertOrUpdateRawtagData = TRUE;
                     } else {
                         if ($mtimeDirectory > $directoryTimestampsMysql[$directoryHash]) {
                             cliLog('mpd-directory timestamp is newer: ' . $trackRelativePath, 5);
                             $insertOrUpdateRawtagData = TRUE;
                         }
                     }
                     if ($insertOrUpdateRawtagData === FALSE) {
                         // track has not been modified - no need for updating
                         unset($fileTimestampsMysql[$trackHash]);
                         unset($deadMysqlFiles[$trackHash]);
                         $unmodifiedFiles++;
                     } else {
                         $t = new Rawtagdata();
                         if (isset($deadMysqlFiles[$trackHash])) {
                             $t->setId($deadMysqlFiles[$trackHash]);
                             // file is alive - remove it from dead items
                             unset($deadMysqlFiles[$trackHash]);
                         }
                         $t->setArtist($artist);
                         $t->setTitle($title);
                         $t->setAlbum($album);
                         $t->setGenre($genre);
                         $t->setYear($date);
                         $t->setTrackNumber($track);
                         $t->setRelativePath($trackRelativePath);
                         $t->setRelativePathHash($trackHash);
                         $t->setRelativeDirectoryPath($dirRelativePath);
                         $t->setRelativeDirectoryPathHash($directoryHash);
                         $t->setDirectoryMtime($mtimeDirectory);
                         $t->setFilemtime($mtime);
                         $t->setMiliseconds($time * 1000);
                         $t->setlastScan(0);
                         $t->setImportStatus(1);
                         $t->update();
                         unset($t);
                         $this->itemCountProcessed++;
                     }
                     cliLog("#" . $this->itemCountChecked . " " . $currentDirectory . DS . $currentSong, 2);
                     //$songs[] = $currentDirectory . DS . $currentSong;
                     $currentSong = "";
                     $currentSection = "";
                     // reset song attributes
                     $mtime = 0;
                     $time = 0;
                     $artist = '';
                     $title = '';
                     $track = '';
                     $album = '';
                     $date = '';
                     $genre = '';
                     break;
                 default:
                     break;
             }
         }
         if (isset($attr[1]) === TRUE) {
             // believe it or not - some people store html in their tags
             $attr[1] = preg_replace('!\\s+!', ' ', trim(strip_tags($attr[1])));
         }
         switch ($attr[0]) {
             case 'directory':
                 $currentSection = "directory";
                 break;
             case 'begin':
                 $level++;
                 $opendirs = explode(DS, $attr[1]);
                 $currentSection = "directory";
                 $currentDirectory = $attr[1];
                 break;
             case 'song_begin':
                 $currentSection = "song";
                 $currentSong = $attr[1];
                 break;
             case 'playlist_begin':
                 $currentSection = "playlist";
                 $currentPlaylist = $attr[1];
                 break;
             case 'end':
                 $level--;
                 //$dirs[$currentDirectory] = TRUE;
                 $dircount++;
                 array_pop($opendirs);
                 $currentDirectory = join(DS, $opendirs);
                 $currentSection = "";
                 break;
             case 'mtime':
                 if ($currentSection == "directory") {
                     $mtimeDirectory = $attr[1];
                 } else {
                     $mtime = $attr[1];
                 }
                 break;
             case 'Time':
                 $time = $attr[1];
                 break;
             case 'Artist':
                 $artist = $attr[1];
                 break;
             case 'Title':
                 $title = $attr[1];
                 break;
             case 'Track':
                 $track = $attr[1];
                 break;
             case 'Album':
                 $album = $attr[1];
                 break;
             case 'Genre':
                 $genre = $attr[1];
                 break;
             case 'Date':
                 $date = $attr[1];
                 break;
         }
     }
     // delete dead items in table:rawtagdata & table:track
     if (count($deadMysqlFiles) > 0) {
         \Slimpd\Rawtagdata::deleteRecordsByIds($deadMysqlFiles);
         \Slimpd\Track::deleteRecordsByIds($deadMysqlFiles);
     }
     cliLog("dircount: " . $dircount);
     cliLog("songs: " . $this->itemCountChecked);
     //cliLog("playlists: " . count($playlists));
     # TODO: flag&handle dead items in mysql-database
     //cliLog("dead dirs: " . count($deadMysqlDirectories));
     cliLog("dead songs: " . count($deadMysqlFiles));
     #print_r($deadMysqlFiles);
     $this->itemCountTotal = $this->itemCountChecked;
     $this->finishJob(array('msg' => 'processed ' . $this->itemCountChecked . ' files', 'directorycount' => $dircount, 'deletedRecords' => count($deadMysqlFiles), 'unmodified_files' => $unmodifiedFiles), __FUNCTION__);
     // destroy large arrays
     unset($deadMysqlFiles);
     unset($fileTimestampsMysql);
     unset($directoryTimestampsMysql);
     return;
 }
Exemple #2
0
    $config['renderitems'] = array('genres' => \Slimpd\Genre::getInstancesForRendering($config['item']), 'labels' => \Slimpd\Label::getInstancesForRendering($config['item']), 'artists' => \Slimpd\Artist::getInstancesForRendering($config['item']), 'albums' => \Slimpd\Album::getInstancesForRendering($config['item']));
    $config['totalitems'] = \Slimpd\Track::getCountAll();
    $app->render('surrounding.twig', $config);
});
$app->get('/maintainance/albumdebug/:itemParams+', function ($itemParams) use($app, $config) {
    $config['action'] = 'maintainance.albumdebug';
    if (count($itemParams) === 1 && is_numeric($itemParams[0])) {
        $search = array('id' => (int) $itemParams[0]);
    }
    $config['album'] = \Slimpd\Album::getInstanceByAttributes($search);
    $tmp = \Slimpd\Track::getInstancesByAttributes(array('albumId' => $config['album']->getId()));
    $trackInstances = array();
    $rawTagDataInstances = array();
    foreach ($tmp as $t) {
        $config['itemlist'][$t->getId()] = $t;
        $config['itemlistraw'][$t->getId()] = \Slimpd\Rawtagdata::getInstanceByAttributes(array('id' => (int) $t->getId()));
    }
    #echo "<pre>" . print_r(array_keys($trackInstances),1) . "</pre>";
    unset($tmp);
    $config['discogstracks'] = array();
    $config['matchmapping'] = array();
    $discogsId = $app->request->get('discogsid');
    if ($discogsId !== NULL) {
        /* possible usecases:
         * we have same track amount on local side and discogs side
         *   each local track matches to one discogs track
         *   one ore more local track does not have a match on the discogs side
         *   two local tracks matches one discogs-track 
         * 
         * we have more tracks on the local side
         *   we have dupes on the local side