From 3a0f9ddcd1140fe3b2a1de58c9cfa8cf2fe71926 Mon Sep 17 00:00:00 2001 From: Naomi Date: Fri, 18 Mar 2011 17:15:12 -0400 Subject: [PATCH 01/74] CC-1987 : Automatic upload of recorded shows to Soundcloud Added fields to preference form for the station's soundcloud user/pass need to generalize file upload as commented out in the new Soundcloud.php file. --- .../controllers/PluploadController.php | 12 ++++--- .../controllers/PreferenceController.php | 5 ++- application/forms/Preferences.php | 31 +++++++++++++++++-- application/models/Preference.php | 27 +++++++++++++++- application/models/Soundcloud.php | 31 +++++++++++++++++++ 5 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 application/models/Soundcloud.php diff --git a/application/controllers/PluploadController.php b/application/controllers/PluploadController.php index fea649499..aae777f23 100644 --- a/application/controllers/PluploadController.php +++ b/application/controllers/PluploadController.php @@ -146,8 +146,7 @@ class PluploadController extends Zend_Controller_Action $storedFile->setMetadataBatch($metadata); - // Return JSON-RPC response - die('{"jsonrpc" : "2.0", "id" : '.$storedFile->getId().' }'); + return $storedFile; } public function indexAction() @@ -158,13 +157,18 @@ class PluploadController extends Zend_Controller_Action public function uploadAction() { $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; - $this->upload($upload_dir); + $file = $this->upload($upload_dir); + + die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); } public function uploadRecordedAction() { $upload_dir = ini_get("upload_tmp_dir"); - $this->upload($upload_dir); + $file = $this->upload($upload_dir); + + //$file->getRealFilePath(); + die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); } public function pluploadAction() diff --git a/application/controllers/PreferenceController.php b/application/controllers/PreferenceController.php index 1b8eb9e0c..58bd6416d 100644 --- a/application/controllers/PreferenceController.php +++ b/application/controllers/PreferenceController.php @@ -29,7 +29,10 @@ class PreferenceController extends Zend_Controller_Action $values = $form->getValues(); Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view); Application_Model_Preference::SetDefaultFade($values["stationDefaultFade"]); - Application_Model_Preference::SetStreamLabelFormat($values["streamFormat"]); + Application_Model_Preference::SetStreamLabelFormat($values["streamFormat"]); + Application_Model_Preference::SetDoSoundCloudUpload($values["UseSoundCloud"]); + Application_Model_Preference::SetSoundCloudUser($values["SoundCloudUser"]); + Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]); $this->view->statusMsg = "Preferences Updated."; } diff --git a/application/forms/Preferences.php b/application/forms/Preferences.php index 6b6903936..594882f6f 100644 --- a/application/forms/Preferences.php +++ b/application/forms/Preferences.php @@ -7,7 +7,7 @@ class Application_Form_Preferences extends Zend_Form { $this->setAction('/Preference/update')->setMethod('post'); - // Add login element + //Station name $this->addElement('text', 'stationName', array( 'class' => 'input_text', 'label' => 'Station Name:', @@ -22,7 +22,7 @@ class Application_Form_Preferences extends Zend_Form $defaultFade = '00:00:00.000000'; } - // Add login element + //Default station fade $this->addElement('text', 'stationDefaultFade', array( 'class' => 'input_text', 'label' => 'Default Fade:', @@ -42,11 +42,38 @@ class Application_Form_Preferences extends Zend_Form $stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat()); $this->addElement($stream_format); + + $this->addElement('checkbox', 'UseSoundCloud', array( + 'label' => 'Automatically Upload Recorded Shows To SoundCloud', + 'required' => false, + 'value' => Application_Model_Preference::GetValue("soundcloud_upload") + )); + + //SoundCloud Username + $this->addElement('text', 'SoundCloudUser', array( + 'class' => 'input_text', + 'label' => 'SoundCloud Username:', + 'required' => false, + 'filters' => array('StringTrim'), + 'value' => Application_Model_Preference::GetValue("soundcloud_user") + )); + + //SoundCloud Password + $this->addElement('password', 'SoundCloudPassword', array( + 'class' => 'input_text', + 'label' => 'SoundCloud Password:', + 'required' => false, + 'filters' => array('StringTrim'), + 'value' => Application_Model_Preference::GetValue("soundcloud_pass") + )); + $this->addElement('submit', 'submit', array( 'class' => 'ui-button ui-state-default', 'ignore' => true, 'label' => 'Submit', )); + + } } diff --git a/application/models/Preference.php b/application/models/Preference.php index 5b2f80cfa..1688fe067 100644 --- a/application/models/Preference.php +++ b/application/models/Preference.php @@ -78,7 +78,7 @@ class Application_Model_Preference return Application_Model_Preference::GetValue("shows_populated_until"); } - public static function SetDefaultFade($fade) { + public static function SetDefaultFade($fade) { Application_Model_Preference::SetValue("default_fade", $fade); } @@ -97,5 +97,30 @@ class Application_Model_Preference public static function GetStationName(){ return Application_Model_Preference::getValue("station_name"); } + + public static function SetDoSoundCloudUpload($upload) { + Application_Model_Preference::SetValue("soundcloud_upload", $upload); + } + + public static function GetDoSoundCloudUpload() { + return Application_Model_Preference::GetValue("soundcloud_upload"); + } + + public static function SetSoundCloudUser($user) { + Application_Model_Preference::SetValue("soundcloud_user", $user); + } + + public static function GetSoundCloudUser() { + return Application_Model_Preference::GetValue("soundcloud_user"); + } + + public static function SetSoundCloudPassword($password) { + Application_Model_Preference::SetValue("soundcloud_password", $password); + } + + public static function GetSoundCloudUserPassword() { + return Application_Model_Preference::GetValue("soundcloud_password"); + } + } diff --git a/application/models/Soundcloud.php b/application/models/Soundcloud.php new file mode 100644 index 000000000..d1a16247b --- /dev/null +++ b/application/models/Soundcloud.php @@ -0,0 +1,31 @@ +accessTokenResourceOwner('naomiaro@gmail.com', 'airtime17'); + +$track_data = array( + 'track[sharing]' => 'private', + 'track[title]' => 'Test', + 'track[asset_data]' => '@/home/naomi/Music/testoutput.mp3' +); + +try { + $response = json_decode( + $soundcloud->post('tracks', $track_data), + true + ); +} +catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) { + show_error($e->getMessage()); +} + +*/ From e64e30d6da1c1ac3da8a9e23fa64aff9031a67be Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 20 Mar 2011 19:34:43 -0400 Subject: [PATCH 02/74] CC-2080: Turn pypo-fetch and pypo-push into threads of the same process First implementation --- dev_tools/pf.sh | 3 - dev_tools/pypoless.sh | 3 + dev_tools/pypotail.sh | 3 + install/airtime-install.php | 1 - pypo/debug.log | 0 pypo/error.log | 0 pypo/install/pypo-daemontools-push.sh | 14 -- ...emontools-fetch.sh => pypo-daemontools.sh} | 0 pypo/install/pypo-install.py | 35 ++-- pypo/install/pypo-start.py | 9 +- pypo/install/pypo-stop.py | 7 +- pypo/install/pypo-uninstall.py | 9 +- pypo/logging.cfg | 48 ++---- pypo/pypo-cli.py | 41 ++--- pypo/pypofetch.py | 113 ++++++------- pypo/pypopush.py | 152 +++++++++--------- 16 files changed, 172 insertions(+), 266 deletions(-) delete mode 100755 dev_tools/pf.sh create mode 100755 dev_tools/pypoless.sh create mode 100755 dev_tools/pypotail.sh delete mode 100644 pypo/debug.log delete mode 100644 pypo/error.log delete mode 100644 pypo/install/pypo-daemontools-push.sh rename pypo/install/{pypo-daemontools-fetch.sh => pypo-daemontools.sh} (100%) diff --git a/dev_tools/pf.sh b/dev_tools/pf.sh deleted file mode 100755 index 324a44a36..000000000 --- a/dev_tools/pf.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -su -l pypo -c "tail -F /etc/service/pypo-fetch/log/main/current" diff --git a/dev_tools/pypoless.sh b/dev_tools/pypoless.sh new file mode 100755 index 000000000..542702527 --- /dev/null +++ b/dev_tools/pypoless.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +su -l pypo -c "less /etc/service/pypo/log/main/current" diff --git a/dev_tools/pypotail.sh b/dev_tools/pypotail.sh new file mode 100755 index 000000000..e91cd3917 --- /dev/null +++ b/dev_tools/pypotail.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +su -l pypo -c "tail -F /etc/service/pypo/log/main/current" diff --git a/install/airtime-install.php b/install/airtime-install.php index 7402b5355..d3badef95 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -39,7 +39,6 @@ AirtimeInstall::InstallPostgresScriptingLanguage(); echo "* Creating Database Tables".PHP_EOL; AirtimeInstall::CreateDatabaseTables(); -AirtimeInstall::MigrateTables(__DIR__); echo "* Storage Directory Setup".PHP_EOL; AirtimeInstall::SetupStorageDirectory($CC_CONFIG); diff --git a/pypo/debug.log b/pypo/debug.log deleted file mode 100644 index e69de29bb..000000000 diff --git a/pypo/error.log b/pypo/error.log deleted file mode 100644 index e69de29bb..000000000 diff --git a/pypo/install/pypo-daemontools-push.sh b/pypo/install/pypo-daemontools-push.sh deleted file mode 100644 index 4c5cc9f7c..000000000 --- a/pypo/install/pypo-daemontools-push.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -pypo_user="pypo" -export HOME="/home/pypo/" -# Location of pypo_cli.py Python script -pypo_path="/opt/pypo/bin/" -pypo_script="pypo-cli.py" -echo "*** Daemontools: starting daemon" -cd ${pypo_path} -exec 2>&1 -# Note the -u when calling python! we need it to get unbuffered binary stdout and stderr -exec setuidgid ${pypo_user} \ - python -u ${pypo_path}${pypo_script} \ - -p -# EOF diff --git a/pypo/install/pypo-daemontools-fetch.sh b/pypo/install/pypo-daemontools.sh similarity index 100% rename from pypo/install/pypo-daemontools-fetch.sh rename to pypo/install/pypo-daemontools.sh diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index 52746f009..23eb8bf14 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -36,7 +36,7 @@ def create_user(username): os.system("adduser --system --quiet --group --shell /bin/bash "+username) #set pypo password - p = os.popen('/usr/bin/passwd pypo', 'w') + p = os.popen('/usr/bin/passwd pypo 2>&1 1>/dev/null', 'w') p.write('pypo\n') p.write('pypo\n') p.close() @@ -103,23 +103,15 @@ try: os.system("chmod -R 755 "+BASE_PATH) os.system("chown -R pypo:pypo "+BASE_PATH) - print "Installing daemontool script pypo-fetch" - create_path("/etc/service/pypo-fetch") - create_path("/etc/service/pypo-fetch/log") - shutil.copy("%s/pypo-daemontools-fetch.sh"%current_script_dir, "/etc/service/pypo-fetch/run") - shutil.copy("%s/pypo-daemontools-logger.sh"%current_script_dir, "/etc/service/pypo-fetch/log/run") - os.system("chmod -R 755 /etc/service/pypo-fetch") - os.system("chown -R pypo:pypo /etc/service/pypo-fetch") + print "Installing pypo daemon" + create_path("/etc/service/pypo") + create_path("/etc/service/pypo/log") + shutil.copy("%s/pypo-daemontools.sh"%current_script_dir, "/etc/service/pypo/run") + shutil.copy("%s/pypo-daemontools-logger.sh"%current_script_dir, "/etc/service/pypo/log/run") + os.system("chmod -R 755 /etc/service/pypo") + os.system("chown -R pypo:pypo /etc/service/pypo") - print "Installing daemontool script pypo-push" - create_path("/etc/service/pypo-push") - create_path("/etc/service/pypo-push/log") - shutil.copy("%s/pypo-daemontools-push.sh"%current_script_dir, "/etc/service/pypo-push/run") - shutil.copy("%s/pypo-daemontools-logger.sh"%current_script_dir, "/etc/service/pypo-push/log/run") - os.system("chmod -R 755 /etc/service/pypo-push") - os.system("chown -R pypo:pypo /etc/service/pypo-push") - - print "Installing daemontool script pypo-liquidsoap" + print "Installing liquidsoap daemon" create_path("/etc/service/pypo-liquidsoap") create_path("/etc/service/pypo-liquidsoap/log") shutil.copy("%s/pypo-daemontools-liquidsoap.sh"%current_script_dir, "/etc/service/pypo-liquidsoap/run") @@ -134,16 +126,12 @@ try: found = True - p = Popen('svstat /etc/service/pypo-fetch', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + p = Popen('svstat /etc/service/pypo', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) output = p.stdout.read() if (output.find("unable to open supervise/ok: file does not exist") >= 0): found = False print output - - p = Popen('svstat /etc/service/pypo-push', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) - output = p.stdout.read() - print output - + p = Popen('svstat /etc/service/pypo-liquidsoap', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) output = p.stdout.read() print output @@ -152,6 +140,7 @@ try: print "Pypo install has completed, but daemontools is not running, please make sure you have it installed and then reboot." except Exception, e: print "exception:" + str(e) + sys.exit(1) diff --git a/pypo/install/pypo-start.py b/pypo/install/pypo-start.py index f23794af1..9d5811638 100644 --- a/pypo/install/pypo-start.py +++ b/pypo/install/pypo-start.py @@ -9,12 +9,9 @@ if os.geteuid() != 0: sys.exit(1) try: - print "Starting daemontool script pypo-fetch" - os.system("svc -u /etc/service/pypo-fetch") - - print "Starting daemontool script pypo-push" - os.system("svc -u /etc/service/pypo-push") - + print "Starting daemontool script pypo" + os.system("svc -u /etc/service/pypo") + print "Starting daemontool script pypo-liquidsoap" os.system("svc -u /etc/service/pypo-liquidsoap") diff --git a/pypo/install/pypo-stop.py b/pypo/install/pypo-stop.py index a27032313..bcfe47e3d 100644 --- a/pypo/install/pypo-stop.py +++ b/pypo/install/pypo-stop.py @@ -9,12 +9,9 @@ if os.geteuid() != 0: sys.exit(1) try: - print "Stopping daemontool script pypo-fetch" - os.system("svc -dx /etc/service/pypo-fetch 2>/dev/null") + print "Stopping daemontool script pypo" + os.system("svc -dx /etc/service/pypo 2>/dev/null") - print "Stopping daemontool script pypo-push" - os.system("svc -dx /etc/service/pypo-push 2>/dev/null") - print "Stopping daemontool script pypo-liquidsoap" os.system("svc -dx /etc/service/pypo-liquidsoap 2>/dev/null") os.system("killall liquidsoap") diff --git a/pypo/install/pypo-uninstall.py b/pypo/install/pypo-uninstall.py index 0b225cc7e..6388b0779 100644 --- a/pypo/install/pypo-uninstall.py +++ b/pypo/install/pypo-uninstall.py @@ -37,12 +37,9 @@ try: print "Removing pypo files" remove_path(BASE_PATH) - print "Removing daemontool script pypo-fetch" - remove_path("rm -rf /etc/service/pypo-fetch") - - print "Removing daemontool script pypo-push" - remove_path("rm -rf /etc/service/pypo-push") - + print "Removing daemontool script pypo" + remove_path("rm -rf /etc/service/pypo") + print "Removing daemontool script pypo-liquidsoap" remove_path("rm -rf /etc/service/pypo-liquidsoap") diff --git a/pypo/logging.cfg b/pypo/logging.cfg index ee3cd2bee..7b679d40c 100644 --- a/pypo/logging.cfg +++ b/pypo/logging.cfg @@ -1,22 +1,27 @@ [loggers] -keys=root +keys=root,fetch,push [handlers] -keys=consoleHandler,fileHandlerERROR,fileHandlerDEBUG,nullHandler +keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG -handlers=consoleHandler,fileHandlerERROR,fileHandlerDEBUG +handlers=consoleHandler -[logger_libs] -handlers=nullHandler +[logger_fetch] level=DEBUG -qualname="process" +handlers=consoleHandler +qualname=fetch propagate=0 +[logger_push] +level=DEBUG +handlers=consoleHandler +qualname=push +propagate=0 [handler_consoleHandler] class=StreamHandler @@ -24,37 +29,6 @@ level=DEBUG formatter=simpleFormatter args=(sys.stdout,) -[handler_fileHandlerERROR] -class=FileHandler -level=WARNING -formatter=simpleFormatter -args=("./error.log",) - -[handler_fileHandlerDEBUG] -class=FileHandler -level=DEBUG -formatter=simpleFormatter -args=("./debug.log",) - -[handler_nullHandler] -class=FileHandler -level=DEBUG -formatter=simpleFormatter -args=("/dev/null",) - - [formatter_simpleFormatter] format=%(asctime)s %(levelname)s - [%(filename)s : %(funcName)s() : line %(lineno)d] - %(message)s datefmt= - - -## multitail color sheme -## pyml / python -# colorscheme:pyml:www.obp.net -# cs_re:blue:\[[^ ]*\] -# cs_re:red:CRITICAL:* -# cs_re:red,black,blink:ERROR:* -# cs_re:blue:NOTICE:* -# cs_re:cyan:INFO:* -# cs_re:green:DEBUG:* - diff --git a/pypo/pypo-cli.py b/pypo/pypo-cli.py index 3c0402908..ca630f618 100755 --- a/pypo/pypo-cli.py +++ b/pypo/pypo-cli.py @@ -27,6 +27,7 @@ import logging.config #import string #import operator #import inspect +from Queue import Queue from pypopush import PypoPush from pypofetch import PypoFetch @@ -66,10 +67,6 @@ logging.config.fileConfig("logging.cfg") # loading config file try: config = ConfigObj('config.cfg') - POLL_INTERVAL = float(config['poll_interval']) - PUSH_INTERVAL = float(config['push_interval']) - LS_HOST = config['ls_host'] - LS_PORT = config['ls_port'] except Exception, e: print 'Error loading config file: ', e sys.exit() @@ -135,41 +132,23 @@ if __name__ == '__main__': g.selfcheck() logger = logging.getLogger() - loops = 0 if options.test: g.test_api() sys.exit() - - if options.fetch_scheduler: - pf = PypoFetch() - while True: - try: pf.fetch('scheduler') - except Exception, e: - print e - sys.exit() + q = Queue() - if (loops%2 == 0): - logger.info("heartbeat") - loops += 1 - time.sleep(POLL_INTERVAL) + pp = PypoPush(q) + pp.start() - if options.push_scheduler: - pp = PypoPush() - while True: - try: pp.push('scheduler') - except Exception, e: - print 'PUSH ERROR!! WILL EXIT NOW:(' - print e - sys.exit() + pf = PypoFetch(q) + pf.start() - if (loops%60 == 0): - logger.info("heartbeat") - - loops += 1 - time.sleep(PUSH_INTERVAL) + pp.join() + pf.join() +""" if options.check: try: g.check_schedule() except Exception, e: @@ -179,4 +158,4 @@ if __name__ == '__main__': try: pf.cleanup('scheduler') except Exception, e: print e - sys.exit() +""" diff --git a/pypo/pypofetch.py b/pypo/pypofetch.py index aaeda54f5..0ca468198 100644 --- a/pypo/pypofetch.py +++ b/pypo/pypofetch.py @@ -9,35 +9,39 @@ import random import string import json import telnetlib +import math +from threading import Thread from api_clients import api_client from util import CueFile from configobj import ConfigObj +# configure logging +logging.config.fileConfig("logging.cfg") + # loading config file try: config = ConfigObj('config.cfg') - POLL_INTERVAL = float(config['poll_interval']) - PUSH_INTERVAL = 0.5 - #PUSH_INTERVAL = float(config['push_interval']) LS_HOST = config['ls_host'] LS_PORT = config['ls_port'] + POLL_INTERVAL = 5 + except Exception, e: print 'Error loading config file: ', e sys.exit() -class PypoFetch: - def __init__(self): +class PypoFetch(Thread): + def __init__(self, q): + Thread.__init__(self) self.api_client = api_client.api_client_factory(config) self.cue_file = CueFile() self.set_export_source('scheduler') + self.queue = q def set_export_source(self, export_source): self.export_source = export_source self.cache_dir = config["cache_dir"] + self.export_source + '/' - self.schedule_file = self.cache_dir + 'schedule.pickle' - self.schedule_tracker_file = self.cache_dir + "schedule_tracker.pickle" """ Fetching part of pypo @@ -48,10 +52,8 @@ class PypoFetch: - runs the cleanup routine, to get rid of unused cashed files """ def fetch(self, export_source): - """ - wrapper script for fetching the whole schedule (in json) - """ - logger = logging.getLogger() + #wrapper script for fetching the whole schedule (in json) + logger = logging.getLogger('fetch') try: os.mkdir(self.cache_dir) except Exception, e: pass @@ -65,30 +67,29 @@ class PypoFetch: except Exception, e: logger.error("%s", e) # prepare the playlists - if config["cue_style"] == 'pre': - try: self.prepare_playlists_cue() - except Exception, e: logger.error("%s", e) - elif config["cue_style"] == 'otf': - try: self.prepare_playlists(self.export_source) - except Exception, e: logger.error("%s", e) + try: + playlists = self.prepare_playlists() + except Exception, e: logger.error("%s", e) + + + scheduled_data = dict() + scheduled_data['playlists'] = playlists + scheduled_data['schedule'] = self.schedule + self.queue.put(scheduled_data) # cleanup try: self.cleanup(self.export_source) except Exception, e: logger.error("%s", e) def get_schedule(self): - logger = logging.getLogger() + logger = logging.getLogger('fetch') status, response = self.api_client.get_schedule() if status == 1: - logger.info("dump serialized schedule to %s", self.schedule_file) schedule = response['playlists'] stream_metadata = response['stream_metadata'] try: - schedule_file = open(self.schedule_file, "w") - pickle.dump(schedule, schedule_file) - schedule_file.close() - + self.schedule = schedule tn = telnetlib.Telnet(LS_HOST, LS_PORT) #encode in latin-1 due to telnet protocol not supporting utf-8 @@ -96,7 +97,7 @@ class PypoFetch: tn.write(('vars.station_name %s\n' % stream_metadata['station_name']).encode('latin-1')) tn.write('exit\n') - logger.debug(tn.read_all()) + tn.read_all() except Exception, e: logger.error("Exception %s", e) @@ -104,45 +105,22 @@ class PypoFetch: return status - #TODO this is a duplicate function!!! - def load_schedule(self): - logger = logging.getLogger() - schedule = None - - # create the file if it doesnt exist - if (not os.path.exists(self.schedule_file)): - logger.debug('creating file ' + self.schedule_file) - open(self.schedule_file, 'w').close() - else: - # load the schedule from cache - #logger.debug('loading schedule file '+self.schedule_file) - try: - schedule_file = open(self.schedule_file, "r") - schedule = pickle.load(schedule_file) - schedule_file.close() - - except Exception, e: - logger.error('%s', e) - - return schedule - - """ Alternative version of playout preparation. Every playlist entry is pre-cued if neccessary (cue_in/cue_out != 0) and stored in the playlist folder. file is eg 2010-06-23-15-00-00/17_cue_10.132-123.321.mp3 """ - def prepare_playlists_cue(self): - logger = logging.getLogger() + def prepare_playlists(self): + logger = logging.getLogger('fetch') - # Load schedule from disk - schedule = self.load_schedule() + schedule = self.schedule + playlists = dict() # Dont do anything if schedule is empty - if (not schedule): + if not schedule: logger.debug("Schedule is empty.") - return + return playlists scheduleKeys = sorted(schedule.iterkeys()) @@ -173,14 +151,10 @@ class PypoFetch: elif int(playlist['subtype']) > 0 and int(playlist['subtype']) < 5: ls_playlist = self.handle_media_file(playlist, pkey) - # write playlist file - plfile = open(self.cache_dir + str(pkey) + '/list.lsp', "w") - plfile.write(json.dumps(ls_playlist)) - plfile.close() - logger.info('ls playlist file written to %s', self.cache_dir + str(pkey) + '/list.lsp') - + playlists[pkey] = ls_playlist except Exception, e: logger.info("%s", e) + return playlists def handle_media_file(self, playlist, pkey): """ @@ -189,7 +163,7 @@ class PypoFetch: """ ls_playlist = [] - logger = logging.getLogger() + logger = logging.getLogger('fetch') for media in playlist['medias']: logger.debug("Processing track %s", media['uri']) @@ -252,7 +226,7 @@ class PypoFetch: def handle_remote_file(self, media, dst, do_cue): - logger = logging.getLogger() + logger = logging.getLogger('fetch') if do_cue == False: if os.path.isfile(dst): logger.debug("file already in cache: %s", dst) @@ -301,7 +275,7 @@ class PypoFetch: Cleans up folders in cache_dir. Look for modification date older than "now - CACHE_FOR" and deletes them. """ - logger = logging.getLogger() + logger = logging.getLogger('fetch') offset = 3600 * int(config["cache_for"]) now = time.time() @@ -323,3 +297,18 @@ class PypoFetch: print e logger.error("%s", e) + def run(self): + loops = 0 + heartbeat_period = math.floor(30/POLL_INTERVAL) + logger = logging.getLogger('fetch') + + while True: + if loops % heartbeat_period == 0: + logger.info("heartbeat") + loops = 0 + try: self.fetch('scheduler') + except Exception, e: + logger.error('Pypo Fetch Error, exiting: %s', e) + sys.exit() + time.sleep(POLL_INTERVAL) + loops += 1 diff --git a/pypo/pypopush.py b/pypo/pypopush.py index 266443b8f..62203fc59 100644 --- a/pypo/pypopush.py +++ b/pypo/pypopush.py @@ -7,29 +7,37 @@ import pickle import telnetlib import calendar import json +import math +from threading import Thread from api_clients import api_client from util import CueFile from configobj import ConfigObj +# configure logging +logging.config.fileConfig("logging.cfg") + # loading config file try: config = ConfigObj('config.cfg') - POLL_INTERVAL = float(config['poll_interval']) - PUSH_INTERVAL = 0.5 - #PUSH_INTERVAL = float(config['push_interval']) LS_HOST = config['ls_host'] LS_PORT = config['ls_port'] + PUSH_INTERVAL = 2 except Exception, e: - print 'Error loading config file: ', e + logger.error('Error loading config file %s', e) sys.exit() -class PypoPush: - def __init__(self): +class PypoPush(Thread): + def __init__(self, q): + Thread.__init__(self) self.api_client = api_client.api_client_factory(config) self.cue_file = CueFile() self.set_export_source('scheduler') + self.queue = q + + self.schedule = dict() + self.playlists = dict() """ push_ahead2 MUST be < push_ahead. The difference in these two values @@ -42,7 +50,6 @@ class PypoPush: def set_export_source(self, export_source): self.export_source = export_source self.cache_dir = config["cache_dir"] + self.export_source + '/' - self.schedule_file = self.cache_dir + 'schedule.pickle' self.schedule_tracker_file = self.cache_dir + "schedule_tracker.pickle" """ @@ -52,41 +59,46 @@ class PypoPush: then liquidsoap is asked (via telnet) to reload and immediately play it. """ def push(self, export_source): - logger = logging.getLogger() + logger = logging.getLogger('push') - self.schedule = self.load_schedule() - playedItems = self.load_schedule_tracker() + if not self.queue.empty(): + scheduled_data = self.queue.get() + self.schedule = scheduled_data['schedule'] + self.playlists = scheduled_data['playlists'] - tcoming = time.localtime(time.time() + self.push_ahead) - tcoming2 = time.localtime(time.time() + self.push_ahead2) + schedule = self.schedule + playlists = self.playlists - - str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5]) - str_tcoming2_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming2[0], tcoming2[1], tcoming2[2], tcoming2[3], tcoming2[4], tcoming2[5]) - currently_on_air = False - if self.schedule == None: - logger.warn('Unable to loop schedule - maybe write in progress?') - logger.warn('Will try again in next loop.') + if schedule: + playedItems = self.load_schedule_tracker() - else: - for pkey in self.schedule: + timenow = time.time() + tcoming = time.localtime(timenow + self.push_ahead) + str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5]) + + tcoming2 = time.localtime(timenow + self.push_ahead2) + str_tcoming2_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming2[0], tcoming2[1], tcoming2[2], tcoming2[3], tcoming2[4], tcoming2[5]) + + tnow = time.localtime(timenow) + str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5]) + + for pkey in schedule: plstart = pkey[0:19] - start = self.schedule[pkey]['start'] - end = self.schedule[pkey]['end'] + start = schedule[pkey]['start'] + end = schedule[pkey]['end'] playedFlag = (pkey in playedItems) and playedItems[pkey].get("played", 0) if plstart == str_tcoming_s or (plstart < str_tcoming_s and plstart > str_tcoming2_s and not playedFlag): logger.debug('Preparing to push playlist scheduled at: %s', pkey) - playlist = self.schedule[pkey] + playlist = schedule[pkey] - ptype = playlist['subtype'] currently_on_air = True # We have a match, replace the current playlist and # force liquidsoap to refresh. - if (self.push_liquidsoap(pkey, self.schedule, ptype) == 1): + if (self.push_liquidsoap(pkey, schedule, playlists) == 1): logger.debug("Pushed to liquidsoap, updating 'played' status.") # Marked the current playlist as 'played' in the schedule tracker # so it is not called again in the next push loop. @@ -100,39 +112,27 @@ class PypoPush: # Call API to update schedule states logger.debug("Doing callback to server to update 'played' status.") - self.api_client.notify_scheduled_item_start_playing(pkey, self.schedule) - - if self.schedule != None: - tnow = time.localtime(time.time()) - str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5]) - for pkey in self.schedule: - start = self.schedule[pkey]['start'] - end = self.schedule[pkey]['end'] + self.api_client.notify_scheduled_item_start_playing(pkey, schedule) + + start = schedule[pkey]['start'] + end = schedule[pkey]['end'] if start <= str_tnow_s and str_tnow_s < end: currently_on_air = True - + else: + logger.debug('Empty schedule') + if not currently_on_air: tn = telnetlib.Telnet(LS_HOST, LS_PORT) - tn.write('source.skip\n'.encode('latin-1')) + tn.write('source.skip\n') tn.write('exit\n') tn.read_all() - #logger.info('source.skip') - #logger.debug(tn.read_all()) - def push_liquidsoap(self, pkey, schedule, ptype): - logger = logging.getLogger() - src = self.cache_dir + str(pkey) + '/list.lsp' + def push_liquidsoap(self, pkey, schedule, playlists): + logger = logging.getLogger('push') try: - if True == os.access(src, os.R_OK): - logger.debug('OK - Can read playlist file') - - pl_file = open(src, "r") - file_content = pl_file.read() - pl_file.close() - logger.debug('file content: %s' % (file_content)) - playlist = json.loads(file_content) + playlist = playlists[pkey] #strptime returns struct_time in local time #mktime takes a time_struct and returns a floating point @@ -180,43 +180,24 @@ class PypoPush: except Exception, e: logger.error('%s', e) status = 0 - return status - - def load_schedule(self): - logger = logging.getLogger() - schedule = None - - # create the file if it doesnt exist - if (not os.path.exists(self.schedule_file)): - logger.debug('creating file ' + self.schedule_file) - open(self.schedule_file, 'w').close() - else: - # load the schedule from cache - #logger.debug('loading schedule file '+self.schedule_file) - try: - schedule_file = open(self.schedule_file, "r") - schedule = pickle.load(schedule_file) - schedule_file.close() - - except Exception, e: - logger.error('%s', e) - - return schedule - - def load_schedule_tracker(self): - logger = logging.getLogger() + logger = logging.getLogger('push') + logger.debug('load_schedule_tracker') playedItems = dict() # create the file if it doesnt exist if (not os.path.exists(self.schedule_tracker_file)): - logger.debug('creating file ' + self.schedule_tracker_file) - schedule_tracker = open(self.schedule_tracker_file, 'w') - pickle.dump(playedItems, schedule_tracker) - schedule_tracker.close() + try: + logger.debug('creating file ' + self.schedule_tracker_file) + schedule_tracker = open(self.schedule_tracker_file, 'w') + pickle.dump(playedItems, schedule_tracker) + schedule_tracker.close() + except Exception, e: + logger.error('Error creating schedule tracker file: %s', e) else: + logger.debug('schedule tracker file exists, opening: ' + self.schedule_tracker_file) try: schedule_tracker = open(self.schedule_tracker_file, "r") playedItems = pickle.load(schedule_tracker) @@ -226,3 +207,18 @@ class PypoPush: return playedItems + def run(self): + loops = 0 + heartbeat_period = math.floor(30/PUSH_INTERVAL) + logger = logging.getLogger('push') + + while True: + if loops % heartbeat_period == 0: + logger.info("heartbeat") + loops = 0 + try: self.push('scheduler') + except Exception, e: + logger.error('Pypo Push Error, exiting: %s', e) + sys.exit() + time.sleep(PUSH_INTERVAL) + loops += 1 From b20294d7e934995e832d236e5ebf627ecd55ed96 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 20 Mar 2011 20:17:10 -0400 Subject: [PATCH 03/74] -changed LAME to re-encode to 128kbps (from 32) by default when cutting a file. --- pypo/util/cue_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypo/util/cue_file.py b/pypo/util/cue_file.py index 0d5f6cab5..8b3a158be 100755 --- a/pypo/util/cue_file.py +++ b/pypo/util/cue_file.py @@ -64,7 +64,7 @@ class CueFile(): print command os.system(command + ' > /dev/null 2>&1') - command = 'lame -b 32 %s %s' % (dst + '.tmp.mp3', dst); + command = 'lame -b 128 %s %s' % (dst + '.tmp.mp3', dst); logger.info("command: %s", command) print command os.system(command + ' > /dev/null 2>&1') From d9431f95b4cf178e93597f49f256c470a481d2c3 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 20 Mar 2011 22:57:48 -0400 Subject: [PATCH 04/74] -removed pp.sh helper script from dev_tools --- dev_tools/pp.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 dev_tools/pp.sh diff --git a/dev_tools/pp.sh b/dev_tools/pp.sh deleted file mode 100755 index f1aac3025..000000000 --- a/dev_tools/pp.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -su -l pypo -c "tail -F /etc/service/pypo-push/log/main/current" From b922e429183cb2cdd40270873f9004ce4a07c95a Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 21 Mar 2011 10:58:30 -0400 Subject: [PATCH 05/74] CC-2080: Turn pypo-fetch and pypo-push into threads of the same process Fixed install scripts to remove old instances of pypo properly --- pypo/install/pypo-install.py | 6 +++--- pypo/install/pypo-stop.py | 9 +++++++-- pypo/install/pypo-uninstall.py | 10 ++++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index 23eb8bf14..9c42ab011 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -36,14 +36,14 @@ def create_user(username): os.system("adduser --system --quiet --group --shell /bin/bash "+username) #set pypo password - p = os.popen('/usr/bin/passwd pypo 2>&1 1>/dev/null', 'w') + p = os.popen('/usr/bin/passwd pypo 1>/dev/null 2>&1', 'w') p.write('pypo\n') p.write('pypo\n') p.close() else: print "User already exists." #add pypo to audio group - os.system("adduser " + username + " audio 2>&1 1>/dev/null") + os.system("adduser " + username + " audio 1>/dev/null 2>&1") def copy_dir(src_dir, dest_dir): if (os.path.exists(dest_dir)) and (dest_dir != "/"): @@ -63,7 +63,7 @@ def get_current_script_dir(): try: current_script_dir = get_current_script_dir() print "Checking and removing any existing pypo processes" - os.system("python %s/pypo-uninstall.py 2>&1 1>/dev/null"% current_script_dir) + os.system("python %s/pypo-uninstall.py 1>/dev/null 2>&1"% current_script_dir) time.sleep(5) # Create users diff --git a/pypo/install/pypo-stop.py b/pypo/install/pypo-stop.py index bcfe47e3d..388c0bc4b 100644 --- a/pypo/install/pypo-stop.py +++ b/pypo/install/pypo-stop.py @@ -10,10 +10,15 @@ if os.geteuid() != 0: try: print "Stopping daemontool script pypo" - os.system("svc -dx /etc/service/pypo 2>/dev/null") + os.system("svc -dx /etc/service/pypo 1>/dev/null 2>&1") + + if os.path.exists("/etc/service/pypo-fetch"): + os.system("svc -dx /etc/service/pypo-fetch 1>/dev/null 2>&1") + if os.path.exists("/etc/service/pypo-push"): + os.system("svc -dx /etc/service/pypo-push 1>/dev/null 2>&1") print "Stopping daemontool script pypo-liquidsoap" - os.system("svc -dx /etc/service/pypo-liquidsoap 2>/dev/null") + os.system("svc -dx /etc/service/pypo-liquidsoap 1>/dev/null 2>&1") os.system("killall liquidsoap") except Exception, e: diff --git a/pypo/install/pypo-uninstall.py b/pypo/install/pypo-uninstall.py index 6388b0779..a9f339be0 100644 --- a/pypo/install/pypo-uninstall.py +++ b/pypo/install/pypo-uninstall.py @@ -15,13 +15,13 @@ def remove_path(path): os.system("rm -rf " + path) def remove_user(username): - os.system("killall -u %s 2>&1 1>/dev/null" % username) + os.system("killall -u %s 1>/dev/null 2>&1" % username) #allow all process to be completely closed before we attempt to delete user print "Waiting for processes to close..." time.sleep(5) - os.system("deluser --remove-home " + username + " 1>/dev/null") + os.system("deluser --remove-home " + username + " 1>/dev/null 2>&1") def get_current_script_dir(): current_script_dir = os.path.realpath(__file__) @@ -39,6 +39,12 @@ try: print "Removing daemontool script pypo" remove_path("rm -rf /etc/service/pypo") + + if os.path.exists("/etc/service/pypo-fetch"): + remove_path("rm -rf /etc/service/pypo-fetch") + + if os.path.exists("/etc/service/pypo-push"): + remove_path("rm -rf /etc/service/pypo-push") print "Removing daemontool script pypo-liquidsoap" remove_path("rm -rf /etc/service/pypo-liquidsoap") From 9f7a223159c2705f73069290bf262af510ad5966 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 21 Mar 2011 13:35:50 -0400 Subject: [PATCH 06/74] CC-2082: OGG stream dies after every song when using MPlayer -Problem fixed -Also replaced 40MB silence.mp3 file with new 172KB file --- pypo/install/pypo-install.py | 8 +------- pypo/scripts/ls_script.liq | 8 ++++++-- pypo/scripts/silence.mp3 | Bin 43141048 -> 0 bytes 3 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 pypo/scripts/silence.mp3 diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index 9c42ab011..07cb43cd9 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -79,14 +79,8 @@ try: create_path(BASE_PATH+"cache") create_path(BASE_PATH+"files") create_path(BASE_PATH+"tmp") - create_path(BASE_PATH+"files/basic") - create_path(BASE_PATH+"files/fallback") - create_path(BASE_PATH+"files/jingles") create_path(BASE_PATH+"archive") - - print "Copying pypo files" - shutil.copy("%s/../scripts/silence.mp3"%current_script_dir, BASE_PATH+"files/basic") - + if platform.architecture()[0] == '64bit': print "Installing 64-bit liquidsoap binary" shutil.copy("%s/../liquidsoap/liquidsoap64"%current_script_dir, "%s/../liquidsoap/liquidsoap"%current_script_dir) diff --git a/pypo/scripts/ls_script.liq b/pypo/scripts/ls_script.liq index a35495839..20e49c35c 100644 --- a/pypo/scripts/ls_script.liq +++ b/pypo/scripts/ls_script.liq @@ -24,7 +24,7 @@ server.register(namespace="vars", "show_name", fun (s) -> begin show_name := s s server.register(namespace="vars", "station_name", fun (s) -> begin station_name := s s end) -default = single(conservative=true, "/opt/pypo/files/basic/silence.mp3") +default = single(audio_to_stereo("/opt/pypo/bin/files/sleeper_03.mp3")) default = rewrite_metadata([("artist","Airtime"), ("title", "offline")],default) s = fallback(track_sensitive=false, [queue, default]) @@ -69,6 +69,10 @@ if output_icecast_mp3 then end if output_icecast_vorbis then + #remove metadata from ogg source and merge tracks to fix bug + #with vlc and mplayer disconnecting at the end of every track + #silence = add(normalize=false,[blank(), audio_to_stereo(single("/opt/pypo/bin/files/sleeper_03.mp3"))]) + ogg_s = add(normalize=false,[blank(),s]) out_vorbis = output.icecast(%vorbis, host = icecast_host, port = icecast_port, password = icecast_pass, mount = mount_point_vorbis, @@ -78,5 +82,5 @@ if output_icecast_vorbis then url = icecast_url, description = icecast_description, genre = icecast_genre, - s) + ogg_s) end diff --git a/pypo/scripts/silence.mp3 b/pypo/scripts/silence.mp3 deleted file mode 100644 index 374dfe28631e2230004dbfdc76daab66dca7bde6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43141048 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 z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ 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 z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga z%V-^60mWSwVC*6|fk++{Il0*cFM9bW;( zT^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?q zWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk z7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC z*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw| zF=hga%V-^60mWSwVC*6|fk++{Il0*cFM z9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSw zVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I z@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvn zUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E z6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il z0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^6 z0mWSwVC*6|fk++{Il0*cFM9bW;(T^3^| zpty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ zipyvnUjfBk7Gox$xQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$ zxQy2E6;Rw|F=hga%V-^60mWSwVC*6|fk z++{Il0*cFM9bW;(T^3^|pty|I@fA?qWie&~ipyvnUjfBk7Gox$xQy2E6;Rw|F=hga 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 zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> 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 zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 z;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{w zE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2Jq zGFr!1KyjDFm?fZ{S*$5%jc zm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JD zS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%> z#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E# zjG2JqGFr!1KyjDFm?fZ{S* z$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDF zm?fZ{S*$5%jcm&KR~C@!OQ zd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbyt zS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP z1r&E#jG2JqGFr!1KyjDFm? zfZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1 zKyjDFm?fZ{S*$5%jcm&KR~ zC@!OQd<7JDS&W&0;xbytS3q%>#h3{wE~9mP1r&E#jG2JqGFr!1KyjDFm?fZ{S*$5%jcm&KR~C@!OQd<7JDS&W&0 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 Date: Mon, 21 Mar 2011 13:43:25 -0400 Subject: [PATCH 07/74] CC-2082: OGG stream dies after every song when using MPlayer -small typo fix --- pypo/scripts/ls_script.liq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypo/scripts/ls_script.liq b/pypo/scripts/ls_script.liq index 20e49c35c..4e3660bc4 100644 --- a/pypo/scripts/ls_script.liq +++ b/pypo/scripts/ls_script.liq @@ -24,7 +24,7 @@ server.register(namespace="vars", "show_name", fun (s) -> begin show_name := s s server.register(namespace="vars", "station_name", fun (s) -> begin station_name := s s end) -default = single(audio_to_stereo("/opt/pypo/bin/files/sleeper_03.mp3")) +default = audio_to_stereo(single("/opt/pypo/bin/files/sleeper_03.mp3")) default = rewrite_metadata([("artist","Airtime"), ("title", "offline")],default) s = fallback(track_sensitive=false, [queue, default]) From 9dae30652663d12faf5e78c1f159ac256cae58fc Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 21 Mar 2011 13:51:36 -0400 Subject: [PATCH 08/74] .gitignore file now only ignores "files/" folder in the root airtime directory --- .gitignore | 2 +- pypo/files/sleeper_03.mp3 | Bin 0 -> 180416 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 pypo/files/sleeper_03.mp3 diff --git a/.gitignore b/.gitignore index 47bb04716..94b090b91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .* *.pyc -files/ +/files pypo/liquidsoap/liquidsoap build/build.properties diff --git a/pypo/files/sleeper_03.mp3 b/pypo/files/sleeper_03.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..786d4ccb31508368e529d9ded209e82f5dc7004e GIT binary patch literal 180416 zcmeIyJ4(b*7(n5Go3OM~8ygD|D+_T7?Q{VO(^-g*fmxP&n4L`P9^!~voPz<2DJ;${ z0w>)3kS~vMy}KHQVQ02E3|HsZ7sp4ZCwm9?^Ow8B+o|=-zHu|>>}Sr@bv{2aXR)O@ zZ(Ex4zNI;1bH3hyiRYfr_Xm=X{}k+e=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3)hZ@(rt8o~1X2WLvVgJ;Y|2F65{POu>K7X7)?H%ub-kaC+^5yku KvGnOJ_4omP+iZjY literal 0 HcmV?d00001 From a3a8ae104a8e27d237f23130f1712e95618872e1 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 21 Mar 2011 15:01:43 -0400 Subject: [PATCH 09/74] CC-2030: Icon needed for Cue In/Out -Implemented --- .../views/scripts/playlist/update.phtml | 1 + public/css/images/cue_playlist.png | Bin 0 -> 1907 bytes public/css/playlist_builder.css | 49 ++++++++++++++++-- public/js/airtime/library/spl.js | 11 ++-- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 public/css/images/cue_playlist.png diff --git a/application/views/scripts/playlist/update.phtml b/application/views/scripts/playlist/update.phtml index 7c9c2a898..590f071cf 100644 --- a/application/views/scripts/playlist/update.phtml +++ b/application/views/scripts/playlist/update.phtml @@ -10,6 +10,7 @@
+
diff --git a/public/css/images/cue_playlist.png b/public/css/images/cue_playlist.png new file mode 100644 index 0000000000000000000000000000000000000000..b928ccfae576d241c26c0e3717440cdbea75ae16 GIT binary patch literal 1907 zcmeAS@N?(olHy`uVBq!ia0vp^ia@N(!3HE1)R;tolw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6H#24;oKkcg59UmvUF{9L_6kQ%*;+ybC(1_m4Zih{)C?9>v4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn`Gtf;oFf&jvGt@IQ zHZeCh*HJJsFf`CNFw!?P(ls=ztz{SPf#L~&h(9qSu!o|$g(aF%s(#+7% z$j!wJrq?AuximL5uLPzy1)~a z3ELYaZ747;&&EX4<0!L%^R5rm**wk~8}K-@KQZixXFhYG^@GxlBccnv4+aD~rd@Ja z(z|8%q_9tt()}kD``_tgZvCFAT6_Q1*|TTYd#!Z78k4!*rs3z$pT`95+_@uDCBVh7 ziSh04JHflv3#>&RT%5)E(<5`)V&<%@|FN&uurmH(xoBr))%7@@kFUreAiw;<8?NPo zGPOcn0);0Ju+4hDW81R-zpH<*Q*JC~&U0;e{~)11*Xp=zYHNINzWMbaWxwL3pZK%a z&VI0}@TwL2+&<={jaBXsj$P!-xD)=tbj!_ik7Sx_J1$P*PxycQxU8Z2PhSNlf$V|@ zPoAiJWf%A(?@}MvYjn)geCOWv_u^l8e_qJe;=B68(=T7Ph_T$f+W6oF!%gYy&sTpJ z_S#^2D1YkufTN7@W##4V4Gjwwme_t+wRgTyixdMRV-i@b_!i#BNP# z__OBy^XHr;8!bYuPk*(1+i>&d_dm9~_AF4`)Y4_b(Bsa&?4hMprJ4o5&x)Hq##4oS zGek8!m_MFB{MXj?Q1oN|{cegaOecf6*tw>(gyF5J0==Klod#}GGbv2}gJrPpOisFzEId$#r z*P8SxMbRFXr*`n>))lM1^fTd~;Ij7iTeV%{WuclE4+PzN9jnEB(z8Q?u|VqKXSOqn zK4&EV-1b;o_;`hTpQXOO{$&2d`P>m}GP8f#|7vDBR(6c3xoyUh2~*TBr0}o0|Ngnw zt0KO`-;{(DqfafZDJ|VPAx$7s5a`|sGpDYeKW9D<3s2dM zD=QGqI&%;6Ezb-4_CES^@ie cPxVYZ4DONT-ScM6R0CCmp00i_>zopr06+5fdjJ3c literal 0 HcmV?d00001 diff --git a/public/css/playlist_builder.css b/public/css/playlist_builder.css index dd1ad24b1..4e2dc5ada 100644 --- a/public/css/playlist_builder.css +++ b/public/css/playlist_builder.css @@ -15,7 +15,11 @@ #spl_sortable > li, #side_playlist > div, #spl_editor, -.spl_artist { +.spl_artist, +.spl_cue_in, +.spl_fade_in, +.spl_cue_out, +.spl_fade_out { clear: left; } @@ -35,8 +39,8 @@ #spl_sortable { list-style: none; padding:0; - height: 400px; - overflow-y: scroll; + height: 300px; + overflow: auto; width:100%; margin-top:0; } @@ -52,6 +56,10 @@ border: none; } +#spl_name { + +} + .ui-icon-closethick { margin-top: 7px; } @@ -72,6 +80,15 @@ font-size:12px; } +/*#spl_editor { + height: 50px; +}*/ + +#spl_editor > div > span { +/* display: inline-block; + width: 150px;*/ +} + .ui-icon-closethick, .ui-icon-play, .spl_fade_control, @@ -239,13 +256,12 @@ margin: 0; } -dd.edit-error { +.edit-error { color:#b80000; margin:0; padding-bottom:0; font-size:12px; display:none; - clear: left; } /*.edit-error:last-child { @@ -276,3 +292,26 @@ dd.edit-error { top: 3px; z-index: 3; } + +#spl_sortable li .spl_cue { + background-color: transparent; + float:right; + font-size: 9px; + height: 15px; + right: 35px; + width: 33px; + margin-top:2px; + cursor:pointer; +} +#spl_sortable li .spl_cue.ui-state-default { + background: transparent url(images/cue_playlist.png) no-repeat 0 0; + border:none; +} +#spl_sortable li .spl_cue.ui-state-default:hover { + background: transparent url(images/cue_playlist.png) no-repeat 0 -15px; + border:none; +} +#spl_sortable li .spl_cue.ui-state-active, #spl_sortable li .spl_cue.ui-state-active:hover { + background: transparent url(images/cue_playlist.png) no-repeat 0 -30px; + border:none; +} \ No newline at end of file diff --git a/public/js/airtime/library/spl.js b/public/js/airtime/library/spl.js index e32e83f62..89203600d 100644 --- a/public/js/airtime/library/spl.js +++ b/public/js/airtime/library/spl.js @@ -205,13 +205,15 @@ function openFadeEditor(event) { function openCueEditor(event) { event.stopPropagation(); - var pos, url, li; + var pos, url, li, icon; li = $(this).parent().parent().parent(); + icon = $(this); pos = li.attr("id").split("_").pop(); if(li.hasClass("ui-state-active")) { li.removeClass("ui-state-active"); + icon.attr("class", "spl_cue ui-state-default"); $("#cues_"+pos) .empty() @@ -220,6 +222,7 @@ function openCueEditor(event) { return; } + icon.attr("class", "spl_cue ui-state-default ui-state-active"); url = '/Playlist/set-cue'; highlightActive(li); @@ -253,7 +256,8 @@ function setSPLContent(json) { $("#spl_sortable .ui-icon-closethick").click(deleteSPLItem); $(".spl_fade_control").click(openFadeEditor); - $(".spl_playlength").click(openCueEditor); + //$(".spl_playlength").click(openCueEditor); + $(".spl_cue").click(openCueEditor); return false; } @@ -487,7 +491,8 @@ function setUpSPL() { $("#spl_sortable .ui-icon-closethick").click(deleteSPLItem); $(".spl_fade_control").click(openFadeEditor); - $(".spl_playlength").click(openCueEditor); + //$(".spl_playlength").click(openCueEditor); + $(".spl_cue").click(openCueEditor); $("#spl_sortable").droppable(); $("#spl_sortable" ).bind( "drop", addSPLItem); From 60649cba8ad2ee915c7dd01c944771239fffd080 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Mon, 21 Mar 2011 15:48:44 -0400 Subject: [PATCH 10/74] CC-1987 : Automatic upload of recorded shows to Soundcloud created Soundcloud.php in models, added upload track method. using python-setuptools in install to find poster package to be able to upload recoded file to airtime and then to soundcloud. --- application/Bootstrap.php | 1 + application/configs/conf.php | 3 + .../controllers/PluploadController.php | 7 +- application/forms/Preferences.php | 10 +-- application/models/Preference.php | 2 +- application/models/Soundcloud.php | 63 ++++++++++++------ install/airtime-install.php | 3 + install/installInit.php | 9 ++- python_apps/eggs/poster-0.8.0-py2.6.egg | Bin 30851 -> 0 bytes python_apps/show-recorder/config.cfg | 2 +- 10 files changed, 71 insertions(+), 29 deletions(-) delete mode 100644 python_apps/eggs/poster-0.8.0-py2.6.egg diff --git a/application/Bootstrap.php b/application/Bootstrap.php index 9911b8931..d9ffceae0 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -14,6 +14,7 @@ require_once (__DIR__."/configs/constants.php"); require_once (__DIR__."/configs/conf.php"); require_once 'DB.php'; +require_once 'Soundcloud.php'; require_once 'Playlist.php'; require_once 'StoredFile.php'; require_once 'Schedule.php'; diff --git a/application/configs/conf.php b/application/configs/conf.php index f43dde788..c1e98d0bb 100644 --- a/application/configs/conf.php +++ b/application/configs/conf.php @@ -46,6 +46,9 @@ $CC_CONFIG = array( 'apiKey' => $values['api_key'], 'apiPath' => '/api/', + 'soundcloud-client-id' => '2CLCxcSXYzx7QhhPVHN4A', + 'soundcloud-client-secret' => 'pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs', + "rootDir" => __DIR__."/../..", 'pearPath' => dirname(__FILE__).'/../../library/pear', 'zendPath' => dirname(__FILE__).'/../../library/Zend', diff --git a/application/controllers/PluploadController.php b/application/controllers/PluploadController.php index aae777f23..25dc47482 100644 --- a/application/controllers/PluploadController.php +++ b/application/controllers/PluploadController.php @@ -167,7 +167,12 @@ class PluploadController extends Zend_Controller_Action $upload_dir = ini_get("upload_tmp_dir"); $file = $this->upload($upload_dir); - //$file->getRealFilePath(); + if(Application_Model_Preference::GetDoSoundCloudUpload()) + { + $soundcloud = new ATSoundcloud(); + $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName()); + } + die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); } diff --git a/application/forms/Preferences.php b/application/forms/Preferences.php index 594882f6f..5af7c6a44 100644 --- a/application/forms/Preferences.php +++ b/application/forms/Preferences.php @@ -17,7 +17,7 @@ class Application_Form_Preferences extends Zend_Form 'value' => Application_Model_Preference::GetValue("station_name") )); - $defaultFade = Application_Model_Preference::GetValue("default_fade"); + $defaultFade = Application_Model_Preference::GetDefaultFade(); if($defaultFade == ""){ $defaultFade = '00:00:00.000000'; } @@ -46,7 +46,7 @@ class Application_Form_Preferences extends Zend_Form $this->addElement('checkbox', 'UseSoundCloud', array( 'label' => 'Automatically Upload Recorded Shows To SoundCloud', 'required' => false, - 'value' => Application_Model_Preference::GetValue("soundcloud_upload") + 'value' => Application_Model_Preference::GetDoSoundCloudUpload() )); //SoundCloud Username @@ -55,16 +55,16 @@ class Application_Form_Preferences extends Zend_Form 'label' => 'SoundCloud Username:', 'required' => false, 'filters' => array('StringTrim'), - 'value' => Application_Model_Preference::GetValue("soundcloud_user") + 'value' => Application_Model_Preference::GetSoundCloudUser() )); //SoundCloud Password - $this->addElement('password', 'SoundCloudPassword', array( + $this->addElement('text', 'SoundCloudPassword', array( 'class' => 'input_text', 'label' => 'SoundCloud Password:', 'required' => false, 'filters' => array('StringTrim'), - 'value' => Application_Model_Preference::GetValue("soundcloud_pass") + 'value' => Application_Model_Preference::GetSoundCloudPassword() )); $this->addElement('submit', 'submit', array( diff --git a/application/models/Preference.php b/application/models/Preference.php index 1688fe067..6ecc83ae4 100644 --- a/application/models/Preference.php +++ b/application/models/Preference.php @@ -118,7 +118,7 @@ class Application_Model_Preference Application_Model_Preference::SetValue("soundcloud_password", $password); } - public static function GetSoundCloudUserPassword() { + public static function GetSoundCloudPassword() { return Application_Model_Preference::GetValue("soundcloud_password"); } diff --git a/application/models/Soundcloud.php b/application/models/Soundcloud.php index d1a16247b..ceaa9cc47 100644 --- a/application/models/Soundcloud.php +++ b/application/models/Soundcloud.php @@ -1,31 +1,54 @@ _soundcloud = new Services_Soundcloud($CC_CONFIG['soundcloud-client-id'], $CC_CONFIG['soundcloud-client-secret']); + } -$soundcloud = new Services_Soundcloud('2CLCxcSXYzx7QhhPVHN4A', 'pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs'); + private function getToken() + { + $username = Application_Model_Preference::GetSoundCloudUser(); + $password = Application_Model_Preference::GetSoundCloudPassword(); -$token = $soundcloud->accessTokenResourceOwner('naomiaro@gmail.com', 'airtime17'); + if($username === "" || $password === "") + { + return false; + } -$track_data = array( - 'track[sharing]' => 'private', - 'track[title]' => 'Test', - 'track[asset_data]' => '@/home/naomi/Music/testoutput.mp3' -); + $token = $this->_soundcloud->accessTokenResourceOwner($username, $password); + + return $token; + } + + public function uploadTrack($filepath, $filename) + { + if($this->getToken()) + { + $track_data = array( + 'track[sharing]' => 'private', + 'track[title]' => $filename, + 'track[asset_data]' => '@' . $filepath + ); + + try { + $response = json_decode( + $this->_soundcloud->post('tracks', $track_data), + true + ); + } + catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) { + echo $e->getMessage(); + echo var_dump($track_data); + } + } + } -try { - $response = json_decode( - $soundcloud->post('tracks', $track_data), - true - ); -} -catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) { - show_error($e->getMessage()); } - -*/ diff --git a/install/airtime-install.php b/install/airtime-install.php index d3badef95..55d5ba068 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -49,6 +49,9 @@ AirtimeInstall::ChangeDirOwnerToWebserver($CC_CONFIG["storageDir"]); echo "* Importing Sample Audio Clips".PHP_EOL; system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null"); +echo "* Python eggs Setup".PHP_EOL; +AirtimeInstall::SetUpPythonEggs(); + echo PHP_EOL."*** Pypo Installation ***".PHP_EOL; system("python ".__DIR__."/../pypo/install/pypo-install.py"); diff --git a/install/installInit.php b/install/installInit.php index 6723b063a..65fb574fb 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -190,10 +190,17 @@ class AirtimeInstall { system($command); } + public static function SetUpPythonEggs() + { + //install poster streaming upload + $command = "sudo easy_install poster"; + @exec($command); + } + public static function DeleteFilesRecursive($p_path) { $command = "rm -rf $p_path"; exec($command); } -} \ No newline at end of file +} diff --git a/python_apps/eggs/poster-0.8.0-py2.6.egg b/python_apps/eggs/poster-0.8.0-py2.6.egg deleted file mode 100644 index 7af5c8f5e187432b063287df681c7ebc7adc826a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30851 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 XQlKBf^1sG7$N+R7b6#GjU!VRTOQI`l diff --git a/python_apps/show-recorder/config.cfg b/python_apps/show-recorder/config.cfg index 274d9d786..f75ea204c 100644 --- a/python_apps/show-recorder/config.cfg +++ b/python_apps/show-recorder/config.cfg @@ -1,5 +1,5 @@ # Hostname -base_url = 'http://campcaster.dev/' +base_url = 'http://localhost/' show_schedule_url = 'Recorder/get-show-schedule/format/json' From 73238f92af046f833ae90306eed025113ba30903 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 21 Mar 2011 16:50:20 -0400 Subject: [PATCH 11/74] CC-2082: OGG stream dies after every song when using MPlayer -Fixed all issues related to OGG streams, including mplayer being confused because the silence mp3 file sent was too silent (no data was being sent because the file was too quiet) -silent mp3 file is no longer used, inaudible white noise is generated instead --- pypo/files/sleeper_03.mp3 | Bin 180416 -> 0 bytes pypo/scripts/ls_script.liq | 5 ++--- 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 pypo/files/sleeper_03.mp3 diff --git a/pypo/files/sleeper_03.mp3 b/pypo/files/sleeper_03.mp3 deleted file mode 100644 index 786d4ccb31508368e529d9ded209e82f5dc7004e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180416 zcmeIyJ4(b*7(n5Go3OM~8ygD|D+_T7?Q{VO(^-g*fmxP&n4L`P9^!~voPz<2DJ;${ z0w>)3kS~vMy}KHQVQ02E3|HsZ7sp4ZCwm9?^Ow8B+o|=-zHu|>>}Sr@bv{2aXR)O@ zZ(Ex4zNI;1bH3hyiRYfr_Xm=X{}k+e=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=} z=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI z$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz? zeCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q z%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG% z?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV z;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8BJ6zV;mXG%?0o3q%Euz?eCXlI$0F=}=;6x8 zBJ6zV;mXG%?0o3)hZ@(rt8o~1X2WLvVgJ;Y|2F65{POu>K7X7)?H%ub-kaC+^5yku KvGnOJ_4omP+iZjY diff --git a/pypo/scripts/ls_script.liq b/pypo/scripts/ls_script.liq index 4e3660bc4..5fec857ea 100644 --- a/pypo/scripts/ls_script.liq +++ b/pypo/scripts/ls_script.liq @@ -24,7 +24,7 @@ server.register(namespace="vars", "show_name", fun (s) -> begin show_name := s s server.register(namespace="vars", "station_name", fun (s) -> begin station_name := s s end) -default = audio_to_stereo(single("/opt/pypo/bin/files/sleeper_03.mp3")) +default = amplify(0.00001, noise()) default = rewrite_metadata([("artist","Airtime"), ("title", "offline")],default) s = fallback(track_sensitive=false, [queue, default]) @@ -71,8 +71,7 @@ end if output_icecast_vorbis then #remove metadata from ogg source and merge tracks to fix bug #with vlc and mplayer disconnecting at the end of every track - #silence = add(normalize=false,[blank(), audio_to_stereo(single("/opt/pypo/bin/files/sleeper_03.mp3"))]) - ogg_s = add(normalize=false,[blank(),s]) + ogg_s = add(normalize=false, [amplify(0.00001, noise()),s]) out_vorbis = output.icecast(%vorbis, host = icecast_host, port = icecast_port, password = icecast_pass, mount = mount_point_vorbis, From 864cda6c34ec99e05b1c4c901b8b0acad26d5211 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Tue, 22 Mar 2011 00:46:31 -0400 Subject: [PATCH 12/74] CC-1630 : Automatic recording of shows multi threading now used in recorded for back to back shows. recorded file id is put into show instances table. --- .../controllers/PluploadController.php | 7 +- application/models/Shows.php | 8 ++ python_apps/show-recorder/testrecordscript.py | 89 ++++++++++++------- 3 files changed, 70 insertions(+), 34 deletions(-) diff --git a/application/controllers/PluploadController.php b/application/controllers/PluploadController.php index 25dc47482..0e73bfbb4 100644 --- a/application/controllers/PluploadController.php +++ b/application/controllers/PluploadController.php @@ -173,7 +173,12 @@ class PluploadController extends Zend_Controller_Action $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName()); } - die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); + $show_instance = $this->_getParam('show_instance'); + + $show = new ShowInstance($show_instance); + $show->setRecordedFile($file->getId()); + + die('{"jsonrpc" : "2.0", "id" : '.$file->getId().'}'); } public function pluploadAction() diff --git a/application/models/Shows.php b/application/models/Shows.php index 959a6bf00..57ba0fb45 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -707,6 +707,14 @@ class ShowInstance { ->delete(); } + public function setRecordedFile($file_id) { + + $showInstance = CcShowInstancesQuery::create() + ->findPK($this->_instanceId); + $showInstance->setDbRecordedFile($file_id) + ->save(); + } + public function getTimeScheduled() { $instance_id = $this->getShowInstanceId(); diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index b5cda7409..4c659cdcb 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -13,6 +13,7 @@ from poster.streaminghttp import register_openers import urllib2 from subprocess import call +from threading import Thread # loading config file try: @@ -23,18 +24,46 @@ except Exception, e: shows_to_record = {} +class Recorder(Thread): -def record_show(filelength, filename, filetype="mp3"): + def __init__ (self, show_instance, filelength, filename, filetype): + Thread.__init__(self) + self.filelength = filelength + self.filename = filename + self.filetype = filetype + self.show_instance = show_instance - length = str(filelength)+".0" - filename = filename.replace(" ", "-") - filepath = "%s%s.%s" % (config["base_recorded_files"], filename, filetype) + def record_show(self): - command = "ecasound -i alsa -o %s -t:%s" % (filepath, filelength) + length = str(self.filelength)+".0" + filename = self.filename.replace(" ", "-") + filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - call(command, shell=True) + command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) + call(command, shell=True) - return filepath + return filepath + + def upload_file(self, filepath): + + filename = os.path.split(filepath)[1] + + # Register the streaming http handlers with urllib2 + register_openers() + + # headers contains the necessary Content-Type and Content-Length + # datagen is a generator object that yields the encoded parameters + datagen, headers = multipart_encode({"file": open(filepath, "rb"), 'name': filename, 'show_instance': self.show_instance}) + + url = config["base_url"] + config["upload_file_url"] + + req = urllib2.Request(url, datagen, headers) + response = urllib2.urlopen(req).read().strip() + print response + + def run(self): + filepath = self.record_show() + self.upload_file(filepath) def getDateTimeObj(time): @@ -46,30 +75,42 @@ def getDateTimeObj(time): return datetime.datetime(int(date[0]), int(date[1]), int(date[2]), int(time[0]), int(time[1]), int(time[2])) def process_shows(shows): + + global shows_to_record + shows_to_record = {} for show in shows: show_starts = getDateTimeObj(show[u'starts']) show_end = getDateTimeObj(show[u'ends']) time_delta = show_end - show_starts - shows_to_record[show[u'starts']] = time_delta + shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id']] def check_record(): tnow = datetime.datetime.now() sorted_show_keys = sorted(shows_to_record.keys()) + print sorted_show_keys start_time = sorted_show_keys[0] next_show = getDateTimeObj(start_time) + print next_show + print tnow delta = next_show - tnow + print delta if delta <= datetime.timedelta(seconds=60): + print "sleeping %s seconds until show" % (delta.seconds) time.sleep(delta.seconds) - - show_length = shows_to_record[start_time] - filepath = record_show(show_length.seconds, start_time) - upload_file(filepath) + + show_length = shows_to_record[start_time][0] + show_instance = shows_to_record[start_time][1] + show = Recorder(show_instance, show_length.seconds, start_time, filetype="mp3") + show.start() + + #remove show from shows to record. + del shows_to_record[start_time] def get_shows(): @@ -77,39 +118,21 @@ def get_shows(): url = config["base_url"] + config["show_schedule_url"] response = urllib.urlopen(url) data = response.read() - print data - + response_json = json.loads(data) shows = response_json[u'shows'] print shows if len(shows): process_shows(shows) - check_record() - -def upload_file(filepath): - - filename = os.path.split(filepath)[1] - - # Register the streaming http handlers with urllib2 - register_openers() - - # headers contains the necessary Content-Type and Content-Length - # datagen is a generator object that yields the encoded parameters - datagen, headers = multipart_encode({"file": open(filepath, "rb"), 'name': filename}) - - url = config["base_url"] + config["upload_file_url"] - - req = urllib2.Request(url, datagen, headers) - response = urllib2.urlopen(req).read().strip() - print response + check_record() if __name__ == '__main__': while True: get_shows() - time.sleep(30) + time.sleep(5) From cbe8f98a7c19c7e84e5737d3a97e404898dd8fd9 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 22 Mar 2011 01:29:23 -0400 Subject: [PATCH 13/74] CC-1990: Widget to display schedule and "Now Playing" on any website -initial checkin, some hardcoded values --- application/controllers/ApiController.php | 13 ++ plugins/jquery.showinfo.js | 214 ++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 plugins/jquery.showinfo.js diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index aa4696f89..1ef0d1155 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -101,6 +101,19 @@ class ApiController extends Zend_Controller_Action exit; } + public function liveInfoAction(){ + global $CC_CONFIG; + + // disable the view and the layout + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $result = Schedule::GetPlayOrderRange(0, 1); + //echo json_encode($result); + header("Content-type: text/javascript"); + echo $_GET['callback'].'('.json_encode($result).')'; + } + public function scheduleAction() { global $CC_CONFIG; diff --git a/plugins/jquery.showinfo.js b/plugins/jquery.showinfo.js new file mode 100644 index 000000000..da5be1af8 --- /dev/null +++ b/plugins/jquery.showinfo.js @@ -0,0 +1,214 @@ +(function($){ + $.fn.airtimeShowSchedule = function(options) { + + var defaults = { + updatePeriod: 5, //seconds + }; + var options = $.extend(defaults, options); + + return this.each(function() { + var obj = $(this); + + obj.append("

On air today

"); + obj.append( + ""+ + "" + + "" + + "" + + ""+ + ""+ + ""+ + ""+ + ""+ + "
13:15 - 13:30Program name Listen
13:15 - 13:30Lorem ipsum dolor
"); + }); + }; +})(jQuery); + + +(function($){ + $.fn.airtimeLiveInfo = function(options) { + + var defaults = { + updatePeriod: 5, //seconds + sourceDomain: "http://localhost/", //where to get show status from + audioStreamSource: "" //where to get audio stream from + }; + var options = $.extend(defaults, options); + + return this.each(function() { + var obj = $(this); + var sd; + getServerData(); + + function updateWidget(){ + var currentShow = sd.getCurrentShowName(); + var timeRemaining = sd.getCurrentShowTimeRemaining(); + var timeElapsed = sd.getCurrentShowTimeElapsed(); + var showStatus = sd.getCurrentShowStatus(); + + var nextShow = sd.getNextShowName(); + var nextShowRange = sd.getNextShowRange(); + + obj.empty(); + obj.append("Listen WADR Live"); + obj.append("

"+showStatus+" >>

"); + obj.append("
    " + + "
  • "+currentShow+ ""+timeElapsed+"" + + ""+timeRemaining+"
  • " + + "" + + "
"); + + //refresh the UI + setTimeout(updateWidget, 1000); + } + + function processData(data){ + sd = new ScheduleData(data); + updateWidget(); + } + + function getServerData(){ + $.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){ + processData(data); + }, error:function(jqXHR, textStatus, errorThrown){}}); + setTimeout(getServerData, defaults.updatePeriod*1000); + } + }); + }; +})(jQuery); + +/* The rest of this file is the ScheduleData class */ +function ScheduleData(data){ + this.data = data; + this.estimatedSchedulePosixTime; + + this.schedulePosixTime = this.convertDateToPosixTime(data.schedulerTime); + this.schedulePosixTime += parseInt(data.timezoneOffset)*1000; + var date = new Date(); + this.localRemoteTimeOffset = date.getTime() - this.schedulePosixTime; +} + + +ScheduleData.prototype.secondsTimer = function(){ + var date = new Date(); + this.estimatedSchedulePosixTime = date.getTime() - this.localRemoteTimeOffset; +} + +ScheduleData.prototype.getCurrentShowName = function() { + var currentShow = this.data.currentShow; + if (currentShow.length > 0){ + return "Current: " + currentShow[0].name; + } else { + return ""; + } +}; + +ScheduleData.prototype.getCurrentShowStatus = function() { + var currentShow = this.data.currentShow; + if (currentShow.length > 0){ + return "On Air Now"; + } else { + return "Offline"; + } +}; + +ScheduleData.prototype.getNextShowName = function() { + var nextShow = this.data.nextShow; + if (nextShow.length > 0){ + return "Next: " + nextShow[0].name; + } else { + return ""; + } +}; + +ScheduleData.prototype.getNextShowRange = function() { + var nextShow = this.data.nextShow; + if (nextShow.length > 0){ + return this.getTime(nextShow[0].start_timestamp) + " - " + this.getTime(nextShow[0].end_timestamp); + } else { + return ""; + } +}; + +ScheduleData.prototype.getCurrentShowTimeElapsed = function() { + this.secondsTimer(); + var currentShow = this.data.currentShow; + if (currentShow.length > 0){ + var showStart = this.convertDateToPosixTime(currentShow[0].start_timestamp); + return this.convertToHHMMSS(this.estimatedSchedulePosixTime - showStart); + } else { + return ""; + } +}; + +ScheduleData.prototype.getCurrentShowTimeRemaining = function() { + this.secondsTimer(); + var currentShow = this.data.currentShow; + if (currentShow.length > 0){ + var showEnd = this.convertDateToPosixTime(currentShow[0].end_timestamp); + return this.convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime); + } else { + return ""; + } +}; + +ScheduleData.prototype.getTime = function(timestamp) { + return timestamp.split(" ")[1]; +}; + + +/* Takes an input parameter of milliseconds and converts these into + * the format HH:MM:SS */ +ScheduleData.prototype.convertToHHMMSS = function(timeInMS){ + var time = parseInt(timeInMS); + + var hours = parseInt(time / 3600000); + time -= 3600000*hours; + + var minutes = parseInt(time / 60000); + time -= 60000*minutes; + + var seconds = parseInt(time / 1000); + + hours = hours.toString(); + minutes = minutes.toString(); + seconds = seconds.toString(); + + if (hours.length == 1) + hours = "0" + hours; + if (minutes.length == 1) + minutes = "0" + minutes; + if (seconds.length == 1) + seconds = "0" + seconds; + if (hours == "00") + return minutes + ":" + seconds; + else + return hours + ":" + minutes + ":" + seconds; +} + +/* Takes in a string of format similar to 2011-02-07 02:59:57, + * and converts this to epoch/posix time. */ +ScheduleData.prototype.convertDateToPosixTime = function(s){ + var datetime = s.split(" "); + + var date = datetime[0].split("-"); + var time = datetime[1].split(":"); + + var year = date[0]; + var month = date[1]; + var day = date[2]; + var hour = time[0]; + var minute = time[1]; + var sec = 0; + var msec = 0; + + if (time[2].indexOf(".") != -1){ + var temp = time[2].split("."); + sec = temp[0]; + msec = temp[1]; + } else + sec = time[2]; + + return Date.UTC(year, month, day, hour, minute, sec, msec); +} From d38e2adb58a11931c03b6dd169ad21f2468956a8 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Tue, 22 Mar 2011 09:55:33 -0400 Subject: [PATCH 14/74] CC-2084: Integrate RabbitMQ for immediate schedule updates and commands This is the code for the server side to push the schedule to RabbitMQ. Right now it is disabled and should cause no changes in behavior. Also added comments to functions and formatted code correctly. --- application/Bootstrap.php | 10 +- application/configs/conf.php | 60 ++-- application/controllers/ApiController.php | 6 +- .../controllers/ScheduleController.php | 61 ++-- application/models/DateHelper.php | 100 ++++-- application/models/RabbitMq.php | 33 ++ application/models/Schedule.php | 101 +++--- application/models/Shows.php | 336 ++++++++++-------- pypo/api_clients/api_client_factory.py | 9 - 9 files changed, 410 insertions(+), 306 deletions(-) create mode 100644 application/models/RabbitMq.php delete mode 100644 pypo/api_clients/api_client_factory.py diff --git a/application/Bootstrap.php b/application/Bootstrap.php index 9911b8931..55154676e 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -19,8 +19,10 @@ require_once 'StoredFile.php'; require_once 'Schedule.php'; require_once 'Shows.php'; require_once 'Users.php'; +require_once 'RabbitMq.php'; -global $CC_CONFIG, $CC_DBC; + +global $CC_CONFIG, $CC_DBC; $dsn = $CC_CONFIG['dsn']; $CC_DBC = DB::connect($dsn, FALSE); @@ -64,14 +66,14 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $this->view->headScript()->appendFile('/js/playlist/helperfunctions.js','text/javascript'); $this->view->headScript()->appendFile('/js/playlist/playlist.js','text/javascript'); - $view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript'); + $view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript'); } - + protected function _initViewHelpers(){ $view = $this->getResource('view'); $view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper'); } - + protected function _initTitle(){ $view = $this->getResource('view'); $view->headTitle(Application_Model_Preference::GetHeadTitle()); diff --git a/application/configs/conf.php b/application/configs/conf.php index f43dde788..506510330 100644 --- a/application/configs/conf.php +++ b/application/configs/conf.php @@ -1,14 +1,15 @@ 'www-data', -// *********************************************************************** + 'rabbitmq' => array("host" => "127.0.0.1", + "port" => "5672", + "user" => "guest", + "password" => "guest", + "vhost" => "/"), + + // *********************************************************************** // STOP CUSTOMIZING HERE // - // You don't need to touch anything below this point. + // You don't need to touch anything below this point. // *********************************************************************** 'baseFilesDir' => $baseFilesDir, @@ -55,26 +62,26 @@ $CC_CONFIG = array( //'AdminsGr' => 'Admins', // name of station preferences group - 'StationPrefsGr'=> 'StationPrefs', +// 'StationPrefsGr'=> 'StationPrefs', // name of 'all users' group //'AllGr' => 'All', /* ==================================== application-specific configuration */ - 'objtypes' => array( - 'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/), - 'File' => array(), - 'audioclip' => array(), - 'playlist' => array(), - ), - 'allowedActions'=> array( - 'File' => array('editPrivs', 'write', 'read'), - 'audioclip' => array('editPrivs', 'write', 'read'), - 'playlist' => array('editPrivs', 'write', 'read'), - ), - 'allActions' => array( - 'editPrivs', 'write', 'read', 'subjects' - ), +// 'objtypes' => array( +// 'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/), +// 'File' => array(), +// 'audioclip' => array(), +// 'playlist' => array(), +// ), +// 'allowedActions'=> array( +// 'File' => array('editPrivs', 'write', 'read'), +// 'audioclip' => array('editPrivs', 'write', 'read'), +// 'playlist' => array('editPrivs', 'write', 'read'), +// ), +// 'allActions' => array( +// 'editPrivs', 'write', 'read', 'subjects' +// ), /* =================================================== cron configuration */ 'cronUserName' => 'www-data', @@ -82,7 +89,7 @@ $CC_CONFIG = array( 'lockfile' => dirname(__FILE__).'/stor/buffer/cron.lock', 'cronfile' => dirname(__FILE__).'/cron/croncall.php', 'paramdir' => dirname(__FILE__).'/cron/params', - 'systemPrefId' => "0", // ID for system prefs in prefs table +// 'systemPrefId' => "0", // ID for system prefs in prefs table ); // Add database table names @@ -94,10 +101,8 @@ $CC_CONFIG['permTable'] = $CC_CONFIG['tblNamePrefix'].'perms'; $CC_CONFIG['sessTable'] = $CC_CONFIG['tblNamePrefix'].'sess'; $CC_CONFIG['subjTable'] = $CC_CONFIG['tblNamePrefix'].'subjs'; $CC_CONFIG['smembTable'] = $CC_CONFIG['tblNamePrefix'].'smemb'; -$CC_CONFIG['transTable'] = $CC_CONFIG['tblNamePrefix'].'trans'; $CC_CONFIG['prefTable'] = $CC_CONFIG['tblNamePrefix'].'pref'; $CC_CONFIG['scheduleTable'] = $CC_CONFIG['tblNamePrefix'].'schedule'; -$CC_CONFIG['backupTable'] = $CC_CONFIG['tblNamePrefix'].'backup'; $CC_CONFIG['playListTimeView'] = $CC_CONFIG['tblNamePrefix'].'playlisttimes'; $CC_CONFIG['showSchedule'] = $CC_CONFIG['tblNamePrefix'].'show_schedule'; $CC_CONFIG['showDays'] = $CC_CONFIG['tblNamePrefix'].'show_days'; @@ -106,16 +111,15 @@ $CC_CONFIG['showInstances'] = $CC_CONFIG['tblNamePrefix'].'show_instances'; $CC_CONFIG['playListSequence'] = $CC_CONFIG['playListTable'].'_id'; $CC_CONFIG['filesSequence'] = $CC_CONFIG['filesTable'].'_id'; -$CC_CONFIG['transSequence'] = $CC_CONFIG['transTable'].'_id'; $CC_CONFIG['prefSequence'] = $CC_CONFIG['prefTable'].'_id'; $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id'; $CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id'; $CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id'; // System users/groups - they cannot be deleted -$CC_CONFIG['sysSubjs'] = array( - 'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr'] -); +//$CC_CONFIG['sysSubjs'] = array( +// 'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr'] +//); // Add libs to the PHP path $old_include_path = get_include_path(); @@ -125,9 +129,9 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'] function load_airtime_config(){ $ini_array = parse_ini_file(dirname(__FILE__).'/../../build/airtime.conf', true); - + return array( - 'database' => array( + 'database' => array( 'username' => $ini_array['database']['dbuser'], 'password' => $ini_array['database']['dbpass'], 'hostspec' => $ini_array['database']['host'], diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index aa4696f89..06ebe1303 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -24,7 +24,7 @@ class ApiController extends Zend_Controller_Action * in application/conf.php * * @return void - * + * */ public function versionAction() { @@ -123,14 +123,10 @@ class ApiController extends Zend_Controller_Action $to = $this->_getParam("to"); if (Schedule::ValidPypoTimeFormat($from) && Schedule::ValidPypoTimeFormat($to)) { $result = Schedule::ExportRangeAsJson($from, $to); - $result['stream_metadata'] = array(); - $result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat(); - $result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName(); echo json_encode($result); } } - public function notifyMediaItemStartPlayAction() { global $CC_CONFIG; diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index db0ec0526..daf774517 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -19,9 +19,9 @@ class ScheduleController extends Zend_Controller_Action ->addActionContext('schedule-show-dialog', 'json') ->addActionContext('show-content-dialog', 'json') ->addActionContext('clear-show', 'json') - ->addActionContext('get-current-playlist', 'json') + ->addActionContext('get-current-playlist', 'json') ->addActionContext('find-playlists', 'json') - ->addActionContext('remove-group', 'json') + ->addActionContext('remove-group', 'json') ->addActionContext('edit-show', 'json') ->addActionContext('add-show', 'json') ->addActionContext('cancel-show', 'json') @@ -64,7 +64,7 @@ class ScheduleController extends Zend_Controller_Action $formRepeats->removeDecorator('DtDdWrapper'); $formStyle->removeDecorator('DtDdWrapper'); $formRecord->removeDecorator('DtDdWrapper'); - + $this->view->what = $formWhat; $this->view->when = $formWhen; @@ -84,7 +84,7 @@ class ScheduleController extends Zend_Controller_Action { $start = $this->_getParam('start', null); $end = $this->_getParam('end', null); - + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); if($user->isAdmin()) @@ -111,6 +111,7 @@ class ScheduleController extends Zend_Controller_Action if(isset($error)) $this->view->error = $error; + } public function resizeShowAction() @@ -134,7 +135,7 @@ class ScheduleController extends Zend_Controller_Action public function deleteShowAction() { $showInstanceId = $this->_getParam('id'); - + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); @@ -158,41 +159,41 @@ class ScheduleController extends Zend_Controller_Action if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { if (($user->isHost($show->getShowId()) || $user->isAdmin()) && !$show->isRecorded() && !$show->isRebroadcast()) { - - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, + + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, 'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add Content'); - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Remove All Content'); } } if(!$show->isRecorded()) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/show-content-dialog'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/show-content-dialog'.$params, 'callback' => 'window["buildContentDialog"]'), 'title' => 'Show Content'); } - + if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) && strtotime($today_timestamp) < strtotime($show->getShowEnd())) { $menu[] = array('action' => array('type' => 'fn', //'url' => '/Schedule/cancel-current-show'.$params, - 'callback' => "window['confirmCancelShow']($id)"), - 'title' => 'Cancel Current Show'); + 'callback' => "window['confirmCancelShow']($id)"), + 'title' => 'Cancel Current Show'); } - + if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { if ($user->isAdmin()) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance'); - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following'); } } - + //returns format jjmenu is looking for. die(json_encode($menu)); } @@ -219,7 +220,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->timeFilled = $show->getTimeScheduled(); $this->view->percentFilled = $show->getPercentScheduled(); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); unset($this->view->showContent); } @@ -242,7 +243,7 @@ class ScheduleController extends Zend_Controller_Action public function findPlaylistsAction() { $post = $this->getRequest()->getPost(); - + $show = new ShowInstance($this->sched_sess->showInstanceId); $playlists = $show->searchPlaylistsForShow($post); @@ -267,7 +268,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->showContent = $show->getShowContent(); $this->view->timeFilled = $show->getTimeScheduled(); $this->view->percentFilled = $show->getPercentScheduled(); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); unset($this->view->showContent); } @@ -275,7 +276,7 @@ class ScheduleController extends Zend_Controller_Action { $showInstanceId = $this->_getParam('id'); $this->sched_sess->showInstanceId = $showInstanceId; - + $show = new ShowInstance($showInstanceId); $start_timestamp = $show->getShowStart(); $end_timestamp = $show->getShowEnd(); @@ -285,14 +286,14 @@ class ScheduleController extends Zend_Controller_Action $this->view->error = "cannot schedule an overlapping show."; return; } - + $start = explode(" ", $start_timestamp); $end = explode(" ", $end_timestamp); $startTime = explode(":", $start[1]); $endTime = explode(":", $end[1]); $dateInfo_s = getDate(strtotime($start_timestamp)); $dateInfo_e = getDate(strtotime($end_timestamp)); - + $this->view->showContent = $show->getShowContent(); $this->view->timeFilled = $show->getTimeScheduled(); $this->view->showName = $show->getName(); @@ -308,7 +309,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->startTime = sprintf("%d:%02d", $startTime[0], $startTime[1]); $this->view->endTime = sprintf("%d:%02d", $endTime[0], $endTime[1]); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); $this->view->dialog = $this->view->render('schedule/schedule-show-dialog.phtml'); unset($this->view->showContent); } @@ -335,7 +336,7 @@ class ScheduleController extends Zend_Controller_Action { $js = $this->_getParam('data'); $data = array(); - + //need to convert from serialized jQuery array. foreach($js as $j){ $data[$j["name"]] = $j["value"]; @@ -392,8 +393,8 @@ class ScheduleController extends Zend_Controller_Action $rebroadAb = $formAbsoluteRebroadcast->isValid($data); $rebroad = $formRebroadcast->isValid($data); - if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) { - + if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) { + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); if($user->isAdmin()) { @@ -413,7 +414,7 @@ class ScheduleController extends Zend_Controller_Action $formRecord->reset(); $formAbsoluteRebroadcast->reset(); $formRebroadcast->reset(); - + $this->view->newForm = $this->view->render('schedule/add-show-form.phtml'); } else { @@ -426,7 +427,7 @@ class ScheduleController extends Zend_Controller_Action { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); - + if($user->isAdmin()) { $showInstanceId = $this->_getParam('id'); @@ -434,14 +435,14 @@ class ScheduleController extends Zend_Controller_Action $show = new Show($showInstance->getShowId()); $show->cancelShow($showInstance->getShowStart()); - } + } } public function cancelCurrentShowAction() { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); - + if($user->isAdmin()) { $showInstanceId = $this->_getParam('id'); $show = new ShowInstance($showInstanceId); diff --git a/application/models/DateHelper.php b/application/models/DateHelper.php index 640e5cd6a..d0f56f647 100644 --- a/application/models/DateHelper.php +++ b/application/models/DateHelper.php @@ -2,61 +2,85 @@ class Application_Model_DateHelper { - private $_timestamp; - - function __construct() { + private $_timestamp; + + function __construct() + { $this->_timestamp = date("U"); - } - - function getDate(){ - return date("Y-m-d H:i:s", $this->_timestamp); - } - - function getTime(){ - return date("H:i:s", $this->_timestamp); - } - - function setDate($dateString){ + } + + /** + * Get time of object construction in the format + * YYYY-MM-DD HH:mm:ss + */ + function getDate() + { + return date("Y-m-d H:i:s", $this->_timestamp); + } + + /** + * Get time of object construction in the format + * HH:mm:ss + */ + function getTime() + { + return date("H:i:s", $this->_timestamp); + } + + /** + * Set the internal timestamp of the object. + */ + function setDate($dateString) + { $this->_timestamp = strtotime($dateString); - } - - function getNowDayStartDiff(){ - $dayStartTS = strtotime(date("Y-m-d", $this->_timestamp)); - return $this->_timestamp - $dayStartTS; - } + } - function getNowDayEndDiff(){ - $dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400))); - return $dayEndTS - $this->_timestamp; - } + /** + * + * Enter description here ... + */ + function getNowDayStartDiff() + { + $dayStartTS = strtotime(date("Y-m-d", $this->_timestamp)); + return $this->_timestamp - $dayStartTS; + } - function getEpochTime(){ + function getNowDayEndDiff() + { + $dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400))); + return $dayEndTS - $this->_timestamp; + } + + function getEpochTime() + { return $this->_timestamp; - } + } - public static function TimeDiff($time1, $time2){ + public static function TimeDiff($time1, $time2) + { return strtotime($time2) - strtotime($time1); - } - - public static function ConvertMSToHHMMSSmm($time){ + } + + public static function ConvertMSToHHMMSSmm($time) + { $hours = floor($time / 3600000); $time -= 3600000*$hours; - + $minutes = floor($time / 60000); $time -= 60000*$minutes; - + $seconds = floor($time / 1000); $time -= 1000*$seconds; - + $ms = $time; - + if (strlen($hours) == 1) - $hours = "0".$hours; + $hours = "0".$hours; if (strlen($minutes) == 1) - $minutes = "0".$minutes; + $minutes = "0".$minutes; if (strlen($seconds) == 1) - $seconds = "0".$seconds; - + $seconds = "0".$seconds; + return $hours.":".$minutes.":".$seconds.".".$ms; } } diff --git a/application/models/RabbitMq.php b/application/models/RabbitMq.php new file mode 100644 index 000000000..d251116bf --- /dev/null +++ b/application/models/RabbitMq.php @@ -0,0 +1,33 @@ +channel(); +// $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); +// +// $EXCHANGE = 'airtime-schedule'; +// $channel->exchange_declare($EXCHANGE, 'direct', false, false, false); +// +// $data = json_encode(Schedule::ExportRangeAsJson()); +// $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); +// +// $channel->basic_publish($msg, $EXCHANGE); +// $channel->close(); +// $conn->close(); + } + +} + diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 5fe66f2ca..fc1c10770 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -110,7 +110,6 @@ class ScheduleGroup { //var_dump($sql); return $result; } - return $this->groupId; } elseif (!is_null($p_playlistId)){ // Schedule a whole playlist @@ -153,8 +152,9 @@ class ScheduleGroup { $itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'"); $id = $this->dateToId($itemStartTime); } - return $this->groupId; } + RabbitMq::PushSchedule(); + return $this->groupId; } public function addAfter($show_instance, $p_groupId, $p_audioFileId) { @@ -176,10 +176,6 @@ class ScheduleGroup { return $this->add($show_instance, $startTime, null, $p_playlistId); } - public function update() { - - } - /** * Remove the group from the schedule. * Note: does not check if it is in the past, you can remove anything. @@ -195,7 +191,9 @@ class ScheduleGroup { $sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"] ." WHERE group_id = ".$this->groupId; //echo $sql; - return $CC_DBC->query($sql); + $retVal = $CC_DBC->query($sql); + RabbitMq::PushSchedule(); + return $retVal; } /** @@ -231,17 +229,14 @@ class ScheduleGroup { return $CC_DBC->GetAll($sql); } - public function reschedule($toDateTime) { - global $CC_CONFIG, $CC_DBC; - // $sql = "UPDATE ".$CC_CONFIG["scheduleTable"]. " SET id=, starts=,ends=" - } - public function notifyGroupStartPlay() { global $CC_CONFIG, $CC_DBC; $sql = "UPDATE ".$CC_CONFIG['scheduleTable'] ." SET schedule_group_played=TRUE" ." WHERE group_id=".$this->groupId; - return $CC_DBC->query($sql); + $retVal = $CC_DBC->query($sql); + RabbitMq::PushSchedule(); + return $retVal; } public function notifyMediaItemStartPlay($p_fileId) { @@ -250,7 +245,9 @@ class ScheduleGroup { ." SET media_item_played=TRUE" ." WHERE group_id=".$this->groupId ." AND file_id=".pg_escape_string($p_fileId); - return $CC_DBC->query($sql); + $retVal = $CC_DBC->query($sql); + RabbitMq::PushSchedule(); + return $retVal; } } @@ -334,9 +331,10 @@ class Schedule { return $res; } - public static function GetPercentScheduled($instance_id, $s_datetime, $e_datetime){ + public static function GetPercentScheduled($instance_id, $s_datetime, $e_datetime) + { $time = Schedule::GetTotalShowTime($instance_id); - + $s_epoch = strtotime($s_datetime); $e_epoch = strtotime($e_datetime); @@ -396,7 +394,8 @@ class Schedule { * @return array * Returns empty array if nothing found */ - public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true) { + public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true) + { global $CC_CONFIG, $CC_DBC; $rows = array(); if (!$p_playlistsOnly) { @@ -433,7 +432,7 @@ class Schedule { ." AND (st.ends <= TIMESTAMP '$p_toDateTime')" //next line makes sure that we aren't returning items that //are past the show's scheduled timeslot. - ." AND (st.starts < si.ends)" + ." AND (st.starts < si.ends)" ." GROUP BY st.group_id" ." ORDER BY starts"; @@ -457,7 +456,8 @@ class Schedule { * @param int $next * @return date */ - public static function GetPlayOrderRange($prev = 1, $next = 1) { + public static function GetPlayOrderRange($prev = 1, $next = 1) + { if (!is_int($prev) || !is_int($next)){ //must enter integers to specify ranges return array(); @@ -469,9 +469,9 @@ class Schedule { $timeNow = $date->getDate(); return array("env"=>APPLICATION_ENV, "schedulerTime"=>gmdate("Y-m-d H:i:s"), - "previous"=>Schedule::Get_Scheduled_Item_Data($timeNow, -1, $prev, "24 hours"), - "current"=>Schedule::Get_Scheduled_Item_Data($timeNow, 0), - "next"=>Schedule::Get_Scheduled_Item_Data($timeNow, 1, $next, "48 hours"), + "previous"=>Schedule::GetScheduledItemData($timeNow, -1, $prev, "24 hours"), + "current"=>Schedule::GetScheduledItemData($timeNow, 0), + "next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"), "currentShow"=>Show_DAL::GetCurrentShow($timeNow), "nextShow"=>Show_DAL::GetNextShow($timeNow), "timezone"=> date("T"), @@ -501,7 +501,8 @@ class Schedule { * want to search the database. For example "5 days", "18 hours", "60 minutes", * "30 seconds" etc. */ - public static function Get_Scheduled_Item_Data($timeStamp, $timePeriod=0, $count = 0, $interval="0 hours"){ + public static function GetScheduledItemData($timeStamp, $timePeriod=0, $count = 0, $interval="0 hours") + { global $CC_CONFIG, $CC_DBC; $sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id" @@ -531,7 +532,8 @@ class Schedule { return $rows; } - public static function GetShowInstanceItems($instance_id){ + public static function GetShowInstanceItems($instance_id) + { global $CC_CONFIG, $CC_DBC; $sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id" @@ -547,12 +549,15 @@ class Schedule { return $rows; } - public static function UpdateMediaPlayedStatus($id){ + public static function UpdateMediaPlayedStatus($p_id) + { global $CC_CONFIG, $CC_DBC; $sql = "UPDATE ".$CC_CONFIG['scheduleTable'] ." SET media_item_played=TRUE" - ." WHERE id=$id"; - return $CC_DBC->query($sql); + ." WHERE id=$p_id"; + $retVal = $CC_DBC->query($sql); + RabbitMq::PushSchedule(); + return $retVal; } @@ -563,7 +568,7 @@ class Schedule { * @param string $p_time * @return string */ - private static function CcTimeToPypoTime($p_time) + private static function AirtimeTimeToPypoTime($p_time) { $p_time = substr($p_time, 0, 19); $p_time = str_replace(" ", "-", $p_time); @@ -578,7 +583,7 @@ class Schedule { * @param string $p_time * @return string */ - private static function PypoTimeToCcTime($p_time) + private static function PypoTimeToAirtimeTime($p_time) { $t = explode("-", $p_time); return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00"; @@ -658,17 +663,29 @@ class Schedule { /** * Export the schedule in json formatted for pypo (the liquidsoap scheduler) * - * @param string $range - * In the format "YYYY-MM-DD HH:mm:ss" - * @param string $source - * In the format "YYYY-MM-DD HH:mm:ss" + * @param string $p_fromDateTime + * In the format "YYYY-MM-DD-HH-mm-SS" + * @param string $p_toDateTime + * In the format "YYYY-MM-DD-HH-mm-SS" */ - public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime) + public static function ExportRangeAsJson($p_fromDateTime = null , $p_toDateTime = null) { global $CC_CONFIG, $CC_DBC; - $range_start = Schedule::PypoTimeToCcTime($p_fromDateTime); - $range_end = Schedule::PypoTimeToCcTime($p_toDateTime); + if (is_null($p_fromDateTime)) { + $t1 = new DateTime(); + $t1->sub(new DateInterval("PT24H")); + $range_start = $t1->format("Y-m-d H:i:s"); + } else { + $range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime); + } + if (is_null($p_fromDateTime)) { + $t2 = new DateTime(); + $t2->add(new DateInterval("PT24H")); + $range_end = $t2->format("Y-m-d H:i:s"); + } else { + $range_end = Schedule::PypoTimeToAirtimeTime($p_toDateTime); + } // Scheduler wants everything in a playlist $data = Schedule::GetItems($range_start, $range_end, true); @@ -684,7 +701,7 @@ class Schedule { $start = substr($start, 0, 19); //Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss" - $pkey = Schedule::CcTimeToPypoTime($start); + $pkey = Schedule::AirtimeTimeToPypoTime($start); $timestamp = strtotime($start); $playlists[$pkey]['source'] = "PLAYLIST"; $playlists[$pkey]['x_ident'] = $dx["playlist_id"]; @@ -696,8 +713,8 @@ class Schedule { $playlists[$pkey]['show_name'] = $dx['show_name']; $playlists[$pkey]['user_id'] = 0; $playlists[$pkey]['id'] = $dx["playlist_id"]; - $playlists[$pkey]['start'] = Schedule::CcTimeToPypoTime($dx["start"]); - $playlists[$pkey]['end'] = Schedule::CcTimeToPypoTime($dx["end"]); + $playlists[$pkey]['start'] = Schedule::AirtimeTimeToPypoTime($dx["start"]); + $playlists[$pkey]['end'] = Schedule::AirtimeTimeToPypoTime($dx["end"]); } } @@ -734,9 +751,12 @@ class Schedule { $result = array(); $result['status'] = array('range' => array('start' => $range_start, 'end' => $range_end), - 'version' => "1.1"); + 'version' => AIRTIME_REST_VERSION); $result['playlists'] = $playlists; $result['check'] = 1; + $result['stream_metadata'] = array(); + $result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat(); + $result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName(); return $result; } @@ -757,6 +777,7 @@ class Schedule { $scheduleGroup = new ScheduleGroup($item["group_id"]); $scheduleGroup->remove(); } + RabbitMq::PushSchedule(); } } diff --git a/application/models/Shows.php b/application/models/Shows.php index 959a6bf00..a50be1c4a 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -6,50 +6,60 @@ class Show { public function __construct($showId=NULL) { - $this->_showId = $showId; + $this->_showId = $showId; } - public function getName() { + public function getName() + { $show = CcShowQuery::create()->findPK($this->_showId); return $show->getDbName(); } - - public function setName($name) { + + public function setName($name) + { $show = CcShowQuery::create()->findPK($this->_showId); $show->setDbName($name); + RabbitMq::PushSchedule(); } - public function getDescription() { + public function getDescription() + { $show = CcShowQuery::create()->findPK($this->_showId); return $show->getDbDescription(); } - - public function setDescription($description) { + + public function setDescription($description) + { $show = CcShowQuery::create()->findPK($this->_showId); $show->setDbDescription($description); } - public function getColor() { + public function getColor() + { $show = CcShowQuery::create()->findPK($this->_showId); return $show->getDbColor(); } - - public function setColor($color) { + + public function setColor($color) + { $show = CcShowQuery::create()->findPK($this->_showId); $show->setDbColor($color); } - public function getBackgroundColor() { + public function getBackgroundColor() + { $show = CcShowQuery::create()->findPK($this->_showId); return $show->getDbBackgroundColor(); } - - public function setBackgroundColor($backgroundColor) { + + public function setBackgroundColor($backgroundColor) + { $show = CcShowQuery::create()->findPK($this->_showId); $show->setDbBackgroundColor($backgroundColor); } - public function cancelShow($day_timestamp) { + public function cancelShow($day_timestamp) + { global $CC_DBC; $timeinfo = explode(" ", $day_timestamp); @@ -62,20 +72,21 @@ class Show { WHERE starts >= '{$day_timestamp}' AND show_id = {$this->_showId}"; $CC_DBC->query($sql); + RabbitMq::PushSchedule(); } //end dates are non inclusive. - public static function addShow($data) { - + public static function addShow($data) + { $con = Propel::getConnection(CcShowPeer::DATABASE_NAME); $sql = "SELECT time '{$data['add_show_start_time']}' + INTERVAL '{$data['add_show_duration']} hour' "; $r = $con->query($sql); - $endTime = $r->fetchColumn(0); + $endTime = $r->fetchColumn(0); $sql = "SELECT EXTRACT(DOW FROM TIMESTAMP '{$data['add_show_start_date']} {$data['add_show_start_time']}')"; $r = $con->query($sql); - $startDow = $r->fetchColumn(0); + $startDow = $r->fetchColumn(0); if($data['add_show_no_end']) { $endDate = NULL; @@ -84,13 +95,13 @@ class Show { else if($data['add_show_repeats']) { $sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' "; $r = $con->query($sql); - $endDate = $r->fetchColumn(0); + $endDate = $r->fetchColumn(0); } else { $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '1 day' "; $r = $con->query($sql); $endDate = $r->fetchColumn(0); - } + } //only want the day of the week from the start date. if(!$data['add_show_repeats']) { @@ -98,7 +109,7 @@ class Show { } else if($data['add_show_repeats'] && $data['add_show_day_check'] == "") { $data['add_show_day_check'] = array($startDow); - } + } //find repeat type or set to a non repeating show. if($data['add_show_repeats']) { @@ -114,7 +125,7 @@ class Show { $show->setDbUrl($data['add_show_url']); $show->setDbColor($data['add_show_color']); $show->setDbBackgroundColor($data['add_show_background_color']); - $show->save(); + $show->save(); $showId = $show->getDbId(); @@ -127,7 +138,6 @@ class Show { //don't set day for monthly repeat type, it's invalid. if($data['add_show_repeats'] && $data["add_show_repeat_type"] == 2) { - $showDay = new CcShowDays(); $showDay->setDbFirstShow($data['add_show_start_date']); $showDay->setDbLastShow($endDate); @@ -137,29 +147,25 @@ class Show { $showDay->setDbShowId($showId); $showDay->setDbRecord($isRecorded); $showDay->save(); - } else { - foreach ($data['add_show_day_check'] as $day) { - if($startDow !== $day){ - - if($startDow > $day) + + if ($startDow > $day) $daysAdd = 6 - $startDow + 1 + $day; else - $daysAdd = $day - $startDow; + $daysAdd = $day - $startDow; $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '{$daysAdd} day' "; $r = $con->query($sql); - $start = $r->fetchColumn(0); + $start = $r->fetchColumn(0); } else { $start = $data['add_show_start_date']; } if(strtotime($start) < strtotime($endDate) || is_null($endDate)) { - $showDay = new CcShowDays(); $showDay->setDbFirstShow($start); $showDay->setDbLastShow($endDate); @@ -180,7 +186,6 @@ class Show { for($i=1; $i<=5; $i++) { if($data['add_show_rebroadcast_date_'.$i]) { - $showRebroad = new CcShowRebroadcast(); $showRebroad->setDbDayOffset($data['add_show_rebroadcast_date_'.$i]); $showRebroad->setDbStartTime($data['add_show_rebroadcast_time_'.$i]); @@ -190,14 +195,13 @@ class Show { } } else if($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type == -1){ - + for($i=1; $i<=5; $i++) { if($data['add_show_rebroadcast_absolute_date_'.$i]) { - $sql = "SELECT date '{$data['add_show_rebroadcast_absolute_date_'.$i]}' - date '{$data['add_show_start_date']}' "; $r = $con->query($sql); - $offset_days = $r->fetchColumn(0); + $offset_days = $r->fetchColumn(0); $showRebroad = new CcShowRebroadcast(); $showRebroad->setDbDayOffset($offset_days." days"); @@ -207,7 +211,7 @@ class Show { } } } - + if(is_array($data['add_show_hosts'])) { //add selected hosts to cc_show_hosts table. foreach ($data['add_show_hosts'] as $host) { @@ -219,18 +223,20 @@ class Show { } Show::populateShowUntilLastGeneratedDate($showId); + RabbitMq::PushSchedule(); } - public static function getShows($start_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=FALSE) { + public static function getShows($start_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=FALSE) + { global $CC_DBC; - $sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, description, - color, background_color, cc_show_instances.id AS instance_id - FROM cc_show_instances + $sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, description, + color, background_color, cc_show_instances.id AS instance_id + FROM cc_show_instances LEFT JOIN cc_show ON cc_show.id = cc_show_instances.show_id"; //only want shows that are starting at the time or later. - if($onlyRecord) { + if ($onlyRecord) { $sql = $sql." WHERE (starts >= '{$start_timestamp}' AND starts < timestamp '{$start_timestamp}' + interval '2 hours')"; $sql = $sql." AND (record = 1)"; @@ -240,10 +246,10 @@ class Show { $sql = $sql." WHERE ((starts >= '{$start_timestamp}' AND starts < '{$end_timestamp}') OR (ends > '{$start_timestamp}' AND ends <= '{$end_timestamp}') OR (starts <= '{$start_timestamp}' AND ends >= '{$end_timestamp}'))"; - } - + } - if(isset($excludeInstance)) { + + if (isset($excludeInstance)) { foreach($excludeInstance as $instance) { $sql_exclude[] = "cc_show_instances.id != {$instance}"; } @@ -257,8 +263,8 @@ class Show { return $CC_DBC->GetAll($sql); } - private static function setNextPop($next_date, $show_id, $day) { - + private static function setNextPop($next_date, $show_id, $day) + { $nextInfo = explode(" ", $next_date); $repeatInfo = CcShowDaysQuery::create() @@ -271,15 +277,16 @@ class Show { } //for a show with repeat_type == -1 - private static function populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp) { + private static function populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp) + { global $CC_DBC; - + $next_date = $first_show." ".$start_time; - + if(strtotime($next_date) < strtotime($end_timestamp)) { - + $start = $next_date; - + $sql = "SELECT timestamp '{$start}' + interval '{$duration}'"; $end = $CC_DBC->GetOne($sql); @@ -298,10 +305,10 @@ class Show { foreach($rebroadcasts as $rebroadcast) { $timeinfo = explode(" ", $start); - + $sql = "SELECT timestamp '{$timeinfo[0]}' + interval '{$rebroadcast["day_offset"]}' + interval '{$rebroadcast["start_time"]}'"; $rebroadcast_start_time = $CC_DBC->GetOne($sql); - + $sql = "SELECT timestamp '{$rebroadcast_start_time}' + interval '{$duration}'"; $rebroadcast_end_time = $CC_DBC->GetOne($sql); @@ -315,12 +322,13 @@ class Show { $newRebroadcastInstance->save(); } } + RabbitMq::PushSchedule(); } //for a show with repeat_type == 0,1,2 - private static function populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + private static function populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, $interval) { - global $CC_DBC; + global $CC_DBC; if(isset($next_pop_date)) { $next_date = $next_pop_date." ".$start_time; @@ -333,9 +341,9 @@ class Show { $rebroadcasts = $CC_DBC->GetAll($sql); while(strtotime($next_date) < strtotime($end_timestamp) && (strtotime($last_show) > strtotime($next_date) || is_null($last_show))) { - + $start = $next_date; - + $sql = "SELECT timestamp '{$start}' + interval '{$duration}'"; $end = $CC_DBC->GetOne($sql); @@ -351,10 +359,10 @@ class Show { foreach($rebroadcasts as $rebroadcast) { $timeinfo = explode(" ", $next_date); - + $sql = "SELECT timestamp '{$timeinfo[0]}' + interval '{$rebroadcast["day_offset"]}' + interval '{$rebroadcast["start_time"]}'"; $rebroadcast_start_time = $CC_DBC->GetOne($sql); - + $sql = "SELECT timestamp '{$rebroadcast_start_time}' + interval '{$duration}'"; $rebroadcast_end_time = $CC_DBC->GetOne($sql); @@ -373,64 +381,65 @@ class Show { } Show::setNextPop($next_date, $show_id, $day); + RabbitMq::PushSchedule(); } - private static function populateShow($repeat_type, $show_id, $next_pop_date, + private static function populateShow($repeat_type, $show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp) { if($repeat_type == -1) { Show::populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp); } else if($repeat_type == 0) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '7 days'); } else if($repeat_type == 1) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '14 days'); } else if($repeat_type == 2) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '1 month'); } - } + } //used to catch up a newly added show private static function populateShowUntilLastGeneratedDate($show_id) { global $CC_DBC; $showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil(); - + $sql = "SELECT * FROM cc_show_days WHERE show_id = {$show_id}"; - $res = $CC_DBC->GetAll($sql); + $res = $CC_DBC->GetAll($sql); foreach($res as $row) { - Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], - $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $showsPopUntil); - } + Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], + $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $showsPopUntil); + } } public static function populateShowsUntil($pop_timestamp, $end_timestamp) { global $CC_DBC; if($pop_timestamp != "") { - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL + $sql = "SELECT * FROM cc_show_days + WHERE last_show IS NULL OR first_show < '{$end_timestamp}' AND last_show > '{$pop_timestamp}'"; } else { $today_timestamp = date("Y-m-d"); - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL + $sql = "SELECT * FROM cc_show_days + WHERE last_show IS NULL OR first_show < '{$end_timestamp}' AND last_show > '{$today_timestamp}'"; } - $res = $CC_DBC->GetAll($sql); + $res = $CC_DBC->GetAll($sql); foreach($res as $row) { - Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], - $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $end_timestamp); - } + Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], + $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $end_timestamp); + } } public static function getFullCalendarEvents($start, $end, $editable=false) { @@ -460,7 +469,7 @@ class Show { private static function makeFullCalendarEvent($show, $options=array()) { global $CC_DBC; - + $event = array(); if($show["rebroadcast"]) { @@ -500,56 +509,68 @@ class ShowInstance { public function __construct($instanceId) { - $this->_instanceId = $instanceId; + $this->_instanceId = $instanceId; } - public function getShowId() { + public function getShowId() + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); return $showInstance->getDbShowId(); } - public function getShowInstanceId() { + public function getShowInstanceId() + { return $this->_instanceId; } - public function isRebroadcast() { + public function isRebroadcast() + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); return $showInstance->getDbOriginalShow(); } - public function isRecorded() { + public function isRecorded() + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); return $showInstance->getDbRecord(); } - public function getName() { + public function getName() + { $show = CcShowQuery::create()->findPK($this->getShowId()); return $show->getDbName(); } - public function getShowStart() { + public function getShowStart() + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); return $showInstance->getDbStarts(); } - public function getShowEnd() { + public function getShowEnd() + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); return $showInstance->getDbEnds(); } - public function setShowStart($start) { + public function setShowStart($start) + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); $showInstance->setDbStarts($start) ->save(); + RabbitMq::PushSchedule(); } - public function setShowEnd($end) { + public function setShowEnd($end) + { $showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId); $showInstance->setDbEnds($end) - ->save(); + ->save(); + RabbitMq::PushSchedule(); } - public function moveScheduledShowContent($deltaDay, $deltaHours, $deltaMin) { + public function moveScheduledShowContent($deltaDay, $deltaHours, $deltaMin) + { global $CC_DBC; $sql = "UPDATE cc_schedule @@ -558,9 +579,11 @@ class ShowInstance { WHERE instance_id = '{$this->_instanceId}'"; $CC_DBC->query($sql); + RabbitMq::PushSchedule(); } - public function moveShow($deltaDay, $deltaMin){ + public function moveShow($deltaDay, $deltaMin) + { global $CC_DBC; $hours = $deltaMin/60; @@ -572,7 +595,7 @@ class ShowInstance { $mins = abs($deltaMin%60); $starts = $this->getShowStart(); - $ends = $this->getShowEnd(); + $ends = $this->getShowEnd(); $sql = "SELECT timestamp '{$starts}' + interval '{$deltaDay} days' + interval '{$hours}:{$mins}'"; $new_starts = $CC_DBC->GetOne($sql); @@ -595,18 +618,20 @@ class ShowInstance { if($rebroadcast) { $sql = "SELECT timestamp '{$new_starts}' < (SELECT starts FROM cc_show_instances WHERE id = {$rebroadcast})"; $isBeforeRecordedOriginal = $CC_DBC->GetOne($sql); - + if($isBeforeRecordedOriginal === 't'){ return "Cannot move a rebroadcast show before its original"; } } - + $this->moveScheduledShowContent($deltaDay, $hours, $mins); $this->setShowStart($new_starts); - $this->setShowEnd($new_ends); + $this->setShowEnd($new_ends); + RabbitMq::PushSchedule(); } - public function resizeShow($deltaDay, $deltaMin){ + public function resizeShow($deltaDay, $deltaMin) + { global $CC_DBC; $hours = $deltaMin/60; @@ -618,7 +643,7 @@ class ShowInstance { $mins = abs($deltaMin%60); $starts = $this->getShowStart(); - $ends = $this->getShowEnd(); + $ends = $this->getShowEnd(); $sql = "SELECT timestamp '{$ends}' + interval '{$deltaDay} days' + interval '{$hours}:{$mins}'"; $new_ends = $CC_DBC->GetOne($sql); @@ -639,106 +664,109 @@ class ShowInstance { WHERE rebroadcast = 1 AND instance_id = {$this->_instanceId}"; $CC_DBC->query($sql); } - + $this->setShowEnd($new_ends); + RabbitMq::PushSchedule(); } - private function getLastGroupId() { + private function getLastGroupId() + { global $CC_DBC; - $sql = "SELECT group_id FROM cc_schedule WHERE instance_id = '{$this->_instanceId}' ORDER BY ends DESC LIMIT 1"; - $res = $CC_DBC->GetOne($sql); - + $res = $CC_DBC->GetOne($sql); return $res; } - public function addPlaylistToShow($plId) { - + public function addPlaylistToShow($plId) + { $sched = new ScheduleGroup(); $lastGroupId = $this->getLastGroupId(); - + if(is_null($lastGroupId)) { - $groupId = $sched->add($this->_instanceId, $this->getShowStart(), null, $plId); + $groupId = $sched->add($this->_instanceId, $this->getShowStart(), null, $plId); } else { $groupId = $sched->addPlaylistAfter($this->_instanceId, $lastGroupId, $plId); } + RabbitMq::PushSchedule(); } - public function scheduleShow($plIds) { - + public function scheduleShow($plIds) + { foreach($plIds as $plId) { $this->addPlaylistToShow($plId); } + RabbitMq::PushSchedule(); } - public function removeGroupFromShow($group_id){ + public function removeGroupFromShow($group_id) + { global $CC_DBC; $sql = "SELECT MAX(ends) as end_timestamp, (MAX(ends) - MIN(starts)) as length - FROM cc_schedule + FROM cc_schedule WHERE group_id = '{$group_id}'"; - + $groupBoundry = $CC_DBC->GetRow($sql); $group = CcScheduleQuery::create() ->filterByDbGroupId($group_id) ->delete(); - $sql = "UPDATE cc_schedule - SET starts = (starts - INTERVAL '{$groupBoundry["length"]}'), ends = (ends - INTERVAL '{$groupBoundry["length"]}') + $sql = "UPDATE cc_schedule + SET starts = (starts - INTERVAL '{$groupBoundry["length"]}'), ends = (ends - INTERVAL '{$groupBoundry["length"]}') WHERE starts >= '{$groupBoundry["end_timestamp"]}' AND instance_id = {$this->_instanceId}"; $CC_DBC->query($sql); + RabbitMq::PushSchedule(); } - public function clearShow() { - + public function clearShow() + { CcScheduleQuery::create() ->filterByDbInstanceId($this->_instanceId) ->delete(); + RabbitMq::PushSchedule(); } - public function deleteShow() { - + public function deleteShow() + { CcShowInstancesQuery::create() ->findPK($this->_instanceId) ->delete(); + RabbitMq::PushSchedule(); } - public function getTimeScheduled() { - + public function getTimeScheduled() + { $instance_id = $this->getShowInstanceId(); $time = Schedule::GetTotalShowTime($instance_id); - return $time; } - public function getTimeUnScheduled() { - - $start_timestamp = $this->getShowStart(); + public function getTimeUnScheduled() + { + $start_timestamp = $this->getShowStart(); $end_timestamp = $this->getShowEnd(); $instance_id = $this->getShowInstanceId(); - $time = Schedule::getTimeUnScheduledInRange($instance_id, $start_timestamp, $end_timestamp); - return $time; } - public function getPercentScheduled() { - - $start_timestamp = $this->getShowStart(); + public function getPercentScheduled() + { + $start_timestamp = $this->getShowStart(); $end_timestamp = $this->getShowEnd(); $instance_id = $this->getShowInstanceId(); - return Schedule::GetPercentScheduled($instance_id, $start_timestamp, $end_timestamp); } - public function getShowLength() { + public function getShowLength() + { global $CC_DBC; - $start_timestamp = $this->getShowStart(); + $start_timestamp = $this->getShowStart(); $end_timestamp = $this->getShowEnd(); $sql = "SELECT TIMESTAMP '{$end_timestamp}' - TIMESTAMP '{$start_timestamp}' "; @@ -747,26 +775,27 @@ class ShowInstance { return $length; } - public function searchPlaylistsForShow($datatables){ - + public function searchPlaylistsForShow($datatables) + { $time_remaining = $this->getTimeUnScheduled(); - return StoredFile::searchPlaylistsForSchedule($time_remaining, $datatables); } - public function getShowListContent() { + public function getShowListContent() + { global $CC_DBC; - $sql = "SELECT * + $sql = "SELECT * FROM (cc_schedule AS s LEFT JOIN cc_files AS f ON f.id = s.file_id LEFT JOIN cc_playlist AS p ON p.id = s.playlist_id ) WHERE s.instance_id = '{$this->_instanceId}' ORDER BY starts"; - return $CC_DBC->GetAll($sql); + return $CC_DBC->GetAll($sql); } - public function getShowContent() { + public function getShowContent() + { global $CC_DBC; $res = $this->getShowListContent(); @@ -788,7 +817,7 @@ class ShowInstance { $items[$pl_counter]["pl_name"] = $row["name"]; $items[$pl_counter]["pl_creator"] = $row["creator"]; $items[$pl_counter]["pl_description"] = $row["description"]; - $items[$pl_counter]["pl_group"] = $row["group_id"]; + $items[$pl_counter]["pl_group"] = $row["group_id"]; $sql = "SELECT SUM(clip_length) FROM cc_schedule WHERE group_id = '{$currGroupId}'"; $length = $CC_DBC->GetOne($sql); @@ -802,33 +831,35 @@ class ShowInstance { $items[$pl_counter]["pl_content"][$f_counter]["f_length"] = $row["length"]; } - return $items; + return $items; } } /* Show Data Access Layer */ -class Show_DAL{ - - public static function GetCurrentShow($timeNow) { +class Show_DAL { + + public static function GetCurrentShow($timeNow) + { global $CC_CONFIG, $CC_DBC; - + $timestamp = explode(" ", $timeNow); $date = $timestamp[0]; $time = $timestamp[1]; - + $sql = "SELECT si.starts as start_timestamp, si.ends as end_timestamp, s.name, s.id, si.id as instance_id, si.record" ." FROM $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s" ." WHERE si.show_id = s.id" ." AND si.starts <= TIMESTAMP '$timeNow'" ." AND si.ends > TIMESTAMP '$timeNow'"; - + $rows = $CC_DBC->GetAll($sql); return $rows; } - - public static function GetNextShow($timeNow) { + + public static function GetNextShow($timeNow) + { global $CC_CONFIG, $CC_DBC; - + $sql = "SELECT *, si.starts as start_timestamp, si.ends as end_timestamp FROM " ." $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s" ." WHERE si.show_id = s.id" @@ -836,12 +867,13 @@ class Show_DAL{ ." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'" ." ORDER BY si.starts" ." LIMIT 1"; - + $rows = $CC_DBC->GetAll($sql); return $rows; } - public static function GetShowsInRange($timeNow, $start, $end){ + public static function GetShowsInRange($timeNow, $start, $end) + { global $CC_CONFIG, $CC_DBC; $sql = "SELECT" ." si.starts as show_starts," @@ -873,5 +905,5 @@ class Show_DAL{ return $CC_DBC->GetAll($sql); } - + } diff --git a/pypo/api_clients/api_client_factory.py b/pypo/api_clients/api_client_factory.py deleted file mode 100644 index 4762b0fc7..000000000 --- a/pypo/api_clients/api_client_factory.py +++ /dev/null @@ -1,9 +0,0 @@ -import airtime_api_client -import obp_api_client - -def create_api_client(config): - if config["api_client"] == "airtime": - return campcaster_api_client.AirtimeApiClient(config) - elif config["api_client"] == "obp": - return obp_api_client.ObpApiClient(config) - From 3e27a3de01e56ff946f8ef88e619733155cf7673 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Tue, 22 Mar 2011 11:42:09 -0400 Subject: [PATCH 15/74] CC-2079: Airtime 1.7 stops playing after a certain amount of time CC-2080: Turn pypo-fetch and pypo-push into threads of the same process Fixed bug where it wasnt possible to exit the program with Control-C. --- pypo/pypo-cli.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pypo/pypo-cli.py b/pypo/pypo-cli.py index ca630f618..208049d7b 100755 --- a/pypo/pypo-cli.py +++ b/pypo/pypo-cli.py @@ -7,14 +7,13 @@ Python part of radio playout (pypo) The main functions are "fetch" (./pypo_cli.py -f) and "push" (./pypo_cli.py -p) """ -# python defaults (debian default) import time #import calendar - - #import traceback from optparse import * import sys +import os +import signal #import datetime import logging import logging.config @@ -32,7 +31,6 @@ from Queue import Queue from pypopush import PypoPush from pypofetch import PypoFetch -# additional modules (should be checked) from configobj import ConfigObj # custom imports @@ -54,7 +52,6 @@ parser.add_option("-v", "--compat", help="Check compatibility with server API ve parser.add_option("-t", "--test", help="Do a test to make sure everything is working properly.", default=False, action="store_true", dest="test") parser.add_option("-f", "--fetch-scheduler", help="Fetch the schedule from server. This is a polling process that runs forever.", default=False, action="store_true", dest="fetch_scheduler") parser.add_option("-p", "--push-scheduler", help="Push the schedule to Liquidsoap. This is a polling process that runs forever.", default=False, action="store_true", dest="push_scheduler") - parser.add_option("-b", "--cleanup", help="Cleanup", default=False, action="store_true", dest="cleanup") parser.add_option("-c", "--check", help="Check the cached schedule and exit", default=False, action="store_true", dest="check") @@ -118,15 +115,19 @@ class Global: for media in playlist['medias']: print media +def keyboardInterruptHandler(signum, frame): + print "\nKeyboard Interrupt\n" + sys.exit(); if __name__ == '__main__': print '###########################################' print '# *** pypo *** #' - print '# Liquidsoap + External Scheduler #' - print '# Playout System #' + print '# Liquidsoap Scheduled Playout System #' print '###########################################' + signal.signal(signal.SIGINT, keyboardInterruptHandler) + # initialize g = Global() g.selfcheck() @@ -140,14 +141,17 @@ if __name__ == '__main__': q = Queue() pp = PypoPush(q) + pp.daemon = True pp.start() pf = PypoFetch(q) + pf.daemon = True pf.start() - pp.join() - pf.join() + while True: time.sleep(3600) + #pp.join() + #pf.join() """ if options.check: try: g.check_schedule() From fae71ed051907b9ce4919777fb3757ac8d558fd4 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Tue, 22 Mar 2011 12:08:09 -0400 Subject: [PATCH 16/74] CC-1985 : Automatic rebroadcast of recorded content scheduling the recorded file in any rebroadcast shows. --- application/models/Schedule.php | 59 +++---------------- application/models/Shows.php | 30 +++++++++- .../models/airtime/map/CcScheduleTableMap.php | 2 +- build/schema.xml | 2 +- build/sql/schema.sql | 2 +- 5 files changed, 39 insertions(+), 56 deletions(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 5fe66f2ca..647b8b95e 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -24,41 +24,6 @@ class ScheduleGroup { return $result != "0"; } - /** - * Convert a date to an ID by stripping out all characters - * and padding with zeros. - * - * @param string $p_dateStr - */ - public static function dateToId($p_dateStr) { - $p_dateStr = str_replace(":", "", $p_dateStr); - $p_dateStr = str_replace(" ", "", $p_dateStr); - $p_dateStr = str_replace(".", "", $p_dateStr); - $p_dateStr = str_replace("-", "", $p_dateStr); - $p_dateStr = substr($p_dateStr, 0, 17); - $p_dateStr = str_pad($p_dateStr, 17, "0"); - return $p_dateStr; - } - - /** - * Add the two times together, return the result. - * - * @param string $p_baseTime - * Specified as YYYY-MM-DD HH:MM:SS - * - * @param string $p_addTime - * Specified as HH:MM:SS.nnnnnn - * - * @return string - * The end time, to the nearest second. - */ - // protected function calculateEndTime($p_startTime, $p_trackTime) { - // $p_trackTime = substr($p_startTime, 0, ); - // $start = new DateTime(); - // $interval = new DateInterval() - // - // } - /** * Add a music clip or playlist to the schedule. * @@ -77,6 +42,7 @@ class ScheduleGroup { */ public function add($show_instance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) { global $CC_CONFIG, $CC_DBC; + if (!is_null($p_audioFileId)) { // Schedule a single audio track @@ -92,19 +58,16 @@ class ScheduleGroup { if (empty($length)) { return new PEAR_Error("Length is empty."); } - if (!Schedule::isScheduleEmptyInRange($p_datetime, $length)) { - return new PEAR_Error("Schedule conflict.", 555); - } - + // Insert into the table $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); + $sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"] - ." (playlist_id, starts, ends, clip_length, group_id, file_id)" - ." VALUES (0, TIMESTAMP '$p_datetime', " + ." (instance_id, starts, ends, clip_length, group_id, file_id, cue_out)" + ." VALUES ($show_instance, TIMESTAMP '$p_datetime', " ." (TIMESTAMP '$p_datetime' + INTERVAL '$length')," ." '$length'," - ." {$this->groupId}, $p_audioFileId)"; + ." {$this->groupId}, $p_audioFileId, '$length')"; $result = $CC_DBC->query($sql); if (PEAR::isError($result)) { //var_dump($sql); @@ -112,7 +75,8 @@ class ScheduleGroup { } return $this->groupId; - } elseif (!is_null($p_playlistId)){ + } + elseif (!is_null($p_playlistId)){ // Schedule a whole playlist // Load existing playlist @@ -130,7 +94,6 @@ class ScheduleGroup { // Insert all items into the schedule $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); $itemStartTime = $p_datetime; $plItems = $playlist->getContents(); @@ -157,7 +120,7 @@ class ScheduleGroup { } } - public function addAfter($show_instance, $p_groupId, $p_audioFileId) { + public function addFileAfter($show_instance, $p_groupId, $p_audioFileId) { global $CC_CONFIG, $CC_DBC; // Get the end time for the given entry $sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"] @@ -176,10 +139,6 @@ class ScheduleGroup { return $this->add($show_instance, $startTime, null, $p_playlistId); } - public function update() { - - } - /** * Remove the group from the schedule. * Note: does not check if it is in the past, you can remove anything. diff --git a/application/models/Shows.php b/application/models/Shows.php index 57ba0fb45..6dc28dcf7 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -652,8 +652,8 @@ class ShowInstance { return $res; } - public function addPlaylistToShow($plId) { - + public function addPlaylistToShow($plId) + { $sched = new ScheduleGroup(); $lastGroupId = $this->getLastGroupId(); @@ -666,6 +666,20 @@ class ShowInstance { } } + public function addFileToShow($file_id) + { + $sched = new ScheduleGroup(); + $lastGroupId = $this->getLastGroupId(); + + if(is_null($lastGroupId)) { + + $groupId = $sched->add($this->_instanceId, $this->getShowStart(), $file_id); + } + else { + $groupId = $sched->addFileAfter($this->_instanceId, $lastGroupId, $file_id); + } + } + public function scheduleShow($plIds) { foreach($plIds as $plId) { @@ -712,7 +726,17 @@ class ShowInstance { $showInstance = CcShowInstancesQuery::create() ->findPK($this->_instanceId); $showInstance->setDbRecordedFile($file_id) - ->save(); + ->save(); + + $rebroadcasts = CcShowInstancesQuery::create() + ->filterByDbOriginalShow($this->_instanceId) + ->find(); + + foreach ($rebroadcasts as $rebroadcast) { + + $rebroad = new ShowInstance($rebroadcast->getDbId()); + $rebroad->addFileToShow($file_id); + } } public function getTimeScheduled() { diff --git a/application/models/airtime/map/CcScheduleTableMap.php b/application/models/airtime/map/CcScheduleTableMap.php index 3f2502f1c..92afaab0c 100644 --- a/application/models/airtime/map/CcScheduleTableMap.php +++ b/application/models/airtime/map/CcScheduleTableMap.php @@ -39,7 +39,7 @@ class CcScheduleTableMap extends TableMap { $this->setPrimaryKeyMethodInfo('cc_schedule_id_seq'); // columns $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); - $this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', true, null, null); + $this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', false, null, null); $this->addColumn('STARTS', 'DbStarts', 'TIMESTAMP', true, null, null); $this->addColumn('ENDS', 'DbEnds', 'TIMESTAMP', true, null, null); $this->addColumn('GROUP_ID', 'DbGroupId', 'INTEGER', false, null, null); diff --git a/build/schema.xml b/build/schema.xml index 36941da37..f00ad14fb 100644 --- a/build/schema.xml +++ b/build/schema.xml @@ -234,7 +234,7 @@ - + diff --git a/build/sql/schema.sql b/build/sql/schema.sql index ee2f9b109..71ff970ef 100644 --- a/build/sql/schema.sql +++ b/build/sql/schema.sql @@ -345,7 +345,7 @@ DROP TABLE "cc_schedule" CASCADE; CREATE TABLE "cc_schedule" ( "id" serial NOT NULL, - "playlist_id" INTEGER NOT NULL, + "playlist_id" INTEGER, "starts" TIMESTAMP NOT NULL, "ends" TIMESTAMP NOT NULL, "group_id" INTEGER, From 582c05a192a0ea8680f82ee01029a3f8ab8a5a43 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 22 Mar 2011 13:39:01 -0400 Subject: [PATCH 17/74] CC-2077: Show is marked as Recording, when it's not set to record -Fixed --- public/js/playlist/playlist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/playlist/playlist.js b/public/js/playlist/playlist.js index 82f277d1c..98b227381 100644 --- a/public/js/playlist/playlist.js +++ b/public/js/playlist/playlist.js @@ -169,7 +169,7 @@ function updatePlaybar(){ $('#playlist').text(currentShow[0].name); var recElem = $('.recording-show'); - currentShow[0].record ? recElem.show(): recElem.hide(); + (currentShow[0].record == "1") ? recElem.show(): recElem.hide(); } $('#show-length').empty(); From e92be3c186ca586626f790c729bcdd4dae3dda4b Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 22 Mar 2011 18:04:27 -0400 Subject: [PATCH 18/74] CC-1990: Widget to display schedule and "Now Playing" on any website -First working version, needs to be called using: --- application/controllers/ApiController.php | 10 + application/models/Schedule.php | 2 +- application/models/Shows.php | 4 +- plugins/jquery.showinfo.js | 213 ++++++++++++++-------- 4 files changed, 146 insertions(+), 83 deletions(-) diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index b4dd0d3a2..f7ff37eb1 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -109,6 +109,16 @@ class ApiController extends Zend_Controller_Action $this->_helper->viewRenderer->setNoRender(true); $result = Schedule::GetPlayOrderRange(0, 1); + + $date = new Application_Model_DateHelper; + $timeNow = $date->getDate(); + $result = array("env"=>APPLICATION_ENV, + "schedulerTime"=>gmdate("Y-m-d H:i:s"), + "currentShow"=>Show_DAL::GetCurrentShow($timeNow), + "nextShow"=>Show_DAL::GetNextShows($timeNow, 5), + "timezone"=> date("T"), + "timezoneOffset"=> date("Z")); + //echo json_encode($result); header("Content-type: text/javascript"); echo $_GET['callback'].'('.json_encode($result).')'; diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 6113eae2e..7435bf407 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -436,7 +436,7 @@ class Schedule { "current"=>Schedule::GetScheduledItemData($timeNow, 0), "next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"), "currentShow"=>Show_DAL::GetCurrentShow($timeNow), - "nextShow"=>Show_DAL::GetNextShow($timeNow), + "nextShow"=>Show_DAL::GetNextShows($timeNow, 1), "timezone"=> date("T"), "timezoneOffset"=> date("Z"), "apiKey"=>$CC_CONFIG['apiKey'][0]); diff --git a/application/models/Shows.php b/application/models/Shows.php index ea2cf5401..f0a7a20bc 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -889,7 +889,7 @@ class Show_DAL { return $rows; } - public static function GetNextShow($timeNow) + public static function GetNextShows($timeNow, $limit) { global $CC_CONFIG, $CC_DBC; @@ -899,7 +899,7 @@ class Show_DAL { ." AND si.starts >= TIMESTAMP '$timeNow'" ." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'" ." ORDER BY si.starts" - ." LIMIT 1"; + ." LIMIT $limit"; $rows = $CC_DBC->GetAll($sql); return $rows; diff --git a/plugins/jquery.showinfo.js b/plugins/jquery.showinfo.js index da5be1af8..c31381a10 100644 --- a/plugins/jquery.showinfo.js +++ b/plugins/jquery.showinfo.js @@ -2,25 +2,64 @@ $.fn.airtimeShowSchedule = function(options) { var defaults = { - updatePeriod: 5, //seconds + updatePeriod: 20, //seconds + sourceDomain: "http://localhost/", //where to get show status from }; var options = $.extend(defaults, options); return this.each(function() { var obj = $(this); + var sd; - obj.append("

On air today

"); - obj.append( - "
"+ - "" + - "" + - "" + - ""+ - ""+ - ""+ - ""+ - ""+ - "
13:15 - 13:30Program name Listen
13:15 - 13:30Lorem ipsum dolor
"); + getServerData(); + + function updateWidget(){ + var currentShow = sd.getCurrentShow(); + var nextShows = sd.getNextShows(); + + var currentShowName = ""; + var nextShowName = "" + + if (currentShow.length > 0){ + currentShowName = currentShow[0].getName(); + } + + if (nextShows.length > 0){ + nextShowName = nextShows[0].getName(); + } + + tableString = ""; + tableString += "

On air today

"; + tableString += ""+ + ""; + + var shows=currentShow.concat(nextShows); + + obj.empty(); + for (var i=0; i" + + "" + + "" + + ""; + } + + tableString += "
"+shows[i].getRange()+""+shows[i].getName()+" Listen
"; + + obj.append(tableString); + } + + function processData(data){ + sd = new ScheduleData(data); + updateWidget(); + } + + function getServerData(){ + $.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){ + processData(data); + }, error:function(jqXHR, textStatus, errorThrown){}}); + setTimeout(getServerData, defaults.updatePeriod*1000); + } }); }; })(jQuery); @@ -42,24 +81,42 @@ getServerData(); function updateWidget(){ - var currentShow = sd.getCurrentShowName(); - var timeRemaining = sd.getCurrentShowTimeRemaining(); - var timeElapsed = sd.getCurrentShowTimeElapsed(); - var showStatus = sd.getCurrentShowStatus(); + var currentShow = sd.getCurrentShow(); + var nextShows = sd.getNextShows(); - var nextShow = sd.getNextShowName(); - var nextShowRange = sd.getNextShowRange(); + var showStatus = "Offline"; + var currentShowName = ""; + var timeElapsed = ""; + var timeRemaining = ""; + + var nextShowName = ""; + var nextShowRange = ""; + + if (currentShow.length > 0){ + showStatus = "On Air Now"; + currentShowName = currentShow[0].getName(); + + timeElapsed = sd.getShowTimeElapsed(currentShow[0]); + timeRemaining = sd.getShowTimeRemaining(currentShow[0]); + } + + if (nextShows.length > 0){ + nextShowName = nextShows[0].getName(); + nextShowRange = nextShows[0].getRange(); + } obj.empty(); obj.append("Listen WADR Live"); obj.append("

"+showStatus+" >>

"); obj.append("
    " + - "
  • "+currentShow+ ""+timeElapsed+"" + - ""+timeRemaining+"
  • " + - "" + + "
  • Current: "+currentShowName+ + ""+timeElapsed+"" + + ""+timeRemaining+""+ + "
  • " + + "" + "
"); - //refresh the UI + //refresh the UI to update the elapsed/remaining time setTimeout(updateWidget, 1000); } @@ -78,12 +135,23 @@ }; })(jQuery); -/* The rest of this file is the ScheduleData class */ +/* ScheduleData class BEGIN */ function ScheduleData(data){ this.data = data; this.estimatedSchedulePosixTime; - this.schedulePosixTime = this.convertDateToPosixTime(data.schedulerTime); + this.currentShow = new Array(); + for (var i=0; i< data.currentShow.length; i++){ + this.currentShow[i] = new Show(data.currentShow[i]); + } + + this.nextShows = new Array(); + for (var i=0; i< data.nextShow.length; i++){ + this.nextShows[i] = new Show(data.nextShow[i]); + } + + + this.schedulePosixTime = convertDateToPosixTime(data.schedulerTime); this.schedulePosixTime += parseInt(data.timezoneOffset)*1000; var date = new Date(); this.localRemoteTimeOffset = date.getTime() - this.schedulePosixTime; @@ -95,72 +163,57 @@ ScheduleData.prototype.secondsTimer = function(){ this.estimatedSchedulePosixTime = date.getTime() - this.localRemoteTimeOffset; } -ScheduleData.prototype.getCurrentShowName = function() { - var currentShow = this.data.currentShow; - if (currentShow.length > 0){ - return "Current: " + currentShow[0].name; - } else { - return ""; - } -}; +ScheduleData.prototype.getCurrentShow = function(){ + return this.currentShow; +} -ScheduleData.prototype.getCurrentShowStatus = function() { - var currentShow = this.data.currentShow; - if (currentShow.length > 0){ - return "On Air Now"; - } else { - return "Offline"; - } -}; +ScheduleData.prototype.getNextShows = function() { + return this.nextShows; +} -ScheduleData.prototype.getNextShowName = function() { - var nextShow = this.data.nextShow; - if (nextShow.length > 0){ - return "Next: " + nextShow[0].name; - } else { - return ""; - } -}; - -ScheduleData.prototype.getNextShowRange = function() { - var nextShow = this.data.nextShow; - if (nextShow.length > 0){ - return this.getTime(nextShow[0].start_timestamp) + " - " + this.getTime(nextShow[0].end_timestamp); - } else { - return ""; - } -}; - -ScheduleData.prototype.getCurrentShowTimeElapsed = function() { +ScheduleData.prototype.getShowTimeElapsed = function(show) { this.secondsTimer(); - var currentShow = this.data.currentShow; - if (currentShow.length > 0){ - var showStart = this.convertDateToPosixTime(currentShow[0].start_timestamp); - return this.convertToHHMMSS(this.estimatedSchedulePosixTime - showStart); - } else { - return ""; - } + + var showStart = convertDateToPosixTime(show.getStartTimestamp()); + return convertToHHMMSS(this.estimatedSchedulePosixTime - showStart); }; -ScheduleData.prototype.getCurrentShowTimeRemaining = function() { +ScheduleData.prototype.getShowTimeRemaining = function(show) { this.secondsTimer(); - var currentShow = this.data.currentShow; - if (currentShow.length > 0){ - var showEnd = this.convertDateToPosixTime(currentShow[0].end_timestamp); - return this.convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime); - } else { - return ""; - } -}; -ScheduleData.prototype.getTime = function(timestamp) { - return timestamp.split(" ")[1]; + var showEnd = convertDateToPosixTime(show.getEndTimestamp()); + return convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime); }; +/* ScheduleData class END */ +/* Show class BEGIN */ +function Show(showData){ + this.showData = showData; +} + +Show.prototype.getName = function(){ + return this.showData.name; +} +Show.prototype.getRange = function(){ + return getTime(this.showData.start_timestamp) + " - " + getTime(this.showData.end_timestamp); +} +Show.prototype.getStartTimestamp = function(){ + return this.showData.start_timestamp; +} +Show.prototype.getEndTimestamp = function(){ + return this.showData.end_timestamp; +} +/* Show class END */ + + +function getTime(timestamp) { + var time = timestamp.split(" ")[1].split(":"); + return time[0] + ":" + time[1]; +}; /* Takes an input parameter of milliseconds and converts these into * the format HH:MM:SS */ -ScheduleData.prototype.convertToHHMMSS = function(timeInMS){ +function convertToHHMMSS(timeInMS){ var time = parseInt(timeInMS); var hours = parseInt(time / 3600000); @@ -189,7 +242,7 @@ ScheduleData.prototype.convertToHHMMSS = function(timeInMS){ /* Takes in a string of format similar to 2011-02-07 02:59:57, * and converts this to epoch/posix time. */ -ScheduleData.prototype.convertDateToPosixTime = function(s){ +function convertDateToPosixTime(s){ var datetime = s.split(" "); var date = datetime[0].split("-"); From 8ffcd75682c89f723355160141a484608235c9af Mon Sep 17 00:00:00 2001 From: naomiaro Date: Tue, 22 Mar 2011 18:07:00 -0400 Subject: [PATCH 19/74] bug, forgot to delete useless line --- application/models/Schedule.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 6113eae2e..0034488d5 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -113,7 +113,6 @@ class ScheduleGroup { return $result; } $itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'"); - $id = $this->dateToId($itemStartTime); } } RabbitMq::PushSchedule(); From f59225424665b0b6f912b3a0f3d099daf5bacefa Mon Sep 17 00:00:00 2001 From: naomiaro Date: Tue, 22 Mar 2011 18:20:22 -0400 Subject: [PATCH 20/74] CC-1630 : Automatic recording of shows scripts to install recorder using daemon tools. haven't tested without pulse audio yet. --- install/airtime-install.php | 3 + install/airtime-uninstall.php | 3 + pypo/install/pypo-install.py | 2 + python_apps/show-recorder/config.cfg | 2 +- .../install/recorder-daemontools-logger.sh | 2 + .../install/recorder-daemontools.sh | 14 ++ .../show-recorder/install/recorder-install.py | 128 ++++++++++++++++++ .../show-recorder/install/recorder-start.py | 16 +++ .../show-recorder/install/recorder-stop.py | 25 ++++ .../install/recorder-uninstall.py | 46 +++++++ python_apps/show-recorder/testsoundcloud.py | 59 -------- 11 files changed, 240 insertions(+), 60 deletions(-) create mode 100644 python_apps/show-recorder/install/recorder-daemontools-logger.sh create mode 100644 python_apps/show-recorder/install/recorder-daemontools.sh create mode 100644 python_apps/show-recorder/install/recorder-install.py create mode 100644 python_apps/show-recorder/install/recorder-start.py create mode 100644 python_apps/show-recorder/install/recorder-stop.py create mode 100644 python_apps/show-recorder/install/recorder-uninstall.py delete mode 100644 python_apps/show-recorder/testsoundcloud.py diff --git a/install/airtime-install.php b/install/airtime-install.php index 55d5ba068..ffcdea662 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -55,6 +55,9 @@ AirtimeInstall::SetUpPythonEggs(); echo PHP_EOL."*** Pypo Installation ***".PHP_EOL; system("python ".__DIR__."/../pypo/install/pypo-install.py"); +echo PHP_EOL."*** Recorder Installation ***".PHP_EOL; +system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install.py"); + echo "******************************* Install Complete *******************************".PHP_EOL; diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index 181006efd..d175856d5 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -83,5 +83,8 @@ AirtimeInstall::DeleteFilesRecursive($CC_CONFIG['storageDir']); $command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py"; system($command); + +$command = "python ".__DIR__."/../python_apps/show-recorder/install/recorder-uninstall.py"; +system($command); echo "****************************** Uninstall Complete ******************************".PHP_EOL; diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index 07cb43cd9..cff58175e 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -44,6 +44,8 @@ def create_user(username): print "User already exists." #add pypo to audio group os.system("adduser " + username + " audio 1>/dev/null 2>&1") + #add pypo to pulse-access group + os.system("adduser " + username + " pulse-access 1>/dev/null 2>&1") def copy_dir(src_dir, dest_dir): if (os.path.exists(dest_dir)) and (dest_dir != "/"): diff --git a/python_apps/show-recorder/config.cfg b/python_apps/show-recorder/config.cfg index f75ea204c..d1bb763ab 100644 --- a/python_apps/show-recorder/config.cfg +++ b/python_apps/show-recorder/config.cfg @@ -6,4 +6,4 @@ show_schedule_url = 'Recorder/get-show-schedule/format/json' upload_file_url = 'Plupload/upload-recorded/format/json' # base path to store recordered shows at -base_recorded_files = '/home/naomi/Music/' +base_recorded_files = '/home/pypo/Music/' diff --git a/python_apps/show-recorder/install/recorder-daemontools-logger.sh b/python_apps/show-recorder/install/recorder-daemontools-logger.sh new file mode 100644 index 000000000..9673575db --- /dev/null +++ b/python_apps/show-recorder/install/recorder-daemontools-logger.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec setuidgid pypo multilog t ./main diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh new file mode 100644 index 000000000..c36996b40 --- /dev/null +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -0,0 +1,14 @@ +#!/bin/sh +recorder_user="pypo" +export HOME="/home/pypo/" +# Location of pypo_cli.py Python script +recorder_path="/opt/recorder/bin/" +recorder_script="testrecordscript.py" +echo "*** Daemontools: starting daemon" +cd ${recorder_path} +exec 2>&1 +# Note the -u when calling python! we need it to get unbuffered binary stdout and stderr +exec setuidgid ${recorder_user} \ + python -u ${recorder_path}${recorder_script} \ + -f +# EOF diff --git a/python_apps/show-recorder/install/recorder-install.py b/python_apps/show-recorder/install/recorder-install.py new file mode 100644 index 000000000..1b8186391 --- /dev/null +++ b/python_apps/show-recorder/install/recorder-install.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import time +import os +import traceback +from optparse import * +import sys +import time +import datetime +import logging +import logging.config +import shutil +import string +import platform +from subprocess import Popen, PIPE, STDOUT + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +BASE_PATH = '/opt/recorder/' + +def create_path(path): + if not (os.path.exists(path)): + print "Creating directory " + path + os.makedirs(path) + +def create_user(username): + print "Checking for user "+username + p = Popen('id '+username, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + if (output[0:3] != "uid"): + # Make the pypo user + print "Creating user "+username + os.system("adduser --system --quiet --group --shell /bin/bash "+username) + + #set pypo password + p = os.popen('/usr/bin/passwd pypo 1>/dev/null 2>&1', 'w') + p.write('pypo\n') + p.write('pypo\n') + p.close() + else: + print "User already exists." + #add pypo to audio group + os.system("adduser " + username + " audio 1>/dev/null 2>&1") + +def copy_dir(src_dir, dest_dir): + if (os.path.exists(dest_dir)) and (dest_dir != "/"): + print "Removing old directory "+dest_dir + shutil.rmtree(dest_dir) + if not (os.path.exists(dest_dir)): + print "Copying directory "+src_dir+" to "+dest_dir + shutil.copytree(src_dir, dest_dir) + +def get_current_script_dir(): + current_script_dir = os.path.realpath(__file__) + index = current_script_dir.rindex('/') + print current_script_dir[0:index] + return current_script_dir[0:index] + + +try: + current_script_dir = get_current_script_dir() + print "Checking and removing any existing recorder processes" + os.system("python %s/recorder-uninstall.py 1>/dev/null 2>&1"% current_script_dir) + time.sleep(5) + + # Create users + create_user("pypo") + + print "Creating home directory" + create_path("/home/pypo") + os.system("chmod -R 755 /home/pypo") + os.system("chown -R pypo:pypo /home/pypo") + + print "Creating home directory" + create_path("/home/pypo/Music") + os.system("chmod -R 755 /home/pypo/Music") + os.system("chown -R pypo:pypo /home/pypo/Music") + + print "Creating log directories" + create_path("/var/log/recorder") + os.system("chmod -R 755 /var/log/recorder") + os.system("chown -R pypo:pypo /var/log/recorder") + + create_path(BASE_PATH) + create_path(BASE_PATH+"bin") + create_path(BASE_PATH+"cache") + create_path(BASE_PATH+"files") + create_path(BASE_PATH+"tmp") + create_path(BASE_PATH+"archive") + + copy_dir("%s/.."%current_script_dir, BASE_PATH+"bin/") + + print "Setting permissions" + os.system("chmod -R 755 "+BASE_PATH) + os.system("chown -R pypo:pypo "+BASE_PATH) + + print "Installing recorder daemon" + create_path("/etc/service/recorder") + create_path("/etc/service/recorder/log") + shutil.copy("%s/recorder-daemontools.sh"%current_script_dir, "/etc/service/recorder/run") + shutil.copy("%s/recorder-daemontools-logger.sh"%current_script_dir, "/etc/service/recorder/log/run") + os.system("chmod -R 755 /etc/service/recorder") + os.system("chown -R pypo:pypo /etc/service/recorder") + + print "Waiting for processes to start..." + time.sleep(5) + os.system("python %s/recorder-start.py" % (get_current_script_dir())) + time.sleep(2) + + found = True + + p = Popen('svstat /etc/service/recorder', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + if (output.find("unable to open supervise/ok: file does not exist") >= 0): + found = False + print output + + if not found: + print "Recorder install has completed, but daemontools is not running, please make sure you have it installed and then reboot." +except Exception, e: + print "exception:" + str(e) + sys.exit(1) + + + diff --git a/python_apps/show-recorder/install/recorder-start.py b/python_apps/show-recorder/install/recorder-start.py new file mode 100644 index 000000000..084b2b1ad --- /dev/null +++ b/python_apps/show-recorder/install/recorder-start.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +try: + print "Starting daemontool script recorder" + os.system("svc -u /etc/service/recorder") + +except Exception, e: + print "exception:" + str(e) diff --git a/python_apps/show-recorder/install/recorder-stop.py b/python_apps/show-recorder/install/recorder-stop.py new file mode 100644 index 000000000..388c0bc4b --- /dev/null +++ b/python_apps/show-recorder/install/recorder-stop.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +try: + print "Stopping daemontool script pypo" + os.system("svc -dx /etc/service/pypo 1>/dev/null 2>&1") + + if os.path.exists("/etc/service/pypo-fetch"): + os.system("svc -dx /etc/service/pypo-fetch 1>/dev/null 2>&1") + if os.path.exists("/etc/service/pypo-push"): + os.system("svc -dx /etc/service/pypo-push 1>/dev/null 2>&1") + + print "Stopping daemontool script pypo-liquidsoap" + os.system("svc -dx /etc/service/pypo-liquidsoap 1>/dev/null 2>&1") + os.system("killall liquidsoap") + +except Exception, e: + print "exception:" + str(e) diff --git a/python_apps/show-recorder/install/recorder-uninstall.py b/python_apps/show-recorder/install/recorder-uninstall.py new file mode 100644 index 000000000..f8ab96432 --- /dev/null +++ b/python_apps/show-recorder/install/recorder-uninstall.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +import time + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +BASE_PATH = '/opt/recorder/' + +def remove_path(path): + os.system("rm -rf " + path) + +def remove_user(username): + os.system("killall -u %s 1>/dev/null 2>&1" % username) + + #allow all process to be completely closed before we attempt to delete user + print "Waiting for processes to close..." + time.sleep(5) + + os.system("deluser --remove-home " + username + " 1>/dev/null 2>&1") + +def get_current_script_dir(): + current_script_dir = os.path.realpath(__file__) + index = current_script_dir.rindex('/') + return current_script_dir[0:index] + +try: + os.system("python %s/recorder-stop.py" % get_current_script_dir()) + + print "Removing log directories" + remove_path("/var/log/recorder") + + print "Removing recorder files" + remove_path(BASE_PATH) + + print "Removing daemontool script recorder" + remove_path("rm -rf /etc/service/recorder") + + remove_user("pypo") + print "Uninstall complete." +except Exception, e: + print "exception:" + str(e) diff --git a/python_apps/show-recorder/testsoundcloud.py b/python_apps/show-recorder/testsoundcloud.py deleted file mode 100644 index 0ba6fd20d..000000000 --- a/python_apps/show-recorder/testsoundcloud.py +++ /dev/null @@ -1,59 +0,0 @@ -import webbrowser -import scapi - -# the host to connect to. Normally, this -# would be api.soundcloud.com -API_HOST = "api.soundcloud.com" - -# This needs to be the consumer ID you got from -# http://soundcloud.com/settings/applications/new -CONSUMER = "2CLCxcSXYzx7QhhPVHN4A" -# This needs to be the consumer secret password you got from -# http://soundcloud.com/settings/applications/new -CONSUMER_SECRET = "pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs" - -# first, we create an OAuthAuthenticator that only knows about consumer -# credentials. This is done so that we can get an request-token as -# first step. -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - None, - None) - -# The connector works with the authenticator to create and sign the requests. It -# has some helper-methods that allow us to do the OAuth-dance. -connector = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) - -# First step is to get a request-token, and to let the user authorize that -# via the browser. -token, secret = connector.fetch_request_token() -authorization_url = connector.get_request_token_authorization_url(token) -webbrowser.open(authorization_url) -oauth_verifier = raw_input("please enter verifier code as seen in the browser:") - -# Now we create a new authenticator with the temporary token & secret we got from -# the request-token. This will give us the access-token -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - -# we need a new connector with the new authenticator! -connector = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) -token, secret = connector.fetch_access_token(oauth_verifier) - - -# now we are finally ready to go - with all four parameters OAuth requires, -# we can setup an authenticator that allows for actual API-calls. -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - -# we pass the connector to a Scope - a Scope is essentially a path in the REST-url-space. -# Without any path-component, it's the root from which we can then query into the -# resources. -root = scapi.Scope(scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator)) - -# Hey, nice meeting you! Connected to SoundCloud using OAuth will allow you to access protected resources, like the current user's name. -print "Hello, %s" % root.me().username From 44d83051b13c682db1742fec7d41cad19dfce976 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Tue, 22 Mar 2011 18:41:02 -0400 Subject: [PATCH 21/74] CC-1630 : Automatic recording of shows using alsahw since users will have pulseaudio removed. --- pypo/install/pypo-install.py | 2 +- python_apps/show-recorder/testrecordscript.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pypo/install/pypo-install.py b/pypo/install/pypo-install.py index cff58175e..b764dcec9 100644 --- a/pypo/install/pypo-install.py +++ b/pypo/install/pypo-install.py @@ -45,7 +45,7 @@ def create_user(username): #add pypo to audio group os.system("adduser " + username + " audio 1>/dev/null 2>&1") #add pypo to pulse-access group - os.system("adduser " + username + " pulse-access 1>/dev/null 2>&1") + #os.system("adduser " + username + " pulse-access 1>/dev/null 2>&1") def copy_dir(src_dir, dest_dir): if (os.path.exists(dest_dir)) and (dest_dir != "/"): diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 4c659cdcb..808918123 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -39,7 +39,7 @@ class Recorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) + command = "ecasound -i alsahw,0,0 -o %s -t:%s" % (filepath, length) call(command, shell=True) return filepath From 72c9e44a91cf8cc7bc6353cb5457e0c3be297778 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 00:17:41 -0400 Subject: [PATCH 22/74] CC-2084: Integrate RabbitMQ for immediate schedule updates and commands Fixed minor issue where schedule was pushed back to pypo after updating the "played" flag for media files and playlists. This isnt necessary. --- application/models/Schedule.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index fc1c10770..0940e0a93 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -235,7 +235,6 @@ class ScheduleGroup { ." SET schedule_group_played=TRUE" ." WHERE group_id=".$this->groupId; $retVal = $CC_DBC->query($sql); - RabbitMq::PushSchedule(); return $retVal; } @@ -246,7 +245,6 @@ class ScheduleGroup { ." WHERE group_id=".$this->groupId ." AND file_id=".pg_escape_string($p_fileId); $retVal = $CC_DBC->query($sql); - RabbitMq::PushSchedule(); return $retVal; } } From 7f7800aa2bd291bfe210d3b13c010217822be5ed Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 00:27:31 -0400 Subject: [PATCH 23/74] CC-2084: Integrate RabbitMQ for immediate schedule updates and commands Fixed minor issue where schedule was pushed back to pypo after updating the "played" flag for media files and playlists. Found one other spot where this was happening and fixed it. --- application/models/Schedule.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 0940e0a93..47faa7ddc 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -554,7 +554,6 @@ class Schedule { ." SET media_item_played=TRUE" ." WHERE id=$p_id"; $retVal = $CC_DBC->query($sql); - RabbitMq::PushSchedule(); return $retVal; } From 1f4c08b1a3fd12e5fb785702275de6c4ae74c410 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Wed, 23 Mar 2011 00:33:46 -0400 Subject: [PATCH 24/74] CC-1630 : Automatic recording of shows need to run show recorder as root to have access to soundcard using daemontools --- python_apps/show-recorder/install/recorder-daemontools.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index c36996b40..d9cec7146 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -8,7 +8,5 @@ echo "*** Daemontools: starting daemon" cd ${recorder_path} exec 2>&1 # Note the -u when calling python! we need it to get unbuffered binary stdout and stderr -exec setuidgid ${recorder_user} \ - python -u ${recorder_path}${recorder_script} \ - -f +exec sudo python -u ${recorder_path}${recorder_script} -f # EOF From 8ebd70a61cb8f4f2d1849606a13eb8b7b085af24 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Wed, 23 Mar 2011 00:36:34 -0400 Subject: [PATCH 25/74] CC-1630 : Automatic recording of shows don't need to give specific device, just using default. --- python_apps/show-recorder/testrecordscript.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 808918123..4c659cdcb 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -39,7 +39,7 @@ class Recorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = "ecasound -i alsahw,0,0 -o %s -t:%s" % (filepath, length) + command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) call(command, shell=True) return filepath From 78b33b9e239d8c2b9db2d30369d214b480a2d411 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 01:09:27 -0400 Subject: [PATCH 26/74] CC-2084: Integrate RabbitMQ for immediate schedule updates and commands Implemented RabbitMQ on the pypo side. Schedule updates are now almost instantaneous and we are only polling the server once per hour if we aren't updated in that time. Canceling a show happens right away. --- application/models/RabbitMq.php | 34 +-- .../demo/amqp_airtime_consumer.php | 54 +++++ pypo/config.cfg | 11 +- pypo/pypofetch.py | 211 +++++++++++------- pypo/pypopush.py | 17 +- 5 files changed, 218 insertions(+), 109 deletions(-) create mode 100644 library/php-amqplib/demo/amqp_airtime_consumer.php diff --git a/application/models/RabbitMq.php b/application/models/RabbitMq.php index d251116bf..af5bffa02 100644 --- a/application/models/RabbitMq.php +++ b/application/models/RabbitMq.php @@ -10,23 +10,23 @@ class RabbitMq * in the future. */ public static function PushSchedule() { -// global $CC_CONFIG; -// $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"], -// $CC_CONFIG["rabbitmq"]["port"], -// $CC_CONFIG["rabbitmq"]["user"], -// $CC_CONFIG["rabbitmq"]["password"]); -// $channel = $conn->channel(); -// $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); -// -// $EXCHANGE = 'airtime-schedule'; -// $channel->exchange_declare($EXCHANGE, 'direct', false, false, false); -// -// $data = json_encode(Schedule::ExportRangeAsJson()); -// $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); -// -// $channel->basic_publish($msg, $EXCHANGE); -// $channel->close(); -// $conn->close(); + global $CC_CONFIG; + $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"], + $CC_CONFIG["rabbitmq"]["port"], + $CC_CONFIG["rabbitmq"]["user"], + $CC_CONFIG["rabbitmq"]["password"]); + $channel = $conn->channel(); + $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); + + $EXCHANGE = 'airtime-schedule'; + $channel->exchange_declare($EXCHANGE, 'direct', false, true); + + $data = json_encode(Schedule::ExportRangeAsJson()); + $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); + + $channel->basic_publish($msg, $EXCHANGE); + $channel->close(); + $conn->close(); } } diff --git a/library/php-amqplib/demo/amqp_airtime_consumer.php b/library/php-amqplib/demo/amqp_airtime_consumer.php new file mode 100644 index 000000000..bb5f8bcc8 --- /dev/null +++ b/library/php-amqplib/demo/amqp_airtime_consumer.php @@ -0,0 +1,54 @@ +#!/usr/bin/php + + */ + +require_once('../amqp.inc'); + +$HOST = 'localhost'; +$PORT = 5672; +$USER = 'guest'; +$PASS = 'guest'; +$VHOST = '/'; +$EXCHANGE = 'airtime-schedule'; +$QUEUE = 'airtime-schedule-msgs'; +$CONSUMER_TAG = 'airtime-consumer'; + +$conn = new AMQPConnection($HOST, $PORT, $USER, $PASS); +$ch = $conn->channel(); +$ch->access_request($VHOST, false, false, true, true); + +$ch->queue_declare($QUEUE); +$ch->exchange_declare($EXCHANGE, 'direct', false, false, false); +$ch->queue_bind($QUEUE, $EXCHANGE); + +function process_message($msg) { + global $ch, $CONSUMER_TAG; + + echo "\n--------\n"; + echo $msg->body; + echo "\n--------\n"; + + $ch->basic_ack($msg->delivery_info['delivery_tag']); + + // Cancel callback + if ($msg->body === 'quit') { + $ch->basic_cancel($CONSUMER_TAG); + } +} + +$ch->basic_consume($QUEUE, $CONSUMER_TAG, false, false, false, false, 'process_message'); + +// Loop as long as the channel has callbacks registered +echo "Waiting for messages...\n"; +while(count($ch->callbacks)) { + $ch->wait(); +} + +$ch->close(); +$conn->close(); +?> diff --git a/pypo/config.cfg b/pypo/config.cfg index 638558fbf..b4dc9424e 100644 --- a/pypo/config.cfg +++ b/pypo/config.cfg @@ -26,6 +26,13 @@ base_url = 'http://localhost/' ls_host = '127.0.0.1' ls_port = '1234' +############################################ +# RabbitMQ settings # +############################################ +rabbitmq_host = 'localhost' +rabbitmq_user = 'guest' +rabbitmq_password = 'guest' + ############################################ # pypo preferences # ############################################ @@ -42,7 +49,7 @@ cache_for = 24 #how long to hold the cache, in hours # the time you expect to "lock-in" your schedule. So if your schedule is set # 24 hours in advance, this can be set to poll every 12 hours. # -poll_interval = 5 # in seconds. +poll_interval = 3600 # in seconds. # Push interval in seconds. @@ -52,7 +59,7 @@ poll_interval = 5 # in seconds. # # It's hard to imagine a situation where this should be more than 1 second. # -push_interval = 2 # in seconds +push_interval = 1 # in seconds # 'pre' or 'otf'. 'pre' cues while playlist preparation # while 'otf' (on the fly) cues while loading into ls diff --git a/pypo/pypofetch.py b/pypo/pypofetch.py index 0ca468198..c31bd094a 100644 --- a/pypo/pypofetch.py +++ b/pypo/pypofetch.py @@ -12,6 +12,10 @@ import telnetlib import math from threading import Thread +# For RabbitMQ +from kombu.connection import BrokerConnection +from kombu.messaging import Exchange, Queue, Consumer, Producer + from api_clients import api_client from util import CueFile @@ -25,91 +29,101 @@ try: config = ConfigObj('config.cfg') LS_HOST = config['ls_host'] LS_PORT = config['ls_port'] - POLL_INTERVAL = 5 + POLL_INTERVAL = int(config['poll_interval']) except Exception, e: print 'Error loading config file: ', e sys.exit() +# Yuk - using a global, i know! +SCHEDULE_PUSH_MSG = [] + +""" +Handle a message from RabbitMQ, put it into our yucky global var. +Hopefully there is a better way to do this. +""" +def handle_message(body, message): + logger = logging.getLogger('fetch') + global SCHEDULE_PUSH_MSG + logger.info("Received schedule from RabbitMQ: " + message.body) + SCHEDULE_PUSH_MSG = json.loads(message.body) + # ACK the message to take it off the queue + message.ack() + + class PypoFetch(Thread): def __init__(self, q): Thread.__init__(self) + logger = logging.getLogger('fetch') self.api_client = api_client.api_client_factory(config) self.cue_file = CueFile() self.set_export_source('scheduler') self.queue = q + logger.info("Initializing RabbitMQ stuff") + schedule_exchange = Exchange("airtime-schedule", "direct", durable=True, auto_delete=True) + schedule_queue = Queue("pypo-fetch", exchange=schedule_exchange, key="foo") + self.connection = BrokerConnection(config["rabbitmq_host"], config["rabbitmq_user"], config["rabbitmq_password"], "/") + channel = self.connection.channel() + consumer = Consumer(channel, schedule_queue) + consumer.register_callback(handle_message) + consumer.consume() + + logger.info("PypoFetch: init complete"); + + def set_export_source(self, export_source): self.export_source = export_source self.cache_dir = config["cache_dir"] + self.export_source + '/' + """ - Fetching part of pypo - - Reads the scheduled entries of a given range (actual time +/- "prepare_ahead" / "cache_for") - - Saves a serialized file of the schedule - - playlists are prepared. (brought to liquidsoap format) and, if not mounted via nsf, files are copied - to the cache dir (Folder-structure: cache/YYYY-MM-DD-hh-mm-ss) - - runs the cleanup routine, to get rid of unused cashed files + Process the schedule + - Reads the scheduled entries of a given range (actual time +/- "prepare_ahead" / "cache_for") + - Saves a serialized file of the schedule + - playlists are prepared. (brought to liquidsoap format) and, if not mounted via nsf, files are copied + to the cache dir (Folder-structure: cache/YYYY-MM-DD-hh-mm-ss) + - runs the cleanup routine, to get rid of unused cashed files """ - def fetch(self, export_source): - #wrapper script for fetching the whole schedule (in json) + def process_schedule(self, schedule_data, export_source): logger = logging.getLogger('fetch') - - try: os.mkdir(self.cache_dir) - except Exception, e: pass - - # get schedule + self.schedule = schedule_data["playlists"] + + # Push stream metadata to liquidsoap + # TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!! + stream_metadata = schedule_data['stream_metadata'] try: - while self.get_schedule() != 1: - logger.warning("failed to read from export url") - time.sleep(1) + tn = telnetlib.Telnet(LS_HOST, LS_PORT) + #encode in latin-1 due to telnet protocol not supporting utf-8 + tn.write(('vars.stream_metadata_type %s\n' % stream_metadata['format']).encode('latin-1')) + tn.write(('vars.station_name %s\n' % stream_metadata['station_name']).encode('latin-1')) + tn.write('exit\n') + tn.read_all() + except Exception, e: + logger.error("Exception %s", e) + status = 0 + # Download all the media and put playlists in liquidsoap format + try: + playlists = self.prepare_playlists() except Exception, e: logger.error("%s", e) - # prepare the playlists - try: - playlists = self.prepare_playlists() - except Exception, e: logger.error("%s", e) - - + # Send the data to pypo-push scheduled_data = dict() scheduled_data['playlists'] = playlists scheduled_data['schedule'] = self.schedule + scheduled_data['stream_metadata'] = schedule_data["stream_metadata"] self.queue.put(scheduled_data) # cleanup try: self.cleanup(self.export_source) except Exception, e: logger.error("%s", e) - def get_schedule(self): - logger = logging.getLogger('fetch') - status, response = self.api_client.get_schedule() - - if status == 1: - schedule = response['playlists'] - stream_metadata = response['stream_metadata'] - try: - self.schedule = schedule - tn = telnetlib.Telnet(LS_HOST, LS_PORT) - - #encode in latin-1 due to telnet protocol not supporting utf-8 - tn.write(('vars.stream_metadata_type %s\n' % stream_metadata['format']).encode('latin-1')) - tn.write(('vars.station_name %s\n' % stream_metadata['station_name']).encode('latin-1')) - - tn.write('exit\n') - tn.read_all() - - except Exception, e: - logger.error("Exception %s", e) - status = 0 - - return status """ - Alternative version of playout preparation. Every playlist entry is - pre-cued if neccessary (cue_in/cue_out != 0) and stored in the - playlist folder. - file is eg 2010-06-23-15-00-00/17_cue_10.132-123.321.mp3 + In this function every audio file is cut as necessary (cue_in/cue_out != 0) + and stored in a playlist folder. + file is e.g. 2010-06-23-15-00-00/17_cue_10.132-123.321.mp3 """ def prepare_playlists(self): logger = logging.getLogger('fetch') @@ -126,7 +140,7 @@ class PypoFetch(Thread): try: for pkey in scheduleKeys: - logger.info("found playlist at %s", pkey) + logger.info("Playlist starting at %s", pkey) playlist = schedule[pkey] # create playlist directory @@ -135,15 +149,15 @@ class PypoFetch(Thread): except Exception, e: pass - logger.debug('*****************************************') - logger.debug('pkey: ' + str(pkey)) - logger.debug('cached at : ' + self.cache_dir + str(pkey)) - logger.debug('subtype: ' + str(playlist['subtype'])) - logger.debug('played: ' + str(playlist['played'])) - logger.debug('schedule id: ' + str(playlist['schedule_id'])) - logger.debug('duration: ' + str(playlist['duration'])) - logger.debug('source id: ' + str(playlist['x_ident'])) - logger.debug('*****************************************') + #logger.debug('*****************************************') + #logger.debug('pkey: ' + str(pkey)) + #logger.debug('cached at : ' + self.cache_dir + str(pkey)) + #logger.debug('subtype: ' + str(playlist['subtype'])) + #logger.debug('played: ' + str(playlist['played'])) + #logger.debug('schedule id: ' + str(playlist['schedule_id'])) + #logger.debug('duration: ' + str(playlist['duration'])) + #logger.debug('source id: ' + str(playlist['x_ident'])) + #logger.debug('*****************************************') if int(playlist['played']) == 1: logger.info("playlist %s already played / sent to liquidsoap, so will ignore it", pkey) @@ -156,11 +170,13 @@ class PypoFetch(Thread): logger.info("%s", e) return playlists + + """ + Download and cache the media files. + This handles both remote and local files. + Returns an updated ls_playlist string. + """ def handle_media_file(self, playlist, pkey): - """ - This handles both remote and local files. - Returns an updated ls_playlist string. - """ ls_playlist = [] logger = logging.getLogger('fetch') @@ -170,11 +186,11 @@ class PypoFetch(Thread): fileExt = os.path.splitext(media['uri'])[1] try: if str(media['cue_in']) == '0' and str(media['cue_out']) == '0': - logger.debug('No cue in/out detected for this file') + #logger.debug('No cue in/out detected for this file') dst = "%s%s/%s%s" % (self.cache_dir, str(pkey), str(media['id']), str(fileExt)) do_cue = False else: - logger.debug('Cue in/out detected') + #logger.debug('Cue in/out detected') dst = "%s%s/%s_cue_%s-%s%s" % \ (self.cache_dir, str(pkey), str(media['id']), str(float(media['cue_in']) / 1000), str(float(media['cue_out']) / 1000), str(fileExt)) do_cue = True @@ -199,7 +215,7 @@ class PypoFetch(Thread): % (str(media['export_source']), media['id'], 0, str(float(media['fade_in']) / 1000), \ str(float(media['fade_out']) / 1000), media['row_id'],dst) - logger.debug(pl_entry) + #logger.debug(pl_entry) """ Tracks are only added to the playlist if they are accessible @@ -213,7 +229,7 @@ class PypoFetch(Thread): entry['show_name'] = playlist['show_name'] ls_playlist.append(entry) - logger.debug("everything ok, adding %s to playlist", pl_entry) + #logger.debug("everything ok, adding %s to playlist", pl_entry) else: print 'zero-file: ' + dst + ' from ' + media['uri'] logger.warning("zero-size file - skipping %s. will not add it to playlist", dst) @@ -225,11 +241,15 @@ class PypoFetch(Thread): return ls_playlist + """ + Download a file from a remote server and store it in the cache. + """ def handle_remote_file(self, media, dst, do_cue): logger = logging.getLogger('fetch') if do_cue == False: if os.path.isfile(dst): - logger.debug("file already in cache: %s", dst) + pass + #logger.debug("file already in cache: %s", dst) else: logger.debug("try to download %s", media['uri']) self.api_client.get_media(media['uri'], dst) @@ -270,11 +290,11 @@ class PypoFetch(Thread): logger.error("%s", e) + """ + Cleans up folders in cache_dir. Look for modification date older than "now - CACHE_FOR" + and deletes them. + """ def cleanup(self, export_source): - """ - Cleans up folders in cache_dir. Look for modification date older than "now - CACHE_FOR" - and deletes them. - """ logger = logging.getLogger('fetch') offset = 3600 * int(config["cache_for"]) @@ -297,18 +317,41 @@ class PypoFetch(Thread): print e logger.error("%s", e) + + """ + Main loop of the thread: + Wait for schedule updates from RabbitMQ, but in case there arent any, + poll the server to get the upcoming schedule. + """ def run(self): - loops = 0 - heartbeat_period = math.floor(30/POLL_INTERVAL) logger = logging.getLogger('fetch') - + + try: os.mkdir(self.cache_dir) + except Exception, e: pass + + # Bootstrap: since we are just starting up, we need to grab the + # most recent schedule. After that we can just wait for updates. + status, schedule_data = self.api_client.get_schedule() + if status == 1: + self.process_schedule(schedule_data, "scheduler") + logger.info("Bootstrap complete: got initial copy of the schedule") + + loops = 1 while True: - if loops % heartbeat_period == 0: - logger.info("heartbeat") - loops = 0 - try: self.fetch('scheduler') - except Exception, e: - logger.error('Pypo Fetch Error, exiting: %s', e) - sys.exit() - time.sleep(POLL_INTERVAL) + logger.info("Loop #"+str(loops)) + try: + # Wait for messages from RabbitMQ. Timeout if we + # dont get any after POLL_INTERVAL. + self.connection.drain_events(timeout=POLL_INTERVAL) + # Hooray for globals! + schedule_data = SCHEDULE_PUSH_MSG + status = 1 + except: + # We didnt get a message for a while, so poll the server + # to get an updated schedule. + status, schedule_data = self.api_client.get_schedule() + + if status == 1: + self.process_schedule(schedule_data, "scheduler") loops += 1 + diff --git a/pypo/pypopush.py b/pypo/pypopush.py index 62203fc59..25bfddbf1 100644 --- a/pypo/pypopush.py +++ b/pypo/pypopush.py @@ -38,6 +38,7 @@ class PypoPush(Thread): self.schedule = dict() self.playlists = dict() + self.stream_metadata = dict() """ push_ahead2 MUST be < push_ahead. The difference in these two values @@ -53,18 +54,21 @@ class PypoPush(Thread): self.schedule_tracker_file = self.cache_dir + "schedule_tracker.pickle" """ - The Push Loop - the push loop periodically (minimal 1/2 of the playlist-grid) - checks if there is a playlist that should be scheduled at the current time. - If yes, the temporary liquidsoap playlist gets replaced with the corresponding one, + The Push Loop - the push loop periodically checks if there is a playlist + that should be scheduled at the current time. + If yes, the current liquidsoap playlist gets replaced with the corresponding one, then liquidsoap is asked (via telnet) to reload and immediately play it. """ def push(self, export_source): logger = logging.getLogger('push') + # get a new schedule from pypo-fetch if not self.queue.empty(): scheduled_data = self.queue.get() + logger.debug("Received data from pypo-fetch") self.schedule = scheduled_data['schedule'] self.playlists = scheduled_data['playlists'] + self.stream_metadata = scheduled_data['stream_metadata'] schedule = self.schedule playlists = self.playlists @@ -120,7 +124,8 @@ class PypoPush(Thread): if start <= str_tnow_s and str_tnow_s < end: currently_on_air = True else: - logger.debug('Empty schedule') + pass + #logger.debug('Empty schedule') if not currently_on_air: tn = telnetlib.Telnet(LS_HOST, LS_PORT) @@ -184,7 +189,7 @@ class PypoPush(Thread): def load_schedule_tracker(self): logger = logging.getLogger('push') - logger.debug('load_schedule_tracker') + #logger.debug('load_schedule_tracker') playedItems = dict() # create the file if it doesnt exist @@ -197,7 +202,7 @@ class PypoPush(Thread): except Exception, e: logger.error('Error creating schedule tracker file: %s', e) else: - logger.debug('schedule tracker file exists, opening: ' + self.schedule_tracker_file) + #logger.debug('schedule tracker file exists, opening: ' + self.schedule_tracker_file) try: schedule_tracker = open(self.schedule_tracker_file, "r") playedItems = pickle.load(schedule_tracker) From 224fa1a0b8a86c7aa42f40821c6d99c47ce942b9 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Wed, 23 Mar 2011 12:09:29 -0400 Subject: [PATCH 27/74] CC-1985 : Automatic rebroadcast of recorded content sending group_id instead of playlist id to playout anything not in a playlist won't have a playlist id scheduling just a file for rebroadcast shows. --- application/models/Schedule.php | 4 +- python_apps/soundcloud-api/AUTHORS | 5 - python_apps/soundcloud-api/ChangeLog | 9 - python_apps/soundcloud-api/LICENSE | 458 ------ python_apps/soundcloud-api/README | 45 - python_apps/soundcloud-api/bootstrap.py | 58 - .../soundcloud-api/docs/api/api-objects.txt | 333 ----- .../soundcloud-api/docs/api/class-tree.html | 216 --- python_apps/soundcloud-api/docs/api/crarr.png | Bin 340 -> 0 bytes .../soundcloud-api/docs/api/epydoc.css | 322 ----- python_apps/soundcloud-api/docs/api/epydoc.js | 293 ---- .../api/exceptions.AssertionError-class.html | 299 ---- .../soundcloud-api/docs/api/frames.html | 17 - python_apps/soundcloud-api/docs/api/help.html | 278 ---- .../docs/api/identifier-index.html | 892 ------------ .../soundcloud-api/docs/api/index.html | 17 - .../soundcloud-api/docs/api/module-tree.html | 130 -- .../soundcloud-api/docs/api/redirect.html | 38 - .../soundcloud-api/docs/api/scapi-module.html | 444 ------ .../soundcloud-api/docs/api/scapi-pysrc.html | 1263 ----------------- .../docs/api/scapi.ApiConnector-class.html | 544 ------- .../docs/api/scapi.Asset-class.html | 258 ---- .../docs/api/scapi.Comment-class.html | 258 ---- .../docs/api/scapi.Event-class.html | 258 ---- .../docs/api/scapi.Group-class.html | 258 ---- .../scapi.InvalidMethodException-class.html | 297 ---- .../api/scapi.NoResultFromRequest-class.html | 195 --- .../docs/api/scapi.Playlist-class.html | 258 ---- .../docs/api/scapi.RESTBase-class.html | 895 ------------ .../api/scapi.SCRedirectHandler-class.html | 319 ----- .../docs/api/scapi.Scope-class.html | 682 --------- .../docs/api/scapi.Track-class.html | 264 ---- .../api/scapi.UnknownContentType-class.html | 337 ----- .../docs/api/scapi.User-class.html | 264 ---- .../docs/api/scapi.authentication-module.html | 228 --- .../docs/api/scapi.authentication-pysrc.html | 348 ----- ...thentication.BasicAuthenticator-class.html | 267 ---- ...thentication.OAuthAuthenticator-class.html | 337 ----- ....OAuthSignatureMethod_HMAC_SHA1-class.html | 294 ---- .../docs/api/scapi.config-module.html | 114 -- .../docs/api/scapi.config-pysrc.html | 122 -- .../docs/api/scapi.json-module.html | 218 --- .../docs/api/scapi.json-pysrc.html | 433 ------ .../docs/api/scapi.json.JsonReader-class.html | 544 ------- .../docs/api/scapi.json.JsonWriter-class.html | 233 --- .../api/scapi.json.ReadException-class.html | 196 --- .../api/scapi.json.WriteException-class.html | 196 --- .../scapi.json._StringGenerator-class.html | 291 ---- .../docs/api/scapi.tests-module.html | 140 -- .../docs/api/scapi.tests-pysrc.html | 122 -- .../api/scapi.tests.scapi_tests-module.html | 172 --- .../api/scapi.tests.scapi_tests-pysrc.html | 760 ---------- ...pi.tests.scapi_tests.SCAPITests-class.html | 1025 ------------- .../api/scapi.tests.test_connect-module.html | 586 -------- .../api/scapi.tests.test_connect-pysrc.html | 627 -------- .../api/scapi.tests.test_oauth-module.html | 225 --- .../api/scapi.tests.test_oauth-pysrc.html | 182 --- .../docs/api/scapi.util-module.html | 173 --- .../docs/api/scapi.util-pysrc.html | 171 --- .../docs/api/scapi.util.MultiDict-class.html | 247 ---- .../docs/api/toc-everything.html | 151 -- .../docs/api/toc-scapi-module.html | 70 - .../api/toc-scapi.authentication-module.html | 46 - .../docs/api/toc-scapi.config-module.html | 29 - .../docs/api/toc-scapi.json-module.html | 40 - .../docs/api/toc-scapi.multidict-module.html | 29 - .../docs/api/toc-scapi.tests-module.html | 29 - .../toc-scapi.tests.scapi_tests-module.html | 34 - .../toc-scapi.tests.test_connect-module.html | 68 - .../toc-scapi.tests.test_oauth-module.html | 41 - .../docs/api/toc-scapi.util-module.html | 37 - python_apps/soundcloud-api/docs/api/toc.html | 46 - python_apps/soundcloud-api/oauth/__init__.py | 0 .../soundcloud-api/oauth/example/client.py | 157 -- .../soundcloud-api/oauth/example/server.py | 167 --- python_apps/soundcloud-api/oauth/oauth.py | 505 ------- .../scapi/MultipartPostHandler.py | 135 -- python_apps/soundcloud-api/scapi/__init__.py | 1012 ------------- .../soundcloud-api/scapi/authentication.py | 195 --- python_apps/soundcloud-api/scapi/config.py | 2 - python_apps/soundcloud-api/scapi/json.py | 310 ---- .../soundcloud-api/scapi/tests/__init__.py | 0 .../soundcloud-api/scapi/tests/knaster.mp3 | Bin 80493 -> 0 bytes .../soundcloud-api/scapi/tests/scapi_tests.py | 563 -------- .../soundcloud-api/scapi/tests/spam.jpg | Bin 85062 -> 0 bytes .../scapi/tests/test_connect.py | 334 ----- .../soundcloud-api/scapi/tests/test_oauth.py | 36 - python_apps/soundcloud-api/scapi/util.py | 53 - python_apps/soundcloud-api/setup.py | 22 - python_apps/soundcloud-api/test.ini | 33 - 90 files changed, 2 insertions(+), 22601 deletions(-) delete mode 100644 python_apps/soundcloud-api/AUTHORS delete mode 100644 python_apps/soundcloud-api/ChangeLog delete mode 100644 python_apps/soundcloud-api/LICENSE delete mode 100644 python_apps/soundcloud-api/README delete mode 100644 python_apps/soundcloud-api/bootstrap.py delete mode 100644 python_apps/soundcloud-api/docs/api/api-objects.txt delete mode 100644 python_apps/soundcloud-api/docs/api/class-tree.html delete mode 100644 python_apps/soundcloud-api/docs/api/crarr.png delete mode 100644 python_apps/soundcloud-api/docs/api/epydoc.css delete mode 100644 python_apps/soundcloud-api/docs/api/epydoc.js delete mode 100644 python_apps/soundcloud-api/docs/api/exceptions.AssertionError-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/frames.html delete mode 100644 python_apps/soundcloud-api/docs/api/help.html delete mode 100644 python_apps/soundcloud-api/docs/api/identifier-index.html delete mode 100644 python_apps/soundcloud-api/docs/api/index.html delete mode 100644 python_apps/soundcloud-api/docs/api/module-tree.html delete mode 100644 python_apps/soundcloud-api/docs/api/redirect.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.ApiConnector-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Asset-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Comment-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Event-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Group-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.InvalidMethodException-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.NoResultFromRequest-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Playlist-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.RESTBase-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.SCRedirectHandler-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Scope-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.Track-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.UnknownContentType-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.User-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.authentication-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.authentication-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.authentication.BasicAuthenticator-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthAuthenticator-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.config-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.config-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json.JsonReader-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json.JsonWriter-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json.ReadException-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json.WriteException-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.json._StringGenerator-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests.SCAPITests-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.util-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.util-pysrc.html delete mode 100644 python_apps/soundcloud-api/docs/api/scapi.util.MultiDict-class.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-everything.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.authentication-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.config-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.json-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.multidict-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.tests-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.tests.scapi_tests-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_connect-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_oauth-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc-scapi.util-module.html delete mode 100644 python_apps/soundcloud-api/docs/api/toc.html delete mode 100644 python_apps/soundcloud-api/oauth/__init__.py delete mode 100644 python_apps/soundcloud-api/oauth/example/client.py delete mode 100644 python_apps/soundcloud-api/oauth/example/server.py delete mode 100644 python_apps/soundcloud-api/oauth/oauth.py delete mode 100644 python_apps/soundcloud-api/scapi/MultipartPostHandler.py delete mode 100644 python_apps/soundcloud-api/scapi/__init__.py delete mode 100644 python_apps/soundcloud-api/scapi/authentication.py delete mode 100644 python_apps/soundcloud-api/scapi/config.py delete mode 100644 python_apps/soundcloud-api/scapi/json.py delete mode 100644 python_apps/soundcloud-api/scapi/tests/__init__.py delete mode 100644 python_apps/soundcloud-api/scapi/tests/knaster.mp3 delete mode 100644 python_apps/soundcloud-api/scapi/tests/scapi_tests.py delete mode 100644 python_apps/soundcloud-api/scapi/tests/spam.jpg delete mode 100644 python_apps/soundcloud-api/scapi/tests/test_connect.py delete mode 100644 python_apps/soundcloud-api/scapi/tests/test_oauth.py delete mode 100644 python_apps/soundcloud-api/scapi/util.py delete mode 100644 python_apps/soundcloud-api/setup.py delete mode 100644 python_apps/soundcloud-api/test.ini diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 21419c4f0..08170af26 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -663,7 +663,7 @@ class Schedule { $pkey = Schedule::AirtimeTimeToPypoTime($start); $timestamp = strtotime($start); $playlists[$pkey]['source'] = "PLAYLIST"; - $playlists[$pkey]['x_ident'] = $dx["playlist_id"]; + $playlists[$pkey]['x_ident'] = $dx['group_id']; $playlists[$pkey]['subtype'] = '1'; // Just needs to be between 1 and 4 inclusive $playlists[$pkey]['timestamp'] = $timestamp; $playlists[$pkey]['duration'] = $dx['clip_length']; @@ -671,7 +671,7 @@ class Schedule { $playlists[$pkey]['schedule_id'] = $dx['group_id']; $playlists[$pkey]['show_name'] = $dx['show_name']; $playlists[$pkey]['user_id'] = 0; - $playlists[$pkey]['id'] = $dx["playlist_id"]; + $playlists[$pkey]['id'] = $dx['group_id']; $playlists[$pkey]['start'] = Schedule::AirtimeTimeToPypoTime($dx["start"]); $playlists[$pkey]['end'] = Schedule::AirtimeTimeToPypoTime($dx["end"]); } diff --git a/python_apps/soundcloud-api/AUTHORS b/python_apps/soundcloud-api/AUTHORS deleted file mode 100644 index ae92c1d26..000000000 --- a/python_apps/soundcloud-api/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -Authors -------- - -Diez B. Roggisch, deets@web.de - diff --git a/python_apps/soundcloud-api/ChangeLog b/python_apps/soundcloud-api/ChangeLog deleted file mode 100644 index 9b5bb4679..000000000 --- a/python_apps/soundcloud-api/ChangeLog +++ /dev/null @@ -1,9 +0,0 @@ -2009-09-10 Diez Roggisch - - * OAuth 1.0a working - * Query-Parameters for GET-requests to allow e.g. filtering - * Setting file-objects as attributes working. - * share to emails working. - * groups - * downloading/streaming private tracks - diff --git a/python_apps/soundcloud-api/LICENSE b/python_apps/soundcloud-api/LICENSE deleted file mode 100644 index 3b473dbfc..000000000 --- a/python_apps/soundcloud-api/LICENSE +++ /dev/null @@ -1,458 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS diff --git a/python_apps/soundcloud-api/README b/python_apps/soundcloud-api/README deleted file mode 100644 index 729a8faac..000000000 --- a/python_apps/soundcloud-api/README +++ /dev/null @@ -1,45 +0,0 @@ -Running tests -============= - -The **SCAPI** comes with a small testsuite. It can be run automatically through either setuptools_ -or nose_. - -Configuring tests ------------------ - -Before you can run the tests, you need to configure them. You do this using the `test.ini` file in the -root of python **SCAPI** workingcopy. - -Running tests through setuptools --------------------------------- - -You can run the whole testsuite through setuptools_ by doing :: - - host:~/SoundCloudAPI deets$ python setup.py test - -Running tests through nose --------------------------- - -If you want a more fine-grained control over which tests to run, you can use the `nosetests`-commandline tool. - -Then to run individual tests, you can e.g. do:: - - host:~/SoundCloudAPI deets$ nosetests -s scapi.tests.scapi_tests:SCAPITests.test_setting_permissions - - -See the nose_-website for more options. - - - -.. _nose: http://somethingaboutorange.com/mrl/projects/nose/ -.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools -.. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html - - -Creating the API-docs -===================== - -Do:: - epydoc -v --name="SoundCloud API" --html -o docs/api scapi --exclude="os|mimetypes|urllib2|exceptions|mimetools" - - diff --git a/python_apps/soundcloud-api/bootstrap.py b/python_apps/soundcloud-api/bootstrap.py deleted file mode 100644 index c04723c5b..000000000 --- a/python_apps/soundcloud-api/bootstrap.py +++ /dev/null @@ -1,58 +0,0 @@ -import webbrowser -import scapi - -# the host to connect to. Normally, this -# would be api.soundcloud.com -API_HOST = "api.sandbox-soundcloud.com" - -# This needs to be the consumer ID you got from -# http://soundcloud.com/settings/applications/new -CONSUMER = "gLnhFeUBnBCZF8a6Ngqq7w" -# This needs to be the consumer secret password you got from -# http://soundcloud.com/settings/applications/new -CONSUMER_SECRET = "nbWRdG5X9xUb63l4nIeFYm3nmeVJ2v4s1ROpvRSBvU8" - -# first, we create an OAuthAuthenticator that only knows about consumer -# credentials. This is done so that we can get an request-token as -# first step. -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - None, - None) - -# The connector works with the authenticator to create and sign the requests. It -# has some helper-methods that allow us to do the OAuth-dance. -connector = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) - -# First step is to get a request-token, and to let the user authorize that -# via the browser. -token, secret = connector.fetch_request_token() -authorization_url = connector.get_request_token_authorization_url(token) -webbrowser.open(authorization_url) -oauth_verifier = raw_input("please enter verifier code as seen in the browser:") - -# Now we create a new authenticator with the temporary token & secret we got from -# the request-token. This will give us the access-token -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - -# we need a new connector with the new authenticator! -connector = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) -token, secret = connector.fetch_access_token(oauth_verifier) - -# now we are finally ready to go - with all four parameters OAuth requires, -# we can setup an authenticator that allows for actual API-calls. -oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - -# we pass the connector to a Scope - a Scope is essentiall a path in the REST-url-space. -# Without any path-component, it's the root from which we can then query into the -# resources. -root = scapi.Scope(scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator)) - -# Hey, nice meeting you! -print "Hello, %s" % root.me().username diff --git a/python_apps/soundcloud-api/docs/api/api-objects.txt b/python_apps/soundcloud-api/docs/api/api-objects.txt deleted file mode 100644 index 8f3e21555..000000000 --- a/python_apps/soundcloud-api/docs/api/api-objects.txt +++ /dev/null @@ -1,333 +0,0 @@ -scapi scapi-module.html -scapi.escape scapi.util-module.html#escape -scapi.USE_PROXY scapi-module.html#USE_PROXY -scapi.REQUEST_TOKEN_URL scapi-module.html#REQUEST_TOKEN_URL -scapi.PROXY scapi-module.html#PROXY -scapi.ACCESS_TOKEN_URL scapi-module.html#ACCESS_TOKEN_URL -scapi.register_classes scapi-module.html#register_classes -scapi.logger scapi-module.html#logger -scapi.AUTHORIZATION_URL scapi-module.html#AUTHORIZATION_URL -scapi.authentication scapi.authentication-module.html -scapi.authentication.USE_DOUBLE_ESCAPE_HACK scapi.authentication-module.html#USE_DOUBLE_ESCAPE_HACK -scapi.authentication.escape scapi.util-module.html#escape -scapi.authentication.logger scapi.authentication-module.html#logger -scapi.config scapi.config-module.html -scapi.json scapi.json-module.html -scapi.json.read scapi.json-module.html#read -scapi.json.write scapi.json-module.html#write -scapi.multidict scapi.multidict-module.html -scapi.tests scapi.tests-module.html -scapi.tests.scapi_tests scapi.tests.scapi_tests-module.html -scapi.tests.scapi_tests.api_logger scapi.tests.scapi_tests-module.html#api_logger -scapi.tests.scapi_tests.logger scapi.tests.scapi_tests-module.html#logger -scapi.tests.test_connect scapi.tests.test_connect-module.html -scapi.tests.test_connect.test_me_having_stress scapi.tests.test_connect-module.html#test_me_having_stress -scapi.tests.test_connect.test_scoped_track_creation scapi.tests.test_connect-module.html#test_scoped_track_creation -scapi.tests.test_connect.test_permissions scapi.tests.test_connect-module.html#test_permissions -scapi.tests.test_connect.CONSUMER_SECRET scapi.tests.test_connect-module.html#CONSUMER_SECRET -scapi.tests.test_connect.CONSUMER scapi.tests.test_connect-module.html#CONSUMER -scapi.tests.test_connect.load_config scapi.tests.test_connect-module.html#load_config -scapi.tests.test_connect.test_upload scapi.tests.test_connect-module.html#test_upload -scapi.tests.test_connect.USER scapi.tests.test_connect-module.html#USER -scapi.tests.test_connect.test_load_config scapi.tests.test_connect-module.html#test_load_config -scapi.tests.test_connect.test_access_token_acquisition scapi.tests.test_connect-module.html#test_access_token_acquisition -scapi.tests.test_connect.test_track_creation scapi.tests.test_connect-module.html#test_track_creation -scapi.tests.test_connect.test_setting_comments scapi.tests.test_connect-module.html#test_setting_comments -scapi.tests.test_connect.test_track_update scapi.tests.test_connect-module.html#test_track_update -scapi.tests.test_connect.SECRET scapi.tests.test_connect-module.html#SECRET -scapi.tests.test_connect.test_contact_add_and_removal scapi.tests.test_connect-module.html#test_contact_add_and_removal -scapi.tests.test_connect.logger scapi.tests.test_connect-module.html#logger -scapi.tests.test_connect.test_connect scapi.tests.test_connect-module.html#test_connect -scapi.tests.test_connect.ROOT scapi.tests.test_connect-module.html#ROOT -scapi.tests.test_connect.test_contact_list scapi.tests.test_connect-module.html#test_contact_list -scapi.tests.test_connect.test_playlists scapi.tests.test_connect-module.html#test_playlists -scapi.tests.test_connect.API_HOST scapi.tests.test_connect-module.html#API_HOST -scapi.tests.test_connect._logger scapi.tests.test_connect-module.html#_logger -scapi.tests.test_connect.TOKEN scapi.tests.test_connect-module.html#TOKEN -scapi.tests.test_connect.test_events scapi.tests.test_connect-module.html#test_events -scapi.tests.test_connect.test_non_global_api scapi.tests.test_connect-module.html#test_non_global_api -scapi.tests.test_connect.test_setting_permissions scapi.tests.test_connect-module.html#test_setting_permissions -scapi.tests.test_connect.PASSWORD scapi.tests.test_connect-module.html#PASSWORD -scapi.tests.test_connect.test_setting_comments_the_way_shawn_says_its_correct scapi.tests.test_connect-module.html#test_setting_comments_the_way_shawn_says_its_correct -scapi.tests.test_connect.test_large_list scapi.tests.test_connect-module.html#test_large_list -scapi.tests.test_connect.CONNECTOR scapi.tests.test_connect-module.html#CONNECTOR -scapi.tests.test_connect.CONFIG_NAME scapi.tests.test_connect-module.html#CONFIG_NAME -scapi.tests.test_connect.RUN_INTERACTIVE_TESTS scapi.tests.test_connect-module.html#RUN_INTERACTIVE_TESTS -scapi.tests.test_connect.setup scapi.tests.test_connect-module.html#setup -scapi.tests.test_connect.test_favorites scapi.tests.test_connect-module.html#test_favorites -scapi.tests.test_connect.USE_OAUTH scapi.tests.test_connect-module.html#USE_OAUTH -scapi.tests.test_oauth scapi.tests.test_oauth-module.html -scapi.tests.test_oauth._logger scapi.tests.test_oauth-module.html#_logger -scapi.tests.test_oauth.test_oauth_connect scapi.tests.test_oauth-module.html#test_oauth_connect -scapi.tests.test_oauth.TOKEN scapi.tests.test_oauth-module.html#TOKEN -scapi.tests.test_oauth.test_base64_connect scapi.tests.test_oauth-module.html#test_base64_connect -scapi.tests.test_oauth.CONSUMER_SECRET scapi.tests.test_oauth-module.html#CONSUMER_SECRET -scapi.tests.test_oauth.SECRET scapi.tests.test_oauth-module.html#SECRET -scapi.tests.test_oauth.logger scapi.tests.test_oauth-module.html#logger -scapi.tests.test_oauth.CONSUMER scapi.tests.test_oauth-module.html#CONSUMER -scapi.util scapi.util-module.html -scapi.util.escape scapi.util-module.html#escape -exceptions.AssertionError exceptions.AssertionError-class.html -exceptions.AssertionError.__init__ exceptions.AssertionError-class.html#__init__ -exceptions.AssertionError.__new__ exceptions.AssertionError-class.html#__new__ -scapi.ApiConnector scapi.ApiConnector-class.html -scapi.ApiConnector.fetch_access_token scapi.ApiConnector-class.html#fetch_access_token -scapi.ApiConnector.LIST_LIMIT scapi.ApiConnector-class.html#LIST_LIMIT -scapi.ApiConnector.LIST_LIMIT_PARAMETER scapi.ApiConnector-class.html#LIST_LIMIT_PARAMETER -scapi.ApiConnector.fetch_request_token scapi.ApiConnector-class.html#fetch_request_token -scapi.ApiConnector.get_request_token_authorization_url scapi.ApiConnector-class.html#get_request_token_authorization_url -scapi.ApiConnector.normalize_method scapi.ApiConnector-class.html#normalize_method -scapi.ApiConnector.__init__ scapi.ApiConnector-class.html#__init__ -scapi.ApiConnector.LIST_OFFSET_PARAMETER scapi.ApiConnector-class.html#LIST_OFFSET_PARAMETER -scapi.Comment scapi.Comment-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.Comment.KIND scapi.Comment-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.RESTBase.ALIASES scapi.RESTBase-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.Event scapi.Event-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.Event.KIND scapi.Event-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.RESTBase.ALIASES scapi.RESTBase-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.Group scapi.Group-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.Group.KIND scapi.Group-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.RESTBase.ALIASES scapi.RESTBase-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.InvalidMethodException scapi.InvalidMethodException-class.html -scapi.InvalidMethodException.__repr__ scapi.InvalidMethodException-class.html#__repr__ -scapi.InvalidMethodException.__init__ scapi.InvalidMethodException-class.html#__init__ -scapi.NoResultFromRequest scapi.NoResultFromRequest-class.html -scapi.Playlist scapi.Playlist-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.Playlist.KIND scapi.Playlist-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.RESTBase.ALIASES scapi.RESTBase-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.RESTBase scapi.RESTBase-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.RESTBase.ALIASES scapi.RESTBase-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.KIND scapi.RESTBase-class.html#KIND -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.SCRedirectHandler scapi.SCRedirectHandler-class.html -scapi.SCRedirectHandler.alternate_method scapi.SCRedirectHandler-class.html#alternate_method -scapi.SCRedirectHandler.http_error_303 scapi.SCRedirectHandler-class.html#http_error_303 -scapi.SCRedirectHandler.http_error_201 scapi.SCRedirectHandler-class.html#http_error_201 -scapi.Scope scapi.Scope-class.html -scapi.Scope.oauth_sign_get_request scapi.Scope-class.html#oauth_sign_get_request -scapi.Scope._map scapi.Scope-class.html#_map -scapi.Scope.__str__ scapi.Scope-class.html#__str__ -scapi.Scope.__getattr__ scapi.Scope-class.html#__getattr__ -scapi.Scope._call scapi.Scope-class.html#_call -scapi.Scope._create_query_string scapi.Scope-class.html#_create_query_string -scapi.Scope._create_request scapi.Scope-class.html#_create_request -scapi.Scope._get_connector scapi.Scope-class.html#_get_connector -scapi.Scope.__init__ scapi.Scope-class.html#__init__ -scapi.Scope.__repr__ scapi.Scope-class.html#__repr__ -scapi.Track scapi.Track-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.Track.KIND scapi.Track-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.Track.ALIASES scapi.Track-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.UnknownContentType scapi.UnknownContentType-class.html -scapi.UnknownContentType.__str__ scapi.UnknownContentType-class.html#__str__ -scapi.UnknownContentType.__repr__ scapi.UnknownContentType-class.html#__repr__ -scapi.UnknownContentType.__init__ scapi.UnknownContentType-class.html#__init__ -scapi.User scapi.User-class.html -scapi.RESTBase._scope scapi.RESTBase-class.html#_scope -scapi.RESTBase.__init__ scapi.RESTBase-class.html#__init__ -scapi.User.KIND scapi.User-class.html#KIND -scapi.RESTBase.create scapi.RESTBase-class.html#create -scapi.RESTBase._as_arguments scapi.RESTBase-class.html#_as_arguments -scapi.RESTBase.__getattr__ scapi.RESTBase-class.html#__getattr__ -scapi.RESTBase.ALL_DOMAIN_CLASSES scapi.RESTBase-class.html#ALL_DOMAIN_CLASSES -scapi.RESTBase.new scapi.RESTBase-class.html#new -scapi.User.ALIASES scapi.User-class.html#ALIASES -scapi.RESTBase.__ne__ scapi.RESTBase-class.html#__ne__ -scapi.RESTBase.get scapi.RESTBase-class.html#get -scapi.RESTBase._convert_value scapi.RESTBase-class.html#_convert_value -scapi.RESTBase.__setattr__ scapi.RESTBase-class.html#__setattr__ -scapi.RESTBase._singleton scapi.RESTBase-class.html#_singleton -scapi.RESTBase.REGISTRY scapi.RESTBase-class.html#REGISTRY -scapi.RESTBase.__eq__ scapi.RESTBase-class.html#__eq__ -scapi.RESTBase.__repr__ scapi.RESTBase-class.html#__repr__ -scapi.RESTBase.__hash__ scapi.RESTBase-class.html#__hash__ -scapi.authentication.BasicAuthenticator scapi.authentication.BasicAuthenticator-class.html -scapi.authentication.BasicAuthenticator.augment_request scapi.authentication.BasicAuthenticator-class.html#augment_request -scapi.authentication.BasicAuthenticator.__init__ scapi.authentication.BasicAuthenticator-class.html#__init__ -scapi.authentication.OAuthAuthenticator scapi.authentication.OAuthAuthenticator-class.html -scapi.authentication.OAuthAuthenticator.augment_request scapi.authentication.OAuthAuthenticator-class.html#augment_request -scapi.authentication.OAuthAuthenticator.generate_nonce scapi.authentication.OAuthAuthenticator-class.html#generate_nonce -scapi.authentication.OAuthAuthenticator.OAUTH_API_VERSION scapi.authentication.OAuthAuthenticator-class.html#OAUTH_API_VERSION -scapi.authentication.OAuthAuthenticator.generate_timestamp scapi.authentication.OAuthAuthenticator-class.html#generate_timestamp -scapi.authentication.OAuthAuthenticator.AUTHORIZATION_HEADER scapi.authentication.OAuthAuthenticator-class.html#AUTHORIZATION_HEADER -scapi.authentication.OAuthAuthenticator.__init__ scapi.authentication.OAuthAuthenticator-class.html#__init__ -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1 scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.FORBIDDEN scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#FORBIDDEN -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.get_name scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#get_name -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.get_normalized_http_method scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#get_normalized_http_method -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.get_normalized_http_url scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#get_normalized_http_url -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.get_normalized_parameters scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#get_normalized_parameters -scapi.authentication.OAuthSignatureMethod_HMAC_SHA1.build_signature scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html#build_signature -scapi.json.JsonReader scapi.json.JsonReader-class.html -scapi.json.JsonReader.escapes scapi.json.JsonReader-class.html#escapes -scapi.json.JsonReader._readObject scapi.json.JsonReader-class.html#_readObject -scapi.json.JsonReader._assertNext scapi.json.JsonReader-class.html#_assertNext -scapi.json.JsonReader._readNumber scapi.json.JsonReader-class.html#_readNumber -scapi.json.JsonReader._peek scapi.json.JsonReader-class.html#_peek -scapi.json.JsonReader._readNull scapi.json.JsonReader-class.html#_readNull -scapi.json.JsonReader._hexDigitToInt scapi.json.JsonReader-class.html#_hexDigitToInt -scapi.json.JsonReader._readTrue scapi.json.JsonReader-class.html#_readTrue -scapi.json.JsonReader._readDoubleSolidusComment scapi.json.JsonReader-class.html#_readDoubleSolidusComment -scapi.json.JsonReader.read scapi.json.JsonReader-class.html#read -scapi.json.JsonReader._readFalse scapi.json.JsonReader-class.html#_readFalse -scapi.json.JsonReader.hex_digits scapi.json.JsonReader-class.html#hex_digits -scapi.json.JsonReader._readComment scapi.json.JsonReader-class.html#_readComment -scapi.json.JsonReader._readArray scapi.json.JsonReader-class.html#_readArray -scapi.json.JsonReader._eatWhitespace scapi.json.JsonReader-class.html#_eatWhitespace -scapi.json.JsonReader._read scapi.json.JsonReader-class.html#_read -scapi.json.JsonReader._readString scapi.json.JsonReader-class.html#_readString -scapi.json.JsonReader._readCStyleComment scapi.json.JsonReader-class.html#_readCStyleComment -scapi.json.JsonReader._next scapi.json.JsonReader-class.html#_next -scapi.json.JsonWriter scapi.json.JsonWriter-class.html -scapi.json.JsonWriter.write scapi.json.JsonWriter-class.html#write -scapi.json.JsonWriter._append scapi.json.JsonWriter-class.html#_append -scapi.json.JsonWriter._write scapi.json.JsonWriter-class.html#_write -scapi.json.ReadException scapi.json.ReadException-class.html -scapi.json.WriteException scapi.json.WriteException-class.html -scapi.json._StringGenerator scapi.json._StringGenerator-class.html -scapi.json._StringGenerator.peek scapi.json._StringGenerator-class.html#peek -scapi.json._StringGenerator.all scapi.json._StringGenerator-class.html#all -scapi.json._StringGenerator.next scapi.json._StringGenerator-class.html#next -scapi.json._StringGenerator.__init__ scapi.json._StringGenerator-class.html#__init__ -scapi.tests.scapi_tests.SCAPITests scapi.tests.scapi_tests.SCAPITests-class.html -scapi.tests.scapi_tests.SCAPITests._load_config scapi.tests.scapi_tests.SCAPITests-class.html#_load_config -scapi.tests.scapi_tests.SCAPITests.test_track_creation_with_artwork scapi.tests.scapi_tests.SCAPITests-class.html#test_track_creation_with_artwork -scapi.tests.scapi_tests.SCAPITests.test_upload scapi.tests.scapi_tests.SCAPITests-class.html#test_upload -scapi.tests.scapi_tests.SCAPITests.test_scoped_track_creation scapi.tests.scapi_tests.SCAPITests-class.html#test_scoped_track_creation -scapi.tests.scapi_tests.SCAPITests.test_permissions scapi.tests.scapi_tests.SCAPITests-class.html#test_permissions -scapi.tests.scapi_tests.SCAPITests.CONSUMER_SECRET scapi.tests.scapi_tests.SCAPITests-class.html#CONSUMER_SECRET -scapi.tests.scapi_tests.SCAPITests.CONSUMER scapi.tests.scapi_tests.SCAPITests-class.html#CONSUMER -scapi.tests.scapi_tests.SCAPITests.test_me_having_stress scapi.tests.scapi_tests.SCAPITests-class.html#test_me_having_stress -scapi.tests.scapi_tests.SCAPITests.USER scapi.tests.scapi_tests.SCAPITests-class.html#USER -scapi.tests.scapi_tests.SCAPITests.CONFIGSPEC scapi.tests.scapi_tests.SCAPITests-class.html#CONFIGSPEC -scapi.tests.scapi_tests.SCAPITests.test_track_creation_with_email_sharers scapi.tests.scapi_tests.SCAPITests-class.html#test_track_creation_with_email_sharers -scapi.tests.scapi_tests.SCAPITests.test_setting_comments scapi.tests.scapi_tests.SCAPITests-class.html#test_setting_comments -scapi.tests.scapi_tests.SCAPITests.test_access_token_acquisition scapi.tests.scapi_tests.SCAPITests-class.html#test_access_token_acquisition -scapi.tests.scapi_tests.SCAPITests.test_track_creation scapi.tests.scapi_tests.SCAPITests-class.html#test_track_creation -scapi.tests.scapi_tests.SCAPITests.test_groups scapi.tests.scapi_tests.SCAPITests-class.html#test_groups -scapi.tests.scapi_tests.SCAPITests.test_track_update scapi.tests.scapi_tests.SCAPITests-class.html#test_track_update -scapi.tests.scapi_tests.SCAPITests.test_modifying_playlists scapi.tests.scapi_tests.SCAPITests-class.html#test_modifying_playlists -scapi.tests.scapi_tests.SCAPITests.SECRET scapi.tests.scapi_tests.SCAPITests-class.html#SECRET -scapi.tests.scapi_tests.SCAPITests.test_oauth_get_signing scapi.tests.scapi_tests.SCAPITests-class.html#test_oauth_get_signing -scapi.tests.scapi_tests.SCAPITests.test_contact_add_and_removal scapi.tests.scapi_tests.SCAPITests-class.html#test_contact_add_and_removal -scapi.tests.scapi_tests.SCAPITests.test_connect scapi.tests.scapi_tests.SCAPITests-class.html#test_connect -scapi.tests.scapi_tests.SCAPITests.test_large_list scapi.tests.scapi_tests.SCAPITests-class.html#test_large_list -unittest.TestCase.failureException exceptions.AssertionError-class.html -scapi.tests.scapi_tests.SCAPITests.test_contact_list scapi.tests.scapi_tests.SCAPITests-class.html#test_contact_list -scapi.tests.scapi_tests.SCAPITests.test_playlists scapi.tests.scapi_tests.SCAPITests-class.html#test_playlists -scapi.tests.scapi_tests.SCAPITests.API_HOST scapi.tests.scapi_tests.SCAPITests-class.html#API_HOST -scapi.tests.scapi_tests.SCAPITests.setUp scapi.tests.scapi_tests.SCAPITests-class.html#setUp -scapi.tests.scapi_tests.SCAPITests.test_downloadable scapi.tests.scapi_tests.SCAPITests-class.html#test_downloadable -scapi.tests.scapi_tests.SCAPITests.TOKEN scapi.tests.scapi_tests.SCAPITests-class.html#TOKEN -scapi.tests.scapi_tests.SCAPITests.test_events scapi.tests.scapi_tests.SCAPITests-class.html#test_events -scapi.tests.scapi_tests.SCAPITests.test_non_global_api scapi.tests.scapi_tests.SCAPITests-class.html#test_non_global_api -scapi.tests.scapi_tests.SCAPITests.PASSWORD scapi.tests.scapi_tests.SCAPITests-class.html#PASSWORD -scapi.tests.scapi_tests.SCAPITests.test_setting_comments_the_way_shawn_says_its_correct scapi.tests.scapi_tests.SCAPITests-class.html#test_setting_comments_the_way_shawn_says_its_correct -scapi.tests.scapi_tests.SCAPITests.CONFIG_NAME scapi.tests.scapi_tests.SCAPITests-class.html#CONFIG_NAME -scapi.tests.scapi_tests.SCAPITests.test_setting_permissions scapi.tests.scapi_tests.SCAPITests-class.html#test_setting_permissions -scapi.tests.scapi_tests.SCAPITests.RUN_INTERACTIVE_TESTS scapi.tests.scapi_tests.SCAPITests-class.html#RUN_INTERACTIVE_TESTS -scapi.tests.scapi_tests.SCAPITests.test_favorites scapi.tests.scapi_tests.SCAPITests-class.html#test_favorites -scapi.tests.scapi_tests.SCAPITests.test_track_creation_with_updated_artwork scapi.tests.scapi_tests.SCAPITests-class.html#test_track_creation_with_updated_artwork -scapi.tests.scapi_tests.SCAPITests.AUTHENTICATOR scapi.tests.scapi_tests.SCAPITests-class.html#AUTHENTICATOR -scapi.tests.scapi_tests.SCAPITests.test_streaming scapi.tests.scapi_tests.SCAPITests-class.html#test_streaming -scapi.tests.scapi_tests.SCAPITests.test_playlist_creation scapi.tests.scapi_tests.SCAPITests-class.html#test_playlist_creation -scapi.tests.scapi_tests.SCAPITests.test_track_deletion scapi.tests.scapi_tests.SCAPITests-class.html#test_track_deletion -scapi.tests.scapi_tests.SCAPITests.test_filtered_list scapi.tests.scapi_tests.SCAPITests-class.html#test_filtered_list -scapi.tests.scapi_tests.SCAPITests.root scapi.tests.scapi_tests.SCAPITests-class.html#root -scapi.util.MultiDict scapi.util.MultiDict-class.html -scapi.util.MultiDict.add scapi.util.MultiDict-class.html#add -scapi.util.MultiDict.iteritemslist scapi.util.MultiDict-class.html#iteritemslist diff --git a/python_apps/soundcloud-api/docs/api/class-tree.html b/python_apps/soundcloud-api/docs/api/class-tree.html deleted file mode 100644 index b2473382f..000000000 --- a/python_apps/soundcloud-api/docs/api/class-tree.html +++ /dev/null @@ -1,216 +0,0 @@ - - - - - Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - - -
[hide private]
[frames] | no frames]
-
-
- [ Module Hierarchy - | Class Hierarchy ] -

-

Class Hierarchy

- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/crarr.png b/python_apps/soundcloud-api/docs/api/crarr.png deleted file mode 100644 index 26b43c52433b71e72a9a478c52d446278335f0e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^f?NMQuI$%1#8??M1uoZK z0}62#ctjR6FvuMOVaB`*rFK9;mUKs7M+SzC{oH>NS%G}l0G|-o|NsA=J-p%i`2!7U zCdJ_j4{u-SDsoA1U`TRixpVcz%O`iHHAYk?=&YaLkmD!Pp6~GW^M_S4D^grJKD>P~ zuPf!ku`N^TLavn`Edv_JSQ6wH%;50sMjDXg>*?YcQgJIe!GUqln>_|<+Os&OOUQS1 zY~Wzutud*iVS#|PHMc&?2WHoZpEo8l+6!Oc$x~=%U)469Gl^f?nq7UBw#1AXkrEde cmFKWBXcRFE*(?@T0vgQV>FVdQ&MBb@0LpZ4r2qf` diff --git a/python_apps/soundcloud-api/docs/api/epydoc.css b/python_apps/soundcloud-api/docs/api/epydoc.css deleted file mode 100644 index 86d417068..000000000 --- a/python_apps/soundcloud-api/docs/api/epydoc.css +++ /dev/null @@ -1,322 +0,0 @@ - - -/* Epydoc CSS Stylesheet - * - * This stylesheet can be used to customize the appearance of epydoc's - * HTML output. - * - */ - -/* Default Colors & Styles - * - Set the default foreground & background color with 'body'; and - * link colors with 'a:link' and 'a:visited'. - * - Use bold for decision list terms. - * - The heading styles defined here are used for headings *within* - * docstring descriptions. All headings used by epydoc itself use - * either class='epydoc' or class='toc' (CSS styles for both - * defined below). - */ -body { background: #ffffff; color: #000000; } -p { margin-top: 0.5em; margin-bottom: 0.5em; } -a:link { color: #0000ff; } -a:visited { color: #204080; } -dt { font-weight: bold; } -h1 { font-size: +140%; font-style: italic; - font-weight: bold; } -h2 { font-size: +125%; font-style: italic; - font-weight: bold; } -h3 { font-size: +110%; font-style: italic; - font-weight: normal; } -code { font-size: 100%; } -/* N.B.: class, not pseudoclass */ -a.link { font-family: monospace; } - -/* Page Header & Footer - * - The standard page header consists of a navigation bar (with - * pointers to standard pages such as 'home' and 'trees'); a - * breadcrumbs list, which can be used to navigate to containing - * classes or modules; options links, to show/hide private - * variables and to show/hide frames; and a page title (using - *

). The page title may be followed by a link to the - * corresponding source code (using 'span.codelink'). - * - The footer consists of a navigation bar, a timestamp, and a - * pointer to epydoc's homepage. - */ -h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } -h2.epydoc { font-size: +130%; font-weight: bold; } -h3.epydoc { font-size: +115%; font-weight: bold; - margin-top: 0.2em; } -td h3.epydoc { font-size: +115%; font-weight: bold; - margin-bottom: 0; } -table.navbar { background: #a0c0ff; color: #000000; - border: 2px groove #c0d0d0; } -table.navbar table { color: #000000; } -th.navbar-select { background: #70b0ff; - color: #000000; } -table.navbar a { text-decoration: none; } -table.navbar a:link { color: #0000ff; } -table.navbar a:visited { color: #204080; } -span.breadcrumbs { font-size: 85%; font-weight: bold; } -span.options { font-size: 70%; } -span.codelink { font-size: 85%; } -td.footer { font-size: 85%; } - -/* Table Headers - * - Each summary table and details section begins with a 'header' - * row. This row contains a section title (marked by - * 'span.table-header') as well as a show/hide private link - * (marked by 'span.options', defined above). - * - Summary tables that contain user-defined groups mark those - * groups using 'group header' rows. - */ -td.table-header { background: #70b0ff; color: #000000; - border: 1px solid #608090; } -td.table-header table { color: #000000; } -td.table-header table a:link { color: #0000ff; } -td.table-header table a:visited { color: #204080; } -span.table-header { font-size: 120%; font-weight: bold; } -th.group-header { background: #c0e0f8; color: #000000; - text-align: left; font-style: italic; - font-size: 115%; - border: 1px solid #608090; } - -/* Summary Tables (functions, variables, etc) - * - Each object is described by a single row of the table with - * two cells. The left cell gives the object's type, and is - * marked with 'code.summary-type'. The right cell gives the - * object's name and a summary description. - * - CSS styles for the table's header and group headers are - * defined above, under 'Table Headers' - */ -table.summary { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin-bottom: 0.5em; } -td.summary { border: 1px solid #608090; } -code.summary-type { font-size: 85%; } -table.summary a:link { color: #0000ff; } -table.summary a:visited { color: #204080; } - - -/* Details Tables (functions, variables, etc) - * - Each object is described in its own div. - * - A single-row summary table w/ table-header is used as - * a header for each details section (CSS style for table-header - * is defined above, under 'Table Headers'). - */ -table.details { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin: .2em 0 0 0; } -table.details table { color: #000000; } -table.details a:link { color: #0000ff; } -table.details a:visited { color: #204080; } - -/* Fields */ -dl.fields { margin-left: 2em; margin-top: 1em; - margin-bottom: 1em; } -dl.fields dd ul { margin-left: 0em; padding-left: 0em; } -dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } -div.fields { margin-left: 2em; } -div.fields p { margin-bottom: 0.5em; } - -/* Index tables (identifier index, term index, etc) - * - link-index is used for indices containing lists of links - * (namely, the identifier index & term index). - * - index-where is used in link indices for the text indicating - * the container/source for each link. - * - metadata-index is used for indices containing metadata - * extracted from fields (namely, the bug index & todo index). - */ -table.link-index { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; } -td.link-index { border-width: 0px; } -table.link-index a:link { color: #0000ff; } -table.link-index a:visited { color: #204080; } -span.index-where { font-size: 70%; } -table.metadata-index { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin: .2em 0 0 0; } -td.metadata-index { border-width: 1px; border-style: solid; } -table.metadata-index a:link { color: #0000ff; } -table.metadata-index a:visited { color: #204080; } - -/* Function signatures - * - sig* is used for the signature in the details section. - * - .summary-sig* is used for the signature in the summary - * table, and when listing property accessor functions. - * */ -.sig-name { color: #006080; } -.sig-arg { color: #008060; } -.sig-default { color: #602000; } -.summary-sig { font-family: monospace; } -.summary-sig-name { color: #006080; font-weight: bold; } -table.summary a.summary-sig-name:link - { color: #006080; font-weight: bold; } -table.summary a.summary-sig-name:visited - { color: #006080; font-weight: bold; } -.summary-sig-arg { color: #006040; } -.summary-sig-default { color: #501800; } - -/* Subclass list - */ -ul.subclass-list { display: inline; } -ul.subclass-list li { display: inline; } - -/* To render variables, classes etc. like functions */ -table.summary .summary-name { color: #006080; font-weight: bold; - font-family: monospace; } -table.summary - a.summary-name:link { color: #006080; font-weight: bold; - font-family: monospace; } -table.summary - a.summary-name:visited { color: #006080; font-weight: bold; - font-family: monospace; } - -/* Variable values - * - In the 'variable details' sections, each varaible's value is - * listed in a 'pre.variable' box. The width of this box is - * restricted to 80 chars; if the value's repr is longer than - * this it will be wrapped, using a backslash marked with - * class 'variable-linewrap'. If the value's repr is longer - * than 3 lines, the rest will be ellided; and an ellipsis - * marker ('...' marked with 'variable-ellipsis') will be used. - * - If the value is a string, its quote marks will be marked - * with 'variable-quote'. - * - If the variable is a regexp, it is syntax-highlighted using - * the re* CSS classes. - */ -pre.variable { padding: .5em; margin: 0; - background: #dce4ec; color: #000000; - border: 1px solid #708890; } -.variable-linewrap { color: #604000; font-weight: bold; } -.variable-ellipsis { color: #604000; font-weight: bold; } -.variable-quote { color: #604000; font-weight: bold; } -.variable-group { color: #008000; font-weight: bold; } -.variable-op { color: #604000; font-weight: bold; } -.variable-string { color: #006030; } -.variable-unknown { color: #a00000; font-weight: bold; } -.re { color: #000000; } -.re-char { color: #006030; } -.re-op { color: #600000; } -.re-group { color: #003060; } -.re-ref { color: #404040; } - -/* Base tree - * - Used by class pages to display the base class hierarchy. - */ -pre.base-tree { font-size: 80%; margin: 0; } - -/* Frames-based table of contents headers - * - Consists of two frames: one for selecting modules; and - * the other listing the contents of the selected module. - * - h1.toc is used for each frame's heading - * - h2.toc is used for subheadings within each frame. - */ -h1.toc { text-align: center; font-size: 105%; - margin: 0; font-weight: bold; - padding: 0; } -h2.toc { font-size: 100%; font-weight: bold; - margin: 0.5em 0 0 -0.3em; } - -/* Syntax Highlighting for Source Code - * - doctest examples are displayed in a 'pre.py-doctest' block. - * If the example is in a details table entry, then it will use - * the colors specified by the 'table pre.py-doctest' line. - * - Source code listings are displayed in a 'pre.py-src' block. - * Each line is marked with 'span.py-line' (used to draw a line - * down the left margin, separating the code from the line - * numbers). Line numbers are displayed with 'span.py-lineno'. - * The expand/collapse block toggle button is displayed with - * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not - * modify the font size of the text.) - * - If a source code page is opened with an anchor, then the - * corresponding code block will be highlighted. The code - * block's header is highlighted with 'py-highlight-hdr'; and - * the code block's body is highlighted with 'py-highlight'. - * - The remaining py-* classes are used to perform syntax - * highlighting (py-string for string literals, py-name for names, - * etc.) - */ -pre.py-doctest { padding: .5em; margin: 1em; - background: #e8f0f8; color: #000000; - border: 1px solid #708890; } -table pre.py-doctest { background: #dce4ec; - color: #000000; } -pre.py-src { border: 2px solid #000000; - background: #f0f0f0; color: #000000; } -.py-line { border-left: 2px solid #000000; - margin-left: .2em; padding-left: .4em; } -.py-lineno { font-style: italic; font-size: 90%; - padding-left: .5em; } -a.py-toggle { text-decoration: none; } -div.py-highlight-hdr { border-top: 2px solid #000000; - border-bottom: 2px solid #000000; - background: #d8e8e8; } -div.py-highlight { border-bottom: 2px solid #000000; - background: #d0e0e0; } -.py-prompt { color: #005050; font-weight: bold;} -.py-more { color: #005050; font-weight: bold;} -.py-string { color: #006030; } -.py-comment { color: #003060; } -.py-keyword { color: #600000; } -.py-output { color: #404040; } -.py-name { color: #000050; } -.py-name:link { color: #000050 !important; } -.py-name:visited { color: #000050 !important; } -.py-number { color: #005000; } -.py-defname { color: #000060; font-weight: bold; } -.py-def-name { color: #000060; font-weight: bold; } -.py-base-class { color: #000060; } -.py-param { color: #000060; } -.py-docstring { color: #006030; } -.py-decorator { color: #804020; } -/* Use this if you don't want links to names underlined: */ -/*a.py-name { text-decoration: none; }*/ - -/* Graphs & Diagrams - * - These CSS styles are used for graphs & diagrams generated using - * Graphviz dot. 'img.graph-without-title' is used for bare - * diagrams (to remove the border created by making the image - * clickable). - */ -img.graph-without-title { border: none; } -img.graph-with-title { border: 1px solid #000000; } -span.graph-title { font-weight: bold; } -span.graph-caption { } - -/* General-purpose classes - * - 'p.indent-wrapped-lines' defines a paragraph whose first line - * is not indented, but whose subsequent lines are. - * - The 'nomargin-top' class is used to remove the top margin (e.g. - * from lists). The 'nomargin' class is used to remove both the - * top and bottom margin (but not the left or right margin -- - * for lists, that would cause the bullets to disappear.) - */ -p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; - margin: 0; } -.nomargin-top { margin-top: 0; } -.nomargin { margin-top: 0; margin-bottom: 0; } - -/* HTML Log */ -div.log-block { padding: 0; margin: .5em 0 .5em 0; - background: #e8f0f8; color: #000000; - border: 1px solid #000000; } -div.log-error { padding: .1em .3em .1em .3em; margin: 4px; - background: #ffb0b0; color: #000000; - border: 1px solid #000000; } -div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; - background: #ffffb0; color: #000000; - border: 1px solid #000000; } -div.log-info { padding: .1em .3em .1em .3em; margin: 4px; - background: #b0ffb0; color: #000000; - border: 1px solid #000000; } -h2.log-hdr { background: #70b0ff; color: #000000; - margin: 0; padding: 0em 0.5em 0em 0.5em; - border-bottom: 1px solid #000000; font-size: 110%; } -p.log { font-weight: bold; margin: .5em 0 .5em 0; } -tr.opt-changed { color: #000000; font-weight: bold; } -tr.opt-default { color: #606060; } -pre.log { margin: 0; padding: 0; padding-left: 1em; } diff --git a/python_apps/soundcloud-api/docs/api/epydoc.js b/python_apps/soundcloud-api/docs/api/epydoc.js deleted file mode 100644 index e787dbcf4..000000000 --- a/python_apps/soundcloud-api/docs/api/epydoc.js +++ /dev/null @@ -1,293 +0,0 @@ -function toggle_private() { - // Search for any private/public links on this page. Store - // their old text in "cmd," so we will know what action to - // take; and change their text to the opposite action. - var cmd = "?"; - var elts = document.getElementsByTagName("a"); - for(var i=0; i...
"; - elt.innerHTML = s; - } -} - -function toggle(id) { - elt = document.getElementById(id+"-toggle"); - if (elt.innerHTML == "-") - collapse(id); - else - expand(id); - return false; -} - -function highlight(id) { - var elt = document.getElementById(id+"-def"); - if (elt) elt.className = "py-highlight-hdr"; - var elt = document.getElementById(id+"-expanded"); - if (elt) elt.className = "py-highlight"; - var elt = document.getElementById(id+"-collapsed"); - if (elt) elt.className = "py-highlight"; -} - -function num_lines(s) { - var n = 1; - var pos = s.indexOf("\n"); - while ( pos > 0) { - n += 1; - pos = s.indexOf("\n", pos+1); - } - return n; -} - -// Collapse all blocks that mave more than `min_lines` lines. -function collapse_all(min_lines) { - var elts = document.getElementsByTagName("div"); - for (var i=0; i 0) - if (elt.id.substring(split, elt.id.length) == "-expanded") - if (num_lines(elt.innerHTML) > min_lines) - collapse(elt.id.substring(0, split)); - } -} - -function expandto(href) { - var start = href.indexOf("#")+1; - if (start != 0 && start != href.length) { - if (href.substring(start, href.length) != "-") { - collapse_all(4); - pos = href.indexOf(".", start); - while (pos != -1) { - var id = href.substring(start, pos); - expand(id); - pos = href.indexOf(".", pos+1); - } - var id = href.substring(start, href.length); - expand(id); - highlight(id); - } - } -} - -function kill_doclink(id) { - var parent = document.getElementById(id); - parent.removeChild(parent.childNodes.item(0)); -} -function auto_kill_doclink(ev) { - if (!ev) var ev = window.event; - if (!this.contains(ev.toElement)) { - var parent = document.getElementById(this.parentID); - parent.removeChild(parent.childNodes.item(0)); - } -} - -function doclink(id, name, targets_id) { - var elt = document.getElementById(id); - - // If we already opened the box, then destroy it. - // (This case should never occur, but leave it in just in case.) - if (elt.childNodes.length > 1) { - elt.removeChild(elt.childNodes.item(0)); - } - else { - // The outer box: relative + inline positioning. - var box1 = document.createElement("div"); - box1.style.position = "relative"; - box1.style.display = "inline"; - box1.style.top = 0; - box1.style.left = 0; - - // A shadow for fun - var shadow = document.createElement("div"); - shadow.style.position = "absolute"; - shadow.style.left = "-1.3em"; - shadow.style.top = "-1.3em"; - shadow.style.background = "#404040"; - - // The inner box: absolute positioning. - var box2 = document.createElement("div"); - box2.style.position = "relative"; - box2.style.border = "1px solid #a0a0a0"; - box2.style.left = "-.2em"; - box2.style.top = "-.2em"; - box2.style.background = "white"; - box2.style.padding = ".3em .4em .3em .4em"; - box2.style.fontStyle = "normal"; - box2.onmouseout=auto_kill_doclink; - box2.parentID = id; - - // Get the targets - var targets_elt = document.getElementById(targets_id); - var targets = targets_elt.getAttribute("targets"); - var links = ""; - target_list = targets.split(","); - for (var i=0; i" + - target[0] + ""; - } - - // Put it all together. - elt.insertBefore(box1, elt.childNodes.item(0)); - //box1.appendChild(box2); - box1.appendChild(shadow); - shadow.appendChild(box2); - box2.innerHTML = - "Which "+name+" do you want to see documentation for?" + - ""; - } - return false; -} - -function get_anchor() { - var href = location.href; - var start = href.indexOf("#")+1; - if ((start != 0) && (start != href.length)) - return href.substring(start, href.length); - } -function redirect_url(dottedName) { - // Scan through each element of the "pages" list, and check - // if "name" matches with any of them. - for (var i=0; i-m" or "-c"; - // extract the portion & compare it to dottedName. - var pagename = pages[i].substring(0, pages[i].length-2); - if (pagename == dottedName.substring(0,pagename.length)) { - - // We've found a page that matches `dottedName`; - // construct its URL, using leftover `dottedName` - // content to form an anchor. - var pagetype = pages[i].charAt(pages[i].length-1); - var url = pagename + ((pagetype=="m")?"-module.html": - "-class.html"); - if (dottedName.length > pagename.length) - url += "#" + dottedName.substring(pagename.length+1, - dottedName.length); - return url; - } - } - } diff --git a/python_apps/soundcloud-api/docs/api/exceptions.AssertionError-class.html b/python_apps/soundcloud-api/docs/api/exceptions.AssertionError-class.html deleted file mode 100644 index 2dbca8db5..000000000 --- a/python_apps/soundcloud-api/docs/api/exceptions.AssertionError-class.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - exceptions.AssertionError - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - exceptions :: - AssertionError :: - Class AssertionError - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class AssertionError

-
-   object --+            
-            |            
-BaseException --+        
-                |        
-        Exception --+    
-                    |    
-        StandardError --+
-                        |
-                       AssertionError
-
- -
-

Assertion failed.

- - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(...)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- - -
- -
- a new object with type S, a subtype of T - - - - - - -
__new__(T, - S, - ...) - - -
- -
-

Inherited from BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __repr__, - __setattr__, - __setstate__, - __str__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(...) -
(Constructor) -

-
  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
-
-
-
- -
- -
- - -
-

__new__(T, - S, - ...) -

-
  -
- - -
-
Returns: a new object with type S, a subtype of T
-
Overrides: - object.__new__ -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/frames.html b/python_apps/soundcloud-api/docs/api/frames.html deleted file mode 100644 index 6d0191e9d..000000000 --- a/python_apps/soundcloud-api/docs/api/frames.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - SoundCloud API - - - - - - - - - diff --git a/python_apps/soundcloud-api/docs/api/help.html b/python_apps/soundcloud-api/docs/api/help.html deleted file mode 100644 index ff7d397f2..000000000 --- a/python_apps/soundcloud-api/docs/api/help.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - Help - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - - -
[hide private]
[frames] | no frames]
-
- -

API Documentation

- -

This document contains the API (Application Programming Interface) -documentation for SoundCloud API. Documentation for the Python -objects defined by the project is divided into separate pages for each -package, module, and class. The API documentation also includes two -pages containing information about the project as a whole: a trees -page, and an index page.

- -

Object Documentation

- -

Each Package Documentation page contains:

-
    -
  • A description of the package.
  • -
  • A list of the modules and sub-packages contained by the - package.
  • -
  • A summary of the classes defined by the package.
  • -
  • A summary of the functions defined by the package.
  • -
  • A summary of the variables defined by the package.
  • -
  • A detailed description of each function defined by the - package.
  • -
  • A detailed description of each variable defined by the - package.
  • -
- -

Each Module Documentation page contains:

-
    -
  • A description of the module.
  • -
  • A summary of the classes defined by the module.
  • -
  • A summary of the functions defined by the module.
  • -
  • A summary of the variables defined by the module.
  • -
  • A detailed description of each function defined by the - module.
  • -
  • A detailed description of each variable defined by the - module.
  • -
- -

Each Class Documentation page contains:

-
    -
  • A class inheritance diagram.
  • -
  • A list of known subclasses.
  • -
  • A description of the class.
  • -
  • A summary of the methods defined by the class.
  • -
  • A summary of the instance variables defined by the class.
  • -
  • A summary of the class (static) variables defined by the - class.
  • -
  • A detailed description of each method defined by the - class.
  • -
  • A detailed description of each instance variable defined by the - class.
  • -
  • A detailed description of each class (static) variable defined - by the class.
  • -
- -

Project Documentation

- -

The Trees page contains the module and class hierarchies:

-
    -
  • The module hierarchy lists every package and module, with - modules grouped into packages. At the top level, and within each - package, modules and sub-packages are listed alphabetically.
  • -
  • The class hierarchy lists every class, grouped by base - class. If a class has more than one base class, then it will be - listed under each base class. At the top level, and under each base - class, classes are listed alphabetically.
  • -
- -

The Index page contains indices of terms and - identifiers:

-
    -
  • The term index lists every term indexed by any object's - documentation. For each term, the index provides links to each - place where the term is indexed.
  • -
  • The identifier index lists the (short) name of every package, - module, class, method, function, variable, and parameter. For each - identifier, the index provides a short description, and a link to - its documentation.
  • -
- -

The Table of Contents

- -

The table of contents occupies the two frames on the left side of -the window. The upper-left frame displays the project -contents, and the lower-left frame displays the module -contents:

- - - - - - - - - -
- Project
Contents
...
- API
Documentation
Frame


-
- Module
Contents
 
...
  -

- -

The project contents frame contains a list of all packages -and modules that are defined by the project. Clicking on an entry -will display its contents in the module contents frame. Clicking on a -special entry, labeled "Everything," will display the contents of -the entire project.

- -

The module contents frame contains a list of every -submodule, class, type, exception, function, and variable defined by a -module or package. Clicking on an entry will display its -documentation in the API documentation frame. Clicking on the name of -the module, at the top of the frame, will display the documentation -for the module itself.

- -

The "frames" and "no frames" buttons below the top -navigation bar can be used to control whether the table of contents is -displayed or not.

- -

The Navigation Bar

- -

A navigation bar is located at the top and bottom of every page. -It indicates what type of page you are currently viewing, and allows -you to go to related pages. The following table describes the labels -on the navigation bar. Note that not some labels (such as -[Parent]) are not displayed on all pages.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LabelHighlighted when...Links to...
[Parent](never highlighted) the parent of the current package
[Package]viewing a packagethe package containing the current object -
[Module]viewing a modulethe module containing the current object -
[Class]viewing a class the class containing the current object
[Trees]viewing the trees page the trees page
[Index]viewing the index page the index page
[Help]viewing the help page the help page
- -

The "show private" and "hide private" buttons below -the top navigation bar can be used to control whether documentation -for private objects is displayed. Private objects are usually defined -as objects whose (short) names begin with a single underscore, but do -not end with an underscore. For example, "_x", -"__pprint", and "epydoc.epytext._tokenize" -are private objects; but "re.sub", -"__init__", and "type_" are not. However, -if a module defines the "__all__" variable, then its -contents are used to decide which objects are private.

- -

A timestamp below the bottom navigation bar indicates when each -page was last updated.

- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/identifier-index.html b/python_apps/soundcloud-api/docs/api/identifier-index.html deleted file mode 100644 index 94e006634..000000000 --- a/python_apps/soundcloud-api/docs/api/identifier-index.html +++ /dev/null @@ -1,892 +0,0 @@ - - - - - Identifier Index - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - - -
[hide private]
[frames] | no frames]
-
- -
-

Identifier Index

-
-[ - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z - _ -] -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

B

- - - - - - - - -

C

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

E

- - - - - - - - -

F

- - - - - - - - -

G

- - - - - - - - - - - - - - - - - -

H

- - - - - - - - -

I

- - - - - - - - -

J

- - - - - - - - -

K

- - - - - - - - - - - - - - - - - -

L

- - - - - - - - - - - - - - - - - -

M

- - - - - - - - -

N

- - - - - - - - - - - - -

O

- - - - - - - - - - - - -

P

- - - - - - - - - - - - -

R

- - - - - - - - - - - - - - - - - - - - - - -

S

- - - - - - - - - - - - - - - - - - - - - - -

T

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

U

- - - - - - - - - - - - - - - - - -

W

- - - - - - - - -

_

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/index.html b/python_apps/soundcloud-api/docs/api/index.html deleted file mode 100644 index 6d0191e9d..000000000 --- a/python_apps/soundcloud-api/docs/api/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - SoundCloud API - - - - - - - - - diff --git a/python_apps/soundcloud-api/docs/api/module-tree.html b/python_apps/soundcloud-api/docs/api/module-tree.html deleted file mode 100644 index bf467d991..000000000 --- a/python_apps/soundcloud-api/docs/api/module-tree.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - Module Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - - -
[hide private]
[frames] | no frames]
-
-
- [ Module Hierarchy - | Class Hierarchy ] -

-

Module Hierarchy

- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/redirect.html b/python_apps/soundcloud-api/docs/api/redirect.html deleted file mode 100644 index 8ac436448..000000000 --- a/python_apps/soundcloud-api/docs/api/redirect.html +++ /dev/null @@ -1,38 +0,0 @@ -Epydoc Redirect Page - - - - - - - - -

Epydoc Auto-redirect page

- -

When javascript is enabled, this page will redirect URLs of -the form redirect.html#dotted.name to the -documentation for the object with the given fully-qualified -dotted name.

-

 

- - - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi-module.html b/python_apps/soundcloud-api/docs/api/scapi-module.html deleted file mode 100644 index e63c5dac9..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi-module.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - scapi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Package scapi

source code

- - - - - - - -
- - - - - -
Submodules[hide private]
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Classes[hide private]
-
-   - - ApiConnector
- The ApiConnector holds all the data necessary to authenticate - against the soundcloud-api. -
-   - - Comment
- A comment domain object/resource. -
-   - - Event
- A event domain object/resource. -
-   - - Group
- A group domain object/resource -
-   - - InvalidMethodException -
-   - - NoResultFromRequest -
-   - - Playlist
- A playlist/set domain object/resource -
-   - - RESTBase
- The baseclass for all our domain-objects/resources. -
-   - - SCRedirectHandler
- A urllib2-Handler to deal with the redirects the RESTful API of SC - uses. -
-   - - Scope
- The basic means to query and create resources. -
-   - - Track
- A track domain object/resource. -
-   - - UnknownContentType -
-   - - User
- A user domain object/resource. -
- - - - - - - - - -
- - - - - -
Functions[hide private]
-
-   - - - - - - -
register_classes() - source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Variables[hide private]
-
-   - - ACCESS_TOKEN_URL = 'http://api.soundcloud.com/oauth/ac...
- The url Soundcould offers to make users authorize a concrete request - token. -
-   - - AUTHORIZATION_URL = 'http://api.soundcloud.com/oauth/a... -
-   - - PROXY = ''
- The url Soundcould offers to obtain request-tokens -
-   - - REQUEST_TOKEN_URL = 'http://api.soundcloud.com/oauth/r...
- The url Soundcould offers to exchange access-tokens for - request-tokens. -
-   - - USE_PROXY = False
- Something like http://127.0.0.1:10000/ -
-   - - logger = logging.getLogger("scapi") -
- - - - - - -
- - - - - -
Variables Details[hide private]
-
- -
- -
-

ACCESS_TOKEN_URL

-

The url Soundcould offers to make users authorize a concrete request - token.

-
-
-
-
Value:
-
-'http://api.soundcloud.com/oauth/access_token'
-
-
-
-
-
- -
- -
-

AUTHORIZATION_URL

- -
-
-
-
Value:
-
-'http://api.soundcloud.com/oauth/authorize'
-
-
-
-
-
- -
- -
-

REQUEST_TOKEN_URL

-

The url Soundcould offers to exchange access-tokens for - request-tokens.

-
-
-
-
Value:
-
-'http://api.soundcloud.com/oauth/request_token'
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi-pysrc.html deleted file mode 100644 index 73d83533b..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi-pysrc.html +++ /dev/null @@ -1,1263 +0,0 @@ - - - - - scapi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Package scapi

-
-  1  ##    SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful 
-  2  ##    API 
-  3  ## 
-  4  ##    Copyright (C) 2008  Diez B. Roggisch 
-  5  ##    Contact mailto:deets@soundcloud.com 
-  6  ## 
-  7  ##    This library is free software; you can redistribute it and/or 
-  8  ##    modify it under the terms of the GNU Lesser General Public 
-  9  ##    License as published by the Free Software Foundation; either 
- 10  ##    version 2.1 of the License, or (at your option) any later version. 
- 11  ## 
- 12  ##    This library is distributed in the hope that it will be useful, 
- 13  ##    but WITHOUT ANY WARRANTY; without even the implied warranty of 
- 14  ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
- 15  ##    Lesser General Public License for more details. 
- 16  ## 
- 17  ##    You should have received a copy of the GNU Lesser General Public 
- 18  ##    License along with this library; if not, write to the Free Software 
- 19  ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- 20   
- 21  import urllib 
- 22  import urllib2 
- 23   
- 24  import logging 
- 25  import simplejson 
- 26  import cgi 
- 27  from scapi.MultipartPostHandler import MultipartPostHandler 
- 28  from inspect import isclass 
- 29  import urlparse 
- 30  from scapi.authentication import BasicAuthenticator 
- 31  from scapi.util import ( 
- 32      escape, 
- 33      MultiDict, 
- 34      ) 
- 35   
- 36  logging.basicConfig() 
- 37  logger = logging.getLogger(__name__) 
- 38   
- 39  USE_PROXY = False 
- 40  """ 
- 41  Something like http://127.0.0.1:10000/ 
- 42  """ 
- 43  PROXY = '' 
- 44   
- 45   
- 46   
- 47  """ 
- 48  The url Soundcould offers to obtain request-tokens 
- 49  """ 
- 50  REQUEST_TOKEN_URL = 'http://api.soundcloud.com/oauth/request_token' 
- 51  """ 
- 52  The url Soundcould offers to exchange access-tokens for request-tokens. 
- 53  """ 
- 54  ACCESS_TOKEN_URL = 'http://api.soundcloud.com/oauth/access_token' 
- 55  """ 
- 56  The url Soundcould offers to make users authorize a concrete request token. 
- 57  """ 
- 58  AUTHORIZATION_URL = 'http://api.soundcloud.com/oauth/authorize' 
- 59   
- 60  __all__ = ['SoundCloudAPI', 'USE_PROXY', 'PROXY', 'REQUEST_TOKEN_URL', 'ACCESS_TOKEN_URL', 'AUTHORIZATION_URL'] 
-
61 - 62 - 63 -class NoResultFromRequest(Exception): -
64 pass -
65 -
66 -class InvalidMethodException(Exception): -
67 -
68 - def __init__(self, message): -
69 self._message = message - 70 Exception.__init__(self) -
71 -
72 - def __repr__(self): -
73 res = Exception.__repr__(self) - 74 res += "\n" - 75 res += "-" * 10 - 76 res += "\nmessage:\n\n" - 77 res += self._message - 78 return res -
79 -
80 -class UnknownContentType(Exception): -
81 - def __init__(self, msg): -
82 Exception.__init__(self) - 83 self._msg = msg -
84 -
85 - def __repr__(self): -
86 return self.__class__.__name__ + ":" + self._msg -
87 -
88 - def __str__(self): -
89 return str(self) -
90 -
91 - 92 -class ApiConnector(object): -
93 """ - 94 The ApiConnector holds all the data necessary to authenticate against - 95 the soundcloud-api. You can instantiate several connectors if you like, but usually one - 96 should be sufficient. - 97 """ - 98 - 99 """ -100 SoundClound imposes a maximum on the number of returned items. This value is that -101 maximum. -102 """ -103 LIST_LIMIT = 50 -104 -105 """ -106 The query-parameter that is used to request results beginning from a certain offset. -107 """ -108 LIST_OFFSET_PARAMETER = 'offset' -109 """ -110 The query-parameter that is used to request results being limited to a certain amount. -111 -112 Currently this is of no use and just for completeness sake. -113 """ -114 LIST_LIMIT_PARAMETER = 'limit' -115 -
116 - def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): -
117 """ -118 Constructor for the API-Singleton. Use it once with parameters, and then the -119 subsequent calls internal to the API will work. -120 -121 @type host: str -122 @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use -123 "api.soundcloud.com:1234" -124 @type user: str -125 @param user: if given, the username for basic HTTP authentication -126 @type password: str -127 @param password: if the user is given, you have to give a password as well -128 @type authenticator: OAuthAuthenticator | BasicAuthenticator -129 @param authenticator: the authenticator to use, see L{scapi.authentication} -130 """ -131 self.host = host -132 if authenticator is not None: -133 self.authenticator = authenticator -134 elif user is not None and password is not None: -135 self.authenticator = BasicAuthenticator(user, password) -136 self._base = base -137 self.collapse_scope = collapse_scope -
138 -
139 - def normalize_method(self, method): -
140 """ -141 This method will take a method that has been part of a redirect of some sort -142 and see if it's valid, which means that it's located beneath our base. -143 If yes, we return it normalized without that very base. -144 """ -145 _, _, path, _, _, _ = urlparse.urlparse(method) -146 if path.startswith("/"): -147 path = path[1:] -148 # if the base is "", we return the whole path, -149 # otherwise normalize it away -150 if self._base == "": -151 return path -152 if path.startswith(self._base): -153 return path[len(self._base)-1:] -154 raise InvalidMethodException("Not a valid API method: %s" % method) -
155 -156 -157 -
158 - def fetch_request_token(self, url=None, oauth_callback="oob", oauth_verifier=None): -
159 """ -160 Helper-function for a registered consumer to obtain a request token, as -161 used by oauth. -162 -163 Use it like this: -164 -165 >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, -166 CONSUMER_SECRET, -167 None, -168 None) -169 -170 >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) -171 >>> token, secret = sca.fetch_request_token() -172 >>> authorization_url = sca.get_request_token_authorization_url(token) -173 -174 Please note the None passed as token & secret to the authenticator. -175 """ -176 if url is None: -177 url = REQUEST_TOKEN_URL -178 req = urllib2.Request(url) -179 self.authenticator.augment_request(req, None, oauth_callback=oauth_callback, oauth_verifier=oauth_verifier) -180 handlers = [] -181 if USE_PROXY: -182 handlers.append(urllib2.ProxyHandler({'http' : PROXY})) -183 opener = urllib2.build_opener(*handlers) -184 handle = opener.open(req, None) -185 info = handle.info() -186 content = handle.read() -187 params = cgi.parse_qs(content, keep_blank_values=False) -188 key = params['oauth_token'][0] -189 secret = params['oauth_token_secret'][0] -190 return key, secret -
191 -192 -
193 - def fetch_access_token(self, oauth_verifier): -
194 """ -195 Helper-function for a registered consumer to exchange an access token for -196 a request token. -197 -198 Use it like this: -199 -200 >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, -201 CONSUMER_SECRET, -202 request_token, -203 request_token_secret) -204 -205 >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) -206 >>> token, secret = sca.fetch_access_token() -207 -208 Please note the values passed as token & secret to the authenticator. -209 """ -210 return self.fetch_request_token(ACCESS_TOKEN_URL, oauth_verifier=oauth_verifier) -
211 -212 -
213 - def get_request_token_authorization_url(self, token): -
214 """ -215 Simple helper function to generate the url needed -216 to ask a user for request token authorization. -217 -218 See also L{fetch_request_token}. -219 -220 Possible usage: -221 -222 >>> import webbrowser -223 >>> sca = scapi.ApiConnector() -224 >>> authorization_url = sca.get_request_token_authorization_url(token) -225 >>> webbrowser.open(authorization_url) -226 """ -227 return "%s?oauth_token=%s" % (AUTHORIZATION_URL, token) -
228 -
229 -230 -231 -class SCRedirectHandler(urllib2.HTTPRedirectHandler): -
232 """ -233 A urllib2-Handler to deal with the redirects the RESTful API of SC uses. -234 """ -235 alternate_method = None -236 -
237 - def http_error_303(self, req, fp, code, msg, hdrs): -
238 """ -239 In case of return-code 303 (See-other), we have to store the location we got -240 because that will determine the actual type of resource returned. -241 """ -242 self.alternate_method = hdrs['location'] -243 # for oauth, we need to re-create the whole header-shizzle. This -244 # does it - it recreates a full url and signs the request -245 new_url = self.alternate_method -246 # if USE_PROXY: -247 # import pdb; pdb.set_trace() -248 # old_url = req.get_full_url() -249 # protocol, host, _, _, _, _ = urlparse.urlparse(old_url) -250 # new_url = urlparse.urlunparse((protocol, host, self.alternate_method, None, None, None)) -251 req = req.recreate_request(new_url) -252 return urllib2.HTTPRedirectHandler.http_error_303(self, req, fp, code, msg, hdrs) -
253 -
254 - def http_error_201(self, req, fp, code, msg, hdrs): -
255 """ -256 We fake a 201 being a 303 so that our redirection-scheme takes place -257 for the 201 the API throws in case we created something. If the location is -258 not available though, that means that whatever we created has succeded - without -259 being a named resource. Assigning an asset to a track is an example of such -260 case. -261 """ -262 if 'location' not in hdrs: -263 raise NoResultFromRequest() -264 return self.http_error_303(req, fp, 303, msg, hdrs) -
265 -
266 -class Scope(object): -
267 """ -268 The basic means to query and create resources. The Scope uses the L{ApiConnector} to -269 create the proper URIs for querying or creating resources. -270 -271 For accessing resources from the root level, you explcitly create a Scope and pass it -272 an L{ApiConnector}-instance. Then you can query it -273 or create new resources like this: -274 -275 >>> connector = scapi.ApiConnector(host='host', user='user', password='password') # initialize the API -276 >>> scope = scapi.Scope(connector) # get the root scope -277 >>> users = list(scope.users()) -278 [<scapi.User object at 0x12345>, ...] -279 -280 Please not that all resources that are lists are returned as B{generator}. So you need -281 to either iterate over them, or call list(resources) on them. -282 -283 When accessing resources that belong to another resource, like contacts of a user, you access -284 the parent's resource scope implicitly through the resource instance like this: -285 -286 >>> user = scope.users().next() -287 >>> list(user.contacts()) -288 [<scapi.Contact object at 0x12345>, ...] -289 -290 """ -
291 - def __init__(self, connector, scope=None, parent=None): -
292 """ -293 Create the Scope. It can have a resource as scope, and possibly a parent-scope. -294 -295 @param connector: The connector to use. -296 @type connector: ApiConnector -297 @type scope: scapi.RESTBase -298 @param scope: the resource to make this scope belong to -299 @type parent: scapi.Scope -300 @param parent: the parent scope of this scope -301 """ -302 -303 if scope is None: -304 scope = () -305 else: -306 scope = scope, -307 if parent is not None: -308 scope = parent._scope + scope -309 self._scope = scope -310 self._connector = connector -
311 -
312 - def _get_connector(self): -
313 return self._connector -
314 -315 -
316 - def oauth_sign_get_request(self, url): -
317 """ -318 This method will take an arbitrary url, and rewrite it -319 so that the current authenticator's oauth-headers are appended -320 as query-parameters. -321 -322 This is used in streaming and downloading, because those content -323 isn't served from the SoundCloud servers themselves. -324 -325 A usage example would look like this: -326 -327 >>> sca = scapi.Scope(connector) -328 >>> track = sca.tracks(params={ -329 "filter" : "downloadable", -330 }).next() -331 -332 -333 >>> download_url = track.download_url -334 >>> signed_url = track.oauth_sign_get_request(download_url) -335 >>> data = urllib2.urlopen(signed_url).read() -336 -337 """ -338 scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) -339 -340 req = urllib2.Request(url) -341 -342 all_params = {} -343 if query: -344 all_params.update(cgi.parse_qs(query)) -345 -346 if not all_params: -347 all_params = None -348 -349 self._connector.authenticator.augment_request(req, all_params, False) -350 -351 auth_header = req.get_header("Authorization") -352 auth_header = auth_header[len("OAuth "):] -353 -354 query_params = [] -355 if query: -356 query_params.append(query) -357 -358 for part in auth_header.split(","): -359 key, value = part.split("=") -360 assert key.startswith("oauth") -361 value = value[1:-1] -362 query_params.append("%s=%s" % (key, value)) -363 -364 query = "&".join(query_params) -365 url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) -366 return url -
367 -368 -
369 - def _create_request(self, url, connector, parameters, queryparams, alternate_http_method=None, use_multipart=False): -
370 """ -371 This method returnes the urllib2.Request to perform the actual HTTP-request. -372 -373 We return a subclass that overload the get_method-method to return a custom method like "PUT". -374 Additionally, the request is enhanced with the current authenticators authorization scheme -375 headers. -376 -377 @param url: the destination url -378 @param connector: our connector-instance -379 @param parameters: the POST-parameters to use. -380 @type parameters: None|dict<str, basestring|list<basestring>> -381 @param queryparams: the queryparams to use -382 @type queryparams: None|dict<str, basestring|list<basestring>> -383 @param alternate_http_method: an alternate HTTP-method to use -384 @type alternate_http_method: str -385 @return: the fully equipped request -386 @rtype: urllib2.Request -387 """ -388 class MyRequest(urllib2.Request): -389 def get_method(self): -390 if alternate_http_method is not None: -391 return alternate_http_method -392 return urllib2.Request.get_method(self) -
393 -394 def has_data(self): -395 return parameters is not None -
396 -397 def augment_request(self, params, use_multipart=False): -398 connector.authenticator.augment_request(self, params, use_multipart) -

399 -400 @classmethod -401 def recreate_request(cls, location): -402 return self._create_request(location, connector, None, None) -403 -404 req = MyRequest(url) -405 all_params = {} -406 if parameters is not None: -407 all_params.update(parameters) -408 if queryparams is not None: -409 all_params.update(queryparams) -410 if not all_params: -411 all_params = None -412 req.augment_request(all_params, use_multipart) -413 req.add_header("Accept", "application/json") -414 return req -415 -416 -
417 - def _create_query_string(self, queryparams): -
418 """ -419 Small helpermethod to create the querystring from a dict. -420 -421 @type queryparams: None|dict<str, basestring|list<basestring>> -422 @param queryparams: the queryparameters. -423 @return: either the empty string, or a "?" followed by the parameters joined by "&" -424 @rtype: str -425 """ -426 if not queryparams: -427 return "" -428 h = [] -429 for key, values in queryparams.iteritems(): -430 if isinstance(values, (int, long, float)): -431 values = str(values) -432 if isinstance(values, basestring): -433 values = [values] -434 for v in values: -435 v = v.encode("utf-8") -436 h.append("%s=%s" % (key, escape(v))) -437 return "?" + "&".join(h) -
438 -439 -
440 - def _call(self, method, *args, **kwargs): -
441 """ -442 The workhorse. It's complicated, convoluted and beyond understanding of a mortal being. -443 -444 You have been warned. -445 """ -446 -447 queryparams = {} -448 __offset__ = ApiConnector.LIST_LIMIT -449 if "__offset__" in kwargs: -450 offset = kwargs.pop("__offset__") -451 queryparams['offset'] = offset -452 __offset__ = offset + ApiConnector.LIST_LIMIT -453 -454 if "params" in kwargs: -455 queryparams.update(kwargs.pop("params")) -456 -457 # create a closure to invoke this method again with a greater offset -458 _cl_method = method -459 _cl_args = tuple(args) -460 _cl_kwargs = {} -461 _cl_kwargs.update(kwargs) -462 _cl_kwargs["__offset__"] = __offset__ -463 def continue_list_fetching(): -464 return self._call(method, *_cl_args, **_cl_kwargs) -
465 connector = self._get_connector() -466 def filelike(v): -467 if isinstance(v, file): -468 return True -469 if hasattr(v, "read"): -470 return True -471 return False -472 alternate_http_method = None -473 if "_alternate_http_method" in kwargs: -474 alternate_http_method = kwargs.pop("_alternate_http_method") -475 urlparams = kwargs if kwargs else None -476 use_multipart = False -477 if urlparams is not None: -478 fileargs = dict((key, value) for key, value in urlparams.iteritems() if filelike(value)) -479 use_multipart = bool(fileargs) -480 -481 # ensure the method has a trailing / -482 if method[-1] != "/": -483 method = method + "/" -484 if args: -485 method = "%s%s" % (method, "/".join(str(a) for a in args)) -486 -487 scope = '' -488 if self._scope: -489 scopes = self._scope -490 if connector.collapse_scope: -491 scopes = scopes[-1:] -492 scope = "/".join([sc._scope() for sc in scopes]) + "/" -493 url = "http://%(host)s/%(base)s%(scope)s%(method)s%(queryparams)s" % dict(host=connector.host, method=method, base=connector._base, scope=scope, queryparams=self._create_query_string(queryparams)) -494 -495 # we need to install SCRedirectHandler -496 # to gather possible See-Other redirects -497 # so that we can exchange our method -498 redirect_handler = SCRedirectHandler() -499 handlers = [redirect_handler] -500 if USE_PROXY: -501 handlers.append(urllib2.ProxyHandler({'http' : PROXY})) -502 req = self._create_request(url, connector, urlparams, queryparams, alternate_http_method, use_multipart) -503 -504 http_method = req.get_method() -505 if urlparams is not None: -506 logger.debug("Posting url: %s, method: %s", url, http_method) -507 else: -508 logger.debug("Fetching url: %s, method: %s", url, http_method) -509 -510 -511 if use_multipart: -512 handlers.extend([MultipartPostHandler]) -513 else: -514 if urlparams is not None: -515 urlparams = urllib.urlencode(urlparams.items(), True) -516 opener = urllib2.build_opener(*handlers) -517 try: -518 handle = opener.open(req, urlparams) -519 except NoResultFromRequest: -520 return None -521 except urllib2.HTTPError, e: -522 if http_method == "GET" and e.code == 404: -523 return None -524 raise -525 -526 info = handle.info() -527 ct = info['Content-Type'] -528 content = handle.read() -529 logger.debug("Content-type:%s", ct) -530 logger.debug("Request Content:\n%s", content) -531 if redirect_handler.alternate_method is not None: -532 method = connector.normalize_method(redirect_handler.alternate_method) -533 logger.debug("Method changed through redirect to: <%s>", method) -534 -535 try: -536 if "application/json" in ct: -537 content = content.strip() -538 if not content: -539 content = "{}" -540 try: -541 res = simplejson.loads(content) -542 except: -543 logger.error("Couldn't decode returned json") -544 logger.error(content) -545 raise -546 res = self._map(res, method, continue_list_fetching) -547 return res -548 elif len(content) <= 1: -549 # this might be the famous SeeOtherSpecialCase which means that -550 # all that matters is just the method -551 pass -552 raise UnknownContentType("%s, returned:\n%s" % (ct, content)) -553 finally: -554 handle.close() -555 -
556 - def _map(self, res, method, continue_list_fetching): -
557 """ -558 This method will take the JSON-result of a HTTP-call and return our domain-objects. -559 -560 It's also deep magic, don't look. -561 """ -562 pathparts = reversed(method.split("/")) -563 stack = [] -564 for part in pathparts: -565 stack.append(part) -566 if part in RESTBase.REGISTRY: -567 cls = RESTBase.REGISTRY[part] -568 # multiple objects -569 if isinstance(res, list): -570 def result_gen(): -571 count = 0 -572 for item in res: -573 yield cls(item, self, stack) -574 count += 1 -575 if count == ApiConnector.LIST_LIMIT: -576 for item in continue_list_fetching(): -577 yield item -
578 return result_gen() -579 else: -580 return cls(res, self, stack) -581 logger.debug("don't know how to handle result") -582 logger.debug(res) -583 return res -584 -
585 - def __getattr__(self, _name): -
586 """ -587 Retrieve an API-method or a scoped domain-class. -588 -589 If the former, result is a callable that supports the following invocations: -590 -591 - calling (...), with possible arguments (positional/keyword), return the resulting resource or list of resources. -592 When calling, you can pass a keyword-argument B{params}. This must be a dict or L{MultiDict} and will be used to add additional query-get-parameters. -593 -594 - invoking append(resource) on it will PUT the resource, making it part of the current resource. Makes -595 sense only if it's a collection of course. -596 -597 - invoking remove(resource) on it will DELETE the resource from it's container. Also only usable on collections. -598 -599 TODO: describe the latter -600 """ -601 scope = self -602 -603 class api_call(object): -604 def __call__(selfish, *args, **kwargs): -605 return self._call(_name, *args, **kwargs) -
606 -607 def new(self, **kwargs): -608 """ -609 Will invoke the new method on the named resource _name, with -610 self as scope. -611 """ -612 cls = RESTBase.REGISTRY[_name] -613 return cls.new(scope, **kwargs) -614 -615 def append(selfish, resource): -616 """ -617 If the current scope is -618 """ -619 self._call(_name, str(resource.id), _alternate_http_method="PUT") -620 -621 def remove(selfish, resource): -622 self._call(_name, str(resource.id), _alternate_http_method="DELETE") -623 -624 if _name in RESTBase.ALL_DOMAIN_CLASSES: -625 cls = RESTBase.ALL_DOMAIN_CLASSES[_name] -626 -627 class ScopeBinder(object): -628 def new(self, *args, **data): -629 -630 d = MultiDict() -631 name = cls._singleton() -632 -633 def unfold_value(key, value): -634 if isinstance(value, (basestring, file)): -635 d.add(key, value) -636 elif isinstance(value, dict): -637 for sub_key, sub_value in value.iteritems(): -638 unfold_value("%s[%s]" % (key, sub_key), sub_value) -639 else: -640 # assume iteration else -641 for sub_value in value: -642 unfold_value(key + "[]", sub_value) -643 -644 -645 for key, value in data.iteritems(): -646 unfold_value("%s[%s]" % (name, key), value) -647 -648 return scope._call(cls.KIND, **d) -649 -650 def create(self, **data): -651 return cls.create(scope, **data) -652 -653 def get(self, id): -654 return cls.get(scope, id) -655 -656 -657 return ScopeBinder() -658 return api_call() -659 -
660 - def __repr__(self): -
661 return str(self) -
662 -
663 - def __str__(self): -
664 scopes = self._scope -665 base = "" -666 if len(scopes) > 1: -667 base = str(scopes[-2]) -668 return base + "/" + str(scopes[-1]) -
669 -
670 -671 # maybe someday I'll make that work. -672 # class RESTBaseMeta(type): -673 # def __new__(self, name, bases, d): -674 # clazz = type(name, bases, d) -675 # if 'KIND' in d: -676 # kind = d['KIND'] -677 # RESTBase.REGISTRY[kind] = clazz -678 # return clazz -679 -680 -class RESTBase(object): -
681 """ -682 The baseclass for all our domain-objects/resources. -683 -684 -685 """ -686 REGISTRY = {} -687 -688 ALL_DOMAIN_CLASSES = {} -689 -690 ALIASES = [] -691 -692 KIND = None -693 -
694 - def __init__(self, data, scope, path_stack=None): -
695 self.__data = data -696 self.__scope = scope -697 # try and see if we can/must create an id out of our path -698 logger.debug("path_stack: %r", path_stack) -699 if path_stack: -700 try: -701 id = int(path_stack[0]) -702 self.__data['id'] = id -703 except ValueError: -704 pass -
705 -
706 - def __getattr__(self, name): -
707 if name in self.__data: -708 obj = self.__data[name] -709 if name in RESTBase.REGISTRY: -710 if isinstance(obj, dict): -711 obj = RESTBase.REGISTRY[name](obj, self.__scope) -712 elif isinstance(obj, list): -713 obj = [RESTBase.REGISTRY[name](o, self.__scope) for o in obj] -714 else: -715 logger.warning("Found %s in our registry, but don't know what to do with"\ -716 "the object.") -717 return obj -718 scope = Scope(self.__scope._get_connector(), scope=self, parent=self.__scope) -719 return getattr(scope, name) -
720 -
721 - def __setattr__(self, name, value): -
722 """ -723 This method is used to set a property, a resource or a list of resources as property of the resource the -724 method is invoked on. -725 -726 For example, to set a comment on a track, do -727 -728 >>> sca = scapi.Scope(connector) -729 >>> track = scapi.Track.new(title='bar', sharing="private") -730 >>> comment = scapi.Comment.create(body="This is the body of my comment", timestamp=10) -731 >>> track.comments = comment -732 -733 To set a list of users as permissions, do -734 -735 >>> sca = scapi.Scope(connector) -736 >>> me = sca.me() -737 >>> track = scapi.Track.new(title='bar', sharing="private") -738 >>> users = sca.users() -739 >>> users_to_set = [user for user in users[:10] if user != me] -740 >>> track.permissions = users_to_set -741 -742 And finally, to simply change the title of a track, do -743 -744 >>> sca = scapi.Scope(connector) -745 >>> track = sca.Track.get(track_id) -746 >>> track.title = "new_title" -747 -748 @param name: the property name -749 @type name: str -750 @param value: the property, resource or resources to set -751 @type value: RESTBase | list<RESTBase> | basestring | long | int | float -752 @return: None -753 """ -754 -755 # update "private" data, such as __data -756 if "_RESTBase__" in name: -757 self.__dict__[name] = value -758 else: -759 if isinstance(value, list) and len(value): -760 # the parametername is something like -761 # permissions[user_id][] -762 # so we try to infer that. -763 parameter_name = "%s[%s_id][]" % (name, value[0]._singleton()) -764 values = [o.id for o in value] -765 kwargs = {"_alternate_http_method" : "PUT", -766 parameter_name : values} -767 self.__scope._call(self.KIND, self.id, name, **kwargs) -768 elif isinstance(value, RESTBase): -769 # we got a single instance, so make that an argument -770 self.__scope._call(self.KIND, self.id, name, **value._as_arguments()) -771 else: -772 # we have a simple property -773 parameter_name = "%s[%s]" % (self._singleton(), name) -774 kwargs = {"_alternate_http_method" : "PUT", -775 parameter_name : self._convert_value(value)} -776 self.__scope._call(self.KIND, self.id, **kwargs) -
777 -
778 - def _as_arguments(self): -
779 """ -780 Converts a resource to a argument-string the way Rails expects it. -781 """ -782 res = {} -783 for key, value in self.__data.items(): -784 value = self._convert_value(value) -785 res["%s[%s]" % (self._singleton(), key)] = value -786 return res -
787 -
788 - def _convert_value(self, value): -
789 if isinstance(value, unicode): -790 value = value.encode("utf-8") -791 elif isinstance(value, file): -792 pass -793 else: -794 value = str(value) -795 return value -
796 -797 @classmethod -
798 - def create(cls, scope, **data): -
799 """ -800 This is a convenience-method for creating an object that will be passed -801 as parameter - e.g. a comment. A usage would look like this: -802 -803 >>> sca = scapi.Scope(connector) -804 >>> track = sca.Track.new(title='bar', sharing="private") -805 >>> comment = sca.Comment.create(body="This is the body of my comment", timestamp=10) -806 >>> track.comments = comment -807 -808 """ -809 return cls(data, scope) -
810 -811 @classmethod -
812 - def new(cls, scope, **data): -
813 """ -814 Create a new resource inside a given Scope. The actual values are in data. -815 -816 So for creating new resources, you have two options: -817 -818 - create an instance directly using the class: -819 -820 >>> scope = scapi.Scope(connector) -821 >>> scope.User.new(...) -822 <scapi.User object at 0x1234> -823 -824 - create a instance in a certain scope: -825 -826 >>> scope = scapi.Scope(connector) -827 >>> user = scapi.User("1") -828 >>> track = user.tracks.new() -829 <scapi.Track object at 0x1234> -830 -831 @param scope: if not empty, a one-element tuple containing the Scope -832 @type scope: tuple<Scope>[1] -833 @param data: the data -834 @type data: dict -835 @return: new instance of the resource -836 """ -837 return getattr(scope, cls.__name__).new(**data) -
838 -839 @classmethod -
840 - def get(cls, scope, id): -
841 """ -842 Fetch a resource by id. -843 -844 Simply pass a known id as argument. For example -845 -846 >>> sca = scapi.Scope(connector) -847 >>> track = sca.Track.get(id) -848 -849 """ -850 return getattr(scope, cls.KIND)(id) -
851 -852 -
853 - def _scope(self): -
854 """ -855 Return the scope this resource lives in, which is the KIND and id -856 -857 @return: "<KIND>/<id>" -858 """ -859 return "%s/%s" % (self.KIND, str(self.id)) -
860 -861 @classmethod -
862 - def _singleton(cls): -
863 """ -864 This method will take a resource name like "users" and -865 return the single-case, in the example "user". -866 -867 Currently, it's not very sophisticated, only strips a trailing s. -868 """ -869 name = cls.KIND -870 if name[-1] == 's': -871 return name[:-1] -872 raise ValueError("Can't make %s to a singleton" % name) -
873 -
874 - def __repr__(self): -
875 res = [] -876 res.append("\n\n******\n%s:" % self.__class__.__name__) -877 res.append("") -878 for key, v in self.__data.iteritems(): -879 key = str(key) -880 if isinstance(v, unicode): -881 v = v.encode('utf-8') -882 else: -883 v = str(v) -884 res.append("%s=%s" % (key, v)) -885 return "\n".join(res) -
886 -
887 - def __hash__(self): -
888 return hash("%s%i" % (self.KIND, self.id)) -
889 -
890 - def __eq__(self, other): -
891 """ -892 Test for equality. -893 -894 Resources are considered equal if the have the same kind and id. -895 """ -896 if not isinstance(other, RESTBase): -897 return False -898 res = self.KIND == other.KIND and self.id == other.id -899 return res -
900 -
901 - def __ne__(self, other): -
902 return not self == other -
903 -
904 -class User(RESTBase): -
905 """ -906 A user domain object/resource. -907 """ -908 KIND = 'users' -909 ALIASES = ['me', 'permissions', 'contacts', 'user'] -
910 -
911 -class Track(RESTBase): -
912 """ -913 A track domain object/resource. -914 """ -915 KIND = 'tracks' -916 ALIASES = ['favorites'] -
917 -
918 -class Comment(RESTBase): -
919 """ -920 A comment domain object/resource. -921 """ -922 KIND = 'comments' -
923 -
924 -class Event(RESTBase): -
925 """ -926 A event domain object/resource. -927 """ -928 KIND = 'events' -
929 -
930 -class Playlist(RESTBase): -
931 """ -932 A playlist/set domain object/resource -933 """ -934 KIND = 'playlists' -
935 -
936 -class Group(RESTBase): -
937 """ -938 A group domain object/resource -939 """ -940 KIND = 'groups' -
941 -
942 -943 -944 # this registers all the RESTBase subclasses. -945 # One day using a metaclass will make this a tad -946 # less ugly. -947 -def register_classes(): -
948 g = {} -949 g.update(globals()) -950 for name, cls in [(k, v) for k, v in g.iteritems() if isclass(v) and issubclass(v, RESTBase) and not v == RESTBase]: -951 RESTBase.REGISTRY[cls.KIND] = cls -952 RESTBase.ALL_DOMAIN_CLASSES[cls.__name__] = cls -953 for alias in cls.ALIASES: -954 RESTBase.REGISTRY[alias] = cls -955 __all__.append(name) -
956 register_classes() -957 - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.ApiConnector-class.html b/python_apps/soundcloud-api/docs/api/scapi.ApiConnector-class.html deleted file mode 100644 index 7e4a213ac..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.ApiConnector-class.html +++ /dev/null @@ -1,544 +0,0 @@ - - - - - scapi.ApiConnector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class ApiConnector - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class ApiConnector

source code

-
-object --+
-         |
-        ApiConnector
-
- -
-

The ApiConnector holds all the data necessary to authenticate against - the soundcloud-api. You can instantiate several connectors if you like, - but usually one should be sufficient.

- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - host, - user=None, - password=None, - authenticator=None, - base='', - collapse_scope=True)
- Constructor for the API-Singleton.
- source code - -
- -
-   - - - - - - -
normalize_method(self, - method)
- This method will take a method that has been part of a redirect of - some sort and see if it's valid, which means that it's located - beneath our base.
- source code - -
- -
-   - - - - - - -
fetch_request_token(self, - url=None, - oauth_callback='oob', - oauth_verifier=None)
- Helper-function for a registered consumer to obtain a request token, - as used by oauth.
- source code - -
- -
-   - - - - - - -
fetch_access_token(self, - oauth_verifier)
- Helper-function for a registered consumer to exchange an access token - for a request token.
- source code - -
- -
-   - - - - - - -
get_request_token_authorization_url(self, - token)
- Simple helper function to generate the url needed to ask a user for - request token authorization.
- source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - LIST_LIMIT = 50
- The query-parameter that is used to request results beginning from a - certain offset. -
-   - - LIST_OFFSET_PARAMETER = 'offset'
- The query-parameter that is used to request results being limited to - a certain amount. -
-   - - LIST_LIMIT_PARAMETER = 'limit' -
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - host, - user=None, - password=None, - authenticator=None, - base='', - collapse_scope=True) -
(Constructor) -

-
source code  -
- -

Constructor for the API-Singleton. Use it once with parameters, and - then the subsequent calls internal to the API will work.

-
-
Parameters:
-
    -
  • host (str) - the host to connect to, e.g. "api.soundcloud.com". If a - port is needed, use "api.soundcloud.com:1234"
  • -
  • user (str) - if given, the username for basic HTTP authentication
  • -
  • password (str) - if the user is given, you have to give a password as well
  • -
  • authenticator (OAuthAuthenticator | BasicAuthenticator) - the authenticator to use, see scapi.authentication
  • -
-
Overrides: - object.__init__ -
-
-
-
- -
- -
- - -
-

normalize_method(self, - method) -

-
source code  -
- -

This method will take a method that has been part of a redirect of - some sort and see if it's valid, which means that it's located beneath - our base. If yes, we return it normalized without that very base.

-
-
-
-
- -
- -
- - -
-

fetch_request_token(self, - url=None, - oauth_callback='oob', - oauth_verifier=None) -

-
source code  -
- -

Helper-function for a registered consumer to obtain a request token, - as used by oauth.

-

Use it like this:

-
->>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, 
-                                                          CONSUMER_SECRET,
-                                                          None, 
-                                                          None)
-
->>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator)
->>> token, secret = sca.fetch_request_token()
->>> authorization_url = sca.get_request_token_authorization_url(token)
-

Please note the None passed as token & secret to the - authenticator.

-
-
-
-
- -
- -
- - -
-

fetch_access_token(self, - oauth_verifier) -

-
source code  -
- -

Helper-function for a registered consumer to exchange an access token - for a request token.

-

Use it like this:

-
->>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, 
-                                                          CONSUMER_SECRET,
-                                                          request_token, 
-                                                          request_token_secret)
-
->>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator)
->>> token, secret = sca.fetch_access_token()
-

Please note the values passed as token & secret to the - authenticator.

-
-
-
-
- -
- -
- - -
-

get_request_token_authorization_url(self, - token) -

-
source code  -
- -

Simple helper function to generate the url needed to ask a user for - request token authorization.

-

See also fetch_request_token.

-

Possible usage:

-
->>> import webbrowser
->>> sca = scapi.ApiConnector()
->>> authorization_url = sca.get_request_token_authorization_url(token)
->>> webbrowser.open(authorization_url)
-
-
-
-
-
- - - - - - -
- - - - - -
Class Variable Details[hide private]
-
- -
- -
-

LIST_OFFSET_PARAMETER

-

The query-parameter that is used to request results being limited to a - certain amount.

-

Currently this is of no use and just for completeness sake.

-
-
-
-
Value:
-
-'offset'
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Asset-class.html b/python_apps/soundcloud-api/docs/api/scapi.Asset-class.html deleted file mode 100644 index f64bc0d2b..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Asset-class.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - scapi.Asset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Asset - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Asset

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Asset
-
- -
-An asset domain object/resource.

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'assets' -
-

Inherited from RESTBase: - ALIASES, - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Comment-class.html b/python_apps/soundcloud-api/docs/api/scapi.Comment-class.html deleted file mode 100644 index 4f2c4c950..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Comment-class.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - scapi.Comment - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Comment - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Comment

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Comment
-
- -
-

A comment domain object/resource.

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'comments' -
-

Inherited from RESTBase: - ALIASES, - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Event-class.html b/python_apps/soundcloud-api/docs/api/scapi.Event-class.html deleted file mode 100644 index 40095b067..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Event-class.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - scapi.Event - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Event - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Event

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Event
-
- -
-

A event domain object/resource.

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'events' -
-

Inherited from RESTBase: - ALIASES, - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Group-class.html b/python_apps/soundcloud-api/docs/api/scapi.Group-class.html deleted file mode 100644 index eb30ab842..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Group-class.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - scapi.Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Group - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Group

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Group
-
- -
-

A group domain object/resource

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'groups' -
-

Inherited from RESTBase: - ALIASES, - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.InvalidMethodException-class.html b/python_apps/soundcloud-api/docs/api/scapi.InvalidMethodException-class.html deleted file mode 100644 index 476502352..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.InvalidMethodException-class.html +++ /dev/null @@ -1,297 +0,0 @@ - - - - - scapi.InvalidMethodException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class InvalidMethodException - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class InvalidMethodException

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              InvalidMethodException
-
- -
- - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - message)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__, - __str__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - message) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.NoResultFromRequest-class.html b/python_apps/soundcloud-api/docs/api/scapi.NoResultFromRequest-class.html deleted file mode 100644 index 5bcb71794..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.NoResultFromRequest-class.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - scapi.NoResultFromRequest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class NoResultFromRequest - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class NoResultFromRequest

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              NoResultFromRequest
-
- -
- - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from exceptions.Exception: - __init__, - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __repr__, - __setattr__, - __setstate__, - __str__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Playlist-class.html b/python_apps/soundcloud-api/docs/api/scapi.Playlist-class.html deleted file mode 100644 index 557f05831..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Playlist-class.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - scapi.Playlist - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Playlist - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Playlist

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Playlist
-
- -
-

A playlist/set domain object/resource

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'playlists' -
-

Inherited from RESTBase: - ALIASES, - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.RESTBase-class.html b/python_apps/soundcloud-api/docs/api/scapi.RESTBase-class.html deleted file mode 100644 index 855d8fd1e..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.RESTBase-class.html +++ /dev/null @@ -1,895 +0,0 @@ - - - - - scapi.RESTBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class RESTBase - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class RESTBase

source code

-
-object --+
-         |
-        RESTBase
-
- -
Known Subclasses:
-
- -
- -
-

The baseclass for all our domain-objects/resources.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - data, - scope, - path_stack=None)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
__getattr__(self, - name) - source code - -
- -
-   - - - - - - -
__setattr__(self, - name, - value)
- This method is used to set a property, a resource or a list of - resources as property of the resource the method is invoked on.
- source code - -
- -
-   - - - - - - -
_as_arguments(self)
- Converts a resource to a argument-string the way Rails expects it.
- source code - -
- -
-   - - - - - - -
_convert_value(self, - value) - source code - -
- -
-   - - - - - - -
_scope(self)
- Return the scope this resource lives in, which is the KIND and id
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
__hash__(self)
- hash(x)
- source code - -
- -
-   - - - - - - -
__eq__(self, - other)
- Test for equality.
- source code - -
- -
-   - - - - - - -
__ne__(self, - other) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - - - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-   - - - - - - -
create(cls, - scope, - **data)
- This is a convenience-method for creating an object that will be - passed as parameter - e.g.
- source code - -
- -
-   - - - - - - -
new(cls, - scope, - **data)
- Create a new resource inside a given Scope.
- source code - -
- -
-   - - - - - - -
get(cls, - scope, - id)
- Fetch a resource by id.
- source code - -
- -
-   - - - - - - -
_singleton(cls)
- This method will take a resource name like "users" and - return the single-case, in the example "user".
- source code - -
- -
- - - - - - - - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - REGISTRY = {'comments': <class 'scapi.Comment'>, 'contacts': <... -
-   - - ALL_DOMAIN_CLASSES = {'Comment': <class 'scapi.Comment'>, 'Eve... -
-   - - ALIASES = [] -
-   - - KIND = None -
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - data, - scope, - path_stack=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__setattr__(self, - name, - value) -

-
source code  -
- -

This method is used to set a property, a resource or a list of - resources as property of the resource the method is invoked on.

-

For example, to set a comment on a track, do

-
->>> sca = scapi.Scope(connector)
->>> track = scapi.Track.new(title='bar', sharing="private")
->>> comment = scapi.Comment.create(body="This is the body of my comment", timestamp=10)    
->>> track.comments = comment
-

To set a list of users as permissions, do

-
->>> sca = scapi.Scope(connector)
->>> me = sca.me()
->>> track = scapi.Track.new(title='bar', sharing="private")
->>> users = sca.users()
->>> users_to_set = [user  for user in users[:10] if user != me]
->>> track.permissions = users_to_set
-

And finally, to simply change the title of a track, do

-
->>> sca = scapi.Scope(connector)
->>> track = sca.Track.get(track_id)
->>> track.title = "new_title"
-
-
Parameters:
-
    -
  • name (str) - the property name
  • -
  • value (RESTBase | list<RESTBase> | basestring | long | int | float) - the property, resource or resources to set
  • -
-
Returns:
-
None
-
Overrides: - object.__setattr__ -
-
-
-
- -
- -
- - -
-

create(cls, - scope, - **data) -
Class Method -

-
source code  -
- -

This is a convenience-method for creating an object that will be - passed as parameter - e.g. a comment. A usage would look like this:

-
->>> sca = scapi.Scope(connector)
->>> track = sca.Track.new(title='bar', sharing="private")
->>> comment = sca.Comment.create(body="This is the body of my comment", timestamp=10)    
->>> track.comments = comment
-
-
-
-
- -
- -
- - -
-

new(cls, - scope, - **data) -
Class Method -

-
source code  -
- -

Create a new resource inside a given Scope. The actual values are in - data.

-

So for creating new resources, you have two options:

-
    -
  • - create an instance directly using the class: -
    ->>> scope = scapi.Scope(connector)
    ->>> scope.User.new(...)
    -<scapi.User object at 0x1234>
    -
  • -
  • - create a instance in a certain scope: -
    ->>> scope = scapi.Scope(connector)
    ->>> user = scapi.User("1")
    ->>> track = user.tracks.new()
    -<scapi.Track object at 0x1234>
    -
  • -
-
-
Parameters:
-
    -
  • scope (tuple<Scope>[1]) - if not empty, a one-element tuple containing the Scope
  • -
  • data (dict) - the data
  • -
-
Returns:
-
new instance of the resource
-
-
-
- -
- -
- - -
-

get(cls, - scope, - id) -
Class Method -

-
source code  -
- -

Fetch a resource by id.

-

Simply pass a known id as argument. For example

-
->>> sca = scapi.Scope(connector)
->>> track = sca.Track.get(id)
-
-
-
-
- -
- -
- - -
-

_scope(self) -

-
source code  -
- -

Return the scope this resource lives in, which is the KIND and id

-
-
Returns:
-
"<KIND>/<id>"
-
-
-
- -
- -
- - -
-

_singleton(cls) -
Class Method -

-
source code  -
- -

This method will take a resource name like "users" and - return the single-case, in the example "user".

-

Currently, it's not very sophisticated, only strips a trailing s.

-
-
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__hash__(self) -
(Hashing function) -

-
source code  -
- -

hash(x)

-
-
Overrides: - object.__hash__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__eq__(self, - other) -
(Equality operator) -

-
source code  -
- -

Test for equality.

-

Resources are considered equal if the have the same kind and id.

-
-
-
-
-
- - - - - - -
- - - - - -
Class Variable Details[hide private]
-
- -
- -
-

REGISTRY

- -
-
-
-
Value:
-
-{'comments': <class 'scapi.Comment'>,
- 'contacts': <class 'scapi.User'>,
- 'events': <class 'scapi.Event'>,
- 'favorites': <class 'scapi.Track'>,
- 'groups': <class 'scapi.Group'>,
- 'me': <class 'scapi.User'>,
- 'permissions': <class 'scapi.User'>,
- 'playlists': <class 'scapi.Playlist'>,
-...
-
-
-
-
-
- -
- -
-

ALL_DOMAIN_CLASSES

- -
-
-
-
Value:
-
-{'Comment': <class 'scapi.Comment'>,
- 'Event': <class 'scapi.Event'>,
- 'Group': <class 'scapi.Group'>,
- 'Playlist': <class 'scapi.Playlist'>,
- 'Track': <class 'scapi.Track'>,
- 'User': <class 'scapi.User'>}
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.SCRedirectHandler-class.html b/python_apps/soundcloud-api/docs/api/scapi.SCRedirectHandler-class.html deleted file mode 100644 index 7fa8dedee..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.SCRedirectHandler-class.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - scapi.SCRedirectHandler - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class SCRedirectHandler - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class SCRedirectHandler

source code

-
-    urllib2.BaseHandler --+    
-                          |    
-urllib2.HTTPRedirectHandler --+
-                              |
-                             SCRedirectHandler
-
- -
-

A urllib2-Handler to deal with the redirects the RESTful API of SC - uses.

- - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
http_error_303(self, - req, - fp, - code, - msg, - hdrs)
- In case of return-code 303 (See-other), we have to store the location - we got because that will determine the actual type of resource - returned.
- source code - -
- -
-   - - - - - - -
http_error_201(self, - req, - fp, - code, - msg, - hdrs)
- We fake a 201 being a 303 so that our redirection-scheme takes place - for the 201 the API throws in case we created something.
- source code - -
- -
-

Inherited from urllib2.HTTPRedirectHandler: - http_error_301, - http_error_302, - http_error_307, - redirect_request -

-

Inherited from urllib2.BaseHandler: - __lt__, - add_parent, - close -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - alternate_method = None -
-

Inherited from urllib2.HTTPRedirectHandler: - inf_msg, - max_redirections, - max_repeats -

-

Inherited from urllib2.BaseHandler: - handler_order -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

http_error_303(self, - req, - fp, - code, - msg, - hdrs) -

-
source code  -
- -

In case of return-code 303 (See-other), we have to store the location - we got because that will determine the actual type of resource - returned.

-
-
Overrides: - urllib2.HTTPRedirectHandler.http_error_302 -
-
-
-
- -
- -
- - -
-

http_error_201(self, - req, - fp, - code, - msg, - hdrs) -

-
source code  -
- -

We fake a 201 being a 303 so that our redirection-scheme takes place - for the 201 the API throws in case we created something. If the location - is not available though, that means that whatever we created has succeded - - without being a named resource. Assigning an asset to a track is an - example of such case.

-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Scope-class.html b/python_apps/soundcloud-api/docs/api/scapi.Scope-class.html deleted file mode 100644 index 0b008e17f..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Scope-class.html +++ /dev/null @@ -1,682 +0,0 @@ - - - - - scapi.Scope - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Scope - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Scope

source code

-
-object --+
-         |
-        Scope
-
- -
-

The basic means to query and create resources. The Scope uses the ApiConnector to create the proper URIs for - querying or creating resources.

-

For accessing resources from the root level, you explcitly create a - Scope and pass it an ApiConnector-instance. Then you can query - it or create new resources like this:

-
->>> connector = scapi.ApiConnector(host='host', user='user', password='password') # initialize the API
->>> scope = scapi.Scope(connector) # get the root scope
->>> users = list(scope.users())
-[<scapi.User object at 0x12345>, ...]
-

Please not that all resources that are lists are returned as - generator. So you need to either iterate over them, or call - list(resources) on them.

-

When accessing resources that belong to another resource, like - contacts of a user, you access the parent's resource scope implicitly - through the resource instance like this:

-
->>> user = scope.users().next()
->>> list(user.contacts())
-[<scapi.Contact object at 0x12345>, ...]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - connector, - scope=None, - parent=None)
- Create the Scope.
- source code - -
- -
-   - - - - - - -
_get_connector(self) - source code - -
- -
-   - - - - - - -
oauth_sign_get_request(self, - url)
- This method will take an arbitrary url, and rewrite it so that the - current authenticator's oauth-headers are appended as - query-parameters.
- source code - -
- -
- urllib2.Request - - - - - - -
_create_request(self, - url, - connector, - parameters, - queryparams, - alternate_http_method=None, - use_multipart=False)
- This method returnes the urllib2.Request to perform the actual - HTTP-request.
- source code - -
- -
- str - - - - - - -
_create_query_string(self, - queryparams)
- Small helpermethod to create the querystring from a dict.
- source code - -
- -
-   - - - - - - -
_call(self, - method, - *args, - **kwargs)
- The workhorse.
- source code - -
- -
-   - - - - - - -
_map(self, - res, - method, - continue_list_fetching)
- This method will take the JSON-result of a HTTP-call and return our - domain-objects.
- source code - -
- -
-   - - - - - - -
__getattr__(self, - _name)
- Retrieve an API-method or a scoped domain-class.
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - connector, - scope=None, - parent=None) -
(Constructor) -

-
source code  -
- -

Create the Scope. It can have a resource as scope, and possibly a - parent-scope.

-
-
Parameters:
-
    -
  • connector (ApiConnector) - The connector to use.
  • -
  • scope (scapi.RESTBase) - the resource to make this scope belong to
  • -
  • parent (scapi.Scope) - the parent scope of this scope
  • -
-
Overrides: - object.__init__ -
-
-
-
- -
- -
- - -
-

oauth_sign_get_request(self, - url) -

-
source code  -
- -

This method will take an arbitrary url, and rewrite it so that the - current authenticator's oauth-headers are appended as - query-parameters.

-

This is used in streaming and downloading, because those content isn't - served from the SoundCloud servers themselves.

-

A usage example would look like this:

-
->>> sca = scapi.Scope(connector)
->>> track = sca.tracks(params={
-      "filter" : "downloadable",
-      }).next()
-
->>> download_url = track.download_url
->>> signed_url = track.oauth_sign_get_request(download_url)
->>> data = urllib2.urlopen(signed_url).read()
-
-
-
-
- -
- -
- - -
-

_create_request(self, - url, - connector, - parameters, - queryparams, - alternate_http_method=None, - use_multipart=False) -

-
source code  -
- -

This method returnes the urllib2.Request to perform the actual - HTTP-request.

-

We return a subclass that overload the get_method-method to return a - custom method like "PUT". Additionally, the request is enhanced - with the current authenticators authorization scheme headers.

-
-
Parameters:
-
    -
  • url - the destination url
  • -
  • connector - our connector-instance
  • -
  • parameters (None|dict<str, basestring|list<basestring>>) - the POST-parameters to use.
  • -
  • queryparams (None|dict<str, basestring|list<basestring>>) - the queryparams to use
  • -
  • alternate_http_method (str) - an alternate HTTP-method to use
  • -
-
Returns: urllib2.Request
-
the fully equipped request
-
-
-
- -
- -
- - -
-

_create_query_string(self, - queryparams) -

-
source code  -
- -

Small helpermethod to create the querystring from a dict.

-
-
Parameters:
-
    -
  • queryparams (None|dict<str, basestring|list<basestring>>) - the queryparameters.
  • -
-
Returns: str
-
either the empty string, or a "?" followed by the - parameters joined by "&"
-
-
-
- -
- -
- - -
-

_call(self, - method, - *args, - **kwargs) -

-
source code  -
- -

The workhorse. It's complicated, convoluted and beyond understanding - of a mortal being.

-

You have been warned.

-
-
-
-
- -
- -
- - -
-

_map(self, - res, - method, - continue_list_fetching) -

-
source code  -
- -

This method will take the JSON-result of a HTTP-call and return our - domain-objects.

-

It's also deep magic, don't look.

-
-
-
-
- -
- -
- - -
-

__getattr__(self, - _name) -
(Qualification operator) -

-
source code  -
- -

Retrieve an API-method or a scoped domain-class.

-

If the former, result is a callable that supports the following - invocations:

-
    -
  • - calling (...), with possible arguments (positional/keyword), return - the resulting resource or list of resources. When calling, you can - pass a keyword-argument params. This must be a dict or MultiDict and - will be used to add additional query-get-parameters. -
  • -
  • - invoking append(resource) on it will PUT the resource, making it part - of the current resource. Makes sense only if it's a collection of - course. -
  • -
  • - invoking remove(resource) on it will DELETE the resource from it's - container. Also only usable on collections. -

    TODO: describe the latter

    -
  • -
-
-
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.Track-class.html b/python_apps/soundcloud-api/docs/api/scapi.Track-class.html deleted file mode 100644 index e8257566a..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.Track-class.html +++ /dev/null @@ -1,264 +0,0 @@ - - - - - scapi.Track - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class Track - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class Track

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            Track
-
- -
-

A track domain object/resource.

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'tracks' -
-   - - ALIASES = ['favorites'] -
-

Inherited from RESTBase: - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.UnknownContentType-class.html b/python_apps/soundcloud-api/docs/api/scapi.UnknownContentType-class.html deleted file mode 100644 index 94f9ee872..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.UnknownContentType-class.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - scapi.UnknownContentType - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class UnknownContentType - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class UnknownContentType

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              UnknownContentType
-
- -
- - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - msg)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - msg) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.User-class.html b/python_apps/soundcloud-api/docs/api/scapi.User-class.html deleted file mode 100644 index 19b1053a9..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.User-class.html +++ /dev/null @@ -1,264 +0,0 @@ - - - - - scapi.User - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Class User - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class User

source code

-
-object --+    
-         |    
-  RESTBase --+
-             |
-            User
-
- -
-

A user domain object/resource.

- - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from RESTBase: - __eq__, - __getattr__, - __hash__, - __init__, - __ne__, - __repr__, - __setattr__ -

-

Inherited from RESTBase (private): - _as_arguments, - _convert_value, - _scope -

-

Inherited from object: - __delattr__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Methods[hide private]
-
-

Inherited from RESTBase: - create, - get, - new -

-

Inherited from RESTBase (private): - _singleton -

-
- - - - - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - KIND = 'users' -
-   - - ALIASES = ['me', 'permissions', 'contacts', 'user'] -
-

Inherited from RESTBase: - ALL_DOMAIN_CLASSES, - REGISTRY -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.authentication-module.html b/python_apps/soundcloud-api/docs/api/scapi.authentication-module.html deleted file mode 100644 index 2f6f5fb8e..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.authentication-module.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - scapi.authentication - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module authentication - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module authentication

source code

- - - - - - - - - - - - - - - -
- - - - - -
Classes[hide private]
-
-   - - OAuthSignatureMethod_HMAC_SHA1 -
-   - - OAuthAuthenticator -
-   - - BasicAuthenticator -
- - - - - - - - - - - - -
- - - - - -
Variables[hide private]
-
-   - - USE_DOUBLE_ESCAPE_HACK = True
- There seems to be an uncertainty on the way parameters are to be - escaped. -
-   - - logger = logging.getLogger(__name__) -
- - - - - - -
- - - - - -
Variables Details[hide private]
-
- -
- -
-

USE_DOUBLE_ESCAPE_HACK

-

There seems to be an uncertainty on the way parameters are to be - escaped. For now, this variable switches between two escaping - mechanisms.

-

If True, the passed parameters - GET or POST - are escaped - *twice*.

-
-
-
-
Value:
-
-True
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.authentication-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.authentication-pysrc.html deleted file mode 100644 index 65492b3c9..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.authentication-pysrc.html +++ /dev/null @@ -1,348 +0,0 @@ - - - - - scapi.authentication - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module authentication - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.authentication

-
-  1  ##    SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful 
-  2  ##    API 
-  3  ## 
-  4  ##    Copyright (C) 2008  Diez B. Roggisch 
-  5  ##    Contact mailto:deets@soundcloud.com 
-  6  ## 
-  7  ##    This library is free software; you can redistribute it and/or 
-  8  ##    modify it under the terms of the GNU Lesser General Public 
-  9  ##    License as published by the Free Software Foundation; either 
- 10  ##    version 2.1 of the License, or (at your option) any later version. 
- 11  ## 
- 12  ##    This library is distributed in the hope that it will be useful, 
- 13  ##    but WITHOUT ANY WARRANTY; without even the implied warranty of 
- 14  ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
- 15  ##    Lesser General Public License for more details. 
- 16  ## 
- 17  ##    You should have received a copy of the GNU Lesser General Public 
- 18  ##    License along with this library; if not, write to the Free Software 
- 19  ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- 20   
- 21  import base64 
- 22  import time, random 
- 23  import urlparse 
- 24  import hmac 
- 25  import hashlib 
- 26  from scapi.util import escape 
- 27  import logging 
- 28   
- 29   
- 30  USE_DOUBLE_ESCAPE_HACK = True 
- 31  """ 
- 32  There seems to be an uncertainty on the way 
- 33  parameters are to be escaped. For now, this 
- 34  variable switches between two escaping mechanisms. 
- 35   
- 36  If True, the passed parameters - GET or POST - are 
- 37  escaped *twice*. 
- 38  """ 
- 39   
- 40  logger = logging.getLogger(__name__) 
- 41   
-
42 -class OAuthSignatureMethod_HMAC_SHA1(object): -
43 - 44 FORBIDDEN = ['realm', 'oauth_signature'] - 45 -
46 - def get_name(self): -
47 return 'HMAC-SHA1' -
48 -
49 - def build_signature(self, request, parameters, consumer_secret, token_secret, oauth_parameters): -
50 if logger.level == logging.DEBUG: - 51 logger.debug("request: %r", request) - 52 logger.debug("parameters: %r", parameters) - 53 logger.debug("consumer_secret: %r", consumer_secret) - 54 logger.debug("token_secret: %r", token_secret) - 55 logger.debug("oauth_parameters: %r", oauth_parameters) - 56 - 57 - 58 temp = {} - 59 temp.update(oauth_parameters) - 60 for p in self.FORBIDDEN: - 61 if p in temp: - 62 del temp[p] - 63 if parameters is not None: - 64 temp.update(parameters) - 65 sig = ( - 66 escape(self.get_normalized_http_method(request)), - 67 escape(self.get_normalized_http_url(request)), - 68 self.get_normalized_parameters(temp), # these are escaped in the method already - 69 ) - 70 - 71 key = '%s&' % consumer_secret - 72 if token_secret is not None: - 73 key += token_secret - 74 raw = '&'.join(sig) - 75 logger.debug("raw basestring: %s", raw) - 76 logger.debug("key: %s", key) - 77 # hmac object - 78 hashed = hmac.new(key, raw, hashlib.sha1) - 79 # calculate the digest base 64 - 80 signature = escape(base64.b64encode(hashed.digest())) - 81 return signature -
82 - 83 -
84 - def get_normalized_http_method(self, request): -
85 return request.get_method().upper() -
86 - 87 - 88 # parses the url and rebuilds it to be scheme://host/path -
89 - def get_normalized_http_url(self, request): -
90 url = request.get_full_url() - 91 parts = urlparse.urlparse(url) - 92 url_string = '%s://%s%s' % (parts.scheme, parts.netloc, parts.path) - 93 return url_string -
94 - 95 -
96 - def get_normalized_parameters(self, params): -
97 if params is None: - 98 params = {} - 99 try: -100 # exclude the signature if it exists -101 del params['oauth_signature'] -102 except: -103 pass -104 key_values = [] -105 -106 for key, values in params.iteritems(): -107 if isinstance(values, file): -108 continue -109 if isinstance(values, (int, long, float)): -110 values = str(values) -111 if isinstance(values, (list, tuple)): -112 values = [str(v) for v in values] -113 if isinstance(values, basestring): -114 values = [values] -115 if USE_DOUBLE_ESCAPE_HACK and not key.startswith("ouath"): -116 key = escape(key) -117 for v in values: -118 v = v.encode("utf-8") -119 key = key.encode("utf-8") -120 if USE_DOUBLE_ESCAPE_HACK and not key.startswith("oauth"): -121 # this is a dirty hack to make the -122 # thing work with the current server-side -123 # implementation. Or is it by spec? -124 v = escape(v) -125 key_values.append(escape("%s=%s" % (key, v))) -126 # sort lexicographically, first after key, then after value -127 key_values.sort() -128 # combine key value pairs in string -129 return escape('&').join(key_values) -
130 -131 -
132 -class OAuthAuthenticator(object): -
133 OAUTH_API_VERSION = '1.0' -134 AUTHORIZATION_HEADER = "Authorization" -135 -
136 - def __init__(self, consumer, consumer_secret, token, secret, signature_method=OAuthSignatureMethod_HMAC_SHA1()): -
137 self._consumer, self._token, self._secret = consumer, token, secret -138 self._consumer_secret = consumer_secret -139 self._signature_method = signature_method -140 random.seed() -
141 -142 -
143 - def augment_request(self, req, parameters, use_multipart=False, oauth_callback=None, oauth_verifier=None): -
144 oauth_parameters = { -145 'oauth_consumer_key': self._consumer, -146 'oauth_timestamp': self.generate_timestamp(), -147 'oauth_nonce': self.generate_nonce(), -148 'oauth_version': self.OAUTH_API_VERSION, -149 'oauth_signature_method' : self._signature_method.get_name(), -150 #'realm' : "http://soundcloud.com", -151 } -152 if self._token is not None: -153 oauth_parameters['oauth_token'] = self._token -154 -155 if oauth_callback is not None: -156 oauth_parameters['oauth_callback'] = oauth_callback -157 -158 if oauth_verifier is not None: -159 oauth_parameters['oauth_verifier'] = oauth_verifier -160 -161 # in case we upload large files, we don't -162 # sign the request over the parameters -163 if use_multipart: -164 parameters = None -165 -166 oauth_parameters['oauth_signature'] = self._signature_method.build_signature(req, -167 parameters, -168 self._consumer_secret, -169 self._secret, -170 oauth_parameters) -171 def to_header(d): -172 return ",".join('%s="%s"' % (key, value) for key, value in sorted(oauth_parameters.items())) -
173 -174 req.add_header(self.AUTHORIZATION_HEADER, "OAuth %s" % to_header(oauth_parameters)) -
175 -
176 - def generate_timestamp(self): -
177 return int(time.time())# * 1000.0) -
178 -
179 - def generate_nonce(self, length=8): -
180 return ''.join(str(random.randint(0, 9)) for i in range(length)) -
181 -182 -
183 -class BasicAuthenticator(object): -
184 -
185 - def __init__(self, user, password, consumer, consumer_secret): -
186 self._base64string = base64.encodestring("%s:%s" % (user, password))[:-1] -187 self._x_auth_header = 'OAuth oauth_consumer_key="%s" oauth_consumer_secret="%s"' % (consumer, consumer_secret) -
188 -
189 - def augment_request(self, req, parameters): -
190 req.add_header("Authorization", "Basic %s" % self._base64string) -191 req.add_header("X-Authorization", self._x_auth_header) -
192 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.authentication.BasicAuthenticator-class.html b/python_apps/soundcloud-api/docs/api/scapi.authentication.BasicAuthenticator-class.html deleted file mode 100644 index 437ef8444..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.authentication.BasicAuthenticator-class.html +++ /dev/null @@ -1,267 +0,0 @@ - - - - - scapi.authentication.BasicAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module authentication :: - Class BasicAuthenticator - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class BasicAuthenticator

source code

-
-object --+
-         |
-        BasicAuthenticator
-
- -
- - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - user, - password, - consumer, - consumer_secret)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
augment_request(self, - req, - parameters) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - user, - password, - consumer, - consumer_secret) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthAuthenticator-class.html b/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthAuthenticator-class.html deleted file mode 100644 index de4541aa2..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthAuthenticator-class.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - scapi.authentication.OAuthAuthenticator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module authentication :: - Class OAuthAuthenticator - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class OAuthAuthenticator

source code

-
-object --+
-         |
-        OAuthAuthenticator
-
- -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - consumer, - consumer_secret, - token, - secret, - signature_method=OAuthSignatureMethod_HMAC_SHA1())
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
augment_request(self, - req, - parameters, - use_multipart=False, - oauth_callback=None, - oauth_verifier=None) - source code - -
- -
-   - - - - - - -
generate_timestamp(self) - source code - -
- -
-   - - - - - - -
generate_nonce(self, - length=8) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - OAUTH_API_VERSION = '1.0' -
-   - - AUTHORIZATION_HEADER = 'Authorization' -
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - consumer, - consumer_secret, - token, - secret, - signature_method=OAuthSignatureMethod_HMAC_SHA1()) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html b/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html deleted file mode 100644 index 82e3a5ee0..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.authentication.OAuthSignatureMethod_HMAC_SHA1-class.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - scapi.authentication.OAuthSignatureMethod_HMAC_SHA1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module authentication :: - Class OAuthSignatureMethod_HMAC_SHA1 - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class OAuthSignatureMethod_HMAC_SHA1

source code

-
-object --+
-         |
-        OAuthSignatureMethod_HMAC_SHA1
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
get_name(self) - source code - -
- -
-   - - - - - - -
build_signature(self, - request, - parameters, - consumer_secret, - token_secret, - oauth_parameters) - source code - -
- -
-   - - - - - - -
get_normalized_http_method(self, - request) - source code - -
- -
-   - - - - - - -
get_normalized_http_url(self, - request) - source code - -
- -
-   - - - - - - -
get_normalized_parameters(self, - params) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __init__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - FORBIDDEN = ['realm', 'oauth_signature'] -
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.config-module.html b/python_apps/soundcloud-api/docs/api/scapi.config-module.html deleted file mode 100644 index 41aa49291..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.config-module.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - scapi.config - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module config - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module config

source code

- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.config-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.config-pysrc.html deleted file mode 100644 index 27eedf60c..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.config-pysrc.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - scapi.config - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module config - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.config

-
-1   
-2   
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json-module.html b/python_apps/soundcloud-api/docs/api/scapi.json-module.html deleted file mode 100644 index 9ac8f0d48..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json-module.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - scapi.json - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module json

source code

- - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Classes[hide private]
-
-   - - _StringGenerator -
-   - - WriteException -
-   - - ReadException -
-   - - JsonReader -
-   - - JsonWriter -
- - - - - - - - - - - - -
- - - - - -
Functions[hide private]
-
-   - - - - - - -
write(obj, - escaped_forward_slash=False) - source code - -
- -
-   - - - - - - -
read(s) - source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.json-pysrc.html deleted file mode 100644 index cde009caf..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json-pysrc.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - scapi.json - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.json

-
-  1  import string 
-  2  import types 
-  3   
-  4  ##    json.py implements a JSON (http://json.org) reader and writer. 
-  5  ##    Copyright (C) 2005  Patrick D. Logan 
-  6  ##    Contact mailto:patrickdlogan@stardecisions.com 
-  7  ## 
-  8  ##    This library is free software; you can redistribute it and/or 
-  9  ##    modify it under the terms of the GNU Lesser General Public 
- 10  ##    License as published by the Free Software Foundation; either 
- 11  ##    version 2.1 of the License, or (at your option) any later version. 
- 12  ## 
- 13  ##    This library is distributed in the hope that it will be useful, 
- 14  ##    but WITHOUT ANY WARRANTY; without even the implied warranty of 
- 15  ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
- 16  ##    Lesser General Public License for more details. 
- 17  ## 
- 18  ##    You should have received a copy of the GNU Lesser General Public 
- 19  ##    License along with this library; if not, write to the Free Software 
- 20  ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- 21   
- 22   
-
23 -class _StringGenerator(object): -
24 - def __init__(self, string): -
25 self.string = string - 26 self.index = -1 -
27 - def peek(self): -
28 i = self.index + 1 - 29 if i < len(self.string): - 30 return self.string[i] - 31 else: - 32 return None -
33 - def next(self): -
34 self.index += 1 - 35 if self.index < len(self.string): - 36 return self.string[self.index] - 37 else: - 38 raise StopIteration -
39 - def all(self): -
40 return self.string -
41 -
42 -class WriteException(Exception): -
43 pass -
44 -
45 -class ReadException(Exception): -
46 pass -
47 -
48 -class JsonReader(object): -
49 hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15} - 50 escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'} - 51 -
52 - def read(self, s): -
53 self._generator = _StringGenerator(s) - 54 result = self._read() - 55 return result -
56 -
57 - def _read(self): -
58 self._eatWhitespace() - 59 peek = self._peek() - 60 if peek is None: - 61 raise ReadException, "Nothing to read: '%s'" % self._generator.all() - 62 if peek == '{': - 63 return self._readObject() - 64 elif peek == '[': - 65 return self._readArray() - 66 elif peek == '"': - 67 return self._readString() - 68 elif peek == '-' or peek.isdigit(): - 69 return self._readNumber() - 70 elif peek == 't': - 71 return self._readTrue() - 72 elif peek == 'f': - 73 return self._readFalse() - 74 elif peek == 'n': - 75 return self._readNull() - 76 elif peek == '/': - 77 self._readComment() - 78 return self._read() - 79 else: - 80 raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all() -
81 -
82 - def _readTrue(self): -
83 self._assertNext('t', "true") - 84 self._assertNext('r', "true") - 85 self._assertNext('u', "true") - 86 self._assertNext('e', "true") - 87 return True -
88 -
89 - def _readFalse(self): -
90 self._assertNext('f', "false") - 91 self._assertNext('a', "false") - 92 self._assertNext('l', "false") - 93 self._assertNext('s', "false") - 94 self._assertNext('e', "false") - 95 return False -
96 -
97 - def _readNull(self): -
98 self._assertNext('n', "null") - 99 self._assertNext('u', "null") -100 self._assertNext('l', "null") -101 self._assertNext('l', "null") -102 return None -
103 -
104 - def _assertNext(self, ch, target): -
105 if self._next() != ch: -106 raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all()) -
107 -
108 - def _readNumber(self): -
109 isfloat = False -110 result = self._next() -111 peek = self._peek() -112 while peek is not None and (peek.isdigit() or peek == "."): -113 isfloat = isfloat or peek == "." -114 result = result + self._next() -115 peek = self._peek() -116 try: -117 if isfloat: -118 return float(result) -119 else: -120 return int(result) -121 except ValueError: -122 raise ReadException, "Not a valid JSON number: '%s'" % result -
123 -
124 - def _readString(self): -
125 result = "" -126 assert self._next() == '"' -127 try: -128 while self._peek() != '"': -129 ch = self._next() -130 if ch == "\\": -131 ch = self._next() -132 if ch in 'brnft': -133 ch = self.escapes[ch] -134 elif ch == "u": -135 ch4096 = self._next() -136 ch256 = self._next() -137 ch16 = self._next() -138 ch1 = self._next() -139 n = 4096 * self._hexDigitToInt(ch4096) -140 n += 256 * self._hexDigitToInt(ch256) -141 n += 16 * self._hexDigitToInt(ch16) -142 n += self._hexDigitToInt(ch1) -143 ch = unichr(n) -144 elif ch not in '"/\\': -145 raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all()) -146 result = result + ch -147 except StopIteration: -148 raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all() -149 assert self._next() == '"' -150 return result -
151 -
152 - def _hexDigitToInt(self, ch): -
153 try: -154 result = self.hex_digits[ch.upper()] -155 except KeyError: -156 try: -157 result = int(ch) -158 except ValueError: -159 raise ReadException, "The character %s is not a hex digit." % ch -160 return result -
161 -
162 - def _readComment(self): -
163 assert self._next() == "/" -164 second = self._next() -165 if second == "/": -166 self._readDoubleSolidusComment() -167 elif second == '*': -168 self._readCStyleComment() -169 else: -170 raise ReadException, "Not a valid JSON comment: %s" % self._generator.all() -
171 -
172 - def _readCStyleComment(self): -
173 try: -174 done = False -175 while not done: -176 ch = self._next() -177 done = (ch == "*" and self._peek() == "/") -178 if not done and ch == "/" and self._peek() == "*": -179 raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all() -180 self._next() -181 except StopIteration: -182 raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all() -
183 -
184 - def _readDoubleSolidusComment(self): -
185 try: -186 ch = self._next() -187 while ch != "\r" and ch != "\n": -188 ch = self._next() -189 except StopIteration: -190 pass -
191 -
192 - def _readArray(self): -
193 result = [] -194 assert self._next() == '[' -195 done = self._peek() == ']' -196 while not done: -197 item = self._read() -198 result.append(item) -199 self._eatWhitespace() -200 done = self._peek() == ']' -201 if not done: -202 ch = self._next() -203 if ch != ",": -204 raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) -205 assert ']' == self._next() -206 return result -
207 -
208 - def _readObject(self): -
209 result = {} -210 assert self._next() == '{' -211 done = self._peek() == '}' -212 while not done: -213 key = self._read() -214 if type(key) is not types.StringType: -215 raise ReadException, "Not a valid JSON object key (should be a string): %s" % key -216 self._eatWhitespace() -217 ch = self._next() -218 if ch != ":": -219 raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch) -220 self._eatWhitespace() -221 val = self._read() -222 result[key] = val -223 self._eatWhitespace() -224 done = self._peek() == '}' -225 if not done: -226 ch = self._next() -227 if ch != ",": -228 raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) -229 assert self._next() == "}" -230 return result -
231 -
232 - def _eatWhitespace(self): -
233 p = self._peek() -234 while p is not None and p in string.whitespace or p == '/': -235 if p == '/': -236 self._readComment() -237 else: -238 self._next() -239 p = self._peek() -
240 -
241 - def _peek(self): -
242 return self._generator.peek() -
243 -
244 - def _next(self): -
245 return self._generator.next() -
246 -
247 -class JsonWriter(object): -
248 -
249 - def _append(self, s): -
250 self._results.append(s) -
251 -
252 - def write(self, obj, escaped_forward_slash=False): -
253 self._escaped_forward_slash = escaped_forward_slash -254 self._results = [] -255 self._write(obj) -256 return "".join(self._results) -
257 -
258 - def _write(self, obj): -
259 ty = type(obj) -260 if ty is types.DictType: -261 n = len(obj) -262 self._append("{") -263 for k, v in obj.items(): -264 self._write(k) -265 self._append(":") -266 self._write(v) -267 n = n - 1 -268 if n > 0: -269 self._append(",") -270 self._append("}") -271 elif ty is types.ListType or ty is types.TupleType: -272 n = len(obj) -273 self._append("[") -274 for item in obj: -275 self._write(item) -276 n = n - 1 -277 if n > 0: -278 self._append(",") -279 self._append("]") -280 elif ty is types.StringType or ty is types.UnicodeType: -281 self._append('"') -282 obj = obj.replace('\\', r'\\') -283 if self._escaped_forward_slash: -284 obj = obj.replace('/', r'\/') -285 obj = obj.replace('"', r'\"') -286 obj = obj.replace('\b', r'\b') -287 obj = obj.replace('\f', r'\f') -288 obj = obj.replace('\n', r'\n') -289 obj = obj.replace('\r', r'\r') -290 obj = obj.replace('\t', r'\t') -291 self._append(obj) -292 self._append('"') -293 elif ty is types.IntType or ty is types.LongType: -294 self._append(str(obj)) -295 elif ty is types.FloatType: -296 self._append("%f" % obj) -297 elif obj is True: -298 self._append("true") -299 elif obj is False: -300 self._append("false") -301 elif obj is None: -302 self._append("null") -303 else: -304 raise WriteException, "Cannot write in JSON: %s" % repr(obj) -
305 -
306 -def write(obj, escaped_forward_slash=False): -
307 return JsonWriter().write(obj, escaped_forward_slash) -
308 -
309 -def read(s): -
310 return JsonReader().read(s) -
311 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json.JsonReader-class.html b/python_apps/soundcloud-api/docs/api/scapi.json.JsonReader-class.html deleted file mode 100644 index bad1801ae..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json.JsonReader-class.html +++ /dev/null @@ -1,544 +0,0 @@ - - - - - scapi.json.JsonReader - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json :: - Class JsonReader - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class JsonReader

source code

-
-object --+
-         |
-        JsonReader
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
read(self, - s) - source code - -
- -
-   - - - - - - -
_read(self) - source code - -
- -
-   - - - - - - -
_readTrue(self) - source code - -
- -
-   - - - - - - -
_readFalse(self) - source code - -
- -
-   - - - - - - -
_readNull(self) - source code - -
- -
-   - - - - - - -
_assertNext(self, - ch, - target) - source code - -
- -
-   - - - - - - -
_readNumber(self) - source code - -
- -
-   - - - - - - -
_readString(self) - source code - -
- -
-   - - - - - - -
_hexDigitToInt(self, - ch) - source code - -
- -
-   - - - - - - -
_readComment(self) - source code - -
- -
-   - - - - - - -
_readCStyleComment(self) - source code - -
- -
-   - - - - - - -
_readDoubleSolidusComment(self) - source code - -
- -
-   - - - - - - -
_readArray(self) - source code - -
- -
-   - - - - - - -
_readObject(self) - source code - -
- -
-   - - - - - - -
_eatWhitespace(self) - source code - -
- -
-   - - - - - - -
_peek(self) - source code - -
- -
-   - - - - - - -
_next(self) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __init__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - hex_digits = {'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F'... -
-   - - escapes = {'b': '\x08', 'f': '\x0c', 'n': '\n', 'r': '\r', 't'... -
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Class Variable Details[hide private]
-
- -
- -
-

hex_digits

- -
-
-
-
Value:
-
-{'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15}
-
-
-
-
-
- -
- -
-

escapes

- -
-
-
-
Value:
-
-{'b': '\x08', 'f': '\x0c', 'n': '\n', 'r': '\r', 't': '\t'}
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json.JsonWriter-class.html b/python_apps/soundcloud-api/docs/api/scapi.json.JsonWriter-class.html deleted file mode 100644 index c376a942f..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json.JsonWriter-class.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - scapi.json.JsonWriter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json :: - Class JsonWriter - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class JsonWriter

source code

-
-object --+
-         |
-        JsonWriter
-
- -
- - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
_append(self, - s) - source code - -
- -
-   - - - - - - -
write(self, - obj, - escaped_forward_slash=False) - source code - -
- -
-   - - - - - - -
_write(self, - obj) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __init__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json.ReadException-class.html b/python_apps/soundcloud-api/docs/api/scapi.json.ReadException-class.html deleted file mode 100644 index acbf8e4c3..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json.ReadException-class.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - scapi.json.ReadException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json :: - Class ReadException - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class ReadException

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              ReadException
-
- -
- - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from exceptions.Exception: - __init__, - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __repr__, - __setattr__, - __setstate__, - __str__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json.WriteException-class.html b/python_apps/soundcloud-api/docs/api/scapi.json.WriteException-class.html deleted file mode 100644 index b97e08ff6..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json.WriteException-class.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - scapi.json.WriteException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json :: - Class WriteException - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class WriteException

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              WriteException
-
- -
- - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-

Inherited from exceptions.Exception: - __init__, - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __repr__, - __setattr__, - __setstate__, - __str__ -

-

Inherited from object: - __hash__, - __reduce_ex__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.json._StringGenerator-class.html b/python_apps/soundcloud-api/docs/api/scapi.json._StringGenerator-class.html deleted file mode 100644 index ead736d6f..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.json._StringGenerator-class.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - scapi.json._StringGenerator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module json :: - Class _StringGenerator - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class _StringGenerator

source code

-
-object --+
-         |
-        _StringGenerator
-
- -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
__init__(self, - string)
- x.__init__(...) initializes x; see x.__class__.__doc__ for signature
- source code - -
- -
-   - - - - - - -
peek(self) - source code - -
- -
-   - - - - - - -
next(self) - source code - -
- -
-   - - - - - - -
all(self) - source code - -
- -
-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

__init__(self, - string) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see x.__class__.__doc__ for - signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests-module.html b/python_apps/soundcloud-api/docs/api/scapi.tests-module.html deleted file mode 100644 index 41a0acbfc..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests-module.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - scapi.tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Package tests

source code

- - - - - - - -
- - - - - -
Submodules[hide private]
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.tests-pysrc.html deleted file mode 100644 index a967c5152..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests-pysrc.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - scapi.tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Package scapi.tests

-
-1   
-2   
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-module.html b/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-module.html deleted file mode 100644 index cff686d84..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-module.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - scapi.tests.scapi_tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module scapi_tests - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module scapi_tests

source code

- - - - - - - - - -
- - - - - -
Classes[hide private]
-
-   - - SCAPITests -
- - - - - - - - - - - - -
- - - - - -
Variables[hide private]
-
-   - - logger = logging.getLogger("scapi.tests") -
-   - - api_logger = logging.getLogger("scapi") -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-pysrc.html deleted file mode 100644 index bca835c59..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests-pysrc.html +++ /dev/null @@ -1,760 +0,0 @@ - - - - - scapi.tests.scapi_tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module scapi_tests - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.tests.scapi_tests

-
-  1  from __future__ import with_statement 
-  2   
-  3  import os 
-  4  import urllib2 
-  5  import itertools 
-  6  from textwrap import dedent 
-  7  import pkg_resources 
-  8  import logging 
-  9  import webbrowser 
- 10  from unittest import TestCase 
- 11   
- 12  from configobj import ConfigObj 
- 13  from validate import Validator 
- 14   
- 15   
- 16  import scapi 
- 17  import scapi.authentication 
- 18   
- 19  logger = logging.getLogger("scapi.tests") 
- 20   
- 21  api_logger = logging.getLogger("scapi") 
-
22 - 23 - 24 -class SCAPITests(TestCase): -
25 - 26 CONFIG_NAME = "test.ini" - 27 TOKEN = None - 28 SECRET = None - 29 CONSUMER = None - 30 CONSUMER_SECRET = None - 31 API_HOST = None - 32 USER = None - 33 PASSWORD = None - 34 AUTHENTICATOR = None - 35 RUN_INTERACTIVE_TESTS = False - 36 - 37 -
38 - def setUp(self): -
39 self._load_config() - 40 assert pkg_resources.resource_exists("scapi.tests.test_connect", "knaster.mp3") - 41 self.data = pkg_resources.resource_stream("scapi.tests.test_connect", "knaster.mp3") - 42 self.artwork_data = pkg_resources.resource_stream("scapi.tests.test_connect", "spam.jpg") -
43 - 44 CONFIGSPEC=dedent(""" - 45 [api] - 46 token=string - 47 secret=string - 48 consumer=string - 49 consumer_secret=string - 50 api_host=string - 51 user=string - 52 password=string - 53 authenticator=option('oauth', 'base', default='oauth') - 54 - 55 [proxy] - 56 use_proxy=boolean(default=false) - 57 proxy=string(default=http://127.0.0.1:10000/) - 58 - 59 [logging] - 60 test_logger=string(default=ERROR) - 61 api_logger=string(default=ERROR) - 62 - 63 [test] - 64 run_interactive_tests=boolean(default=false) - 65 """) - 66 - 67 -
68 - def _load_config(self): -
69 """ - 70 Loads the configuration by looking from - 71 - 72 - the environment variable SCAPI_CONFIG - 73 - the installation location upwards until it finds test.ini - 74 - the current working directory upwards until it finds test.ini - 75 - 76 Raises an error if there is no config found - 77 """ - 78 config_name = self.CONFIG_NAME - 79 - 80 name = None - 81 - 82 if "SCAPI_CONFIG" in os.environ: - 83 if os.path.exists(os.environ["SCAPI_CONFIG"]): - 84 name = os.environ["SCAPI_CONFIG"] - 85 - 86 def search_for_config(current): - 87 while current: - 88 name = os.path.join(current, config_name) - 89 if os.path.exists(name): - 90 return name - 91 new_current = os.path.dirname(current) - 92 if new_current == current: - 93 return - 94 current = new_current -
95 - 96 if name is None: - 97 name = search_for_config(os.path.dirname(__file__)) - 98 if name is None: - 99 name = search_for_config(os.getcwd()) -100 -101 if not name: -102 raise Exception("No test configuration file found!") -103 -104 parser = ConfigObj(name, configspec=self.CONFIGSPEC.split("\n")) -105 val = Validator() -106 if not parser.validate(val): -107 raise Exception("Config file validation error") -108 -109 api = parser['api'] -110 self.TOKEN = api.get('token') -111 self.SECRET = api.get('secret') -112 self.CONSUMER = api.get('consumer') -113 self.CONSUMER_SECRET = api.get('consumer_secret') -114 self.API_HOST = api.get('api_host') -115 self.USER = api.get('user', None) -116 self.PASSWORD = api.get('password', None) -117 self.AUTHENTICATOR = api.get("authenticator") -118 -119 # reset the hard-coded values in the api -120 if self.API_HOST: -121 scapi.AUTHORIZATION_URL = "http://%s/oauth/authorize" % self.API_HOST -122 scapi.REQUEST_TOKEN_URL = 'http://%s/oauth/request_token' % self.API_HOST -123 scapi.ACCESS_TOKEN_URL = 'http://%s/oauth/access_token' % self.API_HOST -124 -125 if "proxy" in parser and parser["proxy"]["use_proxy"]: -126 scapi.USE_PROXY = True -127 scapi.PROXY = parser["proxy"]["proxy"] -128 -129 if "logging" in parser: -130 logger.setLevel(getattr(logging, parser["logging"]["test_logger"])) -131 api_logger.setLevel(getattr(logging, parser["logging"]["api_logger"])) -132 -133 self.RUN_INTERACTIVE_TESTS = parser["test"]["run_interactive_tests"] -
134 -135 -136 @property -
137 - def root(self): -
138 """ -139 Return the properly configured root-scope. -140 """ -141 if self.AUTHENTICATOR == "oauth": -142 authenticator = scapi.authentication.OAuthAuthenticator(self.CONSUMER, -143 self.CONSUMER_SECRET, -144 self.TOKEN, -145 self.SECRET) -146 elif self.AUTHENTICATOR == "base": -147 authenticator = scapi.authentication.BasicAuthenticator(self.USER, self.PASSWORD, self.CONSUMER, self.CONSUMER_SECRET) -148 else: -149 raise Exception("Unknown authenticator setting: %s", self.AUTHENTICATOR) -150 -151 connector = scapi.ApiConnector(host=self.API_HOST, -152 authenticator=authenticator) -153 -154 logger.debug("RootScope: %s authenticator: %s", self.API_HOST, self.AUTHENTICATOR) -155 return scapi.Scope(connector) -
156 -157 -
158 - def test_connect(self): -
159 """ -160 test_connect -161 -162 Tries to connect & performs some read-only operations. -163 """ -164 sca = self.root -165 # quite_a_few_users = list(itertools.islice(sca.users(), 0, 127)) -166 -167 # logger.debug(quite_a_few_users) -168 # assert isinstance(quite_a_few_users, list) and isinstance(quite_a_few_users[0], scapi.User) -169 user = sca.me() -170 logger.debug(user) -171 assert isinstance(user, scapi.User) -172 contacts = list(user.contacts()) -173 assert isinstance(contacts, list) -174 if contacts: -175 assert isinstance(contacts[0], scapi.User) -176 logger.debug(contacts) -177 tracks = list(user.tracks()) -178 assert isinstance(tracks, list) -179 if tracks: -180 assert isinstance(tracks[0], scapi.Track) -181 logger.debug(tracks) -
182 -183 -
185 """ -186 This test is commented out because it needs user-interaction. -187 """ -188 if not self.RUN_INTERACTIVE_TESTS: -189 return -190 oauth_authenticator = scapi.authentication.OAuthAuthenticator(self.CONSUMER, -191 self.CONSUMER_SECRET, -192 None, -193 None) -194 -195 sca = scapi.ApiConnector(host=self.API_HOST, authenticator=oauth_authenticator) -196 token, secret = sca.fetch_request_token() -197 authorization_url = sca.get_request_token_authorization_url(token) -198 webbrowser.open(authorization_url) -199 oauth_verifier = raw_input("please enter verifier code as seen in the browser:") -200 -201 oauth_authenticator = scapi.authentication.OAuthAuthenticator(self.CONSUMER, -202 self.CONSUMER_SECRET, -203 token, -204 secret) -205 -206 sca = scapi.ApiConnector(self.API_HOST, authenticator=oauth_authenticator) -207 token, secret = sca.fetch_access_token(oauth_verifier) -208 logger.info("Access token: '%s'", token) -209 logger.info("Access token secret: '%s'", secret) -210 # force oauth-authentication with the new parameters, and -211 # then invoke some simple test -212 self.AUTHENTICATOR = "oauth" -213 self.TOKEN = token -214 self.SECRET = secret -215 self.test_connect() -
216 -217 -
218 - def test_track_creation(self): -
219 sca = self.root -220 track = sca.Track.new(title='bar', asset_data=self.data) -221 assert isinstance(track, scapi.Track) -
222 -223 -
224 - def test_track_update(self): -
225 sca = self.root -226 track = sca.Track.new(title='bar', asset_data=self.data) -227 assert isinstance(track, scapi.Track) -228 track.title='baz' -229 track = sca.Track.get(track.id) -230 assert track.title == "baz" -
231 -232 -
233 - def test_scoped_track_creation(self): -
234 sca = self.root -235 user = sca.me() -236 track = user.tracks.new(title="bar", asset_data=self.data) -237 assert isinstance(track, scapi.Track) -
238 -239 -
240 - def test_upload(self): -
241 sca = self.root -242 sca = self.root -243 track = sca.Track.new(title='bar', asset_data=self.data) -244 assert isinstance(track, scapi.Track) -
245 -246 -
247 - def test_contact_list(self): -
248 sca = self.root -249 user = sca.me() -250 contacts = list(user.contacts()) -251 assert isinstance(contacts, list) -252 if contacts: -253 assert isinstance(contacts[0], scapi.User) -
254 -255 -
256 - def test_permissions(self): -
257 sca = self.root -258 user = sca.me() -259 tracks = itertools.islice(user.tracks(), 1) -260 for track in tracks: -261 permissions = list(track.permissions()) -262 logger.debug(permissions) -263 assert isinstance(permissions, list) -264 if permissions: -265 assert isinstance(permissions[0], scapi.User) -
266 -267 -
268 - def test_setting_permissions(self): -
269 sca = self.root -270 me = sca.me() -271 track = sca.Track.new(title='bar', sharing="private", asset_data=self.data) -272 assert track.sharing == "private" -273 users = itertools.islice(sca.users(), 10) -274 users_to_set = [user for user in users if user != me] -275 assert users_to_set, "Didn't find any suitable users" -276 track.permissions = users_to_set -277 assert set(track.permissions()) == set(users_to_set) -
278 -279 -
280 - def test_setting_comments(self): -
281 sca = self.root -282 user = sca.me() -283 track = sca.Track.new(title='bar', sharing="private", asset_data=self.data) -284 comment = sca.Comment.create(body="This is the body of my comment", timestamp=10) -285 track.comments = comment -286 assert track.comments().next().body == comment.body -
287 -288 -
290 sca = self.root -291 track = sca.Track.new(title='bar', sharing="private", asset_data=self.data) -292 cbody = "This is the body of my comment" -293 track.comments.new(body=cbody, timestamp=10) -294 assert list(track.comments())[0].body == cbody -
295 -296 -
298 sca = self.root -299 me = sca.me() -300 for user in sca.users(): -301 if user != me: -302 user_to_set = user -303 break -304 -305 contacts = list(me.contacts()) -306 if user_to_set in contacts: -307 me.contacts.remove(user_to_set) -308 -309 me.contacts.append(user_to_set) -310 -311 contacts = list(me.contacts() ) -312 assert user_to_set.id in [c.id for c in contacts] -313 -314 me.contacts.remove(user_to_set) -315 -316 contacts = list(me.contacts() ) -317 assert user_to_set not in contacts -
318 -319 -
320 - def test_favorites(self): -
321 sca = self.root -322 me = sca.me() -323 -324 favorites = list(me.favorites()) -325 assert favorites == [] or isinstance(favorites[0], scapi.Track) -326 -327 track = None -328 for user in sca.users(): -329 if user == me: -330 continue -331 for track in user.tracks(): -332 break -333 if track is not None: -334 break -335 -336 me.favorites.append(track) -337 -338 favorites = list(me.favorites()) -339 assert track in favorites -340 -341 me.favorites.remove(track) -342 -343 favorites = list(me.favorites()) -344 assert track not in favorites -
345 -346 -
347 - def test_large_list(self): -
348 sca = self.root -349 -350 tracks = list(sca.tracks()) -351 if len(tracks) < scapi.ApiConnector.LIST_LIMIT: -352 for i in xrange(scapi.ApiConnector.LIST_LIMIT): -353 sca.Track.new(title='test_track_%i' % i, asset_data=self.data) -354 all_tracks = sca.tracks() -355 assert not isinstance(all_tracks, list) -356 all_tracks = list(all_tracks) -357 assert len(all_tracks) > scapi.ApiConnector.LIST_LIMIT -
358 -359 -360 -
361 - def test_filtered_list(self): -
362 sca = self.root -363 -364 tracks = list(sca.tracks(params={ -365 "bpm[from]" : "180", -366 })) -367 if len(tracks) < scapi.ApiConnector.LIST_LIMIT: -368 for i in xrange(scapi.ApiConnector.LIST_LIMIT): -369 sca.Track.new(title='test_track_%i' % i, asset_data=self.data) -370 all_tracks = sca.tracks() -371 assert not isinstance(all_tracks, list) -372 all_tracks = list(all_tracks) -373 assert len(all_tracks) > scapi.ApiConnector.LIST_LIMIT -
374 -375 -
376 - def test_events(self): -
377 events = list(self.root.events()) -378 assert isinstance(events, list) -379 assert isinstance(events[0], scapi.Event) -
380 -381 -
382 - def test_me_having_stress(self): -
383 sca = self.root -384 for _ in xrange(20): -385 self.setUp() -386 sca.me() -
387 -388 -
389 - def test_non_global_api(self): -
390 root = self.root -391 me = root.me() -392 assert isinstance(me, scapi.User) -393 -394 # now get something *from* that user -395 list(me.favorites()) -
396 -397 -
398 - def test_playlists(self): -
399 sca = self.root -400 playlists = list(itertools.islice(sca.playlists(), 0, 127)) -401 for playlist in playlists: -402 tracks = playlist.tracks -403 if not isinstance(tracks, list): -404 tracks = [tracks] -405 for trackdata in tracks: -406 print trackdata -407 #user = trackdata.user -408 #print user -409 #print user.tracks() -410 print playlist.user -411 break -
412 -413 -414 -415 -
416 - def test_playlist_creation(self): -
417 sca = self.root -418 sca.Playlist.new(title="I'm so happy, happy, happy, happy!") -
419 -420 -421 -
422 - def test_groups(self): -
423 sca = self.root -424 groups = list(itertools.islice(sca.groups(), 0, 127)) -425 for group in groups: -426 users = group.users() -427 for user in users: -428 pass -
429 -430 -
432 sca = self.root -433 emails = [dict(address="deets@web.de"), dict(address="hannes@soundcloud.com")] -434 track = sca.Track.new(title='bar', asset_data=self.data, -435 shared_to=dict(emails=emails) -436 ) -437 assert isinstance(track, scapi.Track) -
438 -439 -440 -
442 sca = self.root -443 track = sca.Track.new(title='bar', -444 asset_data=self.data, -445 artwork_data=self.artwork_data, -446 ) -447 assert isinstance(track, scapi.Track) -448 -449 track.title = "foobarbaz" -
450 -451 -452 -
453 - def test_oauth_get_signing(self): -
454 sca = self.root -455 -456 url = "http://api.soundcloud.dev/oauth/test_request" -457 params = dict(foo="bar", -458 baz="padamm", -459 ) -460 url += sca._create_query_string(params) -461 signed_url = sca.oauth_sign_get_request(url) -462 -463 -464 res = urllib2.urlopen(signed_url).read() -465 assert "oauth_nonce" in res -
466 -467 -
468 - def test_streaming(self): -
469 sca = self.root -470 -471 track = sca.tracks(params={ -472 "filter" : "streamable", -473 }).next() -474 -475 -476 assert isinstance(track, scapi.Track) -477 -478 stream_url = track.stream_url -479 -480 signed_url = track.oauth_sign_get_request(stream_url) -
481 -482 -
483 - def test_downloadable(self): -
484 sca = self.root -485 -486 track = sca.tracks(params={ -487 "filter" : "downloadable", -488 }).next() -489 -490 -491 assert isinstance(track, scapi.Track) -492 -493 download_url = track.download_url -494 -495 signed_url = track.oauth_sign_get_request(download_url) -496 -497 data = urllib2.urlopen(signed_url).read() -498 assert data -
499 -500 -501 -
502 - def test_modifying_playlists(self): -
503 sca = self.root -504 -505 me = sca.me() -506 my_tracks = list(me.tracks()) -507 -508 assert my_tracks -509 -510 playlist = me.playlists().next() -511 playlist = sca.Playlist.get(playlist.id) -512 -513 assert isinstance(playlist, scapi.Playlist) -514 -515 pl_tracks = playlist.tracks -516 -517 playlist.title = "foobarbaz" -
518 -519 -520 -
521 - def test_track_deletion(self): -
522 sca = self.root -523 track = sca.Track.new(title='bar', asset_data=self.data, -524 ) -525 -526 sca.tracks.remove(track) -
527 -528 -529 -
531 sca = self.root -532 track = sca.Track.new(title='bar', -533 asset_data=self.data, -534 ) -535 assert isinstance(track, scapi.Track) -536 -537 track.artwork_data = self.artwork_data -
538 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests.SCAPITests-class.html b/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests.SCAPITests-class.html deleted file mode 100644 index 0c5a5a449..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.scapi_tests.SCAPITests-class.html +++ /dev/null @@ -1,1025 +0,0 @@ - - - - - scapi.tests.scapi_tests.SCAPITests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module scapi_tests :: - Class SCAPITests - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class SCAPITests

source code

-
-       object --+    
-                |    
-unittest.TestCase --+
-                    |
-                   SCAPITests
-
- -
- - - - - - - - - -
- - - - - -
Nested Classes[hide private]
-
-

Inherited from unittest.TestCase: - failureException -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
setUp(self)
- Hook method for setting up the test fixture before exercising it.
- source code - -
- -
-   - - - - - - -
_load_config(self)
- Loads the configuration by looking from
- source code - -
- -
-   - - - - - - -
test_connect(self)
- test_connect
- source code - -
- -
-   - - - - - - -
test_access_token_acquisition(self)
- This test is commented out because it needs user-interaction.
- source code - -
- -
-   - - - - - - -
test_track_creation(self) - source code - -
- -
-   - - - - - - -
test_track_update(self) - source code - -
- -
-   - - - - - - -
test_scoped_track_creation(self) - source code - -
- -
-   - - - - - - -
test_upload(self) - source code - -
- -
-   - - - - - - -
test_contact_list(self) - source code - -
- -
-   - - - - - - -
test_permissions(self) - source code - -
- -
-   - - - - - - -
test_setting_permissions(self) - source code - -
- -
-   - - - - - - -
test_setting_comments(self) - source code - -
- -
-   - - - - - - -
test_setting_comments_the_way_shawn_says_its_correct(self) - source code - -
- -
-   - - - - - - -
test_contact_add_and_removal(self) - source code - -
- -
-   - - - - - - -
test_favorites(self) - source code - -
- -
-   - - - - - - -
test_large_list(self) - source code - -
- -
-   - - - - - - -
test_filtered_list(self) - source code - -
- -
-   - - - - - - -
test_events(self) - source code - -
- -
-   - - - - - - -
test_me_having_stress(self) - source code - -
- -
-   - - - - - - -
test_non_global_api(self) - source code - -
- -
-   - - - - - - -
test_playlists(self) - source code - -
- -
-   - - - - - - -
test_playlist_creation(self) - source code - -
- -
-   - - - - - - -
test_groups(self) - source code - -
- -
-   - - - - - - -
test_track_creation_with_email_sharers(self) - source code - -
- -
-   - - - - - - -
test_track_creation_with_artwork(self) - source code - -
- -
-   - - - - - - -
test_oauth_get_signing(self) - source code - -
- -
-   - - - - - - -
test_streaming(self) - source code - -
- -
-   - - - - - - -
test_downloadable(self) - source code - -
- -
-   - - - - - - -
test_modifying_playlists(self) - source code - -
- -
-   - - - - - - -
test_track_deletion(self) - source code - -
- -
-   - - - - - - -
test_track_creation_with_updated_artwork(self) - source code - -
- -
-

Inherited from unittest.TestCase: - __call__, - __init__, - __repr__, - __str__, - assertAlmostEqual, - assertAlmostEquals, - assertEqual, - assertEquals, - assertFalse, - assertNotAlmostEqual, - assertNotAlmostEquals, - assertNotEqual, - assertNotEquals, - assertRaises, - assertTrue, - assert_, - countTestCases, - debug, - defaultTestResult, - fail, - failIf, - failIfAlmostEqual, - failIfEqual, - failUnless, - failUnlessAlmostEqual, - failUnlessEqual, - failUnlessRaises, - id, - run, - shortDescription, - tearDown -

-

Inherited from unittest.TestCase (private): - _exc_info -

-

Inherited from object: - __delattr__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Class Variables[hide private]
-
-   - - CONFIG_NAME = 'test.ini' -
-   - - TOKEN = None -
-   - - SECRET = None -
-   - - CONSUMER = None -
-   - - CONSUMER_SECRET = None -
-   - - API_HOST = None -
-   - - USER = None -
-   - - PASSWORD = None -
-   - - AUTHENTICATOR = None -
-   - - RUN_INTERACTIVE_TESTS = False -
-   - - CONFIGSPEC = '\n[api]\ntoken=string\nsecret=string\nconsumer=s... -
- - - - - - - - - - - - -
- - - - - -
Properties[hide private]
-
-   - - root
- Return the properly configured root-scope. -
-

Inherited from object: - __class__ -

-
- - - - - - -
- - - - - -
Method Details[hide private]
-
- -
- -
- - -
-

setUp(self) -

-
source code  -
- -

Hook method for setting up the test fixture before exercising it.

-
-
Overrides: - unittest.TestCase.setUp -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

_load_config(self) -

-
source code  -
- -

Loads the configuration by looking from

-
    -
  • - the environment variable SCAPI_CONFIG -
  • -
  • - the installation location upwards until it finds test.ini -
  • -
  • - the current working directory upwards until it finds test.ini -
  • -
-

Raises an error if there is no config found

-
-
-
-
- -
- -
- - -
-

test_connect(self) -

-
source code  -
- -

test_connect

-

Tries to connect & performs some read-only operations.

-
-
-
-
-
- - - - - - -
- - - - - -
Class Variable Details[hide private]
-
- -
- -
-

CONFIGSPEC

- -
-
-
-
Value:
-
-'''
-[api]
-token=string
-secret=string
-consumer=string
-consumer_secret=string
-api_host=string
-user=string
-...
-
-
-
-
-
-
- - - - - - -
- - - - - -
Property Details[hide private]
-
- -
- -
-

root

-

Return the properly configured root-scope.

-
-
Get Method:
-
unreachable.root(self) - - Return the properly configured root-scope. -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-module.html b/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-module.html deleted file mode 100644 index e4780ff79..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-module.html +++ /dev/null @@ -1,586 +0,0 @@ - - - - - scapi.tests.test_connect - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module test_connect - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module test_connect

source code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Functions[hide private]
-
-   - - - - - - -
setup() - source code - -
- -
-   - - - - - - -
load_config(config_name=None) - source code - -
- -
-   - - - - - - -
test_load_config() - source code - -
- -
-   - - - - - - -
test_connect() - source code - -
- -
-   - - - - - - -
test_access_token_acquisition()
- This test is commented out because it needs user-interaction.
- source code - -
- -
-   - - - - - - -
test_track_creation() - source code - -
- -
-   - - - - - - -
test_track_update() - source code - -
- -
-   - - - - - - -
test_scoped_track_creation() - source code - -
- -
-   - - - - - - -
test_upload() - source code - -
- -
-   - - - - - - -
test_contact_list() - source code - -
- -
-   - - - - - - -
test_permissions() - source code - -
- -
-   - - - - - - -
test_setting_permissions() - source code - -
- -
-   - - - - - - -
test_setting_comments() - source code - -
- -
-   - - - - - - -
test_setting_comments_the_way_shawn_says_its_correct() - source code - -
- -
-   - - - - - - -
test_contact_add_and_removal() - source code - -
- -
-   - - - - - - -
test_favorites() - source code - -
- -
-   - - - - - - -
test_large_list() - source code - -
- -
-   - - - - - - -
test_events() - source code - -
- -
-   - - - - - - -
test_me_having_stress() - source code - -
- -
-   - - - - - - -
test_non_global_api() - source code - -
- -
-   - - - - - - -
test_playlists() - source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Variables[hide private]
-
-   - - logger = logging.getLogger(__name__) -
-   - - _logger = logging.getLogger("scapi") -
-   - - RUN_INTERACTIVE_TESTS = False -
-   - - USE_OAUTH = True -
-   - - TOKEN = 'FjNE9aRTg8kpxuOjzwsX8Q' -
-   - - SECRET = 'NP5PGoyKcQv64E0aZgV4CRNzHfPwR4QghrWoqEgEE' -
-   - - CONSUMER = 'EEi2URUfM97pAAxHTogDpQ' -
-   - - CONSUMER_SECRET = 'NFYd8T3i4jVKGZ9TMy9LHaBQB3Sh8V5sxBiMeMZBow' -
-   - - API_HOST = 'api.soundcloud.dev:3000' -
-   - - USER = '' -
-   - - PASSWORD = '' -
-   - - CONFIG_NAME = 'soundcloud.cfg' -
-   - - CONNECTOR = None -
-   - - ROOT = None -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-pysrc.html deleted file mode 100644 index 3c0a41c84..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.test_connect-pysrc.html +++ /dev/null @@ -1,627 +0,0 @@ - - - - - scapi.tests.test_connect - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module test_connect - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.tests.test_connect

-
-  1  from __future__ import with_statement 
-  2  import os 
-  3  import tempfile 
-  4  import itertools 
-  5  from ConfigParser import SafeConfigParser 
-  6  import pkg_resources 
-  7  import scapi 
-  8  import scapi.authentication 
-  9  import logging 
- 10  import webbrowser 
- 11   
- 12  logger = logging.getLogger(__name__) 
- 13  logger.setLevel(logging.DEBUG) 
- 14  _logger = logging.getLogger("scapi") 
- 15  #_logger.setLevel(logging.DEBUG) 
- 16   
- 17  RUN_INTERACTIVE_TESTS = False 
- 18  USE_OAUTH = True 
- 19   
- 20  TOKEN  = "FjNE9aRTg8kpxuOjzwsX8Q" 
- 21  SECRET = "NP5PGoyKcQv64E0aZgV4CRNzHfPwR4QghrWoqEgEE" 
- 22  CONSUMER = "EEi2URUfM97pAAxHTogDpQ" 
- 23  CONSUMER_SECRET = "NFYd8T3i4jVKGZ9TMy9LHaBQB3Sh8V5sxBiMeMZBow" 
- 24  API_HOST = "api.soundcloud.dev:3000" 
- 25  USER = "" 
- 26  PASSWORD = "" 
- 27   
- 28  CONFIG_NAME = "soundcloud.cfg" 
- 29   
- 30  CONNECTOR = None 
- 31  ROOT = None 
-
32 -def setup(): -
33 global CONNECTOR, ROOT - 34 # load_config() - 35 #scapi.ApiConnector(host='192.168.2.101:3000', user='tiga', password='test') - 36 #scapi.ApiConnector(host='sandbox-api.soundcloud.com:3030', user='tiga', password='test') - 37 scapi.USE_PROXY = False - 38 scapi.PROXY = 'http://127.0.0.1:10000/' - 39 - 40 if USE_OAUTH: - 41 authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - 42 CONSUMER_SECRET, - 43 TOKEN, - 44 SECRET) - 45 else: - 46 authenticator = scapi.authentication.BasicAuthenticator(USER, PASSWORD, CONSUMER, CONSUMER_SECRET) - 47 - 48 logger.debug("API_HOST: %s", API_HOST) - 49 CONNECTOR = scapi.ApiConnector(host=API_HOST, - 50 authenticator=authenticator) - 51 ROOT = scapi.Scope(CONNECTOR) -
52 -
53 -def load_config(config_name=None): -
54 global TOKEN, SECRET, CONSUMER_SECRET, CONSUMER, API_HOST, USER, PASSWORD - 55 if config_name is None: - 56 config_name = CONFIG_NAME - 57 parser = SafeConfigParser() - 58 current = os.getcwd() - 59 while current: - 60 name = os.path.join(current, config_name) - 61 if os.path.exists(name): - 62 parser.read([name]) - 63 TOKEN = parser.get('global', 'accesstoken') - 64 SECRET = parser.get('global', 'accesstoken_secret') - 65 CONSUMER = parser.get('global', 'consumer') - 66 CONSUMER_SECRET = parser.get('global', 'consumer_secret') - 67 API_HOST = parser.get('global', 'host') - 68 USER = parser.get('global', 'user') - 69 PASSWORD = parser.get('global', 'password') - 70 logger.debug("token: %s", TOKEN) - 71 logger.debug("secret: %s", SECRET) - 72 logger.debug("consumer: %s", CONSUMER) - 73 logger.debug("consumer_secret: %s", CONSUMER_SECRET) - 74 logger.debug("user: %s", USER) - 75 logger.debug("password: %s", PASSWORD) - 76 logger.debug("host: %s", API_HOST) - 77 break - 78 new_current = os.path.dirname(current) - 79 if new_current == current: - 80 break - 81 current = new_current -
82 - 83 -
84 -def test_load_config(): -
85 base = tempfile.mkdtemp() - 86 oldcwd = os.getcwd() - 87 cdir = os.path.join(base, "foo") - 88 os.mkdir(cdir) - 89 os.chdir(cdir) - 90 test_config = """ - 91 [global] - 92 host=host - 93 consumer=consumer - 94 consumer_secret=consumer_secret - 95 accesstoken=accesstoken - 96 accesstoken_secret=accesstoken_secret - 97 user=user - 98 password=password - 99 """ -100 with open(os.path.join(base, CONFIG_NAME), "w") as cf: -101 cf.write(test_config) -102 load_config() -103 assert TOKEN == "accesstoken" and SECRET == "accesstoken_secret" and API_HOST == 'host' -104 assert CONSUMER == "consumer" and CONSUMER_SECRET == "consumer_secret" -105 assert USER == "user" and PASSWORD == "password" -106 os.chdir(oldcwd) -107 load_config() -
108 -109 -
110 -def test_connect(): -
111 sca = ROOT -112 quite_a_few_users = list(itertools.islice(sca.users(), 0, 127)) -113 -114 logger.debug(quite_a_few_users) -115 assert isinstance(quite_a_few_users, list) and isinstance(quite_a_few_users[0], scapi.User) -116 user = sca.me() -117 logger.debug(user) -118 assert isinstance(user, scapi.User) -119 contacts = list(user.contacts()) -120 assert isinstance(contacts, list) -121 assert isinstance(contacts[0], scapi.User) -122 logger.debug(contacts) -123 tracks = list(user.tracks()) -124 assert isinstance(tracks, list) -125 assert isinstance(tracks[0], scapi.Track) -126 logger.debug(tracks) -
127 -128 -
130 """ -131 This test is commented out because it needs user-interaction. -132 """ -133 if not RUN_INTERACTIVE_TESTS: -134 return -135 oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, -136 CONSUMER_SECRET, -137 None, -138 None) -139 -140 sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) -141 token, secret = sca.fetch_request_token() -142 authorization_url = sca.get_request_token_authorization_url(token) -143 webbrowser.open(authorization_url) -144 raw_input("please press return") -145 oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, -146 CONSUMER_SECRET, -147 token, -148 secret) -149 -150 sca = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) -151 token, secret = sca.fetch_access_token() -152 logger.info("Access token: '%s'", token) -153 logger.info("Access token secret: '%s'", secret) -154 oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, -155 CONSUMER_SECRET, -156 token, -157 secret) -158 -159 sca = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) -160 test_track_creation() -
161 -
163 sca = ROOT -164 track = sca.Track.new(title='bar') -165 assert isinstance(track, scapi.Track) -
166 -
167 -def test_track_update(): -
168 sca = ROOT -169 track = sca.Track.new(title='bar') -170 assert isinstance(track, scapi.Track) -171 track.title='baz' -172 track = sca.Track.get(track.id) -173 assert track.title == "baz" -
174 -
176 sca = ROOT -177 user = sca.me() -178 track = user.tracks.new(title="bar") -179 assert isinstance(track, scapi.Track) -
180 -
181 -def test_upload(): -
182 assert pkg_resources.resource_exists("scapi.tests.test_connect", "knaster.mp3") -183 data = pkg_resources.resource_stream("scapi.tests.test_connect", "knaster.mp3") -184 sca = ROOT -185 user = sca.me() -186 logger.debug(user) -187 asset = sca.assets.new(filedata=data) -188 assert isinstance(asset, scapi.Asset) -189 logger.debug(asset) -190 tracks = list(user.tracks()) -191 track = tracks[0] -192 track.assets.append(asset) -
193 -
194 -def test_contact_list(): -
195 sca = ROOT -196 user = sca.me() -197 contacts = list(user.contacts()) -198 assert isinstance(contacts, list) -199 assert isinstance(contacts[0], scapi.User) -
200 -
201 -def test_permissions(): -
202 sca = ROOT -203 user = sca.me() -204 tracks = itertools.islice(user.tracks(), 1) -205 for track in tracks: -206 permissions = list(track.permissions()) -207 logger.debug(permissions) -208 assert isinstance(permissions, list) -209 if permissions: -210 assert isinstance(permissions[0], scapi.User) -
211 -
213 sca = ROOT -214 me = sca.me() -215 track = sca.Track.new(title='bar', sharing="private") -216 assert track.sharing == "private" -217 users = itertools.islice(sca.users(), 10) -218 users_to_set = [user for user in users if user != me] -219 assert users_to_set, "Didn't find any suitable users" -220 track.permissions = users_to_set -221 assert set(track.permissions()) == set(users_to_set) -
222 -
224 sca = ROOT -225 user = sca.me() -226 track = sca.Track.new(title='bar', sharing="private") -227 comment = sca.Comment.create(body="This is the body of my comment", timestamp=10) -228 track.comments = comment -229 assert track.comments().next().body == comment.body -
230 -231 -
233 sca = ROOT -234 track = sca.Track.new(title='bar', sharing="private") -235 cbody = "This is the body of my comment" -236 track.comments.new(body=cbody, timestamp=10) -237 assert list(track.comments())[0].body == cbody -
238 -
240 sca = ROOT -241 me = sca.me() -242 for user in sca.users(): -243 if user != me: -244 user_to_set = user -245 break -246 -247 contacts = list(me.contacts()) -248 if user_to_set in contacts: -249 me.contacts.remove(user_to_set) -250 -251 me.contacts.append(user_to_set) -252 -253 contacts = list(me.contacts() ) -254 assert user_to_set.id in [c.id for c in contacts] -255 -256 me.contacts.remove(user_to_set) -257 -258 contacts = list(me.contacts() ) -259 assert user_to_set not in contacts -
260 -261 -
262 -def test_favorites(): -
263 sca = ROOT -264 me = sca.me() -265 -266 favorites = list(me.favorites()) -267 assert favorites == [] or isinstance(favorites[0], scapi.Track) -268 -269 track = None -270 for user in sca.users(): -271 if user == me: -272 continue -273 for track in user.tracks(): -274 break -275 if track is not None: -276 break -277 -278 me.favorites.append(track) -279 -280 favorites = list(me.favorites()) -281 assert track in favorites -282 -283 me.favorites.remove(track) -284 -285 favorites = list(me.favorites()) -286 assert track not in favorites -
287 -
288 -def test_large_list(): -
289 sca = ROOT -290 tracks = list(sca.tracks()) -291 if len(tracks) < scapi.ApiConnector.LIST_LIMIT: -292 for i in xrange(scapi.ApiConnector.LIST_LIMIT): -293 scapi.Track.new(title='test_track_%i' % i) -294 all_tracks = sca.tracks() -295 assert not isinstance(all_tracks, list) -296 all_tracks = list(all_tracks) -297 assert len(all_tracks) > scapi.ApiConnector.LIST_LIMIT -
298 -299 -
300 -def test_events(): -
301 events = list(ROOT.events()) -302 assert isinstance(events, list) -303 assert isinstance(events[0], scapi.Event) -
304 -
306 sca = ROOT -307 for _ in xrange(20): -308 setup() -309 sca.me() -
310 -
312 root = scapi.Scope(CONNECTOR) -313 me = root.me() -314 assert isinstance(me, scapi.User) -315 -316 # now get something *from* that user -317 favorites = list(me.favorites()) -318 assert favorites -
319 -
320 -def test_playlists(): -
321 sca = ROOT -322 playlists = list(itertools.islice(sca.playlists(), 0, 127)) -323 found = False -324 for playlist in playlists: -325 tracks = playlist.tracks -326 if not isinstance(tracks, list): -327 tracks = [tracks] -328 for trackdata in tracks: -329 print trackdata -330 user = trackdata.user -331 print user -332 print user.tracks() -333 print playlist.user -334 break -
335 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-module.html b/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-module.html deleted file mode 100644 index 6bf493f9d..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-module.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - scapi.tests.test_oauth - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module test_oauth - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module test_oauth

source code

- - - - - - - - - - - - -
- - - - - -
Functions[hide private]
-
-   - - - - - - -
test_base64_connect() - source code - -
- -
-   - - - - - - -
test_oauth_connect() - source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
Variables[hide private]
-
-   - - logger = logging.getLogger(__name__) -
-   - - _logger = logging.getLogger("scapi") -
-   - - TOKEN = 'QcciYu1FSwDSGKAG2mNw' -
-   - - SECRET = 'gJ2ok6ULUsYQB3rsBmpHCRHoFCAPOgK8ZjoIyxzris' -
-   - - CONSUMER = 'Cy2eLPrIMp4vOxjz9icdQ' -
-   - - CONSUMER_SECRET = 'KsBa272x6M2to00Vo5FdvZXt9kakcX7CDIPJoGwTro' -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-pysrc.html deleted file mode 100644 index 6ecf3c628..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.tests.test_oauth-pysrc.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - scapi.tests.test_oauth - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Package tests :: - Module test_oauth - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.tests.test_oauth

-
- 1  import pkg_resources 
- 2  import scapi 
- 3  import scapi.authentication 
- 4  import urllib 
- 5  import logging 
- 6   
- 7  logger = logging.getLogger(__name__) 
- 8  logger.setLevel(logging.DEBUG) 
- 9  _logger = logging.getLogger("scapi") 
-10  _logger.setLevel(logging.DEBUG) 
-11   
-12  TOKEN  = "QcciYu1FSwDSGKAG2mNw" 
-13  SECRET = "gJ2ok6ULUsYQB3rsBmpHCRHoFCAPOgK8ZjoIyxzris" 
-14  CONSUMER = "Cy2eLPrIMp4vOxjz9icdQ" 
-15  CONSUMER_SECRET = "KsBa272x6M2to00Vo5FdvZXt9kakcX7CDIPJoGwTro" 
-16   
-
18 scapi.USE_PROXY = True -19 scapi.PROXY = 'http://127.0.0.1:10000/' -20 scapi.SoundCloudAPI(host='192.168.2.31:3000', authenticator=scapi.authentication.BasicAuthenticator('tiga', 'test')) -21 sca = scapi.Scope() -22 assert isinstance(sca.me(), scapi.User) -
23 -24 -
26 scapi.USE_PROXY = True -27 scapi.PROXY = 'http://127.0.0.1:10000/' -28 scapi.SoundCloudAPI(host='192.168.2.31:3000', -29 authenticator=scapi.authentication.OAuthAuthenticator(CONSUMER, -30 CONSUMER_SECRET, -31 TOKEN, SECRET)) -32 -33 sca = scapi.Scope() -34 assert isinstance(sca.me(), scapi.User) -
35 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.util-module.html b/python_apps/soundcloud-api/docs/api/scapi.util-module.html deleted file mode 100644 index 2603fb0b1..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.util-module.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - scapi.util - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module util - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Module util

source code

- - - - - - - - - -
- - - - - -
Classes[hide private]
-
-   - - MultiDict -
- - - - - - - - - -
- - - - - -
Functions[hide private]
-
-   - - - - - - -
escape(s) - source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.util-pysrc.html b/python_apps/soundcloud-api/docs/api/scapi.util-pysrc.html deleted file mode 100644 index 1a018ed72..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.util-pysrc.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - scapi.util - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module util - - - - - - -
[hide private]
[frames] | no frames]
-
-

Source Code for Module scapi.util

-
- 1  ##    SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful 
- 2  ##    API 
- 3  ## 
- 4  ##    Copyright (C) 2008  Diez B. Roggisch 
- 5  ##    Contact mailto:deets@soundcloud.com 
- 6  ## 
- 7  ##    This library is free software; you can redistribute it and/or 
- 8  ##    modify it under the terms of the GNU Lesser General Public 
- 9  ##    License as published by the Free Software Foundation; either 
-10  ##    version 2.1 of the License, or (at your option) any later version. 
-11  ## 
-12  ##    This library is distributed in the hope that it will be useful, 
-13  ##    but WITHOUT ANY WARRANTY; without even the implied warranty of 
-14  ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-15  ##    Lesser General Public License for more details. 
-16  ## 
-17  ##    You should have received a copy of the GNU Lesser General Public 
-18  ##    License along with this library; if not, write to the Free Software 
-19  ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
-20   
-21  import urllib 
-22   
-
23 -def escape(s): -
24 # escape '/' too -25 return urllib.quote(s, safe='') -
26 -27 -28 -29 -30 -31 -
32 -class MultiDict(dict): -
33 -34 -
35 - def add(self, key, new_value): -
36 if key in self: -37 value = self[key] -38 if not isinstance(value, list): -39 value = [value] -40 self[key] = value -41 value.append(new_value) -42 else: -43 self[key] = new_value -
44 -45 -
46 - def iteritemslist(self): -
47 for key, value in self.iteritems(): -48 if not isinstance(value, list): -49 value = [value] -50 yield key, value -
51 -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/scapi.util.MultiDict-class.html b/python_apps/soundcloud-api/docs/api/scapi.util.MultiDict-class.html deleted file mode 100644 index fe7b460e9..000000000 --- a/python_apps/soundcloud-api/docs/api/scapi.util.MultiDict-class.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - scapi.util.MultiDict - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Package scapi :: - Module util :: - Class MultiDict - - - - - - -
[hide private]
[frames] | no frames]
-
- -

Class MultiDict

source code

-
-object --+    
-         |    
-      dict --+
-             |
-            MultiDict
-
- -
- - - - - - - - - - - - - - - -
- - - - - -
Instance Methods[hide private]
-
-   - - - - - - -
add(self, - key, - new_value) - source code - -
- -
-   - - - - - - -
iteritemslist(self) - source code - -
- -
-

Inherited from dict: - __cmp__, - __contains__, - __delitem__, - __eq__, - __ge__, - __getattribute__, - __getitem__, - __gt__, - __hash__, - __init__, - __iter__, - __le__, - __len__, - __lt__, - __ne__, - __new__, - __repr__, - __setitem__, - clear, - copy, - fromkeys, - get, - has_key, - items, - iteritems, - iterkeys, - itervalues, - keys, - pop, - popitem, - setdefault, - update, - values -

-

Inherited from object: - __delattr__, - __reduce__, - __reduce_ex__, - __setattr__, - __str__ -

-
- - - - - - - - - -
- - - - - -
Properties[hide private]
-
-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-everything.html b/python_apps/soundcloud-api/docs/api/toc-everything.html deleted file mode 100644 index 3ced23f23..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-everything.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Everything - - - - - -

Everything

-
-

All Classes

- exceptions.AssertionError
- scapi.Comment
scapi.Event
scapi.Group
- - scapi.Playlist
- - - scapi.Track
- scapi.User
- - - scapi.json.JsonReader
scapi.json.JsonWriter
scapi.json.ReadException
scapi.json.WriteException
- scapi.tests.scapi_tests.SCAPITests
-

All Functions

- scapi.json.read
scapi.json.write
- scapi.tests.test_connect.load_config
scapi.tests.test_connect.setup
scapi.tests.test_connect.test_access_token_acquisition
scapi.tests.test_connect.test_connect
scapi.tests.test_connect.test_contact_add_and_removal
scapi.tests.test_connect.test_contact_list
scapi.tests.test_connect.test_events
scapi.tests.test_connect.test_favorites
scapi.tests.test_connect.test_large_list
scapi.tests.test_connect.test_load_config
scapi.tests.test_connect.test_me_having_stress
scapi.tests.test_connect.test_non_global_api
scapi.tests.test_connect.test_permissions
scapi.tests.test_connect.test_playlists
scapi.tests.test_connect.test_scoped_track_creation
scapi.tests.test_connect.test_setting_comments
scapi.tests.test_connect.test_setting_comments_the_way_shawn_says_its_correct
scapi.tests.test_connect.test_setting_permissions
scapi.tests.test_connect.test_track_creation
scapi.tests.test_connect.test_track_update
scapi.tests.test_connect.test_upload
scapi.tests.test_oauth.test_base64_connect
scapi.tests.test_oauth.test_oauth_connect
-

All Variables

- scapi.ACCESS_TOKEN_URL
scapi.AUTHORIZATION_URL
scapi.PROXY
scapi.REQUEST_TOKEN_URL
scapi.USE_PROXY
- - - scapi.tests.scapi_tests.api_logger
scapi.tests.scapi_tests.logger
scapi.tests.test_connect.API_HOST
scapi.tests.test_connect.CONFIG_NAME
scapi.tests.test_connect.CONNECTOR
scapi.tests.test_connect.CONSUMER
scapi.tests.test_connect.CONSUMER_SECRET
scapi.tests.test_connect.PASSWORD
scapi.tests.test_connect.ROOT
scapi.tests.test_connect.RUN_INTERACTIVE_TESTS
scapi.tests.test_connect.SECRET
scapi.tests.test_connect.TOKEN
scapi.tests.test_connect.USER
scapi.tests.test_connect.USE_OAUTH
- scapi.tests.test_connect.logger
scapi.tests.test_oauth.CONSUMER
scapi.tests.test_oauth.CONSUMER_SECRET
scapi.tests.test_oauth.SECRET
scapi.tests.test_oauth.TOKEN
- scapi.tests.test_oauth.logger

-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi-module.html deleted file mode 100644 index b82804b3f..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi-module.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - scapi - - - - - -

Module scapi

-
-

Classes

- - Comment
Event
Group
- - Playlist
- -
- Scope
- Track
- User

Functions

- -

Variables

- ACCESS_TOKEN_URL
AUTHORIZATION_URL
PROXY
REQUEST_TOKEN_URL
USE_PROXY
- logger
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.authentication-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.authentication-module.html deleted file mode 100644 index e86f597b8..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.authentication-module.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - authentication - - - - - -

Module authentication

-
-

Classes

- - - -

Variables

- -
- logger
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.config-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.config-module.html deleted file mode 100644 index bc4635ec9..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.config-module.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - config - - - - - -

Module config

-
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.json-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.json-module.html deleted file mode 100644 index 49c7fa3f6..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.json-module.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - json - - - - - -

Module json

-
-

Classes

- JsonReader
JsonWriter
ReadException
WriteException
-

Functions

- read
write

-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.multidict-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.multidict-module.html deleted file mode 100644 index a4494cd7b..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.multidict-module.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - multidict - - - - - -

Module multidict

-
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.tests-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.tests-module.html deleted file mode 100644 index 4c66376d1..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.tests-module.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - tests - - - - - -

Module tests

-
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.scapi_tests-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.tests.scapi_tests-module.html deleted file mode 100644 index ecc870d8c..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.scapi_tests-module.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - scapi_tests - - - - - -

Module scapi_tests

-
-

Classes

- SCAPITests

Variables

- api_logger
logger

-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_connect-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_connect-module.html deleted file mode 100644 index 791b5ba85..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_connect-module.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - test_connect - - - - - -

Module test_connect

-
-

Functions

- load_config
setup
test_access_token_acquisition
test_connect
test_contact_add_and_removal
test_contact_list
test_events
test_favorites
test_large_list
test_load_config
test_me_having_stress
test_non_global_api
test_permissions
test_playlists
test_scoped_track_creation
test_setting_comments
test_setting_comments_the_way_shawn_says_its_correct
test_setting_permissions
test_track_creation
test_track_update
test_upload

Variables

- API_HOST
CONFIG_NAME
CONNECTOR
CONSUMER
CONSUMER_SECRET
PASSWORD
ROOT
RUN_INTERACTIVE_TESTS
SECRET
TOKEN
USER
USE_OAUTH
- logger

-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_oauth-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_oauth-module.html deleted file mode 100644 index 0d504cee4..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.tests.test_oauth-module.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - test_oauth - - - - - -

Module test_oauth

-
-

Functions

- test_base64_connect
test_oauth_connect

Variables

- CONSUMER
CONSUMER_SECRET
SECRET
TOKEN
- logger

-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc-scapi.util-module.html b/python_apps/soundcloud-api/docs/api/toc-scapi.util-module.html deleted file mode 100644 index c94b46b34..000000000 --- a/python_apps/soundcloud-api/docs/api/toc-scapi.util-module.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - util - - - - - -

Module util

-
-

Classes

- -

Functions

-
- escape
-
-[hide private] - - - - diff --git a/python_apps/soundcloud-api/docs/api/toc.html b/python_apps/soundcloud-api/docs/api/toc.html deleted file mode 100644 index 2e38a4044..000000000 --- a/python_apps/soundcloud-api/docs/api/toc.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Table of Contents - - - - - -

Table of Contents

-
- Everything -
-

Modules

- scapi
- scapi.config
scapi.json
scapi.multidict
scapi.tests
scapi.tests.scapi_tests
scapi.tests.test_connect
scapi.tests.test_oauth
-
- [hide private] - - - - diff --git a/python_apps/soundcloud-api/oauth/__init__.py b/python_apps/soundcloud-api/oauth/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/python_apps/soundcloud-api/oauth/example/client.py b/python_apps/soundcloud-api/oauth/example/client.py deleted file mode 100644 index 3f995c1a5..000000000 --- a/python_apps/soundcloud-api/oauth/example/client.py +++ /dev/null @@ -1,157 +0,0 @@ -''' -Example consumer. -''' -import httplib -import time -import oauth.oauth as oauth -import webbrowser -from scapi import util - -SERVER = 'sandbox-soundcloud.com' # Change to soundcloud.com to reach the live site -PORT = 80 - -REQUEST_TOKEN_URL = 'http://api.' + SERVER + '/oauth/request_token' -ACCESS_TOKEN_URL = 'http://api.' + SERVER + '/oauth/access_token' -AUTHORIZATION_URL = 'http://' + SERVER + '/oauth/authorize' - -CALLBACK_URL = '' -RESOURCE_URL = "http://api." + SERVER + "/me" - -# key and secret granted by the service provider for this consumer application - same as the MockOAuthDataStore -CONSUMER_KEY = 'JysXkO8ErA4EluFnF5nWg' -CONSUMER_SECRET = 'fauVjm61niGckeufkmMvgUo77oWzRHdMmeylJblHk' - -# example client using httplib with headers -class SimpleOAuthClient(oauth.OAuthClient): - - def __init__(self, server, port=httplib.HTTP_PORT, request_token_url='', access_token_url='', authorization_url=''): - self.server = server - self.port = port - self.request_token_url = request_token_url - self.access_token_url = access_token_url - self.authorization_url = authorization_url - self.connection = httplib.HTTPConnection("%s:%d" % (self.server, self.port)) - - def fetch_request_token(self, oauth_request): - # via headers - # -> OAuthToken - print oauth_request.to_url() - #self.connection.request(oauth_request.http_method, self.request_token_url, headers=oauth_request.to_header()) - self.connection.request(oauth_request.http_method, oauth_request.to_url()) - response = self.connection.getresponse() - print "response status", response.status - return oauth.OAuthToken.from_string(response.read()) - - def fetch_access_token(self, oauth_request): - # via headers - # -> OAuthToken - - # This should proably be elsewhere but stays here for now - oauth_request.set_parameter("oauth_signature", util.escape(oauth_request.get_parameter("oauth_signature"))) - self.connection.request(oauth_request.http_method, self.access_token_url, headers=oauth_request.to_header()) - response = self.connection.getresponse() - resp = response.read() - print "*" * 90 - print "response:", resp - print "*" * 90 - - return oauth.OAuthToken.from_string(resp) - - def authorize_token(self, oauth_request): - webbrowser.open(oauth_request.to_url()) - raw_input("press return when authorizing is finished") - - return - - # via url - # -> typically just some okay response - self.connection.request(oauth_request.http_method, oauth_request.to_url()) - response = self.connection.getresponse() - return response.read() - - def access_resource(self, oauth_request): - print "resource url:", oauth_request.to_url() - webbrowser.open(oauth_request.to_url()) - - return - - # via post body - # -> some protected resources - self.connection.request('GET', oauth_request.to_url()) - response = self.connection.getresponse() - return response.read() - -def run_example(): - - # setup - print '** OAuth Python Library Example **' - client = SimpleOAuthClient(SERVER, PORT, REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZATION_URL) - consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET) - signature_method_plaintext = oauth.OAuthSignatureMethod_PLAINTEXT() - signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1() - pause() - # get request token - print '* Obtain a request token ...' - pause() - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, http_url=client.request_token_url) - #oauth_request.sign_request(signature_method_plaintext, consumer, None) - oauth_request.sign_request(signature_method_hmac_sha1, consumer, None) - - print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) - pause() - #import pdb; pdb.set_trace() - - token = client.fetch_request_token(oauth_request) - print 'GOT' - print 'key: %s' % str(token.key) - print 'secret: %s' % str(token.secret) - pause() - - print '* Authorize the request token ...' - pause() - oauth_request = oauth.OAuthRequest.from_token_and_callback(token=token, callback=CALLBACK_URL, http_url=client.authorization_url) - print 'REQUEST (via url query string)' - print 'parameters: %s' % str(oauth_request.parameters) - pause() - # this will actually occur only on some callback - response = client.authorize_token(oauth_request) - print 'GOT' - print response - pause() - - # get access token - print '* Obtain an access token ...' - pause() - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, http_url=client.access_token_url) - oauth_request.sign_request(signature_method_hmac_sha1, consumer, token) - print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) - pause() - token = client.fetch_access_token(oauth_request) - print 'GOT' - print 'key: %s' % str(token.key) - print 'secret: %s' % str(token.secret) - pause() - - # access some protected resources - print '* Access protected resources ...' - pause() - parameters = {} - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, http_method='GET', http_url=RESOURCE_URL, parameters=parameters) - oauth_request.sign_request(signature_method_hmac_sha1, consumer, token) - print 'REQUEST (via get body)' - print 'parameters: %s' % str(oauth_request.parameters) - pause() - params = client.access_resource(oauth_request) - print 'GOT' - print 'non-oauth parameters: %s' % params - pause() - -def pause(): - print '' - time.sleep(1) - -if __name__ == '__main__': - run_example() - print 'Done.' diff --git a/python_apps/soundcloud-api/oauth/example/server.py b/python_apps/soundcloud-api/oauth/example/server.py deleted file mode 100644 index 91fb71538..000000000 --- a/python_apps/soundcloud-api/oauth/example/server.py +++ /dev/null @@ -1,167 +0,0 @@ -from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -import urllib - -import oauth.oauth as oauth - -REQUEST_TOKEN_URL = 'https://photos.example.net/request_token' -ACCESS_TOKEN_URL = 'https://photos.example.net/access_token' -AUTHORIZATION_URL = 'https://photos.example.net/authorize' -RESOURCE_URL = 'http://photos.example.net/photos' -REALM = 'http://photos.example.net/' - -# example store for one of each thing -class MockOAuthDataStore(oauth.OAuthDataStore): - - def __init__(self): - self.consumer = oauth.OAuthConsumer('key', 'secret') - self.request_token = oauth.OAuthToken('requestkey', 'requestsecret') - self.access_token = oauth.OAuthToken('accesskey', 'accesssecret') - self.nonce = 'nonce' - - def lookup_consumer(self, key): - if key == self.consumer.key: - return self.consumer - return None - - def lookup_token(self, token_type, token): - token_attrib = getattr(self, '%s_token' % token_type) - if token == token_attrib.key: - return token_attrib - return None - - def lookup_nonce(self, oauth_consumer, oauth_token, nonce): - if oauth_token and oauth_consumer.key == self.consumer.key and (oauth_token.key == self.request_token.key or token.key == self.access_token.key) and nonce == self.nonce: - return self.nonce - else: - raise oauth.OAuthError('Nonce not found: %s' % str(nonce)) - return None - - def fetch_request_token(self, oauth_consumer): - if oauth_consumer.key == self.consumer.key: - return self.request_token - return None - - def fetch_access_token(self, oauth_consumer, oauth_token): - if oauth_consumer.key == self.consumer.key and oauth_token.key == self.request_token.key: - # want to check here if token is authorized - # for mock store, we assume it is - return self.access_token - return None - - def authorize_request_token(self, oauth_token): - if oauth_token.key == self.request_token.key: - # authorize the request token in the store - # for mock store, do nothing - return self.request_token - return None - -class RequestHandler(BaseHTTPRequestHandler): - - def __init__(self, *args, **kwargs): - self.oauth_server = oauth.OAuthServer(MockOAuthDataStore()) - self.oauth_server.add_signature_method(oauth.OAuthSignatureMethod_PLAINTEXT()) - self.oauth_server.add_signature_method(oauth.OAuthSignatureMethod_HMAC_SHA1()) - BaseHTTPRequestHandler.__init__(self, *args, **kwargs) - - # example way to send an oauth error - def send_oauth_error(self, err=None): - # send a 401 error - self.send_error(401, str(err.message)) - # return the authenticate header - header = oauth.build_authenticate_header(realm=REALM) - for k, v in header.iteritems(): - self.send_header(k, v) - - def do_GET(self): - - # debug info - #print self.command, self.path, self.headers - - # get the post data (if any) - postdata = None - if self.command == 'POST': - try: - length = int(self.headers.getheader('content-length')) - postdata = self.rfile.read(length) - except: - pass - - # construct the oauth request from the request parameters - oauth_request = oauth.OAuthRequest.from_request(self.command, self.path, headers=self.headers, postdata=postdata) - - # request token - if self.path.startswith(REQUEST_TOKEN_URL): - try: - # create a request token - token = self.oauth_server.fetch_request_token(oauth_request) - # send okay response - self.send_response(200, 'OK') - self.end_headers() - # return the token - self.wfile.write(token.to_string()) - except oauth.OAuthError, err: - self.send_oauth_error(err) - return - - # user authorization - if self.path.startswith(AUTHORIZATION_URL): - try: - # get the request token - token = self.oauth_server.fetch_request_token(oauth_request) - callback = self.oauth_server.get_callback(oauth_request) - # send okay response - self.send_response(200, 'OK') - self.end_headers() - # return the callback url (to show server has it) - self.wfile.write('callback: %s' %callback) - # authorize the token (kind of does nothing for now) - token = self.oauth_server.authorize_token(token) - self.wfile.write('\n') - # return the token key - token_key = urllib.urlencode({'oauth_token': token.key}) - self.wfile.write('token key: %s' % token_key) - except oauth.OAuthError, err: - self.send_oauth_error(err) - return - - # access token - if self.path.startswith(ACCESS_TOKEN_URL): - try: - # create an access token - token = self.oauth_server.fetch_access_token(oauth_request) - # send okay response - self.send_response(200, 'OK') - self.end_headers() - # return the token - self.wfile.write(token.to_string()) - except oauth.OAuthError, err: - self.send_oauth_error(err) - return - - # protected resources - if self.path.startswith(RESOURCE_URL): - try: - # verify the request has been oauth authorized - consumer, token, params = self.oauth_server.verify_request(oauth_request) - # send okay response - self.send_response(200, 'OK') - self.end_headers() - # return the extra parameters - just for something to return - self.wfile.write(str(params)) - except oauth.OAuthError, err: - self.send_oauth_error(err) - return - - def do_POST(self): - return self.do_GET() - -def main(): - try: - server = HTTPServer(('', 8080), RequestHandler) - print 'Test server running...' - server.serve_forever() - except KeyboardInterrupt: - server.socket.close() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/python_apps/soundcloud-api/oauth/oauth.py b/python_apps/soundcloud-api/oauth/oauth.py deleted file mode 100644 index 274bbd25b..000000000 --- a/python_apps/soundcloud-api/oauth/oauth.py +++ /dev/null @@ -1,505 +0,0 @@ -import cgi -import urllib -import time -import random -import urlparse -import hmac -import hashlib -import base64 - -VERSION = '1.0' # Hi Blaine! -HTTP_METHOD = 'GET' -SIGNATURE_METHOD = 'PLAINTEXT' - -# Generic exception class -class OAuthError(RuntimeError): - def __init__(self, message='OAuth error occured'): - self.message = message - -# optional WWW-Authenticate header (401 error) -def build_authenticate_header(realm=''): - return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} - -# url escape -def escape(s): - # escape '/' too - return urllib.quote(s, safe='') - -# util function: current timestamp -# seconds since epoch (UTC) -def generate_timestamp(): - return int(time.time()) - -# util function: nonce -# pseudorandom number -def generate_nonce(length=8): - return ''.join(str(random.randint(0, 9)) for i in range(length)) - -# OAuthConsumer is a data type that represents the identity of the Consumer -# via its shared secret with the Service Provider. -class OAuthConsumer(object): - key = None - secret = None - - def __init__(self, key, secret): - self.key = key - self.secret = secret - -# OAuthToken is a data type that represents an End User via either an access -# or request token. -class OAuthToken(object): - # access tokens and request tokens - key = None - secret = None - - ''' - key = the token - secret = the token secret - ''' - def __init__(self, key, secret): - self.key = key - self.secret = secret - - def to_string(self): - return urllib.urlencode({'oauth_token': self.key, 'oauth_token_secret': self.secret}) - - # return a token from something like: - # oauth_token_secret=digg&oauth_token=digg - @staticmethod - def from_string(s): - params = cgi.parse_qs(s, keep_blank_values=False) - key = params['oauth_token'][0] - secret = params['oauth_token_secret'][0] - return OAuthToken(key, secret) - - def __str__(self): - return self.to_string() - -# OAuthRequest represents the request and can be serialized -class OAuthRequest(object): - ''' - OAuth parameters: - - oauth_consumer_key - - oauth_token - - oauth_signature_method - - oauth_signature - - oauth_timestamp - - oauth_nonce - - oauth_version - ... any additional parameters, as defined by the Service Provider. - ''' - parameters = None # oauth parameters - http_method = HTTP_METHOD - http_url = None - version = VERSION - - def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None): - self.http_method = http_method - self.http_url = http_url - self.parameters = parameters or {} - - def set_parameter(self, parameter, value): - self.parameters[parameter] = value - - def get_parameter(self, parameter): - try: - return self.parameters[parameter] - except: - raise OAuthError('Parameter not found: %s' % parameter) - - def _get_timestamp_nonce(self): - return self.get_parameter('oauth_timestamp'), self.get_parameter('oauth_nonce') - - # get any non-oauth parameters - def get_nonoauth_parameters(self): - parameters = {} - for k, v in self.parameters.iteritems(): - # ignore oauth parameters - if k.find('oauth_') < 0: - parameters[k] = v - return parameters - - # serialize as a header for an HTTPAuth request - def to_header(self, realm=''): - auth_header = 'OAuth realm="%s"' % realm - # add the oauth parameters - if self.parameters: - for k, v in self.parameters.iteritems(): - auth_header += ',\n\t %s="%s"' % (k, v) - return {'Authorization': auth_header} - - # serialize as post data for a POST request - def to_postdata(self): - return '&'.join('%s=%s' % (escape(str(k)), escape(str(v))) for k, v in self.parameters.iteritems()) - - # serialize as a url for a GET request - def to_url(self): - return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata()) - - # return a string that consists of all the parameters that need to be signed - def get_normalized_parameters(self): - params = self.parameters - try: - # exclude the signature if it exists - del params['oauth_signature'] - except: - pass - key_values = params.items() - # sort lexicographically, first after key, then after value - key_values.sort() - # combine key value pairs in string and escape - return '&'.join('%s=%s' % (str(k), str(p)) for k, p in key_values) - - # just uppercases the http method - def get_normalized_http_method(self): - return self.http_method.upper() - - # parses the url and rebuilds it to be scheme://host/path - def get_normalized_http_url(self): - parts = urlparse.urlparse(self.http_url) - url_string = '%s://%s%s' % (parts.scheme, parts.netloc, parts.path) - return url_string - - # set the signature parameter to the result of build_signature - def sign_request(self, signature_method, consumer, token): - # set the signature method - self.set_parameter('oauth_signature_method', signature_method.get_name()) - # set the signature - self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token)) - - def build_signature(self, signature_method, consumer, token): - # call the build signature method within the signature method - return signature_method.build_signature(self, consumer, token) - - @staticmethod - def from_request(http_method, http_url, headers=None, postdata=None, parameters=None): - - # let the library user override things however they'd like, if they know - # which parameters to use then go for it, for example XMLRPC might want to - # do this - if parameters is not None: - return OAuthRequest(http_method, http_url, parameters) - - # from the headers - if headers is not None: - try: - auth_header = headers['Authorization'] - # check that the authorization header is OAuth - auth_header.index('OAuth') - # get the parameters from the header - parameters = OAuthRequest._split_header(auth_header) - return OAuthRequest(http_method, http_url, parameters) - except: - pass - - # from the parameter string (post body) - if http_method == 'POST' and postdata is not None: - parameters = OAuthRequest._split_url_string(postdata) - - # from the url string - elif http_method == 'GET': - param_str = urlparse.urlparse(http_url).query - parameters = OAuthRequest._split_url_string(param_str) - - if parameters: - return OAuthRequest(http_method, http_url, parameters) - - raise OAuthError('Missing all OAuth parameters. OAuth parameters must be in the headers, post body, or url.') - - @staticmethod - def from_consumer_and_token(oauth_consumer, token=None, http_method=HTTP_METHOD, http_url=None, parameters=None): - if not parameters: - parameters = {} - - defaults = { - 'oauth_consumer_key': oauth_consumer.key, - 'oauth_timestamp': generate_timestamp(), - 'oauth_nonce': generate_nonce(), - 'oauth_version': OAuthRequest.version, - } - - defaults.update(parameters) - parameters = defaults - - if token: - parameters['oauth_token'] = token.key - - return OAuthRequest(http_method, http_url, parameters) - - @staticmethod - def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD, http_url=None, parameters=None): - if not parameters: - parameters = {} - - parameters['oauth_token'] = token.key - - if callback: - parameters['oauth_callback'] = escape(callback) - - return OAuthRequest(http_method, http_url, parameters) - - # util function: turn Authorization: header into parameters, has to do some unescaping - @staticmethod - def _split_header(header): - params = {} - parts = header.split(',') - for param in parts: - # ignore realm parameter - if param.find('OAuth realm') > -1: - continue - # remove whitespace - param = param.strip() - # split key-value - param_parts = param.split('=', 1) - # remove quotes and unescape the value - params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) - return params - - # util function: turn url string into parameters, has to do some unescaping - @staticmethod - def _split_url_string(param_str): - parameters = cgi.parse_qs(param_str, keep_blank_values=False) - for k, v in parameters.iteritems(): - parameters[k] = urllib.unquote(v[0]) - return parameters - -# OAuthServer is a worker to check a requests validity against a data store -class OAuthServer(object): - timestamp_threshold = 300 # in seconds, five minutes - version = VERSION - signature_methods = None - data_store = None - - def __init__(self, data_store=None, signature_methods=None): - self.data_store = data_store - self.signature_methods = signature_methods or {} - - def set_data_store(self, oauth_data_store): - self.data_store = data_store - - def get_data_store(self): - return self.data_store - - def add_signature_method(self, signature_method): - self.signature_methods[signature_method.get_name()] = signature_method - return self.signature_methods - - # process a request_token request - # returns the request token on success - def fetch_request_token(self, oauth_request): - try: - # get the request token for authorization - token = self._get_token(oauth_request, 'request') - except: - # no token required for the initial token request - version = self._get_version(oauth_request) - consumer = self._get_consumer(oauth_request) - self._check_signature(oauth_request, consumer, None) - # fetch a new token - token = self.data_store.fetch_request_token(consumer) - return token - - # process an access_token request - # returns the access token on success - def fetch_access_token(self, oauth_request): - version = self._get_version(oauth_request) - consumer = self._get_consumer(oauth_request) - # get the request token - token = self._get_token(oauth_request, 'request') - self._check_signature(oauth_request, consumer, token) - new_token = self.data_store.fetch_access_token(consumer, token) - return new_token - - # verify an api call, checks all the parameters - def verify_request(self, oauth_request): - # -> consumer and token - version = self._get_version(oauth_request) - consumer = self._get_consumer(oauth_request) - # get the access token - token = self._get_token(oauth_request, 'access') - self._check_signature(oauth_request, consumer, token) - parameters = oauth_request.get_nonoauth_parameters() - return consumer, token, parameters - - # authorize a request token - def authorize_token(self, token): - return self.data_store.authorize_request_token(token) - - # get the callback url - def get_callback(self, oauth_request): - return oauth_request.get_parameter('oauth_callback') - - # optional support for the authenticate header - def build_authenticate_header(self, realm=''): - return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} - - # verify the correct version request for this server - def _get_version(self, oauth_request): - try: - version = oauth_request.get_parameter('oauth_version') - except: - version = VERSION - if version and version != self.version: - raise OAuthError('OAuth version %s not supported' % str(version)) - return version - - # figure out the signature with some defaults - def _get_signature_method(self, oauth_request): - try: - signature_method = oauth_request.get_parameter('oauth_signature_method') - except: - signature_method = SIGNATURE_METHOD - try: - # get the signature method object - signature_method = self.signature_methods[signature_method] - except: - signature_method_names = ', '.join(self.signature_methods.keys()) - raise OAuthError('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names)) - - return signature_method - - def _get_consumer(self, oauth_request): - consumer_key = oauth_request.get_parameter('oauth_consumer_key') - if not consumer_key: - raise OAuthError('Invalid consumer key') - consumer = self.data_store.lookup_consumer(consumer_key) - if not consumer: - raise OAuthError('Invalid consumer') - return consumer - - # try to find the token for the provided request token key - def _get_token(self, oauth_request, token_type='access'): - token_field = oauth_request.get_parameter('oauth_token') - token = self.data_store.lookup_token(token_type, token_field) - if not token: - raise OAuthError('Invalid %s token: %s' % (token_type, token_field)) - return token - - def _check_signature(self, oauth_request, consumer, token): - timestamp, nonce = oauth_request._get_timestamp_nonce() - self._check_timestamp(timestamp) - self._check_nonce(consumer, token, nonce) - signature_method = self._get_signature_method(oauth_request) - try: - signature = oauth_request.get_parameter('oauth_signature') - except: - raise OAuthError('Missing signature') - # attempt to construct the same signature - built = signature_method.build_signature(oauth_request, consumer, token) - if signature != built: - raise OAuthError('Invalid signature') - - def _check_timestamp(self, timestamp): - # verify that timestamp is recentish - timestamp = int(timestamp) - now = int(time.time()) - lapsed = now - timestamp - if lapsed > self.timestamp_threshold: - raise OAuthError('Expired timestamp: given %d and now %s has a greater difference than threshold %d' % (timestamp, now, self.timestamp_threshold)) - - def _check_nonce(self, consumer, token, nonce): - # verify that the nonce is uniqueish - try: - self.data_store.lookup_nonce(consumer, token, nonce) - raise OAuthError('Nonce already used: %s' % str(nonce)) - except: - pass - -# OAuthClient is a worker to attempt to execute a request -class OAuthClient(object): - consumer = None - token = None - - def __init__(self, oauth_consumer, oauth_token): - self.consumer = oauth_consumer - self.token = oauth_token - - def get_consumer(self): - return self.consumer - - def get_token(self): - return self.token - - def fetch_request_token(self, oauth_request): - # -> OAuthToken - raise NotImplementedError - - def fetch_access_token(self, oauth_request): - # -> OAuthToken - raise NotImplementedError - - def access_resource(self, oauth_request): - # -> some protected resource - raise NotImplementedError - -# OAuthDataStore is a database abstraction used to lookup consumers and tokens -class OAuthDataStore(object): - - def lookup_consumer(self, key): - # -> OAuthConsumer - raise NotImplementedError - - def lookup_token(self, oauth_consumer, token_type, token_token): - # -> OAuthToken - raise NotImplementedError - - def lookup_nonce(self, oauth_consumer, oauth_token, nonce, timestamp): - # -> OAuthToken - raise NotImplementedError - - def fetch_request_token(self, oauth_consumer): - # -> OAuthToken - raise NotImplementedError - - def fetch_access_token(self, oauth_consumer, oauth_token): - # -> OAuthToken - raise NotImplementedError - - def authorize_request_token(self, oauth_token): - # -> OAuthToken - raise NotImplementedError - -# OAuthSignatureMethod is a strategy class that implements a signature method -class OAuthSignatureMethod(object): - def get_name(): - # -> str - raise NotImplementedError - - def build_signature(oauth_request, oauth_consumer, oauth_token): - # -> str - raise NotImplementedError - -class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod): - - def get_name(self): - return 'HMAC-SHA1' - - def build_signature(self, oauth_request, consumer, token): - sig = ( - escape(oauth_request.get_normalized_http_method()), - escape(oauth_request.get_normalized_http_url()), - escape(oauth_request.get_normalized_parameters()), - ) - - key = '%s&' % consumer.secret - if token: - key += token.secret - raw = '&'.join(sig) - - # hmac object - hashed = hmac.new(key, raw, hashlib.sha1) - - # calculate the digest base 64 - return base64.b64encode(hashed.digest()) - -class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod): - - def get_name(self): - return 'PLAINTEXT' - - def build_signature(self, oauth_request, consumer, token): - # concatenate the consumer key and secret - sig = escape(consumer.secret) - if token: - sig = '&'.join((sig, escape(token.secret))) - return sig diff --git a/python_apps/soundcloud-api/scapi/MultipartPostHandler.py b/python_apps/soundcloud-api/scapi/MultipartPostHandler.py deleted file mode 100644 index 34b12943f..000000000 --- a/python_apps/soundcloud-api/scapi/MultipartPostHandler.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/python - -#### -# 02/2006 Will Holcomb -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -""" -Usage: - Enables the use of multipart/form-data for posting forms - -Inspirations: - Upload files in python: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 - urllib2_file: - Fabien Seisen: - -Example: - import MultipartPostHandler, urllib2, cookielib - - cookies = cookielib.CookieJar() - opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), - MultipartPostHandler.MultipartPostHandler) - params = { "username" : "bob", "password" : "riviera", - "file" : open("filename", "rb") } - opener.open("http://wwww.bobsite.com/upload/", params) - -Further Example: - The main function of this file is a sample which downloads a page and - then uploads it to the W3C validator. -""" - -import urllib -import urllib2 -import mimetools, mimetypes -import os, stat - -class Callable: - def __init__(self, anycallable): - self.__call__ = anycallable - -# Controls how sequences are uncoded. If true, elements may be given multiple values by -# assigning a sequence. -doseq = 1 - -class MultipartPostHandler(urllib2.BaseHandler): - handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first - - def http_request(self, request): - data = request.get_data() - if data is not None and type(data) != str: - v_files = [] - v_vars = [] - try: - for(key, value) in data.items(): - if type(value) == file: - v_files.append((key, value)) - else: - v_vars.append((key, value)) - except TypeError: - systype, value, traceback = sys.exc_info() - raise TypeError, "not a valid non-string sequence or mapping object", traceback - - if len(v_files) == 0: - data = urllib.urlencode(v_vars, doseq) - else: - boundary, data = self.multipart_encode(v_vars, v_files) - contenttype = 'multipart/form-data; boundary=%s' % boundary - if(request.has_header('Content-Type') - and request.get_header('Content-Type').find('multipart/form-data') != 0): - print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data') - request.add_unredirected_header('Content-Type', contenttype) - - request.add_data(data) - return request - - def multipart_encode(vars, files, boundary = None, buffer = None): - if boundary is None: - boundary = mimetools.choose_boundary() - if buffer is None: - buffer = '' - for(key, value) in vars: - if isinstance(value, basestring): - value = [value] - for sub_value in value: - buffer += '--%s\r\n' % boundary - buffer += 'Content-Disposition: form-data; name="%s"' % key - buffer += '\r\n\r\n' + sub_value + '\r\n' - for(key, fd) in files: - file_size = os.fstat(fd.fileno())[stat.ST_SIZE] - filename = fd.name.split('/')[-1] - contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' - buffer += '--%s\r\n' % boundary - buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename) - buffer += 'Content-Type: %s\r\n' % contenttype - # buffer += 'Content-Length: %s\r\n' % file_size - fd.seek(0) - buffer += '\r\n' + fd.read() + '\r\n' - buffer += '--%s--\r\n\r\n' % boundary - return boundary, buffer - multipart_encode = Callable(multipart_encode) - - https_request = http_request - -def main(): - import tempfile, sys - - validatorURL = "http://validator.w3.org/check" - opener = urllib2.build_opener(MultipartPostHandler) - - def validateFile(url): - temp = tempfile.mkstemp(suffix=".html") - os.write(temp[0], opener.open(url).read()) - params = { "ss" : "0", # show source - "doctype" : "Inline", - "uploaded_file" : open(temp[1], "rb") } - print opener.open(validatorURL, params).read() - os.remove(temp[1]) - - if len(sys.argv[1:]) > 0: - for arg in sys.argv[1:]: - validateFile(arg) - else: - validateFile("http://www.google.com") - -if __name__=="__main__": - main() diff --git a/python_apps/soundcloud-api/scapi/__init__.py b/python_apps/soundcloud-api/scapi/__init__.py deleted file mode 100644 index ae737cb81..000000000 --- a/python_apps/soundcloud-api/scapi/__init__.py +++ /dev/null @@ -1,1012 +0,0 @@ -## SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful -## API -## -## Copyright (C) 2008 Diez B. Roggisch -## Contact mailto:deets@soundcloud.com -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import urllib -import urllib2 -import re - -import logging -import simplejson -import cgi -from scapi.MultipartPostHandler import MultipartPostHandler -from inspect import isclass -import urlparse -from scapi.authentication import BasicAuthenticator -from scapi.util import ( - escape, - MultiDict, - ) - -logging.basicConfig() -logger = logging.getLogger(__name__) - -USE_PROXY = False -""" -Something like http://127.0.0.1:10000/ -""" -PROXY = '' - - -""" -Endpoints, for reference: -The url Soundcould offers to obtain request-tokens: 'http://api.soundcloud.com/oauth/request_token' -The url Soundcould offers to exchange access-tokens for request-tokens: 'http://api.soundcloud.com/oauth/access_token' -The url Soundcould offers to make users authorize a concrete request token: 'http://api.soundcloud.com/oauth/authorize' -""" - -__all__ = ['SoundCloudAPI', 'USE_PROXY', 'PROXY'] - - -class NoResultFromRequest(Exception): - pass - -class InvalidMethodException(Exception): - - def __init__(self, message): - self._message = message - Exception.__init__(self) - - def __repr__(self): - res = Exception.__repr__(self) - res += "\n" - res += "-" * 10 - res += "\nmessage:\n\n" - res += self._message - return res - -class UnknownContentType(Exception): - def __init__(self, msg): - Exception.__init__(self) - self._msg = msg - - def __repr__(self): - return self.__class__.__name__ + ":" + self._msg - - def __str__(self): - return str(self) - -class PartitionCollectionGenerator(): - def __init__(self, scope, method, Gen, NextPartition): - self.NextPartition = NextPartition - self.Generator = Gen - self.Scope = scope - self.Method = method - - def __iter__(self): - return self.Generator - def next(self): - return self.Generator.next() - def __call__(self, someParam): - self.someParam = someParam - for line in self.content: - if line == someParam: - yield line - - def GetNextPartition(self): - if self.NextPartition != None: - method = re.search('(^[a-z]+)', self.Method).group(0) - params = re.search('\?.+', self.NextPartition).group(0) - params = params.replace('u0026', '&') - - return self.Scope._call(method, params) - else: - return None - -class ApiConnector(object): - """ - The ApiConnector holds all the data necessary to authenticate against - the soundcloud-api. You can instantiate several connectors if you like, but usually one - should be sufficient. - """ - - """ - SoundClound imposes a maximum on the number of returned items. This value is that - maximum. - """ - LIST_LIMIT = 50 - - """ - The query-parameter that is used to request results beginning from a certain offset. - """ - LIST_OFFSET_PARAMETER = 'offset' - """ - The query-parameter that is used to request results being limited to a certain amount. - - Currently this is of no use and just for completeness sake. - """ - LIST_LIMIT_PARAMETER = 'limit' - - def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): - """ - Constructor for the API-Singleton. Use it once with parameters, and then the - subsequent calls internal to the API will work. - - @type host: str - @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use - "api.soundcloud.com:1234" - @type user: str - @param user: if given, the username for basic HTTP authentication - @type password: str - @param password: if the user is given, you have to give a password as well - @type authenticator: OAuthAuthenticator | BasicAuthenticator - @param authenticator: the authenticator to use, see L{scapi.authentication} - """ - self.host = host - self.host = self.host.replace("http://", "") - if self.host[-1] == '/': # Remove a trailing slash, but leave other slashes alone - self.host = self.host[0:-1] - - if authenticator is not None: - self.authenticator = authenticator - elif user is not None and password is not None: - self.authenticator = BasicAuthenticator(user, password) - self._base = base - self.collapse_scope = collapse_scope - - def normalize_method(self, method): - """ - This method will take a method that has been part of a redirect of some sort - and see if it's valid, which means that it's located beneath our base. - If yes, we return it normalized without that very base. - """ - _, _, path, _, _, _ = urlparse.urlparse(method) - if path.startswith("/"): - path = path[1:] - # if the base is "", we return the whole path, - # otherwise normalize it away - if self._base == "": - return path - if path.startswith(self._base): - return path[len(self._base)-1:] - raise InvalidMethodException("Not a valid API method: %s" % method) - - - - def fetch_request_token(self, url=None, oauth_callback="oob", oauth_verifier=None): - """ - Helper-function for a registered consumer to obtain a request token, as - used by oauth. - - Use it like this: - - >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - None, - None) - - >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) - >>> token, secret = sca.fetch_request_token() - >>> authorization_url = sca.get_request_token_authorization_url(token) - - Please note the None passed as token & secret to the authenticator. - """ - request_url = "http://" + self.host + "/oauth/request_token" - if url is None: - url = request_url - req = urllib2.Request(url) - self.authenticator.augment_request(req, None, oauth_callback=oauth_callback, oauth_verifier=oauth_verifier) - handlers = [] - if USE_PROXY: - handlers.append(urllib2.ProxyHandler({'http' : PROXY})) - opener = urllib2.build_opener(*handlers) - handle = opener.open(req, None) - info = handle.info() - content = handle.read() - params = cgi.parse_qs(content, keep_blank_values=False) - key = params['oauth_token'][0] - secret = params['oauth_token_secret'][0] - return key, secret - - - def fetch_access_token(self, oauth_verifier): - """ - Helper-function for a registered consumer to exchange an access token for - a request token. - - Use it like this: - - >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - request_token, - request_token_secret) - - >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) - >>> token, secret = sca.fetch_access_token() - - Please note the values passed as token & secret to the authenticator. - """ - access_token_url = "http://" + self.host + "/oauth/access_token" - return self.fetch_request_token(access_token_url, oauth_verifier=oauth_verifier) - - - def get_request_token_authorization_url(self, token): - """ - Simple helper function to generate the url needed - to ask a user for request token authorization. - - See also L{fetch_request_token}. - - Possible usage: - - >>> import webbrowser - >>> sca = scapi.ApiConnector() - >>> authorization_url = sca.get_request_token_authorization_url(token) - >>> webbrowser.open(authorization_url) - """ - - auth_url = self.host.split("/")[0] - auth_url = "http://" + auth_url + "/oauth/authorize" - auth_url = auth_url.replace("api.", "") - return "%s?oauth_token=%s" % (auth_url, token) - - - -class SCRedirectHandler(urllib2.HTTPRedirectHandler): - """ - A urllib2-Handler to deal with the redirects the RESTful API of SC uses. - """ - alternate_method = None - - def http_error_303(self, req, fp, code, msg, hdrs): - """ - In case of return-code 303 (See-other), we have to store the location we got - because that will determine the actual type of resource returned. - """ - self.alternate_method = hdrs['location'] - # for oauth, we need to re-create the whole header-shizzle. This - # does it - it recreates a full url and signs the request - new_url = self.alternate_method -# if USE_PROXY: -# import pdb; pdb.set_trace() -# old_url = req.get_full_url() -# protocol, host, _, _, _, _ = urlparse.urlparse(old_url) -# new_url = urlparse.urlunparse((protocol, host, self.alternate_method, None, None, None)) - req = req.recreate_request(new_url) - return urllib2.HTTPRedirectHandler.http_error_303(self, req, fp, code, msg, hdrs) - - def http_error_201(self, req, fp, code, msg, hdrs): - """ - We fake a 201 being a 303 so that our redirection-scheme takes place - for the 201 the API throws in case we created something. If the location is - not available though, that means that whatever we created has succeded - without - being a named resource. Assigning an asset to a track is an example of such - case. - """ - if 'location' not in hdrs: - raise NoResultFromRequest() - return self.http_error_303(req, fp, 303, msg, hdrs) - -class Scope(object): - """ - The basic means to query and create resources. The Scope uses the L{ApiConnector} to - create the proper URIs for querying or creating resources. - - For accessing resources from the root level, you explcitly create a Scope and pass it - an L{ApiConnector}-instance. Then you can query it - or create new resources like this: - - >>> connector = scapi.ApiConnector(host='host', user='user', password='password') # initialize the API - >>> scope = scapi.Scope(connector) # get the root scope - >>> users = list(scope.users()) - [, ...] - - Please not that all resources that are lists are returned as B{generator}. So you need - to either iterate over them, or call list(resources) on them. - - When accessing resources that belong to another resource, like contacts of a user, you access - the parent's resource scope implicitly through the resource instance like this: - - >>> user = scope.users().next() - >>> list(user.contacts()) - [, ...] - - """ - def __init__(self, connector, scope=None, parent=None): - """ - Create the Scope. It can have a resource as scope, and possibly a parent-scope. - - @param connector: The connector to use. - @type connector: ApiConnector - @type scope: scapi.RESTBase - @param scope: the resource to make this scope belong to - @type parent: scapi.Scope - @param parent: the parent scope of this scope - """ - - if scope is None: - scope = () - else: - scope = scope, - if parent is not None: - scope = parent._scope + scope - self._scope = scope - self._connector = connector - - def _get_connector(self): - return self._connector - - - def oauth_sign_get_request(self, url): - """ - This method will take an arbitrary url, and rewrite it - so that the current authenticator's oauth-headers are appended - as query-parameters. - - This is used in streaming and downloading, because those content - isn't served from the SoundCloud servers themselves. - - A usage example would look like this: - - >>> sca = scapi.Scope(connector) - >>> track = sca.tracks(params={ - "filter" : "downloadable", - }).next() - - - >>> download_url = track.download_url - >>> signed_url = track.oauth_sign_get_request(download_url) - >>> data = urllib2.urlopen(signed_url).read() - - """ - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - - req = urllib2.Request(url) - - all_params = {} - if query: - all_params.update(cgi.parse_qs(query)) - - if not all_params: - all_params = None - - self._connector.authenticator.augment_request(req, all_params, False) - - auth_header = req.get_header("Authorization") - auth_header = auth_header[len("OAuth "):] - - query_params = [] - if query: - query_params.append(query) - - for part in auth_header.split(","): - key, value = part.split("=") - assert key.startswith("oauth") - value = value[1:-1] - query_params.append("%s=%s" % (key, value)) - - query = "&".join(query_params) - url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) - return url - - - def _create_request(self, url, connector, parameters, queryparams, alternate_http_method=None, use_multipart=False): - """ - This method returnes the urllib2.Request to perform the actual HTTP-request. - - We return a subclass that overload the get_method-method to return a custom method like "PUT". - Additionally, the request is enhanced with the current authenticators authorization scheme - headers. - - @param url: the destination url - @param connector: our connector-instance - @param parameters: the POST-parameters to use. - @type parameters: None|dict> - @param queryparams: the queryparams to use - @type queryparams: None|dict> - @param alternate_http_method: an alternate HTTP-method to use - @type alternate_http_method: str - @return: the fully equipped request - @rtype: urllib2.Request - """ - class MyRequest(urllib2.Request): - def get_method(self): - if alternate_http_method is not None: - return alternate_http_method - return urllib2.Request.get_method(self) - - def has_data(self): - return parameters is not None - - def augment_request(self, params, use_multipart=False): - connector.authenticator.augment_request(self, params, use_multipart) - - @classmethod - def recreate_request(cls, location): - return self._create_request(location, connector, None, None) - - req = MyRequest(url) - all_params = {} - if parameters is not None: - all_params.update(parameters) - if queryparams is not None: - all_params.update(queryparams) - if not all_params: - all_params = None - req.augment_request(all_params, use_multipart) - req.add_header("Accept", "application/json") - return req - - - def _create_query_string(self, queryparams): - """ - Small helpermethod to create the querystring from a dict. - - @type queryparams: None|dict> - @param queryparams: the queryparameters. - @return: either the empty string, or a "?" followed by the parameters joined by "&" - @rtype: str - """ - if not queryparams: - return "" - h = [] - for key, values in queryparams.iteritems(): - if isinstance(values, (int, long, float)): - values = str(values) - if isinstance(values, basestring): - values = [values] - for v in values: - v = v.encode("utf-8") - h.append("%s=%s" % (key, escape(v))) - return "?" + "&".join(h) - - - def _call(self, method, *args, **kwargs): - """ - The workhorse. It's complicated, convoluted and beyond understanding of a mortal being. - - You have been warned. - """ - - queryparams = {} - __offset__ = ApiConnector.LIST_LIMIT - if "__offset__" in kwargs: - offset = kwargs.pop("__offset__") - queryparams['offset'] = offset - __offset__ = offset + ApiConnector.LIST_LIMIT - - if "params" in kwargs: - queryparams.update(kwargs.pop("params")) - - # create a closure to invoke this method again with a greater offset - _cl_method = method - _cl_args = tuple(args) - _cl_kwargs = {} - _cl_kwargs.update(kwargs) - _cl_kwargs["__offset__"] = __offset__ - def continue_list_fetching(): - return self._call(method, *_cl_args, **_cl_kwargs) - connector = self._get_connector() - def filelike(v): - if isinstance(v, file): - return True - if hasattr(v, "read"): - return True - return False - alternate_http_method = None - if "_alternate_http_method" in kwargs: - alternate_http_method = kwargs.pop("_alternate_http_method") - urlparams = kwargs if kwargs else None - use_multipart = False - if urlparams is not None: - fileargs = dict((key, value) for key, value in urlparams.iteritems() if filelike(value)) - use_multipart = bool(fileargs) - - # ensure the method has a trailing / - if method[-1] != "/": - method = method + "/" - if args: - method = "%s%s" % (method, "/".join(str(a) for a in args)) - - scope = '' - if self._scope: - scopes = self._scope - if connector.collapse_scope: - scopes = scopes[-1:] - scope = "/".join([sc._scope() for sc in scopes]) + "/" - url = "http://%(host)s/%(base)s%(scope)s%(method)s%(queryparams)s" % dict(host=connector.host, method=method, base=connector._base, scope=scope, queryparams=self._create_query_string(queryparams)) - - # we need to install SCRedirectHandler - # to gather possible See-Other redirects - # so that we can exchange our method - redirect_handler = SCRedirectHandler() - handlers = [redirect_handler] - if USE_PROXY: - handlers.append(urllib2.ProxyHandler({'http' : PROXY})) - req = self._create_request(url, connector, urlparams, queryparams, alternate_http_method, use_multipart) - - http_method = req.get_method() - if urlparams is not None: - logger.debug("Posting url: %s, method: %s", url, http_method) - else: - logger.debug("Fetching url: %s, method: %s", url, http_method) - - - if use_multipart: - handlers.extend([MultipartPostHandler]) - else: - if urlparams is not None: - urlparams = urllib.urlencode(urlparams.items(), True) - opener = urllib2.build_opener(*handlers) - try: - handle = opener.open(req, urlparams) - except NoResultFromRequest: - return None - except urllib2.HTTPError, e: - if http_method == "GET" and e.code == 404: - return None - raise - - info = handle.info() - ct = info['Content-Type'] - content = handle.read() - logger.debug("Content-type:%s", ct) - logger.debug("Request Content:\n%s", content) - if redirect_handler.alternate_method is not None: - method = connector.normalize_method(redirect_handler.alternate_method) - logger.debug("Method changed through redirect to: <%s>", method) - - try: - if "application/json" in ct: - content = content.strip() - #If linked partitioning is on, extract the URL to the next collection: - partition_url = None - if method.find('linked_partitioning=1') != -1: - pattern = re.compile('(next_partition_href":")(.*?)(")') - if pattern.search(content): - partition_url = pattern.search(content).group(2) - - if not content: - content = "{}" - try: - res = simplejson.loads(content) - except: - logger.error("Couldn't decode returned json") - logger.error(content) - raise - res = self._map(res, method, continue_list_fetching, partition_url) - return res - elif len(content) <= 1: - # this might be the famous SeeOtherSpecialCase which means that - # all that matters is just the method - pass - raise UnknownContentType("%s, returned:\n%s" % (ct, content)) - finally: - handle.close() - - def _map(self, res, method, continue_list_fetching, next_partition = None): - """ - This method will take the JSON-result of a HTTP-call and return our domain-objects. - - It's also deep magic, don't look. - """ - pathparts = reversed(method.split("/")) - stack = [] - for part in pathparts: - stack.append(part) - if part in RESTBase.REGISTRY: - cls = RESTBase.REGISTRY[part] - # multiple objects, without linked partitioning - if isinstance(res, list): - def result_gen(): - count = 0 - for item in res: - yield cls(item, self, stack) - count += 1 - if count == ApiConnector.LIST_LIMIT: - for item in continue_list_fetching(): - yield item - logger.debug(res) - return PartitionCollectionGenerator(self, method, result_gen(), next_partition) - # multiple objects, with linked partitioning - elif isinstance(res, dict) and res.has_key('next_partition_href'): - def result_gen(): - count = 0 - for item in res['collection']: - yield cls(item, self, stack) - count += 1 - if count == ApiConnector.LIST_LIMIT: - for item in continue_list_fetching(): - yield item - logger.debug(res) - return PartitionCollectionGenerator(self, method, result_gen(), next_partition) - else: - return cls(res, self, stack) - logger.debug("don't know how to handle result") - logger.debug(res) - return res - - def __getattr__(self, _name): - """ - Retrieve an API-method or a scoped domain-class. - - If the former, result is a callable that supports the following invocations: - - - calling (...), with possible arguments (positional/keyword), return the resulting resource or list of resources. - When calling, you can pass a keyword-argument B{params}. This must be a dict or L{MultiDict} and will be used to add additional query-get-parameters. - - - invoking append(resource) on it will PUT the resource, making it part of the current resource. Makes - sense only if it's a collection of course. - - - invoking remove(resource) on it will DELETE the resource from it's container. Also only usable on collections. - - TODO: describe the latter - """ - scope = self - - class api_call(object): - def __call__(selfish, *args, **kwargs): - return self._call(_name, *args, **kwargs) - - def new(self, **kwargs): - """ - Will invoke the new method on the named resource _name, with - self as scope. - """ - cls = RESTBase.REGISTRY[_name] - return cls.new(scope, **kwargs) - - def append(selfish, resource): - """ - If the current scope is - """ - try: - self._call(_name, str(resource.id), _alternate_http_method="PUT") - except AttributeError: - self._call(_name, str(resource), _alternate_http_method="PUT") - - def remove(selfish, resource): - try: - self._call(_name, str(resource.id), _alternate_http_method="DELETE") - except AttributeError: - self._call(_name, str(resource), _alternate_http_method="DELETE") - - if _name in RESTBase.ALL_DOMAIN_CLASSES: - cls = RESTBase.ALL_DOMAIN_CLASSES[_name] - - class ScopeBinder(object): - def new(self, *args, **data): - - d = MultiDict() - name = cls._singleton() - - def unfold_value(key, value): - if isinstance(value, (basestring, file)): - d.add(key, value) - elif isinstance(value, dict): - for sub_key, sub_value in value.iteritems(): - unfold_value("%s[%s]" % (key, sub_key), sub_value) - else: - # assume iteration else - for sub_value in value: - unfold_value(key + "[]", sub_value) - - - for key, value in data.iteritems(): - unfold_value("%s[%s]" % (name, key), value) - - return scope._call(cls.KIND, **d) - - def create(self, **data): - return cls.create(scope, **data) - - def get(self, id): - return cls.get(scope, id) - - - return ScopeBinder() - return api_call() - - def __repr__(self): - return str(self) - - def __str__(self): - scopes = self._scope - base = "" - if len(scopes) > 1: - base = str(scopes[-2]) - return base + "/" + str(scopes[-1]) - - -# maybe someday I'll make that work. -# class RESTBaseMeta(type): -# def __new__(self, name, bases, d): -# clazz = type(name, bases, d) -# if 'KIND' in d: -# kind = d['KIND'] -# RESTBase.REGISTRY[kind] = clazz -# return clazz - -class RESTBase(object): - """ - The baseclass for all our domain-objects/resources. - - - """ - REGISTRY = {} - - ALL_DOMAIN_CLASSES = {} - - ALIASES = [] - - KIND = None - - def __init__(self, data, scope, path_stack=None): - self.__data = data - self.__scope = scope - # try and see if we can/must create an id out of our path - logger.debug("path_stack: %r", path_stack) - if path_stack: - try: - id = int(path_stack[0]) - self.__data['id'] = id - except ValueError: - pass - - def __getattr__(self, name): - if name in self.__data: - obj = self.__data[name] - if name in RESTBase.REGISTRY: - if isinstance(obj, dict): - obj = RESTBase.REGISTRY[name](obj, self.__scope) - elif isinstance(obj, list): - obj = [RESTBase.REGISTRY[name](o, self.__scope) for o in obj] - else: - logger.warning("Found %s in our registry, but don't know what to do with"\ - "the object.") - return obj - scope = Scope(self.__scope._get_connector(), scope=self, parent=self.__scope) - return getattr(scope, name) - - def __setattr__(self, name, value): - """ - This method is used to set a property, a resource or a list of resources as property of the resource the - method is invoked on. - - For example, to set a comment on a track, do - - >>> sca = scapi.Scope(connector) - >>> track = scapi.Track.new(title='bar', sharing="private") - >>> comment = scapi.Comment.create(body="This is the body of my comment", timestamp=10) - >>> track.comments = comment - - To set a list of users as permissions, do - - >>> sca = scapi.Scope(connector) - >>> me = sca.me() - >>> track = scapi.Track.new(title='bar', sharing="private") - >>> users = sca.users() - >>> users_to_set = [user for user in users[:10] if user != me] - >>> track.permissions = users_to_set - - And finally, to simply change the title of a track, do - - >>> sca = scapi.Scope(connector) - >>> track = sca.Track.get(track_id) - >>> track.title = "new_title" - - @param name: the property name - @type name: str - @param value: the property, resource or resources to set - @type value: RESTBase | list | basestring | long | int | float - @return: None - """ - - # update "private" data, such as __data - if "_RESTBase__" in name: - self.__dict__[name] = value - else: - if isinstance(value, list) and len(value): - # the parametername is something like - # permissions[user_id][] - # so we try to infer that. - parameter_name = "%s[%s_id][]" % (name, value[0]._singleton()) - values = [o.id for o in value] - kwargs = {"_alternate_http_method" : "PUT", - parameter_name : values} - self.__scope._call(self.KIND, self.id, name, **kwargs) - elif isinstance(value, RESTBase): - # we got a single instance, so make that an argument - self.__scope._call(self.KIND, self.id, name, **value._as_arguments()) - else: - # we have a simple property - parameter_name = "%s[%s]" % (self._singleton(), name) - kwargs = {"_alternate_http_method" : "PUT", - parameter_name : self._convert_value(value)} - self.__scope._call(self.KIND, self.id, **kwargs) - - def _as_arguments(self): - """ - Converts a resource to a argument-string the way Rails expects it. - """ - res = {} - for key, value in self.__data.items(): - value = self._convert_value(value) - res["%s[%s]" % (self._singleton(), key)] = value - return res - - def _convert_value(self, value): - if isinstance(value, unicode): - value = value.encode("utf-8") - elif isinstance(value, file): - pass - else: - value = str(value) - return value - - @classmethod - def create(cls, scope, **data): - """ - This is a convenience-method for creating an object that will be passed - as parameter - e.g. a comment. A usage would look like this: - - >>> sca = scapi.Scope(connector) - >>> track = sca.Track.new(title='bar', sharing="private") - >>> comment = sca.Comment.create(body="This is the body of my comment", timestamp=10) - >>> track.comments = comment - - """ - return cls(data, scope) - - @classmethod - def new(cls, scope, **data): - """ - Create a new resource inside a given Scope. The actual values are in data. - - So for creating new resources, you have two options: - - - create an instance directly using the class: - - >>> scope = scapi.Scope(connector) - >>> scope.User.new(...) - - - - create a instance in a certain scope: - - >>> scope = scapi.Scope(connector) - >>> user = scapi.User("1") - >>> track = user.tracks.new() - - - @param scope: if not empty, a one-element tuple containing the Scope - @type scope: tuple[1] - @param data: the data - @type data: dict - @return: new instance of the resource - """ - return getattr(scope, cls.__name__).new(**data) - - @classmethod - def get(cls, scope, id): - """ - Fetch a resource by id. - - Simply pass a known id as argument. For example - - >>> sca = scapi.Scope(connector) - >>> track = sca.Track.get(id) - - """ - return getattr(scope, cls.KIND)(id) - - - def _scope(self): - """ - Return the scope this resource lives in, which is the KIND and id - - @return: "/" - """ - return "%s/%s" % (self.KIND, str(self.id)) - - @classmethod - def _singleton(cls): - """ - This method will take a resource name like "users" and - return the single-case, in the example "user". - - Currently, it's not very sophisticated, only strips a trailing s. - """ - name = cls.KIND - if name[-1] == 's': - return name[:-1] - raise ValueError("Can't make %s to a singleton" % name) - - def __repr__(self): - res = [] - res.append("\n\n******\n%s:" % self.__class__.__name__) - res.append("") - for key, v in self.__data.iteritems(): - key = str(key) - if isinstance(v, unicode): - v = v.encode('utf-8') - else: - v = str(v) - res.append("%s=%s" % (key, v)) - return "\n".join(res) - - def __hash__(self): - return hash("%s%i" % (self.KIND, self.id)) - - def __eq__(self, other): - """ - Test for equality. - - Resources are considered equal if the have the same kind and id. - """ - if not isinstance(other, RESTBase): - return False - res = self.KIND == other.KIND and self.id == other.id - return res - - def __ne__(self, other): - return not self == other - -class User(RESTBase): - """ - A user domain object/resource. - """ - KIND = 'users' - ALIASES = ['me', 'permissions', 'contacts', 'user'] - -class Track(RESTBase): - """ - A track domain object/resource. - """ - KIND = 'tracks' - ALIASES = ['favorites'] - -class Comment(RESTBase): - """ - A comment domain object/resource. - """ - KIND = 'comments' - -class Event(RESTBase): - """ - A event domain object/resource. - """ - KIND = 'events' - -class Playlist(RESTBase): - """ - A playlist/set domain object/resource - """ - KIND = 'playlists' - -class Group(RESTBase): - """ - A group domain object/resource - """ - KIND = 'groups' - - - -# this registers all the RESTBase subclasses. -# One day using a metaclass will make this a tad -# less ugly. -def register_classes(): - g = {} - g.update(globals()) - for name, cls in [(k, v) for k, v in g.iteritems() if isclass(v) and issubclass(v, RESTBase) and not v == RESTBase]: - RESTBase.REGISTRY[cls.KIND] = cls - RESTBase.ALL_DOMAIN_CLASSES[cls.__name__] = cls - for alias in cls.ALIASES: - RESTBase.REGISTRY[alias] = cls - __all__.append(name) -register_classes() diff --git a/python_apps/soundcloud-api/scapi/authentication.py b/python_apps/soundcloud-api/scapi/authentication.py deleted file mode 100644 index 52c527704..000000000 --- a/python_apps/soundcloud-api/scapi/authentication.py +++ /dev/null @@ -1,195 +0,0 @@ -## SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful -## API -## -## Copyright (C) 2008 Diez B. Roggisch -## Contact mailto:deets@soundcloud.com -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import base64 -import time, random -import urlparse -import hmac -import hashlib -from scapi.util import escape -import logging - - -USE_DOUBLE_ESCAPE_HACK = True -""" -There seems to be an uncertainty on the way -parameters are to be escaped. For now, this -variable switches between two escaping mechanisms. - -If True, the passed parameters - GET or POST - are -escaped *twice*. -""" - -logger = logging.getLogger(__name__) - -class OAuthSignatureMethod_HMAC_SHA1(object): - - FORBIDDEN = ['realm', 'oauth_signature'] - - def get_name(self): - return 'HMAC-SHA1' - - def build_signature(self, request, parameters, consumer_secret, token_secret, oauth_parameters): - if logger.level == logging.DEBUG: - logger.debug("request: %r", request) - logger.debug("parameters: %r", parameters) - logger.debug("consumer_secret: %r", consumer_secret) - logger.debug("token_secret: %r", token_secret) - logger.debug("oauth_parameters: %r", oauth_parameters) - - - temp = {} - temp.update(oauth_parameters) - for p in self.FORBIDDEN: - if p in temp: - del temp[p] - if parameters is not None: - temp.update(parameters) - sig = ( - escape(self.get_normalized_http_method(request)), - escape(self.get_normalized_http_url(request)), - self.get_normalized_parameters(temp), # these are escaped in the method already - ) - - key = '%s&' % consumer_secret - if token_secret is not None: - key += token_secret - raw = '&'.join(sig) - logger.debug("raw basestring: %s", raw) - logger.debug("key: %s", key) - # hmac object - hashed = hmac.new(key, raw, hashlib.sha1) - # calculate the digest base 64 - signature = escape(base64.b64encode(hashed.digest())) - return signature - - - def get_normalized_http_method(self, request): - return request.get_method().upper() - - - # parses the url and rebuilds it to be scheme://host/path - def get_normalized_http_url(self, request): - url = request.get_full_url() - parts = urlparse.urlparse(url) - url_string = '%s://%s%s' % (parts.scheme, parts.netloc, parts.path) - return url_string - - - def get_normalized_parameters(self, params): - if params is None: - params = {} - try: - # exclude the signature if it exists - del params['oauth_signature'] - except: - pass - key_values = [] - - for key, values in params.iteritems(): - if isinstance(values, file): - continue - if isinstance(values, (int, long, float)): - values = str(values) - if isinstance(values, (list, tuple)): - values = [str(v) for v in values] - if isinstance(values, basestring): - values = [values] - if USE_DOUBLE_ESCAPE_HACK and not key.startswith("ouath"): - key = escape(key) - for v in values: - v = v.encode("utf-8") - key = key.encode("utf-8") - if USE_DOUBLE_ESCAPE_HACK and not key.startswith("oauth"): - # this is a dirty hack to make the - # thing work with the current server-side - # implementation. Or is it by spec? - v = escape(v) - key_values.append(escape("%s=%s" % (key, v))) - # sort lexicographically, first after key, then after value - key_values.sort() - # combine key value pairs in string - return escape('&').join(key_values) - - -class OAuthAuthenticator(object): - OAUTH_API_VERSION = '1.0' - AUTHORIZATION_HEADER = "Authorization" - - def __init__(self, consumer=None, consumer_secret=None, token=None, secret=None, signature_method=OAuthSignatureMethod_HMAC_SHA1()): - if consumer == None: - raise ValueError("The consumer key must be passed for all public requests; it may not be None") - self._consumer, self._token, self._secret = consumer, token, secret - self._consumer_secret = consumer_secret - self._signature_method = signature_method - random.seed() - - - def augment_request(self, req, parameters, use_multipart=False, oauth_callback=None, oauth_verifier=None): - oauth_parameters = { - 'oauth_consumer_key': self._consumer, - 'oauth_timestamp': self.generate_timestamp(), - 'oauth_nonce': self.generate_nonce(), - 'oauth_version': self.OAUTH_API_VERSION, - 'oauth_signature_method': self._signature_method.get_name(), - #'realm' : "http://soundcloud.com", - } - if self._token is not None: - oauth_parameters['oauth_token'] = self._token - - if oauth_callback is not None: - oauth_parameters['oauth_callback'] = oauth_callback - - if oauth_verifier is not None: - oauth_parameters['oauth_verifier'] = oauth_verifier - - # in case we upload large files, we don't - # sign the request over the parameters - # There's a bug in the OAuth 1.0 (and a) specs that says that PUT request should omit parameters from the base string. - # This is fixed in the IETF draft, don't know when this will be released though. - HT - if use_multipart or req.get_method() == 'PUT': - parameters = None - - oauth_parameters['oauth_signature'] = self._signature_method.build_signature(req, - parameters, - self._consumer_secret, - self._secret, - oauth_parameters) - def to_header(d): - return ",".join('%s="%s"' % (key, value) for key, value in sorted(oauth_parameters.items())) - - req.add_header(self.AUTHORIZATION_HEADER, "OAuth %s" % to_header(oauth_parameters)) - - def generate_timestamp(self): - return int(time.time())# * 1000.0) - - def generate_nonce(self, length=8): - return ''.join(str(random.randint(0, 9)) for i in range(length)) - - -class BasicAuthenticator(object): - - def __init__(self, user, password, consumer, consumer_secret): - self._base64string = base64.encodestring("%s:%s" % (user, password))[:-1] - self._x_auth_header = 'OAuth oauth_consumer_key="%s" oauth_consumer_secret="%s"' % (consumer, consumer_secret) - - def augment_request(self, req, parameters): - req.add_header("Authorization", "Basic %s" % self._base64string) - req.add_header("X-Authorization", self._x_auth_header) diff --git a/python_apps/soundcloud-api/scapi/config.py b/python_apps/soundcloud-api/scapi/config.py deleted file mode 100644 index 139597f9c..000000000 --- a/python_apps/soundcloud-api/scapi/config.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/python_apps/soundcloud-api/scapi/json.py b/python_apps/soundcloud-api/scapi/json.py deleted file mode 100644 index a28a13e39..000000000 --- a/python_apps/soundcloud-api/scapi/json.py +++ /dev/null @@ -1,310 +0,0 @@ -import string -import types - -## json.py implements a JSON (http://json.org) reader and writer. -## Copyright (C) 2005 Patrick D. Logan -## Contact mailto:patrickdlogan@stardecisions.com -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -class _StringGenerator(object): - def __init__(self, string): - self.string = string - self.index = -1 - def peek(self): - i = self.index + 1 - if i < len(self.string): - return self.string[i] - else: - return None - def next(self): - self.index += 1 - if self.index < len(self.string): - return self.string[self.index] - else: - raise StopIteration - def all(self): - return self.string - -class WriteException(Exception): - pass - -class ReadException(Exception): - pass - -class JsonReader(object): - hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15} - escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'} - - def read(self, s): - self._generator = _StringGenerator(s) - result = self._read() - return result - - def _read(self): - self._eatWhitespace() - peek = self._peek() - if peek is None: - raise ReadException, "Nothing to read: '%s'" % self._generator.all() - if peek == '{': - return self._readObject() - elif peek == '[': - return self._readArray() - elif peek == '"': - return self._readString() - elif peek == '-' or peek.isdigit(): - return self._readNumber() - elif peek == 't': - return self._readTrue() - elif peek == 'f': - return self._readFalse() - elif peek == 'n': - return self._readNull() - elif peek == '/': - self._readComment() - return self._read() - else: - raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all() - - def _readTrue(self): - self._assertNext('t', "true") - self._assertNext('r', "true") - self._assertNext('u', "true") - self._assertNext('e', "true") - return True - - def _readFalse(self): - self._assertNext('f', "false") - self._assertNext('a', "false") - self._assertNext('l', "false") - self._assertNext('s', "false") - self._assertNext('e', "false") - return False - - def _readNull(self): - self._assertNext('n', "null") - self._assertNext('u', "null") - self._assertNext('l', "null") - self._assertNext('l', "null") - return None - - def _assertNext(self, ch, target): - if self._next() != ch: - raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all()) - - def _readNumber(self): - isfloat = False - result = self._next() - peek = self._peek() - while peek is not None and (peek.isdigit() or peek == "."): - isfloat = isfloat or peek == "." - result = result + self._next() - peek = self._peek() - try: - if isfloat: - return float(result) - else: - return int(result) - except ValueError: - raise ReadException, "Not a valid JSON number: '%s'" % result - - def _readString(self): - result = "" - assert self._next() == '"' - try: - while self._peek() != '"': - ch = self._next() - if ch == "\\": - ch = self._next() - if ch in 'brnft': - ch = self.escapes[ch] - elif ch == "u": - ch4096 = self._next() - ch256 = self._next() - ch16 = self._next() - ch1 = self._next() - n = 4096 * self._hexDigitToInt(ch4096) - n += 256 * self._hexDigitToInt(ch256) - n += 16 * self._hexDigitToInt(ch16) - n += self._hexDigitToInt(ch1) - ch = unichr(n) - elif ch not in '"/\\': - raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all()) - result = result + ch - except StopIteration: - raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all() - assert self._next() == '"' - return result - - def _hexDigitToInt(self, ch): - try: - result = self.hex_digits[ch.upper()] - except KeyError: - try: - result = int(ch) - except ValueError: - raise ReadException, "The character %s is not a hex digit." % ch - return result - - def _readComment(self): - assert self._next() == "/" - second = self._next() - if second == "/": - self._readDoubleSolidusComment() - elif second == '*': - self._readCStyleComment() - else: - raise ReadException, "Not a valid JSON comment: %s" % self._generator.all() - - def _readCStyleComment(self): - try: - done = False - while not done: - ch = self._next() - done = (ch == "*" and self._peek() == "/") - if not done and ch == "/" and self._peek() == "*": - raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all() - self._next() - except StopIteration: - raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all() - - def _readDoubleSolidusComment(self): - try: - ch = self._next() - while ch != "\r" and ch != "\n": - ch = self._next() - except StopIteration: - pass - - def _readArray(self): - result = [] - assert self._next() == '[' - done = self._peek() == ']' - while not done: - item = self._read() - result.append(item) - self._eatWhitespace() - done = self._peek() == ']' - if not done: - ch = self._next() - if ch != ",": - raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) - assert ']' == self._next() - return result - - def _readObject(self): - result = {} - assert self._next() == '{' - done = self._peek() == '}' - while not done: - key = self._read() - if type(key) is not types.StringType: - raise ReadException, "Not a valid JSON object key (should be a string): %s" % key - self._eatWhitespace() - ch = self._next() - if ch != ":": - raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch) - self._eatWhitespace() - val = self._read() - result[key] = val - self._eatWhitespace() - done = self._peek() == '}' - if not done: - ch = self._next() - if ch != ",": - raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) - assert self._next() == "}" - return result - - def _eatWhitespace(self): - p = self._peek() - while p is not None and p in string.whitespace or p == '/': - if p == '/': - self._readComment() - else: - self._next() - p = self._peek() - - def _peek(self): - return self._generator.peek() - - def _next(self): - return self._generator.next() - -class JsonWriter(object): - - def _append(self, s): - self._results.append(s) - - def write(self, obj, escaped_forward_slash=False): - self._escaped_forward_slash = escaped_forward_slash - self._results = [] - self._write(obj) - return "".join(self._results) - - def _write(self, obj): - ty = type(obj) - if ty is types.DictType: - n = len(obj) - self._append("{") - for k, v in obj.items(): - self._write(k) - self._append(":") - self._write(v) - n = n - 1 - if n > 0: - self._append(",") - self._append("}") - elif ty is types.ListType or ty is types.TupleType: - n = len(obj) - self._append("[") - for item in obj: - self._write(item) - n = n - 1 - if n > 0: - self._append(",") - self._append("]") - elif ty is types.StringType or ty is types.UnicodeType: - self._append('"') - obj = obj.replace('\\', r'\\') - if self._escaped_forward_slash: - obj = obj.replace('/', r'\/') - obj = obj.replace('"', r'\"') - obj = obj.replace('\b', r'\b') - obj = obj.replace('\f', r'\f') - obj = obj.replace('\n', r'\n') - obj = obj.replace('\r', r'\r') - obj = obj.replace('\t', r'\t') - self._append(obj) - self._append('"') - elif ty is types.IntType or ty is types.LongType: - self._append(str(obj)) - elif ty is types.FloatType: - self._append("%f" % obj) - elif obj is True: - self._append("true") - elif obj is False: - self._append("false") - elif obj is None: - self._append("null") - else: - raise WriteException, "Cannot write in JSON: %s" % repr(obj) - -def write(obj, escaped_forward_slash=False): - return JsonWriter().write(obj, escaped_forward_slash) - -def read(s): - return JsonReader().read(s) diff --git a/python_apps/soundcloud-api/scapi/tests/__init__.py b/python_apps/soundcloud-api/scapi/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/python_apps/soundcloud-api/scapi/tests/knaster.mp3 b/python_apps/soundcloud-api/scapi/tests/knaster.mp3 deleted file mode 100644 index 138749d65d71cdb8cdb76e9d7bc1edff173e96a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80493 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

?ce9^_{qLDvurO(SktEdBp_~@@pj-2k0bGnG6GY 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 Tp scapi.ApiConnector.LIST_LIMIT - - - - def test_filtered_list(self): - if not self.RUN_LONG_TESTS: - return - - sca = self.root - - tracks = list(sca.tracks(params={ - "bpm[from]" : "180", - })) - if len(tracks) < scapi.ApiConnector.LIST_LIMIT: - for i in xrange(scapi.ApiConnector.LIST_LIMIT): - sca.Track.new(title='test_track_%i' % i, asset_data=self.data) - all_tracks = sca.tracks() - assert not isinstance(all_tracks, list) - all_tracks = list(all_tracks) - assert len(all_tracks) > scapi.ApiConnector.LIST_LIMIT - - - def test_events(self): - events = list(self.root.events()) - assert isinstance(events, list) - assert isinstance(events[0], scapi.Event) - - - def test_me_having_stress(self): - sca = self.root - for _ in xrange(20): - self.setUp() - sca.me() - - - def test_non_global_api(self): - root = self.root - me = root.me() - assert isinstance(me, scapi.User) - - # now get something *from* that user - list(me.favorites()) - - - def test_playlists(self): - sca = self.root - playlists = list(itertools.islice(sca.playlists(), 0, 127)) - for playlist in playlists: - tracks = playlist.tracks - if not isinstance(tracks, list): - tracks = [tracks] - for trackdata in tracks: - print trackdata - #user = trackdata.user - #print user - #print user.tracks() - print playlist.user - break - - - - - def test_playlist_creation(self): - sca = self.root - sca.Playlist.new(title="I'm so happy, happy, happy, happy!") - - - - def test_groups(self): - if not self.RUN_LONG_TESTS: - return - - sca = self.root - groups = list(itertools.islice(sca.groups(), 0, 127)) - for group in groups: - users = group.users() - for user in users: - pass - - - def test_track_creation_with_email_sharers(self): - sca = self.root - emails = [dict(address="deets@web.de"), dict(address="hannes@soundcloud.com")] - track = sca.Track.new(title='bar', asset_data=self.data, - shared_to=dict(emails=emails) - ) - assert isinstance(track, scapi.Track) - - - - def test_track_creation_with_artwork(self): - sca = self.root - track = sca.Track.new(title='bar', - asset_data=self.data, - artwork_data=self.artwork_data, - ) - assert isinstance(track, scapi.Track) - - track.title = "foobarbaz" - - - - def test_oauth_get_signing(self): - sca = self.root - - url = "http://api.soundcloud.dev/oauth/test_request" - params = dict(foo="bar", - baz="padamm", - ) - url += sca._create_query_string(params) - signed_url = sca.oauth_sign_get_request(url) - - - res = urllib2.urlopen(signed_url).read() - assert "oauth_nonce" in res - - - def test_streaming(self): - sca = self.root - - track = sca.tracks(params={ - "filter" : "streamable", - }).next() - - - assert isinstance(track, scapi.Track) - - stream_url = track.stream_url - - signed_url = track.oauth_sign_get_request(stream_url) - - - def test_downloadable(self): - sca = self.root - - track = sca.tracks(params={ - "filter" : "downloadable", - }).next() - - - assert isinstance(track, scapi.Track) - - download_url = track.download_url - - signed_url = track.oauth_sign_get_request(download_url) - - data = urllib2.urlopen(signed_url).read() - assert data - - - - def test_modifying_playlists(self): - sca = self.root - - me = sca.me() - my_tracks = list(me.tracks()) - - assert my_tracks - - playlist = me.playlists().next() - # playlist = sca.Playlist.get(playlist.id) - - assert isinstance(playlist, scapi.Playlist) - - pl_tracks = playlist.tracks - - playlist.title = "foobarbaz" - - - - def test_track_deletion(self): - sca = self.root - track = sca.Track.new(title='bar', asset_data=self.data, - ) - - sca.tracks.remove(track) - - - - def test_track_creation_with_updated_artwork(self): - sca = self.root - track = sca.Track.new(title='bar', - asset_data=self.data, - ) - assert isinstance(track, scapi.Track) - - track.artwork_data = self.artwork_data - - def test_update_own_description(self): - sca = self.root - me = sca.me() - - new_description = "This is my new description" - old_description = "This is my old description" - - if me.description == new_description: - change_to_description = old_description - else: - change_to_description = new_description - - me.description = change_to_description - - user = sca.User.get(me.id) - assert user.description == change_to_description diff --git a/python_apps/soundcloud-api/scapi/tests/spam.jpg b/python_apps/soundcloud-api/scapi/tests/spam.jpg deleted file mode 100644 index a5ca9387927d8cf721f79b6386a8b674bf216618..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85062 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 b9~uk>B`)Z{ki_mp6}y6(mX`kj=0E@0vR)f1 diff --git a/python_apps/soundcloud-api/scapi/tests/test_connect.py b/python_apps/soundcloud-api/scapi/tests/test_connect.py deleted file mode 100644 index 3e045e6c1..000000000 --- a/python_apps/soundcloud-api/scapi/tests/test_connect.py +++ /dev/null @@ -1,334 +0,0 @@ -from __future__ import with_statement -import os -import tempfile -import itertools -from ConfigParser import SafeConfigParser -import pkg_resources -import scapi -import scapi.authentication -import logging -import webbrowser - -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) -_logger = logging.getLogger("scapi") -#_logger.setLevel(logging.DEBUG) - -RUN_INTERACTIVE_TESTS = False -USE_OAUTH = True - -TOKEN = "FjNE9aRTg8kpxuOjzwsX8Q" -SECRET = "NP5PGoyKcQv64E0aZgV4CRNzHfPwR4QghrWoqEgEE" -CONSUMER = "EEi2URUfM97pAAxHTogDpQ" -CONSUMER_SECRET = "NFYd8T3i4jVKGZ9TMy9LHaBQB3Sh8V5sxBiMeMZBow" -API_HOST = "api.soundcloud.dev:3000" -USER = "" -PASSWORD = "" - -CONFIG_NAME = "soundcloud.cfg" - -CONNECTOR = None -ROOT = None -def setup(): - global CONNECTOR, ROOT - # load_config() - #scapi.ApiConnector(host='192.168.2.101:3000', user='tiga', password='test') - #scapi.ApiConnector(host='sandbox-api.soundcloud.com:3030', user='tiga', password='test') - scapi.USE_PROXY = False - scapi.PROXY = 'http://127.0.0.1:10000/' - - if USE_OAUTH: - authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - TOKEN, - SECRET) - else: - authenticator = scapi.authentication.BasicAuthenticator(USER, PASSWORD, CONSUMER, CONSUMER_SECRET) - - logger.debug("API_HOST: %s", API_HOST) - CONNECTOR = scapi.ApiConnector(host=API_HOST, - authenticator=authenticator) - ROOT = scapi.Scope(CONNECTOR) - -def load_config(config_name=None): - global TOKEN, SECRET, CONSUMER_SECRET, CONSUMER, API_HOST, USER, PASSWORD - if config_name is None: - config_name = CONFIG_NAME - parser = SafeConfigParser() - current = os.getcwd() - while current: - name = os.path.join(current, config_name) - if os.path.exists(name): - parser.read([name]) - TOKEN = parser.get('global', 'accesstoken') - SECRET = parser.get('global', 'accesstoken_secret') - CONSUMER = parser.get('global', 'consumer') - CONSUMER_SECRET = parser.get('global', 'consumer_secret') - API_HOST = parser.get('global', 'host') - USER = parser.get('global', 'user') - PASSWORD = parser.get('global', 'password') - logger.debug("token: %s", TOKEN) - logger.debug("secret: %s", SECRET) - logger.debug("consumer: %s", CONSUMER) - logger.debug("consumer_secret: %s", CONSUMER_SECRET) - logger.debug("user: %s", USER) - logger.debug("password: %s", PASSWORD) - logger.debug("host: %s", API_HOST) - break - new_current = os.path.dirname(current) - if new_current == current: - break - current = new_current - - -def test_load_config(): - base = tempfile.mkdtemp() - oldcwd = os.getcwd() - cdir = os.path.join(base, "foo") - os.mkdir(cdir) - os.chdir(cdir) - test_config = """ -[global] -host=host -consumer=consumer -consumer_secret=consumer_secret -accesstoken=accesstoken -accesstoken_secret=accesstoken_secret -user=user -password=password -""" - with open(os.path.join(base, CONFIG_NAME), "w") as cf: - cf.write(test_config) - load_config() - assert TOKEN == "accesstoken" and SECRET == "accesstoken_secret" and API_HOST == 'host' - assert CONSUMER == "consumer" and CONSUMER_SECRET == "consumer_secret" - assert USER == "user" and PASSWORD == "password" - os.chdir(oldcwd) - load_config() - - -def test_connect(): - sca = ROOT - quite_a_few_users = list(itertools.islice(sca.users(), 0, 127)) - - logger.debug(quite_a_few_users) - assert isinstance(quite_a_few_users, list) and isinstance(quite_a_few_users[0], scapi.User) - user = sca.me() - logger.debug(user) - assert isinstance(user, scapi.User) - contacts = list(user.contacts()) - assert isinstance(contacts, list) - assert isinstance(contacts[0], scapi.User) - logger.debug(contacts) - tracks = list(user.tracks()) - assert isinstance(tracks, list) - assert isinstance(tracks[0], scapi.Track) - logger.debug(tracks) - - -def test_access_token_acquisition(): - """ - This test is commented out because it needs user-interaction. - """ - if not RUN_INTERACTIVE_TESTS: - return - oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - None, - None) - - sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) - token, secret = sca.fetch_request_token() - authorization_url = sca.get_request_token_authorization_url(token) - webbrowser.open(authorization_url) - raw_input("please press return") - oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - - sca = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) - token, secret = sca.fetch_access_token() - logger.info("Access token: '%s'", token) - logger.info("Access token secret: '%s'", secret) - oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - token, - secret) - - sca = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator) - test_track_creation() - -def test_track_creation(): - sca = ROOT - track = sca.Track.new(title='bar') - assert isinstance(track, scapi.Track) - -def test_track_update(): - sca = ROOT - track = sca.Track.new(title='bar') - assert isinstance(track, scapi.Track) - track.title='baz' - track = sca.Track.get(track.id) - assert track.title == "baz" - -def test_scoped_track_creation(): - sca = ROOT - user = sca.me() - track = user.tracks.new(title="bar") - assert isinstance(track, scapi.Track) - -def test_upload(): - assert pkg_resources.resource_exists("scapi.tests.test_connect", "knaster.mp3") - data = pkg_resources.resource_stream("scapi.tests.test_connect", "knaster.mp3") - sca = ROOT - user = sca.me() - logger.debug(user) - asset = sca.assets.new(filedata=data) - assert isinstance(asset, scapi.Asset) - logger.debug(asset) - tracks = list(user.tracks()) - track = tracks[0] - track.assets.append(asset) - -def test_contact_list(): - sca = ROOT - user = sca.me() - contacts = list(user.contacts()) - assert isinstance(contacts, list) - assert isinstance(contacts[0], scapi.User) - -def test_permissions(): - sca = ROOT - user = sca.me() - tracks = itertools.islice(user.tracks(), 1) - for track in tracks: - permissions = list(track.permissions()) - logger.debug(permissions) - assert isinstance(permissions, list) - if permissions: - assert isinstance(permissions[0], scapi.User) - -def test_setting_permissions(): - sca = ROOT - me = sca.me() - track = sca.Track.new(title='bar', sharing="private") - assert track.sharing == "private" - users = itertools.islice(sca.users(), 10) - users_to_set = [user for user in users if user != me] - assert users_to_set, "Didn't find any suitable users" - track.permissions = users_to_set - assert set(track.permissions()) == set(users_to_set) - -def test_setting_comments(): - sca = ROOT - user = sca.me() - track = sca.Track.new(title='bar', sharing="private") - comment = sca.Comment.create(body="This is the body of my comment", timestamp=10) - track.comments = comment - assert track.comments().next().body == comment.body - - -def test_setting_comments_the_way_shawn_says_its_correct(): - sca = ROOT - track = sca.Track.new(title='bar', sharing="private") - cbody = "This is the body of my comment" - track.comments.new(body=cbody, timestamp=10) - assert list(track.comments())[0].body == cbody - -def test_contact_add_and_removal(): - sca = ROOT - me = sca.me() - for user in sca.users(): - if user != me: - user_to_set = user - break - - contacts = list(me.contacts()) - if user_to_set in contacts: - me.contacts.remove(user_to_set) - - me.contacts.append(user_to_set) - - contacts = list(me.contacts() ) - assert user_to_set.id in [c.id for c in contacts] - - me.contacts.remove(user_to_set) - - contacts = list(me.contacts() ) - assert user_to_set not in contacts - - -def test_favorites(): - sca = ROOT - me = sca.me() - - favorites = list(me.favorites()) - assert favorites == [] or isinstance(favorites[0], scapi.Track) - - track = None - for user in sca.users(): - if user == me: - continue - for track in user.tracks(): - break - if track is not None: - break - - me.favorites.append(track) - - favorites = list(me.favorites()) - assert track in favorites - - me.favorites.remove(track) - - favorites = list(me.favorites()) - assert track not in favorites - -def test_large_list(): - sca = ROOT - tracks = list(sca.tracks()) - if len(tracks) < scapi.ApiConnector.LIST_LIMIT: - for i in xrange(scapi.ApiConnector.LIST_LIMIT): - scapi.Track.new(title='test_track_%i' % i) - all_tracks = sca.tracks() - assert not isinstance(all_tracks, list) - all_tracks = list(all_tracks) - assert len(all_tracks) > scapi.ApiConnector.LIST_LIMIT - - -def test_events(): - events = list(ROOT.events()) - assert isinstance(events, list) - assert isinstance(events[0], scapi.Event) - -def test_me_having_stress(): - sca = ROOT - for _ in xrange(20): - setup() - sca.me() - -def test_non_global_api(): - root = scapi.Scope(CONNECTOR) - me = root.me() - assert isinstance(me, scapi.User) - - # now get something *from* that user - favorites = list(me.favorites()) - assert favorites - -def test_playlists(): - sca = ROOT - playlists = list(itertools.islice(sca.playlists(), 0, 127)) - found = False - for playlist in playlists: - tracks = playlist.tracks - if not isinstance(tracks, list): - tracks = [tracks] - for trackdata in tracks: - print trackdata - user = trackdata.user - print user - print user.tracks() - print playlist.user - break diff --git a/python_apps/soundcloud-api/scapi/tests/test_oauth.py b/python_apps/soundcloud-api/scapi/tests/test_oauth.py deleted file mode 100644 index d283c0048..000000000 --- a/python_apps/soundcloud-api/scapi/tests/test_oauth.py +++ /dev/null @@ -1,36 +0,0 @@ -import pkg_resources -import scapi -import scapi.authentication -import urllib -import logging - -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) -_logger = logging.getLogger("scapi") -_logger.setLevel(logging.DEBUG) - -TOKEN = "QcciYu1FSwDSGKAG2mNw" -SECRET = "gJ2ok6ULUsYQB3rsBmpHCRHoFCAPOgK8ZjoIyxzris" -CONSUMER = "Cy2eLPrIMp4vOxjz9icdQ" -CONSUMER_SECRET = "KsBa272x6M2to00Vo5FdvZXt9kakcX7CDIPJoGwTro" - -def test_base64_connect(): - scapi.USE_PROXY = True - scapi.PROXY = 'http://127.0.0.1:10000/' - scapi.SoundCloudAPI(host='192.168.2.31:3000', authenticator=scapi.authentication.BasicAuthenticator('tiga', 'test')) - sca = scapi.Scope() - assert isinstance(sca.me(), scapi.User) - - -def test_oauth_connect(): - scapi.USE_PROXY = True - scapi.PROXY = 'http://127.0.0.1:10000/' - scapi.SoundCloudAPI(host='192.168.2.31:3000', - authenticator=scapi.authentication.OAuthAuthenticator(CONSUMER, - CONSUMER_SECRET, - TOKEN, SECRET)) - - sca = scapi.Scope() - assert isinstance(sca.me(), scapi.User) - - diff --git a/python_apps/soundcloud-api/scapi/util.py b/python_apps/soundcloud-api/scapi/util.py deleted file mode 100644 index 00fa66897..000000000 --- a/python_apps/soundcloud-api/scapi/util.py +++ /dev/null @@ -1,53 +0,0 @@ -## SouncCloudAPI implements a Python wrapper around the SoundCloud RESTful -## API -## -## Copyright (C) 2008 Diez B. Roggisch -## Contact mailto:deets@soundcloud.com -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import urllib - -def escape(s): - # escape '/' too - return urllib.quote(s, safe='') - - - - - - -class MultiDict(dict): - - - def add(self, key, new_value): - if key in self: - value = self[key] - if not isinstance(value, list): - value = [value] - self[key] = value - value.append(new_value) - else: - self[key] = new_value - - - def iteritemslist(self): - for key, value in self.iteritems(): - if not isinstance(value, list): - value = [value] - yield key, value - - - diff --git a/python_apps/soundcloud-api/setup.py b/python_apps/soundcloud-api/setup.py deleted file mode 100644 index dc057a603..000000000 --- a/python_apps/soundcloud-api/setup.py +++ /dev/null @@ -1,22 +0,0 @@ -from setuptools import setup, find_packages - -TEST_REQUIRES = ["ConfigObj>=4.5.3", "nose>=0.10"] - - -setup( - name = "SoundCloudAPI", - version = "0.1", - packages = find_packages(), - author = "Diez B. Roggisch", - author_email = "deets@web.de", - description = "This is an implementation of the SoundCloud RESTful API", - license = "MIT", - keywords = "Soundcloud client API REST", - url = "http://wiki.github.com/soundcloud/api/python-api-wrapper/", - install_requires = ['simplejson'] + TEST_REQUIRES, -# tests_require = TEST_REQUIRES, -# extras_require = dict( -# test = TEST_REQUIRES -# ), - test_suite = 'nose.collector' -) diff --git a/python_apps/soundcloud-api/test.ini b/python_apps/soundcloud-api/test.ini deleted file mode 100644 index c9d1422b3..000000000 --- a/python_apps/soundcloud-api/test.ini +++ /dev/null @@ -1,33 +0,0 @@ -[api] - -# api.soundcloud.dev credentials -api_host=api.soundcloud.dev -consumer=gLnhFeUBnBCZF8a6Ngqq7w -consumer_secret=nbWRdG5X9xUb63l4nIeFYm3nmeVJ2v4s1ROpvRSBvU8 -token=xt5f76c7qPVCBNX3Vrw6A -secret=Ow2WHDKN4YRxrVfcPOt9pHf52Pzv70fp8lG0catQ5w - -# api.sandbox-soundcloud.com credentials -#api_host=api.sandbox-soundcloud.com -#consumer=gLnhFeUBnBCZF8a6Ngqq7w -#consumer_secret=nbWRdG5X9xUb63l4nIeFYm3nmeVJ2v4s1ROpvRSBvU8 -#token=8aX4ApxRweZJsZYe1PTFxQ -#secret=ydZOeG5zQXe8AiExvnzQVfqgySCrbFp0TLSz7BsnBqo - -user=deets -password=kgl27f - -#request_token_url=api.sandbox-soundcloud.com/oauth/request_token -#authorize_token_url=sandbox-soundcloud.com/oauth/authorize_token -#access_token_url=api.sandbox-soundcloud.com/oauth/request_token - -[proxy] -use_proxy=false - -[logging] -test_logger=DEBUG -api_logger=DEBUG - -[test] -run_interactive_tests=false -run_long_tests=false From ca6fd4b9ee1c84ad8e8b6ff4404b49b0f4dfdd0d Mon Sep 17 00:00:00 2001 From: lukabazuka Date: Wed, 23 Mar 2011 18:19:53 +0100 Subject: [PATCH 28/74] Issue CC-2063 resolved --- public/css/images/icon_rebroadcast.png | Bin 0 -> 1075 bytes public/css/images/icon_record.png | Bin 0 -> 1080 bytes public/css/styles.css | 21 ++++++++++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 public/css/images/icon_rebroadcast.png create mode 100644 public/css/images/icon_record.png diff --git a/public/css/images/icon_rebroadcast.png b/public/css/images/icon_rebroadcast.png new file mode 100644 index 0000000000000000000000000000000000000000..5282d87b2aba3ae5ae60e122f5d1b77c4c42cb27 GIT binary patch literal 1075 zcmbVLO=#0l9M33>Z8#8gFvo;P=0#bPm!#=Owrp#g%oXf5x`G7}mL_j&*pe5MH=7m3 z;!Z*@g5be}mt92gAb1!a1QBF-@uqke1`|B(B#1Blm>$Xw29o!Y-|zSTezdxLeRO1E zgkhM`!je{^>ll4Uh6d^P*3+@Cbh$+I3R%M&q;B|#$y&IIK*2FKQ3)B=?wvz4%P=v^ zE>}pUctbI={xd@A19@XrnhL6@7 z%Vo2%Wo9gPeh$or3Keh=F+k{SyMYp_Y+F~M`{Jo?j zOveeT~2#!}Qo(j7`H&HZY zd}w&Qz(L+|qPW`VfRxZ*H~ON3@~(&Y5(@B+Z_;{fO!de#cV`=lfYcjh#kXlujBO2@ zI}UP5K~q`!hqG);$>>rpk)u%yazclKkQH-DEuGeK8cgZwjMUTU$IVJYn!+VnPUZzc zhiNejwMALXrBh-;7R4U7;0DBSP1Lh%Q@dTRcqUiL`^X^JFJrvj>wwi7COD{J59HTm zaMN}zTo0n+bYj(zZ{J1MqK_TW&aPtjv7XTc4NBQWGA+yfqwa96|H&9no#CU__@`BR zSG514?P=rF!|CWCm(Gh%2SfdkJ)uKI^OY@!->U1)W&`|Q8QNn8yn4j!4_-e1UA@QYUp~HHxY9frfA;e8z=hawb39f^KB;{g)-N8+ ofop}w&Epr2cmL|lOl+Y!z)Wioe%zK{A4X$b(3iDWx%G#C0D9(6HUIzs literal 0 HcmV?d00001 diff --git a/public/css/images/icon_record.png b/public/css/images/icon_record.png new file mode 100644 index 0000000000000000000000000000000000000000..ffedeb5c12ed33368016ea3f435956de0fc28332 GIT binary patch literal 1080 zcmbVLO=#0l91jj{h$N3Zj@LZ)>(CFH7FmY~W=e zDxT(Lmw~8XSi?8=NxMq8E#xEfs&I$b+fSKqOqls zs=hR%rwnfR44d|4Dqta^vA#8Hd$OP5TDmgb2iH8uwjg9C!|gg%E0x(Cb`dK@Kv)NH zz{Z7$5RD}giBqfy1i%B47sRlTkfWju0NZ{zYRxq!sG|Upr@N*@Ol-4(qBeo&Nrt1I?uKAFrP7|T?X?p{ zQ^xz6!wV6>TUHQP3+<5#`s+qlv{zkp5MMzao_BRxkIA79ndWYPLjjO_BagZ!Es8b^ zu|97hn-pP&qkkfXX~-!xs>Bo;wIIb*AP8AeiNjpWGdRx=*CrI`FK15p(Mp~ zf}nyVkf4$Tc~MnTk{E>@ZqfFLX6vY9*Q9pa+}yrgIp-pcV7H3#Y^MXtbxg2V#}1nt zlh|?7HgLlWinALlM6S7jjJ%62wv}Dk>|#9y1qh3#Gr-!}KK{lNimk!38+vy!TRMSP6t@`gbD%+t=wl_WW`R0!=>&++kk8bU3 z_GDk59_{rv#|sL$b?_Q^y4AO`vV8sFhsPQ9YHqN+eDXW|^>ylST>F^ME9=|EXP550 xdNjSUcID#v-^ZGI(_c`3uD%@jbWd74aD=&Am@5yyeK8Qsa#0 h3 > span.ui-icon.ui-icon-triangle-1-e, #schedule_playlist_chosen li > h3 > span.ui-icon.ui-icon-triangle-1-s { float:left; - margin-right: 8px; } #schedule_playlist_chosen li > h3 > span.ui-icon.ui-icon-close { @@ -1474,9 +1473,21 @@ ul.errors li { margin:-4px 3px -3px 0; float:right; } - .time-flow { - float:right; - margin-right:4px; + float:right; + margin-right:4px; } - +.small-icon { + display:block; + width:21px; + height:10px; + float:right; + margin-left:3px; +} +.small-icon.recording { + background:url(images/icon_record.png) no-repeat 0 0; +} +.small-icon.rebroadcast { + background:url(images/icon_rebroadcast.png) no-repeat 0 0; +} + \ No newline at end of file From d982419b164c08d103ef428007e7c9d06b42397c Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 23 Mar 2011 13:43:11 -0400 Subject: [PATCH 29/74] CC-1894: Warn users about time zone differences or clock drift problems on the server -An error msg now appears in pypo log when pypo and server timezones do not match --- application/models/Schedule.php | 1 + pypo/pypofetch.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 21419c4f0..dd3555a26 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -716,6 +716,7 @@ class Schedule { $result['stream_metadata'] = array(); $result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat(); $result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName(); + $result['server_timezone'] = date_default_timezone_get(); return $result; } diff --git a/pypo/pypofetch.py b/pypo/pypofetch.py index c31bd094a..0313e9567 100644 --- a/pypo/pypofetch.py +++ b/pypo/pypofetch.py @@ -69,13 +69,22 @@ class PypoFetch(Thread): consumer.register_callback(handle_message) consumer.consume() - logger.info("PypoFetch: init complete"); + logger.info("PypoFetch: init complete") def set_export_source(self, export_source): self.export_source = export_source self.cache_dir = config["cache_dir"] + self.export_source + '/' + def check_matching_timezones(self, server_timezone): + logger = logging.getLogger('fetch') + f = open('/etc/timezone', 'r') + pypo_timezone = f.readline().strip(' \t\n\r') + f.close() + if server_timezone != pypo_timezone: + logger.error("Server and pypo timezones do not match. Audio playback may not start when expected!") + logger.error("Server timezone: %s", server_timezone) + logger.error("Pypo timezone: %s", pypo_timezone) """ Process the schedule @@ -88,7 +97,9 @@ class PypoFetch(Thread): def process_schedule(self, schedule_data, export_source): logger = logging.getLogger('fetch') self.schedule = schedule_data["playlists"] - + + self.check_matching_timezones(schedule_data["server_timezone"]) + # Push stream metadata to liquidsoap # TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!! stream_metadata = schedule_data['stream_metadata'] From 36a68aa589971142a3ccacdb8e3d803ac950fb3a Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 23 Mar 2011 16:37:35 -0400 Subject: [PATCH 30/74] -incorrectly removing directories in pypo-uninstall script fixed --- pypo/install/pypo-uninstall.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pypo/install/pypo-uninstall.py b/pypo/install/pypo-uninstall.py index a9f339be0..6dcc42ce5 100644 --- a/pypo/install/pypo-uninstall.py +++ b/pypo/install/pypo-uninstall.py @@ -38,16 +38,16 @@ try: remove_path(BASE_PATH) print "Removing daemontool script pypo" - remove_path("rm -rf /etc/service/pypo") + remove_path("/etc/service/pypo") if os.path.exists("/etc/service/pypo-fetch"): - remove_path("rm -rf /etc/service/pypo-fetch") + remove_path("/etc/service/pypo-fetch") if os.path.exists("/etc/service/pypo-push"): - remove_path("rm -rf /etc/service/pypo-push") + remove_path("/etc/service/pypo-push") print "Removing daemontool script pypo-liquidsoap" - remove_path("rm -rf /etc/service/pypo-liquidsoap") + remove_path("/etc/service/pypo-liquidsoap") remove_user("pypo") print "Uninstall complete." From c15c92d855b7e04bfc7c27332e4cf52a0be3745d Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 17:07:59 -0400 Subject: [PATCH 31/74] Fixed comments for poll_interval value. --- pypo/config.cfg | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pypo/config.cfg b/pypo/config.cfg index b4dc9424e..4fd5ac377 100644 --- a/pypo/config.cfg +++ b/pypo/config.cfg @@ -41,13 +41,11 @@ cache_for = 24 #how long to hold the cache, in hours # Poll interval in seconds. # -# This is how often the poll script downloads new schedules and files from the -# server. +# This will rarely need to be changed because any schedule changes are +# automatically sent to pypo immediately. # -# For production use, this number depends on whether you plan on making any -# last-minute changes to your schedule. This number should be set to half of -# the time you expect to "lock-in" your schedule. So if your schedule is set -# 24 hours in advance, this can be set to poll every 12 hours. +# This is how often the poll script downloads new schedules and files from the +# server in the event that no changes are made to the schedule. # poll_interval = 3600 # in seconds. From d943548f27e042f9729c13f7944e8e83b382de0d Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 18:16:08 -0400 Subject: [PATCH 32/74] CC-2095: Changes to the stream metadata are not pushed to pypo Fixed. --- application/models/Preference.php | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/application/models/Preference.php b/application/models/Preference.php index 6ecc83ae4..8662f4424 100644 --- a/application/models/Preference.php +++ b/application/models/Preference.php @@ -8,30 +8,30 @@ class Application_Model_Preference $auth = Zend_Auth::getInstance(); $id = $auth->getIdentity()->id; - + //Check if key already exists $sql = "SELECT COUNT(*) FROM cc_pref" ." WHERE keystr = '$key'"; $result = $CC_DBC->GetOne($sql); - + if ($result == 1){ $sql = "UPDATE cc_pref" ." SET subjid = $id, valstr = '$value'" - ." WHERE keystr = '$key'"; + ." WHERE keystr = '$key'"; } else { $sql = "INSERT INTO cc_pref (subjid, keystr, valstr)" ." VALUES ($id, '$key', '$value')"; } return $CC_DBC->query($sql); } - + public static function GetValue($key){ global $CC_CONFIG, $CC_DBC; //Check if key already exists $sql = "SELECT COUNT(*) FROM cc_pref" ." WHERE keystr = '$key'"; $result = $CC_DBC->GetOne($sql); - + if ($result == 0) return ""; else { @@ -40,9 +40,9 @@ class Application_Model_Preference $result = $CC_DBC->GetOne($sql); return $result; } - + } - + public static function GetHeadTitle(){ /* Caches the title name as a session variable so we dont access * the database on every page load. */ @@ -55,31 +55,32 @@ class Application_Model_Preference } if (strlen($title) > 0) $title .= " - "; - + return $title."Airtime"; } - + public static function SetHeadTitle($title, $view){ - Application_Model_Preference::SetValue("station_name", $title); - $defaultNamespace = new Zend_Session_Namespace('title_name'); + Application_Model_Preference::SetValue("station_name", $title); + $defaultNamespace = new Zend_Session_Namespace('title_name'); $defaultNamespace->title = $title; - + RabbitMq::PushSchedule(); + //set session variable to new station name so that html title is updated. //should probably do this in a view helper to keep this controller as minimal as possible. $view->headTitle()->exchangeArray(array()); //clear headTitle ArrayObject $view->headTitle(Application_Model_Preference::GetHeadTitle()); } - public static function SetShowsPopulatedUntil($timestamp) { - Application_Model_Preference::SetValue("shows_populated_until", $timestamp); + public static function SetShowsPopulatedUntil($timestamp) { + Application_Model_Preference::SetValue("shows_populated_until", $timestamp); } public static function GetShowsPopulatedUntil() { return Application_Model_Preference::GetValue("shows_populated_until"); } - public static function SetDefaultFade($fade) { - Application_Model_Preference::SetValue("default_fade", $fade); + public static function SetDefaultFade($fade) { + Application_Model_Preference::SetValue("default_fade", $fade); } public static function GetDefaultFade() { @@ -88,6 +89,7 @@ class Application_Model_Preference public static function SetStreamLabelFormat($type){ Application_Model_Preference::SetValue("stream_label_format", $type); + RabbitMq::PushSchedule(); } public static function GetStreamLabelFormat(){ @@ -98,24 +100,24 @@ class Application_Model_Preference return Application_Model_Preference::getValue("station_name"); } - public static function SetDoSoundCloudUpload($upload) { - Application_Model_Preference::SetValue("soundcloud_upload", $upload); + public static function SetDoSoundCloudUpload($upload) { + Application_Model_Preference::SetValue("soundcloud_upload", $upload); } public static function GetDoSoundCloudUpload() { return Application_Model_Preference::GetValue("soundcloud_upload"); } - public static function SetSoundCloudUser($user) { - Application_Model_Preference::SetValue("soundcloud_user", $user); + public static function SetSoundCloudUser($user) { + Application_Model_Preference::SetValue("soundcloud_user", $user); } public static function GetSoundCloudUser() { return Application_Model_Preference::GetValue("soundcloud_user"); } - public static function SetSoundCloudPassword($password) { - Application_Model_Preference::SetValue("soundcloud_password", $password); + public static function SetSoundCloudPassword($password) { + Application_Model_Preference::SetValue("soundcloud_password", $password); } public static function GetSoundCloudPassword() { From 52e3f673d1910039a9060c9780a8278c3af3005e Mon Sep 17 00:00:00 2001 From: naomiaro Date: Wed, 23 Mar 2011 19:52:00 -0400 Subject: [PATCH 33/74] CC-1630 : Automatic recording of shows forgot to actually modify this file... now stops recorder service. --- python_apps/show-recorder/install/recorder-stop.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/python_apps/show-recorder/install/recorder-stop.py b/python_apps/show-recorder/install/recorder-stop.py index 388c0bc4b..c8eb45562 100644 --- a/python_apps/show-recorder/install/recorder-stop.py +++ b/python_apps/show-recorder/install/recorder-stop.py @@ -9,17 +9,8 @@ if os.geteuid() != 0: sys.exit(1) try: - print "Stopping daemontool script pypo" - os.system("svc -dx /etc/service/pypo 1>/dev/null 2>&1") - - if os.path.exists("/etc/service/pypo-fetch"): - os.system("svc -dx /etc/service/pypo-fetch 1>/dev/null 2>&1") - if os.path.exists("/etc/service/pypo-push"): - os.system("svc -dx /etc/service/pypo-push 1>/dev/null 2>&1") - - print "Stopping daemontool script pypo-liquidsoap" - os.system("svc -dx /etc/service/pypo-liquidsoap 1>/dev/null 2>&1") - os.system("killall liquidsoap") + print "Stopping daemontool script recorder" + os.system("svc -dx /etc/service/recorder 1>/dev/null 2>&1") except Exception, e: print "exception:" + str(e) From 8a2610aa8482acb04e9b331aafd8e2230c623991 Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 23 Mar 2011 22:14:57 -0400 Subject: [PATCH 34/74] CC-1894: Warn users about time zone differences or clock drift problems on the server -Now using timezone offsets from UTC instead of regions to compare timezones between pypo and the airtime webserver --- application/models/Schedule.php | 2 +- pypo/pypofetch.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index aaff58ef9..ba5b97290 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -716,7 +716,7 @@ class Schedule { $result['stream_metadata'] = array(); $result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat(); $result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName(); - $result['server_timezone'] = date_default_timezone_get(); + $result['server_timezone'] = date('O'); return $result; } diff --git a/pypo/pypofetch.py b/pypo/pypofetch.py index 0313e9567..2958c6bd4 100644 --- a/pypo/pypofetch.py +++ b/pypo/pypofetch.py @@ -11,6 +11,7 @@ import json import telnetlib import math from threading import Thread +from subprocess import Popen, PIPE # For RabbitMQ from kombu.connection import BrokerConnection @@ -78,13 +79,14 @@ class PypoFetch(Thread): def check_matching_timezones(self, server_timezone): logger = logging.getLogger('fetch') - f = open('/etc/timezone', 'r') - pypo_timezone = f.readline().strip(' \t\n\r') - f.close() + + process = Popen(["date", "+%z"], stdout=PIPE) + pypo_timezone = (process.communicate()[0]).strip(' \r\n\t') + if server_timezone != pypo_timezone: - logger.error("Server and pypo timezones do not match. Audio playback may not start when expected!") - logger.error("Server timezone: %s", server_timezone) - logger.error("Pypo timezone: %s", pypo_timezone) + logger.error("Server and pypo timezone offsets do not match. Audio playback may not start when expected!") + logger.error("Server timezone offset: %s", server_timezone) + logger.error("Pypo timezone offset: %s", pypo_timezone) """ Process the schedule From 3fed7a7ab59b8548bf0331bd0df46fddd0e1fb71 Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 23 Mar 2011 22:22:07 -0400 Subject: [PATCH 35/74] CC-2045: Role drop-down box has no label in Manage users page, should default to 'guest' -fixed --- application/forms/AddUser.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/forms/AddUser.php b/application/forms/AddUser.php index e1f0453a7..d1eca586b 100644 --- a/application/forms/AddUser.php +++ b/application/forms/AddUser.php @@ -68,12 +68,13 @@ class Application_Form_AddUser extends Zend_Form $this->addElement($jabber); $select = new Zend_Form_Element_Select('type'); + $select->setLabel('User Type:'); $select->setAttrib('class', 'input_select'); $select->setAttrib('style', 'width: 40%'); $select->setMultiOptions(array( - "A" => "admin", - "H" => "host", "G" => "guest", + "H" => "host", + "A" => "admin" )); $select->setRequired(true); $this->addElement($select); From 50432c0b66093dea663ba8af397fbd59e2626ab2 Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 23 Mar 2011 22:32:12 -0400 Subject: [PATCH 36/74] CC-2046: About box could display version number -Done --- application/views/scripts/partialviews/header.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/views/scripts/partialviews/header.phtml b/application/views/scripts/partialviews/header.phtml index 4905d0d10..a817fc1fd 100644 --- a/application/views/scripts/partialviews/header.phtml +++ b/application/views/scripts/partialviews/header.phtml @@ -43,6 +43,6 @@

From f9c8a7cc11e904adc6af9d74a600eff667e4c15b Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Wed, 23 Mar 2011 23:24:06 -0400 Subject: [PATCH 37/74] CC-2096 Schedule changes should be sent to RabbitMQ at most once per user request Implemented as a plugin to Zend. Now at most one schedule push to RabbitMQ will happen per user action. It's pretty sweet. --- application/Bootstrap.php | 22 ++++++----- .../controllers/plugins/RabbitMqPlugin.php | 9 +++++ application/models/RabbitMq.php | 39 ++++++++++++------- 3 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 application/controllers/plugins/RabbitMqPlugin.php diff --git a/application/Bootstrap.php b/application/Bootstrap.php index bf9591e56..19a2cc72c 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -1,7 +1,7 @@ setFetchMode(DB_FETCHMODE_ASSOC); //Zend_Session::start(); Zend_Validate::setDefaultNamespaces("Zend"); +$front = Zend_Controller_Front::getInstance(); +$front->registerPlugin(new RabbitMqPlugin()); + class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initDoctype() @@ -48,9 +51,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap protected function _initHeadLink() { $view = $this->getResource('view'); - $view->headLink()->appendStylesheet('/css/redmond/jquery-ui-1.8.8.custom.css'); - $this->view->headLink()->appendStylesheet('/css/pro_dropdown_3.css'); $this->view->headLink()->appendStylesheet('/css/styles.css'); } @@ -70,14 +71,17 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript'); } - protected function _initViewHelpers(){ + protected function _initViewHelpers() + { $view = $this->getResource('view'); $view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper'); } - protected function _initTitle(){ + protected function _initTitle() + { $view = $this->getResource('view'); $view->headTitle(Application_Model_Preference::GetHeadTitle()); } + } diff --git a/application/controllers/plugins/RabbitMqPlugin.php b/application/controllers/plugins/RabbitMqPlugin.php new file mode 100644 index 000000000..3316f01b2 --- /dev/null +++ b/application/controllers/plugins/RabbitMqPlugin.php @@ -0,0 +1,9 @@ +channel(); - $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); + if (RabbitMq::$doPush) { + $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"], + $CC_CONFIG["rabbitmq"]["port"], + $CC_CONFIG["rabbitmq"]["user"], + $CC_CONFIG["rabbitmq"]["password"]); + $channel = $conn->channel(); + $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); - $EXCHANGE = 'airtime-schedule'; - $channel->exchange_declare($EXCHANGE, 'direct', false, true); + $EXCHANGE = 'airtime-schedule'; + $channel->exchange_declare($EXCHANGE, 'direct', false, true); - $data = json_encode(Schedule::ExportRangeAsJson()); - $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); + $data = json_encode(Schedule::ExportRangeAsJson()); + $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); - $channel->basic_publish($msg, $EXCHANGE); - $channel->close(); - $conn->close(); + $channel->basic_publish($msg, $EXCHANGE); + $channel->close(); + $conn->close(); + } } } From 9447f4fb8203a413dd4d88eb178e906be3f857f0 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Wed, 23 Mar 2011 23:36:45 -0400 Subject: [PATCH 38/74] CC-2063 : record/rebroadcast icons for calendar display icons are put on calendar. --- application/models/Shows.php | 6 +----- .../schedule/full-calendar-functions.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/application/models/Shows.php b/application/models/Shows.php index f0a7a20bc..8aa83beae 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -473,15 +473,11 @@ class Show { $event = array(); if($show["rebroadcast"]) { - $title = "REBROADCAST ".$show["name"]; $event["disableResizing"] = true; } - else { - $title = $show["name"]; - } $event["id"] = $show["instance_id"]; - $event["title"] = $title; + $event["title"] = $show["name"]; $event["start"] = $show["starts"]; $event["end"] = $show["ends"]; $event["allDay"] = false; diff --git a/public/js/airtime/schedule/full-calendar-functions.js b/public/js/airtime/schedule/full-calendar-functions.js index 33df795b7..ce01e4583 100644 --- a/public/js/airtime/schedule/full-calendar-functions.js +++ b/public/js/airtime/schedule/full-calendar-functions.js @@ -165,6 +165,25 @@ function eventRender(event, element, view) { } $(element).find(".fc-event-title").after(div); + } + + //add the record/rebroadcast icons if needed. + if((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.record === 1) { + + $(element).find(".fc-event-time").after(''); + } + if(view.name === 'month' && event.record === 1) { + + $(element).find(".fc-event-title").after(''); + } + + if((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.rebroadcast === 1) { + + $(element).find(".fc-event-time").after(''); + } + if(view.name === 'month' && event.rebroadcast === 1) { + + $(element).find(".fc-event-title").after(''); } if(event.backgroundColor !== "") { From 5c8719d90c6b4208422941ee1714009726147c3a Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 00:00:46 -0400 Subject: [PATCH 39/74] CC-2016: Rearrange python scripts for reusability -moved files --- {pypo => python_apps}/api_clients/__init__.py | 0 {pypo => python_apps}/api_clients/api_client.py | 0 {pypo => python_apps/pypo}/AUTHORS | 0 {pypo => python_apps/pypo}/LICENSE | 0 {pypo => python_apps/pypo}/config.cfg | 0 {pypo => python_apps/pypo}/config.cfg.dist | 0 {pypo => python_apps/pypo}/dls/__init__.py | 0 {pypo => python_apps/pypo}/dls/dls_client.py | 0 .../pypo}/install/pypo-daemontools-liquidsoap.sh | 0 .../pypo}/install/pypo-daemontools-logger.sh | 0 .../pypo}/install/pypo-daemontools.sh | 0 {pypo => python_apps/pypo}/install/pypo-install.py | 0 {pypo => python_apps/pypo}/install/pypo-start.py | 0 {pypo => python_apps/pypo}/install/pypo-stop.py | 0 .../pypo}/install/pypo-uninstall.py | 0 {pypo => python_apps/pypo}/liquidsoap/liquidsoap32 | Bin {pypo => python_apps/pypo}/liquidsoap/liquidsoap64 | Bin .../pypo}/logging-api-validator.cfg | 0 {pypo => python_apps/pypo}/logging.cfg | 0 {pypo => python_apps/pypo}/pypo-api-validator.py | 0 {pypo => python_apps/pypo}/pypo-cli.py | 0 {pypo => python_apps/pypo}/pypo-cue-in-validator.py | 0 {pypo => python_apps/pypo}/pypo-dls.py | 0 {pypo => python_apps/pypo}/pypo-log.sh | 0 {pypo => python_apps/pypo}/pypo-notify.py | 0 {pypo => python_apps/pypo}/pypofetch.py | 0 {pypo => python_apps/pypo}/pypopush.py | 0 {pypo => python_apps/pypo}/scripts/library/Makefile | 0 .../pypo}/scripts/library/ask-liquidsoap.pl | 0 .../pypo}/scripts/library/ask-liquidsoap.rb | 0 .../pypo}/scripts/library/external-todo.liq | 0 .../pypo}/scripts/library/externals.liq | 0 .../pypo}/scripts/library/extract-replaygain | 0 .../pypo}/scripts/library/interactive.screen | 0 .../pypo}/scripts/library/lastfm.liq | 0 .../pypo}/scripts/library/liquidsoap.gentoo.initd | 0 .../scripts/library/liquidsoap.gentoo.initd.in | 0 .../pypo}/scripts/library/liquidsoap.initd | 0 .../pypo}/scripts/library/liquidsoap.initd.in | 0 .../pypo}/scripts/library/liquidsoap.logrotate | 0 .../pypo}/scripts/library/liquidsoap.logrotate.in | 0 .../pypo}/scripts/library/liquidtts | 0 .../pypo}/scripts/library/liquidtts.in | 0 .../pypo}/scripts/library/pervasives.liq | 0 .../pypo}/scripts/library/shoutcast.liq | 0 {pypo => python_apps/pypo}/scripts/library/test.liq | 0 .../pypo}/scripts/library/typing.liq | 0 .../pypo}/scripts/library/utils.liq | 0 {pypo => python_apps/pypo}/scripts/ls_config.liq | 0 {pypo => python_apps/pypo}/scripts/ls_lib.liq | 0 {pypo => python_apps/pypo}/scripts/ls_script.liq | 0 {pypo => python_apps/pypo}/scripts/notify.sh | 0 {pypo => python_apps/pypo}/scripts/old_files/README | 0 .../pypo}/scripts/old_files/cue_file.py | 0 .../pypo}/scripts/old_files/include_daypart.liq | 0 .../scripts/old_files/include_dynamic_vars.liq | 0 .../pypo}/scripts/old_files/include_live_in.liq | 0 .../pypo}/scripts/old_files/include_notify.liq | 0 .../pypo}/scripts/old_files/include_scheduler.liq | 0 .../pypo}/scripts/old_files/library.liq | 0 .../pypo}/scripts/old_files/log_run.sh | 0 .../pypo}/scripts/old_files/ls_config.liq.dist | 0 .../pypo}/scripts/old_files/ls_cue.liq | 0 .../pypo}/scripts/old_files/ls_run.sh | 0 .../pypo}/scripts/old_files/ls_script.liq | 0 .../pypo}/scripts/old_files/silence-playlist.lsp | 0 .../pypo}/test/airtime-schedule-insert.php | 0 {pypo => python_apps/pypo}/util/__init__.py | 0 {pypo => python_apps/pypo}/util/cue_file.py | 0 {pypo => python_apps/pypo}/util/status.py | 0 70 files changed, 0 insertions(+), 0 deletions(-) rename {pypo => python_apps}/api_clients/__init__.py (100%) rename {pypo => python_apps}/api_clients/api_client.py (100%) rename {pypo => python_apps/pypo}/AUTHORS (100%) rename {pypo => python_apps/pypo}/LICENSE (100%) rename {pypo => python_apps/pypo}/config.cfg (100%) rename {pypo => python_apps/pypo}/config.cfg.dist (100%) rename {pypo => python_apps/pypo}/dls/__init__.py (100%) rename {pypo => python_apps/pypo}/dls/dls_client.py (100%) rename {pypo => python_apps/pypo}/install/pypo-daemontools-liquidsoap.sh (100%) rename {pypo => python_apps/pypo}/install/pypo-daemontools-logger.sh (100%) rename {pypo => python_apps/pypo}/install/pypo-daemontools.sh (100%) rename {pypo => python_apps/pypo}/install/pypo-install.py (100%) rename {pypo => python_apps/pypo}/install/pypo-start.py (100%) rename {pypo => python_apps/pypo}/install/pypo-stop.py (100%) rename {pypo => python_apps/pypo}/install/pypo-uninstall.py (100%) rename {pypo => python_apps/pypo}/liquidsoap/liquidsoap32 (100%) rename {pypo => python_apps/pypo}/liquidsoap/liquidsoap64 (100%) rename {pypo => python_apps/pypo}/logging-api-validator.cfg (100%) rename {pypo => python_apps/pypo}/logging.cfg (100%) rename {pypo => python_apps/pypo}/pypo-api-validator.py (100%) rename {pypo => python_apps/pypo}/pypo-cli.py (100%) rename {pypo => python_apps/pypo}/pypo-cue-in-validator.py (100%) rename {pypo => python_apps/pypo}/pypo-dls.py (100%) rename {pypo => python_apps/pypo}/pypo-log.sh (100%) rename {pypo => python_apps/pypo}/pypo-notify.py (100%) rename {pypo => python_apps/pypo}/pypofetch.py (100%) rename {pypo => python_apps/pypo}/pypopush.py (100%) rename {pypo => python_apps/pypo}/scripts/library/Makefile (100%) rename {pypo => python_apps/pypo}/scripts/library/ask-liquidsoap.pl (100%) rename {pypo => python_apps/pypo}/scripts/library/ask-liquidsoap.rb (100%) rename {pypo => python_apps/pypo}/scripts/library/external-todo.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/externals.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/extract-replaygain (100%) rename {pypo => python_apps/pypo}/scripts/library/interactive.screen (100%) rename {pypo => python_apps/pypo}/scripts/library/lastfm.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.gentoo.initd (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.gentoo.initd.in (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.initd (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.initd.in (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.logrotate (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidsoap.logrotate.in (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidtts (100%) rename {pypo => python_apps/pypo}/scripts/library/liquidtts.in (100%) rename {pypo => python_apps/pypo}/scripts/library/pervasives.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/shoutcast.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/test.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/typing.liq (100%) rename {pypo => python_apps/pypo}/scripts/library/utils.liq (100%) rename {pypo => python_apps/pypo}/scripts/ls_config.liq (100%) rename {pypo => python_apps/pypo}/scripts/ls_lib.liq (100%) rename {pypo => python_apps/pypo}/scripts/ls_script.liq (100%) rename {pypo => python_apps/pypo}/scripts/notify.sh (100%) rename {pypo => python_apps/pypo}/scripts/old_files/README (100%) rename {pypo => python_apps/pypo}/scripts/old_files/cue_file.py (100%) rename {pypo => python_apps/pypo}/scripts/old_files/include_daypart.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/include_dynamic_vars.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/include_live_in.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/include_notify.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/include_scheduler.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/library.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/log_run.sh (100%) rename {pypo => python_apps/pypo}/scripts/old_files/ls_config.liq.dist (100%) rename {pypo => python_apps/pypo}/scripts/old_files/ls_cue.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/ls_run.sh (100%) rename {pypo => python_apps/pypo}/scripts/old_files/ls_script.liq (100%) rename {pypo => python_apps/pypo}/scripts/old_files/silence-playlist.lsp (100%) rename {pypo => python_apps/pypo}/test/airtime-schedule-insert.php (100%) rename {pypo => python_apps/pypo}/util/__init__.py (100%) rename {pypo => python_apps/pypo}/util/cue_file.py (100%) rename {pypo => python_apps/pypo}/util/status.py (100%) diff --git a/pypo/api_clients/__init__.py b/python_apps/api_clients/__init__.py similarity index 100% rename from pypo/api_clients/__init__.py rename to python_apps/api_clients/__init__.py diff --git a/pypo/api_clients/api_client.py b/python_apps/api_clients/api_client.py similarity index 100% rename from pypo/api_clients/api_client.py rename to python_apps/api_clients/api_client.py diff --git a/pypo/AUTHORS b/python_apps/pypo/AUTHORS similarity index 100% rename from pypo/AUTHORS rename to python_apps/pypo/AUTHORS diff --git a/pypo/LICENSE b/python_apps/pypo/LICENSE similarity index 100% rename from pypo/LICENSE rename to python_apps/pypo/LICENSE diff --git a/pypo/config.cfg b/python_apps/pypo/config.cfg similarity index 100% rename from pypo/config.cfg rename to python_apps/pypo/config.cfg diff --git a/pypo/config.cfg.dist b/python_apps/pypo/config.cfg.dist similarity index 100% rename from pypo/config.cfg.dist rename to python_apps/pypo/config.cfg.dist diff --git a/pypo/dls/__init__.py b/python_apps/pypo/dls/__init__.py similarity index 100% rename from pypo/dls/__init__.py rename to python_apps/pypo/dls/__init__.py diff --git a/pypo/dls/dls_client.py b/python_apps/pypo/dls/dls_client.py similarity index 100% rename from pypo/dls/dls_client.py rename to python_apps/pypo/dls/dls_client.py diff --git a/pypo/install/pypo-daemontools-liquidsoap.sh b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh similarity index 100% rename from pypo/install/pypo-daemontools-liquidsoap.sh rename to python_apps/pypo/install/pypo-daemontools-liquidsoap.sh diff --git a/pypo/install/pypo-daemontools-logger.sh b/python_apps/pypo/install/pypo-daemontools-logger.sh similarity index 100% rename from pypo/install/pypo-daemontools-logger.sh rename to python_apps/pypo/install/pypo-daemontools-logger.sh diff --git a/pypo/install/pypo-daemontools.sh b/python_apps/pypo/install/pypo-daemontools.sh similarity index 100% rename from pypo/install/pypo-daemontools.sh rename to python_apps/pypo/install/pypo-daemontools.sh diff --git a/pypo/install/pypo-install.py b/python_apps/pypo/install/pypo-install.py similarity index 100% rename from pypo/install/pypo-install.py rename to python_apps/pypo/install/pypo-install.py diff --git a/pypo/install/pypo-start.py b/python_apps/pypo/install/pypo-start.py similarity index 100% rename from pypo/install/pypo-start.py rename to python_apps/pypo/install/pypo-start.py diff --git a/pypo/install/pypo-stop.py b/python_apps/pypo/install/pypo-stop.py similarity index 100% rename from pypo/install/pypo-stop.py rename to python_apps/pypo/install/pypo-stop.py diff --git a/pypo/install/pypo-uninstall.py b/python_apps/pypo/install/pypo-uninstall.py similarity index 100% rename from pypo/install/pypo-uninstall.py rename to python_apps/pypo/install/pypo-uninstall.py diff --git a/pypo/liquidsoap/liquidsoap32 b/python_apps/pypo/liquidsoap/liquidsoap32 similarity index 100% rename from pypo/liquidsoap/liquidsoap32 rename to python_apps/pypo/liquidsoap/liquidsoap32 diff --git a/pypo/liquidsoap/liquidsoap64 b/python_apps/pypo/liquidsoap/liquidsoap64 similarity index 100% rename from pypo/liquidsoap/liquidsoap64 rename to python_apps/pypo/liquidsoap/liquidsoap64 diff --git a/pypo/logging-api-validator.cfg b/python_apps/pypo/logging-api-validator.cfg similarity index 100% rename from pypo/logging-api-validator.cfg rename to python_apps/pypo/logging-api-validator.cfg diff --git a/pypo/logging.cfg b/python_apps/pypo/logging.cfg similarity index 100% rename from pypo/logging.cfg rename to python_apps/pypo/logging.cfg diff --git a/pypo/pypo-api-validator.py b/python_apps/pypo/pypo-api-validator.py similarity index 100% rename from pypo/pypo-api-validator.py rename to python_apps/pypo/pypo-api-validator.py diff --git a/pypo/pypo-cli.py b/python_apps/pypo/pypo-cli.py similarity index 100% rename from pypo/pypo-cli.py rename to python_apps/pypo/pypo-cli.py diff --git a/pypo/pypo-cue-in-validator.py b/python_apps/pypo/pypo-cue-in-validator.py similarity index 100% rename from pypo/pypo-cue-in-validator.py rename to python_apps/pypo/pypo-cue-in-validator.py diff --git a/pypo/pypo-dls.py b/python_apps/pypo/pypo-dls.py similarity index 100% rename from pypo/pypo-dls.py rename to python_apps/pypo/pypo-dls.py diff --git a/pypo/pypo-log.sh b/python_apps/pypo/pypo-log.sh similarity index 100% rename from pypo/pypo-log.sh rename to python_apps/pypo/pypo-log.sh diff --git a/pypo/pypo-notify.py b/python_apps/pypo/pypo-notify.py similarity index 100% rename from pypo/pypo-notify.py rename to python_apps/pypo/pypo-notify.py diff --git a/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py similarity index 100% rename from pypo/pypofetch.py rename to python_apps/pypo/pypofetch.py diff --git a/pypo/pypopush.py b/python_apps/pypo/pypopush.py similarity index 100% rename from pypo/pypopush.py rename to python_apps/pypo/pypopush.py diff --git a/pypo/scripts/library/Makefile b/python_apps/pypo/scripts/library/Makefile similarity index 100% rename from pypo/scripts/library/Makefile rename to python_apps/pypo/scripts/library/Makefile diff --git a/pypo/scripts/library/ask-liquidsoap.pl b/python_apps/pypo/scripts/library/ask-liquidsoap.pl similarity index 100% rename from pypo/scripts/library/ask-liquidsoap.pl rename to python_apps/pypo/scripts/library/ask-liquidsoap.pl diff --git a/pypo/scripts/library/ask-liquidsoap.rb b/python_apps/pypo/scripts/library/ask-liquidsoap.rb similarity index 100% rename from pypo/scripts/library/ask-liquidsoap.rb rename to python_apps/pypo/scripts/library/ask-liquidsoap.rb diff --git a/pypo/scripts/library/external-todo.liq b/python_apps/pypo/scripts/library/external-todo.liq similarity index 100% rename from pypo/scripts/library/external-todo.liq rename to python_apps/pypo/scripts/library/external-todo.liq diff --git a/pypo/scripts/library/externals.liq b/python_apps/pypo/scripts/library/externals.liq similarity index 100% rename from pypo/scripts/library/externals.liq rename to python_apps/pypo/scripts/library/externals.liq diff --git a/pypo/scripts/library/extract-replaygain b/python_apps/pypo/scripts/library/extract-replaygain similarity index 100% rename from pypo/scripts/library/extract-replaygain rename to python_apps/pypo/scripts/library/extract-replaygain diff --git a/pypo/scripts/library/interactive.screen b/python_apps/pypo/scripts/library/interactive.screen similarity index 100% rename from pypo/scripts/library/interactive.screen rename to python_apps/pypo/scripts/library/interactive.screen diff --git a/pypo/scripts/library/lastfm.liq b/python_apps/pypo/scripts/library/lastfm.liq similarity index 100% rename from pypo/scripts/library/lastfm.liq rename to python_apps/pypo/scripts/library/lastfm.liq diff --git a/pypo/scripts/library/liquidsoap.gentoo.initd b/python_apps/pypo/scripts/library/liquidsoap.gentoo.initd similarity index 100% rename from pypo/scripts/library/liquidsoap.gentoo.initd rename to python_apps/pypo/scripts/library/liquidsoap.gentoo.initd diff --git a/pypo/scripts/library/liquidsoap.gentoo.initd.in b/python_apps/pypo/scripts/library/liquidsoap.gentoo.initd.in similarity index 100% rename from pypo/scripts/library/liquidsoap.gentoo.initd.in rename to python_apps/pypo/scripts/library/liquidsoap.gentoo.initd.in diff --git a/pypo/scripts/library/liquidsoap.initd b/python_apps/pypo/scripts/library/liquidsoap.initd similarity index 100% rename from pypo/scripts/library/liquidsoap.initd rename to python_apps/pypo/scripts/library/liquidsoap.initd diff --git a/pypo/scripts/library/liquidsoap.initd.in b/python_apps/pypo/scripts/library/liquidsoap.initd.in similarity index 100% rename from pypo/scripts/library/liquidsoap.initd.in rename to python_apps/pypo/scripts/library/liquidsoap.initd.in diff --git a/pypo/scripts/library/liquidsoap.logrotate b/python_apps/pypo/scripts/library/liquidsoap.logrotate similarity index 100% rename from pypo/scripts/library/liquidsoap.logrotate rename to python_apps/pypo/scripts/library/liquidsoap.logrotate diff --git a/pypo/scripts/library/liquidsoap.logrotate.in b/python_apps/pypo/scripts/library/liquidsoap.logrotate.in similarity index 100% rename from pypo/scripts/library/liquidsoap.logrotate.in rename to python_apps/pypo/scripts/library/liquidsoap.logrotate.in diff --git a/pypo/scripts/library/liquidtts b/python_apps/pypo/scripts/library/liquidtts similarity index 100% rename from pypo/scripts/library/liquidtts rename to python_apps/pypo/scripts/library/liquidtts diff --git a/pypo/scripts/library/liquidtts.in b/python_apps/pypo/scripts/library/liquidtts.in similarity index 100% rename from pypo/scripts/library/liquidtts.in rename to python_apps/pypo/scripts/library/liquidtts.in diff --git a/pypo/scripts/library/pervasives.liq b/python_apps/pypo/scripts/library/pervasives.liq similarity index 100% rename from pypo/scripts/library/pervasives.liq rename to python_apps/pypo/scripts/library/pervasives.liq diff --git a/pypo/scripts/library/shoutcast.liq b/python_apps/pypo/scripts/library/shoutcast.liq similarity index 100% rename from pypo/scripts/library/shoutcast.liq rename to python_apps/pypo/scripts/library/shoutcast.liq diff --git a/pypo/scripts/library/test.liq b/python_apps/pypo/scripts/library/test.liq similarity index 100% rename from pypo/scripts/library/test.liq rename to python_apps/pypo/scripts/library/test.liq diff --git a/pypo/scripts/library/typing.liq b/python_apps/pypo/scripts/library/typing.liq similarity index 100% rename from pypo/scripts/library/typing.liq rename to python_apps/pypo/scripts/library/typing.liq diff --git a/pypo/scripts/library/utils.liq b/python_apps/pypo/scripts/library/utils.liq similarity index 100% rename from pypo/scripts/library/utils.liq rename to python_apps/pypo/scripts/library/utils.liq diff --git a/pypo/scripts/ls_config.liq b/python_apps/pypo/scripts/ls_config.liq similarity index 100% rename from pypo/scripts/ls_config.liq rename to python_apps/pypo/scripts/ls_config.liq diff --git a/pypo/scripts/ls_lib.liq b/python_apps/pypo/scripts/ls_lib.liq similarity index 100% rename from pypo/scripts/ls_lib.liq rename to python_apps/pypo/scripts/ls_lib.liq diff --git a/pypo/scripts/ls_script.liq b/python_apps/pypo/scripts/ls_script.liq similarity index 100% rename from pypo/scripts/ls_script.liq rename to python_apps/pypo/scripts/ls_script.liq diff --git a/pypo/scripts/notify.sh b/python_apps/pypo/scripts/notify.sh similarity index 100% rename from pypo/scripts/notify.sh rename to python_apps/pypo/scripts/notify.sh diff --git a/pypo/scripts/old_files/README b/python_apps/pypo/scripts/old_files/README similarity index 100% rename from pypo/scripts/old_files/README rename to python_apps/pypo/scripts/old_files/README diff --git a/pypo/scripts/old_files/cue_file.py b/python_apps/pypo/scripts/old_files/cue_file.py similarity index 100% rename from pypo/scripts/old_files/cue_file.py rename to python_apps/pypo/scripts/old_files/cue_file.py diff --git a/pypo/scripts/old_files/include_daypart.liq b/python_apps/pypo/scripts/old_files/include_daypart.liq similarity index 100% rename from pypo/scripts/old_files/include_daypart.liq rename to python_apps/pypo/scripts/old_files/include_daypart.liq diff --git a/pypo/scripts/old_files/include_dynamic_vars.liq b/python_apps/pypo/scripts/old_files/include_dynamic_vars.liq similarity index 100% rename from pypo/scripts/old_files/include_dynamic_vars.liq rename to python_apps/pypo/scripts/old_files/include_dynamic_vars.liq diff --git a/pypo/scripts/old_files/include_live_in.liq b/python_apps/pypo/scripts/old_files/include_live_in.liq similarity index 100% rename from pypo/scripts/old_files/include_live_in.liq rename to python_apps/pypo/scripts/old_files/include_live_in.liq diff --git a/pypo/scripts/old_files/include_notify.liq b/python_apps/pypo/scripts/old_files/include_notify.liq similarity index 100% rename from pypo/scripts/old_files/include_notify.liq rename to python_apps/pypo/scripts/old_files/include_notify.liq diff --git a/pypo/scripts/old_files/include_scheduler.liq b/python_apps/pypo/scripts/old_files/include_scheduler.liq similarity index 100% rename from pypo/scripts/old_files/include_scheduler.liq rename to python_apps/pypo/scripts/old_files/include_scheduler.liq diff --git a/pypo/scripts/old_files/library.liq b/python_apps/pypo/scripts/old_files/library.liq similarity index 100% rename from pypo/scripts/old_files/library.liq rename to python_apps/pypo/scripts/old_files/library.liq diff --git a/pypo/scripts/old_files/log_run.sh b/python_apps/pypo/scripts/old_files/log_run.sh similarity index 100% rename from pypo/scripts/old_files/log_run.sh rename to python_apps/pypo/scripts/old_files/log_run.sh diff --git a/pypo/scripts/old_files/ls_config.liq.dist b/python_apps/pypo/scripts/old_files/ls_config.liq.dist similarity index 100% rename from pypo/scripts/old_files/ls_config.liq.dist rename to python_apps/pypo/scripts/old_files/ls_config.liq.dist diff --git a/pypo/scripts/old_files/ls_cue.liq b/python_apps/pypo/scripts/old_files/ls_cue.liq similarity index 100% rename from pypo/scripts/old_files/ls_cue.liq rename to python_apps/pypo/scripts/old_files/ls_cue.liq diff --git a/pypo/scripts/old_files/ls_run.sh b/python_apps/pypo/scripts/old_files/ls_run.sh similarity index 100% rename from pypo/scripts/old_files/ls_run.sh rename to python_apps/pypo/scripts/old_files/ls_run.sh diff --git a/pypo/scripts/old_files/ls_script.liq b/python_apps/pypo/scripts/old_files/ls_script.liq similarity index 100% rename from pypo/scripts/old_files/ls_script.liq rename to python_apps/pypo/scripts/old_files/ls_script.liq diff --git a/pypo/scripts/old_files/silence-playlist.lsp b/python_apps/pypo/scripts/old_files/silence-playlist.lsp similarity index 100% rename from pypo/scripts/old_files/silence-playlist.lsp rename to python_apps/pypo/scripts/old_files/silence-playlist.lsp diff --git a/pypo/test/airtime-schedule-insert.php b/python_apps/pypo/test/airtime-schedule-insert.php similarity index 100% rename from pypo/test/airtime-schedule-insert.php rename to python_apps/pypo/test/airtime-schedule-insert.php diff --git a/pypo/util/__init__.py b/python_apps/pypo/util/__init__.py similarity index 100% rename from pypo/util/__init__.py rename to python_apps/pypo/util/__init__.py diff --git a/pypo/util/cue_file.py b/python_apps/pypo/util/cue_file.py similarity index 100% rename from pypo/util/cue_file.py rename to python_apps/pypo/util/cue_file.py diff --git a/pypo/util/status.py b/python_apps/pypo/util/status.py similarity index 100% rename from pypo/util/status.py rename to python_apps/pypo/util/status.py From 079878e5f09e2fbed7a351631a5a3e0b7fe935a2 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 00:35:01 -0400 Subject: [PATCH 40/74] CC-2016: Rearrange python scripts for reusability -Added api_client to PYTHONPATH env variable --- install/airtime-install.php | 2 +- install/installInit.php | 2 +- python_apps/pypo/install/pypo-daemontools.sh | 8 ++++++-- python_apps/pypo/install/pypo-install.py | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/install/airtime-install.php b/install/airtime-install.php index ffcdea662..fdd867ee5 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -53,7 +53,7 @@ echo "* Python eggs Setup".PHP_EOL; AirtimeInstall::SetUpPythonEggs(); echo PHP_EOL."*** Pypo Installation ***".PHP_EOL; -system("python ".__DIR__."/../pypo/install/pypo-install.py"); +system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py"); echo PHP_EOL."*** Recorder Installation ***".PHP_EOL; system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install.py"); diff --git a/install/installInit.php b/install/installInit.php index 65fb574fb..fdb4d4d0f 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -79,7 +79,7 @@ class AirtimeInstall { { $api_key = AirtimeInstall::GenerateRandomString(); AirtimeInstall::UpdateIniValue(__DIR__.'/../build/airtime.conf', 'api_key', $api_key); - AirtimeInstall::UpdateIniValue(__DIR__.'/../pypo/config.cfg', 'api_key', "'$api_key'"); + AirtimeInstall::UpdateIniValue(__DIR__.'/../python_apps/pypo/config.cfg', 'api_key', "'$api_key'"); } public static function ExitIfNotRoot() diff --git a/python_apps/pypo/install/pypo-daemontools.sh b/python_apps/pypo/install/pypo-daemontools.sh index 6e7bed55d..1f276cc4e 100644 --- a/python_apps/pypo/install/pypo-daemontools.sh +++ b/python_apps/pypo/install/pypo-daemontools.sh @@ -3,12 +3,16 @@ pypo_user="pypo" export HOME="/home/pypo/" # Location of pypo_cli.py Python script pypo_path="/opt/pypo/bin/" +api_client_path="/opt/pypo/" pypo_script="pypo-cli.py" echo "*** Daemontools: starting daemon" cd ${pypo_path} exec 2>&1 + +PYTHONPATH=${api_client_path}:$PYTHONPATH +export PYTHONPATH + # Note the -u when calling python! we need it to get unbuffered binary stdout and stderr exec setuidgid ${pypo_user} \ - python -u ${pypo_path}${pypo_script} \ - -f + python -u ${pypo_path}${pypo_script} # EOF diff --git a/python_apps/pypo/install/pypo-install.py b/python_apps/pypo/install/pypo-install.py index b764dcec9..1171dfe23 100644 --- a/python_apps/pypo/install/pypo-install.py +++ b/python_apps/pypo/install/pypo-install.py @@ -94,6 +94,7 @@ try: sys.exit(1) copy_dir("%s/.."%current_script_dir, BASE_PATH+"bin/") + copy_dir("%s/../../api_clients"%current_script_dir, BASE_PATH+"api_clients/") print "Setting permissions" os.system("chmod -R 755 "+BASE_PATH) From bf925901c19dc9fbc28f09714b7491d76259f604 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 00:52:35 -0400 Subject: [PATCH 41/74] CC-2016: Rearrange python scripts for reusability -Fixed pypo-notify.py not being to find new location of api_clients module --- .gitignore | 2 +- .../pypo/install/pypo-daemontools-liquidsoap.sh | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 94b090b91..2db593e69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .* *.pyc /files -pypo/liquidsoap/liquidsoap +python_apps/pypo/liquidsoap/liquidsoap build/build.properties diff --git a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh index 6f9061bfa..2b4ce0df4 100644 --- a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh +++ b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh @@ -1,10 +1,16 @@ #!/bin/sh ls_user="pypo" export HOME="/home/pypo/" +api_client_path="/opt/pypo/" ls_path="/opt/pypo/bin/liquidsoap/liquidsoap" ls_param="/opt/pypo/bin/scripts/ls_script.liq" echo "*** Daemontools: starting liquidsoap" exec 2>&1 -echo "exec sudo -u ${ls_user} ${ls_path} ${ls_param} " -cd /opt/pypo/bin/scripts && sudo -u ${ls_user} ${ls_path} ${ls_param} + +PYTHONPATH=${api_client_path}:$PYTHONPATH +export PYTHONPATH + +cd /opt/pypo/bin/scripts +exec setuidgid ${ls_user} \ + ${ls_path} ${ls_param} # EOF From f108ac846f86774ca457197ae7f633e718bb4984 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 02:12:08 -0400 Subject: [PATCH 42/74] CC-2058: Utilities are not in the system $PATH -Added airtime-clean-storage and airtime-import symbolic links --- install/airtime-install.php | 3 + install/airtime-uninstall.php | 1 + install/installInit.php | 16 +++ utils/{CleanStor.sh => airtime-clean-storage} | 2 +- utils/airtime-clean-storage.php | 124 ++++++++++++++++++ utils/airtime-import | 11 +- utils/airtime-import.php | 2 +- utils/{CleanStor.php => cleanStor.php} | 2 +- utils/resetStorage.sh | 41 ------ 9 files changed, 153 insertions(+), 49 deletions(-) rename utils/{CleanStor.sh => airtime-clean-storage} (95%) create mode 100644 utils/airtime-clean-storage.php rename utils/{CleanStor.php => cleanStor.php} (98%) delete mode 100755 utils/resetStorage.sh diff --git a/install/airtime-install.php b/install/airtime-install.php index fdd867ee5..1d350f1e1 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -46,6 +46,9 @@ AirtimeInstall::SetupStorageDirectory($CC_CONFIG); echo "* Setting Dir Permissions".PHP_EOL; AirtimeInstall::ChangeDirOwnerToWebserver($CC_CONFIG["storageDir"]); +echo "* Creating /usr/bin symlinks".PHP_EOL; +AirtimeInstall::CreateSymlinks($CC_CONFIG["storageDir"]); + echo "* Importing Sample Audio Clips".PHP_EOL; system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null"); diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index d175856d5..d30b4ee76 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -20,6 +20,7 @@ require_once(dirname(__FILE__).'/installInit.php'); // Need to check that we are superuser before running this. AirtimeInstall::ExitIfNotRoot(); +AirtimeInstall::RemoveSymlinks(); echo "******************************* Uninstall Begin ********************************".PHP_EOL; //------------------------------------------------------------------------ diff --git a/install/installInit.php b/install/installInit.php index fdb4d4d0f..ffad0ac29 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -203,4 +203,20 @@ class AirtimeInstall { exec($command); } + public static function CreateSymlinks(){ + AirtimeInstall::RemoveSymlinks(); + + $dir = realpath(__DIR__."/../utils/airtime-import"); + exec("ln -s $dir /usr/bin/airtime-import"); + + $dir = realpath(__DIR__."/../utils/airtime-clean-storage"); + exec("ln -s $dir /usr/bin/airtime-clean-storage"); + } + + public static function RemoveSymlinks(){ + exec("rm /usr/bin/airtime-import"); + exec("rm /usr/bin/airtime-clean-storage"); + } + + } diff --git a/utils/CleanStor.sh b/utils/airtime-clean-storage similarity index 95% rename from utils/CleanStor.sh rename to utils/airtime-clean-storage index 2b862ec6e..b96bb7d21 100755 --- a/utils/CleanStor.sh +++ b/utils/airtime-clean-storage @@ -23,4 +23,4 @@ #------------------------------------------------------------------------------- # This script cleans audio files in the Airtime storageServer. -php -q CleanStor.php "$@" || exit 1 +php -q airtime-clean-storage.php "$@" || exit 1 diff --git a/utils/airtime-clean-storage.php b/utils/airtime-clean-storage.php new file mode 100644 index 000000000..d1a063788 --- /dev/null +++ b/utils/airtime-clean-storage.php @@ -0,0 +1,124 @@ + 4)) { + list($dirList,$fileList) = File_Find::maptree($p_path); + + $array_mus; + foreach ($fileList as $filepath) { + + if (@substr($filepath, strlen($filepath) - 3) != "xml") { + $array_mus[] = $filepath; + } + } + + foreach ($array_mus as $audio_file) { + + if (@is_link($audio_file) && !@stat($audio_file)) { + + //filesystem clean up. + @unlink($audio_file); + echo "unlinked $audio_file\n"; + @unlink($audio_file . ".xml"); + echo "unlinked " . $audio_file . ".xml\n"; + @rmdir(@dirname($audio_file)); + echo "removed dir " . @dirname($audio_file) . "\n"; + + //database clean up. + $stored_audio_file = StoredFile::RecallByGunid(@basename($audio_file)); + $stored_audio_file->delete(); + } + } + + } +} + +function airtime_remove_files($p_path) { + + if (!empty($p_path) && (strlen($p_path) > 4)) { + list($dirList,$fileList) = File_Find::maptree($p_path); + + foreach ($fileList as $filepath) { + echo " * Removing $filepath\n"; + @unlink($filepath); + echo "done.\n"; + } + foreach ($dirList as $dirpath) { + echo " * Removing $dirpath\n"; + @rmdir($dirpath); + echo "done.\n"; + } + } +} + +function airtime_empty_db($db) { + global $CC_CONFIG; + + if (!PEAR::isError($db)) { + if (AirtimeInstall::DbTableExists($CC_CONFIG['filesTable'])) { + echo " * Deleting from database table ".$CC_CONFIG['filesTable']."\n"; + $sql = "DELETE FROM ".$CC_CONFIG['filesTable']; + AirtimeInstall::InstallQuery($sql, false); + } + else { + echo " * Skipping: database table ".$CC_CONFIG['filesTable']."\n"; + } + } +} + + +global $CC_CONFIG; + +$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); +$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); + +if ($argc != 2){ + printUsage(); + exit(1); +} + +switch($argv[1]){ + + case '-e': + case '--empty': + airtime_empty_db($CC_DBC); + airtime_remove_files($CC_CONFIG['storageDir']); + break; + case '-c': + case '--clean': + airtime_clean_files($CC_CONFIG['storageDir']); + break; + default: + printUsage(); + +} + diff --git a/utils/airtime-import b/utils/airtime-import index 5098cc01d..4c8d8fdc1 100755 --- a/utils/airtime-import +++ b/utils/airtime-import @@ -29,15 +29,16 @@ #------------------------------------------------------------------------------- # Determine directories, files #------------------------------------------------------------------------------- -reldir=`dirname $0` -phpdir=$reldir -filelistpathname=. + +# Absolute path to this script +SCRIPT=`readlink -f $0` +# Absolute path this script is in +SCRIPTPATH=`dirname $SCRIPT` #------------------------------------------------------------------------------- # Do import #------------------------------------------------------------------------------- invokePwd=$PWD -#echo $invokePwd -cd $phpdir +cd $SCRIPTPATH php -q airtime-import.php --dir "$invokePwd" "$@" || exit 1 diff --git a/utils/airtime-import.php b/utils/airtime-import.php index 9e0696728..168bf0765 100644 --- a/utils/airtime-import.php +++ b/utils/airtime-import.php @@ -56,7 +56,7 @@ function printUsage() echo " -h, --help Print this message and exit.\n"; echo "\n"; echo "Files will be imported to directory:\n"; - echo " ". $CC_CONFIG["storageDir"] ."\n"; + echo " ". realpath($CC_CONFIG["storageDir"]) ."\n"; echo "\n"; } diff --git a/utils/CleanStor.php b/utils/cleanStor.php similarity index 98% rename from utils/CleanStor.php rename to utils/cleanStor.php index 1b4ed9f97..6f0719508 100644 --- a/utils/CleanStor.php +++ b/utils/cleanStor.php @@ -18,7 +18,7 @@ function printUsage() { global $CC_CONFIG; echo "Usage:\n"; - echo " ./CleanStor [OPTION] \n"; + echo " ./cleanStor [OPTION] \n"; echo "\n"; echo "Options:\n"; echo " -c, --clean Removes all broken links from the storage server\n"; diff --git a/utils/resetStorage.sh b/utils/resetStorage.sh deleted file mode 100755 index 9bb49fcee..000000000 --- a/utils/resetStorage.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# Copyright (c) 2010 Sourcefabric O.P.S. -# -# This file is part of the Airtime project. -# http://airtime.sourcefabric.org/ -# To report bugs, send an e-mail to contact@sourcefabric.org -# -# Airtime is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Airtime is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Airtime; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# This script call locstor.resetStorage XMLRPC method -#------------------------------------------------------------------------------- - -reldir=`dirname $0`/.. -WWW_ROOT=`cd $reldir/var/install; php -q getWwwRoot.php` || exit $? -echo "# storageServer root URL: $WWW_ROOT" - -#$reldir/var/xmlrpc/xr_cli_test.py -s $WWW_ROOT/xmlrpc/xrLocStor.php \ -# resetStorage || exit $? - -cd $reldir/var/xmlrpc -php -q xr_cli_test.php -s $WWW_ROOT/xmlrpc/xrLocStor.php \ - resetStorage 1 1 || exit $? - -echo "# resetStorage: OK" -exit 0 From 38090af2719ceae5307d4e40a687b3f3edd7b108 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 02:12:31 -0400 Subject: [PATCH 43/74] CC-2058: Utilities are not in the system $PATH -cleanup --- utils/cleanStor.php | 124 -------------------------------------------- 1 file changed, 124 deletions(-) delete mode 100644 utils/cleanStor.php diff --git a/utils/cleanStor.php b/utils/cleanStor.php deleted file mode 100644 index 6f0719508..000000000 --- a/utils/cleanStor.php +++ /dev/null @@ -1,124 +0,0 @@ - 4)) { - list($dirList,$fileList) = File_Find::maptree($p_path); - - $array_mus; - foreach ($fileList as $filepath) { - - if (@substr($filepath, strlen($filepath) - 3) != "xml") { - $array_mus[] = $filepath; - } - } - - foreach ($array_mus as $audio_file) { - - if (@is_link($audio_file) && !@stat($audio_file)) { - - //filesystem clean up. - @unlink($audio_file); - echo "unlinked $audio_file\n"; - @unlink($audio_file . ".xml"); - echo "unlinked " . $audio_file . ".xml\n"; - @rmdir(@dirname($audio_file)); - echo "removed dir " . @dirname($audio_file) . "\n"; - - //database clean up. - $stored_audio_file = StoredFile::RecallByGunid(@basename($audio_file)); - $stored_audio_file->delete(); - } - } - - } -} - -function airtime_remove_files($p_path) { - - if (!empty($p_path) && (strlen($p_path) > 4)) { - list($dirList,$fileList) = File_Find::maptree($p_path); - - foreach ($fileList as $filepath) { - echo " * Removing $filepath\n"; - @unlink($filepath); - echo "done.\n"; - } - foreach ($dirList as $dirpath) { - echo " * Removing $dirpath\n"; - @rmdir($dirpath); - echo "done.\n"; - } - } -} - -function airtime_empty_db($db) { - global $CC_CONFIG; - - if (!PEAR::isError($db)) { - if (AirtimeInstall::DbTableExists($CC_CONFIG['filesTable'])) { - echo " * Deleting from database table ".$CC_CONFIG['filesTable']."\n"; - $sql = "DELETE FROM ".$CC_CONFIG['filesTable']; - AirtimeInstall::InstallQuery($sql, false); - } - else { - echo " * Skipping: database table ".$CC_CONFIG['filesTable']."\n"; - } - } -} - - -global $CC_CONFIG; - -$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE); -$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); - -if ($argc != 2){ - printUsage(); - exit(1); -} - -switch($argv[1]){ - - case '-e': - case '--empty': - airtime_empty_db($CC_DBC); - airtime_remove_files($CC_CONFIG['storageDir']); - break; - case '-c': - case '--clean': - airtime_clean_files($CC_CONFIG['storageDir']); - break; - default: - printUsage(); - -} - From c254422f72834969d1808b15a4968b02d866b2df Mon Sep 17 00:00:00 2001 From: lukabazuka Date: Thu, 24 Mar 2011 12:02:08 +0100 Subject: [PATCH 44/74] resolved CSS issue CC-2030 --- public/css/playlist_builder.css | 1 - 1 file changed, 1 deletion(-) diff --git a/public/css/playlist_builder.css b/public/css/playlist_builder.css index 4e2dc5ada..bd0ecc44f 100644 --- a/public/css/playlist_builder.css +++ b/public/css/playlist_builder.css @@ -92,7 +92,6 @@ .ui-icon-closethick, .ui-icon-play, .spl_fade_control, -.spl_playlength, .spl_text_input { cursor: pointer; } From c1d1e569145e63264b8e131c3b8f9718aa09cf45 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Thu, 24 Mar 2011 11:50:46 -0400 Subject: [PATCH 45/74] path change for python_apps folder --- install/airtime-uninstall.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index d30b4ee76..fa81129cb 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -82,7 +82,7 @@ if ($results == 0) { AirtimeInstall::DeleteFilesRecursive($CC_CONFIG['storageDir']); -$command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py"; +$command = "python ".__DIR__."/../python_apps/pypo/install/pypo-uninstall.py"; system($command); $command = "python ".__DIR__."/../python_apps/show-recorder/install/recorder-uninstall.py"; From 6a72037c41d7f18b9f20b3b8af88dd725ab523e3 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 24 Mar 2011 11:52:44 -0400 Subject: [PATCH 46/74] Added migration to drop tables we dont use anymore. --- .../Version20110312121200.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 install/DoctrineMigrations/Version20110312121200.php diff --git a/install/DoctrineMigrations/Version20110312121200.php b/install/DoctrineMigrations/Version20110312121200.php new file mode 100644 index 000000000..8bf20d856 --- /dev/null +++ b/install/DoctrineMigrations/Version20110312121200.php @@ -0,0 +1,19 @@ +dropTable("cc_backup"); + $schema->dropTable("cc_trans"); + } + + public function down(Schema $schema) + { + } +} From 17181674b7c366c4ca7805f70f0f8a873827972b Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 14:01:16 -0400 Subject: [PATCH 47/74] CC-2016: Rearrange python scripts for reusability -fixed path issue that was happening on some systems --- install/airtime-uninstall.php | 2 +- install/installInit.php | 4 ++-- python_apps/pypo/install/pypo-uninstall.py | 2 +- python_apps/pypo/scripts/ls_lib.liq | 4 ++-- python_apps/pypo/scripts/notify.sh | 9 ++++++++- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index d30b4ee76..fa81129cb 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -82,7 +82,7 @@ if ($results == 0) { AirtimeInstall::DeleteFilesRecursive($CC_CONFIG['storageDir']); -$command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py"; +$command = "python ".__DIR__."/../python_apps/pypo/install/pypo-uninstall.py"; system($command); $command = "python ".__DIR__."/../python_apps/show-recorder/install/recorder-uninstall.py"; diff --git a/install/installInit.php b/install/installInit.php index ffad0ac29..fe70cff5a 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -214,8 +214,8 @@ class AirtimeInstall { } public static function RemoveSymlinks(){ - exec("rm /usr/bin/airtime-import"); - exec("rm /usr/bin/airtime-clean-storage"); + exec("rm /usr/bin/airtime-import >/dev/null 2>&1"); + exec("rm /usr/bin/airtime-clean-storage >/dev/null 2>&1"); } diff --git a/python_apps/pypo/install/pypo-uninstall.py b/python_apps/pypo/install/pypo-uninstall.py index 6dcc42ce5..cd22e9c4c 100644 --- a/python_apps/pypo/install/pypo-uninstall.py +++ b/python_apps/pypo/install/pypo-uninstall.py @@ -50,6 +50,6 @@ try: remove_path("/etc/service/pypo-liquidsoap") remove_user("pypo") - print "Uninstall complete." + print "Pypo uninstall complete." except Exception, e: print "exception:" + str(e) diff --git a/python_apps/pypo/scripts/ls_lib.liq b/python_apps/pypo/scripts/ls_lib.liq index 27ed94f06..8447e5100 100644 --- a/python_apps/pypo/scripts/ls_lib.liq +++ b/python_apps/pypo/scripts/ls_lib.liq @@ -1,6 +1,6 @@ def notify(m) - system("./notify.sh --data='#{!pypo_data}' --media-id=#{m['schedule_table_id']}") - print("./notify.sh --data='#{!pypo_data}' --media-id=#{m['schedule_table_id']}") + system("/opt/pypo/bin/scripts/notify.sh --data='#{!pypo_data}' --media-id=#{m['schedule_table_id']}") + print("/opt/pypo/bin/scripts/notify.sh --data='#{!pypo_data}' --media-id=#{m['schedule_table_id']}") end # A function applied to each metadata chunk diff --git a/python_apps/pypo/scripts/notify.sh b/python_apps/pypo/scripts/notify.sh index 6298f13dd..8c407282b 100755 --- a/python_apps/pypo/scripts/notify.sh +++ b/python_apps/pypo/scripts/notify.sh @@ -4,4 +4,11 @@ # needed here to keep dirs/configs clean # # and maybe to set user-rights # ############################################ -cd ../ && ./pypo-notify.py $1 $2 $3 $4 $5 $6 $7 $8 & +pwd + +# Absolute path to this script +SCRIPT=`readlink -f $0` +# Absolute path this script is in +SCRIPTPATH=`dirname $SCRIPT` + +cd ${SCRIPTPATH}/../ && ./pypo-notify.py $1 $2 $3 $4 $5 $6 $7 $8 & From 7684fedb50ac45e8334de8cf90ec3ab1cfc4aadf Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 24 Mar 2011 14:55:42 -0400 Subject: [PATCH 48/74] Fixed bug on uninstall where it would complain about removing files that didnt exist, and also would stop the uninstallation if it couldnt connect to the database. --- install/airtime-uninstall.php | 2 +- install/installInit.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index fa81129cb..5b9a58c3a 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -39,7 +39,7 @@ $command = "sudo -u postgres dropdb {$CC_CONFIG['dsn']['database']} 2> /dev/null //------------------------------------------------------------------------ if ($dbDeleteFailed) { echo " * Couldn't delete the database, so deleting all the DB tables...".PHP_EOL; - AirtimeInstall::DbConnect(true); + AirtimeInstall::DbConnect(false); if (!PEAR::isError($CC_DBC)) { $sql = "select * from pg_tables where tableowner = 'airtime'"; diff --git a/install/installInit.php b/install/installInit.php index ffad0ac29..84fe04b81 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -112,7 +112,7 @@ class AirtimeInstall { public static function SetupStorageDirectory($CC_CONFIG) { global $CC_CONFIG, $CC_DBC; - + echo PHP_EOL."*** Directory Setup ***".PHP_EOL; foreach (array('baseFilesDir', 'storageDir') as $d) { if ( !file_exists($CC_CONFIG[$d]) ) { @@ -141,7 +141,7 @@ class AirtimeInstall { // Create the database user $command = "sudo -u postgres psql postgres --command \"CREATE USER {$CC_CONFIG['dsn']['username']} " ." ENCRYPTED PASSWORD '{$CC_CONFIG['dsn']['password']}' LOGIN CREATEDB NOCREATEUSER;\" 2>/dev/null"; - + @exec($command, $output, $results); if ($results == 0) { echo "* User {$CC_CONFIG['dsn']['username']} created.".PHP_EOL; @@ -153,7 +153,7 @@ class AirtimeInstall { public static function CreateDatabase() { global $CC_CONFIG; - + $command = "sudo -u postgres createdb {$CC_CONFIG['dsn']['database']} --owner {$CC_CONFIG['dsn']['username']} 2> /dev/null"; @exec($command, $output, $results); if ($results == 0) { @@ -205,7 +205,7 @@ class AirtimeInstall { public static function CreateSymlinks(){ AirtimeInstall::RemoveSymlinks(); - + $dir = realpath(__DIR__."/../utils/airtime-import"); exec("ln -s $dir /usr/bin/airtime-import"); @@ -214,8 +214,8 @@ class AirtimeInstall { } public static function RemoveSymlinks(){ - exec("rm /usr/bin/airtime-import"); - exec("rm /usr/bin/airtime-clean-storage"); + exec("rm -f /usr/bin/airtime-import"); + exec("rm -f /usr/bin/airtime-clean-storage"); } From 38e84b81db716f7cd2233bece2568213b3537abd Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 24 Mar 2011 15:05:49 -0400 Subject: [PATCH 49/74] CC-2047: Add Audio menu could be labeled Add Media Changed. --- application/configs/navigation.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/application/configs/navigation.php b/application/configs/navigation.php index d696cc4b5..3c4f758f2 100644 --- a/application/configs/navigation.php +++ b/application/configs/navigation.php @@ -2,7 +2,7 @@ /* * Navigation container (config/array) - + * Each element in the array will be passed to * Zend_Navigation_Page::factory() when constructing * the navigation container below. @@ -16,7 +16,7 @@ $pages = array( 'resource' => 'nowplaying' ), array( - 'label' => 'Add Audio', + 'label' => 'Add Media', 'module' => 'default', 'controller' => 'Plupload', 'action' => 'plupload', @@ -51,7 +51,7 @@ $pages = array( 'module' => 'default', 'controller' => 'user', 'action' => 'add-user', - 'resource' => 'user' + 'resource' => 'user' ) ) ), @@ -64,10 +64,10 @@ $pages = array( ) ); - + // Create container from array $container = new Zend_Navigation($pages); $container->id = "nav"; - + //store it in the registry: Zend_Registry::set('Zend_Navigation', $container); From bdf98c9ec8a22eca3edf2e69da0d1837d5429f7c Mon Sep 17 00:00:00 2001 From: "paul.baranowski" Date: Thu, 24 Mar 2011 15:08:58 -0400 Subject: [PATCH 50/74] CC-2035: Context menu says 'Add Content' when it should say 'Add/Remove Content' Changed. --- application/controllers/ScheduleController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index daf774517..acbc7bc60 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -161,7 +161,7 @@ class ScheduleController extends Zend_Controller_Action if (($user->isHost($show->getShowId()) || $user->isAdmin()) && !$show->isRecorded() && !$show->isRebroadcast()) { $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, - 'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add Content'); + 'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add / Remove Content'); $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Remove All Content'); From 26ac9754bfc0ed251d79ca679a57e13bc4cbef9d Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 15:17:17 -0400 Subject: [PATCH 51/74] CC-2016: Rearrange python scripts for reusability -bug fix with liquidsoap not being to see the soundcard --- python_apps/pypo/install/pypo-daemontools-liquidsoap.sh | 3 +-- python_apps/pypo/scripts/notify.sh | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh index 2b4ce0df4..b0ae7377a 100644 --- a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh +++ b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh @@ -11,6 +11,5 @@ PYTHONPATH=${api_client_path}:$PYTHONPATH export PYTHONPATH cd /opt/pypo/bin/scripts -exec setuidgid ${ls_user} \ - ${ls_path} ${ls_param} +sudo -u ${ls_user} ${ls_path} ${ls_param} # EOF diff --git a/python_apps/pypo/scripts/notify.sh b/python_apps/pypo/scripts/notify.sh index 8c407282b..07a70f5d0 100755 --- a/python_apps/pypo/scripts/notify.sh +++ b/python_apps/pypo/scripts/notify.sh @@ -4,7 +4,6 @@ # needed here to keep dirs/configs clean # # and maybe to set user-rights # ############################################ -pwd # Absolute path to this script SCRIPT=`readlink -f $0` From 5b3cd9ea0d2e04dbef7686d500f65938d123f9e1 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 17:36:10 -0400 Subject: [PATCH 52/74] CC-2016: Rearrange python scripts for reusability -fix passing env variables properly when using sudo --- python_apps/pypo/install/pypo-daemontools-liquidsoap.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh index b0ae7377a..cd6177164 100644 --- a/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh +++ b/python_apps/pypo/install/pypo-daemontools-liquidsoap.sh @@ -7,9 +7,6 @@ ls_param="/opt/pypo/bin/scripts/ls_script.liq" echo "*** Daemontools: starting liquidsoap" exec 2>&1 -PYTHONPATH=${api_client_path}:$PYTHONPATH -export PYTHONPATH - cd /opt/pypo/bin/scripts -sudo -u ${ls_user} ${ls_path} ${ls_param} +sudo PYTHONPATH=${api_client_path} -u ${ls_user} ${ls_path} ${ls_param} # EOF From 35b2ddfd295e0fa46f8aa7ea36759af6fd5274cb Mon Sep 17 00:00:00 2001 From: naomiaro Date: Thu, 24 Mar 2011 17:43:37 -0400 Subject: [PATCH 53/74] CC-2097 : Show-recorder: Use RabbitMQ, api_client, and the structure of pypofetch setting up configs --- application/controllers/ApiController.php | 6 ++++++ application/views/helpers/SoundCloudLink.php | 22 -------------------- install/installInit.php | 1 + python_apps/show-recorder/config.cfg | 9 ++++++++ 4 files changed, 16 insertions(+), 22 deletions(-) delete mode 100644 application/views/helpers/SoundCloudLink.php diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index f7ff37eb1..5ca3b51c5 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -150,6 +150,12 @@ class ApiController extends Zend_Controller_Action } } + public function recordedShowsAction() + { + $today_timestamp = date("Y-m-d H:i:s"); + $this->view->shows = Show::getShows($today_timestamp, null, $excludeInstance=NULL, $onlyRecord=TRUE); + } + public function notifyMediaItemStartPlayAction() { global $CC_CONFIG; diff --git a/application/views/helpers/SoundCloudLink.php b/application/views/helpers/SoundCloudLink.php deleted file mode 100644 index 9f4d321e5..000000000 --- a/application/views/helpers/SoundCloudLink.php +++ /dev/null @@ -1,22 +0,0 @@ -getRequest(); - $host = $request->getHttpHost(); - $controller = $request->getControllerName(); - $action = $request->getActionName(); - - $redirectUrl = "http://{$host}/{$controller}/{$action}"; - - $soundcloud = new Services_Soundcloud('2CLCxcSXYzx7QhhPVHN4A', 'pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs', $redirectUrl); - $authorizeUrl = $soundcloud->getAuthorizeUrl(); - - return $authorizeUrl; - } -} - diff --git a/install/installInit.php b/install/installInit.php index 84fe04b81..1efaa4833 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -80,6 +80,7 @@ class AirtimeInstall { $api_key = AirtimeInstall::GenerateRandomString(); AirtimeInstall::UpdateIniValue(__DIR__.'/../build/airtime.conf', 'api_key', $api_key); AirtimeInstall::UpdateIniValue(__DIR__.'/../python_apps/pypo/config.cfg', 'api_key', "'$api_key'"); + AirtimeInstall::UpdateIniValue(__DIR__.'/../python_apps/show-recorder/config.cfg', 'api_key', "'$api_key'"); } public static function ExitIfNotRoot() diff --git a/python_apps/show-recorder/config.cfg b/python_apps/show-recorder/config.cfg index d1bb763ab..b74713841 100644 --- a/python_apps/show-recorder/config.cfg +++ b/python_apps/show-recorder/config.cfg @@ -7,3 +7,12 @@ upload_file_url = 'Plupload/upload-recorded/format/json' # base path to store recordered shows at base_recorded_files = '/home/pypo/Music/' + +# Value needed to access the API +api_key = 'AAA' + +# Path to the base of the API +api_base = 'api/' + +# URL to get the version number of the server API +version_url = 'version/api_key/%%api_key%%' From 9200484d970a1a223e2767fe8593c4840f3ba72a Mon Sep 17 00:00:00 2001 From: lukabazuka Date: Thu, 24 Mar 2011 23:49:11 +0100 Subject: [PATCH 54/74] fixed issues CC-2102, CC-2062 and CC-2083 --- public/css/images/icon_rebroadcast.png | Bin 1075 -> 2876 bytes public/css/images/icon_rebroadcast_m.png | Bin 0 -> 1182 bytes public/css/images/icon_record.png | Bin 1080 -> 990 bytes public/css/images/icon_record_m.png | Bin 0 -> 1226 bytes public/css/styles.css | 17 ++++++++++++++++- 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 public/css/images/icon_rebroadcast_m.png create mode 100644 public/css/images/icon_record_m.png diff --git a/public/css/images/icon_rebroadcast.png b/public/css/images/icon_rebroadcast.png index 5282d87b2aba3ae5ae60e122f5d1b77c4c42cb27..3a6c195713b145e70b7517f348e0dfd38cc3209d 100644 GIT binary patch literal 2876 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 diff --git a/public/css/images/icon_rebroadcast_m.png b/public/css/images/icon_rebroadcast_m.png new file mode 100644 index 0000000000000000000000000000000000000000..585a7d31fee08f0bea53b231b886c01536d5b9d8 GIT binary patch literal 1182 zcmbVMOHABG81@1Ug>0nl0i-lV898b%$=V(-Yh#OrWo=Vd$r7||npI91djJ>gaqOYH zpgbt*AvvTXs;bf+njWHxN>vp&RF!f_6``nzHjhgpC5I{!mquxlHkTYCkuk8e2b4;+ zWP4`(f8X~%eSV<-{XNZZH!}>gC*P+R>3c7|<8SVw&oBONJscenqf7?z2&tF>VtQ;m zj6mKsM^O=(_SDH0)X6aQwo@vTa^Z+-VV5%_8?Ng56wNT5-BsVT#t{L-Xw>mC?9;2) zSm4+h_ISD=6nqVhIepUs8l3JgS<~Z|Vzb>{ptGt{0v8bzRNVl{_Y+Wo>3+xfK zsP}GZ(OrfeBg9vEzEY`hl@y1AQ64Ia5^;!Pl3FCgDUX=dq!%8jG3Y3?0>>u~_CUmF z4&zCZVX3E^A-H~_uubfRTZy76)@F+B^_bRDX@g_T~5 zRkZ+_1P3LICu$uqFop>Z$FL8y!8ADTcs8ztQE@h7)luMlgzVk`yI>=`sV(UjiK>pi9F{b4)%#*f*@ z&C5&K?^kCUU#_qJK7aAzUx&VWhQOKl^3{)D2uJ4L%J;M+8et-qZJkM5CuZY!V<-15 zW#frUv4;x_3lG*8nfaGz>zK>?zis`HtKXeC$Sl5duDB-F{ zwAz*X?by&KH?;1r{rBGOzp~OI#+nMdL}u~R*q67KvyIHsntI{SpKdl3?tQa%Bhl7& zy0P`UwYs@8b4uUJ3wS3#U!F-eefIg@^9|2_{iV-aoUI>9e!$elndg_T7Y}!Vw&;(M MH~RG-aznGP0EuLOtpET3 literal 0 HcmV?d00001 diff --git a/public/css/images/icon_record.png b/public/css/images/icon_record.png index ffedeb5c12ed33368016ea3f435956de0fc28332..020ebe283a8b503b745a5a4b18e199147717040f 100644 GIT binary patch delta 347 zcmdnNagSZGGr-TCmrII^fq{Y7)59eQNQ(e57Y7@V+!9*%Y@(tDqryfnb;ike7?mbx zF=kKR#iTvCnn_y0#M0H+)zZz#)XdD>(9qSu$;r{c!qwH;($vt%!pX&OvK^BQOp!58 zMNgOvVxT4&;8LWdP+Ss}nr4-fpIn-onpfiKVyjet(N-X9GeCUz0B*6A&fNtXSO`DAwSR@#DrcC9XRuEMUG@rrK L)z4*}Q$iB}I^JaZ delta 438 zcmcb|zJo)tGr-TCmrII^fq{Y7)59eQNQ(k77Y7@VjGiufW1^x4W6DM^b;ilF7*i%^ zF>2Nq`1)G;7iFer<|XF1awEb=G}kiT$P3}`EZC%dbk%Q~loCIAaMiEaP@ diff --git a/public/css/images/icon_record_m.png b/public/css/images/icon_record_m.png new file mode 100644 index 0000000000000000000000000000000000000000..50b3ebe152f1075f6f3005348994f3bed0270665 GIT binary patch literal 1226 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W;!3HFgc;@~FQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?@KsLn2Bde0{8v^Ko2Tt~skz|cV7z)0WFNY~KZ%Gk)tz(4^Clz_GsrKDK}xwt{?0`hE?GD=Dctn~HE z%ggo3jrH=2()A53EiFN27#ZmTRp=I1=9MH?=;jqG!%T2VElw`VEGWs$&r<-In3$Ab zT4JjNbScCOxdpzyaD(%Tp#cR9GX09g0)0b01O41wkiWpHi%Wu15zfG>x;Uh=AXPso zwK%`DC>aHCFybnZQU%%yG$2F3nBNEAe!(RRYTBrDUd9nVVRe zJG&Y>nVFcHxf&Q6S{fNSyE+*fS{RwRIGPz5!_2^{*T}-s)Y#C?)XdD>(9qSu$=uA+ z$;s8l%miqnk+A_xuV-FyNn&1dD$L$Yki8JSu6XrYITxiSmgEMq}yTBYn2n_qr;#aCUpJo9!M z>w?Q6rQ*Bt*yde7oDguOG4acXiUcv&?VD!)X=~qOk=kxwK~o5 zLPVaShVM>D!%trGdX8V-4=kVN_FCOBJE@nwDQ>me>$Ufpco?$yLYK^5n|KFQx_G+! KxvX Date: Thu, 24 Mar 2011 21:02:08 -0400 Subject: [PATCH 55/74] -fixed some problems with recorder not working on ubuntu 10.10 --- .../show-recorder/install/recorder-daemontools.sh | 5 ++++- python_apps/show-recorder/testrecordscript.py | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index d9cec7146..3056803d5 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -1,12 +1,15 @@ #!/bin/sh recorder_user="pypo" export HOME="/home/pypo/" +export TERM=xterm # Location of pypo_cli.py Python script recorder_path="/opt/recorder/bin/" recorder_script="testrecordscript.py" echo "*** Daemontools: starting daemon" +echo $PATH +echo $TERM cd ${recorder_path} exec 2>&1 # Note the -u when calling python! we need it to get unbuffered binary stdout and stderr -exec sudo python -u ${recorder_path}${recorder_script} -f +python -u ${recorder_path}${recorder_script} # EOF diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 4c659cdcb..7e1673d73 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -12,7 +12,8 @@ from poster.encode import multipart_encode from poster.streaminghttp import register_openers import urllib2 -from subprocess import call +#from subprocess import call +from subprocess import Popen, PIPE from threading import Thread # loading config file @@ -39,8 +40,10 @@ class Recorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) - call(command, shell=True) + command = ("ecasound -i alsa -o %s -t:%s" % (filepath, length)).split(' ') + print(command) + Popen(command, stdout=PIPE) + #call(command, shell=False) return filepath From 0cab539f8a4ec71f69a14058040ecc00eb043a14 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 21:36:14 -0400 Subject: [PATCH 56/74] -No ticket: Fixed recording light on, even after record show ended. --- public/js/playlist/playlist.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/public/js/playlist/playlist.js b/public/js/playlist/playlist.js index 98b227381..a72e94dc2 100644 --- a/public/js/playlist/playlist.js +++ b/public/js/playlist/playlist.js @@ -165,11 +165,12 @@ function updatePlaybar(){ /* Column 1 update */ $('#playlist').text("Current Show:"); + var recElem = $('.recording-show'); if (currentShow.length > 0){ $('#playlist').text(currentShow[0].name); - - var recElem = $('.recording-show'); (currentShow[0].record == "1") ? recElem.show(): recElem.hide(); + } else { + recElem.hide(); } $('#show-length').empty(); From d71bfbe1919e4352244262672ce278b97b50c205 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 22:07:04 -0400 Subject: [PATCH 57/74] CC-2108: Show time is hardcoded to 00:00 -fixed --- application/views/scripts/partialviews/header.phtml | 2 +- public/css/styles.css | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application/views/scripts/partialviews/header.phtml b/application/views/scripts/partialviews/header.phtml index a817fc1fd..f1de80cc9 100644 --- a/application/views/scripts/partialviews/header.phtml +++ b/application/views/scripts/partialviews/header.phtml @@ -14,7 +14,7 @@
- 00:00 +
diff --git a/public/css/styles.css b/public/css/styles.css index 6f77239ca..3b19a442a 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -184,7 +184,7 @@ select { .progressbar .progress-show-error { background:#d40000 url(images/progressbar_show_error.png) repeat-x 0 0; } -.now-playing-info .lenght { +.now-playing-info .show-length { color:#c4c4c4; padding-left:6px; } @@ -1505,4 +1505,4 @@ ul.errors li { .medium-icon.rebroadcast { background:url(images/icon_rebroadcast_m.png) no-repeat 0 0; } - \ No newline at end of file + From 343fb593eedcf1707c29c427f66cccf936207f66 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 22:29:14 -0400 Subject: [PATCH 58/74] CC-2051: Unable to change user password -Password is changeable, and success message appears whenever a user is added/updated. --- application/controllers/UserController.php | 8 ++++++++ application/forms/AddUser.php | 6 +++--- application/views/scripts/user/add-user.phtml | 1 + public/css/styles.css | 10 ++++++++++ public/js/airtime/user/user.js | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/application/controllers/UserController.php b/application/controllers/UserController.php index 72b6a20ef..081c32b70 100644 --- a/application/controllers/UserController.php +++ b/application/controllers/UserController.php @@ -23,6 +23,8 @@ class UserController extends Zend_Controller_Action $this->view->headScript()->appendFile('/js/airtime/user/user.js','text/javascript'); $request = $this->getRequest(); $form = new Application_Form_AddUser(); + + $this->view->successMessage = ""; if ($request->isPost()) { if ($form->isValid($request->getPost())) { @@ -42,6 +44,12 @@ class UserController extends Zend_Controller_Action $user->save(); $form->reset(); + + if (strlen($formdata['user_id']) == 0){ + $this->view->successMessage = "
User added successfully!
"; + } else { + $this->view->successMessage = "
User updated successfully!
"; + } } } } diff --git a/application/forms/AddUser.php b/application/forms/AddUser.php index d1eca586b..58bc91543 100644 --- a/application/forms/AddUser.php +++ b/application/forms/AddUser.php @@ -72,9 +72,9 @@ class Application_Form_AddUser extends Zend_Form $select->setAttrib('class', 'input_select'); $select->setAttrib('style', 'width: 40%'); $select->setMultiOptions(array( - "G" => "guest", - "H" => "host", - "A" => "admin" + "G" => "Guest", + "H" => "Host", + "A" => "Admin" )); $select->setRequired(true); $this->addElement($select); diff --git a/application/views/scripts/user/add-user.phtml b/application/views/scripts/user/add-user.phtml index b37c032bc..db1e76138 100644 --- a/application/views/scripts/user/add-user.phtml +++ b/application/views/scripts/user/add-user.phtml @@ -26,6 +26,7 @@
+ successMessage ?>
form ?>
diff --git a/public/css/styles.css b/public/css/styles.css index 3b19a442a..7d0dc8690 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -1219,6 +1219,16 @@ ul.errors li { margin-bottom:2px; border:1px solid #c83f3f; } + +div.success{ + color:#3B5323; + font-size:11px; + padding:2px 4px; + background:#93DB70; + margin-bottom:2px; + border:1px solid #488214; +} + .collapsible-header { border: 1px solid #8f8f8f; background-color: #cccccc; diff --git a/public/js/airtime/user/user.js b/public/js/airtime/user/user.js index 4add2d4b1..6a518fdc1 100644 --- a/public/js/airtime/user/user.js +++ b/public/js/airtime/user/user.js @@ -2,6 +2,7 @@ function populateForm(entries){ //$('#user_details').show(); $('.errors').remove(); + $('.success').remove(); $('#user_id').val(entries.id); $('#login').val(entries.login); From c727c338afda0d327cb446c21662e93e0458f32a Mon Sep 17 00:00:00 2001 From: naomiaro Date: Thu, 24 Mar 2011 23:07:13 -0400 Subject: [PATCH 59/74] CC-2097: Show-recorder: Use RabbitMQ, api_client, and the structure of pypofetch using api client now --- application/controllers/ApiController.php | 61 ++++++- .../controllers/PluploadController.php | 158 +----------------- .../controllers/RecorderController.php | 28 ---- .../controllers/plugins/Acl_plugin.php | 2 +- application/models/StoredFile.php | 138 +++++++++++++++ python_apps/api_clients/api_client.py | 61 +++++-- python_apps/show-recorder/config.cfg | 12 +- .../install/recorder-daemontools.sh | 5 +- python_apps/show-recorder/logging.cfg | 22 +++ python_apps/show-recorder/testrecordscript.py | 121 +++++++------- 10 files changed, 334 insertions(+), 274 deletions(-) delete mode 100644 application/controllers/RecorderController.php create mode 100644 python_apps/show-recorder/logging.cfg diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index 5ca3b51c5..e6c2e4c49 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -6,8 +6,10 @@ class ApiController extends Zend_Controller_Action public function init() { /* Initialize action controller here */ - $ajaxContext = $this->_helper->getHelper('AjaxContext'); - $ajaxContext->addActionContext('version', 'json') + $context = $this->_helper->getHelper('contextSwitch'); + $context->addActionContext('version', 'json') + ->addActionContext('recorded-shows', 'json') + ->addActionContext('upload-recorded', 'json') ->initContext(); } @@ -150,12 +152,6 @@ class ApiController extends Zend_Controller_Action } } - public function recordedShowsAction() - { - $today_timestamp = date("Y-m-d H:i:s"); - $this->view->shows = Show::getShows($today_timestamp, null, $excludeInstance=NULL, $onlyRecord=TRUE); - } - public function notifyMediaItemStartPlayAction() { global $CC_CONFIG; @@ -222,5 +218,54 @@ class ApiController extends Zend_Controller_Action exit; } } + + public function recordedShowsAction() + { + global $CC_CONFIG; + + $api_key = $this->_getParam('api_key'); + if (!in_array($api_key, $CC_CONFIG["apiKey"])) + { + header('HTTP/1.0 401 Unauthorized'); + print 'You are not allowed to access this resource.'; + exit; + } + + $today_timestamp = date("Y-m-d H:i:s"); + $this->view->shows = Show::getShows($today_timestamp, null, $excludeInstance=NULL, $onlyRecord=TRUE); + } + + public function uploadRecordedAction() + { + global $CC_CONFIG; + + // disable the view and the layout + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $api_key = $this->_getParam('api_key'); + if (!in_array($api_key, $CC_CONFIG["apiKey"])) + { + header('HTTP/1.0 401 Unauthorized'); + print 'You are not allowed to access this resource.'; + exit; + } + + $upload_dir = ini_get("upload_tmp_dir"); + $file = StoredFile::uploadFile($upload_dir); + + if(Application_Model_Preference::GetDoSoundCloudUpload()) + { + $soundcloud = new ATSoundcloud(); + $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName()); + } + + $show_instance = $this->_getParam('show_instance'); + + $show = new ShowInstance($show_instance); + $show->setRecordedFile($file->getId()); + + $this->view->id = $file->getId(); + } } diff --git a/application/controllers/PluploadController.php b/application/controllers/PluploadController.php index 0e73bfbb4..90687f477 100644 --- a/application/controllers/PluploadController.php +++ b/application/controllers/PluploadController.php @@ -11,143 +11,6 @@ class PluploadController extends Zend_Controller_Action ->initContext(); } - public function upload($targetDir) - { - // HTTP headers for no cache etc - header('Content-type: text/plain; charset=UTF-8'); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - - // Settings - //$targetDir = ini_get("upload_tmp_dir"); //. DIRECTORY_SEPARATOR . "plupload"; - $cleanupTargetDir = false; // Remove old files - $maxFileAge = 60 * 60; // Temp file age in seconds - - // 5 minutes execution time - @set_time_limit(5 * 60); - // usleep(5000); - - // Get parameters - $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0; - $chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0; - $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; - - // Clean the fileName for security reasons - //$fileName = preg_replace('/[^\w\._]+/', '', $fileName); - - // Create target dir - if (!file_exists($targetDir)) - @mkdir($targetDir); - - // Remove old temp files - if (is_dir($targetDir) && ($dir = opendir($targetDir))) { - while (($file = readdir($dir)) !== false) { - $filePath = $targetDir . DIRECTORY_SEPARATOR . $file; - - // Remove temp files if they are older than the max age - if (preg_match('/\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge)) - @unlink($filePath); - } - - closedir($dir); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}'); - - // Look for the content type header - if (isset($_SERVER["HTTP_CONTENT_TYPE"])) - $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; - - if (isset($_SERVER["CONTENT_TYPE"])) - $contentType = $_SERVER["CONTENT_TYPE"]; - - if (strpos($contentType, "multipart") !== false) { - if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { - // Open temp file - $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab"); - if ($out) { - // Read binary input stream and append it to temp file - $in = fopen($_FILES['file']['tmp_name'], "rb"); - - if ($in) { - while ($buff = fread($in, 4096)) - fwrite($out, $buff); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); - - fclose($out); - unlink($_FILES['file']['tmp_name']); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); - } else { - // Open temp file - $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab"); - if ($out) { - // Read binary input stream and append it to temp file - $in = fopen("php://input", "rb"); - - if ($in) { - while ($buff = fread($in, 4096)) - fwrite($out, $buff); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); - - fclose($out); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); - } - - $audio_file = $targetDir . DIRECTORY_SEPARATOR . $fileName; - - $md5 = md5_file($audio_file); - $duplicate = StoredFile::RecallByMd5($md5); - if ($duplicate) { - if (PEAR::isError($duplicate)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}'); - } - else { - $duplicateName = $duplicate->getMetadataValue(UI_MDATA_KEY_TITLE); - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}'); - } - } - - $metadata = Metadata::LoadFromFile($audio_file); - - if (PEAR::isError($metadata)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}'); - } - - // #2196 no id tag -> use the original filename - if (basename($audio_file) == $metadata[UI_MDATA_KEY_TITLE]) { - $metadata[UI_MDATA_KEY_TITLE] = basename($audio_file); - $metadata[UI_MDATA_KEY_FILENAME] = basename($audio_file); - } - - // setMetadataBatch doesnt like these values - unset($metadata['audio']); - unset($metadata['playtime_seconds']); - - $values = array( - "filename" => basename($audio_file), - "filepath" => $audio_file, - "filetype" => "audioclip", - "mime" => $metadata[UI_MDATA_KEY_FORMAT], - "md5" => $md5 - ); - $storedFile = StoredFile::Insert($values); - - if (PEAR::isError($storedFile)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}'); - } - - $storedFile->setMetadataBatch($metadata); - - return $storedFile; - } public function indexAction() { @@ -157,30 +20,11 @@ class PluploadController extends Zend_Controller_Action public function uploadAction() { $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; - $file = $this->upload($upload_dir); + $file = StoredFile::uploadFile($upload_dir); die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); } - public function uploadRecordedAction() - { - $upload_dir = ini_get("upload_tmp_dir"); - $file = $this->upload($upload_dir); - - if(Application_Model_Preference::GetDoSoundCloudUpload()) - { - $soundcloud = new ATSoundcloud(); - $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName()); - } - - $show_instance = $this->_getParam('show_instance'); - - $show = new ShowInstance($show_instance); - $show->setRecordedFile($file->getId()); - - die('{"jsonrpc" : "2.0", "id" : '.$file->getId().'}'); - } - public function pluploadAction() { $this->view->headScript()->appendFile('/js/plupload/plupload.full.min.js','text/javascript'); diff --git a/application/controllers/RecorderController.php b/application/controllers/RecorderController.php deleted file mode 100644 index 1aafbef15..000000000 --- a/application/controllers/RecorderController.php +++ /dev/null @@ -1,28 +0,0 @@ -_helper->getHelper('contextSwitch'); - $ajaxContext->addActionContext('get-show-schedule', 'json') - ->addActionContext('get-uploaded-file', 'json') - ->initContext(); - } - - public function indexAction() - { - // action body - } - - public function getShowScheduleAction() - { - $today_timestamp = date("Y-m-d H:i:s"); - $this->view->shows = Show::getShows($today_timestamp, null, $excludeInstance=NULL, $onlyRecord=TRUE); - } - -} - - - diff --git a/application/controllers/plugins/Acl_plugin.php b/application/controllers/plugins/Acl_plugin.php index a1a641ce4..b380478e7 100644 --- a/application/controllers/plugins/Acl_plugin.php +++ b/application/controllers/plugins/Acl_plugin.php @@ -110,7 +110,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract { $controller = strtolower($request->getControllerName()); - if ($controller == 'api' || $controller == 'recorder' || $controller == 'plupload' && $request->getActionName() == 'upload-recorded'){ + if ($controller == 'api'){ $this->setRoleName("G"); } diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index 32d1ab0dc..ecff91caa 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1647,5 +1647,143 @@ class StoredFile { return array("sEcho" => intval($data["sEcho"]), "iTotalDisplayRecords" => $totalDisplayRows, "iTotalRecords" => $totalRows, "aaData" => $results); } + public static function uploadFile($targetDir) { + + // HTTP headers for no cache etc + header('Content-type: text/plain; charset=UTF-8'); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + + // Settings + //$targetDir = ini_get("upload_tmp_dir"); //. DIRECTORY_SEPARATOR . "plupload"; + $cleanupTargetDir = false; // Remove old files + $maxFileAge = 60 * 60; // Temp file age in seconds + + // 5 minutes execution time + @set_time_limit(5 * 60); + // usleep(5000); + + // Get parameters + $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0; + $chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0; + $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; + + // Clean the fileName for security reasons + //$fileName = preg_replace('/[^\w\._]+/', '', $fileName); + + // Create target dir + if (!file_exists($targetDir)) + @mkdir($targetDir); + + // Remove old temp files + if (is_dir($targetDir) && ($dir = opendir($targetDir))) { + while (($file = readdir($dir)) !== false) { + $filePath = $targetDir . DIRECTORY_SEPARATOR . $file; + + // Remove temp files if they are older than the max age + if (preg_match('/\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge)) + @unlink($filePath); + } + + closedir($dir); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}'); + + // Look for the content type header + if (isset($_SERVER["HTTP_CONTENT_TYPE"])) + $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; + + if (isset($_SERVER["CONTENT_TYPE"])) + $contentType = $_SERVER["CONTENT_TYPE"]; + + if (strpos($contentType, "multipart") !== false) { + if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { + // Open temp file + $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab"); + if ($out) { + // Read binary input stream and append it to temp file + $in = fopen($_FILES['file']['tmp_name'], "rb"); + + if ($in) { + while ($buff = fread($in, 4096)) + fwrite($out, $buff); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); + + fclose($out); + unlink($_FILES['file']['tmp_name']); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); + } else { + // Open temp file + $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab"); + if ($out) { + // Read binary input stream and append it to temp file + $in = fopen("php://input", "rb"); + + if ($in) { + while ($buff = fread($in, 4096)) + fwrite($out, $buff); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); + + fclose($out); + } else + die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); + } + + $audio_file = $targetDir . DIRECTORY_SEPARATOR . $fileName; + + $md5 = md5_file($audio_file); + $duplicate = StoredFile::RecallByMd5($md5); + if ($duplicate) { + if (PEAR::isError($duplicate)) { + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}'); + } + else { + $duplicateName = $duplicate->getMetadataValue(UI_MDATA_KEY_TITLE); + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}'); + } + } + + $metadata = Metadata::LoadFromFile($audio_file); + + if (PEAR::isError($metadata)) { + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}'); + } + + // #2196 no id tag -> use the original filename + if (basename($audio_file) == $metadata[UI_MDATA_KEY_TITLE]) { + $metadata[UI_MDATA_KEY_TITLE] = basename($audio_file); + $metadata[UI_MDATA_KEY_FILENAME] = basename($audio_file); + } + + // setMetadataBatch doesnt like these values + unset($metadata['audio']); + unset($metadata['playtime_seconds']); + + $values = array( + "filename" => basename($audio_file), + "filepath" => $audio_file, + "filetype" => "audioclip", + "mime" => $metadata[UI_MDATA_KEY_FORMAT], + "md5" => $md5 + ); + $storedFile = StoredFile::Insert($values); + + if (PEAR::isError($storedFile)) { + die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}'); + } + + $storedFile->setMetadataBatch($metadata); + + return $storedFile; + } + } diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 6994cf3fd..a13d53794 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -13,6 +13,7 @@ import sys import time import urllib +import urllib2 import logging import json import os @@ -90,6 +91,12 @@ class ApiClientInterface: # You will be able to use this data in update_start_playing def get_liquidsoap_data(self, pkey, schedule): pass + + def get_shows_to_record(self): + pass + + def upload_recorded_show(self): + pass # Put here whatever tests you want to run to make sure your API is working def test(self): @@ -225,24 +232,6 @@ class AirTimeApiClient(ApiClientInterface): except Exception, e: print e - #schedule = response["playlists"] - #scheduleKeys = sorted(schedule.iterkeys()) - # - ## Remove all playlists that have passed current time - #try: - # tnow = time.localtime(time.time()) - # str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5]) - # toRemove = [] - # for pkey in scheduleKeys: - # if (str_tnow_s > schedule[pkey]['end']): - # toRemove.append(pkey) - # else: - # break - # for index in toRemove: - # del schedule[index] - #except Exception, e: - #response["playlists"] = schedule - return status, response @@ -316,6 +305,42 @@ class AirTimeApiClient(ApiClientInterface): except Exception, e: data["schedule_id"] = 0 return data + + def get_shows_to_record(self): + logger = logging.getLogger() + response = '' + try: + url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"] + #logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) + logger.debug(url) + response = urllib.urlopen(url) + response = json.loads(response.read()) + logger.info("shows %s", response) + + except Exception, e: + logger.error("Exception: %s", e) + + return response[u'shows'] + + def upload_recorded_show(self, data, headers): + logger = logging.getLogger() + response = '' + try: + url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"] + #logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) + logger.debug(url) + + request = urllib2.Request(url, data, headers) + response = urllib2.urlopen(request).read().strip() + + logger.info("uploaded show result %s", response) + + except Exception, e: + logger.error("Exception: %s", e) + + return response diff --git a/python_apps/show-recorder/config.cfg b/python_apps/show-recorder/config.cfg index b74713841..ec812b8cf 100644 --- a/python_apps/show-recorder/config.cfg +++ b/python_apps/show-recorder/config.cfg @@ -1,10 +1,8 @@ +api_client = "airtime" + # Hostname base_url = 'http://localhost/' -show_schedule_url = 'Recorder/get-show-schedule/format/json' - -upload_file_url = 'Plupload/upload-recorded/format/json' - # base path to store recordered shows at base_recorded_files = '/home/pypo/Music/' @@ -16,3 +14,9 @@ api_base = 'api/' # URL to get the version number of the server API version_url = 'version/api_key/%%api_key%%' + +# URL to get the schedule of shows set to record +show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%' + +# URL to upload the recorded show's file to Airtime +upload_file_url = 'upload-recorded/format/json/api_key/%%api_key%%' diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index d9cec7146..2e8157098 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -4,9 +4,12 @@ export HOME="/home/pypo/" # Location of pypo_cli.py Python script recorder_path="/opt/recorder/bin/" recorder_script="testrecordscript.py" + +api_client_path="/opt/pypo/" + echo "*** Daemontools: starting daemon" cd ${recorder_path} exec 2>&1 # Note the -u when calling python! we need it to get unbuffered binary stdout and stderr -exec sudo python -u ${recorder_path}${recorder_script} -f +sudo PYTHONPATH=${api_client_path} -u ${recorder_user} python -u ${recorder_path}${recorder_script} -f # EOF diff --git a/python_apps/show-recorder/logging.cfg b/python_apps/show-recorder/logging.cfg new file mode 100644 index 000000000..251fce8d7 --- /dev/null +++ b/python_apps/show-recorder/logging.cfg @@ -0,0 +1,22 @@ +[loggers] +keys=root + +[handlers] +keys=consoleHandler + +[formatters] +keys=simpleFormatter + +[logger_root] +level=DEBUG +handlers=consoleHandler + +[handler_consoleHandler] +class=StreamHandler +level=DEBUG +formatter=simpleFormatter +args=(sys.stdout,) + +[formatter_simpleFormatter] +format=%(asctime)s %(levelname)s - [%(filename)s : %(funcName)s() : line %(lineno)d] - %(message)s +datefmt= diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 4c659cdcb..2209c9184 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -1,6 +1,7 @@ #!/usr/local/bin/python import urllib import logging +import logging.config import json import time import datetime @@ -15,6 +16,15 @@ import urllib2 from subprocess import call from threading import Thread +# For RabbitMQ +from kombu.connection import BrokerConnection +from kombu.messaging import Exchange, Queue, Consumer, Producer + +from api_clients import api_client + +# configure logging +logging.config.fileConfig("logging.cfg") + # loading config file try: config = ConfigObj('config.cfg') @@ -22,12 +32,19 @@ except Exception, e: print 'Error loading config file: ', e sys.exit() -shows_to_record = {} +def getDateTimeObj(time): -class Recorder(Thread): + timeinfo = time.split(" ") + date = timeinfo[0].split("-") + time = timeinfo[1].split(":") + + return datetime.datetime(int(date[0]), int(date[1]), int(date[2]), int(time[0]), int(time[1]), int(time[2])) + +class ShowRecorder(Thread): def __init__ (self, show_instance, filelength, filename, filetype): Thread.__init__(self) + self.api_client = api_client.api_client_factory(config) self.filelength = filelength self.filename = filename self.filetype = filetype @@ -55,83 +72,73 @@ class Recorder(Thread): # datagen is a generator object that yields the encoded parameters datagen, headers = multipart_encode({"file": open(filepath, "rb"), 'name': filename, 'show_instance': self.show_instance}) - url = config["base_url"] + config["upload_file_url"] - - req = urllib2.Request(url, datagen, headers) - response = urllib2.urlopen(req).read().strip() - print response + self.api_client.upload_recorded_show(datagen, headers) def run(self): filepath = self.record_show() self.upload_file(filepath) -def getDateTimeObj(time): +class Record(): - timeinfo = time.split(" ") - date = timeinfo[0].split("-") - time = timeinfo[1].split(":") + def __init__(self): + self.api_client = api_client.api_client_factory(config) + self.shows_to_record = {} - return datetime.datetime(int(date[0]), int(date[1]), int(date[2]), int(time[0]), int(time[1]), int(time[2])) + def process_shows(self, shows): -def process_shows(shows): - - global shows_to_record - shows_to_record = {} - - for show in shows: - show_starts = getDateTimeObj(show[u'starts']) - show_end = getDateTimeObj(show[u'ends']) - time_delta = show_end - show_starts + self.shows_to_record = {} - shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id']] + for show in shows: + show_starts = getDateTimeObj(show[u'starts']) + show_end = getDateTimeObj(show[u'ends']) + time_delta = show_end - show_starts + + self.shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id']] -def check_record(): - - tnow = datetime.datetime.now() - sorted_show_keys = sorted(shows_to_record.keys()) - print sorted_show_keys - start_time = sorted_show_keys[0] - next_show = getDateTimeObj(start_time) + def check_record(self): + + tnow = datetime.datetime.now() + sorted_show_keys = sorted(self.shows_to_record.keys()) + print sorted_show_keys + start_time = sorted_show_keys[0] + next_show = getDateTimeObj(start_time) - print next_show - print tnow - delta = next_show - tnow - print delta + print next_show + print tnow - if delta <= datetime.timedelta(seconds=60): - print "sleeping %s seconds until show" % (delta.seconds) - time.sleep(delta.seconds) - - show_length = shows_to_record[start_time][0] - show_instance = shows_to_record[start_time][1] - show = Recorder(show_instance, show_length.seconds, start_time, filetype="mp3") - show.start() - - #remove show from shows to record. - del shows_to_record[start_time] - + delta = next_show - tnow + min_delta = datetime.timedelta(seconds=60) -def get_shows(): + if delta <= min_delta: + print "sleeping %s seconds until show" % (delta.seconds) + time.sleep(delta.seconds) + + show_length = self.shows_to_record[start_time][0] + show_instance = self.shows_to_record[start_time][1] + show = ShowRecorder(show_instance, show_length.seconds, start_time, filetype="mp3") + show.start() + + #remove show from shows to record. + del self.shows_to_record[start_time] + - url = config["base_url"] + config["show_schedule_url"] - response = urllib.urlopen(url) - data = response.read() - - response_json = json.loads(data) - shows = response_json[u'shows'] - print shows + def get_shows(self): - if len(shows): - process_shows(shows) - check_record() + shows = self.api_client.get_shows_to_record() + + if len(shows): + self.process_shows(shows) + self.check_record() if __name__ == '__main__': + recorder = Record() + while True: - get_shows() + recorder.get_shows() time.sleep(5) From 1107a67579f4baa73458c5ad04a717bbefaf9b3d Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 24 Mar 2011 23:43:27 -0400 Subject: [PATCH 60/74] CC-2098: Only push playlists that havent ended yet -implemented. Removed ability to specify time ranges for now, and defaulted to looking from now to 24 hours ahead. Being able to specify time ranges was removed, since we are not using bi-directional communication between pypofetch and Airtime server. --- application/controllers/ApiController.php | 9 ++-- application/models/RabbitMq.php | 2 +- application/models/Schedule.php | 49 +++++-------------- application/models/tests/SchedulerTests.php | 2 + python_apps/api_clients/api_client.py | 22 +-------- python_apps/pypo/config.cfg | 2 +- .../pypo/test/airtime-schedule-insert.php | 2 +- 7 files changed, 20 insertions(+), 68 deletions(-) diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index f7ff37eb1..1292e4927 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -133,6 +133,7 @@ class ApiController extends Zend_Controller_Action $this->_helper->viewRenderer->setNoRender(true); $api_key = $this->_getParam('api_key'); + if(!in_array($api_key, $CC_CONFIG["apiKey"])) { header('HTTP/1.0 401 Unauthorized'); @@ -142,12 +143,8 @@ class ApiController extends Zend_Controller_Action PEAR::setErrorHandling(PEAR_ERROR_RETURN); - $from = $this->_getParam("from"); - $to = $this->_getParam("to"); - if (Schedule::ValidPypoTimeFormat($from) && Schedule::ValidPypoTimeFormat($to)) { - $result = Schedule::ExportRangeAsJson($from, $to); - echo json_encode($result); - } + $result = Schedule::GetScheduledPlaylists(); + echo json_encode($result); } public function notifyMediaItemStartPlayAction() diff --git a/application/models/RabbitMq.php b/application/models/RabbitMq.php index e2749149c..1672dd4e2 100644 --- a/application/models/RabbitMq.php +++ b/application/models/RabbitMq.php @@ -31,7 +31,7 @@ class RabbitMq $EXCHANGE = 'airtime-schedule'; $channel->exchange_declare($EXCHANGE, 'direct', false, true); - $data = json_encode(Schedule::ExportRangeAsJson()); + $data = json_encode(Schedule::GetScheduledPlaylists()); $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); $channel->basic_publish($msg, $EXCHANGE); diff --git a/application/models/Schedule.php b/application/models/Schedule.php index ba5b97290..d1d556e1f 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -354,13 +354,14 @@ class Schedule { * @return array * Returns empty array if nothing found */ - public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true) + + public static function GetItems($p_currentDateTime, $p_toDateTime, $p_playlistsOnly = true) { global $CC_CONFIG, $CC_DBC; $rows = array(); if (!$p_playlistsOnly) { $sql = "SELECT * FROM ".$CC_CONFIG["scheduleTable"] - ." WHERE (starts >= TIMESTAMP '$p_fromDateTime') " + ." WHERE (starts >= TIMESTAMP '$p_currentDateTime') " ." AND (ends <= TIMESTAMP '$p_toDateTime')"; $rows = $CC_DBC->GetAll($sql); foreach ($rows as &$row) { @@ -388,7 +389,7 @@ class Schedule { ." ON st.instance_id = si.id" ." LEFT JOIN $CC_CONFIG[showTable] as sh" ." ON si.show_id = sh.id" - ." WHERE (st.starts >= TIMESTAMP '$p_fromDateTime')" + ." WHERE (st.ends >= TIMESTAMP '$p_currentDateTime')" ." AND (st.ends <= TIMESTAMP '$p_toDateTime')" //next line makes sure that we aren't returning items that //are past the show's scheduled timeslot. @@ -627,24 +628,16 @@ class Schedule { * @param string $p_toDateTime * In the format "YYYY-MM-DD-HH-mm-SS" */ - public static function ExportRangeAsJson($p_fromDateTime = null , $p_toDateTime = null) + public static function GetScheduledPlaylists() { global $CC_CONFIG, $CC_DBC; - if (is_null($p_fromDateTime)) { - $t1 = new DateTime(); - $t1->sub(new DateInterval("PT24H")); - $range_start = $t1->format("Y-m-d H:i:s"); - } else { - $range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime); - } - if (is_null($p_fromDateTime)) { - $t2 = new DateTime(); - $t2->add(new DateInterval("PT24H")); - $range_end = $t2->format("Y-m-d H:i:s"); - } else { - $range_end = Schedule::PypoTimeToAirtimeTime($p_toDateTime); - } + $t1 = new DateTime(); + $range_start = $t1->format("Y-m-d H:i:s"); + + $t2 = new DateTime(); + $t2->add(new DateInterval("PT24H")); + $range_end = $t2->format("Y-m-d H:i:s"); // Scheduler wants everything in a playlist $data = Schedule::GetItems($range_start, $range_end, true); @@ -720,25 +713,5 @@ class Schedule { return $result; } - - - /** - * Remove all items from the schedule in the given range. - * - * @param string $p_start - * In the format YYYY-MM-DD HH:MM:SS.nnnnnn - * @param string $p_end - * In the format YYYY-MM-DD HH:MM:SS.nnnnnn - */ - public static function RemoveItemsInRange($p_start, $p_end) - { - $items = Schedule::GetItems($p_start, $p_end); - foreach ($items as $item) { - $scheduleGroup = new ScheduleGroup($item["group_id"]); - $scheduleGroup->remove(); - } - RabbitMq::PushSchedule(); - } - } diff --git a/application/models/tests/SchedulerTests.php b/application/models/tests/SchedulerTests.php index 2064830b8..8f86b4ef9 100644 --- a/application/models/tests/SchedulerTests.php +++ b/application/models/tests/SchedulerTests.php @@ -110,6 +110,7 @@ class SchedulerTests extends PHPUnit_TestCase { } } +/* function testGetItems() { $i1 = new ScheduleGroup(); $groupId1 = $i1->add('2008-01-01 12:00:00.000', $this->storedFile->getId()); @@ -123,5 +124,6 @@ class SchedulerTests extends PHPUnit_TestCase { $i1->remove(); $i2->remove(); } +*/ } diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 6994cf3fd..7bafcc74a 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -189,30 +189,10 @@ class AirTimeApiClient(ApiClientInterface): def get_schedule(self, start=None, end=None): logger = logging.getLogger() - - """ - calculate start/end time range (format: YYYY-DD-MM-hh-mm-ss,YYYY-DD-MM-hh-mm-ss) - (seconds are ignored, just here for consistency) - """ - tnow = time.localtime(time.time()) - if (not start): - tstart = time.localtime(time.time() - 3600 * int(self.config["cache_for"])) - start = "%04d-%02d-%02d-%02d-%02d" % (tstart[0], tstart[1], tstart[2], tstart[3], tstart[4]) - - if (not end): - tend = time.localtime(time.time() + 3600 * int(self.config["prepare_ahead"])) - end = "%04d-%02d-%02d-%02d-%02d" % (tend[0], tend[1], tend[2], tend[3], tend[4]) - - range = {} - range['start'] = start - range['end'] = end - + # Construct the URL export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"] - # Insert the start and end times into the URL - export_url = export_url.replace('%%from%%', range['start']) - export_url = export_url.replace('%%to%%', range['end']) logger.info("Fetching schedule from %s", export_url) export_url = export_url.replace('%%api_key%%', self.config["api_key"]) diff --git a/python_apps/pypo/config.cfg b/python_apps/pypo/config.cfg index 4fd5ac377..2c0fce6f0 100644 --- a/python_apps/pypo/config.cfg +++ b/python_apps/pypo/config.cfg @@ -85,7 +85,7 @@ version_url = 'version/api_key/%%api_key%%' # Schedule export path. # %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm # %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm -export_url = 'schedule/api_key/%%api_key%%/from/%%from%%/to/%%to%%' +export_url = 'schedule/api_key/%%api_key%%' # Update whether a schedule group has begun playing. update_item_url = 'notify-schedule-group-play/api_key/%%api_key%%/schedule_id/%%schedule_id%%' diff --git a/python_apps/pypo/test/airtime-schedule-insert.php b/python_apps/pypo/test/airtime-schedule-insert.php index 6d3e37951..bc229dbd4 100644 --- a/python_apps/pypo/test/airtime-schedule-insert.php +++ b/python_apps/pypo/test/airtime-schedule-insert.php @@ -79,7 +79,7 @@ $endTime = date("Y-m-d H:i:s", time()+(60*60)); echo "Removing everything from the scheduler between $startTime and $endTime..."; // Scheduler: remove any playlists for the next hour -Schedule::RemoveItemsInRange($startTime, $endTime); +//Schedule::RemoveItemsInRange($startTime, $endTime); // Check for succcess $scheduleClear = Schedule::isScheduleEmptyInRange($startTime, "01:00:00"); if (!$scheduleClear) { From f38541cb0eab3f95d0ea5ff13af191aa8a4ea56f Mon Sep 17 00:00:00 2001 From: naomiaro Date: Thu, 24 Mar 2011 23:46:55 -0400 Subject: [PATCH 61/74] CC-2097 : Show-recorder: Use RabbitMQ, api_client, and the structure of pypofetch --- .../install/recorder-daemontools.sh | 2 +- python_apps/show-recorder/testrecordscript.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index 36510dfde..6f3664139 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -1,7 +1,7 @@ #!/bin/sh recorder_user="pypo" export HOME="/home/pypo/" -export TERM=xterm + # Location of pypo_cli.py Python script recorder_path="/opt/recorder/bin/" recorder_script="testrecordscript.py" diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 3b005835b..1c0c036f6 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -6,6 +6,7 @@ import json import time import datetime import os +import sys from configobj import ConfigObj @@ -13,8 +14,7 @@ from poster.encode import multipart_encode from poster.streaminghttp import register_openers import urllib2 -#from subprocess import call -from subprocess import Popen, PIPE +from subprocess import call from threading import Thread # For RabbitMQ @@ -24,7 +24,11 @@ from kombu.messaging import Exchange, Queue, Consumer, Producer from api_clients import api_client # configure logging -logging.config.fileConfig("logging.cfg") +try: + logging.config.fileConfig("logging.cfg") +except Exception, e: + print 'Error configuring logging: ', e + sys.exit() # loading config file try: @@ -57,10 +61,8 @@ class ShowRecorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = ("ecasound -i alsa -o %s -t:%s" % (filepath, length)).split(' ') - print(command) - Popen(command, stdout=PIPE) - #call(command, shell=False) + command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) + call(command, shell=True) return filepath From 091938d34ea79b82ce8f82acfb969c462ab9c8cf Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 00:19:44 -0400 Subject: [PATCH 62/74] CC-2097 : Show-recorder: Use RabbitMQ, api_client, and the structure of pypofetch fixing daemon tool to find logging.cfg --- python_apps/show-recorder/install/recorder-daemontools.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index 6f3664139..a381b4de9 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -7,10 +7,11 @@ recorder_path="/opt/recorder/bin/" recorder_script="testrecordscript.py" api_client_path="/opt/pypo/" +cd ${recorder_path} echo "*** Daemontools: starting daemon" exec 2>&1 # Note the -u when calling python! we need it to get unbuffered binary stdout and stderr -sudo PYTHONPATH=${api_client_path} -u ${recorder_user} python -u ${recorder_path}${recorder_script} -f +sudo PYTHONPATH=${api_client_path} -u ${recorder_user} python -u ${recorder_path}${recorder_script} # EOF From bdcabf37a2f2a98ba81c6210a60be4b100bf8061 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Mar 2011 01:38:46 -0400 Subject: [PATCH 63/74] -script to do a tail call on pypo-recorder --- dev_tools/pr.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 dev_tools/pr.sh diff --git a/dev_tools/pr.sh b/dev_tools/pr.sh new file mode 100755 index 000000000..f5e741658 --- /dev/null +++ b/dev_tools/pr.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +su -l pypo -c "tail -F /etc/service/recorder/log/main/current" From 537812298beac28cca1b30206c503d5fa4be9690 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 13:22:44 -0400 Subject: [PATCH 64/74] CC-2097 : Show-recorder: Use RabbitMQ, api_client, and the structure of pypofetch hopefully this will avoid "unknown terminal" problems --- .../install/recorder-daemontools.sh | 1 + python_apps/show-recorder/testrecordscript.py | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/python_apps/show-recorder/install/recorder-daemontools.sh b/python_apps/show-recorder/install/recorder-daemontools.sh index a381b4de9..c1e0df863 100644 --- a/python_apps/show-recorder/install/recorder-daemontools.sh +++ b/python_apps/show-recorder/install/recorder-daemontools.sh @@ -1,6 +1,7 @@ #!/bin/sh recorder_user="pypo" export HOME="/home/pypo/" +export TERM=xterm # Location of pypo_cli.py Python script recorder_path="/opt/recorder/bin/" diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 1c0c036f6..ae520cfd7 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -62,9 +62,15 @@ class ShowRecorder(Thread): filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) - call(command, shell=True) + args = command.split(" ") - return filepath + print "starting record" + + code = call(args) + + print "finishing record, return code %s" % (code) + + return code, filepath def upload_file(self, filepath): @@ -80,8 +86,12 @@ class ShowRecorder(Thread): self.api_client.upload_recorded_show(datagen, headers) def run(self): - filepath = self.record_show() - self.upload_file(filepath) + code, filepath = self.record_show() + + if code === 0: + self.upload_file(filepath) + else: + print "problem recording show" class Record(): From d0d8456a7add0722faabeb1650ecdd11e553858c Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 13:49:04 -0400 Subject: [PATCH 65/74] syntax error fix --- python_apps/show-recorder/testrecordscript.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index ae520cfd7..463fdd7fc 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -88,7 +88,7 @@ class ShowRecorder(Thread): def run(self): code, filepath = self.record_show() - if code === 0: + if code == 0: self.upload_file(filepath) else: print "problem recording show" From 095a2189699c11fcf1ded27df31046f91db25a14 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Mar 2011 15:08:52 -0400 Subject: [PATCH 66/74] CC-2046: About box could display version number -Made About box use the defined constant --- application/configs/conf.php | 2 +- application/views/scripts/partialviews/header.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/configs/conf.php b/application/configs/conf.php index da0c5e9b3..74c3b10ac 100644 --- a/application/configs/conf.php +++ b/application/configs/conf.php @@ -1,5 +1,5 @@
From 32323cb8ae5711f2c2afee4f5ecadbf61fbddf22 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 15:08:57 -0400 Subject: [PATCH 67/74] CC-2107 : Soundcloud username should be changed to email --- application/forms/Preferences.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/forms/Preferences.php b/application/forms/Preferences.php index 5af7c6a44..23cda3d3f 100644 --- a/application/forms/Preferences.php +++ b/application/forms/Preferences.php @@ -52,7 +52,7 @@ class Application_Form_Preferences extends Zend_Form //SoundCloud Username $this->addElement('text', 'SoundCloudUser', array( 'class' => 'input_text', - 'label' => 'SoundCloud Username:', + 'label' => 'SoundCloud Email:', 'required' => false, 'filters' => array('StringTrim'), 'value' => Application_Model_Preference::GetSoundCloudUser() From a58e7ed42eff9b828fda74e075f801d3b09fa5fc Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Mar 2011 15:31:33 -0400 Subject: [PATCH 68/74] CC-2114: stream Metadata shows.showing show-song-song instead of show-artist-song --- python_apps/pypo/scripts/ls_lib.liq | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python_apps/pypo/scripts/ls_lib.liq b/python_apps/pypo/scripts/ls_lib.liq index 8447e5100..5bd611878 100644 --- a/python_apps/pypo/scripts/ls_lib.liq +++ b/python_apps/pypo/scripts/ls_lib.liq @@ -6,9 +6,9 @@ end # A function applied to each metadata chunk def append_title(m) = if !stream_metadata_type == 1 then - [("artist","#{!show_name} - #{m['title']}")] - #elsif !stream_metadata_type == 2 then - # [("artist", ""), ("title", !show_name)] + [("artist","#{!show_name} - #{m['artist']}")] + #####elsif !stream_metadata_type == 2 then + ##### [("artist", ""), ("title", !show_name)] elsif !stream_metadata_type == 2 then [("artist",!station_name), ("title", !show_name)] else From 4ef86fa0841dc32df7062e1535a82672eabac29c Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 15:33:54 -0400 Subject: [PATCH 69/74] CC-2099 : Show dialog: Offset days should go up to 30 days in the future --- application/forms/AddShowRebroadcastDates.php | 47 +++++-------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/application/forms/AddShowRebroadcastDates.php b/application/forms/AddShowRebroadcastDates.php index a8e0a67d0..dc38a583b 100644 --- a/application/forms/AddShowRebroadcastDates.php +++ b/application/forms/AddShowRebroadcastDates.php @@ -9,17 +9,18 @@ class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm array('ViewScript', array('viewScript' => 'form/add-show-rebroadcast.phtml')) )); + + $relativeDates = array(); + $relativeDates[""] = ""; + for($i=0; $i <=30; $i++) { + $relativeDates["$i days"] = "+$i days"; + } + //Add date select $this->addElement('select', 'add_show_rebroadcast_date_1', array( 'required' => false, 'class' => ' input_select', - 'multiOptions' => array( - "" => "", - "0 days" => "+0 days", - "1 day" => "+1 day", - "2 days" => "+2 days", - "3 days" => "+3 days" - ), + 'multiOptions' => $relativeDates, 'decorators' => array( 'ViewHelper' ) @@ -44,13 +45,7 @@ class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm $this->addElement('select', 'add_show_rebroadcast_date_2', array( 'required' => false, 'class' => ' input_select', - 'multiOptions' => array( - "" => "", - "0 days" => "+0 days", - "1 day" => "+1 day", - "2 days" => "+2 days", - "3 days" => "+3 days" - ), + 'multiOptions' => $relativeDates, 'decorators' => array( 'ViewHelper' ) @@ -75,13 +70,7 @@ class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm $this->addElement('select', 'add_show_rebroadcast_date_3', array( 'required' => false, 'class' => ' input_select', - 'multiOptions' => array( - "" => "", - "0 days" => "+0 days", - "1 day" => "+1 day", - "2 days" => "+2 days", - "3 days" => "+3 days" - ), + 'multiOptions' => $relativeDates, 'decorators' => array( 'ViewHelper' ) @@ -106,13 +95,7 @@ class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm $this->addElement('select', 'add_show_rebroadcast_date_4', array( 'required' => false, 'class' => ' input_select', - 'multiOptions' => array( - "" => "", - "0 days" => "+0 days", - "1 day" => "+1 day", - "2 days" => "+2 days", - "3 days" => "+3 days" - ), + 'multiOptions' => $relativeDates, 'decorators' => array( 'ViewHelper' ) @@ -137,13 +120,7 @@ class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm $this->addElement('select', 'add_show_rebroadcast_date_5', array( 'required' => false, 'class' => ' input_select', - 'multiOptions' => array( - "" => "", - "0 days" => "+0 days", - "1 day" => "+1 day", - "2 days" => "+2 days", - "3 days" => "+3 days" - ), + 'multiOptions' => $relativeDates, 'decorators' => array( 'ViewHelper' ) From 7170f8385e643073eededc4397ebe3db60ad80f3 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Mar 2011 17:00:45 -0400 Subject: [PATCH 70/74] CC-2121: Disable OGG streams by default -Done --- python_apps/pypo/scripts/ls_config.liq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/scripts/ls_config.liq b/python_apps/pypo/scripts/ls_config.liq index ef1caa198..20b1f4215 100644 --- a/python_apps/pypo/scripts/ls_config.liq +++ b/python_apps/pypo/scripts/ls_config.liq @@ -44,5 +44,5 @@ icecast_description = "Airtime Radio!" icecast_genre = "genre" output_sound_device = false -output_icecast_vorbis = true +output_icecast_vorbis = false output_icecast_mp3 = true From deb210a8d41fd4716e8f625989bb0adb36df1e7e Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Mar 2011 17:16:22 -0400 Subject: [PATCH 71/74] -Changed text for Show URL -> Website. --- application/forms/AddShowWhat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/forms/AddShowWhat.php b/application/forms/AddShowWhat.php index 7fafdb46e..74e7b0dcc 100644 --- a/application/forms/AddShowWhat.php +++ b/application/forms/AddShowWhat.php @@ -16,7 +16,7 @@ class Application_Form_AddShowWhat extends Zend_Form_SubForm // Add URL element $this->addElement('text', 'add_show_url', array( - 'label' => 'Show URL:', + 'label' => 'Website:', 'class' => 'input_text', 'required' => false, 'filters' => array('StringTrim'), From 40c9c48961e7991d7f481daaf208a34189242921 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Fri, 25 Mar 2011 17:18:42 -0400 Subject: [PATCH 72/74] CC-2029 : Missing icons on buttons --- application/views/scripts/schedule/add-show-form.phtml | 5 ++++- application/views/scripts/user/add-user.phtml | 4 +++- public/js/airtime/schedule/add-show.js | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/application/views/scripts/schedule/add-show-form.phtml b/application/views/scripts/schedule/add-show-form.phtml index 2a111448b..9d8613d7d 100644 --- a/application/views/scripts/schedule/add-show-form.phtml +++ b/application/views/scripts/schedule/add-show-form.phtml @@ -1,7 +1,10 @@
Close - +

What

diff --git a/application/views/scripts/user/add-user.phtml b/application/views/scripts/user/add-user.phtml index db1e76138..4f836e0fa 100644 --- a/application/views/scripts/user/add-user.phtml +++ b/application/views/scripts/user/add-user.phtml @@ -7,7 +7,9 @@
- +
diff --git a/public/js/airtime/schedule/add-show.js b/public/js/airtime/schedule/add-show.js index 50ca4058a..329391086 100644 --- a/public/js/airtime/schedule/add-show.js +++ b/public/js/airtime/schedule/add-show.js @@ -182,7 +182,6 @@ function setAddShowEvents() { }); form.find("#add-show-submit") - .button() .click(function(event){ event.preventDefault(); From df8b9af8f690b72dede7c28b78816e209e5416e8 Mon Sep 17 00:00:00 2001 From: naomiaro Date: Mon, 28 Mar 2011 12:10:51 -0400 Subject: [PATCH 73/74] CC-2110 : Soundcloud file metadata uploading show description, show name in filename, tags ready to be uploaded for creator need to figure out what to upload. --- application/controllers/ApiController.php | 23 +++++++++---------- application/models/Soundcloud.php | 9 +++++--- python_apps/api_clients/api_client.py | 7 +++--- python_apps/show-recorder/testrecordscript.py | 9 +++++--- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index 1cc2e0303..7f1cf524e 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -236,10 +236,6 @@ class ApiController extends Zend_Controller_Action { global $CC_CONFIG; - // disable the view and the layout - $this->view->layout()->disableLayout(); - $this->_helper->viewRenderer->setNoRender(true); - $api_key = $this->_getParam('api_key'); if (!in_array($api_key, $CC_CONFIG["apiKey"])) { @@ -251,16 +247,19 @@ class ApiController extends Zend_Controller_Action $upload_dir = ini_get("upload_tmp_dir"); $file = StoredFile::uploadFile($upload_dir); - if(Application_Model_Preference::GetDoSoundCloudUpload()) - { - $soundcloud = new ATSoundcloud(); - $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName()); - } - $show_instance = $this->_getParam('show_instance'); - $show = new ShowInstance($show_instance); - $show->setRecordedFile($file->getId()); + $show_inst = new ShowInstance($show_instance); + $show_inst->setRecordedFile($file->getId()); + + if(Application_Model_Preference::GetDoSoundCloudUpload()) + { + $show = new Show($show_inst->getShowId()); + $description = $show->getDescription(); + + $soundcloud = new ATSoundcloud(); + $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description); + } $this->view->id = $file->getId(); } diff --git a/application/models/Soundcloud.php b/application/models/Soundcloud.php index ceaa9cc47..352bd8ea7 100644 --- a/application/models/Soundcloud.php +++ b/application/models/Soundcloud.php @@ -28,14 +28,18 @@ class ATSoundcloud { return $token; } - public function uploadTrack($filepath, $filename) + public function uploadTrack($filepath, $filename, $description, $tags=array()) { if($this->getToken()) { + $tags = join(" ", $tags); + $track_data = array( 'track[sharing]' => 'private', 'track[title]' => $filename, - 'track[asset_data]' => '@' . $filepath + 'track[asset_data]' => '@' . $filepath, + 'track[tag_list]' => $tags, + 'track[description]' => $description ); try { @@ -46,7 +50,6 @@ class ATSoundcloud { } catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) { echo $e->getMessage(); - echo var_dump($track_data); } } } diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 0b31b9137..cd2a6e7d7 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -291,9 +291,9 @@ class AirTimeApiClient(ApiClientInterface): response = '' try: url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"] - #logger.debug(url) - url = url.replace("%%api_key%%", self.config["api_key"]) logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) + response = urllib.urlopen(url) response = json.loads(response.read()) logger.info("shows %s", response) @@ -308,9 +308,8 @@ class AirTimeApiClient(ApiClientInterface): response = '' try: url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"] - #logger.debug(url) - url = url.replace("%%api_key%%", self.config["api_key"]) logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) request = urllib2.Request(url, data, headers) response = urllib2.urlopen(request).read().strip() diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 463fdd7fc..c7fb2691d 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -109,14 +109,14 @@ class Record(): show_end = getDateTimeObj(show[u'ends']) time_delta = show_end - show_starts - self.shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id']] + self.shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id'], show[u'name']] def check_record(self): tnow = datetime.datetime.now() sorted_show_keys = sorted(self.shows_to_record.keys()) - print sorted_show_keys + start_time = sorted_show_keys[0] next_show = getDateTimeObj(start_time) @@ -132,7 +132,10 @@ class Record(): show_length = self.shows_to_record[start_time][0] show_instance = self.shows_to_record[start_time][1] - show = ShowRecorder(show_instance, show_length.seconds, start_time, filetype="mp3") + show_name = self.shows_to_record[start_time][2] + filename = show_name+"-"+start_time + + show = ShowRecorder(show_instance, show_length.seconds, filename, filetype="mp3") show.start() #remove show from shows to record. From c0e815207777f9e2dd59430a50ce0f04ab684d17 Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 28 Mar 2011 15:39:01 -0400 Subject: [PATCH 74/74] CC-2110 : Soundcloud file metadata added text area to preferences to allow for additional soundcloud tags. --- application/controllers/PreferenceController.php | 3 ++- application/forms/Preferences.php | 8 ++++++++ application/models/Preference.php | 8 ++++++++ application/models/Soundcloud.php | 14 +++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/application/controllers/PreferenceController.php b/application/controllers/PreferenceController.php index 58bd6416d..61508bb1c 100644 --- a/application/controllers/PreferenceController.php +++ b/application/controllers/PreferenceController.php @@ -32,7 +32,8 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::SetStreamLabelFormat($values["streamFormat"]); Application_Model_Preference::SetDoSoundCloudUpload($values["UseSoundCloud"]); Application_Model_Preference::SetSoundCloudUser($values["SoundCloudUser"]); - Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]); + Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]); + Application_Model_Preference::SetSoundCloudTags($values["SoundCloudTags"]); $this->view->statusMsg = "Preferences Updated."; } diff --git a/application/forms/Preferences.php b/application/forms/Preferences.php index 23cda3d3f..2e770a9a6 100644 --- a/application/forms/Preferences.php +++ b/application/forms/Preferences.php @@ -67,6 +67,14 @@ class Application_Form_Preferences extends Zend_Form 'value' => Application_Model_Preference::GetSoundCloudPassword() )); + // Add the description element + $this->addElement('textarea', 'SoundCloudTags', array( + 'label' => 'space separated SoundCloud Tags', + 'required' => false, + 'class' => 'input_text_area', + 'value' => Application_Model_Preference::GetSoundCloudTags() + )); + $this->addElement('submit', 'submit', array( 'class' => 'ui-button ui-state-default', 'ignore' => true, diff --git a/application/models/Preference.php b/application/models/Preference.php index 8662f4424..948b29645 100644 --- a/application/models/Preference.php +++ b/application/models/Preference.php @@ -124,5 +124,13 @@ class Application_Model_Preference return Application_Model_Preference::GetValue("soundcloud_password"); } + public static function SetSoundCloudTags($tags) { + Application_Model_Preference::SetValue("soundcloud_tags", $tags); + } + + public static function GetSoundCloudTags() { + return Application_Model_Preference::GetValue("soundcloud_tags"); + } + } diff --git a/application/models/Soundcloud.php b/application/models/Soundcloud.php index 352bd8ea7..78e9223a5 100644 --- a/application/models/Soundcloud.php +++ b/application/models/Soundcloud.php @@ -32,7 +32,13 @@ class ATSoundcloud { { if($this->getToken()) { - $tags = join(" ", $tags); + if(count($tags)) { + $tags = join(" ", $tags); + $tags = $tags." ".Application_Model_Preference::GetSoundCloudTags(); + } + else { + $tags = Application_Model_Preference::GetSoundCloudTags(); + } $track_data = array( 'track[sharing]' => 'private', @@ -47,11 +53,17 @@ class ATSoundcloud { $this->_soundcloud->post('tracks', $track_data), true ); + + echo var_dump($response); } catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) { echo $e->getMessage(); } } + else + { + echo "could not get soundcloud token"; + } } }