diff --git a/.gitignore b/.gitignore index b09ed1f..2d18ad1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ __pycache__/ -build.sh -gamebuild/* -!gamebuild/*.css -!gamebuild/*.png -placebuild/* -!placebuild/.gitkeep -recordbuild/index.html -variables.py \ No newline at end of file +build/games/* +!build/games/*.css +!build/games/*.png +secrets.py +build/places/* +!build/places/.gitkeep +placelist.py \ No newline at end of file diff --git a/README.org b/README.org deleted file mode 100644 index a920785..0000000 --- a/README.org +++ /dev/null @@ -1,67 +0,0 @@ -#+TITLE: Trackers - -* About -The scripts in this repository build static webpages based on information from two sources: -- a structured set of =.org= files; -- APIs of selected third-party websites (so far: Discogs). -These pages can be used as a replacement for third-party services e.g. Backloggery. -* Dependencies -- =orgparse= (install via pip) -- =python3= -- =rclone= (for syncing to the server) -- =geopy= if you are tracking places visited (install via pip) -- =python3-discogs-client= if you are displaying a record collection (install via pip) -* General setup -** Structure of the .org files -See =demo.org= for an example. -** Setting the variables -Copy =variables-template.py= to =variables.py= and edit: -- =orgpath=: absolute path to the root directory in which =.org= files are stored, including trailing slash -- =localpath=: absolute path to this directory, including trailing slash -- =domain=: =https://yourdomain.tld= without trailing slash -- =rclonesiteroot=: path =rclone= uses to access your webserver -* Tracking games with a backloggery clone -** Setup -*** Fonts -Upload the fonts Lato, Titillium Web, and Material Icons to the directory =/fonts= on your server (I recommend [[https://gwfh.mranftl.com/fonts][google-webfonts-helper]]). Check the filenames are consistent with those in =gamebuild/backloggery.css=. Alternatively, you can load the fonts remotely and adjust the page head HTML generated by =gameskel.py=. -*** Setting the variables -In =variables.py=, edit: -- =trackgames=: set to =True= -- =gameserverpath=: path to directory on the server where files will be uploaded, including trailing slash -- =endlessgames=: a list of “endless” games in the format =title (console)= -- =description=: content for the “about” section (can include HTML tags) -- =gamestartyear=: year from which to begin tracking (an integer) -- =gamehue=: theme colour expressed as a hue from 0 to 360 -- =consoles=: add or remove consoles following the format provided (=.png= images must be added to the build directory with a filename corresponding with the value of ="img"= for each console) -** Testing -- Run =python3 generategames.py local= to build in =gamebuild=. -* Tracking places visited using Leaflet -** Setup -Upload a CSS file to the server if necessary. Most CSS is set by Leaflet. -*** Setting the variables -In =variables.py=, edit: -- =trackplaces=: set to =True= -- =placeserverpath=: path to directory on the server where files will be uploaded, including trailing slash -- =placestartyear=: year from which to begin tracking (an integer) -- =placecss=: location of the CSS file you wish to apply, relative to the site root -** Testing -- Run =python3 generateplaces.py local= to build in =placebuild=. (This may take some time.) -- Check whether places are displayed accurately in the output file. If not, add regions/countries to disambiguate any incorrectly displayed places to the =disambig= dictionary in =variables.py= (see examples). -* Displaying a record collection (taking data from Discogs) -** Setup -- Upload a CSS file to the server for styling fonts etc; most CSS is set inline. -- Get a Discogs API token [[https://www.discogs.com/settings/developers][here]]. -*** Setting the variables -In =variables.py=, edit: -- =trackrecords=: set to =True= -- =recordserverpath=: path to directory on the server where files will be uploaded, including trailing slash -- =recordcss=: location of the CSS file you wish to apply, relative to the site root -- =discogstoken=: the API token you generated -- =discogsuser=: your Discogs username -** Testing -- Run =python3 generaterecords.py local= to build in =recordbuild=. -* First run (or if adding any new trackers) -- Run =python3 init.py= and then =chmod +x build.sh=. -- Create directories on the server corresponding to any =*serverpath= variables you have set. -* Building -- Run =./build.sh= to build and upload to the server. diff --git a/backlog.py b/backlog.py deleted file mode 100644 index 05bd707..0000000 --- a/backlog.py +++ /dev/null @@ -1,413 +0,0 @@ -import os -import cardstring,gamesort,gameskel,variables -from pathlib import Path -from datetime import datetime,timedelta - -""" -Generates backlog page -""" - -home = str(Path.home()) - -def backlog(local=False): - # delete existing file - if not os.path.isdir("gamebuild/backlog"): - os.mkdir("gamebuild/backlog") - if os.path.exists("gamebuild/backlog/index.html"): - os.remove("gamebuild/backlog/index.html") - # write header - gameskel.headerwrite("gamebuild/backlog/index.html","backlog",local) - output = "gamebuild/backlog/index.html" - filewrite = open(output, "a") - filewrite.write("
\n
\n

Now Playing

\n
\n") - playingnow = [] - def nowplaying(): - for console in gamesort.consolelists: - if len(console["games"]) > 0: - thegame = (console["games"])[-1] - try: - if thegame["gameplay"] > (datetime.now() - timedelta(days=180)): - try: - if thegame["completed"]: - if thegame["completed"] >= thegame["gameplay"]: - playing = False - else: - playing = True - except: - try: - if thegame["beaten"]: - if thegame["beaten"] >= thegame["gameplay"]: - playing = False - else: - playing = True - except: - playing = True - else: - playing = False - except: - playing = False - if playing == True: - playingnow.append(thegame) - - nowplaying() - - playingnow = sorted(playingnow,key=lambda d: d["lastupdate"],reverse=True) - - for game in playingnow: - if playingnow.index(game) == 0: - filewrite.write(cardstring.playcard(game,local)) - else: - filewrite.write(cardstring.playcard(game,local,True)) - - filewrite.write("
\n") - - # BACKLOG BREAKDOWN - - filewrite.write("

Backlog Breakdown

\n
\n
\n
\n \n
\n \n " + gamesort.thisyear + " Backlog\n ") - - if yeargames > 0: - filewrite.write("⬆") - elif yeargames < 0: - filewrite.write("⬇") - - filewrite.write(str(abs(yeargames)) + "\n \n \n") - - yearbacklog = [] - for game in gamesort.games: - try: - if game["completed"].year == int(gamesort.thisyear): - yearbacklog.append(game) - except: - try: - if game["beaten"].year == int(gamesort.thisyear): - yearbacklog.append(game) - except: - if game["initialdate"].year == int(gamesort.thisyear): - yearbacklog.append(game) - - yearcompleted = 0 - yearbeaten = 0 - yearendless = 0 - yearunfinished = 0 - yeartotal = len(yearbacklog) - if yeartotal > 0: - for game in yearbacklog: - try: - if game["completed"]: - yearcompleted += 1 - except: - try: - if game["beaten"]: - yearbeaten += 1 - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - yearendless += 1 - else: - yearunfinished += 1 - except: - pass - yearunplayed = yeartotal - (yearcompleted + yearbeaten + yearunfinished + yearendless) - yeartakeup = 100 - if yearunplayed > 0: - filewrite.write(" \n \n") - yeartakeup = yeartakeup - round(((yearunplayed/yeartotal)*100),1) - if yearunfinished > 0: - filewrite.write(" \n \n") - yeartakeup = yeartakeup - round(((yearunfinished/yeartotal)*100),1) - if yearbeaten > 0: - filewrite.write(" \n \n") - yeartakeup = yeartakeup - round(((yearbeaten/yeartotal)*100),1) - if yearcompleted > 0: - filewrite.write(" \n \n") - yeartakeup = yeartakeup - round(((yearcompleted/yeartotal)*100),1) - if yearendless > 0: - filewrite.write(" \n \n") - - filewrite.write(" \n
\n
\n
\n
\n
") - if ((backlog/gamesort.total(gamesort.games))*100) > 50: - filewrite.write("\n Total Backlog · " + str(backlog) + " · " + str(round(((backlog/gamesort.total(gamesort.games))*100),1)) + "%") - filewrite.write("\n
\n
") - if ((backlog/gamesort.total(gamesort.games))*100) <= 50: - filewrite.write("\n Active Backlog · " + str(backlog) + " · " + str(round(((backlog/gamesort.total(gamesort.games))*100),1)) + "%") - filewrite.write("\n
\n
\n") - - compare = [] - compare.append(gamesort.unplayed(gamesort.games)) - compare.append(gamesort.unfinished(gamesort.games)) - compare.append(gamesort.beaten(gamesort.games)) - compare.append(gamesort.completed(gamesort.games)) - compare.append(gamesort.endless(gamesort.games)) - maxvalue = max(compare) - - if gamesort.unplayed(gamesort.games) / maxvalue > 0.5: - filewrite.write(" \n
" + str(gamesort.unplayed(gamesort.games)) + "
\n
\n \n
\n
\n
" + str(round(((gamesort.unplayed(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Unplayed
\n
\n
\n") - else: - filewrite.write(" \n
" + str(gamesort.unplayed(gamesort.games)) + "
\n
\n \n
\n
\n
\n
\n
" + str(round(((gamesort.unplayed(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Unplayed
\n
\n
\n") - - if gamesort.unfinished(gamesort.games) / maxvalue > 0.5: - filewrite.write(" \n
" + str(gamesort.unfinished(gamesort.games)) + "
\n
\n \n
\n
\n
" + str(round(((gamesort.unfinished(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Unfinished
\n
\n
\n") - else: - filewrite.write(" \n
" + str(gamesort.unfinished(gamesort.games)) + "
\n
\n \n
\n
\n
\n
\n
" + str(round(((gamesort.unfinished(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Unfinished
\n
\n
\n") - - if gamesort.beaten(gamesort.games) / maxvalue > 0.5: - filewrite.write(" \n
" + str(gamesort.beaten(gamesort.games)) + "
\n
\n \n
\n
\n
" + str(round(((gamesort.beaten(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Beaten
\n
\n
\n") - else: - filewrite.write(" \n
" + str(gamesort.beaten(gamesort.games)) + "
\n
\n \n
\n
\n
\n
\n
" + str(round(((gamesort.beaten(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Beaten
\n
\n
\n") - - if gamesort.completed(gamesort.games) / maxvalue > 0.5: - filewrite.write(" \n
" + str(gamesort.completed(gamesort.games)) + "
\n
\n \n
\n
\n
" + str(round(((gamesort.completed(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Completed
\n
\n
\n") - else: - filewrite.write(" \n
" + str(gamesort.completed(gamesort.games)) + "
\n
\n \n
\n
\n
\n
\n
" + str(round(((gamesort.completed(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Completed
\n
\n
\n") - - if gamesort.endless(gamesort.games) / maxvalue > 0.5: - filewrite.write(" \n
" + str(gamesort.endless(gamesort.games)) + "
\n
\n \n
\n
\n
" + str(round(((gamesort.endless(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Endless
\n
\n
\n") - else: - filewrite.write(" \n
" + str(gamesort.endless(gamesort.games)) + "
\n
\n \n
\n
\n
\n
\n
" + str(round(((gamesort.endless(gamesort.games)/gamesort.total(gamesort.games))*100),1)) + "% Endless
\n
\n
\n") - - filewrite.write("
\n
\n
\n") - - # PLATFORM SUMMARY - - filewrite.write("

Platform Summary

\n
\n") - - listofconsoles = sorted(variables.consoles,key=lambda d: d["name"]) - - for console in listofconsoles: - consolegames = [] - for game in gamesort.games: - if game["console"] == console["code"]: - consolegames.append(game) - ccompleted = 0 - cbeaten = 0 - cendless = 0 - cunfinished = 0 - ctotal = len(consolegames) - if ctotal > 0: - filewrite.write("
\n " + console["name"] + "\n " + console["shortname"] + "\n
\n") - for game in consolegames: - try: - if game["completed"]: - ccompleted += 1 - except: - try: - if game["beaten"]: - cbeaten += 1 - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - cendless += 1 - else: - cunfinished += 1 - except: - pass - cunplayed = ctotal - (ccompleted + cbeaten + cunfinished + cendless) - if cunplayed > 0: - filewrite.write(" " + str(cunplayed) + "\n") - if cunfinished > 0: - filewrite.write(" " + str(cunfinished) + "\n") - if cbeaten > 0: - filewrite.write(" " + str(cbeaten) + "\n") - if ccompleted > 0: - filewrite.write(" " + str(ccompleted) + "\n") - if cendless > 0: - filewrite.write(" " + str(cendless) + "\n") - filewrite.write("
\n " + str(ctotal) + "\n Total\n \n
\n") - filewrite.write("
\n
\n \n") - filewrite.close() - gameskel.footerwrite("gamebuild/backlog/index.html") - -if __name__ == "__main__": - backlog(True) diff --git a/cardstring.py b/cardstring.py deleted file mode 100644 index 938a0be..0000000 --- a/cardstring.py +++ /dev/null @@ -1,205 +0,0 @@ -import gamesort,variables -from pathlib import Path -from datetime import datetime,timedelta - -home = str(Path.home()) - -def playcard(game,local=False,decay=False): - cardstring = "" - if decay == True: - cardstring += "
\n" - else: - cardstring += "
\n" - cardstring += " \n
\n
\n" - for console in variables.consoles: - if game["console"] == console["code"]: - cardstring += " \""\n" - cardstring += "
\n
\n
\n" - try: - if game["completed"]: - cardstring += " \"C\"\n" - except: - try: - if game["beaten"]: - cardstring += " \"B\"\n" - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - cardstring += " \"E\"\n" - else: - cardstring += " \"UF\"\n" - except: - cardstring += " \"UP\"\n" - cardstring += "
\n
\n
" + game["name"] + "
\n" - try: - if len(game["recent"]) > 1: - cardstring += "
" + game["recent"] + "
\n" - except: - pass - try: - if game["gameplay"]: - try: - if game["completed"]: - if game["gameplay"] > game["completed"]: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - cardstring += "
\n
\n \n
\n" - else: - cardstring += " \n
\n \"⯈\"\n
\n" - else: - cardstring += " \n
\n \n
\n" - except: - try: - if game["beaten"]: - if game["gameplay"] > game["beaten"]: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - cardstring += " \n
\n \n
\n" - else: - cardstring += " \n
\n \"⯈\"\n
\n" - else: - cardstring += " \n
\n \n
\n" - except: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - if game["id"] in variables.endlessgames: - cardstring += " \n
\n \n
\n" - else: - cardstring += " \n
\n \"⏸\"\n
\n" - else: - cardstring += " \n
\n \"⯈\"\n
\n" - except: - cardstring += " \n
\n \n
\n" - cardstring += "
\n
\n
\n
\n" - try: - if len(game["recent"]) > 1: - cardstring += "
\n \n
" + game["recent"] + "
\n
\n" - except: - pass - cardstring += "
\n
\n \n

" - try: - if game["completed"]: - cardstring += "Completed" - except: - try: - if game["beaten"]: - cardstring += "Beaten" - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - cardstring += "Endless" - else: - cardstring += "Unfinished" - except: - cardstring += "Unplayed" - cardstring += "

\n
\n
\n \n

" - try: - if game["gameplay"]: - try: - if game["completed"]: - if game["gameplay"] > game["completed"]: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - cardstring += "Not playing" - else: - cardstring += "Playing" - else: - cardstring += "Not playing" - except: - try: - if game["beaten"]: - if game["gameplay"] > game["beaten"]: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - cardstring += "Not playing" - else: - cardstring += "Playing" - else: - cardstring += "Not playing" - except: - if game["gameplay"] < (datetime.now() - timedelta(days=180)): - if game["id"] in variables.endlessgames: - cardstring += "Not playing" - else: - cardstring += "Paused" - else: - cardstring += "Playing" - except: - cardstring += "Not playing" - cardstring += "

\n
\n
\n
\n
\n
\n \n

" - for console in variables.consoles: - if game["console"] == console["code"]: - cardstring += console["name"] - cardstring += "

\n
\n
\n \n

" + game["lastupdate"].strftime("%Y-%m-%d") + "

\n
\n
\n
\n
\n
\n

Milestones

\n
\n
\n
" + game["initialdate"].strftime("%Y-%m-%d") + "
\n
\n
Added
\n
\n" - try: - if game["firstplayed"]: - cardstring += "
\n
" + game["firstplayed"].strftime("%Y-%m-%d") + "
\n
\n
Started
\n
\n" - except: - pass - try: - if game["beaten"]: - cardstring += "
\n
" + game["beaten"].strftime("%Y-%m-%d") + "
\n
\n
Beaten
\n
\n" - except: - pass - try: - if game["completed"]: - cardstring += "
\n
" + game["completed"].strftime("%Y-%m-%d") + "
\n
\n
Completed
\n
\n" - except: - pass - cardstring += "
\n
\n
\n
\n
\n" - return cardstring - -if __name__ == "__main__": - playcard(gamesort.games[0],True) diff --git a/demo.org b/demo.org deleted file mode 100644 index a06c603..0000000 --- a/demo.org +++ /dev/null @@ -1,18 +0,0 @@ -<2024-02-17 Sat> - -* note -Files should be stored in a tree and named like so: =YYYY/MM/YYYY-MM-DD.org=. -* games -** acquired -*** demo game 1 (ps2) -** gameplay -*** demo game 2 (pc) -Notes about the games can be stored under each heading. -** beaten -*** demo game 3 (pc) -** completed -*** demo game 4 (nintendo ds) -* places -** visited -*** demo place 1 -*** demo place 2 <2024-02-17 Sat>--<2024-02-18 Sun> diff --git a/gamebuild/360.png b/gamebuild/360.png deleted file mode 100644 index 3a7d379..0000000 Binary files a/gamebuild/360.png and /dev/null differ diff --git a/gamebuild/3DS.png b/gamebuild/3DS.png deleted file mode 100644 index b11d5a1..0000000 Binary files a/gamebuild/3DS.png and /dev/null differ diff --git a/gamebuild/B.png b/gamebuild/B.png deleted file mode 100644 index a01143c..0000000 Binary files a/gamebuild/B.png and /dev/null differ diff --git a/gamebuild/C.png b/gamebuild/C.png deleted file mode 100644 index ca4f592..0000000 Binary files a/gamebuild/C.png and /dev/null differ diff --git a/gamebuild/E.png b/gamebuild/E.png deleted file mode 100644 index e623c80..0000000 Binary files a/gamebuild/E.png and /dev/null differ diff --git a/gamebuild/NDS.png b/gamebuild/NDS.png deleted file mode 100644 index b127d65..0000000 Binary files a/gamebuild/NDS.png and /dev/null differ diff --git a/gamebuild/PC.png b/gamebuild/PC.png deleted file mode 100644 index 6809a28..0000000 Binary files a/gamebuild/PC.png and /dev/null differ diff --git a/gamebuild/PS2.png b/gamebuild/PS2.png deleted file mode 100644 index 0d84094..0000000 Binary files a/gamebuild/PS2.png and /dev/null differ diff --git a/gamebuild/PS3.png b/gamebuild/PS3.png deleted file mode 100644 index d7b6c89..0000000 Binary files a/gamebuild/PS3.png and /dev/null differ diff --git a/gamebuild/PS5.png b/gamebuild/PS5.png deleted file mode 100644 index 06aa3b1..0000000 Binary files a/gamebuild/PS5.png and /dev/null differ diff --git a/gamebuild/Switch.png b/gamebuild/Switch.png deleted file mode 100644 index 5825b47..0000000 Binary files a/gamebuild/Switch.png and /dev/null differ diff --git a/gamebuild/UF.png b/gamebuild/UF.png deleted file mode 100644 index a44a235..0000000 Binary files a/gamebuild/UF.png and /dev/null differ diff --git a/gamebuild/UP.png b/gamebuild/UP.png deleted file mode 100644 index 4e074fa..0000000 Binary files a/gamebuild/UP.png and /dev/null differ diff --git a/gamebuild/backloggery.css b/gamebuild/backloggery.css deleted file mode 100644 index 38e68ca..0000000 --- a/gamebuild/backloggery.css +++ /dev/null @@ -1,1188 +0,0 @@ -/* lato-regular - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Lato'; - font-style: normal; - font-weight: 400; - src: url('/fonts/lato-v24-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* lato-italic - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Lato'; - font-style: italic; - font-weight: 400; - src: url('/fonts/lato-v24-latin-italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* lato-700 - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Lato'; - font-style: normal; - font-weight: 700; - src: url('/fonts/lato-v24-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* lato-700italic - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Lato'; - font-style: italic; - font-weight: 700; - src: url('/fonts/lato-v24-latin-700italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} - -/* titillium-web-regular - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Titillium Web'; - font-style: normal; - font-weight: 400; - src: url('/fonts/titillium-web-v17-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* titillium-web-italic - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Titillium Web'; - font-style: italic; - font-weight: 400; - src: url('/fonts/titillium-web-v17-latin-italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* titillium-web-700 - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Titillium Web'; - font-style: normal; - font-weight: 700; - src: url('/fonts/titillium-web-v17-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} -/* titillium-web-700italic - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Titillium Web'; - font-style: italic; - font-weight: 700; - src: url('/fonts/titillium-web-v17-latin-700italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} - -/* material-icons-regular - latin */ -@font-face { - font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url('/fonts/material-icons-v142-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ -} - -a,aside,body,details,div,fieldset,figcaption,figure,footer,h1,h2,h3,html,img,input,li,main,nav,ol,p,section,select,span,summary,table,textarea,ul { - border:0; - -webkit-box-sizing:border-box; - box-sizing:border-box; - font-size:100%; - margin:0; - outline:none; - padding:0; - vertical-align:baseline -} - -:root { - --default-base:#424957; - --default-secondary:#272c34; - --default-secondary-50:rgba(40,44,52,0.5); - --default-accent:#f58d47; - --default-text:#fff; - --default-secondary-text:#fff; - --default-accent-text:#000; - --default-accent-shadow:hsla(0,0%,0%,50%); - --retro-border:url(/img/border.png); - --active-base:var(--default-base); - --active-secondary:var(--default-secondary); - --active-secondary-50:var(--default-secondary-50); - --active-accent:var(--default-accent); - --active-text:var(--default-text); - --active-secondary-text:var(--default-secondary-text); - --active-secondary-text-25:hsla(0,0%,100%,0.25); - --active-accent-text:var(--default-accent-text); - --beaten-color: hsla(0, 0%, 82%, 0.9); - --completed-color: hsla(48, 80%, 82%, 0.9); - --unplayed-color: hsla(200, 30%, 30%, 0.9); - --unfinished-color: hsla(0, 38%, 35%, 0.9); - --endless-color: hsla(275, 39%, 32%, 0.9); -} - -html { - color:var(--active-text); - font-family:Lato,arial,helvetica,sans-serif; - font-size:.9rem; - overflow-x:hidden; - overflow-y:overlay; - scroll-behavior:smooth -} - -body { - background-attachment:fixed; - background-color:var(--active-base); - margin:0; - padding:0 -} - -#app>div:last-of-type { - display:grid; - grid-gap:0 10px; - grid-template-columns:repeat(12,1fr); - grid-template-rows:auto; - grid-template-areas:"card card card card card card card card card card card card" "side side side side side side side side side side side side" "main main main main main main main main main main main main"; - max-width:1200px; - margin: 0 auto; - padding:0 2vw 0 1vw -} - -section { - padding:2vh 1vw 2vh -} - -a { - text-decoration:none -} - -.link,a { - color:var(--active-text) -} - -img { - max-width:100% -} - -h1,h2 { - font-family:Titillium Web,Tahoma,Arial,Helvetica,sans-serif; - font-variant:small-caps; - letter-spacing:2px; - border-bottom:1px solid var(--active-text); - font-size:18px; - margin:30px 0 10px; - padding-left:5px -} - -details.game-item div.history { - max-width: 95%; -} - -h1:first-of-type { - margin:0 0 15px -} - -svg,svg text { - fill:var(--active-text) -} - -svg text { - font-family:Titillium Web,Tahoma,Arial,Helvetica,sans-serif -} - -.decay { - opacity:.5 -} - -.decay:active,.decay:focus,.decay:focus-within,.decay:hover { - opacity:1 -} - -.tabs { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - /* margin-top:3rem; */ - padding:.3rem 0 -} - -.tabs a,.tabs div { - background-color:var(--active-secondary-50); - border-bottom:2px solid var(--active-text); - color:var(--active-secondary-text); - -webkit-box-flex:1; - -ms-flex:1; - flex:1; - font-family:Titillium Web,Tahoma,Arial,Helvetica,sans-serif; - font-size:1rem; - letter-spacing:1px; - opacity:.7; - padding:.5rem 0 .4rem; - text-align:center; - text-transform:uppercase; - white-space:nowrap -} - -.tabs a:hover,.tabs div:hover { - opacity:1 -} - -.tabs a,.tabs a.router-link-active { - border-top:2px solid var(--active-text) -} - -.tabs a.router-link-active { - background:var(--active-accent); - border-bottom:2px solid var(--active-text); - color:var(--active-accent-text); - font-weight:700; - opacity:1; - position:relative -} - -.tabs a.router-link-active a { - border:none; - display:block; - padding-right:10%; - position:absolute; - top:-7px; - right:0; - text-align:right; - width:100% -} - -.unibar a { - color: inherit; -} - -.Added,.unplayed,.Unplayed { - background-color:var(--unplayed-color)!important; - color:hsla(0,0%,100%,.75); - text-shadow:none -} - -.Started,.unfinished,.Unfinished { - background-color:var(--unfinished-color)!important; - color:hsla(0,0%,100%,.75); - text-shadow:none -} - -.Beat,.beaten,.Beaten { - background-color:var(--beaten-color)!important; - color:rgba(0,0,0,.75); - text-shadow:none -} - -.completed,.Completed { - background-color:var(--completed-color)!important; - color:rgba(0,0,0,.75); - text-shadow:none -} - -.endless,.Endless { - background-color:var(--endless-color)!important; - color:hsla(0,0%,100%,.75); - text-shadow:none -} - -.Playing { - color:hsla(0,0%,100%,.75) - background-color:#202020!important -} - -.borderless { - border:none!important -} - -.markdown { - padding:0 .25rem; - white-space:pre-wrap -} - -div.profile main { - grid-area:main -} - -.game-item { - margin-bottom:-3px; - overflow:hidden; - position:relative; -} - -.game-item>summary { - cursor: pointer; -} - -.game-item>summary:first-child { - background-color:hsla(0,0%,100%,.05); - border:2px solid rgba(0,0,0,.5); - border-radius:4px; - -webkit-box-align:center; - -ms-flex-align:center; - align-items:center; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - margin-bottom:10px; - min-height:54px; - max-height:54px; - overflow:hidden; - position:relative; - text-align:center; - width:100% -} - -.game-item>summary:first-child>div { - -webkit-box-flex:1; - -ms-flex:1; - flex:1 -} - -.game-item>summary:first-child>.platform { - background-color:var(--active-secondary); - border-radius:3px 0 0 3px; - color:var(--active-secondary-text); - min-height:50px; - max-width:50px; - overflow:hidden -} - -.game-item>summary:first-child>.platform img,.game-item>summary:first-child>.platform p { - opacity:.85 -} - -.game-item>summary:first-child>.platform img { - position:relative; - top:7px; - width:35px -} - -.game-item>summary:first-child>.platform img.bw { - -webkit-filter:var(--platform-bw); - filter:var(--platform-bw) -} - -.game-item>summary:first-child>.status { - max-width:48px; - padding:5px 9px -} - -.game-item>summary:first-child>.status img { - margin-top:3px; - max-width:32px -} - -.game-item>summary:first-child>.text { - -webkit-box-flex:5; - -ms-flex-positive:5; - flex-grow:5; - padding:3px 4px; - text-align:left -} - -.game-item>summary:first-child>.text>.title { - font-family:Titillium Web,sans-serif; - font-size:1.1rem; - line-height:1.1rem; - margin:0 0 -3px -} - -@supports(-webkit-line-clamp:1) { - .game-item>summary:first-child>.text>.title { - overflow:hidden; - text-overflow:ellipsis; - white-space:normal; - display:-webkit-box; - -webkit-line-clamp:1; - -webkit-box-orient:vertical - } - - -} - -.game-item>summary:first-child>.text>.markdown { - font-size:.7rem; - max-height:32px; - opacity:.75; - padding:2px 1px; - width:auto; - white-space:nowrap; - text-overflow:ellipsis; - overflow:hidden -} - -@supports(-webkit-line-clamp:2) { - .game-item>summary:first-child>.text>.markdown { - overflow:hidden; - text-overflow:ellipsis; - white-space:normal; - display:-webkit-box; - -webkit-line-clamp:2; - -webkit-box-orient:vertical - } - - -} - -.game-item>summary:first-child>.priority { - max-width:56px; - padding-right:10px; - text-align:center -} - -.game-item>summary:first-child>.priority img { - margin-top:3px; - max-width:32px; - opacity:.5 -} - -.donut { - display:block -} - -.platform-card { - border:2px solid rgba(0,0,0,.5); - border-radius:6px; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - font-weight:700; - margin:0 0 4px; - text-align:center; - width:100% -} - -.platform-card .bars { - border-radius:0 4px 4px 0; - display:-webkit-inline-box; - display:-ms-inline-flexbox; - display:inline-flex; - border-left:2px solid rgba(0,0,0,.5); - -webkit-box-flex:9; - -ms-flex:9; - flex:9 -} - -.platform-card .bars a { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-align:center; - -ms-flex-align:center; - align-items:center; - -webkit-box-pack:center; - -ms-flex-pack:center; - justify-content:center; - border-right:2px solid rgba(0,0,0,.5); - -webkit-box-flex:1; - -ms-flex:1; - flex:1; - font-size:14px; - margin:0; - padding:0 3px; - -webkit-transition:-webkit-box-flex .5s ease-in-out; - transition:-webkit-box-flex .5s ease-in-out; - transition:flex .5s ease-in-out; - transition:flex .5s ease-in-out,-webkit-box-flex .5s ease-in-out,-ms-flex .5s ease-in-out - white-space:nowrap; -} - -.platform-card .bars a:first-of-type { - border-left:none; -} - -.platform-card .bars a.remove_flex { - border:none; - -webkit-box-flex:0; - -ms-flex:0; - flex:0; - min-width:unset; - padding:0 -} - -.platform-card .abbr,.platform-card .title { - background:var(--active-secondary); - border-radius:4px 0 0 4px; - color:var(--active-secondary-text); - -webkit-box-pack:center; - -ms-flex-pack:center; - justify-content:center; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-flex:4; - -ms-flex:4; - flex:4; - font-size:17px; - font-weight:700; - min-width:50px; - overflow:hidden; - padding:5px; - white-space:nowrap -} - -.platform-card .abbr { - display:none -} - -.platform-card .total { - -webkit-box-align:center; - -ms-flex-align:center; - align-items:center; - background:var(--active-secondary); - border-radius:0 4px 4px 0; - color:var(--active-secondary-text); - -webkit-box-pack:right; - -ms-flex-pack:right; - justify-content:right; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-flex:2; - -ms-flex:2; - flex:2; - font-size:17px; - font-weight:700; - overflow:hidden; - padding-right:10px; - white-space:nowrap; - width:100px -} - -.platform-card .total span { - margin-left:6px -} - -.backlog-breakdown { - display:block; - text-align:center; - -ms-flex-wrap:wrap; - flex-wrap:wrap -} - -.backlog-breakdown .backlog-charts { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-orient:vertical; - -webkit-box-direction:normal; - -ms-flex-direction:column; - flex-direction:column; - width:100% -} - -.backlog-breakdown .mem-sum { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-flex:1; - -ms-flex:1; - flex:1 -} - -.backlog-breakdown .mem-sum .donut { - display:inline-block; - margin:0 4vw; - min-width:44% -} - -.status-tally { - -webkit-box-flex:4; - -ms-flex:4; - flex:4; - font-size:18px; - margin:15px 0 25px 25px -} - -.status-tally a:first-of-type div { - padding-top:8px!important -} - -.status-tally a { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-align:center; - -ms-flex-align:center; - align-items:center; - margin:-5px 20px -5px 0; -} - -.status-tally a div { - padding:1px 3px; - vertical-align:middle -} - -.status-tally a div img { - max-width:32px -} - -.status-tally a div:first-child { - text-align:right; - width:60px -} - -.status-tally a div:nth-child(2) { - border-right:2px solid rgba(0,0,0,.5); - padding:4px 5px 4px 0; - width:40px -} - -.status-tally a div:last-child { - -webkit-box-shadow:inset 7px 0 7px -5px rgba(0,0,0,.25); - box-shadow:inset 7px 0 7px -5px rgba(0,0,0,.25); - display:-webkit-box; - display:-ms-flexbox; - display:flex; - padding:4px 0; - width:99% -} - -.status-tally a div:last-child div { - -webkit-animation:width_in 1s ease-in-out; - animation:width_in 1s ease-in-out; - border:2px solid rgba(0,0,0,.5); - border-left:none; - border-radius:0 4px 4px 0; - display:block; - font-size:14px; - font-weight:700; - overflow:hidden; - padding:7px 0 7px 7px; - text-align:left; - -webkit-transition:width .5s ease-in-out; - transition:width .5s ease-in-out; - white-space:nowrap -} - -.status-tally img { - max-width:none; - position:relative; - top:2px -} - -.status-tally .backlog-tally { - border:2px solid rgba(0,0,0,.5); - border-radius:4px; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - margin-bottom:5px -} - -.status-tally .backlog-tally div { - -webkit-box-align:center; - -ms-flex-align:center; - align-items:center; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - font-size:1rem; - font-weight:700; - height:2.35rem; - text-align:center; - -webkit-transition:width .5s ease-in-out; - transition:width .5s ease-in-out -} - -.status-tally .backlog-tally div:first-of-type { - border-radius:4px 0 0 4px; - border-right:2px solid rgba(0,0,0,.5); - background-color:var(--active-accent); - color:var(--active-accent-text) -} - -.status-tally .backlog-tally div:last-of-type { - border-radius:0 4px 4px 0; - background-color:var(--active-secondary); - color:var(--active-secondary-text) -} - -.status-tally .backlog-tally div span { - width:100% -} - -.library .unibar { - border:2px solid rgba(0,0,0,.5);border-radius:8px;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%} - -.library .unibar div { - border-left:2px solid rgba(0,0,0,.5);-webkit-box-flex:1;-ms-flex:1;flex:1;font-size:1.25rem;font-weight:700;line-height:1.25rem;padding:.5rem;text-align:center} - -.library .unibar div:first-of-type { - background-color:var(--active-secondary);border:none;border-radius:6px 0 0 6px;color:var(--active-secondary-text);max-width:30%;padding:.5rem 1rem;white-space:nowrap} - -.library .unibar div:first-of-type span { - margin-right:1rem} - -.library .unibar div:last-of-type { - border-radius:0 6px 6px 0} - -.library .unibar div.unplayed { - background-color:var(--unplayed-color)} - -.library .unibar div.unfinished { - background-color:var(--unfinished-color)} - -.library .unibar div.beaten { - background-color:var(--beaten-color)} - -.library .unibar div.completed { - background-color:var(--completed-color)} - -.library .unibar div.endless { - background-color:var(--endless-color)} - -.library .library-list { - margin-top:20px} - -.game-item .game-info { - -webkit-box-align:start; - -ms-flex-align:start; - align-items:flex-start; - background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.05)),to(rgba(0,0,0,.05))); - background-image:linear-gradient(rgba(0,0,0,.05),rgba(0,0,0,.05)); - border-radius:0 0 5px 5px; - -webkit-box-shadow:inset 0 3px 10px rgba(0,0,0,.5); - box-shadow:inset 0 3px 10px rgba(0,0,0,.5); - margin:-10px 8px 15px 30px; - padding:10px; - position:relative -} - -.game-item .game-info label { - font-size:12px; - font-weight:700; - letter-spacing:.5px; - margin-left:4px; - opacity:.9; - text-transform:uppercase -} - -.game-item .game-info .markdown,.game-item .game-info p { - font-size:16px; - margin:0 0 12px .3rem; - padding:0 -} - -.game-item .game-info .data,.game-item .game-info .history,.game-item .game-info .review { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - margin:auto 15px; -} - -.game-item .game-info .history { - -ms-flex-wrap:wrap; - flex-wrap:wrap; - width:100% -} - -.game-item .game-info .history .list { - font-size:14px -} - -.game-item .game-info .history .list>div { - display:-webkit-box; - display:-ms-flexbox; - display:flex -} - -.game-item .game-info .history .list>div>div:first-of-type { - -webkit-box-flex:1; - -ms-flex:1; - flex:1; - margin-right:5px; - opacity:.65; - text-align:right -} - -.game-item .game-info .history .list>div>div:last-of-type { - -webkit-box-flex:2; - -ms-flex:2; - flex:2 -} - -.game-item .game-info .box_2 { - margin-right:15px -} - -.game-item .game-guest label { - opacity:.5 -} - -.history .box_1 { - width: 95%; -} - -div.profile aside { - grid-area:side; - margin-top:1.5rem; - position: sticky; -} - -.library .filters { -margin:.25rem 0 1.5rem; -width:100%} - -.library .filters>div { -padding:1rem; -width:95%} - -/* .library .filters .empty-filters { - border:2px solid rgba(0,0,0,.5); - background-color:var(--active-secondary); - color:var(--active-secondary-text); - border-radius:.5rem; - margin:.5rem auto; - opacity:.8; - padding:.4rem; - text-align:center} - - .library .filters .empty-filters:hover { - opacity:1} */ - -.library .filters .item { - border:2px solid rgba(0,0,0,.5); - background-color:var(--active-secondary); - color:var(--active-secondary-text); - display: inline-block; - font-size: 0.8rem; -border-radius:.5rem; -margin:.25rem; -max-width:8rem; - opacity:.8; - position: relative; - padding:.45rem 2rem .5rem 1rem; - white-space: nowrap; -} - -.library .filters .item .filter_clear { - border-radius: .5rem; - padding: .425rem .5rem .475rem; - position: absolute; - right: 0; - top: 0; -} - -.library .filters .item:hover { -opacity:1} - -.status-dot { - width:12px; - height:12px; - max-width:12px; - border-radius:8px; - border:2px solid #000; - display:inline-block; - margin-right:3px; - opacity:1; - position:relative; - top:1px; -} - - -/* new for history page */ - -.hide_arrow { - -webkit-transform: translateX(100px); - transform: translateX(100px) -} - -.scroll-button { - border-radius: 8px; - background: var(--active-secondary); - color: var(--active-secondary-text); - cursor: pointer; - display: block; - font-size: 18px; - opacity: .7; - pointer-events: all; - position: fixed; - bottom: 20px; - right: 20px; - text-align: center; - line-height: 26px; - height: 30px; - width: 30px; - -webkit-transition: -webkit-transform .5s; - transition: -webkit-transform .5s; - transition: transform .5s; - transition: transform .5s,-webkit-transform .5s -} - -.box_1 { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1 -} - -.history { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - width: 100% -} - -.history .list, .history .retro { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1 -} - -.history .list>div { - font-size: 14px -} - -.history .list>div:first-of-type h2 { - margin-top: 0 -} - -.history .list>div h2 { - display: block; - font-size: 13px -} - -section.history .list>div>div { - display: -webkit-box; - display: -ms-flexbox; - display: flex -} - -.history .list>div>div>div:first-of-type { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - margin-right: 5px; - opacity: .65; - text-align: right -} - -.history .list>div>div>div:last-of-type { - -webkit-box-flex: 2; - -ms-flex: 2; - flex: 2 -} - -.history .list>div>div>div:last-of-type span { - opacity: .65 -} - -.history .side { - margin-left: 40px; - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1 -} - -.history .side .year-tally { - font-size: 14px; - opacity: .7; - margin: 25px 0 15px 0; - padding: 10px 10px 10px -} - -.history .side .year-tally.active { - background-color: var(--active-secondary-50); - color: var(--active-secondary-text); - border-left: 3px solid var(--active-accent); - border-radius: 0 1rem 1rem 0; - opacity: 1 -} - -.history .side .year-tally:first-of-type { - margin-top: 0 -} - -.history .side .year-tally h2 { - border: none; - margin: 0 0 5px -} - -.history .side .year-tally h2 span { - float: right; - font-size: 14px; - padding-top: 5px -} - -.history .side .year-tally div { - display: table-row -} - -.history .side .year-tally div div { - display: table-cell; - padding: 1px 3px; - vertical-align: middle -} - -.history .side .year-tally div div:first-of-type { - text-align: right -} - -.history .side .year-tally div div:nth-child(2) { - -webkit-box-flex: 0; - -ms-flex: 0; - flex: 0; - border-right: 2px solid #000; - padding: 0 5px 0 3px; - text-align: center; - min-width: 40px -} - -.history .side .year-tally div div:last-child { - -webkit-box-shadow: inset 7px 0 7px -5px rgba(0,0,0,.25); - box-shadow: inset 7px 0 7px -5px rgba(0,0,0,.25); - padding: 4px 0; - width: 100% -} - -.history .side .year-tally div div:last-child div { - -webkit-animation: width_in 1s ease-in-out; - animation: width_in 1s ease-in-out; - border: 2px solid #000; - border-left: none; - border-radius: 0 4px 4px 0; - display: block; - font-size: 14px; - height: 16px; - overflow: hidden; - text-align: left -} - -@media screen and (min-width:800px) { - div.profile { - grid-template-areas:"card card card card card card card card card card card card" "side side side side main main main main main main main main"!important - } - - .tabs { - margin-top:0 - } - - -} - -@media screen and (min-width:1024px) { - .backlog-breakdown,.backlog-breakdown .backlog-charts { - display:-webkit-box; - display:-ms-flexbox; - display:flex - } - - .backlog-breakdown .backlog-charts { - -webkit-box-orient:horizontal; - -webkit-box-direction:normal; - -ms-flex-direction:row; - flex-direction:row; - width:100% - } - - .backlog-breakdown .mem-sum { - -webkit-box-orient:vertical; - -webkit-box-direction:normal; - -ms-flex-direction:column; - flex-direction:column; - min-width:160px; - max-width:160px - } - - .backlog-breakdown .mem-sum .donut { - margin:0 - } - - .backlog-breakdown .mem-sum .donut:last-of-type { - position:relative; - top:-10px - } - -} - -@media screen and (max-width:1024px) { - .platform-card .title { - display:none - } - - .platform-card .abbr { - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-flex:1; - -ms-flex:1; - flex:1; - min-width:80px - } - - .platform-card .bars a:last-of-type { - width:50px - } - - .platform-card .bars a:last-of-type span { - display:none - } - - -} - -@media screen and (max-width:700px) { - .tabs a { - font-size:.8rem - } - - .history { - display:block; - } - - .history .side { - margin-left: 0; - margin-top: 50px - } - - .game-item .game-info { - margin-left:8px - } - - .game-item .game-info .box_2 { - margin-right:0 - } - - .game-item .game-info .data,.game-item .game-info .history,.game-item .game-info .review { - display:block - } - - .game-item .game-info .data .box_1 div { - display:inline-block; - margin-right:1%; - width:48% - } - - -} - -@media screen and (max-width:680px) { - .platform-card .bars a { - content:""; - font-size:.6rem; - } - - .platform-card .abbr,.platform-card .title { - font-size:.8rem; - min-width:45px; - } - - .platform-card .total { - font-size:.8rem; - } - - .platform-card .total>span { - display:none; - } - -} - -@media screen and (max-width:600px) { - .library .unibar div { - font-size:3vw} - - .library .unibar div:first-of-type span { - margin-right:.5rem} -} - -@media screen and (max-width:520px) { - - .game-item>summary:first-child>.text>.title { - font-size:1rem - } - - .game-item>summary:first-child>.status { - padding:5px - } - -} diff --git a/gamebuild/nowplaying.png b/gamebuild/nowplaying.png deleted file mode 100644 index 469fe82..0000000 Binary files a/gamebuild/nowplaying.png and /dev/null differ diff --git a/gamebuild/paused.png b/gamebuild/paused.png deleted file mode 100644 index 5af9a8d..0000000 Binary files a/gamebuild/paused.png and /dev/null differ diff --git a/gameskel.py b/gameskel.py deleted file mode 100644 index 554385d..0000000 --- a/gameskel.py +++ /dev/null @@ -1,60 +0,0 @@ -import colorsys -import variables -from pathlib import Path - -""" -Generate the skeleton for a games backlog HTML page. -""" - -home = str(Path.home()) - -def headerwrite(output,section,local=False): - header = open(output, "a") - rgb = colorsys.hls_to_rgb((variables.gamehue)/360,0.3,0.45) - hexstring = "" - for element in rgb: - hexstring += str(hex(int(element * 255)))[2:] - header.write("\n\n \n \n \n \n Static backlog\n \n \n \n \n
\n
\n \n
\n
\n
\n") - header.write(" Backlog\n Library\n History\n
\n") - header.close() - -def footerwrite(output): - footer = open(output, "a") - footer.write("
\n
\n
\n
\n \n\n") - footer.close() - -if __name__ == "__main__": - headerwrite("gamebuild/backlog/index.html","backlog",True) - footerwrite("test.html") diff --git a/gamesort.py b/gamesort.py deleted file mode 100644 index 866a5e4..0000000 --- a/gamesort.py +++ /dev/null @@ -1,161 +0,0 @@ -import orgparse,os,re,variables -from pathlib import Path -from datetime import datetime - -""" -Load in the list of games from a set of .org files. -""" - -thisyear = datetime.now().strftime("%Y") - -year = variables.gamestartyear - 1 - -concernedfiles = [] - -while year < int(thisyear) + 1: - month = 0 - while month < 13: - if month < 10: - strmonth = "0" + str(month) - else: - strmonth = str(month) - recdir = str(year) + "/" + strmonth + "/" - fullpath = variables.orgpath + recdir - if os.path.exists(fullpath): - for file in sorted(os.listdir(fullpath)): - filename = fullpath + str(file) - if filename.endswith(".org"): - concernedfiles.append(filename) - month = month + 1 - year = year + 1 - -games = [] -gamenames = [] -holding = [] - -for file in concernedfiles: - filedate = file[-14:-4] - dateobj = datetime.strptime(filedate,"%Y-%m-%d") - parsefile = orgparse.load(file) - try: - for node in parsefile.children: - if node.heading == "games": - for action in node.children: - for game in action.children: - name = re.sub(" \(.*\)","",game.heading) - if game.heading not in gamenames: - status = "new" - gamenames.append(game.heading) - else: - status = "existing" - console = (re.findall("\(.*\)",game.heading)[0])[1:-1] - if status == "new": - thedict = {"id":game.heading,"name":name,"initialdate":dateobj,"console":console,game.parent.heading:dateobj,"recent":game.body,"lastupdate":dateobj} - if game.parent.heading != "acquired": - thedict.update({"firstplayed":dateobj}) - games.append(thedict) - else: - twodict = {"id":game.heading,game.parent.heading:dateobj,"lastupdate":dateobj} - if len(game.body) > 1: - twodict.update({"recent":game.body}) - for origgame in games: - if twodict["id"] == origgame["id"]: - try: - if origgame["firstplayed"]: - playedbefore = True - except: - playedbefore = False - if playedbefore == False: - twodict.update({"firstplayed":dateobj}) - holding.append(twodict) - for gameupdate in holding: - for origgame in games: - if gameupdate["id"] == origgame["id"]: - gamemerge = {**origgame, **gameupdate} - games.remove(origgame) - games.insert(0,gamemerge) - holding.remove(gameupdate) - except: - pass - -games = sorted(games,key=lambda d: d["lastupdate"]) - -consolelists = [] -for console in variables.consoles: - consolegames = [] - for game in games: - if game["console"] == console["code"]: - consolegames.append(game) - consolelists.append({"code":console["code"],"name":console["name"],"games":consolegames}) - -def completed(selection): - completed = 0 - for game in selection: - try: - if game["completed"]: - completed += 1 - except: - pass - return completed - -def beaten(selection): - beaten = 0 - for game in selection: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - beaten += 1 - except: - pass - return beaten - -def endless(selection): - endless = 0 - for game in selection: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - pass - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - endless += 1 - except: - pass - return(endless) - -def unfinished(selection): - unfinished = 0 - for game in selection: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - pass - except: - try: - if game["gameplay"]: - if game["id"] not in variables.endlessgames: - unfinished += 1 - except: - pass - return(unfinished) - -def total(selection): - return len(selection) - -def unplayed(selection): - unplayed = total(selection) - (completed(selection) + beaten(selection) + unfinished(selection) + endless(selection)) - return(unplayed) - -if __name__ == "__main__": - print(endless(games)) diff --git a/generategames.py b/generategames.py deleted file mode 100644 index c9f4fab..0000000 --- a/generategames.py +++ /dev/null @@ -1,26 +0,0 @@ -import sys,variables - -try: - if sys.argv[1] == "local": - local = True - else: - local = False -except: - local = False - -if variables.trackgames == True: - import backlog - import library - import sublibrary - import history - if __name__ == "__main__": - if local == True: - backlog.backlog(True) - library.library(True) - sublibrary.sublibrary(True) - history.history(True) - else: - backlog.backlog() - library.library() - sublibrary.sublibrary() - history.history() diff --git a/generateplaces.py b/generateplaces.py deleted file mode 100644 index a9972a8..0000000 --- a/generateplaces.py +++ /dev/null @@ -1,121 +0,0 @@ -import orgparse,os,re,sys,variables -import time -from datetime import datetime -from geopy.geocoders import Nominatim - -try: - if sys.argv[1] == "local": - local = True - else: - local = False -except: - local = False - -if variables.trackplaces == True: - - thisyear = datetime.now().strftime("%Y") - - year = variables.placestartyear - - concernedfiles = [] - - geo = Nominatim(user_agent="python3") - - while year < int(thisyear) + 1: - month = 0 - while month < 13: - if month < 10: - strmonth = "0" + str(month) - else: - strmonth = str(month) - recdir = str(year) + "/" + strmonth + "/" - fullpath = variables.orgpath + recdir - if os.path.exists(fullpath): - for file in sorted(os.listdir(fullpath)): - filename = fullpath + str(file) - if filename.endswith(".org"): - concernedfiles.append(filename) - month = month + 1 - year = year + 1 - - places = [] - placenames = [] - - for file in concernedfiles: - filedate = file[-14:-4] - dateobj = datetime.strptime(filedate,"%Y-%m-%d") - parsefile = orgparse.load(file) - try: - for node in parsefile.children: - if node.heading == "places": - for action in node.children: - if action.heading == "visited": - for place in action.children: - placename = re.sub(" <.*>","",re.sub("<.*> ","",place.heading)) - if placename not in placenames: - status = "new" - placenames.append(placename) - else: - status = "existing" - if "<" in place.heading: - dates = re.sub(" [A-Z][a-z][a-z]","",re.sub("--"," to ",re.sub(">","",re.sub("<","",(re.findall("\<.*\>",place.heading)[0]))))) - else: - dates = filedate - if status == "new": - try: - lookup = placename + ", " + variables.disambig[placename] - except: - lookup = placename - thedict = {"name":placename,"dates":[dates],"lookup":lookup} - places.append(thedict) - else: - twodict = {"name":placename,"dates":[dates]} - for origplace in places: - if twodict["name"] == origplace["name"]: - origplace["dates"].extend(twodict["dates"]) - except: - pass - - for place in places: - place["dates"] = list(dict.fromkeys(place["dates"])) - - theplaces = sorted(places,key=lambda d: d["name"]) - - for place in theplaces: - print("Fetching " + place["name"]) - place["lat"] = None - while place["lat"] == None: - try: - place["lat"] = geo.geocode(place["lookup"]).latitude - except: - time.sleep(3) - continue - place["long"] = None - while place["long"] == None: - try: - place["long"] = geo.geocode(place["lookup"]).longitude - except: - time.sleep(3) - continue - - alllats = [] - alllongs = [] - for place in theplaces: - if place["lat"] != 0: - alllats.append(place["lat"]) - if place["long"] != 0: - alllongs.append(place["long"]) - avglat = (max(alllats) + min(alllats))/2 - avglong = (max(alllongs) + min(alllongs))/2 - writefile = open("placebuild/index.html","w") - writefile.write("\n\n \n \n \n \n Map\n \n \n \n \n \n \n
\n \n \n") diff --git a/generaterecords.py b/generaterecords.py deleted file mode 100644 index 56c88d4..0000000 --- a/generaterecords.py +++ /dev/null @@ -1,88 +0,0 @@ -import discogs_client,re,time,variables -d = discogs_client.Client("Python/1.0",user_token=variables.discogstoken) - -user = d.user(variables.discogsuser) - -try: - if sys.argv[1] == "local": - local = True - else: - local = False -except: - local = False - -if variables.trackrecords == True: - - records = [] - - thenumber = 1 - maxno = len(user.collection_folders[0].releases) - - def typography(thestring): - return re.sub(" / ","/",re.sub(" \(.*\)","",re.sub(" - "," – ",re.sub(" "," ",re.sub("\.\.\."," …",re.sub("'","’",re.sub(" = .*","",thestring))))))) - - print("Fetching records from Discogs") - - for item in user.collection_folders[0].releases: - print("Fetching " + str(thenumber) + " of " + str(maxno)) - theitem = {} - theitem["artist"] = typography(item.release.artists[0].name) - theitem["title"] = typography(item.release.title) - try: - if "LP" in item.release.formats[0]["descriptions"] or "12\"" in item.release.formats[0]["descriptions"]: - theitem["format"] = "large" - else: - theitem["format"] = "small" - except: - theitem["format"] = "small" - try: - theitem["img"] = item.release.images[0]["uri"] - except: - pass - records.append(theitem) - thenumber += 1 - time.sleep(1) # only allowed 1 request per second - - records = sorted(records, key=lambda d: d["title"]) - records = sorted(records, key=lambda d: d["artist"]) - - smalls = [] - larges = [] - for record in records: - if record["format"] == "large": - larges.append(record) - else: - smalls.append(record) - - def recordwrite(record): - recordstring = "
\n \n
\n

" + record["artist"] + "

" + record["title"] + "

\n
\n
\n" - return recordstring - - writefile = open("recordbuild/index.html","w") - - writefile.write("\n\n \n \n \n Record collection\n \n \n \n

Record collection

\n
\n") - - for record in smalls: - writefile.write(recordwrite(record)) - - for record in larges: - writefile.write(recordwrite(record)) - - writefile.write("
\n

Generic disc icons by popo2021 and Dinosoft Labs on Flaticon.

\n \n\n") - - writefile.close() diff --git a/history.py b/history.py deleted file mode 100644 index 9de7fbf..0000000 --- a/history.py +++ /dev/null @@ -1,168 +0,0 @@ -import os -import gamesort,gameskel,variables -from datetime import datetime,timedelta - -""" -Generates history page and RSS feed -""" - -def history(local=False): - # delete existing files - if not os.path.isdir("gamebuild/history"): - os.mkdir("gamebuild/history") - if os.path.exists("gamebuild/history/index.html"): - os.remove("gamebuild/history/index.html") - if os.path.exists("gamebuild/feed.xml"): - os.remove("gamebuild/feed.xml") - # write header - gameskel.headerwrite("gamebuild/history/index.html","history",local) - output = "gamebuild/history/index.html" - filewrite = open(output, "a") - - filewrite.write("

\n
\n") - - feedwrite = open("gamebuild/feed.xml", "a") - feedwrite.write("\n\n \n \n Static backlog\n " + variables.domain + variables.gameserverpath + "backlog\n Feed for gaming updates\n en-gb") - - theyear = int(gamesort.thisyear) - while theyear >= variables.gamestartyear: - yearlist = [] - enddate = datetime.strptime((str(theyear) + "-12-31"),"%Y-%m-%d") - startdate = datetime.strptime((str(theyear) + "-01-01"),"%Y-%m-%d") - eachdate = enddate - while eachdate >= startdate: - for game in gamesort.games: - if game["initialdate"] == eachdate: - yearlist.append({"date":eachdate,"name":game["name"],"console":game["console"],"action":"Added"}) - try: - if game["firstplayed"] == eachdate: - yearlist.append({"date":eachdate,"name":game["name"],"console":game["console"],"action":"Started"}) - except: - pass - try: - if game["beaten"] == eachdate: - yearlist.append({"date":eachdate,"name":game["name"],"console":game["console"],"action":"Beat"}) - except: - pass - try: - if game["completed"] == eachdate: - yearlist.append({"date":eachdate,"name":game["name"],"console":game["console"],"action":"Completed"}) - except: - pass - eachdate -= timedelta(days=1) - checkdate = enddate - for event in yearlist: - filewrite.write("
\n") - if checkdate != event["date"]: - filewrite.write("

" + event["date"].strftime("%Y-%m-%d") + "

\n") - filewrite.write("
\n
" + event["action"] + "\n
\n
\n
" + event["name"] + "\n (" + event["console"] + ")\n
\n
\n
\n") - feedwrite.write(" \n " + event["action"] + " " + event["name"] + " (" + event["console"] + ")\n " + event["date"].strftime("%a, %-d %b %Y") + " 00:00:00 GMT\n " + variables.domain + variables.gameserverpath + "history\n " + event["action"] + "-" + event["name"].replace(" ","-") + "-" + event["console"] + "\n " + event["action"] + " " + event["name"] + " (" + event["console"] + ")\n \n") - checkdate = event["date"] - theyear -= 1 - - feedwrite.write("
\n
") - feedwrite.close() - - filewrite.write("
\n") - - theyear = int(gamesort.thisyear) - filewrite.write("
\n") - while theyear > 2016: - yeargames = 0 - yearplaying = 0 - for game in gamesort.games: - if game["initialdate"].year == theyear: - try: - if game["gameplay"]: - if game["id"] not in variables.endlessgames: - yeargames += 1 - except: - yeargames += 1 - for game in gamesort.games: - try: - if game["beaten"].year == theyear: - yeargames -= 1 - except: - try: - if game["completed"].year == theyear: - yeargames -= 1 - except: - pass - - yearbacklog = [] - for game in gamesort.games: - try: - if game["completed"].year == theyear: - yearbacklog.append(game) - except: - try: - if game["beaten"].year == theyear: - yearbacklog.append(game) - except: - if game["initialdate"].year == theyear: - yearbacklog.append(game) - - yearcompleted = 0 - yearbeaten = 0 - yearstarted = 0 - yearadded = 0 - yeartotal = len(yearbacklog) - if yeartotal > 0: - for game in yearbacklog: - try: - if game["initialdate"].year == theyear: - yearadded += 1 - except: - pass - try: - if game["firstplayed"].year == theyear: - yearstarted += 1 - except: - pass - try: - if game["completed"].year == theyear: - yearcompleted += 1 - except: - pass - try: - if game["beaten"].year == theyear: - yearbeaten += 1 - except: - pass - - compare = [] - compare.append(yearadded) - compare.append(yearstarted) - compare.append(yearbeaten) - compare.append(yearcompleted) - maxvalue = max(compare) - - filewrite.write("
\n

" + str(theyear) + " Summary\n Backlog ") - if yeargames > 0: - filewrite.write("▲ " + str(yeargames)) - elif yeargames == 0: - filewrite.write(" 0") - elif yeargames < 0: - filewrite.write("▼ " + str(yeargames * -1)) - filewrite.write("

\n
\n
Added
\n
" + str(yearadded) + "
\n
\n
\n
\n
\n
\n
\n
Started
\n
" + str(yearstarted) + "
\n
\n
\n
\n
\n
\n
\n
Beat
\n
" + str(yearbeaten) + "
\n
\n
\n
\n
\n
\n
\n
Completed
\n
" + str(yearcompleted) + "
\n
\n
\n
\n
\n
\n
\n") - theyear -= 1 - - filewrite.write("
\n
\n") - - filewrite.close() - gameskel.footerwrite("gamebuild/history/index.html") - -if __name__ == "__main__": - history(True) diff --git a/init.py b/init.py deleted file mode 100644 index 580e0dc..0000000 --- a/init.py +++ /dev/null @@ -1,16 +0,0 @@ -import variables - -script = open("build.sh", "w") - -script.write("#!/usr/bin/env bash\n") - -if variables.trackgames == True: - script.write("python3 generategames.py\nrclone copy gamebuild " + variables.rclonesiteroot + variables.gameserverpath + " -P\n") - -if variables.trackplaces == True: - script.write("python3 generateplaces.py\nrclone copy placebuild " + variables.rclonesiteroot + variables.placeserverpath + " -P\n") - -if variables.trackrecords == True: - script.write("python3 generaterecords.py\nrclone copy recordbuild " + variables.rclonesiteroot + variables.recordserverpath + " -P\n") - -script.close() diff --git a/library.py b/library.py deleted file mode 100644 index 336f53e..0000000 --- a/library.py +++ /dev/null @@ -1,65 +0,0 @@ -import os -import cardstring,gamesort,gameskel,variables - -""" -Generates library page -""" - -def library(local=False): - # delete existing file - if not os.path.isdir("gamebuild/library"): - os.mkdir("gamebuild/library") - if os.path.exists("gamebuild/library/index.html"): - os.remove("gamebuild/library/index.html") - # write header - gameskel.headerwrite("gamebuild/library/index.html","library",local) - output = "gamebuild/library/index.html" - filewrite = open(output, "a") - filewrite.write("
\n
\n
\n
\n Total Found " + str(gamesort.total(gamesort.games)) + "\n
\n") - if gamesort.unplayed(gamesort.games) > 0: - filewrite.write(" \n") - if gamesort.unfinished(gamesort.games) > 0: - filewrite.write(" \n") - if gamesort.beaten(gamesort.games) > 0: - filewrite.write(" \n") - if gamesort.completed(gamesort.games) > 0: - filewrite.write(" \n") - if gamesort.endless(gamesort.games) > 0: - filewrite.write(" \n") - filewrite.write("
\n
\n") - - newgames = sorted(gamesort.games,key=lambda d: d["id"]) - - for game in newgames: - filewrite.write(cardstring.playcard(game,local)) - - filewrite.close() - gameskel.footerwrite("gamebuild/library/index.html") - -if __name__ == "__main__": - library(True) diff --git a/placebuild/.gitkeep b/placebuild/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/recordbuild/large.png b/recordbuild/large.png deleted file mode 100644 index d57e8c2..0000000 Binary files a/recordbuild/large.png and /dev/null differ diff --git a/recordbuild/small.png b/recordbuild/small.png deleted file mode 100644 index b470e62..0000000 Binary files a/recordbuild/small.png and /dev/null differ diff --git a/sublibrary.py b/sublibrary.py deleted file mode 100644 index defffa4..0000000 --- a/sublibrary.py +++ /dev/null @@ -1,176 +0,0 @@ -import os -import cardstring,gamesort,gameskel,variables -from pathlib import Path - -""" -Generates sublibrary pages -""" - -home = str(Path.home()) - -def sublibrary(local=False): - statuses = ["all","completed","beaten","unfinished","endless","unplayed"] - consoleextra = [{"shortname":"all"}] - consolesplus = variables.consoles + consoleextra - for console in consolesplus: - gameslist = [] - for game in gamesort.games: - if console["shortname"] == "all": - gameslist.append(game) - elif game["console"] == console["code"]: - gameslist.append(game) - for status in statuses: - filterlist = [] - if status == "all": - for game in gameslist: - filterlist.append(game) - elif status == "completed": - for game in gameslist: - try: - if game["completed"]: - filterlist.append(game) - except: - pass - elif status == "beaten": - for game in gameslist: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - filterlist.append(game) - except: - pass - elif status == "unfinished": - for game in gameslist: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - pass - except: - try: - if game["gameplay"]: - if game["id"] not in variables.endlessgames: - filterlist.append(game) - except: - pass - elif status == "endless": - for game in gameslist: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - pass - except: - try: - if game["gameplay"]: - if game["id"] in variables.endlessgames: - filterlist.append(game) - except: - pass - elif status == "unplayed": - for game in gameslist: - try: - if game["completed"]: - pass - except: - try: - if game["beaten"]: - pass - except: - try: - if game["gameplay"]: - pass - except: - filterlist.append(game) - if not os.path.isdir("gamebuild/library/" + console["shortname"].lower() + "-" + status): - if len(filterlist) > 0: - os.mkdir("gamebuild/library/" + console["shortname"].lower() + "-" + status) - if os.path.exists("gamebuild/library/" + console["shortname"].lower() + "-" + status + "/index.html"): - os.remove("gamebuild/library/" + console["shortname"].lower() + "-" + status + "/index.html") - # write header - if len(filterlist) > 0: - gameskel.headerwrite(("gamebuild/library/" + console["shortname"].lower() + "-" + status + "/index.html"),"sublibrary",local) - output = "gamebuild/library/" + console["shortname"].lower() + "-" + status + "/index.html" - filewrite = open(output, "a") - filewrite.write("
\n
\n
\n
Filtered by\n") - if console["shortname"] != "all": - filewrite.write(" 1 Platformx\n") - if status != "all": - filewrite.write(" 1 Statusx\n") - filewrite.write("
\n
\n
\n Total Found " + str(gamesort.total(filterlist)) + "\n
\n") - if gamesort.unplayed(filterlist) > 0: - filewrite.write(" \n") - if gamesort.unfinished(filterlist) > 0: - filewrite.write(" \n") - if gamesort.beaten(filterlist) > 0: - filewrite.write(" \n") - if gamesort.completed(filterlist) > 0: - filewrite.write(" \n") - if gamesort.endless(filterlist) > 0: - filewrite.write(" \n") - filewrite.write("
\n
\n") - - newgames = sorted(filterlist,key=lambda d: d["id"]) - - for game in newgames: - filewrite.write(cardstring.playcard(game,local)) - - filewrite.close() - gameskel.footerwrite("gamebuild/library/" + console["shortname"].lower() + "-" + status + "/index.html") - -if __name__ == "__main__": - sublibrary(True) diff --git a/variables-template.py b/variables-template.py deleted file mode 100644 index 8016e83..0000000 --- a/variables-template.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -User-defined variables live here. -""" - -orgpath = "" - -localpath = "" - -domain = "" - -rclonesiteroot = "" - -""" -Games -""" - -trackgames = False - -gameserverpath = "" - -endlessgames = [] - -gamedescription = "" - -gamestartyear = 0 - -gamehue = 0 - -consoles = [{"code":"ps5","name":"PlayStation 5","shortname":"PS5","img":"PS5"}, - {"code":"ps2","name":"PlayStation 2","shortname":"PS2","img":"PS2"}, - {"code":"ps3","name":"PlayStation 3","shortname":"PS3","img":"PS3"}, - {"code":"xbox 360","name":"Xbox 360","shortname":"Xbox360","img":"360"}, - {"code":"nintendo ds","name":"Nintendo DS","shortname":"DS","img":"NDS"}, - {"code":"nintendo 3ds","name":"Nintendo 3DS","shortname":"3DS","img":"3DS"}, - {"code":"nintendo switch","name":"Nintendo Switch","shortname":"Switch","img":"Switch"}, - {"code":"pc","name":"PC","shortname":"PC","img":"PC"}] - -""" -Places -""" - -trackplaces = False - -placeserverpath = "" - -placestartyear = 0 - -placecss = "" - -# disambig = {"london":"england","belfast":"northern ireland"} - -""" -Records -""" - -trackrecords = False - -recordserverpath = "" - -recordcss = "" - -discogstoken = "" - -discogsuser = ""