import orgparse , os , re
from pathlib import Path
from datetime import datetime , timedelta
home = str ( Path . home ( ) )
thisyear = datetime . now ( ) . strftime ( " % Y " )
basedir = home + " /Documents/drive/org/journal/ "
if os . path . exists ( " backlog.html " ) :
os . remove ( " backlog.html " )
writeindex = open ( " backlog.html " , " a " )
if os . path . exists ( " library.html " ) :
os . remove ( " library.html " )
writelibrary = open ( " library.html " , " a " )
year = 2016
concernedfiles = [ ]
endlessgames = [ " the sims 4 (pc) " , " american truck simulator (pc) " , " civilization iv (pc) " , " final fantasy xiv (pc) " , " medieval ii: total war (pc) " , " tabletop simulator (pc) " , " train simulator 2020 (pc) " ]
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 = basedir + 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 " ] )
ps5list = [ ]
for game in games :
if game [ " console " ] == " ps5 " :
ps5list . append ( game )
ps2list = [ ]
for game in games :
if game [ " console " ] == " ps2 " :
ps2list . append ( game )
ps3list = [ ]
for game in games :
if game [ " console " ] == " ps3 " :
ps3list . append ( game )
xbox360list = [ ]
for game in games :
if game [ " console " ] == " xbox 360 " :
xbox360list . append ( game )
pclist = [ ]
for game in games :
if game [ " console " ] == " pc " :
pclist . append ( game )
dslist = [ ]
for game in games :
if game [ " console " ] == " nintendo ds " :
dslist . append ( game )
switchlist = [ ]
for game in games :
if game [ " console " ] == " nintendo switch " :
switchlist . append ( game )
threedslist = [ ]
for game in games :
if game [ " console " ] == " nintendo 3ds " :
threedslist . append ( game )
writeindex . write ( " <!DOCTYPE html> \n <html lang= \" en \" style= \" --active-base: #364563; --active-text: #FFFFFF; --active-text-50: #FFFFFF60; --active-text-25: #FFFFFF30; --active-secondary: #222a3a; --active-secondary-50: #222a3a80; --active-secondary-text: #FFFFFF; --active-secondary-text-50: #FFFFFF70; --active-secondary-text-25: #FFFFFF30; --active-accent: #00fffb; --active-accent-75: #00fffbc0; --active-accent-text: #000000DD; --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); --platform-bw: none; --active-accent-shadow: #FFFFFF66; --retro-border: url( ' /img/border.png ' ); \" > \n <head> \n <meta charset= \" utf-8 \" > \n <meta name= \" viewport \" content= \" width=device-width,initial-scale=1 \" > \n <meta name= \" theme-color \" content= \" #424957 \" > \n <link href= \" https://fonts.googleapis.com/icon?family=Material+Icons \" rel= \" stylesheet \" > \n <link href= \" https://fonts.googleapis.com/css?family=Lato|Teko|Titillium+Web \" rel= \" stylesheet \" > \n <title>Selfhostery etc.</title> \n <link href= \" backloggery.css \" rel= \" stylesheet \" > \n </head> \n <body> \n <div id= \" app \" > \n <div class= \" profile \" > \n <main> \n <section> \n <div class= \" tabs \" > \n <a href= \" \" class= \" router-link-exact-active router-link-active \" aria-current= \" page \" >Backlog</a> \n <a href= \" \" class= \" \" >Library</a> \n <a href= \" \" class= \" \" >History</a> \n </div> \n " )
# NOW PLAYING
writeindex . write ( " <section> \n <div> \n <h1>Now Playing</h1> \n <div class= \" now-playing \" > \n " )
playingnow = [ ]
def nowplaying ( consolelist ) :
if len ( consolelist ) > 0 :
thegame = consolelist [ - 1 ]
try :
if thegame [ " gameplay " ] :
try :
if thegame [ " completed " ] :
if thegame [ " completed " ] > thegame [ " gameplay " ] :
playing = False
else :
playing = True
state = " completed "
except :
try :
if thegame [ " beaten " ] :
if thegame [ " beaten " ] > thegame [ " gameplay " ] :
playing = False
else :
playing = True
state = " beaten "
except :
playing = True
if thegame [ " id " ] in endlessgames :
state = " endless "
else :
state = " playing "
if playing :
playingnow . append ( { " console " : thegame [ " console " ] , " name " : thegame [ " name " ] , " date " : thegame [ " gameplay " ] , " state " : state , " recent " : thegame [ " recent " ] , " gameplay " : thegame [ " gameplay " ] , " id " : thegame [ " id " ] } )
except :
pass
nowplaying ( dslist )
nowplaying ( threedslist )
nowplaying ( switchlist )
nowplaying ( pclist )
nowplaying ( ps2list )
nowplaying ( ps3list )
nowplaying ( ps5list )
nowplaying ( xbox360list )
playingnow = sorted ( playingnow , key = lambda d : d [ " date " ] , reverse = True )
decay = False
def playcard ( game , page ) :
cardstring = " "
if decay == True :
cardstring + = " <div class= \" game-item decay \" > \n "
else :
cardstring + = " <div class= \" game-item \" > \n "
cardstring + = " <div> \n <div class= \" platform \" > \n <div> \n "
if game [ " console " ] == " ps5 " :
cardstring + = " <img src= \" PS5.png \" title= \" PlayStation 5 \" alt= \" PS5 \" class= \" bw \" > \n "
elif game [ " console " ] == " ps2 " :
cardstring + = " <img src= \" PS2.png \" title= \" PlayStation 2 \" alt= \" PS2 \" class= \" bw \" > \n "
elif game [ " console " ] == " ps3 " :
cardstring + = " <img src= \" PS3.png \" title= \" PlayStation 3 \" alt= \" PS3 \" class= \" bw \" > \n "
elif game [ " console " ] == " nintendo switch " :
cardstring + = " <img src= \" Switch.png \" title= \" Nintendo Switch \" alt= \" Switch \" class= \" bw \" > \n "
elif game [ " console " ] == " nintendo ds " :
cardstring + = " <img src= \" NDS.png \" title= \" Nintendo DS \" alt= \" DS \" class= \" bw \" > \n "
elif game [ " console " ] == " nintendo 3ds " :
cardstring + = " <img src= \" 3DS.png \" title= \" Nintendo 3DS \" alt= \" 3DS \" class= \" bw \" > \n "
elif game [ " console " ] == " xbox 360 " :
cardstring + = " <img src= \" 360.png \" title= \" Xbox 360 \" alt= \" Xbox360 \" class= \" bw \" > \n "
elif game [ " console " ] == " pc " :
cardstring + = " <img src= \" PC.png \" title= \" PC \" alt= \" PC \" class= \" bw \" > \n "
cardstring + = " </div> \n </div> \n <div class= \" status \" > \n "
try :
if game [ " completed " ] :
cardstring + = " <img src= \" C.png \" alt= \" C \" title= \" Completed \" > \n "
except :
try :
if game [ " beaten " ] :
cardstring + = " <img src= \" B.png \" alt= \" B \" title= \" Beaten \" > \n "
except :
try :
if game [ " gameplay " ] :
if game [ " id " ] in endlessgames :
cardstring + = " <img src= \" E.png \" alt= \" E \" title= \" Endless \" > \n "
else :
cardstring + = " <img src= \" UF.png \" alt= \" UF \" title= \" Unfinished \" > \n "
except :
cardstring + = " <img src= \" UP.png \" alt= \" UP \" title= \" Unplayed \" > \n "
cardstring + = " </div> \n <div class= \" text \" > \n <div class= \" title \" > " + game [ " name " ] + " </div> \n "
try :
if len ( game [ " recent " ] ) > 1 :
cardstring + = " <div class= \" markdown \" > " + game [ " recent " ] + " </div> \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 + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <img src= \" nowplaying.png \" alt= \" ⯈ \" title= \" Now Playing \" > \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
except :
try :
if game [ " beaten " ] :
if game [ " gameplay " ] > game [ " beaten " ] :
if game [ " gameplay " ] < ( datetime . now ( ) - timedelta ( days = 180 ) ) :
cardstring + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <img src= \" nowplaying.png \" alt= \" ⯈ \" title= \" Now Playing \" > \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
except :
if game [ " gameplay " ] < ( datetime . now ( ) - timedelta ( days = 180 ) ) :
if game [ " id " ] in endlessgames :
cardstring + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <img src= \" paused.png \" alt= \" ⏸ \" title= \" Paused \" > \n </div> \n "
else :
cardstring + = " </div> \n <div class= \" priority \" > \n <img src= \" nowplaying.png \" alt= \" ⯈ \" title= \" Now Playing \" > \n </div> \n "
except :
cardstring + = " </div> \n <div class= \" priority \" > \n <span title= \" Normal \" /> \n </div> \n "
cardstring + = " </div> \n </div> \n "
if page == " main " :
writeindex . write ( cardstring )
elif page == " library " :
writelibrary . write ( cardstring )
for game in playingnow :
playcard ( game , " main " )
decay = True
writeindex . write ( " </div> \n " )
# BACKLOG BREAKDOWN
writeindex . write ( " <h1>Backlog Breakdown</h1> \n <div class= \" backlog-breakdown \" > \n <div class= \" backlog-charts \" > \n <div class= \" mem-sum \" > \n <div class= \" donut \" > \n <svg viewBox= \" 0 0 42 42 \" > \n <text x= \" 21 \" y= \" 17.5 \" style= \" font-size: 3.5px; opacity: 0.75; text-anchor: middle; \" >Total Games</text> \n <text x= \" 21 \" y= \" 27 \" style= \" font-size: 10px; text-anchor: middle; \" > " + str ( len ( games ) ) + " </text> \n <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 4 \" stroke= \" #000000c0 \" fill= \" transparent \" > \n </circle> \n " )
completed = 0
beaten = 0
endless = 0
unfinished = 0
total = len ( games )
if total > 0 :
for game in games :
try :
if game [ " completed " ] :
completed + = 1
except :
try :
if game [ " beaten " ] :
beaten + = 1
except :
try :
if game [ " gameplay " ] :
if game [ " id " ] in endlessgames :
endless + = 1
else :
unfinished + = 1
except :
pass
unplayed = total - ( completed + beaten + unfinished + endless )
backlog = unfinished + unplayed
takeup = 100
if unplayed > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(200, 30 % , 30 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( takeup ) + " 100 \" > \n </circle> \n " )
takeup = takeup - round ( ( ( unplayed / total ) * 100 ) , 1 )
if unfinished > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(0, 38 % , 35 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( takeup ) + " 100 \" > \n </circle> \n " )
takeup = takeup - round ( ( ( unfinished / total ) * 100 ) , 1 )
if beaten > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(0, 0 % , 82 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( takeup ) + " 100 \" > \n </circle> \n " )
takeup = takeup - round ( ( ( beaten / total ) * 100 ) , 1 )
if completed > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(48, 75 % , 70 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( takeup ) + " 100 \" > \n </circle> \n " )
takeup = takeup - round ( ( ( completed / total ) * 100 ) , 1 )
if endless > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(275, 39 % , 32 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( takeup ) + " 100 \" > \n </circle> \n " )
yeargames = 0
yearplaying = 0
for game in games :
if int ( game [ " initialdate " ] . year ) == int ( thisyear ) :
try :
if game [ " completed " ] :
pass
except :
try :
if game [ " beaten " ] :
pass
except :
yeargames + = 1
try :
if game [ " gameplay " ] :
yearplaying + = 1
except :
pass
writeindex . write ( " </svg> \n </div> \n <div class= \" donut \" > \n <svg viewBox= \" 0 0 42 42 \" > \n <text x= \" 21 \" y= \" 17.5 \" style= \" font-size: 3.5px; opacity: 0.75; text-anchor: middle; \" > " + thisyear + " Backlog</text> \n <text x= \" 21 \" y= \" 27 \" style= \" font-size: 10px; text-anchor: middle; \" > " + str ( yeargames ) + " </text> \n <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 4 \" stroke= \" #000000c0 \" fill= \" transparent \" > \n </circle> \n <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(200, 30 % , 30 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" 100 100 \" > \n </circle> \n " )
if yearplaying > 0 :
writeindex . write ( " <circle id= \" circle \" r= \" 15.91549430918954 \" cy= \" 21 \" cx= \" 21 \" stroke-width= \" 3 \" stroke= \" hsla(0, 38 % , 35 % , 0.9) \" fill= \" transparent \" stroke-dasharray= \" " + str ( 100 * yeargames / yearplaying ) + " 100 \" > \n </circle> \n " )
writeindex . write ( " </svg> \n </div> \n </div> \n <div class= \" status-tally \" > \n <div class= \" backlog-tally \" > \n <div style= \" width: " + str ( round ( ( ( backlog / total ) * 100 ) , 1 ) ) + " % ; \" > \n <span>Active Backlog · " + str ( backlog ) + " · " + str ( round ( ( ( backlog / total ) * 100 ) , 1 ) ) + " % </span> \n </div> \n <div style= \" width: " + str ( 100 - round ( ( ( backlog / total ) * 100 ) , 1 ) ) + " % ; \" > \n </div> \n </div> \n " )
compare = [ ]
compare . append ( unplayed )
compare . append ( unfinished )
compare . append ( beaten )
compare . append ( completed )
compare . append ( endless )
maxvalue = max ( compare )
if unplayed / maxvalue > 0.5 :
writeindex . write ( " <a> \n <div> " + str ( unplayed ) + " </div> \n <div> \n <img src= \" UP.png \" > \n </div> \n <div> \n <div class= \" Unplayed \" style= \" width: calc(100 % * ( " + str ( unplayed ) + " / " + str ( maxvalue ) + " )); \" > " + str ( round ( ( ( unplayed / total ) * 100 ) , 1 ) ) + " % Unplayed</div> \n </div> \n </a> \n " )
else :
writeindex . write ( " <a> \n <div> " + str ( unplayed ) + " </div> \n <div> \n <img src= \" UP.png \" > \n </div> \n <div> \n <div class= \" Unplayed \" style= \" width: calc(100 % * ( " + str ( unplayed ) + " / " + str ( maxvalue ) + " )); \" > \n </div> \n <div class= \" borderless \" > " + str ( round ( ( ( unplayed / total ) * 100 ) , 1 ) ) + " % Unplayed</div> \n </div> \n </a> \n " )
if unfinished / maxvalue > 0.5 :
writeindex . write ( " <a> \n <div> " + str ( unfinished ) + " </div> \n <div> \n <img src= \" UF.png \" > \n </div> \n <div> \n <div class= \" Unfinished \" style= \" width: calc(100 % * ( " + str ( unfinished ) + " / " + str ( maxvalue ) + " )); \" > " + str ( round ( ( ( unfinished / total ) * 100 ) , 1 ) ) + " % Unfinished</div> \n </div> \n </a> \n " )
else :
writeindex . write ( " <a> \n <div> " + str ( unfinished ) + " </div> \n <div> \n <img src= \" UF.png \" > \n </div> \n <div> \n <div class= \" Unfinished \" style= \" width: calc(100 % * ( " + str ( unfinished ) + " / " + str ( maxvalue ) + " )); \" > \n </div> \n <div class= \" borderless \" > " + str ( round ( ( ( unfinished / total ) * 100 ) , 1 ) ) + " % Unfinished</div> \n </div> \n </a> \n " )
if beaten / maxvalue > 0.5 :
writeindex . write ( " <a> \n <div> " + str ( beaten ) + " </div> \n <div> \n <img src= \" B.png \" > \n </div> \n <div> \n <div class= \" Beaten \" style= \" width: calc(100 % * ( " + str ( beaten ) + " / " + str ( maxvalue ) + " )); \" > " + str ( round ( ( ( beaten / total ) * 100 ) , 1 ) ) + " % Beaten</div> \n </div> \n </a> \n " )
else :
writeindex . write ( " <a> \n <div> " + str ( beaten ) + " </div> \n <div> \n <img src= \" B.png \" > \n </div> \n <div> \n <div class= \" Beaten \" style= \" width: calc(100 % * ( " + str ( beaten ) + " / " + str ( maxvalue ) + " )); \" > \n </div> \n <div class= \" borderless \" > " + str ( round ( ( ( beaten / total ) * 100 ) , 1 ) ) + " % Beaten</div> \n </div> \n </a> \n " )
if completed / maxvalue > 0.5 :
writeindex . write ( " <a> \n <div> " + str ( completed ) + " </div> \n <div> \n <img src= \" C.png \" > \n </div> \n <div> \n <div class= \" Completed \" style= \" width: calc(100 % * ( " + str ( completed ) + " / " + str ( maxvalue ) + " )); \" > " + str ( round ( ( ( completed / total ) * 100 ) , 1 ) ) + " % Completed</div> \n </div> \n </a> \n " )
else :
writeindex . write ( " <a> \n <div> " + str ( completed ) + " </div> \n <div> \n <img src= \" C.png \" > \n </div> \n <div> \n <div class= \" Completed \" style= \" width: calc(100 % * ( " + str ( completed ) + " / " + str ( maxvalue ) + " )); \" > \n </div> \n <div class= \" borderless \" > " + str ( round ( ( ( completed / total ) * 100 ) , 1 ) ) + " % Completed</div> \n </div> \n </a> \n " )
if endless / maxvalue > 0.5 :
writeindex . write ( " <a> \n <div> " + str ( endless ) + " </div> \n <div> \n <img src= \" E.png \" > \n </div> \n <div> \n <div class= \" Endless \" style= \" width: calc(100 % * ( " + str ( endless ) + " / " + str ( maxvalue ) + " )); \" > " + str ( round ( ( ( endless / total ) * 100 ) , 1 ) ) + " % E ndless</div> \n </div> \n </a> \n " )
else :
writeindex . write ( " <a> \n <div> " + str ( endless ) + " </div> \n <div> \n <img src= \" E.png \" > \n </div> \n <div> \n <div class= \" Endless \" style= \" width: calc(100 % * ( " + str ( endless ) + " / " + str ( maxvalue ) + " )); \" > \n </div> \n <div class= \" borderless \" > " + str ( round ( ( ( endless / total ) * 100 ) , 1 ) ) + " % E ndless</div> \n </div> \n </a> \n " )
writeindex . write ( " </div> \n </div> \n </div> " )
# PLATFORM SUMMARY
writeindex . write ( " <h1>Platform Summary</h1> \n <div class= \" platform-summary \" > \n " )
def liststats ( title , abbr , consolelist ) :
completed = 0
beaten = 0
endless = 0
unfinished = 0
total = len ( consolelist )
if total > 0 :
writeindex . write ( " <div class= \" platform-card \" > \n <a class= \" title \" > " + title + " </a> \n <a class= \" abbr \" > " + abbr + " </a> \n <div class= \" bars \" > \n " )
for game in consolelist :
try :
if game [ " completed " ] :
completed + = 1
except :
try :
if game [ " beaten " ] :
beaten + = 1
except :
try :
if game [ " gameplay " ] :
if game [ " id " ] in endlessgames :
endless + = 1
else :
unfinished + = 1
except :
pass
unplayed = total - ( completed + beaten + unfinished )
if unplayed > 0 :
writeindex . write ( " <a class= \" unplayed \" title= \" Unplayed \" style= \" flex: " + str ( unplayed ) + " 1 0 % ; \" > " + str ( unplayed ) + " </a> \n " )
if unfinished > 0 :
writeindex . write ( " <a class= \" unfinished \" title= \" Unfinished \" style= \" flex: " + str ( unfinished ) + " 1 0 % ; \" > " + str ( unfinished ) + " </a> \n " )
if beaten > 0 :
writeindex . write ( " <a class= \" beaten \" title= \" Beaten \" style= \" flex: " + str ( beaten ) + " 1 0 % ; \" > " + str ( beaten ) + " </a> \n " )
if completed > 0 :
writeindex . write ( " <a class= \" completed \" title= \" Completed \" style= \" flex: " + str ( completed ) + " 1 0 % ; \" > " + str ( completed ) + " </a> \n " )
if endless > 0 :
writeindex . write ( " <a class= \" endless \" title= \" Endless \" style= \" flex: " + str ( endless ) + " 1 0 % ; \" > " + str ( endless ) + " </a> \n " )
writeindex . write ( " </div> \n <a class= \" total \" > " + str ( total ) + " \n <span>Total</span> \n </a> \n </div> \n " )
liststats ( " Nintendo DS " , " DS " , dslist )
liststats ( " Nintendo 3DS " , " 3DS " , threedslist )
liststats ( " Nintendo Switch " , " Switch " , switchlist )
liststats ( " PC " , " PC " , pclist )
liststats ( " PlayStation 2 " , " PS2 " , ps2list )
liststats ( " PlayStation 3 " , " PS3 " , ps3list )
liststats ( " PlayStation 5 " , " PS5 " , ps5list )
liststats ( " Xbox 360 " , " Xbox360 " , xbox360list )
writeindex . write ( " </div> \n </div> \n </section> \n </section> \n </main> \n </div> \n </div> \n </body> \n </html> \n " )
# LIBRARY
writelibrary . write ( " <!DOCTYPE html> \n <html lang= \" en \" style= \" --active-base: #364563; --active-text: #FFFFFF; --active-text-50: #FFFFFF60; --active-text-25: #FFFFFF30; --active-secondary: #222a3a; --active-secondary-50: #222a3a80; --active-secondary-text: #FFFFFF; --active-secondary-text-50: #FFFFFF70; --active-secondary-text-25: #FFFFFF30; --active-accent: #00fffb; --active-accent-75: #00fffbc0; --active-accent-text: #000000DD; --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); --platform-bw: none; --active-accent-shadow: #FFFFFF66; --retro-border: url( ' /img/border.png ' ); \" > \n <head> \n <meta charset= \" utf-8 \" > \n <meta name= \" viewport \" content= \" width=device-width,initial-scale=1 \" > \n <meta name= \" theme-color \" content= \" #424957 \" > \n <link href= \" https://fonts.googleapis.com/icon?family=Material+Icons \" rel= \" stylesheet \" > \n <link href= \" https://fonts.googleapis.com/css?family=Lato|Teko|Titillium+Web \" rel= \" stylesheet \" > \n <title>Selfhostery etc.</title> \n <link href= \" backloggery.css \" rel= \" stylesheet \" > \n </head> \n <body> \n <div id= \" app \" > \n <div class= \" profile \" > \n <main> \n <section> \n <div class= \" tabs \" > \n <a href= \" \" class= \" \" >Backlog</a> \n <a href= \" \" class= \" router-link-exact-active router-link-active \" style= \" \" aria-current= \" page \" >Library</a> \n <a href= \" https://backloggery.club/demo/history \" class= \" \" >History</a> \n </div> \n <section id= \" library-top \" class= \" library \" > \n <div> \n <div class= \" unibar \" > \n <div> \n <span>Total Found</span> " + str ( total ) + " \n </div> \n " )
if unplayed > 0 :
writelibrary . write ( " <div class= \" unplayed \" style= \" flex: " + str ( unplayed ) + " 1 0 % ; \" > " + str ( unplayed ) + " </div> \n " )
if unfinished > 0 :
writelibrary . write ( " <div class= \" unfinished \" style= \" flex: " + str ( unfinished ) + " 1 0 % ; \" > " + str ( unfinished ) + " </div> \n " )
if beaten > 0 :
writelibrary . write ( " <div class= \" beaten \" style= \" flex: " + str ( beaten ) + " 1 0 % ; \" > " + str ( beaten ) + " </div> \n " )
if completed > 0 :
writelibrary . write ( " <div class= \" completed \" style= \" flex: " + str ( completed ) + " 1 0 % ; \" > " + str ( completed ) + " </div> \n " )
if endless > 0 :
writelibrary . write ( " <div class= \" endless \" style= \" flex: " + str ( endless ) + " 1 0 % ; \" > " + str ( endless ) + " </div> \n " )
writelibrary . write ( " </div> \n <div class= \" library-list sorted \" > \n " )
newgames = sorted ( games , key = lambda d : d [ " id " ] )
decay = False
for game in newgames :
playcard ( game , " library " )
# HISTORY
theyear = int ( thisyear )
while theyear > 2016 :
added = 0
started = 0
beat = 0
completed = 0
beatorcompleted = 0
for game in games :
if game [ " initialdate " ] . year == theyear :
added + = 1
try :
if game [ " firstplayed " ] . year == theyear :
started + = 1
except :
pass
try :
if game [ " beaten " ] . year == theyear :
beat + = 1
beatorcompleted + = 1
try :
if game [ " completed " ] . year == theyear :
completed + = 1
except :
pass
except :
try :
if game [ " completed " ] . year == theyear :
completed + = 1
beatorcompleted + = 1
except :
pass
backlog = added - beatorcompleted
print ( str ( theyear ) + " Summary " )
if backlog > 0 :
print ( " Backlog ▲ " + str ( backlog ) )
elif backlog == 0 :
print ( " Backlog 0 " )
elif backlog < 0 :
print ( " Backlog ▼ " + str ( backlog * - 1 ) )
print ( " Added " + str ( added ) )
print ( " Started " + str ( started ) )
print ( " Beat " + str ( beat ) )
print ( " Completed " + str ( completed ) )
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 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 :
if checkdate != event [ " date " ] :
print ( event [ " date " ] . strftime ( " % Y- % -m- %-d " ) )
print ( event [ " action " ] + " : " + event [ " name " ] + " ( " + event [ " console " ] + " ) " )
checkdate = event [ " date " ]
theyear - = 1