Example #1
0
 public static function import($new_songs, $force = false)
 {
     $db_stats = array('skipped' => 0, 'updated' => 0, 'inserted' => 0, 'deleted' => 0);
     if (empty($new_songs)) {
         return false;
     }
     Debug::startTimer('Import data into database');
     $em = self::getEntityManager();
     $existing_hashes = self::getHashes();
     $existing_ids = self::getIds();
     $unused_hashes = $existing_hashes;
     $song_ids = Song::getIds();
     $i = 0;
     foreach ($new_songs as $song_hash => $processed) {
         if (!in_array($song_hash, $song_ids)) {
             Song::getOrCreate($processed);
         }
         if (isset($existing_hashes[$song_hash])) {
             if ($force && $existing_hashes[$song_hash] == $processed['id']) {
                 $db_stats['updated']++;
                 $record = self::find($processed['id']);
             } else {
                 $db_stats['skipped']++;
                 $record = null;
             }
         } else {
             if (isset($existing_ids[$processed['id']])) {
                 $db_stats['updated']++;
                 $record = self::find($processed['id']);
             } else {
                 $db_stats['inserted']++;
                 $record = new self();
             }
         }
         if ($record instanceof self) {
             $existing_ids[$processed['id']] = $processed['hash'];
             $existing_hashes[$processed['hash']] = $processed['id'];
             $record->fromArray($processed);
             $em->persist($record);
         }
         unset($unused_hashes[$song_hash]);
         $i++;
         if ($i % 200 == 0) {
             $em->flush();
             $em->clear();
         }
     }
     $em->flush();
     $em->clear();
     // Clear out any songs not found.
     $hashes_remaining = array_keys($unused_hashes);
     $db_stats['deleted'] = count($hashes_remaining);
     $em->createQuery('DELETE FROM ' . __CLASS__ . ' e WHERE e.hash IN (:hashes)')->setParameter('hashes', $hashes_remaining)->execute();
     Debug::endTimer('Import data into database');
     Debug::print_r($db_stats);
     return $db_stats;
 }
Example #2
0
 /**
  * Process a single audio stream's NowPlaying info.
  *
  * @param StationStream $stream
  * @param Station $station
  * @return array Structured NowPlaying Data
  */
 public static function processAudioStream(StationStream $stream, Station $station, $force = false)
 {
     $current_np_data = (array) $stream->nowplaying_data;
     // Only process non-default streams on odd-numbered "segments" to improve performance.
     if (!$stream->is_default && !$force && NOWPLAYING_SEGMENT % 2 == 0 && !empty($current_np_data)) {
         return $current_np_data;
     }
     $np = StationStream::api($stream);
     $custom_class = Station::getStationClassName($station->name);
     $custom_adapter = '\\PVL\\RadioAdapter\\' . $custom_class;
     if (class_exists($custom_adapter)) {
         $np_adapter = new $custom_adapter($stream, $station);
     } elseif ($stream->type == "icecast") {
         $np_adapter = new \PVL\RadioAdapter\IceCast($stream, $station);
     } elseif ($stream->type == "icebreath") {
         $np_adapter = new \PVL\RadioAdapter\IceBreath($stream, $station);
     } elseif ($stream->type == "shoutcast2") {
         $np_adapter = new \PVL\RadioAdapter\ShoutCast2($stream, $station);
     } elseif ($stream->type == "shoutcast1") {
         $np_adapter = new \PVL\RadioAdapter\ShoutCast1($stream, $station);
     } else {
         return array();
     }
     Debug::log('Adapter Class: ' . get_class($np_adapter));
     $stream_np = $np_adapter->process();
     $np = array_merge($np, $stream_np['meta']);
     $np['listeners'] = $stream_np['listeners'];
     // Pull from current NP data if song details haven't changed.
     $current_song_hash = Song::getSongHash($stream_np['current_song']);
     if (strcmp($current_song_hash, $current_np_data['current_song']['id']) == 0) {
         $np['current_song'] = $current_np_data['current_song'];
         $np['song_history'] = $current_np_data['song_history'];
     } else {
         if (empty($stream_np['current_song']['text'])) {
             $np['current_song'] = array();
             $np['song_history'] = $station->getRecentHistory($stream);
         } else {
             // Register a new item in song history.
             $np['current_song'] = array();
             $np['song_history'] = $station->getRecentHistory($stream);
             // Determine whether to log this song play for analytics.
             $log_radio_play = $stream->is_default && $station->category == 'audio';
             $song_obj = Song::getOrCreate($stream_np['current_song'], $log_radio_play);
             $sh_obj = SongHistory::register($song_obj, $station, $stream, $np);
             // Compose "current_song" object for API.
             $current_song = Song::api($song_obj);
             $current_song['sh_id'] = $sh_obj->id;
             $current_song['score'] = SongVote::getScoreForStation($song_obj, $station);
             $vote_urls = array();
             $vote_functions = array('like', 'dislike', 'clearvote');
             foreach ($vote_functions as $vote_function) {
                 $vote_urls[$vote_function] = \PVL\Url::api(array('module' => 'api', 'controller' => 'song', 'action' => $vote_function, 'sh_id' => $sh_obj->id));
             }
             $current_song['vote_urls'] = $vote_urls;
             $external = $song_obj->getExternal();
             if ($external) {
                 $current_song['external'] = $song_obj->getExternal();
             }
             $np['current_song'] = $current_song;
         }
     }
     $stream->nowplaying_data = $np;
     return $np;
 }
Example #3
0
 /** @PrePersist */
 public function preSave()
 {
     $this->song = Song::getOrCreate(array('text' => $this->artist . ' - ' . $this->title, 'artist' => $this->artist, 'title' => $this->title));
 }
Example #4
0
 public function songconfirmAction()
 {
     // Handle files submitted directly to page.
     $ignore_files = (int) $this->getParam('ignore_files');
     $request = $this->di->get('request');
     if ($request->hasFiles() && !$ignore_files) {
         $this->_processSongUpload();
     }
     // Validate song identifier token.
     $token = $this->_getSongHashToken();
     if (!$this->_validateSongHash($token)) {
         return $this->redirectFromHere(array('action' => 'song'));
     }
     // Check that any stations were selected
     if (!$this->hasParam('stations')) {
         throw new \DF\Exception\DisplayOnly('You did not specify any stations!');
     }
     // Check for uploaded songs.
     $temp_dir_name = 'song_uploads';
     $temp_dir = DF_INCLUDE_TEMP . DIRECTORY_SEPARATOR . $temp_dir_name;
     $all_files = glob($temp_dir . DIRECTORY_SEPARATOR . $token . '*.mp3');
     if (empty($all_files)) {
         throw new \DF\Exception\DisplayOnly('No files were uploaded!');
     }
     $songs = array();
     $getId3 = new GetId3();
     $getId3->encoding = 'UTF-8';
     foreach ($all_files as $song_file_base) {
         $song_file_path = $temp_dir . DIRECTORY_SEPARATOR . basename($song_file_base);
         // Attempt to analyze the MP3.
         $audio = $getId3->analyze($song_file_path);
         if (isset($audio['error'])) {
             @unlink($song_file_path);
             throw new \DF\Exception\DisplayOnly(sprintf('Error at reading audio properties with GetId3: %s.', $audio['error'][0]));
         }
         if (isset($audio['tags']['id3v1']['title'])) {
             $song_data = array('title' => $audio['tags']['id3v1']['title'][0], 'artist' => $audio['tags']['id3v1']['artist'][0]);
         } elseif (isset($audio['tags']['id3v2']['title'])) {
             $song_data = array('title' => $audio['tags']['id3v2']['title'][0], 'artist' => $audio['tags']['id3v2']['artist'][0]);
         } else {
             @unlink($song_file_path);
             continue;
         }
         // Check if existing submission exists.
         $song = Song::getOrCreate($song_data);
         $existing_submission = SongSubmission::getRepository()->findOneBy(array('hash' => $song->id));
         if ($existing_submission instanceof SongSubmission) {
             @unlink($song_file_path);
             continue;
         }
         // Create record in database.
         $metadata = array('File Format' => strtoupper($audio['fileformat']), 'Play Time' => $audio['playtime_string'], 'Bitrate' => round($audio['audio']['bitrate'] / 1024) . 'kbps', 'Bitrate Mode' => strtoupper($audio['audio']['bitrate_mode']), 'Channels' => $audio['audio']['channels'], 'Sample Rate' => $audio['audio']['sample_rate']);
         $record = new SongSubmission();
         $record->song = $song;
         $auth = $this->di->get('auth');
         $record->user = $auth->getLoggedInUser();
         $record->title = $song_data['title'];
         $record->artist = $song_data['artist'];
         $record->song_metadata = $metadata;
         $record->stations = $this->getParam('stations');
         $song_download_url = $record->uploadSong($song_file_path);
         $record->save();
         // Append information to e-mail to stations.
         $song_row = array('Download URL' => '<a href="' . $song_download_url . '" target="_blank">' . $song_download_url . '</a>', 'Title' => $song_data['title'], 'Artist' => $song_data['artist']) + $metadata;
         $songs[] = $song_row;
     }
     if (!empty($songs)) {
         // Notify all existing managers.
         $network_administrators = Action::getUsersWithAction('administer all');
         $email_to = Utilities::ipull($network_administrators, 'email');
         // Pull list of station managers for the specified stations.
         $station_managers = array();
         $short_names = Station::getShortNameLookup();
         foreach ($this->getParam('stations') as $station_key) {
             if (isset($short_names[$station_key])) {
                 $station_id = $short_names[$station_key]['id'];
                 $station = Station::find($station_id);
                 foreach ($station->managers as $manager) {
                     $station_managers[] = $manager->email;
                 }
             }
         }
         $email_to = array_merge($email_to, $station_managers);
         // Trigger e-mail notice.
         if (!empty($email_to)) {
             \DF\Messenger::send(array('to' => $email_to, 'subject' => 'New Song(s) Submitted to Station', 'template' => 'newsong', 'vars' => array('songs' => $songs)));
         }
     }
     // Have to manually call view because a view was already rendered (e-mail was sent).
     // TODO: Fix this. It's dumb.
     $this->view->songs = $songs;
     return $this->view->render('submit', 'songconfirm');
 }