def prep(self, duration, rest=5, read_delay=5): """Set the exercise durations. Arguments: duration - time to exercise for in seconds rest - time afterwards to allow the athlete to rest read_delay - time before to read and understand the instructions Throws: Exception for invalid input """ if duration < 0: raise exceptions.ParseError( "Not a time traveller: Can't exercise for {0} second(s)". format(repr(duration))) if rest < 0: raise exceptions.ParseError( "Not a time traveller: Can't rest for {0} second(s)".format( repr(rest))) if read_delay < 0: raise exceptions.ParseError( "Not a time traveller: Can't let the user read for {0} second(s)" .format(repr(read_delay))) self.reading = countdown.Countdown(read_delay, self.session_start) self.countdown = countdown.Countdown(duration, self.finish, self.tick) self.duration = duration self.rest = rest self.read_delay = read_delay
def __add_exercise(self, routine, args): """ Add a named exercise. Parameters: routine The routine object to add the exercise to the instructions before beginning args The arguments taken from a routine file including the exercise id, duration, rest and read delay Throws: DefaultError If either or both of rest and read_delay isn't specified, and neither have they been defined as defaults ParseError If any of the parameters which should be ints aren't """ ex_id = args[0] vals = [self.__to_int(args[1], 'duration')] parms = ('rest', 'read_delay') # Routine.add_exercise parameter order for i in range(len(parms)): if len(args) > i + 2: val = self.__to_int(args[i + 2], self.desc[parms[i]]) else: val = self.settings[parms[i]] if val == None: raise exceptions.DefaultError("""If a default {0} hasn't been set, you must supply an explicit one""".format(parms[i])) vals.append(val) if len(args) > len(parms) + 2: raise exceptions.ParseError( "Unrecognised exercise in routine file (too many arguments)") routine.add_exercise(ex_id, *vals)
def yaml_parse_as_scalar(self, entry): if hasattr(entry, 'keys'): # Dictionary-like raise exceptions.ParseError("Expected scalar; got " + str(entry)) elif hasattr(entry, 'append'): # Sequence type return "\n".join(entry) else: return entry
def new_task(message: Message): parsed = message.text.split(maxsplit=1) if len(parsed) == 1: bot.send_message(message.chat.id, 'Write a new task...') bot.register_next_step_handler(message, _adding_task_next) elif len(parsed) == 2: db.insert_task(parsed[1]) bot.send_message(message.chat.id, 'Great, your task is written!') else: raise ex.ParseError()
def set_default(self, setting, value_str): """ Raises ParseError if value_str isn't a string representing an integer """ if not setting in self.desc or self.desc[setting].endswith('()'): raise exceptions.ParseError("{0} is not a valid setting".format( repr(setting))) else: self.settings[setting] = self.__to_int(value_str, self.desc[setting])
def __set_setting(self, setting, value, routine): if not setting in self.desc: raise exceptions.ParseError("Unrecognised setting {0}".format( repr(setting))) if self.desc[setting].endswith('()'): function = self.desc[setting][:-2] # Call function(value) routine.__getattribute__(function)(value) else: self.set_default(setting, value)
def parse(self, yamlfile): self.exercises = {} for ex_id in yamlfile: if not self.valid_id(ex_id): raise exceptions.ParseError( "Exercise id '{0}' is not valid; ".format(ex_id) + "Exercise ids must not contain newlines." + "and must not begin with whitespace") ex = yamlfile[ex_id] try: name = ex.get('Name') except AttributeError: raise exceptions.ParseError("Badly formed exercise: " + ex_id) desc = ex.get('Description') tips = ex.get('Tips') name = self.yaml_parse_as_scalar(name) desc = self.yaml_parse_as_scalar(desc) self.exercises[ex_id] = [name, desc, tips]
def __to_int(self, string, meaning): """ Either returns the string as an integer, or raises ParserError using 'meaning' as part of the message """ try: return int(string, base=10) except (TypeError, ValueError) as e: raise exceptions.ParseError( "{0} is not a valid {1}: not a valid integer".format( repr(string), meaning))
def load_io(self, iostream): """ Load exercises from a stream. Raises ParseError on a parse failure """ try: yamlfile = yaml.safe_load(iostream) except yaml.error.YAMLError as e: raise exceptions.ParseError(e) self.db = self.parse(yamlfile) self.filename = "StreamIO"
def delete(self, filename): """Delete a file from Parse.com""" url = "%s/%s" % (self.settings["parse"]["rest_file_url"], filename) headers = { 'X-Parse-Application-Id': self.settings["parse"]["application_id"], 'X-Parse-Master-Key': self.settings["parse"]["master_key"] } r = requests.delete(url, headers=headers) if r.status_code != 200: raise exceptions.ParseError("Delete failed: %s" % r.status_code)
def get_user(api, ptt_id: str) -> data_type.UserInfo: cmd_list = list() cmd_list.append(command.GoMainMenu) cmd_list.append('T') cmd_list.append(command.Enter) cmd_list.append('Q') cmd_list.append(command.Enter) cmd_list.append(ptt_id) cmd_list.append(command.Enter) cmd = ''.join(cmd_list) target_list = [ connect_core.TargetUnit( [ i18n.GetUser, i18n.Success, ], screens.Target.AnyKey, break_detect=True), connect_core.TargetUnit( [ i18n.GetUser, i18n.Fail, ], screens.Target.InTalk, break_detect=True), ] index = api.connect_core.send( cmd, target_list) ori_screen = api.connect_core.get_screen_queue()[-1] if index == 1: raise exceptions.NoSuchUser(ptt_id) # PTT1 # 《ID暱稱》CodingMan (專業程式 BUG 製造機)《經濟狀況》小康 ($73866) # 《登入次數》1118 次 (同天內只計一次) 《有效文章》15 篇 (退:0) # 《目前動態》閱讀文章 《私人信箱》最近無新信件 # 《上次上站》10/06/2019 17:29:49 Sun 《上次故鄉》111.251.231.184 # 《 五子棋 》 0 勝 0 敗 0 和 《象棋戰績》 0 勝 0 敗 0 和 # https://github.com/Truth0906/PTTLibrary # 強大的 PTT 函式庫 # 提供您 快速 穩定 完整 的 PTT API # 提供專業的 PTT 機器人諮詢服務 # PTT2 # 《ID暱稱》CodingMan (專業程式 BUG 製造機)《經濟狀況》家徒四壁 ($0) # 《登入次數》8 次 (同天內只計一次) 《有效文章》0 篇 # 《目前動態》看板列表 《私人信箱》最近無新信件 # 《上次上站》10/06/2019 17:27:55 Sun 《上次故鄉》111.251.231.184 # 《 五子棋 》 0 勝 0 敗 0 和 《象棋戰績》 0 勝 0 敗 0 和 # 《個人名片》CodingMan 目前沒有名片 # print(ori_screen) # data = lib_util.get_sub_string_list(ori_screen, '》', ['《', '\n']) data = parse_user_page(ori_screen) if len(data) < 10: print('\n'.join(data)) print(len(data)) raise exceptions.ParseError(ori_screen) # print('\n=> '.join(data)) ptt_id = data[0] money = data[1] login_time = int(data[2]) temp = re.findall(r'\d+', data[3]) legal_post = int(temp[0]) # PTT2 沒有退文 if api.config.host == data_type.host_type.PTT1: illegal_post = int(temp[1]) else: illegal_post = -1 status = data[4] mail = data[5] last_login = data[6] last_ip = data[7] five_chess = data[8] chess = data[9] signature_file = '\n'.join(ori_screen.split('\n')[6:-1]) log.show_value(api.config, log.level.DEBUG, 'ptt_id', ptt_id) log.show_value(api.config, log.level.DEBUG, 'money', money) log.show_value(api.config, log.level.DEBUG, 'login_time', login_time) log.show_value(api.config, log.level.DEBUG, 'legal_post', legal_post) log.show_value(api.config, log.level.DEBUG, 'illegal_post', illegal_post) log.show_value(api.config, log.level.DEBUG, 'status', status) log.show_value(api.config, log.level.DEBUG, 'mail', mail) log.show_value(api.config, log.level.DEBUG, 'last_login', last_login) log.show_value(api.config, log.level.DEBUG, 'last_ip', last_ip) log.show_value(api.config, log.level.DEBUG, 'five_chess', five_chess) log.show_value(api.config, log.level.DEBUG, 'chess', chess) log.show_value(api.config, log.level.DEBUG, 'signature_file', signature_file) user = data_type.UserInfo( ptt_id, money, login_time, legal_post, illegal_post, status, mail, last_login, last_ip, five_chess, chess, signature_file) return user
def load_io_into(self, routine, file_io): """ Load a specification from a file object into a pre-prepared Routine object. The data will be loaded using any pre-existing default settings """ in_setting = False for line in file_io.readlines(): # Eat the indent - not important to this file format line = line.strip() if len(line) == 0: if in_setting: # Ended a multi-line setting in_setting = False try: self.__set_setting(setting, value, routine) except exceptions.ParseError as e: raise exceptions.ParseError("{0}\n Line:{1}".format( str(e), setting_line)) continue if line[0] == "#": # Comment continue if in_setting: if len(value) > 0: value += ' ' value += line continue setline = self.__unescape(line, '=') if '\x0b' in setline: if setline.endswith('\x0b'): # Multi-line setting setting = setline[:setline.index('\x0b')].lower().strip() if not setting in self.desc: raise exceptions.ParseError( "Unrecognised setting {0}\n Line:{1}".format( repr(setting), line)) in_setting = True setting_line = line value = "" else: # Single line setting (setting, value) = setline.split('\x0b') setting = setting.lower().strip() try: self.__set_setting(setting, value, routine) except exceptions.ParseError as e: raise exceptions.ParseError("{0}\n Line:{1}".format( str(e), line)) continue exline = self.__unescape(line, ',') if '\x0b' in exline: # Exercise (args) = exline.split('\x0b') try: self.__add_exercise(routine, args) except exceptions.ParseError as e: raise exceptions.ParseError("{0}:\n {1}".format( str(e), line)) else: raise exceptions.ParseError( "Unrecognised line in routine file: {0}".format(line)) return routine
def parse_beer(beer_html): ''' saves less information than the whole webpage returns image location, name (name is an unpleasant combination with the brewer) location style brewer ABV IBU text skipping the following parseable data: estimated calories rating information served in glass shapes availability tags reviews similar ''' beer_soup = BeautifulSoup(beer_html, html_parser) wrapping_div = beer_soup.find(class_='p-4') if wrapping_div == None: raise exceptions.ParseError("no wrapping div") try: info_and_text_divs = wrapping_div.find_all('div', recursive=False) info_div = info_and_text_divs[0] text_div = info_and_text_divs[1] try: aka_text = text_div.span.span.text.strip() if aka_text == 'Also Known As': alias = text_div.a.text return ({'type': 'aka'}) else: print('aka_text: "' + aka_text + '"') raise exceptions.ParseError("looks like AKA but doesn't parse") except: pass broken_info_div = info_div.div.find_all('div', recursive=False) name_and_loc_divs = broken_info_div[0].div.find_all('div', recursive=False) name_div = name_and_loc_divs[0] loc_div = name_and_loc_divs[1] other_info_div = broken_info_div[1] broken_other_divs = other_info_div.find_all('div', recursive=False) style_brewer_div = broken_other_divs[0] abv_ibu_div = broken_other_divs[1] style_brewer_divs = style_brewer_div.find_all('div', recursive=False) style_div = style_brewer_divs[0] brewer_div = style_brewer_divs[1] abv_ibu_divs = abv_ibu_div.find_all('div', recursive=False) abv_div = abv_ibu_divs[0] ibu_div = abv_ibu_divs[1] beer_info = {} beer_info['name'] = name_div.text beer_info['location'] = loc_div.text beer_info['brewer'] = brewer_div.a.text beer_info['image_url'] = info_div.img['src'] beer_info['style'] = style_div.a.text abv_string = abv_div.div.text beer_info['abv'] = parse_abv(abv_string) ibu_string = ibu_div.div.text beer_info['ibu'] = parse_ibu(ibu_string) beer_info['text'] = text_div.text if beer_info['text'] and beer_info['text'][-1] == '…': description_count = beer_html.count('"description"') if description_count == 1: description_location = beer_html.index('"description"') full_text_raw = beer_html[description_location + 16:].split('",\n')[0] beer_info['full_text'] = codecs.decode(full_text_raw, 'unicode-escape') elif description_count > 1: raise exceptions.ParseError('too many descriptions') else: raise exceptions.NoFullDescription('not enough descriptions', beer_info['name']) return (beer_info) except (exceptions.ParseError, exceptions.NoFullDescription): raise except: print('wrapping div: ') print(wrapping_div.prettify()) print() raise