diff --git a/cps/cw_login/login_manager.py b/cps/cw_login/login_manager.py
index 23ba52e73..a3714af60 100644
--- a/cps/cw_login/login_manager.py
+++ b/cps/cw_login/login_manager.py
@@ -1,4 +1,5 @@
-from datetime import datetime, UTC
+from datetime import datetime
+from datetime import timezone
from datetime import timedelta
import hashlib
@@ -496,7 +497,7 @@ class LoginManager:
duration = timedelta(seconds=duration)
try:
- expires = datetime.now(UTC) + duration
+ expires = datetime.now(timezone.utc) + duration
except TypeError as e:
raise Exception(
"REMEMBER_COOKIE_DURATION must be a datetime.timedelta,"
diff --git a/cps/db.py b/cps/db.py
index 758714ed1..d0edb871f 100644
--- a/cps/db.py
+++ b/cps/db.py
@@ -20,7 +20,7 @@
import os
import re
import json
-from datetime import datetime
+from datetime import datetime, timezone
from urllib.parse import quote
import unidecode
from weakref import WeakSet
@@ -378,10 +378,10 @@ class Books(Base):
title = Column(String(collation='NOCASE'), nullable=False, default='Unknown')
sort = Column(String(collation='NOCASE'))
author_sort = Column(String(collation='NOCASE'))
- timestamp = Column(TIMESTAMP, default=datetime.utcnow)
+ timestamp = Column(TIMESTAMP, default=lambda: datetime.now(timezone.utc))
pubdate = Column(TIMESTAMP, default=DEFAULT_PUBDATE)
series_index = Column(String, nullable=False, default="1.0")
- last_modified = Column(TIMESTAMP, default=datetime.utcnow)
+ last_modified = Column(TIMESTAMP, default=lambda: datetime.now(timezone.utc))
path = Column(String, default="", nullable=False)
has_cover = Column(Integer, default=0)
uuid = Column(String)
diff --git a/cps/editbooks.py b/cps/editbooks.py
index a143919c0..33a95fb19 100644
--- a/cps/editbooks.py
+++ b/cps/editbooks.py
@@ -21,7 +21,7 @@
# along with this program. If not, see .
import os
-from datetime import datetime, UTC
+from datetime import datetime, timezone
import json
from shutil import copyfile
from uuid import uuid4
@@ -200,7 +200,7 @@ def edit_book(book_id):
book.pubdate = db.Books.DEFAULT_PUBDATE
if modify_date:
- book.last_modified = datetime.now(UTC)
+ book.last_modified = datetime.now(timezone.utc)
kobo_sync_status.remove_synced_book(edited_books_id, all=True)
calibre_db.set_metadata_dirty(book.id)
@@ -444,7 +444,7 @@ def edit_list_book(param):
mimetype='application/json')
else:
return _("Parameter not found"), 400
- book.last_modified = datetime.now(UTC)
+ book.last_modified = datetime.now(timezone.utc)
calibre_db.session.commit()
# revert change for sort if automatic fields link is deactivated
@@ -560,7 +560,7 @@ def table_xchange_author_title():
# toDo: Handle error
edit_error = helper.update_dir_structure(edited_books_id, config.get_book_path(), input_authors[0])
if modify_date:
- book.last_modified = datetime.now(UTC)
+ book.last_modified = datetime.now(timezone.utc)
calibre_db.set_metadata_dirty(book.id)
try:
calibre_db.session.commit()
@@ -711,8 +711,8 @@ def create_book_on_upload(modify_date, meta):
pubdate = datetime(101, 1, 1)
# Calibre adds books with utc as timezone
- db_book = db.Books(title, "", sort_authors, datetime.now(UTC), pubdate,
- '1', datetime.now(UTC), path, meta.cover, db_author, [], "")
+ db_book = db.Books(title, "", sort_authors, datetime.now(timezone.utc), pubdate,
+ '1', datetime.now(timezone.utc), path, meta.cover, db_author, [], "")
modify_date |= modify_database_object(input_authors, db_book.authors, db.Authors, calibre_db.session,
'author')
diff --git a/cps/helper.py b/cps/helper.py
index a5931019a..bc95762c6 100644
--- a/cps/helper.py
+++ b/cps/helper.py
@@ -25,7 +25,7 @@ import re
import regex
import shutil
import socket
-from datetime import datetime, timedelta, UTC
+from datetime import datetime, timedelta, timezone
import requests
import unidecode
from uuid import uuid4
@@ -793,7 +793,7 @@ def get_book_cover_thumbnail(book, resolution):
.filter(ub.Thumbnail.type == THUMBNAIL_TYPE_COVER)
.filter(ub.Thumbnail.entity_id == book.id)
.filter(ub.Thumbnail.resolution == resolution)
- .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(UTC)))
+ .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(timezone.utc)))
.first())
@@ -831,7 +831,7 @@ def get_series_thumbnail(series_id, resolution):
.filter(ub.Thumbnail.type == THUMBNAIL_TYPE_SERIES)
.filter(ub.Thumbnail.entity_id == series_id)
.filter(ub.Thumbnail.resolution == resolution)
- .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(UTC)))
+ .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(timezone.utc)))
.first())
diff --git a/cps/kobo.py b/cps/kobo.py
index 8e5eed559..bd4deea50 100644
--- a/cps/kobo.py
+++ b/cps/kobo.py
@@ -18,7 +18,7 @@
# along with this program. If not, see .
import base64
-from datetime import datetime, UTC
+from datetime import datetime, timezone
import os
import uuid
import zipfile
@@ -131,7 +131,7 @@ def convert_to_kobo_timestamp_string(timestamp):
return timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
except AttributeError as exc:
log.debug("Timestamp not valid: {}".format(exc))
- return datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
+ return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
@kobo.route("/v1/library/sync")
@@ -375,7 +375,7 @@ def create_book_entitlement(book, archived):
book_uuid = str(book.uuid)
return {
"Accessibility": "Full",
- "ActivePeriod": {"From": convert_to_kobo_timestamp_string(datetime.now(UTC))},
+ "ActivePeriod": {"From": convert_to_kobo_timestamp_string(datetime.now(timezone.utc))},
"Created": convert_to_kobo_timestamp_string(book.timestamp),
"CrossRevisionId": book_uuid,
"Id": book_uuid,
@@ -795,7 +795,7 @@ def HandleStateRequest(book_uuid):
if new_book_read_status == ub.ReadBook.STATUS_IN_PROGRESS \
and new_book_read_status != book_read.read_status:
book_read.times_started_reading += 1
- book_read.last_time_started_reading = datetime.now(UTC)
+ book_read.last_time_started_reading = datetime.now(timezone.utc)
book_read.read_status = new_book_read_status
update_results_response["StatusInfoResult"] = {"Result": "Success"}
except (KeyError, TypeError, ValueError, StatementError):
diff --git a/cps/kobo_sync_status.py b/cps/kobo_sync_status.py
index 46e35e9be..357b84efe 100644
--- a/cps/kobo_sync_status.py
+++ b/cps/kobo_sync_status.py
@@ -19,7 +19,7 @@
from .cw_login import current_user
from . import ub
-from datetime import datetime, UTC
+from datetime import datetime, timezone
from sqlalchemy.sql.expression import or_, and_, true
# from sqlalchemy import exc
@@ -58,7 +58,7 @@ def change_archived_books(book_id, state=None, message=None):
archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id)
archived_book.is_archived = state if state else not archived_book.is_archived
- archived_book.last_modified = datetime.now(UTC) # toDo. Check utc timestamp
+ archived_book.last_modified = datetime.now(timezone.utc) # toDo. Check utc timestamp
ub.session.merge(archived_book)
ub.session_commit(message)
diff --git a/cps/shelf.py b/cps/shelf.py
index 1cf4bdb94..6558e8d59 100644
--- a/cps/shelf.py
+++ b/cps/shelf.py
@@ -21,7 +21,7 @@
# along with this program. If not, see .
import sys
-from datetime import datetime, UTC
+from datetime import datetime, timezone
from flask import Blueprint, flash, redirect, request, url_for, abort
from flask_babel import gettext as _
@@ -80,7 +80,7 @@ def add_to_shelf(shelf_id, book_id):
return "%s is a invalid Book Id. Could not be added to Shelf" % book_id, 400
shelf.books.append(ub.BookShelf(shelf=shelf.id, book_id=book_id, order=maxOrder + 1))
- shelf.last_modified = datetime.now(UTC)
+ shelf.last_modified = datetime.now(timezone.utc)
try:
ub.session.merge(shelf)
ub.session.commit()
@@ -139,7 +139,7 @@ def search_to_shelf(shelf_id):
for book in books_for_shelf:
maxOrder += 1
shelf.books.append(ub.BookShelf(shelf=shelf.id, book_id=book, order=maxOrder))
- shelf.last_modified = datetime.now(UTC)
+ shelf.last_modified = datetime.now(timezone.utc)
try:
ub.session.merge(shelf)
ub.session.commit()
@@ -185,7 +185,7 @@ def remove_from_shelf(shelf_id, book_id):
try:
ub.session.delete(book_shelf)
- shelf.last_modified = datetime.now(UTC)
+ shelf.last_modified = datetime.now(timezone.utc)
ub.session.commit()
except (OperationalError, InvalidRequestError) as e:
ub.session.rollback()
@@ -271,7 +271,7 @@ def order_shelf(shelf_id):
for book in books_in_shelf:
setattr(book, 'order', to_save[str(book.book_id)])
counter += 1
- # if order different from before -> shelf.last_modified = datetime.now(UTC)
+ # if order different from before -> shelf.last_modified = datetime.now(timezone.utc)
try:
ub.session.commit()
except (OperationalError, InvalidRequestError) as e:
diff --git a/cps/tasks/thumbnail.py b/cps/tasks/thumbnail.py
index 769309531..2142b018b 100644
--- a/cps/tasks/thumbnail.py
+++ b/cps/tasks/thumbnail.py
@@ -20,7 +20,7 @@ import os
from shutil import copyfile, copyfileobj
from urllib.request import urlopen
from io import BytesIO
-from datetime import datetime, UTC
+from datetime import datetime, timezone
from .. import constants
from cps import config, db, fs, gdriveutils, logger, ub
@@ -122,7 +122,7 @@ class TaskGenerateCoverThumbnails(CalibreTask):
.query(ub.Thumbnail) \
.filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \
.filter(ub.Thumbnail.entity_id == book_id) \
- .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(UTC))) \
+ .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(timezone.utc))) \
.all()
def create_book_cover_thumbnails(self, book):
@@ -164,7 +164,7 @@ class TaskGenerateCoverThumbnails(CalibreTask):
self.app_db_session.rollback()
def update_book_cover_thumbnail(self, book, thumbnail):
- thumbnail.generated_at = datetime.now(UTC)
+ thumbnail.generated_at = datetime.now(timezone.utc)
try:
self.app_db_session.commit()
@@ -325,7 +325,7 @@ class TaskGenerateSeriesThumbnails(CalibreTask):
.query(ub.Thumbnail)
.filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_SERIES)
.filter(ub.Thumbnail.entity_id == series_id)
- .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(UTC)))
+ .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.now(timezone.utc)))
.all())
def create_series_thumbnail(self, series, series_books, resolution):
@@ -345,7 +345,7 @@ class TaskGenerateSeriesThumbnails(CalibreTask):
self.app_db_session.rollback()
def update_series_thumbnail(self, series_books, thumbnail):
- thumbnail.generated_at = datetime.now(UTC)
+ thumbnail.generated_at = datetime.now(timezone.utc)
try:
self.app_db_session.commit()
diff --git a/cps/ub.py b/cps/ub.py
index 86184c729..e548cc12f 100644
--- a/cps/ub.py
+++ b/cps/ub.py
@@ -20,7 +20,7 @@
import atexit
import os
import sys
-from datetime import datetime, UTC, timedelta
+from datetime import datetime, timezone, timedelta
import itertools
import uuid
from flask import session as flask_session
@@ -370,8 +370,8 @@ class Shelf(Base):
user_id = Column(Integer, ForeignKey('user.id'))
kobo_sync = Column(Boolean, default=False)
books = relationship("BookShelf", backref="ub_shelf", cascade="all, delete-orphan", lazy="dynamic")
- created = Column(DateTime, default=lambda: datetime.now(UTC))
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
+ created = Column(DateTime, default=lambda: datetime.now(timezone.utc))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
def __repr__(self):
return '' % (self.id, self.name)
@@ -385,7 +385,7 @@ class BookShelf(Base):
book_id = Column(Integer)
order = Column(Integer)
shelf = Column(Integer, ForeignKey('shelf.id'))
- date_added = Column(DateTime, default=lambda: datetime.now(UTC))
+ date_added = Column(DateTime, default=lambda: datetime.now(timezone.utc))
def __repr__(self):
return '' % self.id
@@ -398,7 +398,7 @@ class ShelfArchive(Base):
id = Column(Integer, primary_key=True)
uuid = Column(String)
user_id = Column(Integer, ForeignKey('user.id'))
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc))
class ReadBook(Base):
@@ -418,7 +418,7 @@ class ReadBook(Base):
cascade="all",
backref=backref("book_read_link",
uselist=False))
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
last_time_started_reading = Column(DateTime, nullable=True)
times_started_reading = Column(Integer, default=0, nullable=False)
@@ -441,7 +441,7 @@ class ArchivedBook(Base):
user_id = Column(Integer, ForeignKey('user.id'))
book_id = Column(Integer)
is_archived = Column(Boolean, unique=False)
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc))
class KoboSyncedBooks(Base):
@@ -460,8 +460,8 @@ class KoboReadingState(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('user.id'))
book_id = Column(Integer)
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
- priority_timestamp = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
+ priority_timestamp = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
current_bookmark = relationship("KoboBookmark", uselist=False, backref="kobo_reading_state", cascade="all, delete")
statistics = relationship("KoboStatistics", uselist=False, backref="kobo_reading_state", cascade="all, delete")
@@ -471,7 +471,7 @@ class KoboBookmark(Base):
id = Column(Integer, primary_key=True)
kobo_reading_state_id = Column(Integer, ForeignKey('kobo_reading_state.id'))
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
location_source = Column(String)
location_type = Column(String)
location_value = Column(String)
@@ -484,7 +484,7 @@ class KoboStatistics(Base):
id = Column(Integer, primary_key=True)
kobo_reading_state_id = Column(Integer, ForeignKey('kobo_reading_state.id'))
- last_modified = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
+ last_modified = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
remaining_time_minutes = Column(Integer)
spent_reading_minutes = Column(Integer)
@@ -495,11 +495,11 @@ def receive_before_flush(session, flush_context, instances):
for change in itertools.chain(session.new, session.dirty):
if isinstance(change, (ReadBook, KoboStatistics, KoboBookmark)):
if change.kobo_reading_state:
- change.kobo_reading_state.last_modified = datetime.now(UTC)
+ change.kobo_reading_state.last_modified = datetime.now(timezone.utc)
# Maintain the last_modified_bit for the Shelf table.
for change in itertools.chain(session.new, session.deleted):
if isinstance(change, BookShelf):
- change.ub_shelf.last_modified = datetime.now(UTC)
+ change.ub_shelf.last_modified = datetime.now(timezone.utc)
# Baseclass representing Downloads from calibre-web in app.db
@@ -563,7 +563,7 @@ class Thumbnail(Base):
type = Column(SmallInteger, default=constants.THUMBNAIL_TYPE_COVER)
resolution = Column(SmallInteger, default=constants.COVER_THUMBNAIL_SMALL)
filename = Column(String, default=filename)
- generated_at = Column(DateTime, default=lambda: datetime.now(UTC))
+ generated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
expiration = Column(DateTime, nullable=True)