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 newssummaryfooter(page): lines = [ '€D€]€CNews index€G102€CExtra€G140€CWeather €G400', '€D€]€CFront page€G100€CTV €G600€CChildren€G500', '€A1st story€BNews Indx€CHeadlines€FMain Menu' ] line = 22 for l in lines: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(0x104, 0x102, 0x101, 0x100, 0x8ff, 0x199)
def newsindexfooter(page): lines = [ '€T€]€CSummary€G103€CExtra€G140€CFront page €G100', '€D€]€CLottery€G555€CFlash€G150€CRegional €G160', '€ASummary €B1st story €CLocalNews€FMain Menu' ] line = 22 for l in lines: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(0x103, 0x104, 0x160, 0x100, 0x8ff, 0x199)
def sport_footer(page, section): nextpage = ttxutils.nextpage(page.page) if nextpage == 0x316: nextpage = 0x324 if is_football(section): footer = [ "€D€]€CCEEFAX FOOTBALL SECTION PAGE 302", "€D€]€CBBC WEBSITE: bbc.co.uk/football", "€ANext page €BFootball €CHeadlines €FSport", ] pages = _config['pages']['sport']['football'] index = pages['index'] elif section in [ 'Formula 1', 'formula1' ]: footer = [ "€D€]€CCEEFAX MOTORSPORT SECTION PAGE 360 ", "€D€]€CBBC WEBSITE: bbc.co.uk/motorsport ", "€ANext page €BM/sport €CHeadlines €FSport ", ] pages = _config['pages']['sport']['formula1'] index = pages['index'] elif section in [ 'Cricket' ]: footer= [ "€D€]€CCEEFAX CRICKET SECTION PAGE 340 ", "€D€]€CBBC WEBSITE: bbc.co.uk/cricket ", "€ANext page €BCricket €CHeadlines €FSport ", ] pages = _config['pages']['sport']['cricket'] index = pages['index'] elif section in [ 'Rugby Union' ]: footer= [ "€D€]€CCEEFAX RUGBY SECTION PAGE 370 ", "€D€]€CBBC WEBSITE: bbc.co.uk/rugby ", "€ANext page €BRugby U €CHeadlines €FSport ", ] pages = _config['pages']['sport']['rugby_union'] index = pages['index'] else: footer = [ "€D€]€CCEEFAX SPORT SECTION PAGE 300", "€D€]€CBBC WEBSITE: bbc.co.uk/sport", "€ANext page €BFootball €CHeadlines €FSport", ] pages = _config['pages']['sport']['football'] index = pages['index'] line = 22 for l in footer: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext(nextpage, index, 0x301, 0x300, 0x8FF, 0x199)
def football_guide(pages): pagenum = pages['guide'] header = [ "€Wj#3kj#3kj#3k€T€]€R h<h<|h<|(|$|l4|l4| |", "€Wj $kj $kj 'k€T€]€R j7ju¬ju¬ ¬ ¬{4¬k5¬0¬0", '€W"###"###"###€T///-.-,,-,,/,/,,.,-.,.,.//' ] footer = [ "€D€]€C MAIN FOOTBALL INDEX ON PAGE 302", "€ACricket €BFootball €CTop Sport €FSport", ] lines = [ ttxutils.decode("€B GUIDE TO FOOTBALL PAGES"), ttxutils.decode("€G LATEST NEWS `€FStories/reports€G303-315"), ttxutils.decode("€F Gossip column€G338"), "", "", ttxutils.decode("€G FIXTURES/RESULTS"), ] pgs = [] for page, offset, label in _config['football_fixtures']: day = datetime.date.today() + datetime.timedelta(days=offset) if not label: label = day.strftime("%A") pgs.append((page, label.capitalize())) stride = math.ceil(len(pgs) / 2) for i in range(stride): page,label = pgs[i] l = f"{ttxcolour.cyan()} {label:<9.9}{ttxcolour.white()}{page:03x}" if i + stride < len(pgs): page,label = pgs[i+stride] l += f"{ttxcolour.cyan()} {label:<9.9}{ttxcolour.white()}{page:03x}" lines.append(l) lines += [ "", ttxutils.decode("€G TABLES"), ttxutils.decode("€F Premier league€G324€FLeague Two €G327"), ttxutils.decode("€F Championship €G325€FScottish prem.€G328"), ttxutils.decode("€F League One €G326€FScottish champ€G329"), ] ttxutils.generic_page("Football", pagenum, pages, header, footer, lines, [0x340, 0x302, 0x301, 0x300])
def makefrontpage(headlines): page = ttxpage.TeletextPage("Service Front Page", 0x100, time=8) subpage = 1 for h in headlines: if h is None: continue page.header(0x100, subpage, status=0xc000) # pp.pprint(h) entry, pagenum = h title = entry['short_title'].upper() title = page.truncate(title, 35, ' ') lines = [ '€W`ppp`ppp`ppp€T||,,,<,,<,,<,,|,,,|,l<,|||', '€Wj $zj $zj tz€T€]€S¬7#j¬sj¬sj¬sh¬s¬4ouz?€T¬', "€Wj %jj %jj 'k€T€]€S¬upj¬pj¬pj¬ j¬ ¬5¬5j¬€T¬", '€W"###"###"###€T##########################', f"€C{entry['section']}", f"€M{title:<35}€C{pagenum:03x}", '', '€D```````````````````````````````````````', '€CA-Z INDEX €G199€CNEWS HEADLINES €G101', '€CBBC INFO €G695€CNEWS FOR REGION €G160', "€CCHESS €G568€CNEWSROUND €G570", "€CCOMMUNITY€GBBC2€G650€CRADIO €GBBC1€G640", "€CENTERTAINMENT €G500€CREAD HEAR €GBBC2€G640", "€C ", "€CFILM REVIEWS €G526€CSPORT €G300", "€CFINANCE€G BBC2€G200€CSUBTITLING €G888", "€CFLIGHTS €G440€CTOP 40 €G528", "€CGAMES REVIEWS €G527€CTRAVEL €G430", "€CHORSERACING €G660€CTV LINKS €G615", "€CLOTTERY €G555€CTV LISTINGS €G600", "€CSCI-TECH €G154€CWEATHER €G400", "€C ", "€D€]€CCeefax: The world at your fingertips ", "€AHeadlines €BSport €CLocal TV €FA-Z Index " ] line = 1 for l in lines: page.addline(line, ttxutils.decode(l)) line += 1 subpage += 1 page.addfasttext(0x101, 0x300, 0x600, 0x199, 0x8ff, 0x199) 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 sport_header(page, section): if is_football(section): header = [ "€Wj#3kj#3kj#3k€T€]€R h<h<|h<|(|$|l4|l4| |", "€Wj $kj $kj 'k€T€]€R j7ju¬ju¬ ¬ ¬{4¬k5¬0¬0", '€W"###"###"###€T///-.-,,-,,/,/,,.,-.,.,.//', ] elif section in [ 'Formula 1', 'formula1' ]: header = [ "€Wj#3kj#3kj#3k€T€]€Rh,hlhl <<4444hl hlhlh$ ", "€Wj $kj $kj 'k€T€]€Rj#jzj#5555u5ujk jzjjj1 ", '€W"###"###"###€T//-/-,-/....,.,--/-,---.//' ] elif section in [ 'Cricket' ]: header = [ '€Wj#3kj#3kj#3k€T€]€R |,h<|h4|,h4|h<(|$', "€Wj $kj $kj 'k€T€]€R ¬pj7}j5¬pj7}jw ¬", '€W"###"###"###€T////,,-.,-.,,-.,-,/,///////' ] elif section in ['Rugby Union']: header = [ '€Wj#3kj#3kj#3k€T€]€R hl 44<,hl 44', "€Wj $kj $kj 'k€T€]€R j#5u5u{js5s5", '€W"###"###"###€T//////-/.,.,,-,.,.////////' ] else: header = [ "€Wj#3kj#3kj#3k€T€]€R h<,h<|h<|h<|(|$ ", "€Wj $kj $kj 'k€T€]€R bs¬j7#ju¬j7} ¬ ", '€W"###"###"###€T/////-,,-./-,,-.,/,///////' ] line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1
def weatherregion(W): cfg = _config["weather"] region = _config["bbc_news_regions"][_config["bbc_news_region"]] wx_text = W.text_forecast( metoffer.REGIONAL_FORECAST, regions[region["weather"]] ) headline = wx_text.data[0][1] head1 = wx_text.data[1][0].replace(":", "") head2 = wx_text.data[2][0].replace(":", "") body1 = wx_text.data[1][1] body2 = wx_text.data[2][1] min = None max = None if "Minimum Temperature" in body1: s = re.search(r"Minimum Temperature (-?\d+)C", body1) min = s[1] s = re.search(r"Maximum Temperature (-?\d+)C", body2) max = s[1] else: s = re.search(r"Minimum Temperature (-?\d+)C", body2) min = s[1] s = re.search(r"Maximum Temperature (-?\d+)C", body1) max = s[1] body1 = re.sub(r" M(ax|in)imum Temperature -?\d+C.*", r"", body1) body2 = re.sub(r" M(ax|in)imum Temperature -?\d+C.*", r"", body2) header = [ "€Wh,,lh,,lh,,l€T||,<<|,,|,,|,,|l<l,,<,,l||", "€Wj 1nj 1nj =n€T€]€S¬jj5¬shw{4k7juz5¬sjw{%", "€W*,,.*,,.*,,.€T€]€Sozz%¬pj5j5j5j5j5¬pj5j5", "1234567890123€T//-,,/,,-.-.-.-.-.,,-.-.//", ] footer = [ "€T€]€G REGIONAL€CNews€G160€CWeather€G302", "€T€]€GNATIONAL€CMain menu€G100€CWeather€G400", "€AOutlook €BSport €CWeather €FMain Menu", ] short_name = f"{region['medium']:^13.13}" header[3] = short_name + header[3][13:] page = ttxpage.TeletextPage("Weather Page", cfg["regional"]) subpage = 1 for h, b in [(head1, body1), (head2, body2)]: lines = textwrap.wrap(page.fixup(b), 19) rows = ["", f"{ttxcolour.yellow()}{h.upper()}", ""] for l in range(13): try: t = lines[l] except: t = "" t = ( f"{ttxcolour.green()}{t:<19.19}" f"{ttxcolour.colour(ttxcolour.MOSAICYELLOW)}5" ) if l == 0: t += f" {ttxcolour.yellow()}STATISTICS" elif l == 2: t += f" {ttxcolour.white()}Maximum" elif l == 3: t += f"{ttxcolour.white()}Temperature{ttxcolour.yellow()}{max}C" elif l == 5: t += f" {ttxcolour.white()}Minimum" elif l == 6: t += f"{ttxcolour.white()}Temperature{ttxcolour.yellow()}{min}C" rows.append(t) bot = f"{subpage}/2" rows.append(f"{bot:>39.39}") page.header(cfg["regional"], subpage, status=0xC000) line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1 for ll in rows: page.addline(line, ll) line += 1 line = 25 - len(footer) for l in footer: page.addline(line, ttxutils.decode(l)) line += 1 page.addfasttext( cfg["national"], 0x300, cfg["index"], 0x100, 0x8FF, 0x199 ) subpage += 1 page.save() return headline
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 map_lines(self): return [ttxutils.decode(l, low=True) for l in self.map[2:]]
def weatherindex(regionhead, ukhead): cfg = _config["weather"] page = ttxpage.TeletextPage("Weather Index", cfg["index"]) regionheads = textwrap.wrap(page.fixup(regionhead), 35) regionhead = f"{regionheads[0]:<35.35}" regionheads = regionheads[1:] headline = "WEATHER NEWS:¬" + page.fixup(ukhead) headlines = textwrap.wrap(headline, 39) for i in range(len(headlines)): l = headlines[i] if i == 0: l = ttxcolour.yellow() + l.replace("¬", ttxcolour.green()) elif i == len(headlines) - 1: l = ( ttxcolour.green() + f"{l:<35.35}" + ttxcolour.yellow() + f"{cfg['maps']:03x}" ) else: l = ttxcolour.green() + l headlines[i] = l header = [ "␗j#3kj#3kj#3k␔␝␑␓h44|h<h<|(|$|h4|$|l ", "␗j $kj $kj 'k␔␝␑␓*uu?jwj7␡ ␡ ␡k5␡1␡k4 ", '␗"###"###"###␔////,,.-,-.,/,/,-.,.,-.///', ] middle = [ "␃UK␄````````````````````````````````````", "␆Forecast maps ␃401␆UK Cities 5 Day␃406", "␆Regions ␃402␆ ␃ ", "␆National ␃403␆ ␃ ", "␆Current Weather␃404 ", " ", ] attrib = "From the Met Office" attrib = f"{attrib:^39}"[2:] footer = headlines + [ "", ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + f"{ttxcolour.yellow()}{attrib}", ttxutils.decode("€AMaps €BRegional €COutlook €FMain Menu"), ] page.header(cfg["index"]) line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1 page.addline( line, ttxcolour.colour(ttxcolour.DOUBLE_HEIGHT) + regionhead + ttxcolour.yellow() + f"{cfg['regional']:03x}", ) line += 2 for l in regionheads: page.addline(line, " " + l) line += 1 line += 1 for l in middle: page.addline(line, ttxutils.decode(l)) line += 1 line = 25 - len(footer) for l in footer: page.addline(line, l) line += 1 page.addfasttext( cfg["maps"], cfg["regional"], cfg["national"], 0x100, 0x8FF, 0x199 ) 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 newsheader(page, title): headers = [] category = title if title in ['Health']: headers = [ '€Wj#3kj#3kj#3k€T€]€S | |h<$|,|h4h||4| | ', "€Wj $kj $kj 'k€T€]€S ¬#¬jw1¬#¬ju0j5 ¬#¬ ", '€W"###"###"###€T///,/,-,.,/,-,.-./,/,/////' ] elif title in ['Technology', 'Science & Environment']: headers = [ '€Wj#3kj#3kj#3k€T€]€S |,h<$|h<$|0|h<$|, ', "€Wj $kj $kj 'k€T€]€S s¬ju0¬jw1¬+¬ju0¬s", '€W"###"###"###€T////,,-,.,-,.,/,-,.,,/////' ] category = 'scitech' elif title in ['Lancashire']: headers = [ "€Wj#3kj#3kj#3k€T€]€S | `<thth4x,`<,", "€Wj $kj $kj 'k€T€]€S ¬pj7¬j7o5opbs?`0", '€W"###"###"###€T///,,-.,-.-.-,-,.-.///////' ] elif title in ['Manchester']: headers = [ "€Wj#3kj#3kj#3k€T€]€S|||4xl0|0|`<$|h4 | |l0", "€Wj $kj $kj 'k€T€]€S¬jj5¬k5¬+¬*u0¬k5\"! ¬k4", '€W"###"###"###€T//,--.,-.,/,/,.,-.///,-.//' ] elif title in [ 'UK', "Business", "Entertainment & Arts", "London", "Family & Education", "Cambridgeshire", "Shropshire", "Leicester", "Norfolk", "Sheffield & South Yorkshire", "Bristol", "Beds, Herts & Bucks", "Essex", "England", "Sussex", "Wiltshire", "Tyne & Wear", "Suffolk", "Kent", "Leeds & West Yorkshire", "Liverpool", "Birmingham & Black Country", "Devon", "York & North Yorkshire", "Lincolnshire", "Surrey", "Humberside", "Derby", "Dorset", "Hereford & Worcester", "Hampshire & Isle of Wight", "Nottingham", "Oxford", "Tees" ]: headers = [ '€Wj#3kj#3kj#3k€T€]€S h4h4|,|h<<|h<$', "€Wj $kj $kj 'k€T€]€S j7k5¬p¬j55¬jw1", '€W"###"###"###€T//////-.-.,,,-..,-,.//////' ] elif title in [ "Scotland", "Edinburgh, Fife & East Scotland", "Tayside and Central Scotland", "NE Scotland, Orkney & Shetland", "Glasgow & West Scotland", "Hearts", "South Scotland", "Scotland politics", "Highlands & Islands", "Scotland business" ]: headers = [ '€Wj#3kj#3kj#3k€D€]€Sx,h<$|l4l<h4 x,th|0|h<t ', "€Wj $kj $kj 'k€T€]€Ss?ju0¬z5j5ju0¬#¬j5+¬ju> ", '€W"###"###"###€T//,.-,.,,.-.-,.,/,-./,-,./' ] category = 'scotland' elif title in ["Northern Ireland", "Foyle & West", "N. Ireland Politics"]: headers = [ '€Wj#3kj#3kj#3k€T€]€S|0| h4|l4|,h4`<thth4|l0', "€Wj $kj $kj 'k€T€]€S¬+¬`j5¬k4¬sjuj7¬j7o5¬z%", '€W"###"###"###€T//,/,--.,-.,,-,-.,-.-.,,//' ] category = 'northern ireland' elif title in [ "Wales", "Wales politics", "North West Wales", "North East Wales", "South East Wales", "South West Wales" ]: headers = [ '€Wj#3kj#3kj#3k€D€]€S h44|`<l0| h<$x,', "€Wj $kj $kj 'k€T€]€S *uu?j7k5¬pjw1s?", '€W"###"###"###€T//////,,.-.-.,,-,.,.//////' ] category = 'wales' elif title in [ "World", "Europe", "Latin America & Caribbean", "Middle East", "US & Canada", "Africa", "Australia", "India", "Asia", "China" ]: headers = [ '€Wj#3kj#3kj#3k€T€]€S |hh4|,|h<l4| h<l0', "€Wj $kj $kj 'k€T€]€S ozz%¬p¬j7k4¬pjuz%", '€W"###"###"###€T/////-,,/,,,-.-.,,-,,/////' ] elif title in ["Politics", "UK Politics"]: headers = [ '€Wj#3kj#3kj#3k€T€]€S h<|h<|h4 |(|$|h<$|,$ ', "€Wj $kj $kj 'k€T€]€S j7#ju¬ju0¬ ¬ ¬ju0s{5 ", '€W"###"###"###€T///-./-,,-,.,/,/,-,.,,.///' ] category = 'politics' elif title in ['headlines']: headers = [ '€Wj#3kj#3kj#3k€T€]€Sh4|h<h<|h<th4h4xl0|$|, ', "€Wj $kj $kj 'k€T€]€Sj7¬jwj7¬ju?juj5¬j5¬1s¬ ", '€W"###"###"###€T//-.,-,-.,-,.-,-.,-.,.,,//' ] elif title in ['index']: headers = [ '€D€]€S|h4|h4 `h44|`<th<|h4h<t hth4|$|hh4|,$', '€D€]€Soz%¬k48!*uu?*u?j7}juju? j7o5¬1ozz%s{5', '€T//-,/,-.///,,./,.-.,-,-,./-.-.,.-,,/,,.' ] elif title in ['summary']: headers = [ '€Wj#3kj#3kj#3k€T€]€S|,$|h4|ll4|ll4|l4|l4|h4 ', "€Wj $kj $kj 'k€T€]€Ss{5¬z5¬jj5¬jj5¬k5¬k4s{5 ", '€W"###"###"###€T//,,.,,.,--.,--.,-.,-.,,./' ] elif title in ['scitechhead']: headers = [ '€Wj#3kj#3kj#3k€T€]€S x,$x,h4 (|$|,`<$|h4 ', "€Wj $kj $kj 'k€T€]€S s{%opj5# ¬ ¬s*u0¬k5 ", '€W"###"###"###€T////,,/-,-.//,/,,/,.,-.///' ] else: headers = [ '€Wj#3kj#3kj#3k€T€]€S xl0|,h44|h,$', "€Wj $kj $kj 'k€T€]€S ¬j5¬s*uu?bs5", '€W"###"###"###€T///////,-.,,/,,.-,.///////' ] line = 1 for h in headers: page.addline(line, ttxutils.decode(h)) line += 1
def weathermaps(W): cfg = _config["weather"] if datetime.datetime.now().hour > 16: advance = 1 else: advance = 0 pagenum = cfg["maps"] subpage = 1 page = ttxpage.TeletextPage("Weather Maps", pagenum, time=10) for index in range(3): caption = None advanced = False page.header(pagenum, subpage, status=0xC000) region_wx = dict() region_wx_reduced = dict() for reg_name, reg_id in region_ids.items(): w = W.loc_forecast(reg_id, metoffer.DAILY) now = w.data[index + advance] if (not advanced and now["timestamp"][0].date() < datetime.datetime.now().date()): # handle overnight transition advanced = True advance += 1 now = w.data[index + advance] wx_type = now["Weather Type"][0] wx_type_full = weathers.get(wx_type, "N/A") if wx_type_full in region_wx: region_wx[wx_type_full].append(reg_name) else: region_wx[wx_type_full] = [reg_name] if wx_type in reduction_mapping: wx_type = reduction_mapping[wx_type] wx_type_reduced = weathers.get(wx_type, "N/A") if wx_type_reduced in region_wx_reduced: region_wx_reduced[wx_type_reduced].append(reg_name) else: region_wx_reduced[wx_type_reduced] = [reg_name] if len(region_wx.keys()) > len(colours_a): # Reduce colours in weather map region_wx = region_wx_reduced map = weathermap.WeatherMap() reg_mapping = dict() i = 0 for wx, locs in region_wx.items(): if i >= len(colours_a): print(f"Out of colours on weather map {subpage}", flush=True) i = 0 map.plot_text(firstmap(locs), colours_a[i], wx) for loc in locs: reg_mapping[loc] = colours_m[i] i += 1 for city_name, city_id in city_ids.items(): w = W.loc_forecast(city_id, metoffer.DAILY) now = w.data[index + advance] if not caption: caption = now["timestamp"][0].strftime("%A") if now["timestamp"][1] == "Night": caption += " night" if now["timestamp"][1] == "Day": wx_temp = now["Day Maximum Temperature"][0] else: wx_temp = now["Night Minimum Temperature"][0] map.plot_temp(city_name, wx_temp) # This needs to go after temperatures, as it changes # the colours following the numbers map.plot_borders(reg_mapping) title = f"Weather for {caption}" title = f"{title:^39}"[2:] page.addline( 1, ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + f"{ttxcolour.yellow()}{title}", ) l = 2 subpagenum = chr(ttxcolour.ALPHAWHITE) + f"{subpage}/3" map.put_text(2, 35, subpagenum) for ll in map.map_lines(): page.addline(l, ll) l += 1 title = "From the Met Office" title = f"{title:^39}"[2:] page.addline( 23, ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + f"{ttxcolour.yellow()}{title}", ) page.addline( 24, ttxutils.decode("€ARegional €BSport €CWeather €FMain Menu") ) page.addfasttext( cfg["regional"], 0x300, cfg["index"], 0x100, 0x8FF, 0x199 ) subpage += 1 page.save(add_to_newsreel=True)
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 weatheroutlook(W): cfg = _config["weather"] wx_text = W.text_forecast(metoffer.REGIONAL_FORECAST, regions["uk"]) headline = wx_text.data[0][1] page = ttxpage.TeletextPage("Weather Page", cfg["national"]) pages = [] for i in range(3): head = wx_text.data[i + 1][0].replace(":", "") head = textwrap.wrap(page.fixup(head), 39) body = wx_text.data[i + 1][1] body = re.sub(r" M(ax|in)imum Temperature \d+C.*", r"", body) body = textwrap.wrap(page.fixup(body), 39) block = [] for h in head: block.append(f" {h:<.39}") for b in body: block.append(f"{ttxcolour.cyan()}{b:<.39}") if len(pages) and len(pages[-1]) + len(block) + 1 <= 15: pages[-1].append('') pages[-1].extend(block) else: pages.append(block) header = [ "␗j#3kj#3kj#3k␔␝␑␓h44|h<h<|(|$|h4|$|l ", "␗j $kj $kj 'k␔␝␑␓*uu?jwj7␡ ␡ ␡k5␡1␡k4 ", '␗"###"###"###␔////,,.-,-.,/,/,-.,.,-.///', ] title = "From the Met Office" title = f"{title:^39}"[2:] footer = [ ttxcolour.blue() + ttxcolour.colour(ttxcolour.NEW_BACK) + f"{ttxcolour.yellow()}{title}", ttxutils.decode("€AUK cities €BSport €CWeather €FMain Menu"), ] for subpage in range(len(pages)): rows = [] top = f"{subpage + 1}/{len(pages)}" rows.append(f"{top:>39.39}") rows.append(" UK WEATHER OUTLOOK") rows.append("") rows.extend(pages[subpage]) page.header(cfg["national"], subpage + 1, status=0xC000) line = 1 for l in header: page.addline(line, ttxutils.decode(l)) line += 1 for l in rows: page.addline(line, l) line += 1 line = 25 - len(footer) for l in footer: page.addline(line, l) line += 1 page.addfasttext( cfg["observations"], 0x300, cfg["index"], 0x100, 0x8FF, 0x199 ) page.save(add_to_newsreel=True) return headline