import json from datetime import timedelta, datetime from pathlib import Path from typing import Optional from sqlalchemy import Column, Integer, String, Boolean, JSON, Date, ARRAY, ForeignKey, Computed, types from sqlalchemy.orm import relationship, Session from sqlalchemy.orm.collections import InstrumentedList from wrolpi.common import Base, tsvector, ModelHelper, PathColumn, get_absolute_media_path from wrolpi.dates import now, today, TZDateTime from wrolpi.db import get_db_curs from wrolpi.errors import UnknownVideo, NoFrequency, UnknownFile, UnknownDirectory class ChannelPath(types.TypeDecorator): impl = types.String def process_bind_param(self, value, dialect): return str(value) if value else None def process_result_value(self, value, dialect): if value: return Path(value) class Video(ModelHelper, Base): __tablename__ = 'video' id = Column(Integer, primary_key=True) channel_id = Column(Integer, ForeignKey('channel.id')) channel = relationship('Channel', primaryjoin='Video.channel_id==Channel.id', back_populates='videos') idempotency = Column(String) # File paths caption_path = Column(ChannelPath) description_path = Column(ChannelPath) ext = Column(String) info_json_path = Column(ChannelPath) poster_path = Column(ChannelPath) video_path = Column(ChannelPath) caption = Column(String) duration = Column(Integer) favorite = Column(TZDateTime) size = Column(Integer) source_id = Column(String) title = Column(String) upload_date = Column(TZDateTime) validated_poster = Column(Boolean, default=False) viewed = Column(TZDateTime) view_count = Column(Integer) textsearch = Column(tsvector, Computed('''to_tsvector('english'::regconfig, ((COALESCE(title, ''::text) || ' '::text) || COALESCE(caption, ''::text)))''')) def __repr__(self): return f'