def news_headlines(entries, conf, region=None): pagenum = conf['headlines'] if region: page = ttxpage.TeletextPage(f"Regional Headlines {pagenum:03x}", pagenum) page.header(pagenum) category = newsheaders.newsheader(page, region) nextpage = conf['first'] maxlines = 9 else: page = ttxpage.TeletextPage(f"News Headlines {pagenum:03x}", pagenum) page.header(pagenum) category = newsheaders.newsheader(page, 'headlines') nextpage = conf['first'] maxlines = 8 line = 4 count = 0 for contents in entries: if line == 4: textattr = ttxcolour.colour(ttxcolour.DOUBLE_HEIGHT) else: textattr = ttxcolour.colour(ttxcolour.ALPHAWHITE) headline = page.truncate(contents['short_title'], 70, ' ') headlines = textwrap.wrap(headline, 35) page.addline( line, '{}{:<35}{}{:03x}'.format(textattr, headlines[0], ttxcolour.yellow(), nextpage)) nextpage = ttxutils.nextpage(nextpage) if line <= 4: line += 2 else: line += 1 if line >= 22: break if len(headlines) > 1: page.addline(line, '{} {}'.format(ttxcolour.white(), headlines[1])) if line < 7 and region is None: line += 2 else: line += 1 count += 1 if count >= maxlines: break newsheaders.newsheadlinesfooter(page, category) page.save()
def generic_page(category : str, pagenum : int, pages : dict, header : List[str], footer : List[str], lines : List[str], fasttext : Optional[List[int]] = None): page = ttxpage.TeletextPage( f"{category} Page {pagenum:03x}", pagenum) page.header(pagenum) line = 1 for l in header: page.addline(line, decode(l)) line += 1 for l in lines: page.addline(line, l) line += 1 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['index'], *fasttext, 0x8ff, 0x199] elif len(fasttext) == 4: f = [*fasttext, 0x8ff, 0x199] else: f = fasttext page.addfasttext(*f) else: page.addfasttext(pages['index'], 0x100, 0x101, 0x100, 0x8ff, 0x199) page.save()
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 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 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 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 fixture_page(pagenum, date, dayname, cache): nextpage = ttxutils.nextpage(pagenum) page = ttxpage.TeletextPage("Football Fixtures", pagenum) maxrows = 18 isodate = date.isoformat() url = f"{_config['football_fixtures_url']}/{isodate}" fixes = fixtures_table(url, cache) pages = [] header = f"{ttxcolour.green()}{dayname}" p = [header] for f in fixes: rows = [] r = f"{ttxcolour.white()}{page.fixup(f['league']).upper()}" if f['round_']: r += f"{ttxcolour.magenta()}{page.fixup(f['round_'])}" rows.append(f"{r:<38}") for m in f['matches']: home_team = page.fixup(m['home_team'])[:13] away_team = page.fixup(m['away_team'])[:13] r = f"{ttxcolour.cyan()}{home_team:<13}" if m['kickoff']: r += f"{ttxcolour.white()}{'v':^5}" else: r += f"{ttxcolour.white()}{m['home_goals']:>2}" r += f"-{m['away_goals']:<2}" r += f"{ttxcolour.cyan()}{away_team:<13}" if m['kickoff']: r += f"{ttxcolour.green()}{page.fixup(m['kickoff']):>5}" elif m['status']: status = page.fixup(m['status'])[:5] r += f"{ttxcolour.yellow()}{status:>5}" rows.append(r) 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) if len(fixes) == 0: p.append('') p.append(f'{ttxcolour.cyan()}No matches today.') 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 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 cricket_fixture_page(pagenum, dates, cache): nextpage = ttxutils.nextpage(pagenum) page = ttxpage.TeletextPage("Cricket Fixtures", pagenum) maxrows = 18 pages = [] links = [] for offset in dates: date = datetime.date.today() + datetime.timedelta(days=offset) if offset == 0: dayname = "Today" elif offset == -1: dayname = "Yesterday" else: dayname = date.strftime("%A") isodate = date.isoformat() url = f"{_config['cricket_fixtures_url']}/{isodate}" fixes = cricket_fixtures_table(url, cache) header = f"{ttxcolour.yellow()}{dayname}'s Matches" p = [header] for f in fixes: rows = [] r = f"{ttxcolour.white()}{page.fixup(f['series']).upper()}" rows.append(f"{r:<38}") for m in f['matches']: if len(rows)>1: rows.append('') home_team = page.fixup(m['home_team']) away_team = page.fixup(m['away_team']) if m['home_batting']: home_team = f"{home_team:<.16}{ttxcolour.yellow()}*" r = f"{ttxcolour.cyan()}{home_team:<18.18}" else: r = f"{ttxcolour.cyan()}{home_team:<17.17}" r += f"{ttxcolour.white()}v" if m['away_batting']: away_team = f"{away_team:<.16}{ttxcolour.yellow()}*" r += f"{ttxcolour.cyan()}{away_team:<18.18}" else: r += f"{ttxcolour.cyan()}{away_team:<17.17}" rows.append(r) if m['title']: rows.append(f"{ttxcolour.green()}{page.fixup(m['title'])}") if m['home_score'] or m['away_score']: if offset in [-1, 0]: links.append(m['link']) for innings in range(2): if m['home_score'] and innings < len(m['home_score']): a = page.fixup(m['home_score'][innings]) else: a = '' if m['away_score'] and innings < len(m['away_score']): b = page.fixup(m['away_score'][innings]) else: b = '' if a or b: r = f"{ttxcolour.cyan()}{a:<17.17} {b:<17.17}" rows.append(r) r = '' if m['time']: if m['time'] not in ['LIVE', 'V']: r += page.fixup(m['time']) if m['status']: status = page.fixup(m['status']) r += f"¬\t{status}" if m['venue']: venue = m['venue'].replace('Venue: ','').strip() venue = page.fixup(venue) r += f"¬\t{venue}" colour = ttxcolour.green() for ll in textwrap.wrap(r, 39, expand_tabs=False, replace_whitespace=False): if '\t' in ll or '¬' in ll: ll = ll.replace('¬', '\t') ll = ll.replace('\t\t', '\t') if ll.startswith('\t'): ll = ll.replace('\t','') colour = ttxcolour.magenta() else: ll = ll.replace('\t', ttxcolour.magenta()) rows.append(f"{colour}{ll}") colour = ttxcolour.magenta() else: rows.append(f"{colour}{ll}") 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) if len(fixes) == 0: p.append('') p.append(f'{ttxcolour.cyan()}No matches today.') 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, '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 sport_footer(page, 'Cricket') page.save() return links
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 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
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()
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 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 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