Initial version
commit
79a4d3411b
|
@ -0,0 +1,4 @@
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.swp
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Wilty
|
||||||
|
|
||||||
|
A mini utility script for curiouser's *botany* (a plant-cultivating game).
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT (c) 2019 mio
|
|
@ -0,0 +1,104 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import pwd
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class Wilty():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.save_dir = ".botany"
|
||||||
|
self.plant_file = "_plant_data.json"
|
||||||
|
self.visit_file = "visitors.json"
|
||||||
|
self.plants = {}
|
||||||
|
self.loadData()
|
||||||
|
|
||||||
|
def convertTS(self, ts):
|
||||||
|
"""Convert a timestamp in seconds to a legible format, e.g. 12d 12h
|
||||||
|
12m."""
|
||||||
|
days = int(ts / 86400)
|
||||||
|
hours = int((ts % 86400) / 3600)
|
||||||
|
mins = round(((ts % 86400) % 3600) / 60)
|
||||||
|
return str(days) + "d " + str(hours) + "h " + str(mins) + "m"
|
||||||
|
|
||||||
|
def getUsers(self):
|
||||||
|
"""Load usernames into the plants dictionary as keys."""
|
||||||
|
sys_users = pwd.getpwall()
|
||||||
|
for u in sys_users:
|
||||||
|
if os.path.exists("/home/" + u.pw_name + "/" + self.save_dir):
|
||||||
|
self.plants[u.pw_name] = {}
|
||||||
|
|
||||||
|
def checkPlant(self, user):
|
||||||
|
"""Given the username, calculates the last time since the user's
|
||||||
|
plant was watered, estimates whether it is dead and updates the plants
|
||||||
|
dictionary."""
|
||||||
|
# Get last visitor timestamp and check if later than user's
|
||||||
|
visitor_ts = 0
|
||||||
|
if self.plants[user]["visitors"] != []:
|
||||||
|
visitor_ts = self.plants[user]["visitors"][-1]["timestamp"]
|
||||||
|
watered = max(self.plants[user]["last_watered"], visitor_ts)
|
||||||
|
time_since = int(time.time()) - watered
|
||||||
|
self.plants[user]["time_since"] = time_since
|
||||||
|
# >432000 (5 days) = dead plant
|
||||||
|
if time_since > 432000:
|
||||||
|
self.plants[user]["is_dead"] = True
|
||||||
|
self.plants[user]["time_since_fmt"] = self.convertTS(time_since)
|
||||||
|
|
||||||
|
def loadData(self):
|
||||||
|
"""Load plant and visitor data into plants dictionary."""
|
||||||
|
self.getUsers()
|
||||||
|
for u in self.plants:
|
||||||
|
sv_dir = "/home/" + u + "/" + self.save_dir + "/"
|
||||||
|
# Get plant data
|
||||||
|
if os.access(sv_dir + u + self.plant_file, os.R_OK):
|
||||||
|
with open(sv_dir + u + self.plant_file) as plant_fh:
|
||||||
|
plant_json = plant_fh.read()
|
||||||
|
self.plants[u] = json.loads(plant_json)
|
||||||
|
self.plants[u]["allow_query"] = True
|
||||||
|
else:
|
||||||
|
self.plants[u]["allow_query"] = False
|
||||||
|
# Get visitor data
|
||||||
|
if os.access(sv_dir + self.visit_file, os.R_OK) and \
|
||||||
|
os.access(sv_dir + self.visit_file, os.W_OK):
|
||||||
|
with open(sv_dir + self.visit_file) as visit_fh:
|
||||||
|
visit_json = visit_fh.read()
|
||||||
|
self.plants[u]["visitors"] = json.loads(visit_json)
|
||||||
|
self.plants[u]["allow_visit"] = True
|
||||||
|
else:
|
||||||
|
self.plants[u]["allow_visit"] = False
|
||||||
|
self.plants[u]["visitors"] = []
|
||||||
|
# Update plant watered state if plant data is readable
|
||||||
|
if self.plants[u]["allow_query"]:
|
||||||
|
self.checkPlant(u)
|
||||||
|
|
||||||
|
def listLivePlants(self, *args, **kwargs):
|
||||||
|
"""List living plants open to visitors."""
|
||||||
|
sort_l = []
|
||||||
|
for p in self.plants:
|
||||||
|
if self.plants[p]["allow_query"] and \
|
||||||
|
self.plants[p]["allow_visit"] and \
|
||||||
|
not self.plants[p]["is_dead"]:
|
||||||
|
sort_l.append((p, self.plants[p]["description"].split()[-1], \
|
||||||
|
self.plants[p]["time_since_fmt"], \
|
||||||
|
self.plants[p]["time_since"]))
|
||||||
|
# Sort by column
|
||||||
|
column = kwargs.get("sort", "")
|
||||||
|
if column == "user":
|
||||||
|
sort_l.sort(key=lambda c: c[0])
|
||||||
|
elif column == "plant":
|
||||||
|
sort_l.sort(key=lambda c: c[1])
|
||||||
|
else:
|
||||||
|
sort_l.sort(key=lambda c: c[3], reverse=True)
|
||||||
|
# Format output
|
||||||
|
border = "-" * 47
|
||||||
|
print(border)
|
||||||
|
print("{:<20s}{:<15s}{:<15s}".format("User", "Plant", "Last Watered"))
|
||||||
|
print(border)
|
||||||
|
for i in sort_l:
|
||||||
|
print("{:<20s}{:<15s}{:<15s}".format(i[0], i[1], i[2]))
|
||||||
|
print(border)
|
||||||
|
|
||||||
|
|
||||||
|
instance = Wilty()
|
||||||
|
instance.listLivePlants()
|
Loading…
Reference in New Issue