Merge branch 'devel' of dev.sourcefabric.org:airtime into devel
This commit is contained in:
commit
ece84a04c5
8 changed files with 73 additions and 56 deletions
|
@ -417,6 +417,10 @@ class AirTimeApiClient(ApiClientInterface):
|
|||
|
||||
return response
|
||||
|
||||
#returns a list of all db files for a given directory in JSON format:
|
||||
#{"files":["path/to/file1", "path/to/file2"]}
|
||||
#Note that these are relative paths to the given directory. The full
|
||||
#path is not returned.
|
||||
def list_all_db_files(self, dir_id):
|
||||
logger = logging.getLogger()
|
||||
try:
|
||||
|
|
|
@ -31,7 +31,7 @@ class AirtimeMediaMonitorBootstrap():
|
|||
|
||||
def get_list_of_watched_dirs(self):
|
||||
json = self.api_client.list_all_watched_dirs()
|
||||
return json["dirs"]
|
||||
return json["dirs"]
|
||||
|
||||
def check_for_diff(self, dir_id, dir):
|
||||
#set to hold new and/or modified files. We use a set to make it ok if files are added
|
||||
|
@ -46,14 +46,11 @@ class AirtimeMediaMonitorBootstrap():
|
|||
for file in files['files']:
|
||||
db_known_files_set.add(file)
|
||||
|
||||
|
||||
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable" % dir
|
||||
stdout = self.execCommandAndReturnStdOut(command)
|
||||
new_files = stdout.split('\n')
|
||||
new_files = self.pe.scan_dir_for_new_files(dir)
|
||||
all_files_set = set()
|
||||
for file_path in new_files:
|
||||
if len(file_path.strip(" \n")) > 0:
|
||||
all_files_set.add(file_path)
|
||||
all_files_set.add(file_path[len(dir)+1:])
|
||||
|
||||
|
||||
if os.path.exists("/var/tmp/airtime/.media_monitor_boot"):
|
||||
|
@ -65,12 +62,13 @@ class AirtimeMediaMonitorBootstrap():
|
|||
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable" % dir
|
||||
|
||||
stdout = self.execCommandAndReturnStdOut(command)
|
||||
|
||||
new_files = stdout.split('\n')
|
||||
|
||||
stdout = unicode(stdout, "utf_8")
|
||||
|
||||
new_files = stdout.splitlines()
|
||||
|
||||
for file_path in new_files:
|
||||
if len(file_path.strip(" \n")) > 0:
|
||||
new_and_modified_files.add(file_path)
|
||||
new_and_modified_files.add(file_path[len(dir)+1:])
|
||||
|
||||
#new_and_modified_files gives us a set of files that were either copied or modified
|
||||
#since the last time media-monitor was running. These files were collected based on
|
||||
|
@ -91,13 +89,15 @@ class AirtimeMediaMonitorBootstrap():
|
|||
open("/var/tmp/airtime/.media_monitor_boot","w")
|
||||
|
||||
for file_path in deleted_files_set:
|
||||
self.pe.handle_removed_file(False, file_path)
|
||||
self.pe.handle_removed_file(False, "%s/%s" % (dir, file_path))
|
||||
|
||||
for file_path in new_files_set:
|
||||
file_path = "%s/%s" % (dir, file_path)
|
||||
if os.path.exists(file_path):
|
||||
self.pe.handle_created_file(False, os.path.basename(file_path), file_path)
|
||||
|
||||
for file_path in modified_files_set:
|
||||
file_path = "%s/%s" % (dir, file_path)
|
||||
if os.path.exists(file_path):
|
||||
self.pe.handle_modified_file(False, os.path.basename(file_path), file_path)
|
||||
|
||||
|
|
|
@ -66,13 +66,10 @@ class AirtimeNotifier(Notifier):
|
|||
|
||||
elif m['event_type'] == "new_watch":
|
||||
mm = self.proc_fun()
|
||||
if mm.has_correct_permissions(m['directory']):
|
||||
self.logger.info("AIRTIME NOTIFIER add watched folder event " + m['directory'])
|
||||
self.walk_newly_watched_directory(m['directory'])
|
||||
self.logger.info("AIRTIME NOTIFIER add watched folder event " + m['directory'])
|
||||
self.walk_newly_watched_directory(m['directory'])
|
||||
|
||||
mm.watch_directory(m['directory'])
|
||||
else:
|
||||
self.logger.warn("filepath '%s' has does not have sufficient read permissions. Ignoring.", full_filepath)
|
||||
mm.watch_directory(m['directory'])
|
||||
|
||||
elif m['event_type'] == "remove_watch":
|
||||
watched_directory = m['directory'].encode('utf-8')
|
||||
|
|
|
@ -75,12 +75,25 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
else:
|
||||
return False
|
||||
|
||||
#file needs to be readable by all users, and directories
|
||||
#up to this file needs to be readable AND executable by all
|
||||
#users.
|
||||
#check if file is readable by "nobody"
|
||||
def has_correct_permissions(self, filepath):
|
||||
st = os.stat(filepath)
|
||||
return bool(st.st_mode & stat.S_IROTH)
|
||||
#drop root permissions and become "nobody"
|
||||
os.seteuid(65534)
|
||||
|
||||
try:
|
||||
open(filepath)
|
||||
readable = True
|
||||
except IOError:
|
||||
self.logger.warn("File does not have correct permissions: '%s'", filepath)
|
||||
readable = False
|
||||
except Exception, e:
|
||||
self.logger.error("Unexpected exception thrown: %s", e)
|
||||
readable = False
|
||||
finally:
|
||||
#reset effective user to root
|
||||
os.seteuid(0)
|
||||
|
||||
return readable
|
||||
|
||||
def set_needed_file_permissions(self, item, is_dir):
|
||||
|
||||
|
@ -98,8 +111,7 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
os.chmod(item, 0666)
|
||||
|
||||
except Exception, e:
|
||||
self.logger.error("Failed to change file's owner/group/permissions.")
|
||||
self.logger.error(item)
|
||||
self.logger.error("Failed to change file's owner/group/permissions. %s", e)
|
||||
finally:
|
||||
os.umask(omask)
|
||||
|
||||
|
@ -247,7 +259,7 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
|
||||
|
||||
def organize_new_file(self, pathname):
|
||||
self.logger.info("Processing new file: %s", pathname)
|
||||
self.logger.info(u"Organizing new file: %s", pathname)
|
||||
file_md = self.md_manager.get_md_from_file(pathname)
|
||||
|
||||
if file_md is not None:
|
||||
|
@ -255,7 +267,7 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
# file_md['MDATA_KEY_CREATOR'] == "AIRTIMERECORDERSOURCEFABRIC".encode('utf-8')
|
||||
filepath = self.create_file_path(pathname, file_md)
|
||||
|
||||
self.logger.debug("Moving from %s to %s", pathname, filepath)
|
||||
self.logger.debug(u"Moving from %s to %s", pathname, filepath)
|
||||
self.move_file(pathname, filepath)
|
||||
else:
|
||||
self.logger.warn("File %s, has invalid metadata", pathname)
|
||||
|
@ -306,6 +318,20 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
else:
|
||||
#show dragged from unwatched folder into a watched folder. Do not "organize".
|
||||
self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': event.pathname, 'is_recorded_show': False})
|
||||
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.
|
||||
#need to scan the entire directory for files.
|
||||
files = self.scan_dir_for_new_files(event.pathname)
|
||||
if self.is_parent_directory(event.pathname, self.config.organize_directory):
|
||||
for file in files:
|
||||
self.organize_new_file(file)
|
||||
else:
|
||||
for file in files:
|
||||
self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': file, 'is_recorded_show': False})
|
||||
|
||||
|
||||
|
||||
|
||||
def process_IN_DELETE(self, event):
|
||||
self.logger.info("process_IN_DELETE: %s", event)
|
||||
|
@ -337,6 +363,14 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
f = open(file, 'w')
|
||||
f.write(string)
|
||||
f.close()
|
||||
|
||||
def scan_dir_for_new_files(self, dir):
|
||||
command = 'find "%s" -type f -iname "*.ogg" -o -iname "*.mp3" -readable' % dir.replace('"', '\\"')
|
||||
self.logger.debug(command)
|
||||
stdout = self.execCommandAndReturnStdOut(command)
|
||||
stdout = unicode(stdout, "utf_8")
|
||||
|
||||
return stdout.splitlines()
|
||||
|
||||
def notifier_loop_callback(self, notifier):
|
||||
if len(self.file_events) > 0:
|
||||
|
|
|
@ -53,7 +53,7 @@ s = map_metadata(append_title, s)
|
|||
|
||||
|
||||
if output_sound_device then
|
||||
ignore(out(s))
|
||||
ignore(output.alsa(s))
|
||||
end
|
||||
|
||||
if output_icecast_mp3 then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue