Skip to content

Commit 12c2008

Browse files
pSpitznersemohr
andauthored
RC1-v1.0.0 (#61)
* Started to create functions to send status updates to the client. Not sure why it is not working in redis workers but it works via a notebook... Still a bit of debugging needed, maybe switching to a non async socket client works? * Fixed data encoding issue with websockets status update. * Status updates mostly integrated, might need a bit of cleanup for the old code but should work now. * Updated docstring of run_preview and removed delete_tags function. * Serialize enums by value instead of by name as it is easier to work with values in ts, even tho it is less readable it improves ux if the types are generated by py2ts. Also added a new FolderStatusIcon component. see /jobs route for example. * with_folder decorator a bit more generic. Also added a very simple by_folder endpoint for sessions. * Show folder status instead of match chip. Might need a bit more refinement also added a subpage to view the current session. (Just shows the candidates at the moment). * Merged library_routes_refactor * Created a chip that shows the status of the tag and the best match. * Added cur beets album and artist to db serialization this is the current data from the file metadata... We should remove this in near future. Added duplicate ids to task serialization. * Started to migrate importer candidate view. To new format. * Fixed import order and started a new candidate component to merge some of the old design decisions with the new inbox/library design. Still needs alot of work. * (WIP) Migration and Fixes with @semohr: - Eslint disable unused variables - Theming: custom colors and icon sizes - Migrating Candidate Preview from CSS to MUI Theming - Theming of inbox view for mobile * A bit of styling for the accordion setup. Also added an expand and collapse all button. * by_folder endpoint was not returning the most recent session * Continued with candidate refactor, candidate diff now takes a from and to candidate. Also cleaned up diff components in general. * A bit of styling updates in the design subpage. Replaced hardcoded colors with dynamic ones. And added icons for selection. * Added metadata to serialized session, removed duplicate items from serialized session. Adapted frontend to use this new syntax. Added a new first proposal for the major minor change layout. With @pSpitzner * A bit of cleanup: - removed old tailwind css @... removes warning - cleanup trackdiff and added a context to precompute changes - added placeholder components for unmatched tracks and extra items TODOS: compute extra items and tracks, migrate old view * UseDiff hook * style tweaks with @semohr - more consistent trackdiff view - candidate view with working unmatched tracks and item lists - list of (candidate) duplicate ids send to frontend * More styling: - Removed old named columns as they are not really used - Added mobile layout for fullwidth grid as this overflow on small devices - Changes are wrapped across two rows * Added a counter to track changes, unmatched items and unmatched tracks and added line through visual for generic diffs * Fixed a small bug with beets plugins not beeing loaded. No idea why this happens seems like it is an artifact of our new config setup. Not sure at all tho. Loading the plugins manually seems to fix this. * Also removed some log.warnings and updated ruff * Refactored my old state_seralize.ipynb notebook and included it in the documentation. Added contribution guide, and refactored dev documentation slightly. * Added an endpoint to load candidate artworks. Atm working are spotify and musicbrainz. Needs a decision for asis... A bit of refactoring in frontend too, diffs needs yet some more work. * Asis candidates now set data_url as file uri pointing to the folder. I.e. file:///album/folder Added an art preview handler for file:: uris. Added skeleton for image loading. * Generalized inline diffs. I'm quite happy with the overview now, the track/item diff alignment still needs a bit of work tho. Especially the diff.tsx fill needs a bit of cleanup. * Bigger backend cleanup. Removed old tag, tag_group routes. Refactored db_models to use a class base approach, should be easier to extend in the future. Removed old inbox folder. Will break the frontend, needs fixing! * a bit of cleanup * Fixed tests. * Tidying and fixing with @semohr - removed a bunch of old files - fixed venn diagram for candidates (unmatched tracks) - fixed and moved inbox and library stats (homescreen) - tidied up candidate filestructure in frontend - speed dial now uses mutations * Small style tweaks in inbox, clickable rows * Fixed accordion rerender performance issue. Needed some memoization. * Fixed an issue with clickable rows. Needed to add stopPropagate otherwise the row will not be selected properly. E.g. checkbox clicks will trigger the toggleSelected twice. Added a generalized handling for the moreactions menu. Can be triggered on context menu click or long press on mobile. Needs some more content and actions but I like the feel of it now. * Started to migrate import selection from interactive import. Needs some work but all main components do exist now. * A bit more refinement of layout. Very similar to old layout. * Fixed some minor mypy issues. * Added proposal for search candidates session. * fixes and import id into db: - fixed duplicate chip - fixed import not going through - found out how to set our gui import id, using hash and datetime. * fixes around chips and session lookup from db via folder path _and/or_ hash * Added a folderhashmismatch chip. Also fixed a small issue with reconstructing folders from the database was recomputing the hash. * Readded fast refresh plugin. Was somehow lost in migration to eslint 9 * Created an "api" folder in the frontend, all query options should be placed here. I think using a similar structure as in the backend should be preferred. Might need some more additions only migrated inbox and session. * Added tooltip to duplicate and integrity chip. * Added a styled dialogs component which we should use instead of the plain mui one. * Removed old unused files. Renamed tags folder to tags_old just for future reference. This is kinda a high pressure cleaning approach, but we really have too much historic frontend code. Might need more cleaning but should make things easier going forwards. * Library now uses "@/api" * Moved search to generic dialog. * Implemented AddCandidateSession and removed old notebook. See state_serialize notebook for an example. * removed unused kind argument in invoker job functions. * Added add_candidate route and mutation for frontend. Search modal should already work. In theory we could make this a bit better if we return the new candidates from the endpoint. This we we could omit refetching the session data, but should be fine for now. Also replace all :nth-child with :nth-of-type to prevent react warnings. * Fixed terminal * visual tweaks, added action placeholders * Extended the inbox info modal with some more information. The actions still need a description, otherwise it should be pretty complete :) * Fixed a small visual bug with chips on mobile and generalized pagewrapper. Generalized pagewrapper allows to fill the full screen on mobile while constraining the layout to max desktop size. * Added a frontpage hero showing logo and small title. * Added a footer for the frontpage with some links to github and the documentation. Looks good on desktop imo but needs some work on mobile as the navbar wraps to the bottom and this makes it look strange. Maybe the navbar in general needs a bit of a change. * Removed fixed height in favor of minheight as otherwise the scroll would not work as expected. * Started with a proposal for a new frontpage stats card. Am more happy with the current look for library stats, but need a bit of work: A bit of cleanup and generalization for use with inbox stats. Others: - Removed old frontpage modals, not used anymore. - Size of library wasn't computed correctly in stats route * Generalized stats cards and added card(s) for inbox. Other: - Added a function to get num files in folder - Changed secondary color to complementary, might need a bit of discussion - Readded muted colors * implemented action for terminal import, and fixes for terminal backend-frontend sync (backspacing was still wonky) * POC: Terminal can now scroll up a bit. We should figure out how to load this "history" only once we scroll :) * Added a proposal for testing session flows. I really think we should implement them before continuing with the frontend as all these cases have to be handled properly in the backend before we can confidently respond/visualize them in the frontend. * Fixed old reset_db function not working properly. Now fully dynamic :) * Refactor invoker and some minor changes to other things (wip) * small fixes: progress comparison for session retry, reset of candidate search from, duplicate action "ask" now raises an error. * Mocking setup for redis in tests. * Added a simple setup for flow tests, will prop. need some more work. * added a bunch of tests with @semohr, and - fixed duplicate detection in import session - improved and refactored folder states (todo: frontend) - removed pickled response of mocked api reply from music brains, it contains absolute folder paths :/ - main todo: finish tests. * Added error handling to redis jobs: We follow an exceptions as values approach for job error handling now. This commit adds an decorator which wraps any job function and allows to returns any raised exception as a value. These are than stored in the redis store. In our session status endpoint we now additionally check a jobs results and if it is of exception type we set the status as failed. Remark: Using the rq failed job queue does not work for this as they do not serialize the raised exceptions properly only the traceback as str. No idea why they think this is a proper way on how to handle exceptions... * Unified logging in invoker. * Persisting exceptions and failed jobs on container restart i.e. when redis cache is cleared. Added optional exception attributes to session and session state which are populated when a session is run and throws an exception. * Improved exception handling, is now a bit more streamlined: Introduced an generic api error from which integrity, notfound and invalidusage extend. This allows for more general error handling, i.e. less code for handling :D We now have a serialized exceptions typeddict which is used to transfer generic exceptions from backend to frontend. SerializedSessionState now includes the exception from its state, should allow us to create a nice error page for common problems with the session! * Added new serialized exception to frontend. * Updated frontend packages. * Added a prototype for session exception handling in frontend. Needs to be enhanced, mainly styling work, flow should be pretty set in stone now. * some fixes for folder status and regeneration * Added a persistent beets lib mixin. Allows for an easier duplicate import check. * Enhanced support for multiple inboxes, added inbox name and current autotag preview into a inbox header. Moved number of selected folder to the bottom left. * Small adjustment to styling * Restructured pytest folder a bit: - mixins: Contains all mixin classes - integration: Contains all integration tests, i.e. flow and routes We might want to add a unit tests folder at some point. * Added placeholder for test todos. * Created unit test folder with all unit tests. * Added todo test for revert import. * Added test for all duplicate actions. Is relative simple for, run import which should not error :) * Readded/revamped a delete endpoint which allows to delete folders. Also added test for the endpoint. * Added a mutation option to delete an folder, i.e. corresponding to the python endpoint (see prev. commit). Also added a optimistic updates function for the inbox such that items are automatically removed. Should make the process more responsive for the user. * reworked folder status logic in db_models/session.py * fix and test for progress comparison, fix for stage skipping * wip: undo / deletion of past import sessions * Fixed undo and reimport: After items have been imported they get a new path and can thus not be found anymore as they are deleted already. To fix this we need to use the old paths, interestingly beets already has an old_paths property which I now just moved into our state. * Reenabled duplicate action tests. * Renamed previewed to tagged in the status chip. * Added optimistic updates to enqueue mutation. Now the pending status chip is show as soon as a user triggers the mutation. * moved more of the undo mechanic into the undo session. for that, added the currently chosen candidate to the database (taskstate) * Retag now generates a new session and does not fail anymore: - We now have a revision system to uniquely define the newest session for a folder hash - Added tests for regenerate preview * Added deleteAction to SpeedDial. Needed some minor fixes in backend for cache invalidation. * Exceptions are often not serialized properly thus replaced normal exceptions as return with serializedExc as return values. * Replaced exception response with more general SerializedException in folder status endpoint. Was basically duplicate code. * Revamped frontend error component. * Started with a small refactor of the /inbox/session/$id subpage. * Fixed progress tests which we broke by giving progress other values. * Some frontend experiments: - Added duplicate action logic for candidate selector. - Added a experimental stepper to show the current session progress. - Am not too sure about this, seems too much if you ask me and a bit unnecessary - Added Card with session information, am pretty happy with this one * Moved searchbar to top of the page next to the expand and collapse all buttons. Added a header for the candidate select card. * Fixed performance issue with checkboxes. * Fixed a small bug, with yet more exc serialization. * The import button in the candidate selector is now bound to the mutation. Also a bit of cleanup. * Duplicate chip is not shown anymore if session is imported. * WIP of enqueue mutation with @semohr. Status: - adding candidates works, both with success and timeout - (timoeut still needs frontend handling). - types are still a bit inconsistent - we need to adapt this to the general enqueue - and send failures + exceptions. Changes: - better mutation <-> enqueue logic. the initial fetch now returns quickly, to avoid blocking and job updates are delivered via websocket, and handled in the mutationFn. - use rq callback to notify frontend about job status change via websocket - new types around JobMeta and parsing to enqueue functions - added job_id to JobMeta for convenience - left a bunch of comments for you, sorry for the mess :P * tweaks to search dialog fixed timeout is now secondary colored, and wrapped in a form, which enables enter to start search. * unified a bit: folder and job status updates via websocket. * Further unified websocket status updates. Currently BREAKING py2ts, had to disable it. Would be easy fix if we move the FolderStatusUpdate and JobStatusUpdate elsewhere, but I like them here. * A bit of cleanup: - modularized invoker a bit to fix circular error, now in folder. File got quite big too - Removed some unused imports - rerun generate type * Added a basestate as timestamps where missing in serialized states. * Added a overview for the selected candidate. A bit hacky but should work for now. * Refactored pop_extra_meta slightly. Needs to handle arrays, same as folder hashes to allow same functions in enqueue as for add_candidate. * Fixed a bug with encoding dataclasses with socketio which was introduced in a refactor some commits before this. * Job status updates are not properly emitted for each enqueued job. - Added a function to enqueue a job in redis which automatically does the status update callback setup. - Fixed some typing issues in the frontend. * Added a common back button that allows us to go back one page. * Cleanup: - Moved loading component with feedback into loading.tsx - Allow to prefix a promise with void to prevent eslint errors - Fixed small issue with invalidation * Refactor and cleanup of the session/$id route: - cleanup folder card component and move to own file - added endpoint to get a folder to make things a bit easier - added integrity warning if hashes do not match - added ability to retag the folder if it has no session affiliated - added statuscode to apierror (not needed yet but was missing) * Fixed issues with status updates not beeing a dict anymore. This resulted in the tests not running because of key errors. Also added the ability to chose a candidate per task (needs a bit more testing) (todo). * Added tests for multi task session. - Needed to adjust lookup to use item hashs otherwise the wrong candidates are used for multi task mocks * Fixed the long standing typing issue with user_query and group_albums * Duplicate action is now bound to a task instead of a a session, similar to the candidate id. * Added a tagCard which shows the user selection for an active session (wip) - allows to import multi tasks session - very similar to previous structur - renamed candidate to candidate selector and move some state out of the candidate.tsx file The frontend is still in a pretty broken state, I think maybe next time it should be usable again. * Add candidate with search should now also support multiple searches, one per task. Very similar to the import candidate_id and duplicate action logic (might need some testing). * Added a helper to get a task state or raise, removes alot of duplicate code. * Added a test for single task session candidate search. * Integrated new candidate search into frontend: - updated packages - added tanstack devtools for queries debugging - changed frontend to accept task_id or session_id instead of hash as this makes a bit more sense from the frontend perspective - strongly typed enqueue mutations * Readded the last missing card (imported) to standard import flow with user selection. Everything should be working again now. I mostly like how it feels now, but some minor fixes might still be necessary. Routing is now done via /folder/$path/$hash instead of /session/$hash, allows us to be a bit more flexible. * A bit of tidy up in tagCard, errors are now raised if they occur in the session (still needs handling in the frontend). Replaced session import id with task id. Added endpoint to get beets album by id from import. Fixed precommit extension not found by pre-commit... (I think this never worked) * fixed missing attributes for task state * using uv to cache python dependecies install, makes building for redis workers faster (docker compose up --build --force-recreate) * Fixed delete for multitasks. Also added an enqueue function to delete items, not used yet but might be important in the future. * duplicate warning in the tagCard instead of throwing the general error interface * copy path action added * Added JSON representation of import item in beets to importedcard. Also fixed an issue where I delete some still used code for artist lookup in a previous commit. * Chosen duplicate action is not added to task_state after import, allows to show it in frontend. Also some minor adjustments to importedCard * fixed undone action, chip, and tests * - added time formatting helper - add manual id for cli import to make (manual) cli-undos possible * fixed library not loading recently added items automatically in various places, removed router.useLoaderData with suspense queries to fix invalidation * progress on import asis and autotag (new flags to preview session, better handling in import session) moved asis candidate out of list of candidates of the task, now is a separate property. frontend needs to be udpated for this. removed import_asis stage, logic moved into choose_match. * (double) clicking anywhere on a candidate now (expands) selects it * fixed auto-import, added tests. i used an exception to propagate to the user if we are worse than threshold. normal import now also falls back to auto-import when no previews were generated before. * Better abstraction for multi-task arguments to sessions. * cleanup, removed old files * tweaked color scheme * Added some comments to hooks Changed diff computation from useeffect to usememo (better performance) * Added a small proposal for subactions in speeddial, we might need to create our own speed dial components if we want more customization. Styling the mui speeddials is annoying. * Started refactor and frontend cleanup: - debug pages cleanup (was very high priority :D) - added overview page - added tanstack queries for monitor.py - updated mui to 7.0.0 - useTheme should be used via "mui/material" import - other than that was relatively painless - added common link component * Removed unused dependencies and updated other dependences (be sure to run pnpm i) * Tiny bit of additions to dev docs. * Added typing to socket-io client (we do not need it right now but will enhance things once the websocket gets more complex) * Removed old unused stats components. * Tried to restyle the inboxes a bit to match better with the frontpage, might need a bit more work. * started on asis candidate view that uses file metadata @semohr, please check mutation. we probably need two types that overlap. likely build on top our existing iteminfo: - view of whats in the track (can be any and a lot, beets keeps this in tact in the file) - view of the asis candidate (i.e. the subset of those values that beets will put into its own library) * added some badges for meta data * Moved FileMetadata type into api folder and fixed type error with query. Changed candidate order as otherwise the expanded state is not initialized correctly. * Added a search field to the metadata table. * Sticky table top and added filter functions. * - Moved folder refresh to top left - removed old retag action - disabled color gradient for folders/files on desktop (I really dont like the gradient for depth, even on mobile...) * Added missing stat items on frontpage for inboxes. * Run ruff on all files * Removed old import route * Inheritance now supported by py2ts. * Added a frontend route to get to the session by taskid (basically a redirect) This is useful for backrefs from the library via the gui_import_id. Needed an new backend route to get a dbfolder via taskid. * Fixed a small issue with coverart showing skeleton even tho data is available. Removed component from taskid route as it should always redirect and the component is not needed. * Audio is now streamed while transcoding! Created own ffmpeg pipeline as I did not find any usable async one. * Removed unused showPlaceholder coverart prop and added a default placeholder if art is not found. * Modularization of track length formatting and removed duplicate func. * Didnt want to commit this earlier... * Progress on the Asis MetadataBadges * tweaks to asis candidate view * Reenabled eslint hooks rule. * Moved propertyValue table into own file to reuse in library. * Small additions to prop value table to allow styling from parent. * re-added style tweaks to asis candidate that got lost during merge * lyrics badge * Minor cleanup, added track diffs to imported details. Excluded traktor4 tags. Renamed badge to chip. * Removed some old config options and readded watchdog functions. * fixes for bootleg inbox * added file system change websocket event to notify frontend of file changes in inboxes * fixed dirhash_c audio extension filter and auto-inbox tagging on startup * updated config docu and added watchdog auto-import threshold * eslint fixes * removed unused frontend files * fixed some frontend types * bugfix: duplicate action for asis candidates * reworked candidate overview and diffs, now uses dialog and is more consistent * also watch inboxes that dont autoimport for file changes to update frontend view * improved styling of chips * Inbox Type Icons and cleaner inbox headers * wip: started on button-bar rework for inbox * fixed logging in pytest, added readable repr to live states * fixed search test - nena id seems to not exit (anymore?) search session now raises an error when nothing is found * most tests working again, except: - usual old suspect, states, where it matters if other tests run before. no clue. - disk: seems like we are copying something extra: a "multi" folder with data i dont know where it comes from or if we want it :P * added test for dirhash, and it now considers much less information of directories to be less picky but more consistent with the audio_regex * started changelog for v1.0.0, need to decide what do with the few fixes in main, maybe make a v0.1.1 * Fixed state tests. Found an actually error in our states code, see importer/states.py * shortened watchdog interval for tests and fixed disk test by removing multi folder this test as it is only used in flow test. * Fixed mypy issues :) Also allow ci to continue if ruff or mypy fails. * Started with creating a more thought threw library routing: - Get album via /album/albumID (no need for artist selection) - Added some components for album specific view (shows the album, including cover-art and list all tracks, similar to the items we may add multiple tabs) - added parallel routes with for album information (atm only ids) * Started with an device agnostic global audio player. At the moment just a bit of fun testing. * Restructured audio player and added desktop component and context manager. * Added audio duration helper * Added endpoint for audio peaks extraction. * Audio stream is now webm format as the support for mp3 streams is limited on web. Added frontend streaming capabilities with MediaSource. * Added enhanced waveform component. Modified audio context and player to use audio streaming. * Fixed a bug with audio streaming on chromium based browsers. Also added fullscreen mobile layout. * We now can server art in 3 sizes and support multi artworks if they are set. * Fullsize layout image should be responsive now. * Audioplayer is now a global component (mounted in __root). Added scrolling to pages once the audio is mounted. * Fixed an issue with media session updates trigger ever render, oops. Moved to a single wavesurfer instance as extensive rerender can produces freezes. Moved album library route to files instead of folders, like it more this way. * A bit more layouting for the enhanced library view, adding a item route. * Audio volume is now stored in local storage. * Created the details view of new item/[id] route. * Moved links into own file to cleanup some duplicate logic. * Added item identifier and artist route. * Changed styling of the artist, item and album pages. Added icon back button. * Renamed route from artist to artists * Added initial list for artists. * More refined artists list. * slightly bit of refactor. Thanks drive * continued to modularization list see prev commit * Readded pageinated query to resources. Also added tests for albums query * Added infinite query. * Added react compiler to production builds. Added grid and list component for album view. * Moved common table components into table folder. Albums browse route is now fully functional. * Removed old library browse files. We sill need overview page for the library and the search needs some more work. * Removed ansi-to-react and updated packages. * Cleaned up artists endpoint a bit we now can split artists by a separator :D We need pandas for this, sorry image size * Enhanced artists endpoint and added a new library overview. Still a bit ugly but shows way more information now. * Disabled standard out for tests in ci. Kinda difficult to see which tests fail and why. * Overwrite beets config output dir in tests. * Revert last commit and mixin now set library paths and dir after reload. Fingers crossed this fixes the ci issue * Small refactor of disk tests. * Disable fast refresh rule in ci as it is not really useful. * Used old eslint config format * Fixed outstanding eslint issues. Moved some debugging code into debugging folder. Fixed some useEffect issues. * Removed old browserHeader file. Fixed type issue in coverArt and links. * Fixed issue with artist test. We now split artists by separator in the library few which was not tested properly yet. * fixed beets_flask not found error in production. note: we should consider renaming interactive-beets to beets-flask in pyproject.toml for consistency * fixed frontend path for production * mypy, and failing checks should still error in the ci output * renamed ci jobs --------- Co-authored-by: Sebastian Mohr <sebastian@mohrenclan.de>
1 parent 0304eb7 commit 12c2008

File tree

298 files changed

+34074
-15680
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

298 files changed

+34074
-15680
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
!backend/pyproject.toml
1212
!backend/main.py
1313
!backend/launch_redis_workers.py
14+
!backend/generate_types.py
1415

1516
!configs/
1617

.github/workflows/javascript.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Javascript
1+
name: Javascript checks
22

33
on:
44
push:
@@ -12,7 +12,7 @@ on:
1212

1313
jobs:
1414
eslint:
15-
name: Run eslint scanning
15+
name: Javascript checks
1616
runs-on: ubuntu-latest
1717
permissions:
1818
contents: read
@@ -39,6 +39,11 @@ jobs:
3939
cd ./frontend
4040
pnpm install --frozen-lockfile
4141
- name: Run ESLint
42+
continue-on-error: true
4243
run: |
4344
cd ./frontend
4445
pnpm run lint
46+
- name: Run TypeScript type check
47+
run: |
48+
cd ./frontend
49+
pnpm run check-types

.github/workflows/python.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ on:
44
push:
55
branches: ["main"]
66
paths:
7-
- backend/**
7+
- backend/**
88
pull_request:
99
# The branches below must be a subset of the branches above
1010
branches: ["main"]
1111

1212
jobs:
13-
ruff:
14-
name: Ruff check and linting
13+
python:
14+
name: Python checks
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v4
@@ -26,15 +26,24 @@ jobs:
2626
pip install ruff
2727
pip install .[typed]
2828
- name: Check style with Ruff
29+
continue-on-error: true
2930
run: |
3031
cd ./backend
3132
ruff check --output-format=github .
3233
- name: Check type hints with mypy
34+
continue-on-error: true
3335
run: |
3436
cd ./backend
3537
mypy --show-error-codes --check-untyped-defs --config-file ./pyproject.toml ./beets_flask
3638
- name: Test with pytest
39+
env:
40+
PYTEST_ADDOPTS: "--color=yes"
3741
run: |
3842
cd ./backend
3943
pip install .[test]
40-
coverage run -m pytest -v -s
44+
coverage run -m pytest -v
45+
- name: Check for failures
46+
if: steps.ruff.outcome == 'failure' || steps.mypy.outcome == 'failure'
47+
run: |
48+
echo "One or more checks failed"
49+
exit 1

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ share/python-wheels/
3939
*.egg
4040
MANIFEST
4141

42+
.ruff_cache/
43+
4244
# PyInstaller
4345
# Usually these files are written by a python script from a template
4446
# before PyInstaller builds the exe, so as to inject date/other infos into it.
@@ -74,7 +76,7 @@ local_settings.py
7476
db.sqlite3
7577
db.sqlite3-journal
7678

77-
# Flask stuff:
79+
# Quart stuff:
7880
instance/
7981
.webassets-cache
8082

@@ -173,3 +175,9 @@ cython_debug/
173175
#.idea/
174176
node_modules/
175177
.pnpm-store/
178+
179+
180+
.vscode/
181+
182+
# TODO: Pickle for tests contains local paths and has to be ignored until fixed
183+
lookup*.pickle
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
33
# Ruff version.
4-
rev: v0.6.5
4+
rev: v0.11.2
55
hooks:
66
# Run the linter.
77
- id: ruff
8-
args: [--fix, --config=./backend/pyproject.toml]
8+
args: [--fix, --config=backend/pyproject.toml]
99
# Run the formatter.
1010
- id: ruff-format
11-
args: [--config=./backend/pyproject.toml]
11+
args: [--config=backend/pyproject.toml]

CHANGELOG.md

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,60 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## upcoming
8+
## [1.0.0] - upcoming
9+
10+
This is a breaking change, you will need to update your configs and delete your beets-flask
11+
database (**not** the beets db!).
12+
13+
### Changed
14+
15+
- Migrated backend to quart (the async version of flask)
16+
- Reworked most of the frontend
17+
- Removed interactive imports. We now store states for _any_ preview and import that is generated. Thus, sessions are resumable, and we can go back and forth seemlessly, to e.g. undo an import and pick a better candidate.
18+
- Inbox types have changed. For now we only have `preview`, `auto` and `bootleg`.
19+
- beets updated to version 2.2.0
20+
- Implemented our own async pipeline for beets, that is typed and handles our custom sessions (should become obsolete once upstream PRs are merged).
21+
- Improved library view, and track preview / streaming.
22+
- Improved candidate preview, including cover art and asis details (current metadata).
23+
- Terminal now has a bit of scroll-back and history.
24+
- Much better test coverage.
25+
- Now using [py2ts](https://github.com/semohr/py2ts) to automatically generate frontend (typescript) types from their backend (python) equivalents.
26+
27+
## [0.1.1] - unreleased
928

1029
### Added
1130

12-
- Option to install beets plugins by placing either `requirements.txt` or `startup.sh` in /`config`. cf. [Readthedocs](https://beets-flask.readthedocs.io/en/latest/plugins.html)
13-
- [Documentation](https://beets-flask.readthedocs.io/en/latest/?badge=latest) on readthedocs.
14-
- Option to import Asis via right-click, or as inbox type. Good for Bootlegs that do not
15-
have online meta data and you curate manually. Currently also applies `--group-albums`.
31+
- Option to install beets plugins by placing either `requirements.txt` or `startup.sh` in /`config`. cf. [Readthedocs](https://beets-flask.readthedocs.io/en/latest/plugins.html)
32+
- [Documentation](https://beets-flask.readthedocs.io/en/latest/?badge=latest) on readthedocs.
33+
- Option to import Asis via right-click, or as inbox type. Good for Bootlegs that do not
34+
have online meta data and you curate manually. Currently also applies `--group-albums`.
1635

1736
### Fixed
1837

19-
- Path escaping for right-click import via cli (#51)
38+
- Path escaping for right-click import via cli (#51)
2039

2140
## [0.1.0] - 24-11-13
2241

2342
### Fixed
2443

25-
- Renamed `kind` to `type` in search frontend code to be consistent with backend.
26-
Using kind for tags (preview, import, auto), and types for search (album, track).
44+
- Renamed `kind` to `type` in search frontend code to be consistent with backend.
45+
Using kind for tags (preview, import, auto), and types for search (album, track).
2746

2847
### Changed
2948

30-
31-
- Improved readme and onboarding experience
32-
- Mountpoint to persist config files and databases changed to `/config` (was `/home/beetle/.config/beets/`)
33-
We create the `/config/beets` and `/config/beets-flask` folders on startup if they do not exist.
34-
Library files are placed there, and you can drop a `config.yaml` either or both of these folders. Settings in `/config/beets-flask/config.yaml` take precedence over `/config/beets/config.yaml`.
35-
**You will need to update your docker-compose!**
49+
- Improved readme and onboarding experience
50+
- Mountpoint to persist config files and databases changed to `/config` (was `/home/beetle/.config/beets/`)
51+
We create the `/config/beets` and `/config/beets-flask` folders on startup if they do not exist.
52+
Library files are placed there, and you can drop a `config.yaml` either or both of these folders. Settings in `/config/beets-flask/config.yaml` take precedence over `/config/beets/config.yaml`.
53+
**You will need to update your docker-compose!**
3654

3755
### Added
3856

39-
- Logo and favicon
40-
- Image now on docker hub: `pspitzner/beets-flask:stable`
41-
- Auto-import: automatically import folders that are added to the inbox if the match is good enough.
42-
After a preview, import will start if the match quality is above the configured.
43-
Enable via the config.yaml, set the `autotag` field of a configred inbox folders to `"auto"`.
57+
- Logo and favicon
58+
- Image now on docker hub: `pspitzner/beets-flask:stable`
59+
- Auto-import: automatically import folders that are added to the inbox if the match is good enough.
60+
After a preview, import will start if the match quality is above the configured.
61+
Enable via the config.yaml, set the `autotag` field of a configred inbox folders to `"auto"`.
4462

4563
## [0.0.4] - 24-10-04
4664

QUESTIONS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55
- AlbumMatch
66
- Pipeline decorators
77
- How to serialize Task objects (to db)?
8+
9+
10+
- Import task typing especially for candidates (`beets/importer.py/BaseImportTask` und `ImportTask`)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- start intro -->
22
<p align="center">
3-
<h1 align="center">Beets Flask</h1>
3+
<h1 align="center">Beets Quart</h1>
44
</p>
55

66
[![version number](https://img.shields.io/github/package-json/v/pspitzner/beets-flask/main?filename=frontend%2Fpackage.json&label=version&color=blue)](https://github.com/pSpitzner/beets-flask/blob/main/CHANGELOG.md)

RESOURCES.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Here you can find some resources that might be useful and interesting for develo
55
## Tech Stack
66

77
- Backend:
8-
- [Flask](https://flask.palletsprojects.com/en/3.0.x/) with some plugins
8+
- [Quart](https://flask.palletsprojects.com/en/3.0.x/) with some plugins
99
- [Gunicorn](https://gunicorn.org/)
1010
- [Redis Queue](https://python-rq.org/)
1111
- [SQLite via SQLAlchemy](https://docs.sqlalchemy.org/en/20/)
@@ -82,11 +82,11 @@ The container runs a tmux session that you can connect to from the host, or from
8282
To access the tmux from the host:
8383

8484
```
85-
docker exec -it beets-flask /usr/bin/tmux attach-session -t beets-socket-term
85+
docker exec -it -u beetle beets-flask /usr/bin/tmux attach-session -t beets-socket-term
8686
```
8787

8888
If you use iTerm on macOS and want to create a profile for connecting to the tmux session natively:
8989

9090
```
91-
ssh -t yourserver "/usr/bin/docker exec -it beets-flask /usr/bin/tmux -CC new -A -s beets-socket-term"
91+
ssh -t yourserver "/usr/bin/docker exec -it -u beetle beets-flask /usr/bin/tmux -CC new -A -s beets-socket-term"
9292
```

backend/beets_flask/__init__.py

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,3 @@
1-
from __future__ import annotations
2-
3-
import os
4-
from typing import TYPE_CHECKING
5-
6-
from flask import Flask
7-
from flask_cors import CORS
8-
9-
from .config.flask_config import ServerConfig, init_server_config
10-
from .database import setup_database
111
from .logger import log
122

13-
if TYPE_CHECKING:
14-
from .config.flask_config import ServerConfig
15-
16-
17-
def create_app(config: str | ServerConfig | None = None) -> Flask:
18-
19-
# create and configure the app
20-
app = Flask(__name__, instance_relative_config=True)
21-
# CORS needed for Dev so vite can talk to the backend
22-
CORS(app)
23-
24-
config = init_server_config(config)
25-
app.config.from_object(config)
26-
# make routes with and without trailing slahes the same
27-
app.url_map.strict_slashes = False
28-
29-
global socketio
30-
# app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
31-
32-
# sqlite
33-
setup_database(app)
34-
35-
# Register blueprints
36-
from beets_flask.routes import backend_bp
37-
38-
from .routes import frontend_bp
39-
40-
app.register_blueprint(backend_bp)
41-
app.register_blueprint(frontend_bp)
42-
43-
# Start websocket for realtime Terminal and status updates
44-
from .websocket import register_socketio
45-
46-
register_socketio(app)
47-
48-
from .websocket.importer import register_importer
49-
from .websocket.status import register_status
50-
from .websocket.terminal import register_tmux
51-
52-
register_tmux()
53-
register_importer()
54-
register_status()
55-
56-
from .inbox import register_inboxes
57-
58-
register_inboxes()
59-
60-
from .invoker import delete_tags
61-
62-
delete_tags(with_status=["pending", "tagging", "importing"])
63-
64-
log.debug("App created")
65-
66-
return app
3+
__all__ = ["log"]

0 commit comments

Comments
 (0)