try timezones

This commit is contained in:
tonyrewin 2022-11-23 17:09:35 +03:00
parent a41af344a7
commit 94a31e29e5
16 changed files with 41 additions and 43 deletions

View File

@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timezone
import jwt import jwt
from base.exceptions import ExpiredToken, InvalidToken from base.exceptions import ExpiredToken, InvalidToken
from validations.auth import TokenPayload, AuthInput from validations.auth import TokenPayload, AuthInput
@ -8,13 +8,11 @@ from settings import JWT_ALGORITHM, JWT_SECRET_KEY
class JWTCodec: class JWTCodec:
@staticmethod @staticmethod
def encode(user: AuthInput, exp: datetime) -> str: def encode(user: AuthInput, exp: datetime) -> str:
expires = int(exp.timestamp() * 1000) issued = datetime.now(tz=timezone.utc)
issued = int(datetime.now().timestamp() * 1000)
payload = { payload = {
"user_id": user.id, "user_id": user.id,
"username": user.email or user.phone, "username": user.email or user.phone,
# "device": device, # no use cases "exp": exp,
"exp": expires,
"iat": issued, "iat": issued,
"iss": "discours" "iss": "discours"
} }

View File

@ -9,7 +9,7 @@ from settings import SESSION_TOKEN_LIFE_SPAN, ONETIME_TOKEN_LIFE_SPAN
async def save(token_key, life_span, auto_delete=True): async def save(token_key, life_span, auto_delete=True):
await redis.execute("SET", token_key, "True") await redis.execute("SET", token_key, "True")
if auto_delete: if auto_delete:
expire_at = (datetime.now() + timedelta(seconds=life_span)).timestamp() expire_at = (datetime.now(tz=timezone.utc) + timedelta(seconds=life_span)).timestamp()
await redis.execute("EXPIREAT", token_key, int(expire_at)) await redis.execute("EXPIREAT", token_key, int(expire_at))

View File

@ -4,7 +4,7 @@ import json
import os import os
import subprocess import subprocess
import sys import sys
from datetime import datetime from datetime import datetime, timezone
import bs4 import bs4
from migration.tables.comments import migrate as migrateComment from migration.tables.comments import migrate as migrateComment
@ -21,7 +21,7 @@ from orm import init_tables
# from export import export_email_subscriptions # from export import export_email_subscriptions
from .export import export_mdx, export_slug from .export import export_mdx, export_slug
TODAY = datetime.strftime(datetime.now(), "%Y%m%d") TODAY = datetime.strftime(datetime.now(tz=timezone.utc), "%Y%m%d")
OLD_DATE = "2016-03-05 22:22:00.350000" OLD_DATE = "2016-03-05 22:22:00.350000"

View File

@ -1,6 +1,6 @@
import json import json
import os import os
from datetime import datetime from datetime import datetime, timezone
import frontmatter import frontmatter
@ -11,7 +11,7 @@ OLD_DATE = "2016-03-05 22:22:00.350000"
EXPORT_DEST = "../discoursio-web/data/" EXPORT_DEST = "../discoursio-web/data/"
parentDir = "/".join(os.getcwd().split("/")[:-1]) parentDir = "/".join(os.getcwd().split("/")[:-1])
contentDir = parentDir + "/discoursio-web/content/" contentDir = parentDir + "/discoursio-web/content/"
ts = datetime.now() ts = datetime.now(tz=timezone.utc)
def get_metadata(r): def get_metadata(r):

View File

@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timezone
from dateutil.parser import parse as date_parse from dateutil.parser import parse as date_parse
@ -10,7 +10,7 @@ from orm.topic import TopicFollower
from orm.user import User from orm.user import User
from services.stat.reacted import ReactedStorage from services.stat.reacted import ReactedStorage
ts = datetime.now() ts = datetime.now(tz=timezone.utc)
async def migrate(entry, storage): async def migrate(entry, storage):

View File

@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timezone
import json import json
from dateutil.parser import parse as date_parse from dateutil.parser import parse as date_parse
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
@ -13,7 +13,7 @@ from services.stat.reacted import ReactedStorage
from services.stat.viewed import ViewedStorage from services.stat.viewed import ViewedStorage
OLD_DATE = "2016-03-05 22:22:00.350000" OLD_DATE = "2016-03-05 22:22:00.350000"
ts = datetime.now() ts = datetime.now(tz=timezone.utc)
type2layout = { type2layout = {
"Article": "article", "Article": "article",
"Literature": "literature", "Literature": "literature",

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import datetime from datetime import datetime, timezone
from urllib.parse import quote_plus from urllib.parse import quote_plus
from graphql.type import GraphQLResolveInfo from graphql.type import GraphQLResolveInfo
@ -26,7 +26,7 @@ from settings import SESSION_TOKEN_HEADER
async def get_current_user(_, info): async def get_current_user(_, info):
print('[resolvers.auth] get current user %s' % str(info)) print('[resolvers.auth] get current user %s' % str(info))
user = info.context["request"].user user = info.context["request"].user
user.lastSeen = datetime.now() user.lastSeen = datetime.now(tz=timezone.utc)
with local_session() as session: with local_session() as session:
session.add(user) session.add(user)
session.commit() session.commit()
@ -50,7 +50,7 @@ async def confirm_email(_, info, token):
user = session.query(User).where(User.id == user_id).first() user = session.query(User).where(User.id == user_id).first()
session_token = await TokenStorage.create_session(user) session_token = await TokenStorage.create_session(user)
user.emailConfirmed = True user.emailConfirmed = True
user.lastSeen = datetime.now() user.lastSeen = datetime.now(tz=timezone.utc)
session.add(user) session.add(user)
session.commit() session.commit()
return { return {

View File

@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timezone
from auth.authenticate import login_required from auth.authenticate import login_required
from base.orm import local_session from base.orm import local_session
@ -37,7 +37,7 @@ async def invite_author(_, info, author, shout):
if author.id in authors: if author.id in authors:
return {"error": "already added"} return {"error": "already added"}
shout.authors.append(author) shout.authors.append(author)
shout.updated_at = datetime.now() shout.updated_at = datetime.now(tz=timezone.utc)
session.add(shout) session.add(shout)
session.commit() session.commit()
@ -63,7 +63,7 @@ async def remove_author(_, info, author, shout):
if author.id not in authors: if author.id not in authors:
return {"error": "not in authors"} return {"error": "not in authors"}
shout.authors.remove(author) shout.authors.remove(author)
shout.updated_at = datetime.now() shout.updated_at = datetime.now(tz=timezone.utc)
session.add(shout) session.add(shout)
session.commit() session.commit()

View File

@ -1,4 +1,4 @@
from datetime import datetime from datetime import datetime, timezone
from auth.authenticate import login_required from auth.authenticate import login_required
from base.orm import local_session from base.orm import local_session
@ -71,7 +71,7 @@ async def update_shout(_, info, inp):
return {"error": "access denied"} return {"error": "access denied"}
else: else:
shout.update(inp) shout.update(inp)
shout.updatedAt = datetime.now() shout.updatedAt = datetime.now(tz=timezone.utc)
session.add(shout) session.add(shout)
if inp.get("topics"): if inp.get("topics"):
# remove old links # remove old links
@ -103,7 +103,7 @@ async def delete_shout(_, info, slug):
return {"error": "access denied"} return {"error": "access denied"}
for a in authors: for a in authors:
reactions_unfollow(a.slug, slug, True) reactions_unfollow(a.slug, slug, True)
shout.deletedAt = datetime.now() shout.deletedAt = datetime.now(tz=timezone.utc)
session.add(shout) session.add(shout)
session.commit() session.commit()

View File

@ -1,6 +1,6 @@
import json import json
import uuid import uuid
from datetime import datetime from datetime import datetime, timezone
from auth.authenticate import login_required from auth.authenticate import login_required
from base.redis import redis from base.redis import redis
@ -67,7 +67,7 @@ async def update_chat(_, info, chat_new: dict):
chat.update({ chat.update({
"title": chat_new.get("title", chat["title"]), "title": chat_new.get("title", chat["title"]),
"description": chat_new.get("description", chat["description"]), "description": chat_new.get("description", chat["description"]),
"updatedAt": int(datetime.now().timestamp()), "updatedAt": int(datetime.now(tz=timezone.utc).timestamp()),
"admins": chat_new.get("admins", chat["admins"]), "admins": chat_new.get("admins", chat["admins"]),
"users": chat_new.get("users", chat["users"]) "users": chat_new.get("users", chat["users"])
}) })
@ -90,8 +90,8 @@ async def create_chat(_, info, title="", members=[]):
members.append(user.slug) members.append(user.slug)
chat = { chat = {
"title": title, "title": title,
"createdAt": int(datetime.now().timestamp()), "createdAt": int(datetime.now(tz=timezone.utc).timestamp()),
"updatedAt": int(datetime.now().timestamp()), "updatedAt": int(datetime.now(tz=timezone.utc).timestamp()),
"createdBy": user.slug, "createdBy": user.slug,
"id": chat_id, "id": chat_id,
"users": members, "users": members,

View File

@ -1,5 +1,5 @@
import json import json
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from auth.authenticate import login_required from auth.authenticate import login_required
from base.redis import redis from base.redis import redis
@ -83,7 +83,7 @@ async def load_messages_by(_, info, by, limit: int = 50, offset: int = 0):
days = by.get("days") days = by.get("days")
if days: if days:
messages = filter( messages = filter(
lambda m: datetime.now() - int(m["createdAt"]) < timedelta(days=by.get("days")), lambda m: datetime.now(tz=timezone.utc) - int(m["createdAt"]) < timedelta(days=by.get("days")),
messages messages
) )
return { return {

View File

@ -1,6 +1,6 @@
import asyncio import asyncio
import json import json
from datetime import datetime from datetime import datetime, timezone
from auth.authenticate import login_required from auth.authenticate import login_required
from base.redis import redis from base.redis import redis
@ -28,7 +28,7 @@ async def create_message(_, info, chat: str, body: str, replyTo=None):
"author": user.slug, "author": user.slug,
"body": body, "body": body,
"replyTo": replyTo, "replyTo": replyTo,
"createdAt": int(datetime.now().timestamp()), "createdAt": int(datetime.now(tz=timezone.utc).timestamp()),
} }
await redis.execute( await redis.execute(
"SET", f"chats/{chat['id']}/messages/{message_id}", json.dumps(new_message) "SET", f"chats/{chat['id']}/messages/{message_id}", json.dumps(new_message)
@ -70,7 +70,7 @@ async def update_message(_, info, chat_id: str, message_id: int, body: str):
return {"error": "access denied"} return {"error": "access denied"}
message["body"] = body message["body"] = body
message["updatedAt"] = int(datetime.now().timestamp()) message["updatedAt"] = int(datetime.now(tz=timezone.utc).timestamp())
await redis.execute("SET", f"chats/{chat_id}/messages/{message_id}", json.dumps(message)) await redis.execute("SET", f"chats/{chat_id}/messages/{message_id}", json.dumps(message))

View File

@ -1,4 +1,4 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.sql.expression import desc, asc, select, case from sqlalchemy.sql.expression import desc, asc, select, case
@ -27,7 +27,7 @@ def apply_filters(q, filters, user=None):
if filters.get("body"): if filters.get("body"):
q = q.filter(Shout.body.ilike(f'%{filters.get("body")}%s')) q = q.filter(Shout.body.ilike(f'%{filters.get("body")}%s'))
if filters.get("days"): if filters.get("days"):
before = datetime.now() - timedelta(days=int(filters.get("days")) or 30) before = datetime.now(tz=timezone.utc) - timedelta(days=int(filters.get("days")) or 30)
q = q.filter(Shout.createdAt > before) q = q.filter(Shout.createdAt > before)
return q return q

View File

@ -1,5 +1,5 @@
from typing import List from typing import List
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from sqlalchemy import and_, func from sqlalchemy import and_, func
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
@ -203,10 +203,10 @@ async def load_authors_by(_, info, by, limit, offset):
aaa = list(map(lambda a: a.slug, TopicStat.authors_by_topic.get(by["topic"]))) aaa = list(map(lambda a: a.slug, TopicStat.authors_by_topic.get(by["topic"])))
aq = aq.filter(User.name._in(aaa)) aq = aq.filter(User.name._in(aaa))
if by.get("lastSeen"): # in days if by.get("lastSeen"): # in days
days_before = datetime.now() - timedelta(days=by["lastSeen"]) days_before = datetime.now(tz=timezone.utc) - timedelta(days=by["lastSeen"])
aq = aq.filter(User.lastSeen > days_before) aq = aq.filter(User.lastSeen > days_before)
elif by.get("createdAt"): # in days elif by.get("createdAt"): # in days
days_before = datetime.now() - timedelta(days=by["createdAt"]) days_before = datetime.now(tz=timezone.utc) - timedelta(days=by["createdAt"])
aq = aq.filter(User.createdAt > days_before) aq = aq.filter(User.createdAt > days_before)
aq = aq.group_by( aq = aq.group_by(
User.id User.id

View File

@ -1,4 +1,4 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from sqlalchemy import and_, asc, desc, select, text, func from sqlalchemy import and_, asc, desc, select, text, func
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
@ -109,7 +109,7 @@ def check_to_hide(session, user, reaction):
def set_published(session, slug, publisher): def set_published(session, slug, publisher):
s = session.query(Shout).where(Shout.slug == slug).first() s = session.query(Shout).where(Shout.slug == slug).first()
s.publishedAt = datetime.now() s.publishedAt = datetime.now(tz=timezone.utc)
s.publishedBy = publisher s.publishedBy = publisher
s.visibility = text('public') s.visibility = text('public')
session.add(s) session.add(s)
@ -166,7 +166,7 @@ async def update_reaction(_, info, inp):
if reaction.createdBy != user.slug: if reaction.createdBy != user.slug:
return {"error": "access denied"} return {"error": "access denied"}
reaction.body = inp["body"] reaction.body = inp["body"]
reaction.updatedAt = datetime.now() reaction.updatedAt = datetime.now(tz=timezone.utc)
if reaction.kind != inp["kind"]: if reaction.kind != inp["kind"]:
# NOTE: change mind detection can be here # NOTE: change mind detection can be here
pass pass
@ -191,7 +191,7 @@ async def delete_reaction(_, info, rid):
return {"error": "invalid reaction id"} return {"error": "invalid reaction id"}
if reaction.createdBy != user.slug: if reaction.createdBy != user.slug:
return {"error": "access denied"} return {"error": "access denied"}
reaction.deletedAt = datetime.now() reaction.deletedAt = datetime.now(tz=timezone.utc)
session.commit() session.commit()
return {} return {}
@ -240,7 +240,7 @@ async def load_reactions_by(_, _info, by, limit=50, offset=0):
if by.get('search', 0) > 2: if by.get('search', 0) > 2:
q = q.filter(Reaction.body.ilike(f'%{by["body"]}%')) q = q.filter(Reaction.body.ilike(f'%{by["body"]}%'))
if by.get("days"): if by.get("days"):
after = datetime.now() - timedelta(days=int(by["days"]) or 30) after = datetime.now(tz=timezone.utc) - timedelta(days=int(by["days"]) or 30)
q = q.filter(Reaction.createdAt > after) q = q.filter(Reaction.createdAt > after)
order_way = asc if by.get("sort", "").startswith("-") else desc order_way = asc if by.get("sort", "").startswith("-") else desc
order_field = by.get("sort") or Reaction.createdAt order_field = by.get("sort") or Reaction.createdAt

View File

@ -478,7 +478,7 @@ type TopicStat {
authors: Int! authors: Int!
# viewed: Int # viewed: Int
# reacted: Int! # reacted: Int!
#commented: Int # commented: Int
# rating: Int # rating: Int
} }