def __init__(self, index=None, outdir=OUTDIR, max_downloads=MAX_DOWNLOADS, max_priority=MAX_PRIORITY, max_watches=MAX_WATCHES, live_rate=LIVE_RATE, schedule_ticks=SCHEDULE_TICKS, end_hour=END_HOUR, resume_hour=RESUME_HOUR, new_index=True, index_loc=NEW_INDEX_LOC, logging=False, exit_behaviour='hard', noisy=False): self.session = WatchSession() if new_index: self.index = IndexerNew(index_loc) else: # TODO: convert this to IndexerOld self.index = index self.settings = { 'outdir': outdir, 'max_downloads': max_downloads, 'max_watches': max_watches, 'max_priority': max_priority, 'live_rate': live_rate, 'schedule_ticks': schedule_ticks, 'logging': logging, 'noisy': noisy } self.end_time = datetime.time(hour=end_hour, minute=10, tzinfo=TOKYO_TZ) self.resume_time = datetime.time(hour=resume_hour - 1, minute=50, tzinfo=TOKYO_TZ) self.live_rate = self.settings['live_rate'] self.input_queue = InputQueue() self.scheduler = None self.watchers = None self.downloaders = None self.time = None if exit_behaviour == 'soft': self.soft_exit = True else: self.soft_exit = False self.quitting = False self._announcer = Announcer()
def __init__(self, member, session, outdir, logging): self.session = session self._member = member self.process = None # self.failures = 0 self.rootdir = outdir # set by WatchManager self.destdir, self.tempdir, self.outfile = "", "", "" self._url = "" self._logging = logging self._announcer = Announcer()
def privilegedStartService(self): print 'Starting' # Start TCP server on random port self.tcpFactory = CastFactory() self.tcpFactory.protocol.timeout = self.tcptimeout self.tcpFactory.session.timeout = self.commitperiod self.tcpFactory.maxActive = self.maxActive # Attaching CastFactory to ProcessorController self.tcpFactory.commit = self.ctrl.commit self.tcp = self.reactor.listenTCP(0, self.tcpFactory, interface=self.bind) self.tcp.startListening() # Find out which port is in use addr = self.tcp.getHost() print 'listening on',addr self.key = random.randint(0,0xffffffff) # start up the UDP announcer self.udpProto = Announcer(tcpport=addr.port, key=self.key, udpaddrs=self.addrlist, period=self.annperiod) self.udp = SharedUDP(0, self.udpProto, reactor=self.reactor) self.udp.startListening() # This will start up plugin Processors service.MultiService.privilegedStartService(self)
def __init__(self, member, session, outdir, logging, noisy): self.session = session self._member = member self.process = None # self.failures = 0 self.rootdir = outdir # set by WatchManager self.destdir, self.tempdir, self.outfile = "", "", "" self._url = "" self._logging = logging if noisy: self._announcer = Announcer() else: self._announcer = DummyAnnouncer() self.sent_quit = False self.start_time = None
class Controller(object): # slavish adaptation of # http://stackoverflow.com/a/19655992/3380530 def __init__(self, index=None, outdir=OUTDIR, max_downloads=MAX_DOWNLOADS, max_priority=MAX_PRIORITY, max_watches=MAX_WATCHES, live_rate=LIVE_RATE, schedule_ticks=SCHEDULE_TICKS, end_hour=END_HOUR, resume_hour=RESUME_HOUR, new_index=True, index_loc=NEW_INDEX_LOC, logging=False, exit_behaviour='hard', noisy=False): self.session = WatchSession() if new_index: self.index = IndexerNew(index_loc) else: # TODO: convert this to IndexerOld self.index = index self.settings = {'outdir': outdir, 'max_downloads': max_downloads, 'max_watches': max_watches, 'max_priority': max_priority, 'live_rate': live_rate, 'schedule_ticks': schedule_ticks, 'logging': logging, 'noisy': noisy} self.end_time = datetime.time(hour=end_hour, minute=10, tzinfo=TOKYO_TZ) self.resume_time = datetime.time(hour=resume_hour-1, minute=50, tzinfo=TOKYO_TZ) self.live_rate = self.settings['live_rate'] self.input_queue = InputQueue() self.scheduler = None self.watchers = None self.downloaders = None self.time = None if exit_behaviour == 'soft': self.soft_exit = True else: self.soft_exit = False self.quitting = False self._announcer = Announcer() def filter(self, names_filter): self.index.filter(names_filter) def run(self): # why are these defined here? self.scheduler = Scheduler(index=self.index, settings=self.settings) self.watchers = self.scheduler.watchmanager self.downloaders = self.watchers.downloads # self.downloaders # sleep_minutes = 20 while True: self.time = datetime.datetime.now(tz=TOKYO_TZ) ''' if self.resume_time > self.time.time() > self.end_time: sleep_seconds = (datetime.datetime.combine(self.time, self.resume_time) - self.time).total_seconds() + 1.0 print('Time is {}, sleeping for {} seconds, until {}'.format(self.time.strftime('%H:%M'), sleep_seconds, self.resume_time.strftime('%H:%M'))) self.scheduler.reset_ticks() time.sleep(sleep_seconds) else:''' self.scheduler.tick(self.time) # Scheduler object self.watchers.tick(self.time) # WatchManager object self.downloaders.tick(self.time) # DownloadManager object while not self.input_queue.empty(): try: command = self.input_queue.get(block=False) except QueueEmpty: break else: try: self.heed_command(command) except ShowroomExitRequest: return time.sleep(0.5) def quit(self): # TODO: Put the downloaders on a ThreadPool print("Exiting...") self.downloaders.quit() raise(ShowroomExitRequest) def heed_command(self, key): """Responds to (single) key presses: q/Q == Quit (asks for confirmation) s/S == Print full schedule (including current downloads) d/D == Print all current downloads l/L == Print all current downloads with rtmp and http links""" if self.quitting and key.lower() == 'y': self.quit() else: self.quitting = False if key.lower() == 'q': self.input_queue.clear() print('Are you sure you want to quit? (y/N)') if self.soft_exit: print('(Active downloads will continue until finished) ') else: print('(Active downloads will be stopped) ') self.quitting = True # TODO: encapsulate these more sanely so that other types of Announcer will work elif key.lower() == 's': self.input_queue.clear() self._announcer.send_message(('Current Schedule:',) + tuple(self.scheduler.list)) elif key.lower() == 'd': self.input_queue.clear() self._announcer.send_message(('Current Downloads:',) + tuple(self.downloaders.list)) elif key.lower() == 'l': self.input_queue.clear() self._announcer.send_message(('Current Downloads with Links:',) + tuple(self.downloaders.list_with_links))
class Downloader(object): def __init__(self, member, session, outdir, logging): self.session = session self._member = member self.process = None # self.failures = 0 self.rootdir = outdir # set by WatchManager self.destdir, self.tempdir, self.outfile = "", "", "" self._url = "" self._logging = logging self._announcer = Announcer() @property def name(self): return self._member['engName'] @property def room_id(self): return self._member['showroom_id'] @property def priority(self): return self._member['priority'] @property def member(self): return self._member @property def logging(self): return self._logging @property def web_url(self): return self._member['web_url'] def announce(self, msg): self._announcer.send_message(msg) def is_live(self): while True: try: status = self.session.get( 'https://www.showroom-live.com/room/is_live', params={ "room_id": self.room_id }).json()['ok'] except JSONDecodeError: continue if status == 0: return False elif status == 1: return True def check(self): self.process.poll() if self.process.returncode == None: #_, err = self.process.communicate() #if b'already exists. Overwrite' in err: # self.process.communicate(b'y\n') return False else: if self.outfile: self.move_to_dest() if self.is_live(): time.sleep(2) # give the stream some time to restart self.start() return False return True # how to respond to failed exits? def kill(self): if not self.sent_quit: print('Quitting {}'.format(self.name)) self.process.terminate() self.sent_quit = True else: self.process.kill() self.sent_quit = False def move_to_dest(self): srcpath = '{}/{}'.format(self.tempdir, self.outfile) destpath = '{}/{}'.format(self.destdir, self.outfile) if os.path.exists(destpath): # how? why? this should never happen raise FileExistsError else: try: os.replace(srcpath, destpath) except FileNotFoundError: # probably means srcpath not found, which means the download errored out # before creating a file. right now, do nothing # Most likely what's happening is the script is trying to access the stream # while it's down (but the site still reports it as live) # print('Download for {} failed'.format(self.name)) pass else: print('Completed {}/{}'.format(self.destdir, self.outfile)) self.destdir, self.tempdir, self.outfile = ("", "", "") def start(self): data = self.session.get( 'https://www.showroom-live.com/room/get_live_data', params={ 'room_id': self.room_id }).json() stream_name = data['streaming_name_rtmp'] stream_url = data["streaming_url_rtmp"] tokyo_time = datetime.datetime.now(tz=TOKYO_TZ) new_url = '{}/{}'.format(stream_url, stream_name) self.tempdir, self.destdir, self.outfile = format_name( self.rootdir, tokyo_time.strftime('%Y-%m-%d %H%M%S'), self.member) self.sent_quit = False if new_url != self.url: self._url = new_url print('Downloading {}\'s Showroom'.format(self.name, self.url)) self.announce((self.web_url, self.url)) if self.logging == True: log_file = os.path.normpath('{}/logs/{}.log'.format( self.destdir, self.outfile)) ENV = {'FFREPORT': 'file={}:level=40'.format(log_file)} else: ENV = None normed_outpath = os.path.normpath('{}/{}'.format( self.tempdir, self.outfile)) self.process = subprocess.Popen([ 'ffmpeg', '-loglevel', '16', '-copytb', '1', '-i', self.url, '-c', 'copy', normed_outpath ], stdin=subprocess.PIPE, env=ENV) @property def url(self): return self._url
logger_port =int( config.get('Logging', 'port')) handler = logging.handlers.SysLogHandler(address = (logger_host, logger_port), facility=19) logger.addHandler(handler) logger.info('Starting lockd') #add_custom_print_exception() try: #if 1: serialdevice = config.get('Master Controller', 'serialdevice') baudrate = config.get('Master Controller', 'baudrate') announcer = Announcer(False) ser = serialinterface.SerialInterface(serialdevice, baudrate, timeout=.1) command_queue = Queue.Queue() udpcommand = UDPCommand('127.0.0.1', 2323, command_queue) doors = {} master = None for section in config.sections(): if config.has_option(section, 'type'): t = config.get(section, 'type') if t == 'door': name = section
def __init__(self, config): self.logger = logging.getLogger('logger') self.logger.info('Starting lockd') #add_custom_print_exception() serialdevice = config.get('Master Controller', 'serialdevice') baudrate = config.get('Master Controller', 'baudrate') self.serial_interface = serialinterface.SerialInterface(serialdevice, baudrate, timeout=.1) self.input_queue = Queue.Queue() udpcommand = UDPCommand('127.0.0.1', 2323, self.input_queue) self.doors = {} self.master = None display = None self.display_controller = None self.logic = DoorLogic() for section in config.sections(): if config.has_option(section, 'type'): t = config.get(section, 'type') if t == 'door': door_name = section self.logger.debug('Adding door "%s"'%door_name) buttons = {1: 'manual_control', 2: 'bell_code'} door = Door(door_name, config, self.serial_interface, self.input_queue, buttons) door_address = config.get(door_name, 'address') self.doors[door_address] = door self.logic.add_door(door) else: self.logger.warning('Unknown entry type "%s"', t) elif section == 'Master Controller': #txseq = int(config.get(section, 'txsequence')) #rxseq = int(config.get(section, 'rxsequence')) #key = config.get(section, 'key') buttons_section = 'Master Controller Buttons' buttons = {} for button_name in config.options(buttons_section): button_pin = int(config.get(buttons_section, button_name)) buttons[button_pin] = button_name leds_section = 'Master Controller LEDs' leds = {} for led_name in config.options(leds_section): led_pin = int(config.get(leds_section, led_name)) leds[led_name] = led_pin self.master = MasterController(self.serial_interface, self.input_queue, buttons, leds) elif section == 'Display': display_type = config.get(section, 'display_type') max_update_rate = float(config.get(section, 'max_update_rate')) if display_type == "Nokia_1600": from display import Display display = Display(self.serial_interface) elif display_type == 'simulation': from display_pygame import Display display = Display() elif display_type == 'network': from display_network import Display display = Display() elif display_type == 'None': display = None else: self.logger.warning('Unknown display type "%s"', display_type) elif section == 'Status Receiver': host = config.get(section, 'host') port = int(config.get(section, 'port')) self.announcer = Announcer(host, port) self.logic.add_state_listener(self.announcer.update_state) if self.master == None: self.logger.error('Please specify a self.master controller') sys.exit(1) self.interface_logic = UserInterfaceLogic(self.master) self.logic.add_state_listener(self.interface_logic.update_state) if display != None: self.display_controller = DisplayController(display, max_update_rate) self.display_logic = DisplayLogic(self.display_controller) self.logic.add_state_listener(self.display_logic.update_state) for door in self.doors.values(): self.display_logic.add_door(door) else: self.logger.warning('No display specified.') self.input_queue.put({'origin_name': 'init', 'origin_type': DoorLogic.Origin.INTERNAL, 'input_name': '', 'input_type': DoorLogic.Input.COMMAND, 'input_value': 'down'})
handler = logging.handlers.SysLogHandler(address=(logger_host, logger_port), facility=19) logger.addHandler(handler) logger.info('Starting lockd') #add_custom_print_exception() try: #if 1: serialdevice = config.get('Master Controller', 'serialdevice') baudrate = config.get('Master Controller', 'baudrate') announcer = Announcer(False) ser = serialinterface.SerialInterface(serialdevice, baudrate, timeout=.1) command_queue = Queue.Queue() udpcommand = UDPCommand('127.0.0.1', 2323, command_queue) doors = {} master = None for section in config.sections(): if config.has_option(section, 'type'): t = config.get(section, 'type') if t == 'door': name = section