Skip to content

Commit

Permalink
pinnwand: use aware datetime objects
Browse files Browse the repository at this point in the history
Deprecation warnings are being emitted about using `datetime.utcnow` and
to replace those with `datetime.now(timezone.utc)`. This creates a
timezone aware datetime object hence we now need to get datetime aware
objects from the database as well.

This seems to a bit annoying in (for example SQLite) for the backend.

We use a 3rd-party package to provide us with an `UtcDateTime` type for
SQLAlchemy to fix this.

Signed-off-by: Simon de Vlieger <[email protected]>
  • Loading branch information
supakeen committed Nov 15, 2024
1 parent 8ce9367 commit e2af682
Show file tree
Hide file tree
Showing 10 changed files with 671 additions and 548 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ v1.6.1 (unreleased)
*******************
* Removed the default indentation from pastes. It now only applies to configured
languages again. Opened a public discussion about this behavior.
* Switched to timezone-aware objects in the databse to squash deprecation
warnings.

v1.6.0 (20241101)
*******************
Expand Down
603 changes: 336 additions & 267 deletions pdm.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies = [
"token-bucket>=0.3.0",
"tomli>=2.0.1",
"python-dotenv>=1.0.1",
"sqlalchemy-utc>=0.14.0",
]
requires-python = ">=3.8"
readme = "README.md"
Expand Down
558 changes: 304 additions & 254 deletions requirements.txt

Large diffs are not rendered by default.

23 changes: 12 additions & 11 deletions src/pinnwand/database/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import datetime
from datetime import timedelta
from datetime import timedelta, timezone
from typing import Optional

import pygments.lexers
from pygments_better_html import BetterHtmlFormatter
from sqlalchemy import (
Column,
DateTime,
ForeignKey,
Integer,
String,
Expand All @@ -18,6 +17,8 @@
relationship,
)

from sqlalchemy_utc import UtcDateTime

from pinnwand import defensive, error, logger, utility
from pinnwand.configuration import Configuration, ConfigurationProvider

Expand All @@ -42,15 +43,15 @@ def __tablename__(cls) -> str: # pylint: disable=no-self-argument
class Paste(Base): # type: ignore
"""The Paste model represents a single Paste."""

pub_date = Column(DateTime)
chg_date = Column(DateTime)
pub_date = Column(UtcDateTime)
chg_date = Column(UtcDateTime)

slug = Column(String(250), unique=True)
removal = Column(String(250), unique=True)

src = Column(String(250))

exp_date = Column(DateTime)
exp_date = Column(UtcDateTime)

files = relationship("File", cascade="all,delete", backref="paste")

Expand All @@ -66,8 +67,8 @@ def __init__(
self.slug = slug
self.removal = utility.slug_create(auto_scale=False)

self.pub_date = datetime.datetime.utcnow()
self.chg_date = datetime.datetime.utcnow()
self.pub_date = datetime.datetime.now(timezone.utc)
self.chg_date = datetime.datetime.now(timezone.utc)

self.src = src

Expand All @@ -82,8 +83,8 @@ class File(Base): # type: ignore
paste_id = Column(ForeignKey("paste.id"))
slug = Column(String(255), unique=True)

pub_date = Column(DateTime)
chg_date = Column(DateTime)
pub_date = Column(UtcDateTime)
chg_date = Column(UtcDateTime)

lexer = Column(String(250))

Expand All @@ -110,8 +111,8 @@ def __init__(
f"Text exceeds size limit {configuration.paste_size//1024} (kB)"
)

self.pub_date = datetime.datetime.utcnow()
self.chg_date = datetime.datetime.utcnow()
self.pub_date = datetime.datetime.now(timezone.utc)
self.chg_date = datetime.datetime.now(timezone.utc)

self.raw = raw

Expand Down
4 changes: 2 additions & 2 deletions src/pinnwand/handler/api_deprecated.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Any
from urllib.parse import urljoin

Expand Down Expand Up @@ -87,7 +87,7 @@ async def get(self, slug: str) -> None: # type: ignore
if not paste:
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down
4 changes: 2 additions & 2 deletions src/pinnwand/handler/api_v1.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Any
from urllib.parse import urljoin

Expand Down Expand Up @@ -136,7 +136,7 @@ async def get(self, slug: str) -> None:
if not paste:
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down
16 changes: 8 additions & 8 deletions src/pinnwand/handler/website.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import binascii
import io
import zipfile
from datetime import datetime
from datetime import datetime, timezone
from typing import Any

import docutils.core
Expand Down Expand Up @@ -307,7 +307,7 @@ async def get(self, slug: str) -> None: # type: ignore
if not paste:
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down Expand Up @@ -344,7 +344,7 @@ async def get(self, slug: str) -> None: # type: ignore
if not paste:
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down Expand Up @@ -374,7 +374,7 @@ async def get(self, file_id: str) -> None: # type: ignore
if not file:
raise tornado.web.HTTPError(404)

if file.paste.exp_date < datetime.utcnow():
if file.paste.exp_date < datetime.now(timezone.utc):
session.delete(file.paste)
session.commit()

Expand Down Expand Up @@ -405,7 +405,7 @@ async def get(self, file_id: str) -> None: # type: ignore
if not file:
raise tornado.web.HTTPError(404)

if file.paste.exp_date < datetime.utcnow():
if file.paste.exp_date < datetime.now(timezone.utc):
session.delete(file.paste)
session.commit()

Expand Down Expand Up @@ -436,7 +436,7 @@ async def get(self, paste_id: str) -> None: # type: ignore
if not paste:
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down Expand Up @@ -483,7 +483,7 @@ async def get(self, file_id: str) -> None: # type: ignore
if not file:
raise tornado.web.HTTPError(404)

if file.paste.exp_date < datetime.utcnow():
if file.paste.exp_date < datetime.now(timezone.utc):
session.delete(file.paste)
session.commit()

Expand Down Expand Up @@ -527,7 +527,7 @@ async def get(self, removal: str) -> None: # type: ignore
log.info("RemovePaste.get: someone visited with invalid id")
raise tornado.web.HTTPError(404)

if paste.exp_date < datetime.utcnow():
if paste.exp_date < datetime.now(timezone.utc):
session.delete(paste)
session.commit()

Expand Down
4 changes: 2 additions & 2 deletions src/pinnwand/utility.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import math
import re
from base64 import b32encode
from datetime import datetime
from datetime import datetime, timezone
from os import urandom
from typing import Any, Dict, List, Optional

Expand Down Expand Up @@ -192,7 +192,7 @@ def reap() -> None:
with manager.DatabaseManager.get_session() as session:
pastes = (
session.query(models.Paste)
.filter(models.Paste.exp_date < datetime.utcnow())
.filter(models.Paste.exp_date < datetime.now(timezone.utc))
.all()
)

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/pinnwand.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
database_uri = "sqlite:///C:\\Users\\shtlrs\\AppData\\Local\\Temp\\tmpvb8tgs72"
reaping_periodicity = 2000 # in milliseconds
database_uri = "sqlite:////tmp/tmp5r3kq5tn"
reaping_periodicity = 2000

[ratelimit.read]
capacity = 200
Expand Down

0 comments on commit e2af682

Please sign in to comment.