Merge branch 'devel' of dev.sourcefabric.org:airtime into cc-2528-use-virtualenv-for-installing

Conflicts:
	python_apps/media-monitor/airtime-media-monitor
This commit is contained in:
James 2011-07-19 15:09:55 -04:00
commit 107c100cc4
35 changed files with 842 additions and 290 deletions

View file

@ -0,0 +1 @@
bin_dir = "/usr/lib/airtime/api_clients"

View file

@ -0,0 +1,25 @@
import os
import shutil
import sys
from configobj import ConfigObj
def get_current_script_dir():
return os.path.dirname(os.path.realpath(__file__))
def copy_dir(src_dir, dest_dir):
if (os.path.exists(dest_dir)) and (dest_dir != "/"):
shutil.rmtree(dest_dir)
if not (os.path.exists(dest_dir)):
print "Copying directory "+os.path.realpath(src_dir)+" to "+os.path.realpath(dest_dir)
shutil.copytree(src_dir, dest_dir)
current_script_dir = get_current_script_dir()
"""load config file"""
try:
config = ConfigObj("%s/../api_client.cfg" % current_script_dir)
except Exception, e:
print 'Error loading config file: ', e
sys.exit(1)
copy_dir("%s/../../api_clients"%current_script_dir, config["bin_dir"])

View file

@ -0,0 +1,21 @@
import os
import sys
from configobj import ConfigObj
def remove_path(path):
os.system('rm -rf "%s"' % path)
def get_current_script_dir():
return os.path.dirname(os.path.realpath(__file__))
current_script_dir = get_current_script_dir()
"""load config file"""
try:
config = ConfigObj("%s/../api_client.cfg" % current_script_dir)
except Exception, e:
print 'Error loading config file: ', e
sys.exit(1)
print "Removing API Client files"
remove_path(config["bin_dir"])

View file

@ -30,6 +30,8 @@ except Exception, e:
logger = logging.getLogger()
logger.info("\n\n*** Media Monitor bootup ***\n\n")
try:
config = AirtimeMediaConfig(logger)
api_client = api_client.api_client_factory(config.cfg)

View file

@ -8,7 +8,7 @@ virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
media_monitor_path="/usr/lib/airtime/media-monitor/"
media_monitor_script="MediaMonitor.py"
api_client_path="/usr/lib/airtime/pypo/"
api_client_path="/usr/lib/airtime/"
cd ${media_monitor_path}

View file

@ -6,7 +6,7 @@ from subprocess import Popen, PIPE
class AirtimeMediaMonitorBootstrap():
"""AirtimeMediaMonitorBootstrap constructor
Keyword Arguments:
logger -- reference to the media-monitor logging facility
pe -- reference to an instance of ProcessEvent
@ -17,36 +17,36 @@ class AirtimeMediaMonitorBootstrap():
self.pe = pe
self.api_client = api_client
self.mmc = mmc
"""On bootup we want to scan all directories and look for files that
weren't there or files that changed before media-monitor process
went offline.
"""
def scan(self):
directories = self.get_list_of_watched_dirs();
self.logger.info("watched directories found: %s", directories)
for id, dir in directories.iteritems():
self.logger.debug("%s, %s", id, dir)
self.sync_database_to_filesystem(id, dir)
"""Gets a list of files that the Airtime database knows for a specific directory.
You need to provide the directory's row ID, which is obtained when calling
You need to provide the directory's row ID, which is obtained when calling
get_list_of_watched_dirs function.
dir_id -- row id of the directory in the cc_watched_dirs database table
"""
def list_db_files(self, dir_id):
return self.api_client.list_all_db_files(dir_id)
"""
returns the path and the database row id for this path for all watched directories. Also
returns the path and the database row id for this path for all watched directories. Also
returns the Stor directory, which can be identified by its row id (always has value of "1")
"""
def get_list_of_watched_dirs(self):
json = self.api_client.list_all_watched_dirs()
return json["dirs"]
return json["dirs"]
"""
This function takes in a path name provided by the database (and its corresponding row id)
and reads the list of files in the local file system. Its purpose is to discover which files
@ -57,42 +57,42 @@ class AirtimeMediaMonitorBootstrap():
dir -- pathname of the directory
"""
def sync_database_to_filesystem(self, dir_id, dir):
"""
"""
set to hold new and/or modified files. We use a set to make it ok if files are added
twice. This is because some of the tests for new files return result sets that are not
mutually exclusive from each other.
"""
new_and_modified_files = set()
removed_files = set()
db_known_files_set = set()
files = self.list_db_files(dir_id)
for file in files['files']:
db_known_files_set.add(file)
new_files = self.mmc.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[len(dir):])
all_files_set.add(file_path[len(dir):])
if os.path.exists(self.mmc.timestamp_file):
"""find files that have been modified since the last time media-monitor process started."""
time_diff_sec = time.time() - os.path.getmtime(self.mmc.timestamp_file)
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable -mmin -%d" % (dir, time_diff_sec/60+1)
else:
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable" % dir
stdout = self.mmc.execCommandAndReturnStdOut(command)
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[len(dir)+1:])
new_and_modified_files.add(file_path[len(dir):])
"""
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
@ -101,28 +101,32 @@ class AirtimeMediaMonitorBootstrap():
not affect last modified timestamp). Lets get a list of files that are on the file-system
that the db has no record of, and vice-versa.
"""
deleted_files_set = db_known_files_set - all_files_set
new_files_set = all_files_set - db_known_files_set
modified_files_set = new_and_modified_files - new_files_set
self.logger.info("Deleted files: \n%s\n\n"%deleted_files_set)
self.logger.info("New files: \n%s\n\n"%new_files_set)
self.logger.info("Modified files: \n%s\n\n"%modified_files_set)
self.logger.info("Modified files: \n%s\n\n"%modified_files_set)
#"touch" file timestamp
self.mmc.touch_index_file()
for file_path in deleted_files_set:
self.pe.handle_removed_file(False, "%s/%s" % (dir, file_path))
self.pe.handle_removed_file(False, "%s%s" % (dir, file_path))
deleted_files_set.clear()
for file_path in new_files_set:
file_path = "%s/%s" % (dir, file_path)
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)
new_files_set.clear()
for file_path in modified_files_set:
file_path = "%s/%s" % (dir, file_path)
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)
modified_files_set.clear()

View file

@ -112,7 +112,7 @@ class AirtimeNotifier(Notifier):
self.logger.info("Adding file to ignore: %s ", filepath)
mm.add_filepath_to_ignore(filepath)
if m['delete'] == "true":
if m['delete']:
self.logger.info("Deleting file: %s ", filepath)
os.unlink(filepath)

View file

@ -57,6 +57,9 @@ class AirtimeProcessEvent(ProcessEvent):
#file created is a tmp file which will be modified and then moved back to the original filename.
#Easy Tag creates this when changing metadata of ogg files.
self.temp_files[pathname] = None
#file is being overwritten/replaced in GUI.
elif "goutputstream" in pathname:
self.temp_files[pathname] = None
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

View file

@ -1,44 +0,0 @@
from airtimefilemonitor.mediamonitorcommon import MediaMonitorCommon
from airtimefilemonitor.mediaconfig import AirtimeMediaConfig
import logging
import logging.config
import sys
import os
import json
import ConfigParser
import os.path
# configure logging
try:
logging.config.fileConfig("%s/logging.cfg"%os.path.dirname(__file__))
except Exception, e:
print 'Error configuring logging: ', e
sys.exit(1)
logger = logging.getLogger()
mmconfig = AirtimeMediaConfig(logger)
#get stor folder location from /etc/airtime/airtime.conf
config = ConfigParser.RawConfigParser()
config.read('/etc/airtime/airtime.conf')
stor_dir = config.get('general', 'base_files_dir') + "/stor"
mmconfig.storage_directory = os.path.normpath(stor_dir)
mmconfig.imported_directory = os.path.normpath(stor_dir + '/imported')
mmconfig.organize_directory = os.path.normpath(stor_dir + '/organize')
mmc = MediaMonitorCommon(mmconfig)
#read list of all files in stor location.....and one-by-one pass this through to
#mmc.organize_files. print out json encoding of before and after
pairs = []
for root, dirs, files in os.walk(mmconfig.storage_directory):
for f in files:
#print os.path.join(root, f)
#print mmc.organize_new_file(os.path.join(root, f))
pair = os.path.join(root, f), mmc.organize_new_file(os.path.join(root, f))
pairs.append(pair)
print json.dumps(pairs)

View file

@ -5,7 +5,7 @@ virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
ls_user="pypo"
export HOME="/var/tmp/airtime/pypo/"
api_client_path="/usr/lib/airtime/pypo/"
api_client_path="/usr/lib/airtime/"
ls_path="/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap"
ls_param="/usr/lib/airtime/pypo/bin/liquidsoap_scripts/ls_script.liq"

View file

@ -7,7 +7,7 @@ pypo_user="pypo"
# Location of pypo_cli.py Python script
pypo_path="/usr/lib/airtime/pypo/bin/"
api_client_path="/usr/lib/airtime/pypo/"
api_client_path="/usr/lib/airtime/"
pypo_script="pypo-cli.py"
cd ${pypo_path}
exec 2>&1

View file

@ -96,7 +96,6 @@ try:
sys.exit(1)
copy_dir("%s/.."%current_script_dir, config["bin_dir"]+"/bin/")
copy_dir("%s/../../api_clients"%current_script_dir, config["bin_dir"]+"/api_clients/")
print "Setting permissions"
os.system("chmod -R 755 "+config["bin_dir"])

View file

@ -10,7 +10,7 @@ recorder_user="pypo"
recorder_path="/usr/lib/airtime/show-recorder/"
recorder_script="recorder.py"
api_client_path="/usr/lib/airtime/pypo/"
api_client_path="/usr/lib/airtime/"
cd ${recorder_path}
exec 2>&1