diff --git a/.vscode/launch.json b/.vscode/launch.json index f3e42404..8838fbb3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "TagStudio", "type": "python", "request": "launch", - "program": "${workspaceRoot}/tagstudio/tagstudio.py", + "program": "${workspaceRoot}/tagstudio/tag_studio.py", "console": "integratedTerminal", "justMyCode": true, "args": [] diff --git a/README.md b/README.md index 3563733f..dd78737e 100644 --- a/README.md +++ b/README.md @@ -90,14 +90,14 @@ _Learn more about setting up a virtual environment [here](https://docs.python.or To launch TagStudio, launch the `start_win.bat` file. You can modify this .bat file or create a shortcut and add one or more additional arguments if desired. -Alternatively, with the virtual environment loaded, run the python file at `tagstudio\tagstudio.py` from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tagstudio.py`. +Alternatively, with the virtual environment loaded, run the python file at `tagstudio\tag_studio.py` from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tag_studio.py`. > [!CAUTION] > TagStudio on Linux & macOS likely won't function correctly at this time. If you're trying to run this in order to help test, debug, and improve compatibility, then charge on ahead! #### macOS -With the virtual environment loaded, run the python file at "tagstudio/tagstudio.py" from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tagstudio.py`. When launching the program in the future, remember to activate the virtual environment each time before launching *(an easier method is currently being worked on).* +With the virtual environment loaded, run the python file at "tagstudio/tag_studio.py" from your terminal. If you're in the project's root directory, simply run `python3 tagstudio/tag_studio.py`. When launching the program in the future, remember to activate the virtual environment each time before launching *(an easier method is currently being worked on).* #### Linux diff --git a/TagStudio.sh b/TagStudio.sh index cff969c3..762f752f 100755 --- a/TagStudio.sh +++ b/TagStudio.sh @@ -2,4 +2,4 @@ python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt -python tagstudio/tagstudio.py +python tagstudio/tag_studio.py diff --git a/start_win.bat b/start_win.bat index 51a5ddf8..73dcfb0f 100644 --- a/start_win.bat +++ b/start_win.bat @@ -1,2 +1,2 @@ @echo off -.venv\Scripts\python.exe .\TagStudio\tagstudio.py --ui qt %* \ No newline at end of file +.venv\Scripts\python.exe .\TagStudio\tag_studio.py --ui qt %* \ No newline at end of file diff --git a/tagstudio/src/core/library.py b/tagstudio/src/core/library.py index ac35ec7f..97f2e871 100644 --- a/tagstudio/src/core/library.py +++ b/tagstudio/src/core/library.py @@ -5,24 +5,22 @@ """The Library object and related methods for TagStudio.""" import datetime -from enum import Enum -import os -import traceback -from typing import Optional -import json import glob -from pathlib import Path -# from typing_extensions import deprecated -import src.core.ts_core as ts_core -from src.core.utils.web import * -from src.core.utils.str import * -from src.core.utils.fs import * -import xml.etree.ElementTree as ET +import json +import logging +import os import sys import time -import logging +import traceback +import xml.etree.ElementTree as ET +from enum import Enum + import ujson +from src.core import ts_core +from src.core.utils.str import strip_punctuation +from src.core.utils.web import strip_web_protocol + TYPE = ['file', 'meta', 'alt', 'mask'] # RESULT_TYPE = Enum('Result', ['ENTRY', 'COLLATION', 'TAG_GROUP']) class ItemType(Enum): diff --git a/tagstudio/src/core/ts_core.py b/tagstudio/src/core/ts_core.py index 1ef7f028..5f50954d 100644 --- a/tagstudio/src/core/ts_core.py +++ b/tagstudio/src/core/ts_core.py @@ -4,16 +4,10 @@ """The core classes and methods of TagStudio.""" -import os -from types import FunctionType -# from typing import Dict, Optional, TypedDict, List import json -from pathlib import Path -import traceback -# import requests -# from bs4 import BeautifulSoup as bs -from src.core.library import * -from src.core.field_template import FieldTemplate +import os + +from src.core.library import Entry, Library VERSION: str = '9.1.0' # Major.Minor.Patch VERSION_BRANCH: str = 'Alpha' # 'Alpha', 'Beta', or '' for Full Release diff --git a/tagstudio/src/core/utils/fs.py b/tagstudio/src/core/utils/fs.py index 1307b0e8..7c1052a6 100644 --- a/tagstudio/src/core/utils/fs.py +++ b/tagstudio/src/core/utils/fs.py @@ -2,9 +2,6 @@ # Licensed under the GPL-3.0 License. # Created for TagStudio: https://github.com/CyanVoxel/TagStudio -import os - - def clean_folder_name(folder_name: str) -> str: cleaned_name = folder_name invalid_chars = "<>:\"/\\|?*." diff --git a/tagstudio/src/qt/flowlayout.py b/tagstudio/src/qt/flowlayout.py index 1e3c5075..b71c962d 100644 --- a/tagstudio/src/qt/flowlayout.py +++ b/tagstudio/src/qt/flowlayout.py @@ -4,9 +4,8 @@ """PySide6 port of the widgets/layouts/flowlayout example from Qt v6.x""" -import sys from PySide6.QtCore import Qt, QMargins, QPoint, QRect, QSize -from PySide6.QtWidgets import QApplication, QLayout, QPushButton, QSizePolicy, QWidget +from PySide6.QtWidgets import QLayout, QSizePolicy, QWidget # class Window(QWidget): diff --git a/tagstudio/src/qt/main_window.py b/tagstudio/src/qt/main_window.py index 38c1c099..8055d930 100644 --- a/tagstudio/src/qt/main_window.py +++ b/tagstudio/src/qt/main_window.py @@ -12,23 +12,14 @@ # Licensed under the GPL-3.0 License. # Created for TagStudio: https://github.com/CyanVoxel/TagStudio -from re import S -import time -from typing import Optional -from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, - QMetaObject, QObject, QPoint, QRect, - QSize, QTime, QUrl, Qt) -from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, - QFont, QFontDatabase, QGradient, QIcon, - QImage, QKeySequence, QLinearGradient, QPainter, - QPalette, QPixmap, QRadialGradient, QTransform, QAction) -from PySide6.QtWidgets import (QApplication, QComboBox, QFrame, QGridLayout, +from PySide6.QtCore import (QCoreApplication, QMetaObject, QRect, + QSize, Qt) +from PySide6.QtGui import (QFont, QAction) +from PySide6.QtWidgets import (QComboBox, QFrame, QGridLayout, QHBoxLayout, QVBoxLayout, QLayout, QLineEdit, QMainWindow, QMenuBar, QPushButton, QScrollArea, QSizePolicy, QStatusBar, QWidget, QSplitter, QMenu) from src.qt.pagination import Pagination -# from src.qt.qtacrylic.qtacrylic import WindowEffect -# from qframelesswindow import FramelessMainWindow, StandardTitleBar class Ui_MainWindow(QMainWindow): diff --git a/tagstudio/src/qt/pagination.py b/tagstudio/src/qt/pagination.py index 642cd103..074bf869 100644 --- a/tagstudio/src/qt/pagination.py +++ b/tagstudio/src/qt/pagination.py @@ -5,10 +5,10 @@ """A pagination widget created for TagStudio.""" # I never want to see this code again. -from PySide6 import QtCore -from PySide6.QtGui import * -from PySide6.QtWidgets import * -from PySide6.QtCore import QFile, QObject, QThread, Signal, QRunnable, Qt, QThreadPool, QSize, QEvent, QMimeData +from PySide6.QtCore import QObject, Signal, QSize +from PySide6.QtGui import QIntValidator +from PySide6.QtWidgets import QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit, QSizePolicy + # class NumberEdit(QLineEdit): # def __init__(self, parent=None) -> None: diff --git a/tagstudio/src/qt/ts_qt.py b/tagstudio/src/qt/ts_qt.py index 253f9d20..d9bbccc1 100644 --- a/tagstudio/src/qt/ts_qt.py +++ b/tagstudio/src/qt/ts_qt.py @@ -7,42 +7,46 @@ """A Qt driver for TagStudio.""" -from copy import copy, deepcopy import ctypes -import math -from os import times -import sys import logging -import threading -from time import sleep -from queue import Empty, Queue +import math +import os +import sys import time -from typing import Optional, Union -from PySide6 import QtCore -import PySide6 -from PySide6.QtGui import * -from PySide6.QtWidgets import * -from PySide6.QtCore import QFile, QObject, QThread, Signal, QRunnable, Qt, QThreadPool, QSize, QEvent, QMimeData, QTimer -from PySide6.QtUiTools import QUiLoader -from PIL import Image, ImageOps, ImageChops, UnidentifiedImageError, ImageQt, ImageDraw, ImageFont, ImageEnhance -import PySide6.QtWidgets -import humanfriendly -import pillow_avif -import cv2 +import traceback +import shutil +import subprocess +from types import FunctionType from datetime import datetime as dt -from src.core.ts_core import * -# from src.core.utils.web import * -# from src.core.utils.fs import * -from src.core.library import * +from pathlib import Path +from queue import Empty, Queue +from time import sleep +from typing import Optional + +import cv2 +from PIL import Image, ImageChops, UnidentifiedImageError, ImageQt, ImageDraw, ImageFont, ImageEnhance +from PySide6 import QtCore +from PySide6.QtCore import QObject, QThread, Signal, QRunnable, Qt, QThreadPool, QSize, QEvent, QTimer +from PySide6.QtGui import (QGuiApplication, QPixmap, QEnterEvent, QMouseEvent, QResizeEvent, QPainter, QColor, QPen, + QAction, QStandardItemModel, QStandardItem, QPainterPath, QFontDatabase, QIcon) +from PySide6.QtUiTools import QUiLoader +from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QPlainTextEdit, + QLineEdit, QScrollArea, QFrame, QTextEdit, QComboBox, QProgressDialog, QFileDialog, + QListView, QSplitter, QSizePolicy, QMessageBox, QBoxLayout, QCheckBox, QSplashScreen, + QMenu) +from humanfriendly import format_timespan, format_size + +from src.core.library import Collation, Entry, ItemType, Library, Tag from src.core.palette import ColorType, get_tag_color +from src.core.ts_core import (TagStudioCore, TAG_COLORS, DATE_FIELDS, TEXT_FIELDS, BOX_FIELDS, ALL_FILE_TYPES, + SHORTCUT_TYPES, PROGRAM_TYPES, ARCHIVE_TYPES, PRESENTATION_TYPES, + SPREADSHEET_TYPES, TEXT_TYPES, AUDIO_TYPES, VIDEO_TYPES, IMAGE_TYPES, + LIBRARY_FILENAME, COLLAGE_FOLDER_NAME, BACKUP_FOLDER_NAME, TS_FOLDER_NAME, + VERSION_BRANCH, VERSION) +from src.core.utils.web import strip_web_protocol from src.qt.flowlayout import FlowLayout, FlowWidget from src.qt.main_window import Ui_MainWindow import src.qt.resources_rc -# from typing_extensions import deprecated -from humanfriendly import format_timespan -# from src.qt.qtacrylic.qtacrylic import WindowEffect -import shutil -import subprocess # SIGQUIT is not defined on Windows if sys.platform == "win32": @@ -2126,12 +2130,12 @@ class PreviewPanel(QWidget): # Stats for specific file types are displayed here. if extension in (IMAGE_TYPES + VIDEO_TYPES): - self.dimensions_label.setText(f"{extension.upper()} • {humanfriendly.format_size(os.stat(filepath).st_size)}\n{image.width} x {image.height} px") + self.dimensions_label.setText(f"{extension.upper()} • {format_size(os.stat(filepath).st_size)}\n{image.width} x {image.height} px") else: self.dimensions_label.setText(f"{extension.upper()}") if not image: - self.dimensions_label.setText(f"{extension.upper()} • {humanfriendly.format_size(os.stat(filepath).st_size)}") + self.dimensions_label.setText(f"{extension.upper()} • {format_size(os.stat(filepath).st_size)}") raise UnidentifiedImageError except (UnidentifiedImageError, FileNotFoundError, cv2.error): @@ -4525,7 +4529,7 @@ class QtDriver(QObject): self.completed += 1 # logging.info(f'threshold:{len(self.lib.entries}, completed:{self.completed}') if self.completed == len(self.lib.entries): - filename = os.path.normpath(f'{self.lib.library_dir}/{TS_FOLDER_NAME}/{COLLAGE_FOLDER_NAME}/collage_{datetime.datetime.utcnow().strftime("%F_%T").replace(":", "")}.png') + filename = os.path.normpath(f'{self.lib.library_dir}/{TS_FOLDER_NAME}/{COLLAGE_FOLDER_NAME}/collage_{dt.utcnow().strftime("%F_%T").replace(":", "")}.png') self.collage.save(filename) self.collage = None diff --git a/tagstudio/tagstudio.py b/tagstudio/tag_studio.py similarity index 99% rename from tagstudio/tagstudio.py rename to tagstudio/tag_studio.py index 50f48d6d..54039eb7 100644 --- a/tagstudio/tagstudio.py +++ b/tagstudio/tag_studio.py @@ -9,7 +9,6 @@ from src.cli.ts_cli import CliDriver from src.qt.ts_qt import QtDriver import argparse import traceback -# import ctypes def main():