diff --git a/Changelog b/Changelog index 5e2a2e38c..93bd0a634 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,56 @@ -1.8.2 - May 25, 2011 +1.9.0 - ???, 2011 + +The cool stuff: + * New file storage system. + * Human-readable file structure. The directory structure and file names on disk are now + human-readable. This means you can easily find files using your file browser on your + server. + + * Magic file synchronization. Edits to your files are automatically noticed by Airtime. If + you edit any files on disk, such as trimming the length of a track, Airtime will + automatically notice this and adjust the playlist lengths and shows for that audio file. + + * Auto-import and multiple-directory support. You can set any number of directories to be + watched by Airtime. Any new files you add to watched directories will be automatically + imported into Airtime, and any deleted files will be automatically removed. + + * Graceful recovery from reboot. If the playout engine starts up and detects that a show + should be playing at the current time, it will skip to the right point in the track and + start playing. Previously, Airtime would not play anything until the next show started. + This also fixes a problem where the metadata on the stream was lost when a file had + cue-in/out values set. Thanks to the Liquidsoap developers for implementing the ability + to do all of this! + + * Output to Shoutcast. Now both Shoutcast and Icecast are supported. + + * No more rebooting after install! Airtime now uses standard SystemV initd scripts instead of + non-standard daemontools. This also makes for a much faster install. + + * Extensible daemon monitoring system. The tool "monit" is being used to monitor the + daemon processes(playout engine, media monitor, etc) and automatically restart them in the + unlikely event that a daemon crashes. It also allows you to easily add your own actions when + something happens with a daemon. For example, you could send yourself an email notification if + a daemon process dies. + +Improvements: + * Cumulative time shown on playlists. The Playlist Builder now shows the total time since + the beginning of the playlist for each song. + + * "End Time" instead of "Duration". In the Add/Edit Show dialog, we replaced the "Duration" + field with "End Time". Users reported that this was a much more intuitive way to schedule the + show. Duration is still shown as a read-only field. + + * Feedback & promotion system. Airtime now includes a way to send feedback and promote your + site on the Sourcefabric web page. This will greatly enhance our ability to understand who is + using the software, which in turn will allow us to make appropriate features and receive grant + funding. + +Bug fixes: + * Fixed bug where you couldnt import a file with a name longer than 255 characters. + * Fixed bug where searching an audio archive of 15K+ files was slow. + + +1.8.2 - June 8, 2011 Highlights: * Improvements: - You can now download audio files from the search screen and from the "Show Content" screen. @@ -23,7 +75,8 @@ Highlights: - Fixed problem with Record Check box occasionally being greyed-out when creating new show - Fixed a problem with default genre not being applied to recorded shows - Fixed a problem where shows repeating bi-weekly or monthly did not update properly when edited. - + - Fixed problem when a user changed the name of a recorded show right before it started playing would cause the recorded audio not to be linked to the show. + - and many more... 1.8.1 - May 2, 2011 * Fixed issue where an track's progress bar would keep updating, even if the track was no longer playing. diff --git a/install/install_twitter_plugin.php b/install/install_twitter_plugin.php deleted file mode 100644 index 1c473fb2b..000000000 --- a/install/install_twitter_plugin.php +++ /dev/null @@ -1,39 +0,0 @@ -/dev/null 2>&1'; -$old_regex = '/ui_twitterCron\.php/'; - -$cron = new Cron(); -$access = $cron->openCrontab('write'); -if ($access != 'write') { - do { - $r = $cron->forceWriteable(); - } while ($r); -} - -foreach ($cron->ct->getByType(CRON_CMD) as $id => $line) { - if (preg_match($old_regex, $line['command'])) { - echo " removing old entry\n"; - $cron->ct->delEntry($id); - } -} -echo " adding new entry\n"; -$cron->ct->addCron($m, $h, $dom, $mon, $dow, $command); -$cron->closeCrontab(); -echo "Done.\n"; - diff --git a/install/uninstall_twitter_plugin.php b/install/uninstall_twitter_plugin.php deleted file mode 100644 index 6fd9c6731..000000000 --- a/install/uninstall_twitter_plugin.php +++ /dev/null @@ -1,31 +0,0 @@ -openCrontab('write'); -if ($access != 'write') { - do { - $r = $cron->forceWriteable(); - } while ($r); -} - -foreach ($cron->ct->getByType(CRON_CMD) as $id => $line) { - if (preg_match($old_regex, $line['command'])) { - echo " removing cron entry\n"; - $cron->ct->delEntry($id); - } -} - -$cron->closeCrontab(); -echo "Done.\n"; diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index d9ca1aa90..ef9c22935 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -145,15 +145,22 @@ class MetadataExtractor: self.logger.error('Filepath %s', m['MDATA_KEY_FILEPATH']) def get_md_from_file(self, filepath): + + self.logger.info("getting info about file %s", filepath) + md = {} md5 = self.get_md5(filepath) md['MDATA_KEY_MD5'] = md5 file_info = mutagen.File(filepath, easy=True) - attrs = self.mutagen2airtime - for key in file_info.keys() : - if key in attrs : - md[attrs[key]] = file_info[key][0] + + self.logger.info(file_info) + + #check if file has any metadata + if file_info is not None: + for key in file_info.keys() : + if key in self.mutagen2airtime : + md[self.mutagen2airtime[key]] = file_info[key][0] if 'MDATA_KEY_TITLE' not in md: #get rid of file extention from original name, name might have more than 1 '.' in it. @@ -283,10 +290,14 @@ class AirtimeNotifier(Notifier): def walk_newly_watched_directory(self, directory): + mm = self.proc_fun() + for (path, dirs, files) in os.walk(directory): for filename in files: full_filepath = path+"/"+filename - self.update_airtime({'filepath': full_filepath, 'mode': MODE_CREATE}) + + if mm.is_audio_file(full_filepath): + self.update_airtime({'filepath': full_filepath, 'mode': MODE_CREATE}) class MediaMonitor(ProcessEvent):