def search(bot,mess,args): """search all paths for matches - search [include -exclude]""" if not args: args = ['/'] matches = [] # search all library paths dirs = [bot.lib_video_dir,bot.lib_video_file, bot.lib_audio_dir,bot.lib_audio_file] for d in dirs: matches.extend(util.matches(d,args)) if len(matches)==0: return 'Found 0 matches' # reply with matches based on max_matches setting if len(matches)>1: maxm = bot.opt('library.max_matches') if maxm<1 or len(matches)<=maxm: return 'Found '+str(len(matches))+' matches: '+util.list2str(matches) else: return 'Found '+str(len(matches))+' matches' return 'Found '+str(len(matches))+' match: '+str(matches[0])
def __errors(self,mess,args): """list errors - errors [*] [search1 search2]""" if not self.errors: return 'No errors' if not args: args = ['-startup'] if '*' in args: matches = self.errors else: matches = util.matches(self.errors,args,sort=False) if not matches: return 'No matching errors' return util.list2str(matches)
def _file(bot, args, dirs): """helper function for video() and audio()""" if not args: return 'You must specify a search term' # find matches and respond if len(matches)!=1 matches = util.matches(dirs, args) if len(matches) == 0: return 'Found 0 matches' if len(matches) > 1: maxm = bot.opt('library.max_matches') if maxm < 1 or len(matches) <= maxm: return 'Found ' + str( len(matches)) + ' matches: ' + util.list2str(matches) else: return 'Found ' + str(len(matches)) + ' matches' # translate library path if necessary match = bot.library_translate(matches[0]) # if there was 1 match, play the file, and check for not found error result = bot.xbmc('Player.Open', {'item': {'file': match}}) if 'error' in result.keys(): s = 'Unable to open: ' + match log.error(s) return s bot.run_cmd('fullscreen', ['on']) # clear last_played bot.last_played = None if bot.has_plugin('bookmark'): bot.last_resume = None return 'Playing "' + match + '"'
def _file(bot,args,dirs): """helper function for video() and audio()""" if not args: return 'You must specify a search term' # find matches and respond if len(matches)!=1 matches = util.matches(dirs,args) if len(matches)==0: return 'Found 0 matches' if len(matches)>1: maxm = bot.opt('library.max_matches') if maxm<1 or len(matches)<=maxm: return 'Found '+str(len(matches))+' matches: '+util.list2str(matches) else: return 'Found '+str(len(matches))+' matches' # translate library path if necessary match = bot.library_translate(matches[0]) # if there was 1 match, play the file, and check for not found error result = bot.xbmc('Player.Open',{'item':{'file':match}}) if 'error' in result.keys(): s = 'Unable to open: '+match log.error(s) return s bot.run_cmd('fullscreen',['on']) # clear last_played bot.last_played = None if bot.has_plugin('bookmark'): bot.last_resume = None return 'Playing "'+match+'"'
def _files(bot, args, dirs, pid): """helper function for videos() and audios()""" if not args: return 'You must specify a search term' cmd = ' '.join(args) # check for item# as last arg and @ for item match string last = args[-1] num = None search = None if last.startswith('@'): search = util.get_args(last[1:]) elif last.startswith('#'): try: num = int(last[1:]) - 1 except ValueError: pass # default is 0 if not specified if (search is not None) or (num is not None): args = args[:-1] if not search and not num: num = 0 # find matches and respond if len(matches)!=1 matches = util.matches(dirs, args) if len(matches) == 0: return 'Found 0 matches' # default to top dir if every match is a sub dir matches = util.reducetree(matches) if len(matches) > 1: maxm = bot.opt('library.max_matches') if maxm < 1 or len(matches) <= maxm: return 'Found ' + str( len(matches)) + ' matches: ' + util.list2str(matches) else: return 'Found ' + str(len(matches)) + ' matches' # translate library path if necessary match = bot.library_translate(matches[0]) # if there was 1 match, add the whole directory to a playlist # also check for an error opening the directory bot.xbmc('Playlist.Clear', {'playlistid': pid}) result = bot.xbmc('Playlist.Add', { 'playlistid': pid, 'item': { 'directory': match } }, timeout=60) if 'error' in result.keys(): s = 'Unable to open: ' + match log.error(s) return s msg = '' # find first item matching @search if search: params = {'playlistid': pid, 'properties': ['file']} items = bot.xbmc('Playlist.GetItems', params)['result']['items'] items = [x['file'] for x in items] item_matches = util.matches(items, search, False) if len(item_matches): num = items.index(item_matches[0]) msg += 'Found matching item "%s" --- ' % os.path.basename( item_matches[0]) else: num = 0 msg += 'No item matching "%s" --- ' % ' '.join(search) bot.xbmc('Player.Open', {'item': {'playlistid': pid, 'position': num}}) bot.run_cmd('fullscreen', ['on']) # set last_played for bookmarking bot.last_played = (pid, matches[0]) return msg + 'Playlist from "' + match + '" starting with #' + str(num + 1)
def bookmark(bot, mess, args): """manage bookmarks - bookmark [show|set|remove|update] [name]""" if not args: args = ['show'] if args[0] == 'set': # check if last_played is set if bot.last_played is None: return 'No active audios or videos playlist to bookmark' # check if anything is actually playing if bot.xbmc_active_player() is None: return 'Nothing playing' # check if a name was passed name = bot.last_played[1] args = args[1:] if len(args) > 0: name = str(args[0]) # get info for bookmark pid = bot.last_played[0] path = bot.last_played[1] params = {'playerid': pid, 'properties': ['position', 'time']} result = bot.xbmc('Player.GetProperties', params) pos = result['result']['position'] t = str(util.time2str(result['result']['time'])) add = time.time() result = bot.xbmc('Player.GetItem', { 'playerid': pid, 'properties': ['file'] }) fil = os.path.basename(str(result['result']['item']['file'])) # note that the position is stored 0-indexed bot.bm_store[name] = { 'path': path, 'add': add, 'time': t, 'pid': pid, 'pos': pos, 'file': fil } bm_update(bot, name, bot.bm_store[name]) return 'Bookmark added for "' + name + '" item ' + str(pos + 1) + ' at ' + t elif args[0] == 'remove': if len(args) == 1: return 'To remove all bookmarks use "bookmarks remove *"' if not bm_remove(bot, args[1]): return 'Bookmark "' + name + '" not found' return 'Removed bookmark "%s"' % args[1] elif args[0] == 'update': if not bot.last_resume: return 'No active bookmark' return bot.run_cmd('bookmark', ['set', bot.last_resume]) elif args[0] == 'show': args = args[1:] # actual code for show function because this is default behavior if len(bot.bm_store) == 0: return 'No bookmarks' # if no args are passed return all bookmark names matches = bot.bm_store.keys() if len(args) == 0 or args[0] == '': return 'There are ' + str( len(matches)) + ' bookmarks: ' + ', '.join(matches) # if a search term was passed find matches and display them search = ' '.join(args).lower() matches = [m for m in matches if search in m.lower()] entries = [] for m in matches: item = bot.bm_store[m] pos = item['pos'] t = item['time'] f = item['file'] entries.append('"%s" at item %s and time %s which is "%s"' % (m, pos + 1, t, f)) if len(entries) == 0: return 'Found 0 bookmarks' if len(entries) == 1: return 'Found 1 bookmark: ' + str(entries[0]) return 'Found ' + str( len(entries)) + ' bookmarks: ' + util.list2str(entries)
def config(bot,mess,args): """view and edit config - config (show|set|save|diff|reset|reload|default) (opt|*) [value]""" if (not bot.opt('general.config_rooms')) and mess.get_type()==Message.GROUP: return 'The config command is disabled in rooms' # default action is 'show' if not args or args[0] not in ('show','set','save','diff','reset','reload','default'): args.insert(0,'show') cmd = args[0] opt = '*' if len(args)>1 and args[1]!='': opt = args[1] if opt=='*' and cmd=='show': opts = bot.opt() for opt in opts: if opt.endswith('password'): opts[opt] = 'REDACTED' for proto in opts['rooms']: for room in opts['rooms'][proto]: if room['pass']: room['pass'] = '******' return util.list2str(['%s: %s' % (k,opts[k]) for k in sorted(opts.keys())]) if opt not in bot.opt() and opt!='*': return 'Invalid opt' if opt.endswith('password'): return 'You may not access passwords via chat!' # return the value of the specified opt if cmd=='show': val = bot.opt(opt) if opt=='rooms': for proto in val: for room in val[proto]: if room['pass']: room['pass'] = '******' return opt+' = '+str(val) # return opt values that have been edited but not saved if cmd=='diff': if len(bot.conf_diff)==0: return 'No differences between bot and config file' if opt in ('','*'): return str(bot.conf_diff.keys()) if opt not in bot.conf_diff: return 'Opt "'+opt+'" has not changed from config file' return ('Opt "%s" was "%s" but is now "%s"' % (opt,bot.conf_diff[opt][0],bot.opt[opt])) # some options don't make sense to edit in chat if opt in ('protocols','disable','enable','rename','cmd_dir','rooms'): return 'You may not edit that option via chat' # revert to original config if cmd=='reset': if len(bot.conf_diff)==0: return 'No config options to reset' if opt in ('','*'): opts = bot.conf_diff.keys() for opt in opts: bot.conf.opts[opt] = bot.conf_diff[opt][0] bot.conf_diff = {} return 'Reset opts: %s' % opts if opt not in bot.conf_diff: return 'Opt "%s" has not been changed' % opt bot.conf.opts[opt] = bot.conf_diff[opt][0] del bot.conf_diff[opt] return 'Reset "%s" to "%s"' % (opt,bot.opt(opt)) # set opt values in this bot instance only if cmd=='set': if opt=='*': return 'Invalid opt' old = bot.opt(opt) if bot.conf.set_opt(opt,args[2]): if old==bot.opt(opt): return 'Value unchanged' else: bot.conf_diff[opt] = (old,args[2]) return 'Set opt "'+opt+'" to "'+args[2]+'"' else: return 'Invalid value for opt "'+opt+'"' # reload the specified config option if cmd=='reload': if opt=='*': return 'Invalid opt' old = bot.opt(opt) result = bot.conf.reload_opt(opt) if not result: s = 'Success reloading "%s"; ' % (opt,) if old==bot.opt(opt): return s+'value unchanged' else: return s+'new value = "%s"' % (bot.opt(opt),) return ('Errors reloading "%s" so nothing changed: %s' % (opt,' '.join(['(%s) %s' % (l,m) for (l,m) in result]))) # set an option to its default value if cmd=='default': if opt=='*': return 'Invalid opt' old = bot.opt(opt) result = bot.conf.default_opt(opt) if not result: if old==bot.opt(opt): return 'Value unchanged' else: bot.conf_diff[opt] = (old,None) return 'New value = "%s"' % (bot.opt(opt),) return result # logic for 'save' command that also modifies the config file if len(args)>2: value = ' '.join(args[2:]) elif opt in bot.conf_diff: value = bot.conf_diff[opt][1] elif opt!='*': return 'Invalid value' name = (mess.get_user().get_real().get_base() if mess else 'SibylBot') # save all changed opts if opt=='*': for opt in bot.conf_diff: bot.conf.save_opt(opt,bot.conf_diff[opt][1],name) opts = bot.conf_diff.keys() bot.conf_diff = {} return 'Saved opts: '+str(opts) if bot.conf.save_opt(opt,value,name): if opt in bot.conf_diff: del bot.conf_diff[opt] return 'Saved opt "'+opt+'" to be "'+value+'"' return 'Invalid value for opt "'+opt+'"'
def bookmark(bot,mess,args): """manage bookmarks - bookmark [show|set|remove|update] [name]""" if not args: args = ['show'] if args[0]=='set': # check if last_played is set if bot.last_played is None: return 'No active audios or videos playlist to bookmark' # check if anything is actually playing if bot.xbmc_active_player() is None: return 'Nothing playing' # check if a name was passed name = bot.last_played[1] args = args[1:] if len(args)>0: name = str(args[0]) # get info for bookmark pid = bot.last_played[0] path = bot.last_played[1] params = {'playerid':pid,'properties':['position','time']} result = bot.xbmc('Player.GetProperties',params) pos = result['result']['position'] t = str(util.time2str(result['result']['time'])) add = time.time() result = bot.xbmc('Player.GetItem',{'playerid':pid,'properties':['file']}) fil = os.path.basename(str(result['result']['item']['file'])) # note that the position is stored 0-indexed bot.bm_store[name] = {'path':path,'add':add,'time':t, 'pid':pid,'pos':pos,'file':fil} bm_update(bot,name,bot.bm_store[name]) return 'Bookmark added for "'+name+'" item '+str(pos+1)+' at '+t elif args[0]=='remove': if len(args)==1: return 'To remove all bookmarks use "bookmarks remove *"' if not bm_remove(bot,args[1]): return 'Bookmark "'+name+'" not found' return 'Removed bookmark "%s"' % args[1] elif args[0]=='update': if not bot.last_resume: return 'No active bookmark' return bot.run_cmd('bookmark',['set',bot.last_resume]) elif args[0]=='show': args = args[1:] # actual code for show function because this is default behavior if len(bot.bm_store)==0: return 'No bookmarks' # if no args are passed return all bookmark names matches = bot.bm_store.keys() if len(args)==0 or args[0]=='': return 'There are '+str(len(matches))+' bookmarks: '+', '.join(matches) # if a search term was passed find matches and display them search = ' '.join(args).lower() matches = [m for m in matches if search in m.lower()] entries = [] for m in matches: item = bot.bm_store[m] pos = item['pos'] t = item['time'] f = item['file'] entries.append('"%s" at item %s and time %s which is "%s"' % (m,pos+1,t,f)) if len(entries)==0: return 'Found 0 bookmarks' if len(entries)==1: return 'Found 1 bookmark: '+str(entries[0]) return 'Found '+str(len(entries))+' bookmarks: '+util.list2str(entries)
def _files(bot,args,dirs,pid): """helper function for videos() and audios()""" if not args: return 'You must specify a search term' cmd = ' '.join(args) # check for item# as last arg and @ for item match string last = args[-1] num = None search = None if last.startswith('@'): search = util.get_args(last[1:]) elif last.startswith('#'): try: num = int(last[1:])-1 except ValueError: pass # default is 0 if not specified if (search is not None) or (num is not None): args = args[:-1] if not search and not num: num = 0 # find matches and respond if len(matches)!=1 matches = util.matches(dirs,args) if len(matches)==0: return 'Found 0 matches' # default to top dir if every match is a sub dir matches = util.reducetree(matches) if len(matches)>1: maxm = bot.opt('library.max_matches') if maxm<1 or len(matches)<=maxm: return 'Found '+str(len(matches))+' matches: '+util.list2str(matches) else: return 'Found '+str(len(matches))+' matches' # translate library path if necessary match = bot.library_translate(matches[0]) # if there was 1 match, add the whole directory to a playlist # also check for an error opening the directory bot.xbmc('Playlist.Clear',{'playlistid':pid}) result = bot.xbmc('Playlist.Add',{'playlistid':pid,'item': {'directory':match}},timeout=60) if 'error' in result.keys(): s = 'Unable to open: '+match log.error(s) return s msg = '' # find first item matching @search if search: params = {'playlistid':pid,'properties':['file']} items = bot.xbmc('Playlist.GetItems',params)['result']['items'] items = [x['file'] for x in items] item_matches = util.matches(items,search,False) if len(item_matches): num = items.index(item_matches[0]) msg += 'Found matching item "%s" --- ' % os.path.basename(item_matches[0]) else: num = 0 msg += 'No item matching "%s" --- ' % ' '.join(search) bot.xbmc('Player.Open',{'item':{'playlistid':pid,'position':num}}) bot.run_cmd('fullscreen',['on']) # set last_played for bookmarking bot.last_played = (pid,matches[0]) return msg+'Playlist from "'+match+'" starting with #'+str(num+1)