From a514e3b60aa243da13f8d389d41972b5c947c04e Mon Sep 17 00:00:00 2001 From: Naomi Aro Date: Mon, 7 May 2012 18:19:18 +0200 Subject: [PATCH 1/5] CC-3776 : Current Recorded show is resizeable on the calendar (by dragging) --- airtime_mvc/application/models/Show.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 8d9645c00..6794fe756 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -1583,7 +1583,7 @@ class Application_Model_Show { $interval = $p_start->diff($p_end); $days = $interval->format('%a'); $shows = Application_Model_Show::getShows($p_start, $p_end); - $today_timestamp = gmdate("Y-m-d H:i:s"); + $nowEpoch = time(); foreach ($shows as $show) { $options = array(); @@ -1593,8 +1593,17 @@ class Application_Model_Show { if (intval($days) <= 7) { $options["percent"] = Application_Model_Show::getPercentScheduled($show["starts"], $show["ends"], $show["time_filled"]); } + + $startsDT = new DateTime($show["starts"], new DateTimeZone("UTC")); + $endsDT = new DateTime($show["ends"], new DateTimeZone("UTC")); + + $startsEpoch = intval($startsDT->format("U")); + $endsEpoch = intval($endsDT->format("U")); - if ($p_editable && (strtotime($today_timestamp) < strtotime($show["ends"]))) { + if ($p_editable && $show["record"] && $nowEpoch < $endsEpoch) { + $options["editable"] = false; + } + else if ($p_editable && $nowEpoch < $endsEpoch) { $options["editable"] = true; } $events[] = Application_Model_Show::makeFullCalendarEvent($show, $options); From c466b946a00c99ec3352212b90b9a12591f93a43 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 7 May 2012 13:12:20 -0400 Subject: [PATCH 2/5] CC-3770: Make sure files in /srv/airtime/stor have world-readable permissions. -change read permissions on files right after they're uploaded --- airtime_mvc/application/models/StoredFile.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index d699b47d1..b09421aca 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -879,6 +879,11 @@ Logging::log("getting media! - 2"); $audio_stor = Application_Common_OsPath::join($stor, "organize", $fileName); Logging::log("copyFileToStor: moving file $audio_file to $audio_stor"); + + if (chmod($audio_file, 0644) === false){ + Logging::log("Warning: couldn't change permissions of $audio_file to 0644"); + } + //Martin K.: changed to rename: Much less load + quicker since this is an atomic operation $r = @rename($audio_file, $audio_stor); From 91d1dfbbfaf7508329a261cfe627a22f6cf8182d Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 7 May 2012 13:54:39 -0400 Subject: [PATCH 3/5] CC-3770: Make sure files in /srv/airtime/stor have world-readable permissions. -fixed --- .../airtimefilemonitor/airtimeprocessevent.py | 109 +++++++++--------- .../airtimefilemonitor/mediamonitorcommon.py | 38 ++++++ 2 files changed, 92 insertions(+), 55 deletions(-) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index 6d1ffbfa8..d816e3edf 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -134,8 +134,9 @@ class AirtimeProcessEvent(ProcessEvent): #file is being overwritten/replaced in GUI. elif "goutputstream" in pathname: self.temp_files[pathname] = None - elif self.mmc.is_audio_file(pathname) and self.mmc.is_readable(pathname, False): + elif self.mmc.is_audio_file(pathname): if self.mmc.is_parent_directory(pathname, self.config.organize_directory): + #file was created in /srv/airtime/stor/organize. Need to process and move #to /srv/airtime/stor/imported oldPath = pathname @@ -144,21 +145,18 @@ class AirtimeProcessEvent(ProcessEvent): #delete files from organize if they can not be read properly. if pathname is None: try: - self.logger.info("Deleting file because it cannot be read properly: %s", oldPath) + self.logger.warn("Deleting file because it cannot be read properly: %s", oldPath) os.remove(oldPath) - return except Exception, e: self.logger.error('Exception: %s', e) self.logger.error("traceback: %s", traceback.format_exc()) - - self.mmc.is_readable(pathname, dir) - is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) - self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) - - else: - #event is because of a created directory - if self.mmc.is_parent_directory(pathname, self.config.storage_directory): - self.mmc.is_readable(pathname, dir) + else: + #ensure file is world readable (Liquidsoap and Web UI preview) + if self.mmc.make_readable(pathname): + is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) + self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) + else: + self.logger.warn("Couldn't add %s because failed to change file permissions", pathname) def process_IN_MODIFY(self, event): # if IN_MODIFY is followed by IN_CREATE, it's not true modify event @@ -175,7 +173,7 @@ class AirtimeProcessEvent(ProcessEvent): self.create_dict[pathname] = time.time() if not dir and not self.mmc.is_parent_directory(pathname, self.config.organize_directory): self.logger.info("Modified: %s", pathname) - if self.mmc.is_audio_file(name): + if self.mmc.is_audio_file(name) and self.mmc.make_readable(pathname): self.file_events.append({'filepath': pathname, 'mode': self.config.MODE_MODIFY}) # if change is detected on /etc/mtab, we check what mount(file system) was added/removed @@ -238,51 +236,52 @@ class AirtimeProcessEvent(ProcessEvent): self.handle_mount_change() if not event.dir: - if self.mmc.is_audio_file(event.name) and self.mmc.is_readable(event.pathname, False): - if event.cookie in self.temp_files: - self.file_events.append({'filepath': event.pathname, 'mode': self.config.MODE_MODIFY}) - del self.temp_files[event.cookie] - elif event.cookie in self.cookies_IN_MOVED_FROM: - #files original location was also in a watched directory - del self.cookies_IN_MOVED_FROM[event.cookie] - if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): - filepath = self.mmc.organize_new_file(event.pathname) - - #delete files from organize if they can not be read properly. - if filepath is None: - try: - self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) - os.remove(event.pathname) - return - except Exception, e: - self.logger.error('Exception: %s', e) - self.logger.error("traceback: %s", traceback.format_exc()) + if self.mmc.is_audio_file(event.name): + if self.mmc.make_readable(event.pathname): + if event.cookie in self.temp_files: + self.file_events.append({'filepath': event.pathname, 'mode': self.config.MODE_MODIFY}) + del self.temp_files[event.cookie] + elif event.cookie in self.cookies_IN_MOVED_FROM: + #files original location was also in a watched directory + del self.cookies_IN_MOVED_FROM[event.cookie] + if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): + filepath = self.mmc.organize_new_file(event.pathname) + + #delete files from organize if they can not be read properly. + if filepath is None: + try: + self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) + os.remove(event.pathname) + return + except Exception, e: + self.logger.error('Exception: %s', e) + self.logger.error("traceback: %s", traceback.format_exc()) - else: - filepath = event.pathname + else: + filepath = event.pathname - if (filepath is not None): - self.file_events.append({'filepath': filepath, 'mode': self.config.MODE_MOVED}) - else: - if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): - filepath = self.mmc.organize_new_file(event.pathname) - - #delete files from organize if they can not be read properly. - if filepath is None: - try: - self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) - os.remove(event.pathname) - return - except Exception, e: - self.logger.error('Exception: %s', e) - self.logger.error("traceback: %s", traceback.format_exc()) + if (filepath is not None): + self.file_events.append({'filepath': filepath, 'mode': self.config.MODE_MOVED}) else: - #show dragged from unwatched folder into a watched folder. Do not "organize".:q! - if self.mmc.is_parent_directory(event.pathname, self.config.recorded_directory): - is_recorded = True - else : - is_recorded = False - self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': event.pathname, 'is_recorded_show': is_recorded}) + if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): + filepath = self.mmc.organize_new_file(event.pathname) + + #delete files from organize if they can not be read properly. + if filepath is None: + try: + self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) + os.remove(event.pathname) + return + except Exception, e: + self.logger.error('Exception: %s', e) + self.logger.error("traceback: %s", traceback.format_exc()) + else: + #show dragged from unwatched folder into a watched folder. Do not "organize".:q! + if self.mmc.is_parent_directory(event.pathname, self.config.recorded_directory): + is_recorded = True + else: + is_recorded = False + self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': event.pathname, 'is_recorded_show': is_recorded}) else: #When we move a directory into a watched_dir, we only get a notification that the dir was created, #and no additional information about files that came along with that directory. diff --git a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py index fdd83de6b..92f292337 100644 --- a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py +++ b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py @@ -83,6 +83,44 @@ class MediaMonitorCommon: except Exception, e: self.logger.warn("Failed to check owner/group/permissions for %s", item) return False + + def make_file_readable(self, pathname, is_dir): + if is_dir: + #set to 755 + os.chmod(pathname, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR | stat.S_IRGRP|stat.S_IXGRP | stat.S_IROTH|stat.S_IXOTH) + else: + #set to 644 + os.chmod(pathname, stat.S_IRUSR|stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + + def make_readable(self, pathname): + """ + Should only call this function if is_readable() returns False. This function + will attempt to make the file world readable by modifying the file's permission's + as well as the file's parent directory permissions. We should only call this function + on files in Airtime's stor directory, not watched directories! + + Returns True if we were able to make the file world readable. False otherwise. + """ + original_file = pathname + is_dir = False + try: + while not is_readable(original_file, is_dir): + #Not readable. Make appropriate permission changes. + + self.make_file_readable(pathname, is_dir) + + dirname = os.path.dirname(pathname) + if dirname == pathname: + #most likey reason for this is that we've hit '/'. Avoid infinite loop by terminating loop + raise Exception() + else: + pathname = dirname + is_dir = True + except Exception, e: + #something went wrong while we were trying to make world readable. + return False + + return True #checks if path is a directory, and if it doesnt exist, then creates it. #Otherwise prints error to log file. From d997047f5ebf3e0df6e7dc551c4f3fdcbdd37c88 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 7 May 2012 14:25:49 -0400 Subject: [PATCH 4/5] CC-3770: Make sure files in /srv/airtime/stor have world-readable permissions. -fixed --- .../airtimefilemonitor/airtimeprocessevent.py | 93 +++++++++---------- .../airtimefilemonitor/mediamonitorcommon.py | 6 +- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index d816e3edf..271976c4a 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -152,11 +152,9 @@ class AirtimeProcessEvent(ProcessEvent): self.logger.error("traceback: %s", traceback.format_exc()) else: #ensure file is world readable (Liquidsoap and Web UI preview) - if self.mmc.make_readable(pathname): - is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) - self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) - else: - self.logger.warn("Couldn't add %s because failed to change file permissions", pathname) + is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) + self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) + def process_IN_MODIFY(self, event): # if IN_MODIFY is followed by IN_CREATE, it's not true modify event @@ -173,7 +171,7 @@ class AirtimeProcessEvent(ProcessEvent): self.create_dict[pathname] = time.time() if not dir and not self.mmc.is_parent_directory(pathname, self.config.organize_directory): self.logger.info("Modified: %s", pathname) - if self.mmc.is_audio_file(name) and self.mmc.make_readable(pathname): + if self.mmc.is_audio_file(name): self.file_events.append({'filepath': pathname, 'mode': self.config.MODE_MODIFY}) # if change is detected on /etc/mtab, we check what mount(file system) was added/removed @@ -237,51 +235,50 @@ class AirtimeProcessEvent(ProcessEvent): if not event.dir: if self.mmc.is_audio_file(event.name): - if self.mmc.make_readable(event.pathname): - if event.cookie in self.temp_files: - self.file_events.append({'filepath': event.pathname, 'mode': self.config.MODE_MODIFY}) - del self.temp_files[event.cookie] - elif event.cookie in self.cookies_IN_MOVED_FROM: - #files original location was also in a watched directory - del self.cookies_IN_MOVED_FROM[event.cookie] - if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): - filepath = self.mmc.organize_new_file(event.pathname) - - #delete files from organize if they can not be read properly. - if filepath is None: - try: - self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) - os.remove(event.pathname) - return - except Exception, e: - self.logger.error('Exception: %s', e) - self.logger.error("traceback: %s", traceback.format_exc()) + if event.cookie in self.temp_files: + self.file_events.append({'filepath': event.pathname, 'mode': self.config.MODE_MODIFY}) + del self.temp_files[event.cookie] + elif event.cookie in self.cookies_IN_MOVED_FROM: + #files original location was also in a watched directory + del self.cookies_IN_MOVED_FROM[event.cookie] + if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): + filepath = self.mmc.organize_new_file(event.pathname) + + #delete files from organize if they can not be read properly. + if filepath is None: + try: + self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) + os.remove(event.pathname) + return + except Exception, e: + self.logger.error('Exception: %s', e) + self.logger.error("traceback: %s", traceback.format_exc()) - else: - filepath = event.pathname - - if (filepath is not None): - self.file_events.append({'filepath': filepath, 'mode': self.config.MODE_MOVED}) else: - if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): - filepath = self.mmc.organize_new_file(event.pathname) - - #delete files from organize if they can not be read properly. - if filepath is None: - try: - self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) - os.remove(event.pathname) - return - except Exception, e: - self.logger.error('Exception: %s', e) - self.logger.error("traceback: %s", traceback.format_exc()) + filepath = event.pathname + + if (filepath is not None): + self.file_events.append({'filepath': filepath, 'mode': self.config.MODE_MOVED}) + else: + if self.mmc.is_parent_directory(event.pathname, self.config.organize_directory): + filepath = self.mmc.organize_new_file(event.pathname) + + #delete files from organize if they can not be read properly. + if filepath is None: + try: + self.logger.info("Deleting file because it cannot be read properly: %s", event.pathname) + os.remove(event.pathname) + return + except Exception, e: + self.logger.error('Exception: %s', e) + self.logger.error("traceback: %s", traceback.format_exc()) + else: + #show dragged from unwatched folder into a watched folder. Do not "organize".:q! + if self.mmc.is_parent_directory(event.pathname, self.config.recorded_directory): + is_recorded = True else: - #show dragged from unwatched folder into a watched folder. Do not "organize".:q! - if self.mmc.is_parent_directory(event.pathname, self.config.recorded_directory): - is_recorded = True - else: - is_recorded = False - self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': event.pathname, 'is_recorded_show': is_recorded}) + is_recorded = False + self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': event.pathname, 'is_recorded_show': is_recorded}) else: #When we move a directory into a watched_dir, we only get a notification that the dir was created, #and no additional information about files that came along with that directory. diff --git a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py index 92f292337..7ac2d9aec 100644 --- a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py +++ b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py @@ -104,9 +104,8 @@ class MediaMonitorCommon: original_file = pathname is_dir = False try: - while not is_readable(original_file, is_dir): + while not self.is_readable(original_file, is_dir): #Not readable. Make appropriate permission changes. - self.make_file_readable(pathname, is_dir) dirname = os.path.dirname(pathname) @@ -315,6 +314,9 @@ class MediaMonitorCommon: self.logger.debug("Moving from %s to %s", pathname, filepath) self.move_file(pathname, filepath) + if not self.mmc.make_readable(filepath): + self.logger.warn("Couldn't make filepath %s readable", pathname) + filepath = None else: filepath = None self.logger.warn("File %s, has invalid metadata", pathname) From ece93ac054b8fb71ec7a269b03dd91781a0ca8fb Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 7 May 2012 14:39:54 -0400 Subject: [PATCH 5/5] CC-3770: Make sure files in /srv/airtime/stor have world-readable permissions. -fix silly regression --- .../airtimefilemonitor/airtimeprocessevent.py | 10 +++++----- .../airtimefilemonitor/mediamonitorcommon.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index 271976c4a..43a665a59 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -134,7 +134,7 @@ class AirtimeProcessEvent(ProcessEvent): #file is being overwritten/replaced in GUI. elif "goutputstream" in pathname: self.temp_files[pathname] = None - elif self.mmc.is_audio_file(pathname): + elif self.mmc.is_audio_file(name): if self.mmc.is_parent_directory(pathname, self.config.organize_directory): #file was created in /srv/airtime/stor/organize. Need to process and move @@ -150,10 +150,10 @@ class AirtimeProcessEvent(ProcessEvent): except Exception, e: self.logger.error('Exception: %s', e) self.logger.error("traceback: %s", traceback.format_exc()) - else: - #ensure file is world readable (Liquidsoap and Web UI preview) - is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) - self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) + return + + is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory) + self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded}) def process_IN_MODIFY(self, event): diff --git a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py index 7ac2d9aec..d6ace676d 100644 --- a/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py +++ b/python_apps/media-monitor/airtimefilemonitor/mediamonitorcommon.py @@ -314,7 +314,7 @@ class MediaMonitorCommon: self.logger.debug("Moving from %s to %s", pathname, filepath) self.move_file(pathname, filepath) - if not self.mmc.make_readable(filepath): + if not self.make_readable(filepath): self.logger.warn("Couldn't make filepath %s readable", pathname) filepath = None else: