From a32c34dab635a74f3a7e2bcd138c12090f5942e9 Mon Sep 17 00:00:00 2001 From: rsiddharth Date: Thu, 9 Jul 2020 22:41:52 -0400 Subject: Format via black. --- lps_gen.py | 284 ++++++++++++++++++++++++++++--------------------------------- 1 file changed, 128 insertions(+), 156 deletions(-) (limited to 'lps_gen.py') diff --git a/lps_gen.py b/lps_gen.py index f8b1ab6..de2c5c2 100644 --- a/lps_gen.py +++ b/lps_gen.py @@ -42,14 +42,14 @@ def read_file(filename): :param str filename: Absolute pathname of the file. """ - content = '' + content = "" try: - with open(filename, 'r') as f: + with open(filename, "r") as f: for line in f: content = content + line except IOError: - print('Error: unable to open {}'.format(filename)) + print("Error: unable to open {}".format(filename)) return content @@ -65,11 +65,11 @@ def write_file(filename, filecontent): """ file_ = None try: - file_ = open(filename, 'w') - file_.write(filecontent) - file_.close() + file_ = open(filename, "w") + file_.write(filecontent) + file_.close() except IOError: - print('Error creating and writing content to {}'.format(filename)) + print("Error creating and writing content to {}".format(filename)) exit(1) @@ -89,19 +89,18 @@ def json_read(filename): if not path.isfile(filename): return False - return json.loads(read_file(filename), - object_pairs_hook=OrderedDict) + return json.loads(read_file(filename), object_pairs_hook=OrderedDict) def template_read(name): """Return template as `str`. """ - p = 'lpschedule_generator' - r = 'data/{}.jinja2'.format(name) + p = "lpschedule_generator" + r = "data/{}.jinja2".format(name) t = None try: - t = pkgr.resource_string(p, r).decode('utf-8') + t = pkgr.resource_string(p, r).decode("utf-8") except Exception as e: print(e, file=sys.stderr) @@ -117,15 +116,14 @@ class LPiCal(object): self.lp_year = str(lp_year) # Matches strings like '09:45 - 10:30: Lorem ipsum dolor sit.' - self.timeslot_re = re.compile(r'(\d+:\d+).+?(\d+:\d+)' - r'\s*[:-]?\s*(.+\b)?') + self.timeslot_re = re.compile(r"(\d+:\d+).+?(\d+:\d+)" r"\s*[:-]?\s*(.+\b)?") # Matches strings like 'Saturday, March 19' - self.month_day_re = re.compile(r'\w+,\s*([a-zA-Z]+)\s*(\d+)') + self.month_day_re = re.compile(r"\w+,\s*([a-zA-Z]+)\s*(\d+)") self.cal = Calendar() - self.cal.add('prodid', '-//lpschedule generator//mxm.dk//') - self.cal.add('version', '2.0') - self.cal.add('x-wr-calname', 'LibrePlanet {}'.format(self.lp_year)) + self.cal.add("prodid", "-//lpschedule generator//mxm.dk//") + self.cal.add("version", "2.0") + self.cal.add("x-wr-calname", "LibrePlanet {}".format(self.lp_year)) # RFC 2445 requires DTSTAMP to be in UTC. DTSTAMP is used in # VEVENT (Event object, see `add_event` method). @@ -134,16 +132,13 @@ class LPiCal(object): # used to generate uid for ical. self.ucounter = 0 - def gen_uid(self): """Returns an unique id. Used for Event object. """ self.ucounter = self.ucounter + 1 - return '{}@LP{}@libreplanet.org'.format(str(self.ucounter), - self.lp_year) - + return "{}@LP{}@libreplanet.org".format(str(self.ucounter), self.lp_year) def get_timeslot(self, s): """Get start and end time for a timeslot. @@ -156,11 +151,10 @@ class LPiCal(object): t_start = timeslot.group(1) t_end = timeslot.group(2) - name = timeslot.group(3) or '' + name = timeslot.group(3) or "" return t_start, t_end, name - def get_month_day(self, s): """Get month and day. """ @@ -175,7 +169,6 @@ class LPiCal(object): return month, day - def mk_datetime(self, month, day, time): """Returns datetime object (EST). """ @@ -185,78 +178,72 @@ class LPiCal(object): # Hour %H (24-hr) # Minute %M (zero padded) # Second %S (zero padded) - datetime_fmt = '%d %B %Y %H:%M:%S' - eastern = timezone('US/Eastern') + datetime_fmt = "%d %B %Y %H:%M:%S" + eastern = timezone("US/Eastern") - hour = time.split(':')[0] - minute = time.split(':')[1] - datetime_str = '{} {} {} {}:{}:{}'.format(day, month, - self.lp_year, - hour.zfill(2), - minute.zfill(2), - '00') + hour = time.split(":")[0] + minute = time.split(":")[1] + datetime_str = "{} {} {} {}:{}:{}".format( + day, month, self.lp_year, hour.zfill(2), minute.zfill(2), "00" + ) dt_object = datetime.strptime(datetime_str, datetime_fmt) return vDatetime(eastern.localize(dt_object)) - def mk_attendee(self, speaker): """Make Attendee to be added to an Event object. See `add_event` method. """ # Get rid of HTML ( element, etc) in `speaker` - speaker = BeautifulSoup(speaker, 'html.parser').get_text() + speaker = BeautifulSoup(speaker, "html.parser").get_text() - attendee = vCalAddress('invalid:nomail') - attendee.params['cn'] = vText(speaker) - attendee.params['ROLE'] = vText('REQ-PARTICIPANT') - attendee.params['CUTYPE'] = vText('INDIVIDUAL') + attendee = vCalAddress("invalid:nomail") + attendee.params["cn"] = vText(speaker) + attendee.params["ROLE"] = vText("REQ-PARTICIPANT") + attendee.params["CUTYPE"] = vText("INDIVIDUAL") return attendee - - def add_event(self, month, day, t_start, t_end, t_name, session, - session_info): + def add_event(self, month, day, t_start, t_end, t_name, session, session_info): """Adds event to calendar. """ event = Event() - event['uid'] = self.gen_uid() - event['dtstamp'] = self.dtstamp - event['class'] = vText('PUBLIC') - event['status'] = vText('CONFIRMED') - event['method'] = vText('PUBLISH') - - if session == 'st-from-ts': - event['summary'] = t_name + event["uid"] = self.gen_uid() + event["dtstamp"] = self.dtstamp + event["class"] = vText("PUBLIC") + event["status"] = vText("CONFIRMED") + event["method"] = vText("PUBLISH") + + if session == "st-from-ts": + event["summary"] = t_name else: - event['summary'] = session + event["summary"] = session - event['location'] = vText(session_info['room']) + event["location"] = vText(session_info["room"]) # Get rid of HTML in 'desc' - desc = BeautifulSoup(' '.join( - session_info['desc']).replace( - '\n', ' '), 'html.parser').get_text() - event['description'] = desc + desc = BeautifulSoup( + " ".join(session_info["desc"]).replace("\n", " "), "html.parser" + ).get_text() + event["description"] = desc # Add speakers - for speaker in session_info['speakers']: - event.add('attendee', self.mk_attendee(speaker), encode=0) + for speaker in session_info["speakers"]: + event.add("attendee", self.mk_attendee(speaker), encode=0) dt_start = self.mk_datetime(month, day, t_start) dt_end = self.mk_datetime(month, day, t_end) - event['dtstart'] = dt_start - event['dtend'] = dt_end + event["dtstart"] = dt_start + event["dtend"] = dt_end # Add to calendar self.cal.add_component(event) return event - def gen_ical(self): """Parse LP schedule dict and generate iCal Calendar object. """ @@ -274,16 +261,16 @@ class LPiCal(object): # this timeslot continue for session, session_info in sessions.items(): - self.add_event(month, day, t_start, t_end, t_name, - session, session_info) - - return self.cal.to_ical().decode('utf-8') + self.add_event( + month, day, t_start, t_end, t_name, session, session_info + ) + return self.cal.to_ical().decode("utf-8") def to_ical(self): """Writes iCal to disk. """ - filename = 'lp{}-schedule.ics'.format(self.lp_year) + filename = "lp{}-schedule.ics".format(self.lp_year) write_file(filename, self.gen_ical()) return filename @@ -313,8 +300,7 @@ class LPSRenderer(Renderer): # If it is 'False', then the 'speaker.ids' file was not found; # otherwise it is an OrderedDict containing the mapping of # speakers and their corresponding id. - self.speakers_ids = json_read('speakers.ids') - + self.speakers_ids = json_read("speakers.ids") def get_uid(self, speaker): """Generate unique id for `speaker`. @@ -332,7 +318,6 @@ class LPSRenderer(Renderer): # speaker not found in speakers_ids OrderedDict. return False - def _check_session_title_exists(self): """Checks if :py:attr:`.last_session` is set. @@ -356,10 +341,8 @@ class LPSRenderer(Renderer): # no session title. # # st-from-ts -> session title from time slot. - lps_dict[self.last_day][self.last_time_slot][ - 'st-from-ts'] = OrderedDict() - self.last_session = 'st-from-ts' - + lps_dict[self.last_day][self.last_time_slot]["st-from-ts"] = OrderedDict() + self.last_session = "st-from-ts" def _process_video(self, text): """Process the video text. @@ -369,15 +352,15 @@ class LPSRenderer(Renderer): This method is meant to be called from the :py:method:`.paragraph` method. """ - soup = BeautifulSoup(text, 'html.parser') - links = soup.find_all('a') + soup = BeautifulSoup(text, "html.parser") + links = soup.find_all("a") if len(links) == 0: # no links found, so return text # link(s) found, return the first link's href. - return links[0]['href'] + return links[0]["href"] def link(self, link, title, text): # Here, we catch speaker names that have to be autolinked and @@ -388,7 +371,7 @@ class LPSRenderer(Renderer): # Here, `text` is the speaker' name. id_ = self.get_uid(text) if id_: - link = 'speakers.html#{}'.format(id_) + link = "speakers.html#{}".format(id_) else: # Oh no, there is no id for this speaker. self.speakers_noids.append(text) @@ -397,7 +380,6 @@ class LPSRenderer(Renderer): return super(LPSRenderer, self).link(link, title, text) - def header(self, text, level, raw=None): global lps_dict @@ -415,8 +397,7 @@ class LPSRenderer(Renderer): self.last_session = None elif level == 4: # Add new session - lps_dict[self.last_day][self.last_time_slot][ - text] = OrderedDict() + lps_dict[self.last_day][self.last_time_slot][text] = OrderedDict() self.last_session = text # We found a new session; set no of paragraphs processed # to 0. @@ -424,7 +405,6 @@ class LPSRenderer(Renderer): return super(LPSRenderer, self).header(text, level, raw) - def paragraph(self, text): global lps_dict @@ -433,26 +413,29 @@ class LPSRenderer(Renderer): if self.no_paragraph == 0: # Speaker - speakers = text.split(', ') + speakers = text.split(", ") - lps_dict[self.last_day][self.last_time_slot][ - self.last_session]['speakers'] = speakers + lps_dict[self.last_day][self.last_time_slot][self.last_session][ + "speakers" + ] = speakers self.no_paragraph = self.no_paragraph + 1 elif self.no_paragraph == 1: # Room - lps_dict[self.last_day][self.last_time_slot][ - self.last_session]['room'] = text + lps_dict[self.last_day][self.last_time_slot][self.last_session][ + "room" + ] = text self.no_paragraph = self.no_paragraph + 1 elif self.no_paragraph == 2: - lps_dict[self.last_day][self.last_time_slot][ - self.last_session]['video'] = self._process_video(text) + lps_dict[self.last_day][self.last_time_slot][self.last_session][ + "video" + ] = self._process_video(text) # Initialize description - lps_dict[self.last_day][self.last_time_slot][ - self.last_session]['desc'] = [] + lps_dict[self.last_day][self.last_time_slot][self.last_session]["desc"] = [] self.no_paragraph = self.no_paragraph + 1 elif self.no_paragraph > 1: - lps_dict[self.last_day][self.last_time_slot][ - self.last_session]['desc'].append(text) + lps_dict[self.last_day][self.last_time_slot][self.last_session][ + "desc" + ].append(text) return p @@ -466,8 +449,8 @@ class LPSpeakersRenderer(Renderer): global lpspeakers_dict lpspeakers_dict = OrderedDict() - lpspeakers_dict['keynote-speakers'] = [] - lpspeakers_dict['speakers'] = [] + lpspeakers_dict["keynote-speakers"] = [] + lpspeakers_dict["speakers"] = [] # Type of present speaker being processed; can either be # 'keynote-speakers' or 'speakers'. @@ -476,12 +459,11 @@ class LPSpeakersRenderer(Renderer): # Maintain a dict of speakers and their IDs. self.speakers_ids = OrderedDict() - def mk_uid(self, speaker_block): """Returns a unique id. """ # 'John HÖcker, Onion Project' -> 'John HÖcker' - speaker = str(speaker_block.split(', ')[0]) + speaker = str(speaker_block.split(", ")[0]) # 'John HÖcker' -> 'John Hacker' ascii_speaker = unidecode(speaker) @@ -490,60 +472,52 @@ class LPSpeakersRenderer(Renderer): id_ = ascii_speaker.split()[-1].lower() if id_ not in self.speakers_ids.values(): - self.speakers_ids[speaker]= id_ + self.speakers_ids[speaker] = id_ return id_ else: # 'John Hacker' -> 'john_hacker' - id_ = '_'.join([s.lower() for s in ascii_speaker.split()]) + id_ = "_".join([s.lower() for s in ascii_speaker.split()]) self.speakers_ids[speaker] = id_ return id_ - def header(self, text, level, raw=None): global lpspeakers_dict if level == 1: - self.speaker_type = 'keynote-speakers' + self.speaker_type = "keynote-speakers" lpspeakers_dict[self.speaker_type].append(OrderedDict()) - lpspeakers_dict[self.speaker_type][-1]['speaker'] = text - lpspeakers_dict[self.speaker_type][-1][ - 'id'] = self.mk_uid(text) - lpspeakers_dict[self.speaker_type][-1][ - 'bio'] = [] + lpspeakers_dict[self.speaker_type][-1]["speaker"] = text + lpspeakers_dict[self.speaker_type][-1]["id"] = self.mk_uid(text) + lpspeakers_dict[self.speaker_type][-1]["bio"] = [] elif level == 2: - self.speaker_type = 'speakers' + self.speaker_type = "speakers" lpspeakers_dict[self.speaker_type].append(OrderedDict()) - lpspeakers_dict[self.speaker_type][ - -1]['speaker'] = text.split(', ')[0] - lpspeakers_dict[self.speaker_type][ - -1]['id'] = self.mk_uid(text) - lpspeakers_dict[self.speaker_type][ - -1]['bio'] = [] + lpspeakers_dict[self.speaker_type][-1]["speaker"] = text.split(", ")[0] + lpspeakers_dict[self.speaker_type][-1]["id"] = self.mk_uid(text) + lpspeakers_dict[self.speaker_type][-1]["bio"] = [] return super(LPSpeakersRenderer, self).header(text, level, raw) - def image(self, src, title, text): global lpspeakers_dict - lpspeakers_dict[self.speaker_type][-1]['img_url'] = src - lpspeakers_dict[self.speaker_type][-1]['img_alt'] = text + lpspeakers_dict[self.speaker_type][-1]["img_url"] = src + lpspeakers_dict[self.speaker_type][-1]["img_alt"] = text return super(LPSpeakersRenderer, self).image(src, title, text) - def paragraph(self, text): global lpspeakers_dict p = super(LPSpeakersRenderer, self).paragraph(text) - if text.startswith('