aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/utils
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2018-04-20 22:12:03 +0200
committerGravatar GitHub <[email protected]>2018-04-20 22:12:03 +0200
commit35e0f4466677602e9ec6db614e8ea881dbf656cb (patch)
tree43ebdcc530b57211e45e4fe96bb2811e334640f0 /pysite/utils
parentAdded image URLs for each of these famous rappers. (#55) (diff)
[#1eeu1] Hiphopify (#54)
* Changed the dev-mode logic to be the same as prod for creating new tables if they don't exist. Also added a new feature where a table can be initialized with data if you create a JSON file in the pysite/database/table_init/ folder and fill it with a list of dicts where each dict represents a row in your table. Included a hiphoppers json so that I can actually test if it works in production. It will only init the table if the table is empty. * Not sure if this will solve it, but I think so. * Renamed the tables and primary keys, and alphabetized the dict. Now complies with the gdudes holy wishes. * Almost done with the initial build for this. Implemented GET and DELETE, in order to finish POST I need to expand the database.py interface class. * Alphabetized database convenience wrappers. * Fixed a few typehints and added the sample convenience wrapper to the database class. * Finishing up the POST method and adding a duration parser to the utils folder so we can handle strings like 2w3d and turn them into a timestamp. * Fixed API blueprint loading, which was broken by the setup method in the DBMixIn. I'd forgotten to remove the check for table_name attribute. Also adde some logging and got the DELETE route working. * Added timezone-sensitivity to the duration parser so it will work with rethink. renamed the json and fixed some bugs in the hiphopify API. * Added a utility to test if rdb timestamps are expired, and only returning data from the GET calls if it isn't expired. * changed some log wording * Setting up Lil Joseph as default image. Adding some rappers to the list. * Adding a bunch of logging * These tests no longer apply. New tests must be written in the long run, removing them for now. * Addressing review comments left by Volcyy * Fixed misleading comment.
Diffstat (limited to 'pysite/utils')
-rw-r--r--pysite/utils/time.py62
1 files changed, 62 insertions, 0 deletions
diff --git a/pysite/utils/time.py b/pysite/utils/time.py
new file mode 100644
index 00000000..334408a4
--- /dev/null
+++ b/pysite/utils/time.py
@@ -0,0 +1,62 @@
+from datetime import datetime, timedelta
+
+from rethinkdb import make_timezone
+
+
+UNITS = {
+ 's': lambda value: value,
+ 'm': lambda value: value * 60,
+ 'h': lambda value: value * 60 * 60,
+ 'd': lambda value: value * 60 * 60 * 24,
+ 'w': lambda value: value * 60 * 60 * 24 * 7
+}
+
+
+def parse_duration(duration: str) -> datetime:
+ """
+ Parses a string like '3w' into a datetime 3 weeks from now.
+
+ Also supports strings like 1w2d or 1h25m.
+
+ This function is adapted from a bot called ROWBOAT, written by b1naryth1ef.
+ See https://github.com/b1naryth1ef/rowboat/blob/master/rowboat/util/input.py
+
+ :param duration: a string containing the number and a time unit shorthand.
+ :return: A datetime representing now + the duration
+ """
+
+ if not duration:
+ raise ValueError("No duration provided.")
+
+ value = 0
+ digits = ''
+
+ for char in duration:
+
+ # Add all numbers to the digits string
+ if char.isdigit():
+ digits += char
+ continue
+
+ # If it's not a number and not one of the letters in UNITS, it must be invalid.
+ if char not in UNITS or not digits:
+ raise ValueError("Invalid duration")
+
+ # Otherwise, call the corresponding lambda to convert the value, and keep iterating.
+ value += UNITS[char](int(digits))
+ digits = ''
+
+ return datetime.now(make_timezone("00:00")) + timedelta(seconds=value + 1)
+
+
+def is_expired(rdb_datetime: datetime) -> bool:
+ """
+ Takes a rethinkdb datetime (timezone aware) and
+ figures out if it has expired yet.
+
+ Always compares with UTC 00:00
+
+ :param rdb_timestamp: A datetime as stored in rethinkdb.
+ :return: True if the datetime is in the past.
+ """
+ return datetime.now(make_timezone("00:00")) > rdb_datetime