-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Video downloads have many more options. Downloads are migrated.
Storing video settings in session storage to help user start downloads consistently. Applying channel tag name to new channels when download videos or channels. Initializing map tiles when importing and resetting map.
- Loading branch information
1 parent
a385d4f
commit 389167e
Showing
70 changed files
with
5,310 additions
and
1,544 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
"""Create Download.destination column. | ||
Revision ID: 170d1be52bc7 | ||
Revises: 9ec4c765ef8d | ||
Create Date: 2024-11-02 11:16:15.297850 | ||
""" | ||
import os | ||
|
||
from alembic import op | ||
from sqlalchemy.orm import Session | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = '170d1be52bc7' | ||
down_revision = '9ec4c765ef8d' | ||
branch_labels = None | ||
depends_on = None | ||
|
||
DOCKERIZED = True if os.environ.get('DOCKER', '').lower().startswith('t') else False | ||
|
||
|
||
def upgrade(): | ||
bind = op.get_bind() | ||
session = Session(bind=bind) | ||
|
||
session.execute('ALTER TABLE download ADD COLUMN IF NOT EXISTS destination TEXT') | ||
session.execute('ALTER TABLE download ADD COLUMN IF NOT EXISTS tag_names TEXT[]') | ||
|
||
|
||
def downgrade(): | ||
bind = op.get_bind() | ||
session = Session(bind=bind) | ||
|
||
session.execute('ALTER TABLE download DROP COLUMN IF EXISTS tag_names') | ||
session.execute('ALTER TABLE download DROP COLUMN IF EXISTS destination') |
137 changes: 137 additions & 0 deletions
137
alembic/versions/1f2325523525_download_destination_migrate.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
"""Create `Download.destination` and `Download.tag_names`, migrate from `Download.settings`. | ||
Revision ID: 1f2325523525 | ||
Revises: 170d1be52bc7 | ||
Create Date: 2024-11-02 11:20:45.028865 | ||
""" | ||
import os | ||
from copy import copy | ||
|
||
from alembic import op | ||
from sqlalchemy import Column, Integer, Text, String, ARRAY | ||
from sqlalchemy.dialects.postgresql import JSONB | ||
from sqlalchemy.ext.declarative import declarative_base | ||
from sqlalchemy.orm import Session | ||
|
||
from wrolpi.common import ModelHelper | ||
from wrolpi.dates import TZDateTime | ||
from wrolpi.downloader import get_download_manager_config, DownloadStatus | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = '1f2325523525' | ||
down_revision = '170d1be52bc7' | ||
branch_labels = None | ||
depends_on = None | ||
|
||
DOCKERIZED = True if os.environ.get('DOCKER', '').lower().startswith('t') else False | ||
|
||
Base = declarative_base() | ||
|
||
|
||
class MDownload(ModelHelper, Base): | ||
__tablename__ = 'download' | ||
id = Column(Integer, primary_key=True) | ||
url = Column(String, nullable=False, unique=True) | ||
attempts = Column(Integer, default=0) | ||
destination = Column(Text) | ||
downloader = Column(Text) | ||
sub_downloader = Column(Text) | ||
error = Column(Text) | ||
frequency = Column(Integer) | ||
info_json = Column(JSONB) | ||
last_successful_download = Column(TZDateTime) | ||
location = Column(Text) | ||
next_download = Column(TZDateTime) | ||
settings = Column(JSONB) | ||
status = Column(String, default=DownloadStatus.new) | ||
tag_names = Column(ARRAY(Text)) | ||
|
||
|
||
def upgrade(): | ||
bind = op.get_bind() | ||
session = Session(bind=bind) | ||
|
||
for download in session.query(MDownload): | ||
if not download.settings: | ||
continue | ||
# Move `download.settings['destination']` to `download.destination`, if any. | ||
settings = copy(download.settings) if download.settings else dict() | ||
destination = settings.pop('destination', None) | ||
tag_names = settings.pop('tag_names', None) | ||
if isinstance(excluded_urls := settings.get('excluded_urls'), list): | ||
settings['excluded_urls'] = ','.join(excluded_urls) | ||
download.destination = destination or None | ||
download.tag_names = tag_names or None | ||
download.settings = settings | ||
|
||
# This will migrate the config as-is at the time that this migration was written. This code is probably not | ||
# safe to reuse in the future! | ||
|
||
# Read config file directly. | ||
try: | ||
config = get_download_manager_config() | ||
config._config.update(config.read_config_file()) | ||
except FileNotFoundError: | ||
# Config does not exist, probably testing, or a new WROLPi. | ||
return | ||
|
||
new_downloads = [] | ||
for download in session.query(MDownload).order_by(MDownload.url): | ||
if download.last_successful_download and not download.frequency: | ||
# This once-download has completed, do not save it. | ||
continue | ||
new_download = dict( | ||
destination=download.destination, | ||
downloader=download.downloader, | ||
frequency=download.frequency, | ||
last_successful_download=download.last_successful_download, | ||
next_download=download.next_download, | ||
settings=download.settings, | ||
status=download.status, | ||
sub_downloader=download.sub_downloader, | ||
url=download.url, | ||
) | ||
new_downloads.append(new_download) | ||
|
||
# Write directly to file, bypassing usual checks. | ||
config._config['downloads'] = new_downloads | ||
config.write_config_data(config._config, config.get_file()) | ||
|
||
|
||
def downgrade(): | ||
bind = op.get_bind() | ||
session = Session(bind=bind) | ||
|
||
for download in session.query(MDownload): | ||
if download.destination: | ||
settings = copy(download.settings) if download.settings else dict() | ||
settings['destination'] = download.destination or settings.get('destination') | ||
settings['tag_names'] = download.tag_names or settings.get('tag_names') | ||
if isinstance(excluded_urls := settings.get('excluded_urls'), str): | ||
settings['excluded_urls'] = excluded_urls.split(',') | ||
download.settings = settings | ||
|
||
try: | ||
config = get_download_manager_config() | ||
config._config.update(config.read_config_file()) | ||
except FileNotFoundError: | ||
# Config does not exist, probably testing, or a new WROLPi. | ||
return | ||
|
||
new_downloads = [] | ||
for download in session.query(MDownload).order_by(MDownload.url): | ||
new_download = dict( | ||
downloader=download.downloader, | ||
frequency=download.frequency, | ||
last_successful_download=download.last_successful_download, | ||
next_download=download.next_download, | ||
settings=download.settings, | ||
status=download.status, | ||
sub_downloader=download.sub_downloader, | ||
url=download.url, | ||
) | ||
new_downloads.append(new_download) | ||
|
||
config._config['downloads'] = new_downloads | ||
config.write_config_data(config._config, config.get_file()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const { defineConfig } = require("cypress"); | ||
|
||
module.exports = defineConfig({ | ||
component: { | ||
devServer: { | ||
framework: "create-react-app", | ||
bundler: "webpack", | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"name": "Using fixtures to represent data", | ||
"email": "hello@cypress.io", | ||
"body": "Fixtures are a great way to mock data for responses to routes" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// *********************************************** | ||
// This example commands.js shows you how to | ||
// create various custom commands and overwrite | ||
// existing commands. | ||
// | ||
// For more comprehensive examples of custom | ||
// commands please read more here: | ||
// https://on.cypress.io/custom-commands | ||
// *********************************************** | ||
// | ||
// | ||
// -- This is a parent command -- | ||
// Cypress.Commands.add('login', (email, password) => { ... }) | ||
// | ||
// | ||
// -- This is a child command -- | ||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This is a dual command -- | ||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This will overwrite an existing command -- | ||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||
<title>Components App</title> | ||
</head> | ||
<body> | ||
<div data-cy-root></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// *********************************************************** | ||
// This example support/component.js is processed and | ||
// loaded automatically before your test files. | ||
// | ||
// This is a great place to put global configuration and | ||
// behavior that modifies Cypress. | ||
// | ||
// You can change the location of this file or turn off | ||
// automatically serving support files with the | ||
// 'supportFile' configuration option. | ||
// | ||
// You can read more here: | ||
// https://on.cypress.io/configuration | ||
// *********************************************************** | ||
|
||
// Import commands.js using ES2015 syntax: | ||
import './commands' | ||
|
||
// Alternatively you can use CommonJS syntax: | ||
// require('./commands') | ||
|
||
import { mount } from 'cypress/react18' | ||
|
||
Cypress.Commands.add('mount', mount) | ||
|
||
// Example use: | ||
// cy.mount(<MyComponent />) |
Oops, something went wrong.