mirror of
https://codeberg.org/Reuh/feather.git
synced 2025-10-27 18:19:32 +00:00
fix: handle negative timestamps
This commit is contained in:
parent
54fa01d4e5
commit
48c2c0f850
2 changed files with 24 additions and 12 deletions
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from ttrss.client import TTRClient
|
from ttrss.client import TTRClient, Headline
|
||||||
import google_reader
|
import google_reader
|
||||||
|
|
||||||
from feather.config import Config
|
from feather.config import Config
|
||||||
|
|
@ -146,11 +146,19 @@ class GReaderArticle(Article):
|
||||||
# several API references I've seen didn't mention canonical, but alternate seems to also be the article link (?) and should be an ok fallback
|
# several API references I've seen didn't mention canonical, but alternate seems to also be the article link (?) and should be an ok fallback
|
||||||
self.article_url = item_content.alternate[0].href
|
self.article_url = item_content.alternate[0].href
|
||||||
|
|
||||||
self._compute_json_path()
|
self.json_path = self._get_json_path()
|
||||||
|
|
||||||
|
|
||||||
## Tiny Tiny RSS API ##
|
## Tiny Tiny RSS API ##
|
||||||
|
|
||||||
|
# Monkey patch Headline.__init__ to skip timestamp to datetime conversion
|
||||||
|
# Articles may have a negative timestamp and Python's datetime.fromtimestamp doesn't like that, so instead we keep the timestamp and deal with the issue in data.py/format_datetime
|
||||||
|
def Headline_init(self, attr, client):
|
||||||
|
super(Headline, self).__init__(attr, client)
|
||||||
|
|
||||||
|
|
||||||
|
Headline.__init__ = Headline_init
|
||||||
|
|
||||||
|
|
||||||
class TTRSession(ClientSession):
|
class TTRSession(ClientSession):
|
||||||
"""Tiny Tiny RSS API client"""
|
"""Tiny Tiny RSS API client"""
|
||||||
|
|
@ -234,8 +242,8 @@ class TTRArticle(Article):
|
||||||
|
|
||||||
self.unread = article.unread
|
self.unread = article.unread
|
||||||
self.title = article.title
|
self.title = article.title
|
||||||
self.published = article.updated.timestamp()
|
self.published = article.updated
|
||||||
self.updated = article.updated.timestamp()
|
self.updated = article.updated
|
||||||
self.author = article.author
|
self.author = article.author
|
||||||
self.summary = article.excerpt
|
self.summary = article.excerpt
|
||||||
self.content = article.content
|
self.content = article.content
|
||||||
|
|
@ -248,4 +256,4 @@ class TTRArticle(Article):
|
||||||
self.language = article.lang
|
self.language = article.lang
|
||||||
self.image_url = article.flavor_image
|
self.image_url = article.flavor_image
|
||||||
|
|
||||||
self._compute_json_path()
|
self.json_path = self._get_json_path()
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
@ -40,9 +40,13 @@ def sanitize_filename(
|
||||||
|
|
||||||
def format_datetime(config: Config, timestamp: int) -> str:
|
def format_datetime(config: Config, timestamp: int) -> str:
|
||||||
"""Format a timestamp according to the configuraiton."""
|
"""Format a timestamp according to the configuraiton."""
|
||||||
return datetime.fromtimestamp(timestamp, config.timezone).strftime(
|
if timestamp < 0:
|
||||||
config.time_format
|
date = datetime(1970, 1, 1, tzinfo=config.timezone) + timedelta(
|
||||||
)
|
seconds=timestamp
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
date = datetime.fromtimestamp(timestamp, config.timezone)
|
||||||
|
return date.strftime(config.time_format)
|
||||||
|
|
||||||
|
|
||||||
def atomic_write(path: Path, content: str):
|
def atomic_write(path: Path, content: str):
|
||||||
|
|
@ -168,13 +172,13 @@ class Article(ABC):
|
||||||
d["category"] = self.category.asdict()
|
d["category"] = self.category.asdict()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def _compute_json_path(self):
|
def _get_json_path(self) -> Path:
|
||||||
self.json_path = self.config.json_root / f"{self._hash_id()}.json"
|
return self.config.json_root / f"{self._hash_id()}.json"
|
||||||
|
|
||||||
def _write_json(self, recompute_path=False):
|
def _write_json(self, recompute_path=False):
|
||||||
"""Write the JSON file associated with this article. Error if it already exists."""
|
"""Write the JSON file associated with this article. Error if it already exists."""
|
||||||
if recompute_path:
|
if recompute_path:
|
||||||
self._compute_json_path()
|
self.json_path = self._get_json_path()
|
||||||
stored_fields = (
|
stored_fields = (
|
||||||
"id",
|
"id",
|
||||||
"unread",
|
"unread",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue