remove obsolete kontor.py #61

Merged
tpeetz merged 166 commits from develop/0.1.0 into main 2025-04-30 15:31:19 +00:00
13 changed files with 221 additions and 211 deletions
Showing only changes of commit 611d6b9e61 - Show all commits
+1 -1
View File
@@ -40,6 +40,6 @@ class CliBase(Controller):
) )
def gui(self): def gui(self):
application = QApplication([]) application = QApplication([])
window = MainWindow(self.app.session, self.app.engine, self.app.log) window = MainWindow(self.app.engine, self.app.config, self.app.log)
window.show() window.show()
application.exec() application.exec()
+2 -2
View File
@@ -26,7 +26,7 @@ class Database(Controller):
} }
if self.app.pargs.db_file is not None: if self.app.pargs.db_file is not None:
data['db_file'] = self.app.pargs.db_file data['db_file'] = self.app.pargs.db_file
kontor_db = KontorDB(self.app.session, self.app.engine, self.app.log) kontor_db = KontorDB(self.app.engine, self.app.log)
kontor_db.export_db(data['export_type'], data['db_file']) kontor_db.export_db(data['export_type'], data['db_file'])
self.app.render(data, 'command1.jinja2') self.app.render(data, 'command1.jinja2')
@@ -47,6 +47,6 @@ class Database(Controller):
} }
if self.app.pargs.db_file is not None: if self.app.pargs.db_file is not None:
data['db_file'] = self.app.pargs.db_file data['db_file'] = self.app.pargs.db_file
kontor_db = KontorDB(self.app.session, self.app.engine, self.app.log) kontor_db = KontorDB(self.app.engine, self.app.log)
self.app.render(data, 'import.jinja2') self.app.render(data, 'import.jinja2')
kontor_db.import_db(data['db_file'], self.app.pargs.dry_run) kontor_db.import_db(data['db_file'], self.app.pargs.dry_run)
+5 -9
View File
@@ -15,11 +15,8 @@ class Media(Controller):
help='update title for mediafiles', help='update title for mediafiles',
) )
def update_title(self): def update_title(self):
if self.app.pargs.dry_run: kontor_db = KontorDB(self.app.engine, self.app.config, self.app.log)
print('print command to shell') kontor_db.update_title(self.app.pargs.dry_run)
self.app.render({}, 'update.jinja2')
@ex( @ex(
label='download', label='download',
@@ -37,9 +34,8 @@ class Media(Controller):
} }
if self.app.pargs.media_dir is not None: if self.app.pargs.media_dir is not None:
data['media_dir'] = self.app.pargs.media_dir data['media_dir'] = self.app.pargs.media_dir
if self.app.pargs.dry_run: kontor_db = KontorDB(self.app.engine, self.app.config, self.app.log)
print('print command to shell') kontor_db.download_file(self.app.pargs.dry_run)
self.app.render(data, 'download.jinja2')
@ex( @ex(
help='add url to database', help='add url to database',
@@ -58,7 +54,7 @@ class Media(Controller):
data['link_url'] = self.app.pargs.link data['link_url'] = self.app.pargs.link
if self.app.pargs.dry_run: if self.app.pargs.dry_run:
print(f"add url {data['link_url']} to database") print(f"add url {data['link_url']} to database")
kontor_db = KontorDB(self.app.session, self.app.engine, self.app.log) kontor_db = KontorDB(self.app.engine, self.app.config, self.app.log)
kontor_db.add_link(self.app.pargs.link, self.app.pargs.dry_run) kontor_db.add_link(self.app.pargs.link, self.app.pargs.dry_run)
else: else:
+134 -43
View File
@@ -1,8 +1,15 @@
import json import json
import re
import subprocess
import uuid import uuid
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Any
import requests
from bs4 import BeautifulSoup
from cement.core.config import ConfigHandler
from sqlalchemy import Engine
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
@@ -16,9 +23,9 @@ from .media import MediaFile, MediaArticle, MediaVideo
class KontorDB: class KontorDB:
def __init__(self, db_session, db_engine, log): def __init__(self, db_engine: Engine, config: ConfigHandler, log):
self.session = db_session
self.engine = db_engine self.engine = db_engine
self.config = config
self.log = log self.log = log
self.registry = {} self.registry = {}
self.init_registry() self.init_registry()
@@ -50,37 +57,41 @@ class KontorDB:
self.registry['media_file'] = MediaFile self.registry['media_file'] = MediaFile
self.registry['media_article'] = MediaArticle self.registry['media_article'] = MediaArticle
self.registry['media_video'] = MediaVideo self.registry['media_video'] = MediaVideo
self.registry['meta_data_table'] = MetaDataTable
self.registry[MetaDataColumn.__tablename__] = MetaDataColumn
def get_table_names(self) -> list: def get_table_names(self) -> list:
result = [] result = []
__session__ = sessionmaker(self.engine) __session__ = sessionmaker(self.engine)
with __session__() as session: with __session__() as session:
tables = self.session.query(MetaDataTable).all() tables = session.query(MetaDataTable).all()
result = [table.table_name for table in tables] result = [table.table_name for table in tables]
return result return result
def get_column_meta_data(self, table_name: str, view_only=True) -> dict: def get_column_meta_data(self, table_name: str, view_only=True) -> dict:
meta_data = {} meta_data = {}
order = 0 order = 0
if view_only: __session__ = sessionmaker(self.engine)
for (_, column) in (self.session.query(MetaDataTable, MetaDataColumn). with __session__() as session:
filter(MetaDataTable.id == MetaDataColumn.table_id). if view_only:
filter(MetaDataTable.table_name == table_name). for (_, column) in (session.query(MetaDataTable, MetaDataColumn).
filter(MetaDataColumn.is_shown == 1).all()): filter(MetaDataTable.id == MetaDataColumn.table_id).
meta_data[order] = {'column': column.column_name, 'label': column.column_label, filter(MetaDataTable.table_name == table_name).
'order': column.column_order, 'ref_column': column.ref_column} filter(MetaDataColumn.is_shown == 1).all()):
order += 1 meta_data[order] = {'column': column.column_name, 'label': column.column_label,
else: 'order': column.column_order, 'ref_column': column.ref_column}
for (_, column) in (self.session.query(MetaDataTable, MetaDataColumn). order += 1
filter(MetaDataTable.id == MetaDataColumn.table_id). else:
filter(MetaDataTable.table_name == table_name).all()): for (_, column) in (session.query(MetaDataTable, MetaDataColumn).
meta_data[order] = { filter(MetaDataTable.id == MetaDataColumn.table_id).
'column': column.column_name, filter(MetaDataTable.table_name == table_name).all()):
'order': column.column_order, meta_data[order] = {
'ref_column': column.ref_column 'column': column.column_name,
} 'order': column.column_order,
order += 1 'ref_column': column.ref_column
return meta_data }
order += 1
return meta_data
def get_filters(self, table_name): def get_filters(self, table_name):
_filter_map = {} _filter_map = {}
@@ -193,20 +204,23 @@ class KontorDB:
def import_table(self, table_name, items, dry_run: bool): def import_table(self, table_name, items, dry_run: bool):
existing_ids = self.get_ids(table_name) existing_ids = self.get_ids(table_name)
for item in items: for item in items:
self.log.debug(f"{item}") # self.log.debug(f"{item}")
current_id = item['id'] current_id = item['id']
found_item = self.session.query(self.registry[table_name]).get(current_id) found_item = None
self.log.debug(f"found: {found_item}") __session__ = sessionmaker(self.engine)
if found_item is not None: with __session__() as session:
changed = self.update_entry(found_item, item, dry_run) found_item = session.query(self.registry[table_name]).get(current_id)
if changed: self.log.debug(f"found: {found_item}")
print(f"{current_id} has changed") if found_item is not None:
existing_ids.remove(current_id) changed = self.update_entry(found_item, item, dry_run)
else: if changed:
self.log.info("item to import not found in database, add new one...") print(f"{current_id} has changed")
existing_ids.remove(current_id)
else:
self.log.info("item to import not found in database, add new one...")
self.add_entry(table_name, item, session, dry_run)
if len(existing_ids) > 0: if len(existing_ids) > 0:
print("remaining items") print("remaining items")
self.session.commit()
def get_ids(self, table_name: str) -> list: def get_ids(self, table_name: str) -> list:
existing_ids = [] existing_ids = []
@@ -217,14 +231,15 @@ class KontorDB:
existing_ids.append(getattr(item, 'id')) existing_ids.append(getattr(item, 'id'))
return existing_ids return existing_ids
def add_entry(self, update_item: dict): def add_entry(self, table_name: str, update_item: dict, session, dry_run: bool):
media_file = MediaFile() add_item = self.registry[table_name]()
__session__ = sessionmaker(self.engine) for key in update_item.keys():
with __session__() as session: update_value = update_item[key]
for key in update_item.keys(): setattr(add_item, key, update_value)
update_value = update_item[key] if dry_run:
setattr(media_file, key, update_value) self.log.info(f"add item {type(add_item)} with id {update_item['id']}")
session.add(media_file) else:
session.add(add_item)
session.commit() session.commit()
def update_entry(self, existing_item, update_item: dict, dry_run: bool) -> bool: def update_entry(self, existing_item, update_item: dict, dry_run: bool) -> bool:
@@ -233,7 +248,7 @@ class KontorDB:
update_value = update_item[key] update_value = update_item[key]
existing_value = getattr(existing_item, key) existing_value = getattr(existing_item, key)
if type(existing_value) is not type(update_value): if type(existing_value) is not type(update_value):
self.log.debug(f"compare {type(existing_value)} with {type(update_value)}") # self.log.debug(f"compare {type(existing_value)} with {type(update_value)}")
existing_value = str(existing_value) existing_value = str(existing_value)
if existing_value != update_value: if existing_value != update_value:
print(f"{key} has changed: {existing_value} != {update_value}") print(f"{key} has changed: {existing_value} != {update_value}")
@@ -261,5 +276,81 @@ class KontorDB:
session.commit() session.commit()
self.log.info(f"entry {media_file} successfully added") self.log.info(f"entry {media_file} successfully added")
except IntegrityError as error: except IntegrityError as error:
self.session.rollback() session.rollback()
self.log.info(error.orig) self.log.info(error.orig)
def update_title(self, dry_run=False):
self.log.info(f"get links to review of media_file")
__session__ = sessionmaker(self.engine)
with __session__() as session:
links = session.query(MediaFile).filter(MediaFile.review == 1).all()
self.log.info(f"try to update {len(links)} items")
for link in links:
url = link.url
if url is None:
self.log.info(f"url has not been set for {link.id}")
continue
self.log.info('get title for url {}'.format(url))
if dry_run:
continue
try:
r = requests.get(url)
soup = BeautifulSoup(r.content, "html.parser")
title = soup.title.string
except:
self.log.info("Sorry, could not retrieve title")
continue
self.log.info('ID {} has title {}'.format(link.id, title))
link.title = title
link.review = 0
session.commit()
def download_file(self, dry_run=False):
self.log.info(f"download marked files of media_file")
__session__ = sessionmaker(self.engine)
with __session__() as session:
links = session.query(MediaFile).filter(MediaFile.should_download == 1).all()
self.log.info(f"try to download {len(links)} items")
for link in links:
url = link.url
if url is None:
self.log.info(f"url has not been set for {link.id}")
continue
if dry_run:
self.log.info(f"download {link.url} to {self.config.get('media', 'dir')}")
continue
filename = self.download_url(link)
if filename is None:
link.file_name = filename
link.should_download = 0
session.commit()
def parse_output(self, lines_list):
file_name = ""
for line in lines_list:
if 'has already been downloaded' in line:
end_len = len(' has already been downloaded')
file_name = line[11:-end_len]
self.log.info('found file: "%s"', file_name)
if 'Destination' in line:
line_len = len(line)
start_len = len('[download] Destination: ')
file_len = line_len - start_len
file_name = line[-file_len:]
self.log.info('new file: "%s"', file_name)
return file_name
def download_url(self, video_url):
media_dir = Path(self.config.get('media', 'dir'))
if not media_dir.exists():
media_dir = Path().absolute()
self.log.info(f"download video to {media_dir}")
result = subprocess.run([self.config.get('media', 'yt-dlp'), video_url], cwd=media_dir, capture_output=True,
text=True)
if result.returncode == 0:
output = result.stdout
output = re.sub(' +', ' ', output)
lines_list = output.splitlines()
return self.parse_output(lines_list)
else:
return None
+16 -1
View File
@@ -1,5 +1,20 @@
from sqlalchemy.orm import DeclarativeBase import uuid
from datetime import datetime
from sqlalchemy import Integer, func, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase): class Base(DeclarativeBase):
pass pass
class BaseMixin:
# id = Column(String, primary_key=True)
id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4())
# created_date = Column(DateTime)
created_date: Mapped[datetime] = mapped_column(default=func.now())
# last_modified_date = Column(DateTime)
last_modified_date: Mapped[datetime] = mapped_column(default=func.now())
# version = Column(Integer)
version: Mapped[int] = mapped_column(default=0)
+7 -31
View File
@@ -2,47 +2,31 @@ from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.dialects.mysql import BIT from sqlalchemy.dialects.mysql import BIT
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .base import Base from .base import Base, BaseMixin
class Article(Base): class Article(Base, BaseMixin):
__tablename__ = 'article' __tablename__ = 'article'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
title = Column(String(length=255), unique=True) title = Column(String(length=255), unique=True)
article_authors = relationship("ArticleAuthor") article_authors = relationship("ArticleAuthor")
class Author(Base): class Author(Base, BaseMixin):
__tablename__ = 'author' __tablename__ = 'author'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
first_name = Column(String(255)) first_name = Column(String(255))
last_name = Column(String(255)) last_name = Column(String(255))
article_authors = relationship("ArticleAuthor") article_authors = relationship("ArticleAuthor")
book_authors = relationship("BookAuthor") book_authors = relationship("BookAuthor")
class BookshelfPublisher(Base): class BookshelfPublisher(Base, BaseMixin):
__tablename__ = 'bookshelf_publisher' __tablename__ = 'bookshelf_publisher'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), unique=True) name = Column(String(length=255), unique=True)
books = relationship("Book") books = relationship("Book")
class Book(Base): class Book(Base, BaseMixin):
__tablename__ = 'book' __tablename__ = 'book'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
isbn = Column(String(255), unique=True) isbn = Column(String(255), unique=True)
title = Column(String(255)) title = Column(String(255))
year = Column(Integer, nullable=False) year = Column(Integer, nullable=False)
@@ -51,24 +35,16 @@ class Book(Base):
book_authors = relationship("BookAuthor") book_authors = relationship("BookAuthor")
class ArticleAuthor(Base): class ArticleAuthor(Base, BaseMixin):
__tablename__ = 'article_author' __tablename__ = 'article_author'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
article_id = Column(String, ForeignKey('article.id'), nullable=False) article_id = Column(String, ForeignKey('article.id'), nullable=False)
article = relationship('Article', back_populates="article_authors") article = relationship('Article', back_populates="article_authors")
author_id = Column(String, ForeignKey('author.id'), nullable=False) author_id = Column(String, ForeignKey('author.id'), nullable=False)
author = relationship('Author', back_populates="article_authors") author = relationship('Author', back_populates="article_authors")
class BookAuthor(Base): class BookAuthor(Base, BaseMixin):
__tablename__ = 'book_author' __tablename__ = 'book_author'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
author_id = Column(String, ForeignKey('author.id'), nullable=False) author_id = Column(String, ForeignKey('author.id'), nullable=False)
author = relationship('Author', back_populates="book_authors") author = relationship('Author', back_populates="book_authors")
book_id = Column(String, ForeignKey('book.id'), nullable=False) book_id = Column(String, ForeignKey('book.id'), nullable=False)
+16 -46
View File
@@ -2,15 +2,11 @@ from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.dialects.mysql import BIT from sqlalchemy.dialects.mysql import BIT
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .base import Base from .base import Base, BaseMixin
class Publisher(Base): class Publisher(Base, BaseMixin):
__tablename__ = "publisher" __tablename__ = "publisher"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), unique=True) name = Column(String(length=255), unique=True)
comics = relationship("Comic") comics = relationship("Comic")
@@ -21,12 +17,8 @@ class Publisher(Base):
return self.__repr__() return self.__repr__()
class Comic(Base): class Comic(Base, BaseMixin):
__tablename__ = 'comic' __tablename__ = 'comic'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
title = Column(String(length=255), unique=True) title = Column(String(length=255), unique=True)
publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False)
publisher = relationship("Publisher", back_populates="comics") publisher = relationship("Publisher", back_populates="comics")
@@ -45,24 +37,16 @@ class Comic(Base):
return f'{self.title}({self.id})' return f'{self.title}({self.id})'
class Volume(Base): class Volume(Base, BaseMixin):
__tablename__ = "volume" __tablename__ = "volume"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), nullable=False) name = Column(String(length=255), nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="volumes") comic = relationship("Comic", back_populates="volumes")
issues = relationship("Issue") issues = relationship("Issue")
class TradePaperback(Base): class TradePaperback(Base, BaseMixin):
__tablename__ = "trade_paperback" __tablename__ = "trade_paperback"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), nullable=False) name = Column(String(length=255), nullable=False)
issue_start = Column(Integer) issue_start = Column(Integer)
issue_end = Column(Integer) issue_end = Column(Integer)
@@ -70,23 +54,15 @@ class TradePaperback(Base):
comic = relationship("Comic", back_populates="trade_paperbacks") comic = relationship("Comic", back_populates="trade_paperbacks")
class StoryArc(Base): class StoryArc(Base, BaseMixin):
__tablename__ = "story_arc" __tablename__ = "story_arc"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), nullable=False) name = Column(String(length=255), nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="story_arcs") comic = relationship("Comic", back_populates="story_arcs")
class Issue(Base): class Issue(Base, BaseMixin):
__tablename__ = "issue" __tablename__ = "issue"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
issue_number = Column(String(255)) issue_number = Column(String(255))
in_stock = Column(BIT(1)) in_stock = Column(BIT(1))
is_read = Column(BIT(1)) is_read = Column(BIT(1))
@@ -96,32 +72,26 @@ class Issue(Base):
volume = relationship("Volume", back_populates="issues") volume = relationship("Volume", back_populates="issues")
class Artist(Base): class Artist(Base, BaseMixin):
__tablename__ = "artist" __tablename__ = "artist"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), nullable=False) name = Column(String(length=255), nullable=False)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
class WorkType(Base): class WorkType(Base, BaseMixin):
__tablename__ = "worktype" __tablename__ = "worktype"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(length=255), nullable=False, unique=True) name = Column(String(length=255), nullable=False, unique=True)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
def __repr__(self):
return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})'
class ComicWork(Base): def __str__(self):
return f'{self.name}({self.id})'
class ComicWork(Base, BaseMixin):
__tablename__ = "comic_work" __tablename__ = "comic_work"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="comic_works") comic = relationship("Comic", back_populates="comic_works")
artist_id = Column(String, ForeignKey("artist.id"), nullable=False) artist_id = Column(String, ForeignKey("artist.id"), nullable=False)
+4 -16
View File
@@ -1,15 +1,11 @@
from sqlalchemy import Column, DateTime, Integer, String from sqlalchemy import Column, DateTime, Integer, String
from sqlalchemy.dialects.mysql import BIT from sqlalchemy.dialects.mysql import BIT
from .base import Base from .base import Base, BaseMixin
class MediaFile(Base): class MediaFile(Base, BaseMixin):
__tablename__ = 'media_file' __tablename__ = 'media_file'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
cloud_link = Column(String(255)) cloud_link = Column(String(255))
file_name = Column(String(255)) file_name = Column(String(255))
path = Column(String(255)) path = Column(String(255))
@@ -25,23 +21,15 @@ class MediaFile(Base):
return f'{self.title}({self.id})' return f'{self.title}({self.id})'
class MediaArticle(Base): class MediaArticle(Base, BaseMixin):
__tablename__ = 'media_article' __tablename__ = 'media_article'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
review = Column(BIT(1)) review = Column(BIT(1))
title = Column(String(255)) title = Column(String(255))
url = Column(String(255), unique=True) url = Column(String(255), unique=True)
class MediaVideo(Base): class MediaVideo(Base, BaseMixin):
__tablename__ = 'media_video' __tablename__ = 'media_video'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
cloud_link = Column(String(255)) cloud_link = Column(String(255))
file_name = Column(String(255)) file_name = Column(String(255))
path = Column(String(255)) path = Column(String(255))
+3 -11
View File
@@ -2,15 +2,11 @@ from sqlalchemy import Column, String, ForeignKey, DateTime, Integer, Boolean
from sqlalchemy.dialects.mysql import BIT from sqlalchemy.dialects.mysql import BIT
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .base import Base from .base import Base, BaseMixin
class MetaDataTable(Base): class MetaDataTable(Base, BaseMixin):
__tablename__ = 'meta_data_table' __tablename__ = 'meta_data_table'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
table_name = Column(String(255), unique=True) table_name = Column(String(255), unique=True)
table_columns = relationship("MetaDataColumn") table_columns = relationship("MetaDataColumn")
@@ -21,12 +17,8 @@ class MetaDataTable(Base):
return f'{self.table_name}({self.id})' return f'{self.table_name}({self.id})'
class MetaDataColumn(Base): class MetaDataColumn(Base, BaseMixin):
__tablename__ = 'meta_data_column' __tablename__ = 'meta_data_column'
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
column_modifier = Column(String(255), nullable=True) column_modifier = Column(String(255), nullable=True)
column_name = Column(String(255)) column_name = Column(String(255))
column_order = Column(Integer) column_order = Column(Integer)
+10 -41
View File
@@ -2,29 +2,21 @@ from sqlalchemy import Column, DateTime, Integer, String, ForeignKey, UniqueCons
from sqlalchemy.dialects.mysql import BIT from sqlalchemy.dialects.mysql import BIT
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .base import Base from .base import Base, BaseMixin
class Sport(Base): class Sport(Base, BaseMixin):
__tablename__ = "sport" __tablename__ = "sport"
__table_args__ = ( __table_args__ = (
UniqueConstraint("name"), UniqueConstraint("name"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String(255), nullable=False, index=True, unique=True)
teams = relationship("Team") teams = relationship("Team")
positions = relationship("FieldPosition") positions = relationship("FieldPosition")
class Team(Base): class Team(Base, BaseMixin):
__tablename__ = "team" __tablename__ = "team"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String(255), nullable=False, index=True, unique=True)
short_name = Column(String(255), nullable=False, ) short_name = Column(String(255), nullable=False, )
sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport_id = Column(String, ForeignKey("sport.id"), nullable=False)
@@ -32,16 +24,12 @@ class Team(Base):
roosters = relationship("Rooster") roosters = relationship("Rooster")
class FieldPosition(Base): class FieldPosition(Base, BaseMixin):
__tablename__ = "field_position" __tablename__ = "field_position"
__table_args__ = ( __table_args__ = (
UniqueConstraint("name", "sport_id"), UniqueConstraint("name", "sport_id"),
UniqueConstraint("short_name", "sport_id"), UniqueConstraint("short_name", "sport_id"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(255), nullable=False, index=True) name = Column(String(255), nullable=False, index=True)
short_name = Column(String(255), nullable=False) short_name = Column(String(255), nullable=False)
sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True)
@@ -49,15 +37,11 @@ class FieldPosition(Base):
roosters = relationship("Rooster") roosters = relationship("Rooster")
class Player(Base): class Player(Base, BaseMixin):
__tablename__ = "player" __tablename__ = "player"
__table_args__ = ( __table_args__ = (
UniqueConstraint("first_name", "last_name"), UniqueConstraint("first_name", "last_name"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
first_name = Column(String(255), nullable=False, index=True) first_name = Column(String(255), nullable=False, index=True)
last_name = Column(String(255), nullable=False, index=True) last_name = Column(String(255), nullable=False, index=True)
roosters = relationship("Rooster") roosters = relationship("Rooster")
@@ -66,15 +50,11 @@ class Player(Base):
return f"{self.last_name}, {self.first_name}" return f"{self.last_name}, {self.first_name}"
class Rooster(Base): class Rooster(Base, BaseMixin):
__tablename__ = "rooster" __tablename__ = "rooster"
__table_args__ = ( __table_args__ = (
UniqueConstraint("year", "team_id", "player_id", "position_id"), UniqueConstraint("year", "team_id", "player_id", "position_id"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
year = Column(Integer) year = Column(Integer)
team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True)
team = relationship("Team", back_populates="roosters") team = relationship("Team", back_populates="roosters")
@@ -84,26 +64,19 @@ class Rooster(Base):
position = relationship("FieldPosition", back_populates="roosters") position = relationship("FieldPosition", back_populates="roosters")
cards = relationship("Card") cards = relationship("Card")
class Vendor(Base):
class Vendor(Base, BaseMixin):
__tablename__ = "vendor" __tablename__ = "vendor"
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(255), nullable=False, unique=True, index=True) name = Column(String(255), nullable=False, unique=True, index=True)
card_sets = relationship("CardSet") card_sets = relationship("CardSet")
cards = relationship("Card") cards = relationship("Card")
class CardSet(Base): class CardSet(Base, BaseMixin):
__tablename__ = "card_set" __tablename__ = "card_set"
__table_args__ = ( __table_args__ = (
UniqueConstraint("name", "vendor_id"), UniqueConstraint("name", "vendor_id"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
name = Column(String(255), index=True) name = Column(String(255), index=True)
parallel_set = Column(BIT(1)) parallel_set = Column(BIT(1))
insert_set = Column(BIT(1)) insert_set = Column(BIT(1))
@@ -112,15 +85,11 @@ class CardSet(Base):
cards = relationship("Card") cards = relationship("Card")
class Card(Base): class Card(Base, BaseMixin):
__tablename__ = "card" __tablename__ = "card"
__table_args__ = ( __table_args__ = (
UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"),
) )
id = Column(String, primary_key=True)
created_date = Column(DateTime)
last_modified_date = Column(DateTime)
version = Column(Integer)
card_number = Column(Integer, index=True) card_number = Column(Integer, index=True)
year = Column(Integer, index=True) year = Column(Integer, index=True)
card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False)
+18 -2
View File
@@ -1,6 +1,10 @@
from typing import Any
from PySide6.QtGui import QAction, QIcon from PySide6.QtGui import QAction, QIcon
from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView
from PySide6.QtWidgets import QLabel, QMainWindow from PySide6.QtWidgets import QLabel, QMainWindow
from cement.core.config import ConfigHandler
from sqlalchemy import Engine
from ..database import KontorDB from ..database import KontorDB
from ..database.media import MediaFile from ..database.media import MediaFile
@@ -12,7 +16,7 @@ from .table_model import KontorTableModel
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self, session, engine, log): def __init__(self, engine: Engine, config: ConfigHandler, log):
super().__init__() super().__init__()
self.tick = QIcon('kontor/res/tick.png') self.tick = QIcon('kontor/res/tick.png')
@@ -30,7 +34,7 @@ class MainWindow(QMainWindow):
self.data = [] self.data = []
self.filter = {} self.filter = {}
self.kontor_db = KontorDB(session, engine, log) self.kontor_db = KontorDB(engine, config, log)
self.log = log self.log = log
self.central_widget = QWidget() self.central_widget = QWidget()
parent_layout = QVBoxLayout() parent_layout = QVBoxLayout()
@@ -55,7 +59,9 @@ class MainWindow(QMainWindow):
self.refreshAction = QAction(self.circle_icon, "&Refresh", self) self.refreshAction = QAction(self.circle_icon, "&Refresh", self)
self.refreshAction.triggered.connect(self.refresh) self.refreshAction.triggered.connect(self.refresh)
self.updateTitleAction = QAction("&Update Titles", self) self.updateTitleAction = QAction("&Update Titles", self)
self.updateTitleAction.triggered.connect(self.update_title)
self.downloadAction = QAction("&Download Videos", self) self.downloadAction = QAction("&Download Videos", self)
self.downloadAction.triggered.connect(self.download_file)
self.exitAction = QAction("&Beenden", self) self.exitAction = QAction("&Beenden", self)
self.exitAction.setShortcut("Alt+F4") self.exitAction.setShortcut("Alt+F4")
self.exitAction.triggered.connect(self.close) self.exitAction.triggered.connect(self.close)
@@ -118,6 +124,16 @@ class MainWindow(QMainWindow):
else: else:
self.statusBar.showMessage("Export cancelled", 3000) self.statusBar.showMessage("Export cancelled", 3000)
def update_title(self):
self.log.info("update title for table MediaFile")
self.statusBar.showMessage("update title for table MediaFile", 3000)
self.kontor_db.update_title()
def download_file(self):
self.log.info("download videos for table MediaFile")
self.statusBar.showMessage("download videos for table MediaFile", 3000)
self.kontor_db.download_file()
def refresh(self): def refresh(self):
self.data[self.tabs.currentIndex()].refresh() self.data[self.tabs.currentIndex()].refresh()
+4 -8
View File
@@ -10,17 +10,20 @@ from .controllers.clibase import CliBase
from .controllers.database import Database from .controllers.database import Database
# configuration defaults # configuration defaults
CONFIG = init_defaults('kontor', 'mariadb','output.json', 'output.yaml') CONFIG = init_defaults('kontor', 'mariadb', 'media')
CONFIG['kontor']['foo'] = 'bar' CONFIG['kontor']['foo'] = 'bar'
CONFIG['mariadb']['user'] = 'kontor' CONFIG['mariadb']['user'] = 'kontor'
CONFIG['mariadb']['password'] = 'kontor' CONFIG['mariadb']['password'] = 'kontor'
CONFIG['mariadb']['host'] = '127.0.0.1' CONFIG['mariadb']['host'] = '127.0.0.1'
CONFIG['mariadb']['port'] = '3306' CONFIG['mariadb']['port'] = '3306'
CONFIG['mariadb']['database'] = 'kontor' CONFIG['mariadb']['database'] = 'kontor'
CONFIG['media']['ytdlp'] = '/home/tpeetz/bin/yt-dlp'
CONFIG['media']['dir'] = '/data/media'
META = init_defaults('output.json', 'output.yaml') META = init_defaults('output.json', 'output.yaml')
META['output.json']['overridable'] = True META['output.json']['overridable'] = True
META['output.yaml']['overridable'] = True META['output.yaml']['overridable'] = True
def extend_sqlalchemy(app): def extend_sqlalchemy(app):
app.log.info('extending kontor application with sqlalchemy') app.log.info('extending kontor application with sqlalchemy')
connect_string = ('mariadb+mariadbconnector://{}:{}@{}:{}/{}'.format( connect_string = ('mariadb+mariadbconnector://{}:{}@{}:{}/{}'.format(
@@ -34,15 +37,9 @@ def extend_sqlalchemy(app):
engine = create_engine(connect_string) engine = create_engine(connect_string)
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
__session__ = sessionmaker(bind=engine) __session__ = sessionmaker(bind=engine)
app.extend('session', __session__())
app.extend('engine', engine) app.extend('engine', engine)
def close_session(app):
app.log.info('close session')
app.session.close()
class Kontor(App): class Kontor(App):
"""Kontor primary application.""" """Kontor primary application."""
@@ -79,7 +76,6 @@ class Kontor(App):
hooks = [ hooks = [
('post_setup', extend_sqlalchemy), ('post_setup', extend_sqlalchemy),
('pre_close', close_session),
] ]
# register handlers # register handlers
handlers = [ handlers = [
+1
View File
@@ -5,3 +5,4 @@ cement[colorlog]
mariadb mariadb
sqlalchemy sqlalchemy
PySide6 PySide6
beautifulsoup4