def newsfooter(page, category): newsconf = _config['pages']['news'] nextpage = ttxutils.nextpage(page.page) lastpage = ttxutils.nextpage(newsconf['main']['last']) lastregpage = ttxutils.nextpage(newsconf['regional']['last']) if nextpage in [lastpage, lastregpage]: fastext = (red() + 'In Depth ' + green() + 'News Indx' + yellow() + 'Headlines' + cyan() + 'Main Menu') else: fastext = (red() + 'Next News' + green() + 'News Indx' + yellow() + 'Headlines' + cyan() + 'Main Menu') if category: lines = [ '€T€]€GREGIONAL €CHeadlines€G160€CSport €G390', '€D€]€GNATIONAL€C Main menu€G100€CWeather€G 400', fastext ] else: lines = [ '€D€]€CHome news digest€G141€CWorld digest€G142', '€D€]€CNews Index€G102€CFlash€G150€CRegional€G160', fastext ] line = 22 for l in lines: page.addline(line, ttxutils.decode(l)) line += 1 if nextpage > newsconf['regional']['headlines']: page.addfasttext(nextpage, newsconf['regional']['headlines'], newsconf['main']['headlines'], 0x100, 0x8ff, 0x199) else: page.addfasttext(nextpage, newsconf['main']['index'], newsconf['main']['headlines'], 0x100, 0x8ff, 0x199)
def news_scitech(entries, conf): pagenum = conf['carousel'] page = ttxpage.TeletextPage(f"Sci-Tech {pagenum:03x}", pagenum, time=15) subpage = 1 length = len(entries) for contents in entries: page.header(pagenum, subpage, status=0xc000) newsheaders.newsheader(page, 'scitechhead') line = 4 line += page.wrapline(line, 21, page.fixup(contents['title']), ttxcolour.yellow()) colour = ' ' for para in contents['text']: if line <= 21: added = page.wrapline(line, 22, page.fixup(para), colour) if added: line += added + 1 colour = ttxcolour.cyan() index = f"{subpage}/{length} " footers = [ f"{index:>40}" '€D€]€CHeadlines €G101€CIndex€G102€CSport €G300', '€D€]€CFront Page€G100€CTV €G600€CWeather€G400', '€ALocalNews€BHeadlines€CNews Indx€FMain Menu' ] line = 22 for l in footers: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(0x160, 0x101, 0x102, 0x100, 0x8ff, 0x100) subpage += 1 page.save()
def news_summary(entries, conf): summarynum = conf['summary'] page = ttxpage.TeletextPage(f"News Summary {summarynum:03x}", summarynum, time=15) offset = 0 pagenum = conf['first'] for subpage in range(2): page.header(summarynum, subpage + 1, status=0xc000) newsheaders.newsheader(page, 'summary') index = f"{subpage + 1}/2 " page.addline(4, f"{index:>40}") line = 5 while offset < len(entries): contents = entries[offset] para = contents['text'][0] lines = page.wrapline(line, 21, page.fixup(para), ttxcolour.cyan()) if lines: line += lines page.addline(line, f" See {pagenum:03x}") line += 2 pagenum = ttxutils.nextpage(pagenum) offset += 1 else: break newsheaders.newssummaryfooter(page) page.save()
def news_index(entries, conf): pagenum = conf['index'] page = ttxpage.TeletextPage("News Index {:03x}".format(pagenum), pagenum, time=15) toptitles = [] subtitles = [] index = 0 nextpage = conf['first'] for contents in entries: if index < 3: textcolour = ttxcolour.cyan() else: textcolour = ttxcolour.white() headline = page.truncate(contents['short_title'], 35, ' ') if index <= 11: toptitles.append("{}{:<35}{}{:03x}".format(textcolour, headline, ttxcolour.yellow(), nextpage)) else: subtitles.append("{}{:<35}{}{:03x}".format(textcolour, headline, ttxcolour.yellow(), nextpage)) index += 1 nextpage = ttxutils.nextpage(nextpage) maxsubpage = int((len(subtitles) + 2) / 3) for subpage in range(maxsubpage): line = 4 page.header(pagenum, subpage + 1, status=0xc000) category = newsheaders.newsheader(page, 'index') for t in toptitles: if line == 10: line += 1 page.addline(line, t) line += 1 page.addline( 17, "{}Other News {}/{}".format(ttxcolour.yellow(), subpage + 1, maxsubpage)) line = 18 offset = subpage * 3 subset = subtitles[offset:offset + 3] for t in subset: page.addline(line, t) line += 1 newsheaders.newsindexfooter(page) if offset + 3 > len(subtitles): break page.save()
def newsheadlinesfooter(page, category): if category: lines = [ '€T€]€GREGIONAL €CHeadlines€G160€CSport €G390', '€D€]€GNATIONAL€C Main menu€G100€CWeather€G 400', red() + 'Next Page' + green() + 'Top Story' + yellow() + 'Reg Sport' + cyan() + 'Main Menu' ] else: lines = [ '€W€]€DGet BBC News on your mobile phone 153', '€D€]€CCATCH UP WITH REGIONAL NEWS €G160', red() + 'News Index' + green() + 'Top Story' + yellow() + 'TV/Radio' + cyan() + 'Main Menu' ] line = 22 for l in lines: page.addline(line, ttxutils.decode(l)) line += 1 if category: page.addfasttext(0x161, 0x161, 0x390, 0x100, 0x8ff, 0x199) else: page.addfasttext(0x102, 0x104, 0x600, 0x100, 0x8ff, 0x199)
def news_page(category : str, pages : dict, number : int, contents : dict, header : List[str], footer : List[str], fasttext : Optional[List[int]] = None): url = contents['link'] page = ttxpage.TeletextPage( f"{category} Page {number:03x} {url}", number) page.header(number) line = 1 for l in header: page.addline(line, decode(l)) line += 1 title = contents['title'] line += page.wrapline(line, 21, page.fixup(title), ttxcolour.green()) colour = ' ' for para in contents['text']: if line <= 21: added = page.wrapline(line, 22, page.fixup(para), colour) if added: line += added + 1 colour = ttxcolour.cyan() line = 25 - len(footer) for l in footer: page.addline(line, decode(l)) line += 1 if fasttext and len(fasttext) in [3, 4, 6]: if len(fasttext) == 3: f = [nextpage(number), *fasttext, 0x8ff, 0x199] if len(fasttext) == 4: f = [*fasttext, 0x8ff, 0x199] else: f = fasttext page.addfasttext(*f) else: page.addfasttext(pages['first'], 0x100, 0x101, 0x100, 0x8ff, 0x199) page.save()
def news_page(number, contents, add_to_newsreel=False): url = contents['link'] page = ttxpage.TeletextPage("News Page {:03x} {}".format(number, url), number) page.header(number) category = newsheaders.newsheader(page, contents['section']) line = 4 line += page.wrapline(line, 21, page.fixup(contents['title']), ttxcolour.yellow()) colour = ' ' for para in contents['text']: if line <= 21: increment = page.wrapline(line, 22, page.fixup(para), colour) if increment: line += increment + 1 colour = ttxcolour.cyan() newsheaders.newsfooter(page, category) page.save(add_to_newsreel=add_to_newsreel)
def sport_page(number, contents, add_to_newsreel=False): url = contents['link'] page = ttxpage.TeletextPage("Sport Page {:03x} {}".format(number, url), number) page.header(number) sport_header(page, contents['section']) line = 4 title = contents['title'].replace(" - BBC Sport", "") line += page.wrapline(line, 21, page.fixup(title), ttxcolour.green()) colour = ' ' for para in contents['text']: if line <= 21: added = page.wrapline(line, 22, page.fixup(para), colour) if added: line += added + 1 colour = ttxcolour.cyan() sport_footer(page, contents['section']) page.save(add_to_newsreel=add_to_newsreel)
def cricket_scorecard_page(pagenum, url, cache): nextpage = ttxutils.nextpage(pagenum) page = ttxpage.TeletextPage("Cricket Scorecard", pagenum) maxrows = 18 pages = [] data = cricket_scorecard_table(url, cache) match = data['match'].upper() match = match.replace('INTERNATIONAL ','') match = match.replace(' -','') match = match.replace(' SERIES','') match = match.replace('UNDER-','U') short_match = match.replace("MATCH", "").strip() short_match = re.sub(r"\s*DAY\s+\d+\s+OF\s+\d+.*", r"", short_match) match = re.sub(r'DAY\s+(\d+)\s+OF\s+\d+.*', r'(Day \1)', match) if data['venue']: match += f", {data['venue']}" home_line = f"{data['home_name']}: " home_line += " & ".join( [f.replace(' all out','') for f in data['home_scores']]) away_line = f"{data['away_name']}: " away_line += " & ".join( [f.replace(' all out','') for f in data['away_scores']]) header = [ f"{ttxcolour.green()}{page.fixup(match)}", f"{ttxcolour.yellow()}{page.fixup(home_line)}", f"{ttxcolour.yellow()}{page.fixup(away_line)}", ] for i in data['innings']: rows = [] rows.extend(header) r = f"{ttxcolour.white()}{page.fixup(i['name'])}:" rows.append(f"{r:<41}") for m in i['batting']: colour = ttxcolour.cyan() if len(m) > 4: batsman, how_out, bowler, runs = m[:4] batsman = page.fixup(names.shorten(batsman)) if how_out == 'not out': colour = ttxcolour.white() elif how_out.startswith("run out"): s = re.search(r'(\(.+?\))', how_out) how_out = "run out" bowler = s[1] else: if ' ' in how_out: how, _, fielder = how_out.partition(' ') how_out = f"{how} {names.shorten(fielder)}" if bowler: bowler = page.fixup(bowler) if 'c & b' in bowler: bowler = bowler.replace('c & b', 'b') how_out = 'c &' how, _, name = bowler.partition(' ') bowler = f"{how} {names.shorten(name)}" how_out = page.fixup(how_out) r = f"{colour}{batsman:<9} {how_out:<12} {bowler:<12} {runs:>3}" rows.append(r) else: extras = page.fixup(m[1].strip()) runs = m[2] extratext = " Extras " if extras: extratext += f"({extras})" r = f"{colour}{extratext:<36}{runs:>3}" rows.append(r) # total row runs = i['runs'] dec = '' if "all out" in runs: wickets = "all out" runs = runs.replace("all out", "").strip() else: if "dec" in runs: runs = re.sub(r'\s*dec$', r'', runs) dec = ' dec' s = re.search(r'(\d+)-(\d+)', runs) runs = s[1] wickets = f"for {s[2]} wkts{dec}" s = re.search(r'([0-9]+)', i['overs']) total = f"TOTAL ({wickets}, {s[1]} ovs)" r = f"{ttxcolour.white()}{total:<36}{runs:>3}" rows.append(r) falls = i['falls'] if falls: falls = [re.sub(r"(\d+-\d+).*", r"\1", f[0]) for f in falls] r = "Fall: " + " ".join(falls[:5]) rows.append(f'{ttxcolour.white()}{r:<39}') r = " " + " ".join(falls[5:]) rows.append(f'{ttxcolour.white()}{r:<39}') else: rows.append('') r = page.fixup(data['status'].upper()) rows.append(f'{ttxcolour.yellow()}{r:<39}') if len(rows) < 20: r = page.fixup(data['toss']) rows.append(f'{ttxcolour.cyan()}{r:<39}') pages.append(copy.deepcopy(rows)) subpage = 0 for p in pages: if len(pages) > 1: subpage += 1 page.header(pagenum, subpage, status=0xc000) else: page.header(pagenum, subpage, status=0x8000) sport_header(page, 'Cricket') if len(pages) > 1: index = f"{subpage}/{len(pages)}" p[0] = f"{p[0]:<34.34}{ttxcolour.white()}{index:>5}" line = 4 for r in p: if len(r): page.addline(line, r) line += 1 footer= [ "€ANext page €BCricket €CHeadlines €FSport ", ] line = 25 - len(footer) for l in footer: page.addline(line, ttxutils.decode(l)) line += 1 pagec = _config['pages']['sport']['cricket'] index = pagec['index'] nextpage = ttxutils.nextpage(pagenum) page.addfasttext(nextpage, index, 0x301, 0x300, 0x8FF, 0x199) page.save() return f"{short_match}: {data['home_name']} v {data['away_name']}"
def football_gossip_page(pagenum, entries): nextpage = ttxutils.nextpage(pagenum) page = ttxpage.TeletextPage("Football Gossip", pagenum) maxrows = 18 pages = [] header = f"{ttxcolour.green()}Gossip column" p = [header] for f in entries: h, l, t = f h = page.fixup(h) l = page.fixup(l) t = page.fixup(t) lines = textwrap.wrap(f"{h}¬\t{l}",39, expand_tabs=False, replace_whitespace=False) rows = [] colour = ttxcolour.white() for ll in lines: if '\t' in ll or '¬' in ll: ll = ll.replace('¬', '\t') ll = ll.replace('\t\t', '\t') ll = ll.replace('\t', ttxcolour.cyan()) rows.append(f"{colour}{ll}") colour = ttxcolour.cyan() else: rows.append(f"{colour}{ll}") if len(rows[-1]) + len(t) > 40: rows.append(f"{ttxcolour.green()}{t:>39}") else: rows[-1] += f"{ttxcolour.green()}{t}" if ((len(p) + len(rows) < maxrows) or (len(p) == 0 and len(rows) == maxrows)): if len(p)>1: p.append('') p.extend(rows) else: pages.append(p) p = [header] p.extend(rows) pages.append(p) subpage = 0 for p in pages: if len(pages) > 1: subpage += 1 page.header(pagenum, subpage, status=0xc000) else: page.header(pagenum, subpage, status=0x8000) sport_header(page, 'Football') if len(pages) > 1: index = f"{subpage}/{len(pages)}" p[0] = f"{p[0]:<34}{ttxcolour.white()}{index:>5}" line = 4 for r in p: if len(r): page.addline(line, r) line += 1 sport_footer(page, 'Football') page.save()
def league(pagenum, url, cache): nextpage = ttxutils.nextpage(pagenum) page = ttxpage.TeletextPage("Football League Table", pagenum) league, date, table = league_table(url, cache) league = league.upper().replace(" TABLE", "") datefmt = date.strftime("%b %d %H:%M") subpage = 1 footers = [ "€ANext page €BFootball €CHeadlines €FSport" ] count = 0 for r in table: count += 1 if r[8]: count += 1 pages = math.ceil(count / 14) if len(table) == 12: pages = 1 newpage = True white = True row = 1 pagecount = 0 status = 0x8000 if pages > 1: status = 0xc000 for r in table: if newpage: pagecount += 1 page.header(pagenum, subpage, status=status) sport_header(page, 'Football') if pages > 1: index = f"{ttxcolour.white()}{pagecount}/{pages}" else: index = '' page.addline(4, f"{ttxcolour.green()} {league:<32} {index}") page.addline(6, f"{ttxcolour.white()} {datefmt} P W D L F A Pts") line = 8 newpage = False if white: colour = ttxcolour.white() else: colour = ttxcolour.cyan() white = not white team = r[0] team = team.replace("Crystal Palace", "C Palace") team = team.replace("Huddersfield", "H'field") team = team[:12] p = f"{r[1]:>2}" w = f"{r[2]:>2}" d = f"{r[3]:>2}" l = f"{r[4]:>2}" f = f"{r[5]:>3}" a = f"{r[6]:>3}" pts = f"{r[7]:>3}" brk = r[8] page.addline(line, f"{colour}{row:>2} {team:<12} {p} {w} {d} {l} {f} {a} {pts}") row += 1 line += 1 if brk and line < 21: page.addline(line, "{}```````````````````````````````````````".format( ttxcolour.red())) line += 1 if (line > 21 and len(table)>12) or (line > 22): subpage += 1 newpage = True line = 24 for l in footers: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(nextpage, 0x302, 0x301, 0x300, 0x8ff, 0x320) if not newpage: line = 24 for l in footers: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(nextpage, 0x302, 0x301, 0x300, 0x8ff, 0x320) page.save()
def weatherfiveday(W): cfg = _config["weather"] maximum = -9999 minimum = 9999 today = None entries = [] for city, num in fiveday_ids.items(): wx = W.loc_forecast(num, metoffer.DAILY).data if today is None: today = wx[0]["timestamp"][0] entry = [city] for i in range(5): wx_type = short_weathers.get(wx[i * 2]["Weather Type"][0], "N/A") max_temp = int(wx[i * 2]["Day Maximum Temperature"][0]) min_temp = int(wx[i * 2 + 1]["Night Minimum Temperature"][0]) date = wx[i * 2]["timestamp"][0] entry.append( f"{date.strftime('%a')}" f"{max_temp:>4}{min_temp:>4} {wx_type}" ) if max_temp > maximum: maximum = max_temp if min_temp < minimum: minimum = min_temp entries.append(entry) header = [ "␗j#3kj#3kj#3k␔␝␑␓h44|h<h<|(|$|h4|$|l ", "␗j $kj $kj 'k␔␝␑␓*uu?jwj7␡ ␡ ␡k5␡1␡k4 ", '␗"###"###"###␔////,,.-,-.,/,/,-.,.,-.///', ] temps_c = [] temps_f = [] steps = (maximum - minimum) / 10 if steps < 1: steps = 1 minimum = (minimum + maximum) // 2 - 5 for i in range(11): temp_c = round(minimum + i * steps) temp_f = round((temp_c * 1.8) + 32) c = str(temp_c) f = str(temp_f) l = max(len(c), len(f)) temps_c.append(f"{c:>{l}}") temps_f.append(f"{f:>{l}}") footer = [] back = ( ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + ttxcolour.yellow() ) footer.append(f"{back}C= " + " ".join(temps_c)) footer.append(f"{back}F= " + " ".join(temps_f)) footer.append( ttxutils.decode("€AUK map €B Sport €CWeather €FMain Menu") ) page = ttxpage.TeletextPage("Weather Five Day", cfg["fiveday"]) numpages = (len(entries) + 3) // 4 for sub in range(numpages): body = [] top = f"{sub+1}/{numpages}" body.append(f"{top:>39.39}") body.append( ttxcolour.yellow() + "UK FIVE DAY FORECAST FROM " + today.strftime("%e %b").strip() ) body.append(ttxcolour.green() + "max for 0600-1800 min for 1800-0600") body.append( ttxcolour.yellow() + " max min" + ttxcolour.white() + "C " + ttxcolour.yellow() + " max min" + ttxcolour.white() + "C" ) for i in range(2): count = 0 c1 = [] c2 = [] offset = (sub * 4) + i if offset < len(entries): c1 = entries[offset] offset = (sub * 4) + i + 2 if offset < len(entries): c2 = entries[offset] while len(c1) and len(c2): row = "" if count % 2: row += ttxcolour.cyan() else: row += ttxcolour.white() if len(c1): row += f"{c1[0]:<19.19} " c1 = c1[1:] if len(c2): row += c2[0] c2 = c2[1:] body.append(row) count += 1 body.append("") page.header(cfg["fiveday"], sub + 1, status=0xC000) line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1 for l in body: page.addline(line, l) line += 1 line = 25 - len(footer) for l in footer: page.addline(line, l) line += 1 page.addfasttext(cfg["maps"], 0x300, cfg["index"], 0x100, 0x8FF, 0x199) page.save()
def weatherobservations(W): cfg = _config["weather"] minimum = 9999 maximum = -9999 rows = [] timestamp = None for city, num in observation_ids.items(): obs = W.loc_observations(num, cache_hours=1).data time = None temp = '-' wind_speed = '-' wind_dir = '-' pressure = '-' trend = '-' weather_type = None for o in obs: if "timestamp" in o: time = o["timestamp"][0] if "Temperature" in o: temp = round(float(o["Temperature"][0])) if "Wind Speed" in o: wind_speed = o["Wind Speed"][0] if "Wind Direction" in o: wind_dir = o["Wind Direction"][0] if "Pressure" in o: pressure = o["Pressure"][0] if "Pressure Tendency" in o: trend = o["Pressure Tendency"][0] if "Weather Type" in o: weather_type = o["Weather Type"][0] if len(rows) % 2 == 1: row_colour = ttxcolour.white() else: row_colour = ttxcolour.cyan() if trend == "F": trend_colour = ttxcolour.green() elif trend == "S": trend_colour = ttxcolour.white() else: trend_colour = ttxcolour.cyan() row = f"{row_colour}{city:<12.12}{temp:>4}{wind_dir:>4}{wind_speed:>3}" row += f"{pressure:>6}{trend_colour}{trend}{row_colour}" if weather_type is not None: row += short_weathers[weather_type] else: row += "n/a" rows.append(row) if time is not None and (timestamp is None or time > timestamp): timestamp = time if temp and temp != '-': if temp < minimum: minimum = temp if temp > maximum: maximum = temp header = [ "␗j#3kj#3kj#3k␔␝␑␓h44|h<h<|(|$|h4|$|l ", "␗j $kj $kj 'k␔␝␑␓*uu?jwj7␡ ␡ ␡k5␡1␡k4 ", '␗"###"###"###␔////,,.-,-.,/,/,-.,.,-.///', ] temps_c = [] temps_f = [] steps = (maximum - minimum) / 10 if steps < 1: steps = 1 minimum = (minimum + maximum) // 2 - 5 for i in range(11): temp_c = round(minimum + i * steps) temp_f = round((temp_c * 1.8) + 32) c = str(temp_c) f = str(temp_f) l = max(len(c), len(f)) temps_c.append(f"{c:>{l}}") temps_f.append(f"{f:>{l}}") footer = [] footer.append(ttxutils.decode(" ␃pressure␆R␃rising␇S␃steady␂F␃falling")) footer.append("") back = ( ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + ttxcolour.yellow() ) footer.append(f"{back}C= " + " ".join(temps_c)) footer.append(f"{back}F= " + " ".join(temps_f)) footer.append( ttxutils.decode("€AUK 5 day€B Sport €CWeather €FMain Menu") ) page = ttxpage.TeletextPage("Weather Reports", cfg["observations"]) for subpage in (1, 2, 3): body = [] top = f"{subpage}/3" body.append(f"{top:>39.39}") time = timestamp.strftime("%H%M") body.append(f"{ttxcolour.yellow()}CURRENT UK WEATHER: Report at {time}") body.append("") body.append(ttxutils.decode(" ␃temp wind pres")) body.append(ttxutils.decode(" ␇C mph mB")) base = (subpage - 1) * 10 for l in rows[base : base + 10]: body.append(l) page.header(cfg["observations"], subpage, status=0xC000) line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1 for l in body: page.addline(line, l) line += 1 line = 25 - len(footer) for l in footer: page.addline(line, l) line += 1 page.addfasttext( cfg["fiveday"], 0x300, cfg["index"], 0x100, 0x8FF, 0x199 ) subpage += 1 page.save()
def index_page(category : str, pages : dict, header : List[str], footer : List[str], entries : list, fasttext : Optional[List[int]] = None, increment : int =1, rule: Optional[str] = None, number_colour: str = ttxcolour.white()): index = pages['index'] page = ttxpage.TeletextPage( f"{category} Index {index:03x}", index) page.header(index) line = 1 for l in header: page.addline(line, decode(l)) line += 1 colour = ttxcolour.colour(ttxcolour.DOUBLE_HEIGHT) number = pages['first'] index = 0 for contents in entries: if increment == 1: if index in [ 1, 6, 10 ]: line += 1 elif index == 1: line += 1 if line == rule: page.addline(line, f"{ttxcolour.magenta()}" "```````````````````````````````````````") line += 1 title = contents['short_title'] l, _, r = title.partition(': ') if r: title = r title = page.truncate(title, 35, ' ') page.addline(line, f"{colour}{title:<35.35}{number_colour}{number:03x}") colour = ttxcolour.cyan() line += increment index += 1 number = nextpage(number) if number > pages['last']: break line = 25 - len(footer) for l in footer: page.addline(line, decode(l)) line += 1 if fasttext and len(fasttext) in [3, 4, 6]: if len(fasttext) == 3: f = [pages['first'], *fasttext, 0x8ff, 0x199] elif len(fasttext) == 4: f = [*fasttext, 0x8ff, 0x199] else: f = fasttext page.addfasttext(*f) else: page.addfasttext(pages['first'], 0x100, 0x101, 0x100, 0x8ff, 0x199) page.save()