diff --git a/README.md b/README.md index 991dac0..8b62e31 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The host sees the answer on the laptop screen and can adjudicate with the arrow - WebSocket buzzer for use on mobile devices - Up to 8 players - Complete access to all games on J-Archive -- Load custom games via a simple Google Sheets template +- Load custom games via a simple Google Sheets template - Scrape games from https://jeopardylabs.com using this Google Chrome extension - Final Jeopardy, Daily Doubles, Double Jeopardy @@ -54,17 +54,17 @@ The host sees the answer on the laptop screen and can adjudicate with the arrow To debug, run -` -pip install -r requirements.txt; -cd jparty; +``` +conda env create -f environment.yml +cd jparty python ../run.py -` +``` -Too build from source, run +To build from source, run -` +``` pyinstaller -y JParty.spec -` +``` ## FAQ @@ -72,12 +72,12 @@ pyinstaller -y JParty.spec JParty minimally scrapes the J-Archive (https://j-archive.com) to download a previously-played game and then simulates that on the screen. The game then uses PyQt6 to produce a GUI that simulates the motions of a full _Jeopardy!_ game. A `tornado` web server uses WebSockets to connect to the contestants' smartphones. If that's all gibberish to you, don't worry! You can still play without any technical knowledge. ### Can I create my own custom game? -Yes! JParty supports playing your own custom game via this simple Google Sheets template. First, make a copy of the template and change the sharing permissions to "Anyone With the Link Can View". Then, copy the Google Sheet file ID and paste it into the "Game ID" box. There are more detailed instructions on the template page. Limitations: there is no way to add pictures (yet!) and you are limited to the traditional 6 categories x 5 dollar values board. +Yes! JParty supports playing your own custom game via this simple Google Sheets template. First, make a copy of the template and change the sharing permissions to "Anyone With the Link Can View". Then, copy the Google Sheet file ID and paste it into the "Game ID" box. There are more detailed instructions on the template page. Limitations: there is no way to add pictures (yet!) and you are limited to the traditional 6 categories x 5 dollar values board. If you don't want to write your own questions but want to play a topical _Jeopardy!_ game, use this handy Google Chrome extension to scrape Jeopardy Labs questions (source code). There are millions of games available on https://jeopardylabs.com that are free to play on a variety of topics. While Jeopardy Labs is a great repository for many topical games & worked great 20 years ago, it lacks in features such as daily doubles, final jeopardy, music/sound effects, and buzzers. To use the extension: -1. Make a copy of the Jparty Google Sheets custom game template +1. Make a copy of the Jparty Google Sheets custom game template 2. Find a game on https://jeopardylabs.com. 3. Click the extension icon. 4. The questions will download as a csv (spreadsheet) in the style of the template. diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..1165d19 --- /dev/null +++ b/environment.yml @@ -0,0 +1,11 @@ +name: JParty +dependencies: + - requests==2.31.0 + - tornado==6.3.3 + - beautifulsoup4==4.11.1 + - pip + - pip: + - pyinstaller==6.6.0 + - pyqt6==6.4.0 + - qrcode==7.3.1 + - simpleaudio==1.0.4 diff --git a/jparty/retrieve.py b/jparty/retrieve.py index f11ef7e..b9c3b37 100644 --- a/jparty/retrieve.py +++ b/jparty/retrieve.py @@ -52,7 +52,11 @@ def get_Gsheet_game(file_id): def get_game(game_id): if len(str(game_id)) < 7: - return get_wayback_jarchive_game(game_id) + try: + return get_wayback_game(game_id) + except Exception as e: + logging.error(e) + return get_jarchive_game(game_id) else: return get_Gsheet_game(str(game_id)) @@ -60,12 +64,12 @@ def get_game(game_id): def findanswer(clue): return re.findall(r'correct_response">(.*?) h1")[0].contents[0] @@ -121,7 +125,7 @@ def get_JArchive_Game(game_id, wayback_url=None): return GameData(boards, date, comments) -def get_wayback_jarchive_game(game_id): +def get_wayback_game(game_id): # kudos to Abhi Kumbar: https://medium.com/analytics-vidhya/the-wayback-machine-scraper-63238f6abb66 # this query's the wayback cdx api for possible instances of the saved jarchive page with the specified game id & returns the latest one JArchive_url = f"j-archive.com/showgame.php?game_id={str(game_id)}" # use the url w/o the http:// or https:// to include both in query @@ -130,9 +134,8 @@ def get_wayback_jarchive_game(game_id): parse_url = json.loads(urls) # parses the JSON from urls. if len(parse_url) == 0: # if no results, return None logging.info("no games found in wayback") - # return None # alternative: use fallback to get game from scraping j-archive directly - return get_JArchive_Game(game_id) + raise Exception("no games found in wayback") ## Extracts timestamp and original columns from urls and compiles a url list. url_list = [] @@ -143,7 +146,8 @@ def get_wayback_jarchive_game(game_id): final_url = f'http://web.archive.org/web/{waylink}' url_list.append(final_url) latest_url = url_list[-1] - return get_JArchive_Game(game_id, latest_url) + return get_generic_game(game_id, latest_url) + def get_game_sum(soup): date = re.search( diff --git a/requirements.txt b/requirements.txt index 799e7b5..a834fa0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ PyQt6==6.4.0 -requests==2.31.0 +requests==2.32.0 simpleaudio==1.0.4 tornado==6.3.3 BeautifulSoup4==4.11.1 -pyinstaller==5.6.2 +pyinstaller==5.13.1 qrcode==7.3.1 \ No newline at end of file