Source code for models

"""
    twtxt.models
    ~~~~~~~~~~~~

    This module implements the main models used in twtxt.

    :copyright: (c) 2016-2022 by buckket.
    :license: MIT, see LICENSE for more details.
"""

from datetime import datetime, timezone

import humanize
from dateutil.tz import tzlocal


[docs]class Tweet: """A :class:`Tweet` represents a single tweet. :param str text: text of the tweet in raw format :param ~datetime.datetime created_at: (optional) when the tweet was created, defaults to :meth:`~datetime.datetime.now` when no value is given :param Source source: (optional) the :class:`Source` the tweet is from """ def __init__(self, text, created_at=None, source=None): if text: self.text = text else: raise ValueError("empty text") if created_at is None: created_at = datetime.now(tzlocal()) try: self.created_at = created_at.replace(microsecond=0) except AttributeError: raise TypeError("created_at is of invalid type") self.source = source @staticmethod def _is_valid_operand(other): return (hasattr(other, "text") and hasattr(other, "created_at")) def __lt__(self, other): if not self._is_valid_operand(other): return NotImplemented return self.created_at < other.created_at def __le__(self, other): if not self._is_valid_operand(other): return NotImplemented return self.created_at < other.created_at or (self.created_at == other.created_at and self.text == other.text) def __gt__(self, other): if not self._is_valid_operand(other): return NotImplemented return self.created_at > other.created_at def __ge__(self, other): if not self._is_valid_operand(other): return NotImplemented return self.created_at > other.created_at or (self.created_at == other.created_at and self.text == other.text) def __eq__(self, other): if not self._is_valid_operand(other): return NotImplemented return self.created_at == other.created_at and self.text == other.text def __str__(self): return "{created_at}\t{text}".format(created_at=self.created_at.isoformat(), text=self.text) @property def relative_datetime(self): """Return human-readable relative time string.""" now = datetime.now(timezone.utc) created_at = self.created_at.astimezone(timezone.utc) delta = humanize.naturaldelta(abs(created_at - now)) tense = "from now" if now < created_at else "ago" return f"{delta} {tense}" @property def absolute_datetime(self): """Return human-readable absolute time string.""" return self.created_at.strftime("%a, %d %b %Y %H:%M:%S")
[docs]class Source: """A :class:`Source` represents a twtxt feed, remote as well as local. :param str nick: nickname of twtxt user :param str url: URL to remote twtxt file :param str file: path to local twtxt file """ def __init__(self, nick, url=None, file=None): self.nick = nick.lower() self.url = url self.file = file