Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 50 additions & 56 deletions guidebook/sync_guidebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
except ImportError:
import xdg

DBASE_DEFAULT = "https://www.socallinuxexpo.org/scale/23x/app"
EVENTS_FEED = "https://www.socallinuxexpo.org/scale/23x/app"
TRACKS_FEED = "https://www.socallinuxexpo.org/api/tracks/23x"
GUIDE_NAME = "SCaLE 23x"


Expand Down Expand Up @@ -153,7 +154,7 @@ def send_to_datadog(self, logger, dryrun=False):

class OurJSON:
rooms = set()
tracks = set()
tracks = {}
sessions_by_name = {}
sessions_by_nid = {}

Expand All @@ -162,28 +163,42 @@ class OurJSON:
"rooms": "Location",
}

def __init__(self, path, logger):
def __init__(self, event_feed, track_feed, logger):
self.logger = logger

event_data = self._get_feed_data(event_feed)
track_data = self._get_feed_data(track_feed)

self.sessions_by_name, self.sessions_by_nid = self._load_event_json(
event_data
)
self.tracks = self._load_tracks_json(track_data)

def _get_feed_data(self, path):
self.logger.info("Loading JSON feed from %s" % path)
if path.startswith("http://") or path.startswith("https://"):
response = requests.get(path)
blob = response.text
else:
blob = open(path, "r").read()
self.sessions_by_name, self.sessions_by_nid = self.load_json(blob)
return response.text
return open(path, "r").read()

def load_json(self, raw):
self.logger.info("Loading JSON file")
def _load_tracks_json(self, raw):
raw = json.loads(raw)
tracks = {}
for track in raw:
# temporary until we fix the feed
name = track["name"].replace("&", "&")
tracks[name] = track["color"]
return tracks

def _load_event_json(self, raw):
raw = json.loads(raw)
data_by_name = {}
data_by_nid = {}
for session in raw:
# handle leading/trailing spaces in names
name = session["Name"].strip()
session["Name"] = name
track = session[self.FIELD_MAPPING["tracks"]].strip()
room = session[self.FIELD_MAPPING["rooms"]].strip()
if track != "":
self.tracks.add(track)
if room != "":
self.rooms.add(room)
clean_session = {k: v.strip() for k, v in session.items()}
Expand All @@ -204,38 +219,6 @@ class GuideBook:
"publish": "https://builder.guidebook.com/api/guides/{guide}/publish/",
}

COLOR_MAP = {
"Applied Science": "#dddddd",
"AstriCon": "#8b4789",
"BoFs": "#ffbc00",
"Career Day": "#dddddd", # Open Source Career Day
"Cloud Native": "#638dce", # Cloud Native Days
"Developer": "#d65c09",
"DevOpsDay LA": "#565448",
"Embedded Linux": "#004a4a",
"Entertainment": "#ff6f91",
"Fedora Hatch Day": "#294172",
"FOSS @ HOME": "#998876",
"General": "#97a67a",
"HAM Radio": "#96beef",
"Higher Education": "#fff8dc", # Open Source in Higher Education
"Kernel & Low Level Systems": "#ffa200",
"Keynote": "#d31111",
"Kwaai Summit": "#4b2e83",
"LibreGraphics": "#e10098",
"MySQL": "#0aaca0",
"Next Generation": "#96f74b", # The Next Generation
"Observability": "#ffbc00",
"Open Government": "#6c6c6c",
"Open Source AI": "#ffd672",
"PlanetNix": "#2d5d3f",
"PostgreSQL": "#0aaca0",
"Security": "#000000",
"SunSecCon": "#e63946",
"Systems & Infrastructure": "#c4c249",
"Workshops": "#774022",
}

ROOM_TO_MAP_REGION = {
"Ballroom A": {"h": 0.04, "w": 0.056, "x": 0.668, "y": 0.477},
"Ballroom B": {"h": 0.04, "w": 0.056, "x": 0.668, "y": 0.519},
Expand Down Expand Up @@ -406,7 +389,7 @@ def add_thing(self, thing, name, data, update, tid):
sys.exit(1)
return response

def add_track(self, track, update, tid):
def add_track(self, track, color, update, tid):
"""
Track-specific wrapper around add_thing()
"""
Expand All @@ -416,34 +399,38 @@ def add_track(self, track, update, tid):
"guide": self.guide,
"name": track,
# NOTE WELL: Guidebook cannot handle lower-case letters
"color": self.COLOR_MAP[track].upper(),
"color": color,
}
self.tracks[track] = self.add_thing("tracks", track, data, update, tid)
newinfo = self.add_thing("tracks", track, data, update, tid)
if not self.dryrun:
self.tracks[track] = newinfo
operation = "updated" if update else "added"
self.stats.increment("tracks", operation)

def setup_tracks(self, tracks):
"""
Add all tracks passed in if missing.
"""
for track in tracks:
for track, color in tracks.items():
# Guidebook only deals in upper-case colors, so we must match
color = color.upper()
update = False
tid = None
if track in self.tracks:
orig = self.tracks[track]
# the only "info" about a track is the color (the name is
# our primary key), so if the color is correct, it's up to date.
if orig["color"].upper() == self.COLOR_MAP[track].upper():
if orig["color"] == color:
self.logger.debug(
"Track '%s' exists in Guidebook and has correct color"
" %s. No update needed.",
track,
self.COLOR_MAP[track].upper(),
color,
)
continue
update = True
tid = self.tracks[track]["id"]
self.add_track(track, update, tid)
self.add_track(track, color, update, tid)

def add_room(self, room, update, rid):
"""
Expand Down Expand Up @@ -966,12 +953,17 @@ def get_tokens(logger):
help="Delete all tracks, rooms, and sessions",
)
@click.option(
"--json",
"feed",
"--event-feed",
metavar="FILE_OR_URL",
default=DBASE_DEFAULT,
default=EVENTS_FEED,
help="JSON file or http(s) URL to JSON data.",
)
@click.option(
"--track-feed",
metavar="FILE_OR_URL",
default=TRACKS_FEED,
help="JSON file or http(s) URL to track data.",
)
@click.option(
"--dryrun/--no-dryrun",
"-n",
Expand All @@ -984,7 +976,9 @@ def get_tokens(logger):
help="Max number of sessions to delete when syncing. Zero will not"
" delete any sessions. Ignored if --delete-all is used.",
)
def main(debug, update, delete_all, feed, dryrun, max_deletes):
def main(
debug, update, delete_all, event_feed, track_feed, dryrun, max_deletes
):
"""
Sync the schedule data from our website to Guidebook.

Expand Down Expand Up @@ -1019,7 +1013,7 @@ def main(debug, update, delete_all, feed, dryrun, max_deletes):
print("into a schedule to lose all of that work.")
click.confirm("ARE YOU FUCKING SURE?!", abort=True)
else:
ourdata = OurJSON(feed, logger)
ourdata = OurJSON(event_feed, track_feed, logger)

ourguide = GuideBook(
logger, update, dryrun, max_deletes, key, stats_tracker, x_key=x_key
Expand Down