1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-13 05:20:01 +00:00

Make datetime utcnow compatible to older python versions

This commit is contained in:
Ozzie Isaacs 2024-08-10 21:05:29 +02:00
parent a56d1c80ae
commit 7a8d054b28
9 changed files with 45 additions and 44 deletions

View File

@ -1,4 +1,5 @@
from datetime import datetime, UTC from datetime import datetime
from datetime import timezone
from datetime import timedelta from datetime import timedelta
import hashlib import hashlib
@ -496,7 +497,7 @@ class LoginManager:
duration = timedelta(seconds=duration) duration = timedelta(seconds=duration)
try: try:
expires = datetime.now(UTC) + duration expires = datetime.now(timezone.utc) + duration
except TypeError as e: except TypeError as e:
raise Exception( raise Exception(
"REMEMBER_COOKIE_DURATION must be a datetime.timedelta," "REMEMBER_COOKIE_DURATION must be a datetime.timedelta,"

View File

@ -20,7 +20,7 @@
import os import os
import re import re
import json import json
from datetime import datetime from datetime import datetime, timezone
from urllib.parse import quote from urllib.parse import quote
import unidecode import unidecode
from weakref import WeakSet from weakref import WeakSet
@ -378,10 +378,10 @@ class Books(Base):
title = Column(String(collation='NOCASE'), nullable=False, default='Unknown') title = Column(String(collation='NOCASE'), nullable=False, default='Unknown')
sort = Column(String(collation='NOCASE')) sort = Column(String(collation='NOCASE'))
author_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) pubdate = Column(TIMESTAMP, default=DEFAULT_PUBDATE)
series_index = Column(String, nullable=False, default="1.0") 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) path = Column(String, default="", nullable=False)
has_cover = Column(Integer, default=0) has_cover = Column(Integer, default=0)
uuid = Column(String) uuid = Column(String)

View File

@ -21,7 +21,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os import os
from datetime import datetime, UTC from datetime import datetime, timezone
import json import json
from shutil import copyfile from shutil import copyfile
from uuid import uuid4 from uuid import uuid4
@ -200,7 +200,7 @@ def edit_book(book_id):
book.pubdate = db.Books.DEFAULT_PUBDATE book.pubdate = db.Books.DEFAULT_PUBDATE
if modify_date: 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) kobo_sync_status.remove_synced_book(edited_books_id, all=True)
calibre_db.set_metadata_dirty(book.id) calibre_db.set_metadata_dirty(book.id)
@ -444,7 +444,7 @@ def edit_list_book(param):
mimetype='application/json') mimetype='application/json')
else: else:
return _("Parameter not found"), 400 return _("Parameter not found"), 400
book.last_modified = datetime.now(UTC) book.last_modified = datetime.now(timezone.utc)
calibre_db.session.commit() calibre_db.session.commit()
# revert change for sort if automatic fields link is deactivated # revert change for sort if automatic fields link is deactivated
@ -560,7 +560,7 @@ def table_xchange_author_title():
# toDo: Handle error # toDo: Handle error
edit_error = helper.update_dir_structure(edited_books_id, config.get_book_path(), input_authors[0]) edit_error = helper.update_dir_structure(edited_books_id, config.get_book_path(), input_authors[0])
if modify_date: if modify_date:
book.last_modified = datetime.now(UTC) book.last_modified = datetime.now(timezone.utc)
calibre_db.set_metadata_dirty(book.id) calibre_db.set_metadata_dirty(book.id)
try: try:
calibre_db.session.commit() calibre_db.session.commit()
@ -711,8 +711,8 @@ def create_book_on_upload(modify_date, meta):
pubdate = datetime(101, 1, 1) pubdate = datetime(101, 1, 1)
# Calibre adds books with utc as timezone # Calibre adds books with utc as timezone
db_book = db.Books(title, "", sort_authors, datetime.now(UTC), pubdate, db_book = db.Books(title, "", sort_authors, datetime.now(timezone.utc), pubdate,
'1', datetime.now(UTC), path, meta.cover, db_author, [], "") '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, modify_date |= modify_database_object(input_authors, db_book.authors, db.Authors, calibre_db.session,
'author') 'author')

View File

@ -25,7 +25,7 @@ import re
import regex import regex
import shutil import shutil
import socket import socket
from datetime import datetime, timedelta, UTC from datetime import datetime, timedelta, timezone
import requests import requests
import unidecode import unidecode
from uuid import uuid4 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.type == THUMBNAIL_TYPE_COVER)
.filter(ub.Thumbnail.entity_id == book.id) .filter(ub.Thumbnail.entity_id == book.id)
.filter(ub.Thumbnail.resolution == resolution) .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()) .first())
@ -831,7 +831,7 @@ def get_series_thumbnail(series_id, resolution):
.filter(ub.Thumbnail.type == THUMBNAIL_TYPE_SERIES) .filter(ub.Thumbnail.type == THUMBNAIL_TYPE_SERIES)
.filter(ub.Thumbnail.entity_id == series_id) .filter(ub.Thumbnail.entity_id == series_id)
.filter(ub.Thumbnail.resolution == resolution) .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()) .first())

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64 import base64
from datetime import datetime, UTC from datetime import datetime, timezone
import os import os
import uuid import uuid
import zipfile import zipfile
@ -131,7 +131,7 @@ def convert_to_kobo_timestamp_string(timestamp):
return timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") return timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
except AttributeError as exc: except AttributeError as exc:
log.debug("Timestamp not valid: {}".format(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") @kobo.route("/v1/library/sync")
@ -375,7 +375,7 @@ def create_book_entitlement(book, archived):
book_uuid = str(book.uuid) book_uuid = str(book.uuid)
return { return {
"Accessibility": "Full", "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), "Created": convert_to_kobo_timestamp_string(book.timestamp),
"CrossRevisionId": book_uuid, "CrossRevisionId": book_uuid,
"Id": book_uuid, "Id": book_uuid,
@ -795,7 +795,7 @@ def HandleStateRequest(book_uuid):
if new_book_read_status == ub.ReadBook.STATUS_IN_PROGRESS \ if new_book_read_status == ub.ReadBook.STATUS_IN_PROGRESS \
and new_book_read_status != book_read.read_status: and new_book_read_status != book_read.read_status:
book_read.times_started_reading += 1 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 book_read.read_status = new_book_read_status
update_results_response["StatusInfoResult"] = {"Result": "Success"} update_results_response["StatusInfoResult"] = {"Result": "Success"}
except (KeyError, TypeError, ValueError, StatementError): except (KeyError, TypeError, ValueError, StatementError):

View File

@ -19,7 +19,7 @@
from .cw_login import current_user from .cw_login import current_user
from . import ub from . import ub
from datetime import datetime, UTC from datetime import datetime, timezone
from sqlalchemy.sql.expression import or_, and_, true from sqlalchemy.sql.expression import or_, and_, true
# from sqlalchemy import exc # 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 = 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.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.merge(archived_book)
ub.session_commit(message) ub.session_commit(message)

View File

@ -21,7 +21,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys import sys
from datetime import datetime, UTC from datetime import datetime, timezone
from flask import Blueprint, flash, redirect, request, url_for, abort from flask import Blueprint, flash, redirect, request, url_for, abort
from flask_babel import gettext as _ 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 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.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: try:
ub.session.merge(shelf) ub.session.merge(shelf)
ub.session.commit() ub.session.commit()
@ -139,7 +139,7 @@ def search_to_shelf(shelf_id):
for book in books_for_shelf: for book in books_for_shelf:
maxOrder += 1 maxOrder += 1
shelf.books.append(ub.BookShelf(shelf=shelf.id, book_id=book, order=maxOrder)) 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: try:
ub.session.merge(shelf) ub.session.merge(shelf)
ub.session.commit() ub.session.commit()
@ -185,7 +185,7 @@ def remove_from_shelf(shelf_id, book_id):
try: try:
ub.session.delete(book_shelf) ub.session.delete(book_shelf)
shelf.last_modified = datetime.now(UTC) shelf.last_modified = datetime.now(timezone.utc)
ub.session.commit() ub.session.commit()
except (OperationalError, InvalidRequestError) as e: except (OperationalError, InvalidRequestError) as e:
ub.session.rollback() ub.session.rollback()
@ -271,7 +271,7 @@ def order_shelf(shelf_id):
for book in books_in_shelf: for book in books_in_shelf:
setattr(book, 'order', to_save[str(book.book_id)]) setattr(book, 'order', to_save[str(book.book_id)])
counter += 1 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: try:
ub.session.commit() ub.session.commit()
except (OperationalError, InvalidRequestError) as e: except (OperationalError, InvalidRequestError) as e:

View File

@ -20,7 +20,7 @@ import os
from shutil import copyfile, copyfileobj from shutil import copyfile, copyfileobj
from urllib.request import urlopen from urllib.request import urlopen
from io import BytesIO from io import BytesIO
from datetime import datetime, UTC from datetime import datetime, timezone
from .. import constants from .. import constants
from cps import config, db, fs, gdriveutils, logger, ub from cps import config, db, fs, gdriveutils, logger, ub
@ -122,7 +122,7 @@ class TaskGenerateCoverThumbnails(CalibreTask):
.query(ub.Thumbnail) \ .query(ub.Thumbnail) \
.filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \ .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \
.filter(ub.Thumbnail.entity_id == book_id) \ .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() .all()
def create_book_cover_thumbnails(self, book): def create_book_cover_thumbnails(self, book):
@ -164,7 +164,7 @@ class TaskGenerateCoverThumbnails(CalibreTask):
self.app_db_session.rollback() self.app_db_session.rollback()
def update_book_cover_thumbnail(self, book, thumbnail): def update_book_cover_thumbnail(self, book, thumbnail):
thumbnail.generated_at = datetime.now(UTC) thumbnail.generated_at = datetime.now(timezone.utc)
try: try:
self.app_db_session.commit() self.app_db_session.commit()
@ -325,7 +325,7 @@ class TaskGenerateSeriesThumbnails(CalibreTask):
.query(ub.Thumbnail) .query(ub.Thumbnail)
.filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_SERIES) .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_SERIES)
.filter(ub.Thumbnail.entity_id == series_id) .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()) .all())
def create_series_thumbnail(self, series, series_books, resolution): def create_series_thumbnail(self, series, series_books, resolution):
@ -345,7 +345,7 @@ class TaskGenerateSeriesThumbnails(CalibreTask):
self.app_db_session.rollback() self.app_db_session.rollback()
def update_series_thumbnail(self, series_books, thumbnail): def update_series_thumbnail(self, series_books, thumbnail):
thumbnail.generated_at = datetime.now(UTC) thumbnail.generated_at = datetime.now(timezone.utc)
try: try:
self.app_db_session.commit() self.app_db_session.commit()

View File

@ -20,7 +20,7 @@
import atexit import atexit
import os import os
import sys import sys
from datetime import datetime, UTC, timedelta from datetime import datetime, timezone, timedelta
import itertools import itertools
import uuid import uuid
from flask import session as flask_session from flask import session as flask_session
@ -370,8 +370,8 @@ class Shelf(Base):
user_id = Column(Integer, ForeignKey('user.id')) user_id = Column(Integer, ForeignKey('user.id'))
kobo_sync = Column(Boolean, default=False) kobo_sync = Column(Boolean, default=False)
books = relationship("BookShelf", backref="ub_shelf", cascade="all, delete-orphan", lazy="dynamic") books = relationship("BookShelf", backref="ub_shelf", cascade="all, delete-orphan", lazy="dynamic")
created = Column(DateTime, default=lambda: datetime.now(UTC)) created = Column(DateTime, default=lambda: datetime.now(timezone.utc))
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))
def __repr__(self): def __repr__(self):
return '<Shelf %d:%r>' % (self.id, self.name) return '<Shelf %d:%r>' % (self.id, self.name)
@ -385,7 +385,7 @@ class BookShelf(Base):
book_id = Column(Integer) book_id = Column(Integer)
order = Column(Integer) order = Column(Integer)
shelf = Column(Integer, ForeignKey('shelf.id')) 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): def __repr__(self):
return '<Book %r>' % self.id return '<Book %r>' % self.id
@ -398,7 +398,7 @@ class ShelfArchive(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
uuid = Column(String) uuid = Column(String)
user_id = Column(Integer, ForeignKey('user.id')) 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): class ReadBook(Base):
@ -418,7 +418,7 @@ class ReadBook(Base):
cascade="all", cascade="all",
backref=backref("book_read_link", backref=backref("book_read_link",
uselist=False)) 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) last_time_started_reading = Column(DateTime, nullable=True)
times_started_reading = Column(Integer, default=0, nullable=False) times_started_reading = Column(Integer, default=0, nullable=False)
@ -441,7 +441,7 @@ class ArchivedBook(Base):
user_id = Column(Integer, ForeignKey('user.id')) user_id = Column(Integer, ForeignKey('user.id'))
book_id = Column(Integer) book_id = Column(Integer)
is_archived = Column(Boolean, unique=False) 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): class KoboSyncedBooks(Base):
@ -460,8 +460,8 @@ class KoboReadingState(Base):
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('user.id')) user_id = Column(Integer, ForeignKey('user.id'))
book_id = Column(Integer) book_id = Column(Integer)
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))
priority_timestamp = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(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") 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") 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) id = Column(Integer, primary_key=True)
kobo_reading_state_id = Column(Integer, ForeignKey('kobo_reading_state.id')) 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_source = Column(String)
location_type = Column(String) location_type = Column(String)
location_value = Column(String) location_value = Column(String)
@ -484,7 +484,7 @@ class KoboStatistics(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
kobo_reading_state_id = Column(Integer, ForeignKey('kobo_reading_state.id')) 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) remaining_time_minutes = Column(Integer)
spent_reading_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): for change in itertools.chain(session.new, session.dirty):
if isinstance(change, (ReadBook, KoboStatistics, KoboBookmark)): if isinstance(change, (ReadBook, KoboStatistics, KoboBookmark)):
if change.kobo_reading_state: 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. # Maintain the last_modified_bit for the Shelf table.
for change in itertools.chain(session.new, session.deleted): for change in itertools.chain(session.new, session.deleted):
if isinstance(change, BookShelf): 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 # Baseclass representing Downloads from calibre-web in app.db
@ -563,7 +563,7 @@ class Thumbnail(Base):
type = Column(SmallInteger, default=constants.THUMBNAIL_TYPE_COVER) type = Column(SmallInteger, default=constants.THUMBNAIL_TYPE_COVER)
resolution = Column(SmallInteger, default=constants.COVER_THUMBNAIL_SMALL) resolution = Column(SmallInteger, default=constants.COVER_THUMBNAIL_SMALL)
filename = Column(String, default=filename) 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) expiration = Column(DateTime, nullable=True)