def move_tray(self, direction='toggle'): """ Move the tray. direction can be toggle/open/close """ global im_thread if direction == 'toggle': if self.is_tray_open(): direction = 'close' else: direction = 'open' if direction == 'open' and self.can_eject: pop = PopupBox(text=_('Ejecting disc in drive %s') % self.drivename) pop.show() if util.is_mounted(self.mountdir): self.umount() self.mount_ref_count = 0 self.open_tray() pop.destroy() elif direction == 'close' and self.can_close: pop = PopupBox(text=_('Reading disc in drive %s') % self.drivename) pop.show() self.close_tray() if im_thread: im_thread.check_all() pop.destroy()
def copy_fxd(self, arg=None, menuw=None): """ Find all fxd files inside a given folder, and copy them to the configured destination folder """ self.item.media.mount() box = PopupBox(text=_('Finding and copying FXD files...')) box.show() time.sleep(1) fxds = util.fileops.match_files_recursively(self.item.dir, ['fxd']) msg = '' for i in fxds: logger.debug('file: %r', i) self.cwd = os.path.dirname(i) parser = util.fxdparser.FXD(i) parser.set_handler('movie', self.fxdparser) parser.set_handler('movie', self.fxdparsew, mode='w') parser.parse() if self.ismovie: parser.tree.filename = '%s/%s' % ( self.archives, os.path.basename(parser.filename)) try: parser.save() self.nfiles += 1 except: print "Error while trying to write ", parser.tree.filename msg = _( "There was a error while trying to write the fxd file") if self.coverimg: coverfrom = os.path.join(self.cwd, self.coverimg) coverto = os.path.join(self.archives, self.coverimg) try: shutil.copy(coverfrom, coverto) # is there a better way to do this? os.chmod(coverto, 0644) except: print "Error while trying to copy %s to %s" % ( coverfrom, coverto) msg = _("But I couldn't copy a cover image file.") self.ismovie = False box.destroy() box = PopupBox(text=_('%(nfiles)d fxd files archived. %(msg)s') % ({ 'nfiles': self.nfiles, 'msg': msg })) box.show() time.sleep(3) box.destroy() self.item.media.umount() #reset a few variables self.nfiles = 0 msg = ''
def chapter(self): if self.schapter == None: rc.add_app(self) self.pop = PopupBox(_('Choose title to play. <1-9>')) self.pop.show() else: self.play()
def mpd_status(self, arg=None, menuw=None): """bring up a dialog showing mpd's current status""" stat = self.conn.status() track = self.conn.currentsong() text = "status: %s\n" % (stat['state']) if (stat['state'] != 'stop'): text += "title: %s\n" % (track['title']) text += "album: %s\n" % (track['album']) text += "artist: %s\n" % (track['artist']) text += "track: %s\\%s\n" % (int(stat['song']) + 1, stat['playlistlength']) text += "time: %s\n" % (stat['time']) if (stat['repeat'] == '1'): text += "repeat: on\n" else: text += "repeat: off\n" if (stat['random'] == '1'): text += "random: on\n" else: text += "random: off\n" text += "volume: %s" % (stat['volume']) pop = PopupBox(text) pop.show()
def poll(self, menuw=None, arg=None): """ poll to check for devices """ changes = False current_devices = util.list_usb_devices() for d in current_devices: try: self.devices.remove(d) except ValueError: _debug_('new device %s' % (d)) for device, message, action in config.USB_HOTPLUG: if d == device: pop = PopupBox(text=message) pop.show() os.system(action) pop.destroy() break else: changes = True for d in self.devices: changes = True _debug_('removed device %s' % (d)) if changes: rc.post_event(plugin.event('USB')) self.devices = current_devices
def create_podcast_menu(self, arg=None, menuw=None): """ Create the main menu item for the video podcasts """ popup = PopupBox(text=_('Fetching podcasts...')) popup.show() podcast_menu_items = [] for location in config.VPODCAST_LOCATIONS: url = location[1] image_path = config.VPODCAST_DIR + '/' + location[ 0] + '/' + 'cover.jpg' if self.check_logo(image_path): p = podcast() p.open_rss(url) p.rss_title() name = p.rss_title try: image_url = p.rss_image self.download(image_url, image_path) except: print 'No image in RSS' if (len(config.VPODCAST_DIR) == 0): podcast_items += [ menu.MenuItem(_('Set VPODCAST_DIR in local_conf.py'), menwu.goto_prev_page, 0) ] podcast_menu_items += [menu.MenuItem(_(location[0]), action=self.create_podcast_submenu, \ arg=location, image=image_path)] popup.destroy() podcast_main_menu = menu.Menu(_('Video Podcasts'), podcast_menu_items) rc.app(None) menuw.pushmenu(podcast_main_menu) menuw.refresh()
def play(self, arg=None, menuw=None): """ Play this Podcast""" # play the item. isYT = self.vp_url.find('youtube.com') #YouTube podcast isMC = self.vp_url.find('metacafe.com') #Metacafe podcast if isYT != -1: self.download_url = self.youtube(self.vp_url) elif isMC != -1: self.download_url = self.metacafe(self.vp_url) else: self.download_url = self.vp_url if not os.path.exists(self.filename): background = BGDownload(self.download_url, self.filename) background.start() popup = PopupBox(text=_('Buffering podcast...')) popup.show() time.sleep(20) # 20s. buffering time popup.destroy() # call the play funuction of VideoItem VideoItem.play(self, menuw=menuw, arg=arg)
def chapter(self): if self.schapter == None: rc.app(self) rc.set_context('input') self.pop = PopupBox(_('Choose title to play. <1-9>')) self.pop.show() else: self.play()
def copyHere(self, arg=None, menuw=None): popup = PopupBox(text=_('Copying files...')) popup.show() try: for cartfile in self.cart: cartfile.files.copy(self.item.dir) except OSError, e: print 'Copy failed: %s' % e
def moveHere(self, arg=None, menuw=None): popup = PopupBox(text=_('Moving files...')) popup.show() try: for cartfile in self.cart: cartfile.files.move(self.item.dir) except OSError, e: print 'Move failed: %s' % e
class ZoneMinderCommon(): def __init__(self, id): self.id = id self.conn = None self.stream_file = None self.stop_display = False def build_auth(self): auth = '' if config.ZONEMINDER_SERVER_AUTH_TYPE == 'builtin': if config.ZONEMINDER_SERVER_AUTH_RELAY == 'plain': auth = '&user=%s&pass=%s' % (config.ZONEMINDER_SERVER_USERNAME, config.ZONEMINDER_SERVER_PASSWORD) if config.ZONEMINDER_SERVER_AUTH_RELAY == 'hashed': # $time = localtime(); # $auth_key = ZM_AUTH_HASH_SECRET.$_SESSION['username'].$_SESSION['password_hash'].$_SESSION['remote_addr'].$time[2].$time[3].$time[4].$time[5]; # $auth = md5($auth_key); lt = localtime() auth_key = md5.new() auth_key.update(config.ZONEMINDER_SERVER_AUTH_HASH_SECRET) auth_key.update(config.ZONEMINDER_SERVER_USERNAME) auth_key.update(config.ZONEMINDER_SERVER_PASSWORD_HASH) if config.ZONEMINDER_CLIENT_IPV4_ADDRESS: auth_key.update(config.ZONEMINDER_CLIENT_IPV4_ADDRESS) else: my_ipv4_address = socket.gethostbyname(socket.gethostname()) if (my_ipv4_address == '127.0.0.1'): log.warning("gethostbyname has return '127.0.0.1' as you ip address, streaming or events display should not work, please check you hosts file or use ZONEMINDER_CLIENT_IPV4_ADDRESS.") auth_key.update(socket.gethostbyname(socket.gethostname())) # should return my ip auth_key.update("%d%d%d%d" % (lt[3], lt[2], lt[1] - 1, lt[0] - 1900)) auth = '&auth=' + auth_key.hexdigest() return auth def start_stream(self): if config.ZONEMINDER_SERVER_USE_SSL: self.conn = httplib.HTTPSConnection( config.ZONEMINDER_SERVER_HOST, port=int(config.ZONEMINDER_SERVER_PORT), key_file=config.ZONEMINDER_SERVER_SSL_KEY, cert_file=config.ZONEMINDER_SERVER_SSL_CERT, ) else: self.conn = httplib.HTTPConnection(config.ZONEMINDER_SERVER_HOST, port=int(config.ZONEMINDER_SERVER_PORT)) self.conn.connect() try: self.conn.putrequest('GET', self.build_request()) self.conn.endheaders() except socket.error, e: self.stream_file = None PopupBox(text=_('Error: %s') % e[1]).show() return except httplib.HTTPException, e: self.stream_file = None PopupBox(text=_('Error: %s') % e.message).show() return
def create_thumbnail(self, arg=None, menuw=None): """ Create a thumbnail as image icon """ import util.videothumb pop = PopupBox(text=_('Please wait....')) pop.show() util.videothumb.snapshot(self.filename) pop.destroy() menuw.delete_submenu()
def play_dvd(self, arg=None, menuw=None): self.schapter = None self.selected = None if len(self.files)>1: rc.add_app(self) self.pop = PopupBox(_('Choose disc (%i discs available).' % len(self.files) )) self.pop.show() else: self.selected = 1 self.chapter()
def create_thumbnail(self, arg=None, menuw=None): """ create a thumbnail as image icon """ import util.videothumb pop = PopupBox(text=_('Please wait....')) pop.show() util.videothumb.snapshot(self.filename) pop.destroy() if menuw.menustack[-1].selected != self: menuw.back_one_menu()
def start_external(self, arg=None, menuw=None): """start the external browser in the config file""" if (config.MPD_EXTERNAL_CLIENT is None or config.MPD_EXTERNAL_CLIENT == ''): return #if (config.MPD_EXTERNAL_CLIENT_ARGS is None or config.MPD_EXTERNAL_CLIENT_ARGS == ''): #args = None #else: #args = config.MPD_EXTERNAL_CLIENT_ARGS.split() try: #os,spawnv(os.P_NOWAIT, config.MPD_EXTERNAL_CLIENT, args) childapp.ChildApp(config.MPD_EXTERNAL_CLIENT) except: text = "Error starting external client\n%s\n%s" %sys.exc_info()[:2] pop = PopupBox(text) pop.show()
def create_podcast_submenu(self, arg=None, menuw=None, image=None): """ create the sub-menu for the podcast """ popup = PopupBox(text=_('Fetching podcast...')) popup.show() url = arg[1] p = podcast() p.open_rss(url) p.rss_title() p.rss_count() podcast_items = [] for pc_location in range(p.rss.count): p.rss_item(pc_location) if p.image != None: image = config.VPODCAST_DIR + '/' + arg[ 0] + '/' + p.title + '.jpg' self.download(p.image, image) else: image = None url = p.link name = p.title if url != 'ERROR': isYT = url.find('youtube.com') isMC = url.find('metacafe.com') if isYT == -1 and isMC == -1: file_ext = '.avi' else: file_ext = '.flv' filename = config.VPODCAST_DIR + '/' + arg[ 0] + '/' + name + file_ext podcast_items += [menu.MenuItem(_(p.title), \ action=VPVideoItem(filename, url, self), arg=None, image=image)] popup.destroy() if (len(podcast_items) == 0): podcast_items += [ menu.MenuItem(_('No Podcast locations found'), menwu.goto_prev_page, 0) ] podcast_sub_menu = menu.Menu(_('Video Podcasts'), podcast_items) rc.app(None) menuw.pushmenu(podcast_sub_menu) menuw.refresh()
def start_stream(self): if config.ZONEMINDER_SERVER_USE_SSL: self.conn = httplib.HTTPSConnection( config.ZONEMINDER_SERVER_HOST, port=int(config.ZONEMINDER_SERVER_PORT), key_file=config.ZONEMINDER_SERVER_SSL_KEY, cert_file=config.ZONEMINDER_SERVER_SSL_CERT, ) else: self.conn = httplib.HTTPConnection(config.ZONEMINDER_SERVER_HOST, port=int(config.ZONEMINDER_SERVER_PORT)) self.conn.connect() try: self.conn.putrequest('GET', self.build_request()) self.conn.endheaders() except socket.error, e: self.stream_file = None PopupBox(text=_('Error: %s') % e[1]).show() return
def play(self, arg=None, menuw=None): """ Play this Podcast """ download_failed = False self.download_url = self.item_url if not os.path.exists( self.filename) or os.path.getsize(self.filename) < 1024: try: background = BGDownload(self.download_url, self.filename, self.results) background.start() popup = PopupBox(text=_('Fetching "%s"...' % self.name)) popup.show() try: size = 0 for i in range(int(config.VPODCAST_BUFFERING_TIME)): if os.path.exists(self.filename): size = os.stat(self.filename)[stat.ST_SIZE] if size > config.VPODCAST_BUFFERING_SIZE: break time.sleep(1.0) else: if size < config.VPODCAST_BUFFERING_SIZE: download_failed = True finally: popup.destroy() if download_failed: AlertBox(text=_('Fetching "%s" failed\nNo data') % self.filename).show() return except youtube.DownloadError, why: AlertBox(text=_('Fetching "%(filename)s" failed:\n%(why)s') % ({ 'filename': self.filename, 'why': why })).show() return
def searchProg(self, find): if DEBUG: print String('SEARCHING FOR: %s' % find) pop = PopupBox(parent=self, text=_('Searching, please wait...')) pop.show() (result, matches) = record_client.findMatches(find) if result: if DEBUG: print 'FOUND: %s' % len(matches) i = 0 self.results.items = [] if len(matches) > self.num_shown_items: self.results.show_v_scrollbar = 1 else: self.results.show_v_scrollbar = 0 f = lambda a, b: cmp(a.start, b.start) matches.sort(f) for prog in matches: i += 1 self.results.add_item(text='%s %s: %s' % \ (time.strftime('%b %d %I:%M %p', time.localtime(prog.start)), tv_util.get_chan_displayname(prog.channel_id), prog.title), value=prog) space_left = self.num_shown_items - i if space_left > 0: for i in range(space_left): self.results.add_item(text=' ', value=0) pop.destroy()
self.conn.connect() try: self.conn.putrequest('GET', self.build_request()) self.conn.endheaders() except socket.error, e: self.stream_file = None PopupBox(text=_('Error: %s') % e[1]).show() return except httplib.HTTPException, e: self.stream_file = None PopupBox(text=_('Error: %s') % e.message).show() return response = self.conn.getresponse() if response.status != 200: self.stream_file = None PopupBox(text=_('HTTP Status %(status)d:%(reason)s') % ( {'status': response.status, 'reason': response.reason})).show() return ct = response.getheader('content-type') boundary = ct[ct.find('=') + 1:] self.stream_file = response.fp def get_picture(self): if self.stream_file is None: return None image_parser = ImageFile.Parser() self.stream_file.readline() # skip boundary self.stream_file.readline() # Content-type p = self.stream_file.readline() # Content-Length try: cl = int(p[p.find(' ') + 1:-2])
def actions(self): """ Menu actions for a video item. @returns: a list of possible actions on this item. """ if not self.possible_players: return [] # DVD actions if self.url.startswith('dvd://') and self.url[-1] == '/': if self.player_rating >= 20: items = [(self.play, _('Play DVD')), (self.dvd_vcd_title_menu, _('DVD title list'))] else: # this player is not able to deal with menus items = [(self.dvd_vcd_title_menu, _('DVD title list')), (self.play, _('Play default track'))] # VCD actions elif self.url == 'vcd://': if self.player_rating >= 20: items = [(self.play, _('Play VCD')), (self.dvd_vcd_title_menu, _('VCD title list'))] else: items = [(self.dvd_vcd_title_menu, _('VCD title list')), (self.play, _('Play default track'))] # youtube elif self.url.startswith('youtube:'): popup = PopupBox('Resolving YouTube video URL....') popup.show() if hasattr(config, 'YOUTUBE_USER'): cmdline = 'youtube-dl -g -u ' + config.YOUTUBE_USER + ' -p ' + config.YOUTUBE_PASSWORD + ' ' else: cmdline = 'youtube-dl -g ' pipe = os.popen(cmdline + self.url[8:]) self.url = pipe.readline() pipe.close() popup.hide() items = [(self.play, _('Play'))] else: items = [(self.play, _('Play'))] items.append((self.show_details, _('Full description'))) if self.network_play: items.append((self.play_max_cache, _('Play with maximum cache'))) items += configure.get_items(self) if self.variants and len(self.variants) > 1: items = [(self.show_variants, _('Show variants'))] + items if self.mode == 'file' and not self.variants and ( not self.image or not self.image.endswith('raw')): items.append((self.create_thumbnail, _('Create Thumbnail'), 'create_thumbnail')) return items
def move_tray(self, dir='toggle', notify=1): """ Move the tray. dir can be toggle/open/close """ if dir == 'toggle': if self.is_tray_open(): dir = 'close' else: dir = 'open' if dir == 'open': _debug_('Ejecting disc in drive %s' % self.drivename, 2) if notify: pop = PopupBox(text=_('Ejecting disc in drive %s') % self.drivename) pop.show() try: fd = os.open(self.devicename, os.O_RDONLY | os.O_NONBLOCK) if os.uname()[0] == 'FreeBSD': s = ioctl(fd, CDIOCEJECT, 0) else: s = ioctl(fd, CDROMEJECT) os.close(fd) except: try: traceback.print_exc() except IOError: # believe it or not, this sometimes causes an IOError if # you've got a music track playing in the background (detached) pass # maybe we need to close the fd if ioctl fails, maybe # open fails and there is no fd try: os.close(fd) except: pass self.tray_open = 1 if notify: pop.destroy() elif dir == 'close': _debug_('Inserting %s' % self.drivename, 2) if notify: pop = PopupBox(text=_('Reading disc in drive %s') % self.drivename) pop.show() # close the tray, identifymedia does the rest, # including refresh screen try: fd = os.open(self.devicename, os.O_RDONLY | os.O_NONBLOCK) if os.uname()[0] == 'FreeBSD': s = ioctl(fd, CDIOCCLOSE, 0) else: s = ioctl(fd, CDROMCLOSETRAY) os.close(fd) except: traceback.print_exc() # maybe we need to close the fd if ioctl fails, maybe # open fails and there is no fd try: os.close(fd) except: pass self.tray_open = 0 global im_thread if im_thread: im_thread.check_all() if notify: pop.destroy()
def create_podcast_submenu(self, arg=None, menuw=None, image=None): """ create the sub-menu for the podcast """ name, rss_url, feed_type = arg podcastdir = _name_to_filename(name) popup = PopupBox(text=_('Fetching podcast items...')) popup.show() try: p = Podcast(rss_url, feed_type) feed = p.feed() rss_title = p.rss_title() rss_stitle = _name_to_filename(rss_title) rss_description = p.rss_description() rss_imageurl = p.rss_image() if rss_imageurl: image_path = os.path.join(config.VPODCAST_DIR, podcastdir, 'cover.jpg') if not os.path.exists(image_path): self.download(rss_imageurl, image_path) else: image_path = None podcast_items = [] for item in feed.entries: try: item_link = p.rss_item_link(item) if item_link is None: raise PodcastException item_title = p.rss_item_title(item) item_stitle = _name_to_filename(item_title) item_image_url = p.rss_item_image(item) if item_image_url is None: item_image_url = rss_imageurl item_mimetype = p.rss_item_mimetype(item) item_updated = p.rss_item_updated(item) isYT = item_link.find('youtube.com') isMC = item_link.find('metacafe.com') item_ext = isYT >= 0 and config.YOUTUBE_FORMAT == '18' and 'mp4' \ or isYT >= 0 and config.YOUTUBE_FORMAT == '17' and '3gp' \ or isMC >= 0 and 'flv' \ or item_mimetype == 'video/mpeg' and 'mpeg' \ or item_mimetype == 'video/quicktime' and 'mov' \ or item_mimetype == 'video/x-la-asf' and 'asf' \ or item_mimetype == 'video/x-ms-asf' and 'asf' \ or item_mimetype == 'video/x-msvideo' and 'avi' \ or item_mimetype == 'video/x-m4v' and 'mp4' \ or item_mimetype == 'video/x-flv' and 'flv' \ or item_mimetype == 'application/x-shockwave-flash' and 'flv' \ or '' if not item_ext: item_ext = 'avi' results = [{ 'id': time.strftime('%s').decode('utf-8'), 'url': item_link.decode('utf-8'), 'uploader': u'', 'title': item_title.decode('utf-8'), 'stitle': item_stitle.decode('utf-8'), 'ext': item_ext.decode('utf-8'), }] item_path = os.path.join(config.VPODCAST_DIR, podcastdir, item_stitle + '.' + item_ext) if item_image_url is not None: image_path = os.path.join(config.VPODCAST_DIR, podcastdir, item_stitle + '.jpg') if not os.path.exists(image_path): self.download(item_image_url, image_path) podcast_items += [ menu.MenuItem(item_title, action=VPVideoItem( item_path, self, item_link, results), arg=None, image=image_path) ] if os.path.exists(item_path): if item_updated > os.stat(item_path)[stat.ST_MTIME]: os.remove(item_path) logger.info('%r removed updated %r > %r', item_path, item_updated, os.stat(item_path)[stat.ST_MTIME]) except PodcastException: pass if not podcast_items: podcast_items += [ menu.MenuItem(_('No Podcast locations found'), menuw.back_one_menu, 0) ] finally: popup.destroy() podcast_sub_menu = menu.Menu(_('Video Podcasts'), podcast_items) menuw.pushmenu(podcast_sub_menu) menuw.refresh()