Skip to content

Instantly share code, notes, and snippets.

@suhailpatel
Created March 19, 2022 21:41
Show Gist options
  • Save suhailpatel/0314ebcd8d209d5cace5d59f855899c0 to your computer and use it in GitHub Desktop.
Save suhailpatel/0314ebcd8d209d5cace5d59f855899c0 to your computer and use it in GitHub Desktop.
A CLI to interact with the QCon London 2022 website
#!/usr/bin/python3
import cmd, re, sys, traceback
from dataclasses import dataclass
from typing import List
import requests
from bs4 import BeautifulSoup
# This is part of Suhail's talk on the Developer Enablement
# track at QCon London 2022
class QConShell(cmd.Cmd):
prompt = '\nQCon London 🇬🇧 2022 > '
def __init__(self):
super(QConShell, self).__init__()
self.postcmd(None, None)
def postcmd(self, stop, line):
if self.lastcmd == "exit":
return True
def do_schedule(self, args):
req = requests.get("https://qconlondon.com/schedule/london2022/apr/tabular")
for item in parse_schedule(req.content):
print(f"{item.date_time} | {item.talk_title} - {item.author} ({item.room})")
def do_tracks(self, args):
req = requests.get("https://qconlondon.com/#program")
for item in parse_tracks(req.content):
print(f"{item.day} | {item.track_title} - {item.host} ({item.bio})")
def do_speakers(self, args):
req = requests.get("https://qconlondon.com/speakers/london2022/apr")
for item in sorted(parse_speakers(req.content), key=lambda x: x.name):
print(f"{item.name} ({item.bio})")
def do_exit(self, _):
raise KeyboardInterrupt()
@dataclass
class ScheduleItem:
talk_title: str
author: str
date_time: str
room: str
# I hereby apologise to all the Pythonistas and BeautifulSoup gurus
# for my sloppy parsing code, it got the job done for the demo :)
def parse_schedule(contents):
soup = BeautifulSoup(contents, features="html.parser")
output = []
for row in soup.findAll('tr', class_='presentations-row'):
for item in row.findAll('td', class_='presentation'):
talk_title = clean_string(item.findAll('a', class_='presentation-title')[0].string)
author = clean_string(item.findAll('div', class_='session-speakers')[0].getText())
date_time = clean_string(item['data-start'])
room = clean_string(item.findAll('span', class_='location')[0].string)
output.append(ScheduleItem(talk_title, author, date_time, room))
return output
@dataclass
class TrackItem:
track_title: str
host: str
bio: str
day: str
def parse_tracks(contents):
soup = BeautifulSoup(contents, features="html.parser")
output = []
for item in soup.findAll('div', class_='border-l-4'):
title = clean_string(item.findAll('a', class_='text-black')[0].string)
host = clean_string(item.findAll('a', class_='text-black')[1].findAll('span')[0].string)
bio = clean_string(item.findAll('a', class_='text-black')[1].findAll('span')[1].string)
date = clean_string(item.findAll('p', class_='track-date')[0].string)
output.append(TrackItem(title, host, bio, date))
return output
@dataclass
class SpeakerItem:
name: str
bio: str
def parse_speakers(contents):
soup = BeautifulSoup(contents, features="html.parser")
output = []
for item in soup.findAll('section', class_='max-w-screen-xl')[0].findAll('div', class_='xl:p-6'):
name = clean_string(item.findAll('h4')[0].string)
bio = clean_string(item.findAll('p')[0].string)
output.append(SpeakerItem(name, bio))
return output
def clean_string(input):
out = input.strip()
return re.sub(r"\s+", " ", out)
if __name__ == '__main__':
print(f"Welcome to the Developer Enablement Track at QCon London 2022")
shell = QConShell()
while True:
try:
shell.cmdloop()
except KeyboardInterrupt:
sys.exit()
except:
traceback.print_exc()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment