From 79a4d3411bb7896194ee66a147b9c7f50d6213c1 Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 5 Jan 2019 23:26:07 +0000 Subject: [PATCH] Initial version --- .gitignore | 4 +++ README.md | 8 +++++ wilty.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 wilty.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cfef69 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.py[cod] +*$py.class +*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..a5f038f --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Wilty + +A mini utility script for curiouser's *botany* (a plant-cultivating game). + + +## License + +MIT (c) 2019 mio diff --git a/wilty.py b/wilty.py new file mode 100644 index 0000000..d28437d --- /dev/null +++ b/wilty.py @@ -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()