def SearchFolder(query=None, genre=[], country=[]): oc = ObjectContainer(title2=L('MAIN_SEARCH')) genres_title = 'GENRE' # TODO: localize countries_title = 'COUNTRY' # TODO: localize if Client.Product in DumbKeyboard.clients: genres_title = genres_title + ': %s' % ''.join('[%s]' % i for i in genre) countries_title = countries_title + ': %s' % ''.join('[%s]' % i for i in country) DumbKeyboard(PREFIX + '/search', oc, GetSearchResultFolder, genre=genre, country=country, dktitle=L('SEARCH_INPUT')) else: oc.add( InputDirectoryObject(key=Callback(GetSearchResultFolder, genre=genre, country=country), title=L('SEARCH_INPUT'))) if Prefs['api_key']: oc.add( DirectoryObject(key=Callback(GetSearchGenreFolder, query=query, genre=genre, country=country), title=L('SEARCH_PICK_GENRE'))) # TODO: localize oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, genre=genre, country=country), title=L('SEARCH_PICK_COUNTRY'))) # TODO: localize return oc
def GetSeasonFolder(show_name, season_id, check_updates=False): season = GetSeasonCacheOrCreate(show_name, season_id, as_string=False) PushToHistory(season) oc = ObjectContainer(title2=season['title']) if season['playlist']: oc.add( DirectoryObject(key=Callback(GetTranslatesFolder, show_name=show_name, season_id=season_id, check_updates=check_updates), title=L('SEASON_TRANSLATES_FOLDER'), thumb=season['thumb'], art=season['thumb'])) if 'other_season' in season: oc.add( DirectoryObject(key=Callback(GetOtherSeasonsFolder, show_name=show_name, season_id=season_id), title=L('SEASON_OTHER_SEASONS_FOLDER'), thumb=season['thumb'], art=season['thumb'])) # TODO: add check if exists in bookmarks and related stuff oc.add( DirectoryObject(key=Callback(Dummy), title=L('SEASON_ADD_BOOKMARK'), thumb=R('icon_add.png'), art=season['thumb'])) oc.add( DirectoryObject(key=Callback(Dummy), title=L('SEASON_DEL_BOOKMARK'), thumb=R('icon_del.png'), art=season['thumb'])) return oc
class ERROR(object): HEADER = 'ERROR' API_KEY_NO_PREMIUM = L('MSG_ERROR_API_KEY_NO_PREMIUM') IP_NO_PREMIUM = L('MSG_ERROR_IP_NO_PREMIUM') # NB: Further usage with F() and IP as arg # MISSING_API_KEY = L('MSG_ERROR_MISSING_API_KEY') # MISSING_CREDENTIALS = L('MSG_ERROR_MISSING_CREDENTIALS') NOT_IMPLEMENTED = L('MSG_ERROR_NOT_IMPLEMENTED') ONLY_NUMBERS_ALLOWED = L('MSG_ERROR_ONLY_NUMBERS_ALLOWED')
class INFO(object): HEADER = 'INFO' # API_KEY_UPDATED = L('MSG_INFO_API_KEY_UPDATED') API_KEY_VALID = L('MSG_INFO_API_KEY_VALID') # DISPLAY_API_KEYS = 'Prefs: {} || Web: {}' HISTORY_CLEARED = L('MSG_INFO_HISTORY_CLEARED') HISTORY_EMPTY = L('MSG_INFO_HISTORY_EMPTY') CACHE_CLEARED = L('MSG_INFO_CACHE_CLEARED') IP_ALLOWED = L('MSG_INFO_IP_ALLOWED') # NB: Further usage with F() and IP as arg
def receive(self, params, epoch): """ updates parameters from the server. does some validation, writes config file to disk. Returns True on success, False failure """ if epoch != self._epoch: return def same_type(a, b): ta = type(a) tb = type(b) if ta == int: ta = float if tb == int: tb = float return ta == tb if self.keys() != params.keys(): diff = self.keys() ^ params.keys() E("Mismatching params, %s" % str(diff)) return False for k, v in params.items(): if not same_type(v, self[k]): E("Bad type for %s" % k) return False dir = os.path.dirname(config.PARAMS_FILE) try: t = tempfile.NamedTemporaryFile( prefix='config', mode='w+t', # NamedTemporaryFile is binary by default dir=dir, delete=False) out = json.dumps(params, sort_keys=True, indent=4) + '\n' t.write(out) name = t.name t.close() os.rename(name, config.PARAMS_FILE) except Exception as e: EX("Problem: %s" % e) return False self.update(params) L("Received parameters") L(self.save_string()) return True
def GetTranslatesFolder(show_name, season_id, check_updates): season = GetSeasonCacheOrCreate(show_name, season_id, as_string=False) oc = ObjectContainer(title2=season['title'], content=ContainerContent.Seasons) for trans_index, translate in enumerate(season['playlist'].keys()): fake_url = make_fake_url(show_name=show_name, season_id=season_id, translate=translate) title = translate if check_updates: if season_id in Dict[UPDATES_CACHE_KEY]: update_messages = Dict[UPDATES_CACHE_KEY][season_id][ 'update_messages'] # NB: know why? because F**K YOU! that's why... NameError: global name 'any' is not defined if True in [ translate in message for message in update_messages ]: title = '(*) ' + translate oc.add( SeasonObject(key=Callback(GetEpisodesFolder, show_name=show_name, season_id=season_id, translate=translate), rating_key=fake_url, index=trans_index + 1, title=L(title), source_title=TITLE, thumb=season['thumb'], summary=season['summary'])) return oc
def suite(self, node): node = L(node) node.code = [] for child in node: if DEBUG: print(child) node.code += pushExpr(child) return node
def reload_signal(self, no_file=False): try: if not no_file: self.params.load() L("Reloaded.") self._wakeup.set() self._wakeup.clear() except Error as e: W("Problem reloading: %s" % str(e))
def run(self): if self.server.params.disabled: L("Fridge is disabled") while True: try: self.do() yield from self.server.sleep(config.FRIDGE_SLEEP) except Exception as e: EX("fridge failed")
def keyget_expr(self, node): node = L(node) node.type = "u" leftType = getTypeSignature(node[0]) if leftType != "u": abort("Cannot use non 'u' %s as index to keyget" % leftType, node[0]) node.code = pushExpr(node[0]) node.code += ["KEYGET"] return node
def arealen_expr(self, node): node = L(node) node.type = "u" leftType = getTypeSignature(node[0]) if leftType != "u": abort("Cannot use non 'u' %s as index to arealen" % leftType, node[0]) node.code = pushExpr(node[0]) node.code += ["AREALEN"] return node
def _do_load(self, f): try: u = utils.json_load_round_float(f.read()) except Exception as e: raise self.Error(e) for k in u: if k.startswith('_'): continue if k not in self: raise self.Error( "Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???'))) self.update(u) # new epoch, 120 random bits self._set_epoch(binascii.hexlify(os.urandom(15)).decode()) L("Loaded parameters") L(self.save_string())
def GetSearchCountryFolder(query=None, genre=[], country=[]): country_list = GetCountryCacheOrCreate() done_title = L('DONE') # TODO: localize if Client.Product in DumbKeyboard.clients: done_title = done_title + ': %s' % ''.join('[%s]' % c for c in country) oc = ObjectContainer( ) # TODO: think about how to deal with web player back navigation oc.add( DirectoryObject(key=Callback(SearchFolder, query=query, country=country, genre=genre), title=done_title)) if country: oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, country=country[:-1], genre=genre), title=L('DELETE_LAST'))) # TODO: localize oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, country=[], genre=genre), title=L('DELETE_ALL'))) # TODO: localize for item in country_list.values(): if item not in genre: oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, country=country + [item], genre=genre), title=item)) else: oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, country=country, genre=genre), title=u'✓ %s' % item)) return oc
def funcall(self, node): if DEBUG: print("()", node) node = L(node) otherfuncname = node[0].children[0].value otherfunc = funcs[otherfuncname] node.type = otherfunc["out"] node.code = [] # CANNOT CHANGE STACK FRAME BOUNDARY; THEN pushExpr, because they depend on unmodified AREALEN! # Allocate parameter space if len(node) > 1: intypes = otherfunc["in"] for i, param in enumerate(node[1].children): paramsig = getTypeSignature(param) if compareTypes(intypes[i][0], paramsig): abort( "Wrong types on function call, expected %s, got %s" % (intypes[i], paramsig)) node.code += pushExpr(param) node.code += asm("alloc(%i,%i)" % (MEM_STACK, inTypLen(otherfunc["in"]))) for i, param in enumerate(node[1].children[::-1]): paramsig = getTypeSignature(param) for index in range(types[paramsig]["len"]): # Write args to end of current stack frame node.code += asm("push(%i,sub(arealen(%i),%i))" % (MEM_STACK, MEM_STACK, index + i + 1)) node.code += ["ROT2"] node.code += ["WRITE"] # Push return address # TODO do this dynamically with IP # XXX this doesn't work anymore anyway #label = generator.label() #node.code += ["PUSH %s" % label] node.code += ["PUSH 4", "HEADER"] node.code += ["PUSH 8", "ADD"] #XXX must add a few for this to work # XXX PUSH FUNC___!"§"otherfuncname (collisions) #node.code += ["PUSH %s" % otherfuncname, "JUMP"] node.code += asm("keyget(%i)" % nametoint(otherfuncname)) node.code += ["JUMP"] #node.code += [label+":"] # TODO now handle returned values! # Deallocate return values #XXX node.code += asm("dealloc(%i,%i)" % (MEM_STACK, typLen(otherfunc["out"]))) # Deallocate parameters node.code += asm("dealloc(%i,%i)" % (MEM_STACK, inTypLen(otherfunc["in"]))) return node
def MainMenu(): oc = ObjectContainer() oc.add( DirectoryObject(key=Callback(UpdatesFolder), title=L('MAIN_LATEST_UPDATES'), thumb=R('icon_updates.png'))) oc.add( DirectoryObject(key=Callback(Dummy), title=L('MAIN_BOOKMARKS'), thumb=R('icon_bookmarks.png'))) oc.add( DirectoryObject(key=Callback(SearchFolder), title=L('MAIN_SEARCH'), thumb=R('icon_search.png'))) oc.add( DirectoryObject(key=Callback(HistoryFolder), title=L('MAIN_HISTORY'), thumb=R('icon_history.png'))) oc.add( DirectoryObject(key=Callback(Dummy), title=L('MAIN_FILTER'), thumb=R('icon_filter.png'))) oc.add( DirectoryObject(key=Callback(ToolsFolder), title=L('MAIN_TOOLS'), thumb=R('icon_tools.png'))) return oc
def ToolsFolder(): # TODO: move here all ip/api cheks and other usefull stuff oc = ObjectContainer(title2=L('MAIN_TOOLS')) if Prefs['dev_mode']: oc.add( DirectoryObject(key=Callback(ToolDebug), title=L('TOOLS_DEBUG'), thumb=R('icon_debug.png'))) oc.add( DirectoryObject(key=Callback(ToolClearCache), title=L('TOOLS_CLEAR_CACHE'), thumb=R('icon_clear.png'))) if Prefs['username'] and Prefs['password']: oc.add( DirectoryObject(key=Callback(ToolCheckApiKey), title=L('TOOLS_CHECK_API_KEY'), thumb=R('icon_key.png'))) if Prefs['api_key'] and (Prefs['username'] and Prefs['password']): oc.add( DirectoryObject(key=Callback(ToolCheckIp), title=L('TOOLS_CHECK_IP'), thumb=R('icon_ip.png'))) return oc
def doreturn(self, node): node = L(node) node.code = [] retType = getTypeSignature(node[0]) if compareTypes(retType, func["out"]): abort( "Return type doesn't match function signature\nExpected %s, got %s" % (func["out"], retType)) node.type = retType node.code += pushExpr(node[0]) node.code += coda() return node
def while_stmt(self, node): node = L(node) start_label = generator.label() end_label = generator.label() node.code = [start_label + ':'] if len(node) == 2: node.code += pushExpr(node[0]) node.code += ['PUSHR %s' % end_label] node.code += ['JZR'] node.code += node[1].code else: node.code += node[0].code node.code += ['PUSHR %s' % start_label] node.code += ['JUMPR'] node.code += [end_label + ':'] return node
def string(self, node): # TODO allocate on heap node = L(node) node.type = "vector" arr = node[0].value[1:-1] new = stringToWords(arr) if DEBUG: print("String", new) node.code = [] node.code += asm("alloc(%i,%i)" % (MEM_HEAP, len(new))) for i, c in enumerate(new): node.code += asm("write(%i,sub(arealen(%i),%i),%i)" % (MEM_HEAP, MEM_HEAP, len(new) - i, c)) node.code += asm("push(sub(arealen(%i),%i),%i)" % (MEM_HEAP, len(new), len(new))) return node
def arith_expr(self, node): node = L(node) node.code = pushExpr(node[0]) for i in range((len(node) - 1) // 2): nextop = node[1 + i * 2 + 1] leftType, rightType = ensurePrimitive(node[1].value, node[0], nextop) node.code += pushExpr(nextop) node.code += [ '%s' % { '+': 'ADD', '-': 'SUB', '~': 'NOT' }[node[1 + i * 2].value] ] node.type = leftType return node
def term(self, node): node = L(node) node.code = pushExpr(node[0]) for i in range((len(node) - 1) // 2): nextop = node[1 + i * 2 + 1] leftType, rightType = ensurePrimitive(node[1].value, node[0], nextop) node.code += pushExpr(nextop) node.code += [ '%s' % { '*': 'MUL', '/': 'DIV', '%': 'MOD' }[node[1 + i * 2].value] ] node.type = leftType return node
def attr(self, node): if not hasType(node[0].value): abort("Name %s has no type" % node[0].value, node[0]) typ = getTypeSignature(node[0]) #XXX if not typ in types: abort("%s's type is not a struct" % node[0].value, node[0]) subtype = getSubtype(typ, node[1].value) if subtype is None: abort( "%s.'%s' is not a valid attribute" % (node[0].value, node[1].value), node[1]) node = L(node) node.code = [] for index in range(subtype["len"]): node.code += getAbsoluteOffset(node[0].value, subtype["offset"] + index) node.code += ["READ"] node.type = subtype["type"] return node
def if_stmt(self, node): node = L(node) node.code = [] node.code += pushExpr(node[0]) end_label = generator.label() if len(node) == 3: else_label = generator.label() node.code += ['PUSHR %s' % else_label] else: node.code += ['PUSHR %s' % end_label] node.code += ['JZR'] node.code += node[1].code if len(node) == 3: node.code += ['PUSHR %s' % end_label] node.code += ['JUMPR'] node.code += [else_label + ':'] node += node[2].code node.code += [end_label + ':'] return node
def getitem(self, node): node = L(node) leftType = getTypeSignature(node[0]) rightType = getTypeSignature(node[1]) if not leftType.startswith("*"): abort( "Cannot index into non-pointer type %s of '%s'" % (leftType, node[0]), node) if rightType != "u": abort( "Cannot index into pointer using non-u type %s of %s" % (rightType, node[1]), node) if DEBUG: print("[]", leftType, rightType) node.code = [] node.code += ["PUSH 0"] + pushExpr(node[0]) + pushExpr( node[1]) + ["ADD", "READ"] node.type = leftType[1:] return node
def read(self, node): node = L(node) node.code = [] leftType = getTypeSignature(node[0]) if leftType != "u": abort("Cannot use non 'u' %s as index" % leftType, node[0]) if len(node) == 1: node.code += ["PUSH 0"] node.code += pushExpr(node[0]) else: rightType = getTypeSignature(node[1]) if rightType != "u": abort("Cannot use non 'u' %s as index" % rightType, node[1]) node.code += pushExpr(node[0]) node.code += pushExpr(node[1]) node.code += ["READ"] node.type = "u" return node
def alloc_stmt(self, node): node = L(node) node.code = [] leftType = getTypeSignature(node[0]) if leftType != "u": abort("Cannot use non 'u' %s as index to alloc" % leftType, node[0]) if len(node) == 1: node.code += ["PUSH 0"] node.code += pushExpr(node[0]) else: rightType = getTypeSignature(node[1]) if rightType != "u": abort("Cannot use non 'u' %s as size to alloc" % rightType, node[1]) node.code += pushExpr(node[0]) node.code += pushExpr(node[1]) node.code += ["ALLOC"] return node
def assign(self, node): if DEBUG: print("=", node) rightType = getTypeSignature(node[1]) if DEBUG: print("=", rightType) if hasType(node[0].value): leftType = getTypeSignature(node[0].value) if compareTypes(leftType, rightType): abort( "Assignment type mismatch %s = %s" % (leftType, rightType), node) else: #print("New var", node[0].value) if isinstance(rightType, list) and len(rightType) > 1: raise NotImplemented("nope") elif len(rightType) == 0: abort("Cannot assign from () to something", node[0]) var[node[0].value] = {"type": rightType} #node.code += [["_RESERVE", node[0].value]] #print(types,var[node[0].value]) node = L(node) node.code = [] """ node.code += getAbsoluteOffset(node[0].value) node.code += getAbsoluteOffset(node[1].value) node.code += rightType["len"] node.code += "MEMCOPY" """ node.code += pushExpr(node[1]) for index in range(types[rightType]["len"] - 1, -1, -1): # composite assignment somewhere else! node.code += getAbsoluteOffset(node[0].value, index) node.code += ["ROT2"] node.code += ["WRITE"] return node
def write_stmt(self, node): node = L(node) node.code = [] leftType = getTypeSignature(node[0]) if leftType != "u": abort("Cannot use non 'u' %s as index" % leftType, node[0]) if len(node) == 2: abort("disabled write", node) node.code += ["PUSH 0"] node.code += pushExpr(node[0]) else: middleType = getTypeSignature(node[1]) if middleType != "u": abort("Cannot use non 'u' %s as index" % middleType, node[1]) node.code += pushExpr(node[0]) node.code += pushExpr(node[1]) node.code += pushExpr(node[-1]) node.code += ["WRITE"] return node
def comparison(self, node): node = L(node) if DEBUG: print("cmp", node) leftType, rightType = ensurePrimitive("cmp", node[0], node[2]) node.code = [] cmp = node[1].value if cmp in ["!=", "=="]: node.code += pushExpr(node[0]) node.code += pushExpr(node[2]) node.code += ["SUB"] if cmp == "==": node.code += ["NOT"] elif cmp == "<": node.code += pushExpr(node[0]) node.code += pushExpr(node[2]) node.code += ["CMP"] node.code += ["NOT"] elif cmp == ">=": node.code += pushExpr(node[2]) node.code += pushExpr(node[0]) node.code += ["CMP"] elif cmp == ">": node.code += pushExpr(node[0]) node.code += pushExpr(node[2]) node.code += ["CMP"] node.code += ["NOT"] elif cmp == "<=": node.code += pushExpr(node[2]) node.code += pushExpr(node[0]) node.code += ["CMP"] else: abort("Unknown comparison operator %s" % node[1].value, node[1]) #print("COMPARISON", cmp, node.code) node.type = "u" return node
def funcbody(self, node): node = L(node) node.code = [] # Allocate stack frame #print("RET", func["out"]) # Calculate stack frame size # + return address + stack frame framesize = varLen() + 2 #XXX retlen + # Allocate stack frame node.code += asm("alloc(%i,%i)" % (MEM_STACK, framesize)) # Write current stack frame address to second last item of stack frame node.code += asm("write(%i,sub(arealen(%i),2),read(%i,0))" % (MEM_STACK, MEM_STACK, MEM_STACK)) # Write return address from stack to end of stack frame node.code += asm("write(%i,sub(arealen(%i),1),rot2)" % (MEM_STACK, MEM_STACK)) # Write stack frame address to 0:0 node.code += asm("write(%i,0,sub(arealen(%i), %i))" % (MEM_STACK, MEM_STACK, framesize)) # Put last index of area on stack #node.code += ["PUSH 0"] #node.code += ["PUSH 0", "arealen", "PUSH 1", "SUB"] # Save return address in frame #node.code += ["ROT2", "WRITE"] if DEBUG: print(funcname, node[0]) node.code += node[0].code node.code += ecoda() code = "\n".join(node.code) #XXX check for jump at end of function! return code