diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 33f2c92..527ca36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,6 +120,6 @@ jobs: docker compose down rm docker-compose.yml wget "https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/docker-compose.yml" - docker compose pull + docker compose pull --quiet docker compose up --detach docker network connect nginx_default tubee_beta_app diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eb80f5c..e00766c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,7 @@ +ci: + autoupdate_branch: "develop" + autoupdate_commit_msg: "🗄 chore: pre-commit autoupdate" + repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: "v4.4.0" diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d0970c3 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "bungcip.better-toml", + "ryanluker.vscode-coverage-gutters", + "whatwedo.twig", + "donjayamanne.jquerysnippets", + "cschleiden.vscode-github-actions" + ] +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..58ccf01 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +define USAGE +Tubee, the YouTube subscription dashboard + +Commands: + install Install dependencies for local development + build Build docker images + start Start the application for development + test Run coverage unit tests + shell Enter interactive shell for debug + db_migrate Create a new database migration (Run with make db_migrate MESSAGE="message") + db_upgrade Upgrade the database to the latest migration + uninstall Uninstall environment + reinstall Reinstall environment (when Python version is bumped) + +endef + +export USAGE + +help: + @echo "$$USAGE" + +install: + pyenv install -s $(shell cat .python-version) + poetry env use $(shell echo $(shell pyenv shell $(shell cat .python-version); pyenv which python)) + poetry install + +build: + docker compose --file docker-compose.dev.yml build + +start: + docker compose --file docker-compose.dev.yml up + +test: + poetry run flask test --coverage + +shell: + poetry run flask shell + +db_migrate: + docker compose --file docker-compose.dev.yml exec tubee flask db migrate -m $(MESSAGE) + +db_upgrade: + docker compose --file docker-compose.dev.yml exec tubee flask db upgrade + +uninstall: + poetry env remove --all + +reinstall: uninstall install build diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 015aeb4..a4655c7 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -38,12 +38,6 @@ services: celery: build: . command: - - "watchmedo" - - "auto-restart" - - "--directory=./" - - "--pattern=*.py" - - "--recursive" - - "--" - "celery" - "--app=celery_worker.celery" - "worker" diff --git a/pyproject.toml b/pyproject.toml index a4c30f5..2e3c71d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ name = "tubee" version = "0.15.0" description = "A Web Application for Monitoring New YouTube Videos" license = "MIT License" -authors = ["Tomy Hsieh "] +authors = ["Tomy Hsieh "] readme = "README.md" homepage = "https://github.com/tomy0000000/Tubee" repository = "https://github.com/tomy0000000/Tubee" diff --git a/tubee/models/action.py b/tubee/models/action.py index 0f79895..950cd08 100644 --- a/tubee/models/action.py +++ b/tubee/models/action.py @@ -42,10 +42,14 @@ class Action(db.Model): # type: ignore ), {}, ) - channel = db.relationship("Channel", back_populates="actions") - subscription = db.relationship("Subscription", back_populates="_actions") + channel = db.relationship( + "Channel", back_populates="actions", overlaps="subscription" + ) + subscription = db.relationship( + "Subscription", back_populates="_actions", overlaps="channel" + ) tag = db.relationship("Tag", back_populates="actions") - user = db.relationship("User", back_populates="actions") + user = db.relationship("User", back_populates="actions", overlaps="subscription") def __init__(self, username: str, params: Union[dict[str, str], None] = None): from .subscription import Subscription diff --git a/tubee/models/channel.py b/tubee/models/channel.py index 26eece9..17df75a 100644 --- a/tubee/models/channel.py +++ b/tubee/models/channel.py @@ -36,7 +36,9 @@ class Channel(db.Model): # type: ignore hub_infos = db.Column(db.JSON, nullable=False, default={}) subscribe_timestamp = db.Column(db.DateTime, default=datetime.utcnow) unsubscribe_timestamp = db.Column(db.DateTime) - actions = db.relationship("Action", back_populates="channel") + actions = db.relationship( + "Action", back_populates="channel", overlaps="subscription" + ) videos = db.relationship( "Video", back_populates="channel", lazy="dynamic", cascade="all, delete-orphan" ) diff --git a/tubee/models/subscription.py b/tubee/models/subscription.py index c8654ec..bd86051 100644 --- a/tubee/models/subscription.py +++ b/tubee/models/subscription.py @@ -31,6 +31,7 @@ class Subscription(db.Model): # type: ignore back_populates="subscription", lazy="dynamic", cascade="all, delete-orphan", + overlaps="actions,channel,user", ) _subscription_tags = db.relationship( "SubscriptionTag", diff --git a/tubee/models/user.py b/tubee/models/user.py index b55fa1b..32ffbd9 100644 --- a/tubee/models/user.py +++ b/tubee/models/user.py @@ -60,7 +60,12 @@ class User(UserMixin, db.Model): # type: ignore tags = db.relationship( "Tag", back_populates="user", lazy="dynamic", cascade="all, delete-orphan" ) - actions = db.relationship("Action", back_populates="user", lazy="dynamic") + actions = db.relationship( + "Action", + back_populates="user", + lazy="dynamic", + overlaps="_actions,subscription", + ) def __init__(self, username, password, admin=False, **kwargs): self.username = username