Git Product home page Git Product logo

metatube's Introduction

MetaTube

Github top language Github language count Repository size License Github issues Github forks Github stars

Status

โœ”๏ธ MetaTube ๐Ÿš€ Finished! โœ”๏ธ

Disclaimer: This project will most likely not receive any major features. The focus will be on fixing breaking bugs and updating the dependencies.


About ย  | ย  Features ย  | ย  Technologies ย  | ย  Requirements ย  | ย  Starting ย  | ย  License ย  | ย  Disclaimer ย  | ย  Author


๐ŸŽฏ About

MetaTube downloads video from YouTube and can add metadata from a specified metadata provider on the downloaded file.

Normal view Dark mode
startpage darkstartpage
2022-01-03.21-40-37.mp4
2022-01-03.21-39-36.mp4

โœจ Features

It's finished (for now) and these features are currently supported:

โœ”๏ธ Fetch information from a YouTube video based on an URL
โœ”๏ธ Query and fetch results from the Musicbrainz API, the Spotify Web API, and the Deezer API
โœ”๏ธ Set up templates and options for the YouTube download
โœ”๏ธ Download YouTube videos based on a selected template
โœ”๏ธ Exclude fragments (such as intros, outros, etc.) from the download
โœ”๏ธ Metadata from either the user or the chosen metadata provider can be merged with MP3, Opus, FLAC, WAV, OGG, M4A & MP4 files
โœ”๏ธ Hardware encoding using NVENC, Intel Quick Sync
โœ”๏ธ Hardware encoding is supported, but not yet tested for Video Toolbox, Video Acceleration API (VAAPI), AMD AMF & OpenMax OMX
โœ”๏ธ Manually set height and width, if a video type has been selected
โœ”๏ธ Store the information about downloaded releases in the database, to edit the downloaded metadata or the file itself later after the download
โœ”๏ธ Dark mode is available
โœ”๏ธ Docker is supported

I'm currently not planning on adding any new features; I'll only fix any bugs, but if you have a nice feature, feel free to create an issue, and I'll decide whether I'll actually do it.

๐Ÿš€ Technologies

The following tools were used in this project:

For a complete list, visit the Dependencies overview in the Insights.

โœ… Requirements

Before starting ๐Ÿ, you need to have Git and Python 3.8 or higher installed.

๐Ÿ Starting

๐Ÿณ Using Docker

CLI docker:

docker run \
  -d \
  --name metatube \
  --restart always \
  -p 5000:5000 \
  -e PORT=5000 \
  -e HOST=0.0.0.0 \
  -v /downloads:/downloads:rw \
  -v /metatube/database:/database:rw \
  -v /metatube/migrations:/config/migrations \
  jvt038/metatube:latest

Docker-compose:

version: '3.3'
services:
    metatube:
        container_name: metatube
        restart: always
        image: jvt038/metatube:latest
        ports:
            - '5000:5000'
        environment:
            - PORT=5000
            - HOST=0.0.0.0
        volumes:
            - '/downloads:/downloads:rw'
            - '/metatube/database:/database:rw'
            - '/metatube/migrations:/config/migrations:rw'      

You need to set the variable DATABASE_URL to a custom mount point (in these examples /database), because otherwise your database file will reset everytime the Docker container updates.

๐Ÿ› ๏ธ Manually build and start server

# Clone this project
$ git clone https://github.com/JVT038/metatube

# Access
$ cd metatube

# Skip these steps if you don't want to use a virtual environment
# Install virtualenv
$ pip install virtualenv
# Create virtual environment in current directory
$ virtualenv .
# Activate environment
# Windows:
$ cd Scripts
$ activate
# Linux:
$ source bin/activate
 
# Navigate to the root directory
$ cd ../

# Install dependencies
$ pip install -r requirements.txt

# If you're using Windows, you need to install python-magic-bin
$ pip install python-magic-bin
# If you're using Debian / Ubuntu, you'll need to install libmagic1
$ sudo apt-get install libmagic1
# If you're using iOS, you'll need to install libmagic
$ brew install libmagic

# Run the file
$ python metatube.py

# The server will initialize in the <http://localhost:5000>

You can set the following environment variables:

Name Description Default value
PORT Set the port on which the MetaTube server will be available 5000
HOST Set the address on which the MetaTube server will run 127.0.0.1
DEBUG Whether to enable debug mode or not False
DATABASE_URL The URL to your Database. Currently only SQLite3 is supported. sqlite:///app.db
FFMPEG An absolute path to the folder containing ffmpeg. Empty
DOWNLOADS An absolute path to the default download folder /absolute/path/to/MetaTube/downloads; absolute path will be calculated automatically
LOG Whether to keep logs or not False
SOCKET_LOG Whether to log in- and outcoming websocket connections; warning: your console can be spammed with connections False
LOG_LEVEL Numeric value from which MetaTube will keep logs. Info here 10
URL_SUBPATH Set the URL subpath, if you want to run MetaTube on a subpath. Example: /metatube will run the server on host:port/metatube /
INIT_DB Automatically initialize the database and make all migrations. Set to 'False' if you're having issues with migrations True
# On Windows 10, you can set an environment variable like this: 
$ set ENVIRONMENT_VARIABLE = Value

# On Linux and MacOS, you can set an environment variable like this:
$ export ENVIRONMENT_VARIABLE = Value

Additionally you can create a file called .flaskenv and set the environment variables in there. An example is provided in example.flaskenv. You can use that template and rename the file to .flaskenv.

Fix the artist values

So I recently discovered I made a mistake in the process of adding artists to files.
Some songs have tags multiple artists, and I noticed these tags were misinterpreted by my audio player.
Basically, the TPE1 tag contained was like this: ['artist 1; artist 2'], while it should've been ['artist 1', 'artist 2'].
Thanks to #310 I discovered this, corrected it in metadata.py and wrote a small script in fixartists.py to fix the existing audio files that had the tags in the wrong way.
Put all the wrong audio files in one directory, run the file and enter the path to the directory containing the incorrect tags, and it should be fixed.
My apologies for this (annoying) bug.

๐Ÿ“ License

This project is under license from GNUv3. For more details, see the LICENSE file.
I am not responsible for any legal consequences the user may or may not face by using this project.

Made with โค๏ธ by JVT038

To-Do

Finished

  • Add support for the use of proxies to download YouTube videos
  • Add Docker support
  • Add Docker support for ARM64/v8 devices (such as Raspberry Pi 4)
  • Add Github action / workflow thing, to automatically create Docker image upon a new commit
  • Add support for Spotify as a metadata provider
  • Add support for Deezer as a metadata provider
  • Add support for Genius as a metadata provider
  • Add support for embedded lyrics (if possible)
  • Add support for subpath (such as localhost:5000/metatube)
  • Add a nice progress bar
  • Add a function to allow users to download the song onto their device
  • Add button in settings to download all the downloaded content
  • Add ability to manually set video width & height, if a video type has been selected
  • Add ability to manually set video width & height, if a video type has been selected, AFTER the item has been inserted into the database
  • Add in-built file explorer, making manual paths optional
  • Preview filenames when entering an output template
  • Make the Docker file smaller, because it's huge
  • Build a logger
  • Catch and show errors properly
  • Support looking for YouTube videos and downloading them
  • Store the information of downloaded songs in a SQL database
  • Make it mobile-friendly
  • Use Sponsorblock and yt-dlp to automatically skip fragments
  • Manually edit metadata of file, before the download
  • Manually edit metadata of file, after the download
  • Select output type (coding, extension, etc.)
  • Switch from AJAX to websockets
  • Hardware transcoding with NVENC, Intel Quick Sync, Video Acceleration API (VAAPI) & AMD AMF
  • Improve the automatic creation of the database, the tables and the default rows, because it's horrible right now.
  • Use multiprocessing and websockets to make the overview page faster
  • Dark mode support
  • Fix error Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end userโ€™s experience. For more help http://xhr.spec.whatwg.org/ in overview
  • Make sure the search for downloaded song field works
  • Make sure the progress bar works properly in a Docker container, because it doesn't work properly rn

Not finished (I'll probably never finish this lol)

  • Add it to the PyPi library
  • Add support for sites other than YouTube
  • Add support for YouTube playlists
  • Add custom YouTube-DLP options
  • Add support for H.265 / HEVC
  • Add authentication system with an optional reverse proxy
  • Add support for TheAudioDB
  • Add support for YouTube Music
  • Add support for Last.fm!
  • Add translations
  • Add some nice animations
  • Add a cancel download button when the video is being downloaded
  • Add button in settings to download the entire SQlite3 Database
  • Add support for HTTPS / SSL
  • Give the user the option which level of logs to show / log and whether to save the logs to a file
  • Support querying the Musicbrainz database and matching YouTube videos with them
  • Support MySQL
  • Make a CLI to download and match music
  • Have a proper versioning system, because it's impossible to keep track of versions rn
  • Cache and store the segments and other video data, so next time of loading a video will be faster
  • Send websocket requests to one specific device / client only, to prevent duplicate websocket requests
  • Use proper queues and threading during download instead of the weird ping-pong system between the client and the server.*
  • Add unit tests for the download, metadata logic, template / database stuff, config detection, automatic migrations
  • in progress ย 

Disclaimer

I made this project to educate myself about Python, and to learn how metadata works in combination with files. Additionally, I want to emphasize I do NOT encourage any pirating, or any other illegal activities. This project's purpose isn't to illegally download content from YouTube; its purpose is to educate and enlighten myself (and others viewing the source code) about Python, how Python interacts with metadata in files, and metadata works, and how yt-dlp works. I am not responsible if the user downloads illegal content, or faces any (legal) consequences.

Back to top

metatube's People

Contributors

cristiangauma avatar dependabot[bot] avatar jvt038 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

metatube's Issues

Qol bugs

  1. Even when I edited the metadata manually, it still asks me to pick one from the list that it searched from musicbrainz, etc even though there's literally no results.
  2. It's slow. is there no concurrency in this project?
  3. When I recreate the Docker container or just restart it, I get this error:
ERROR [flask_migrate] Error: Can't locate revision identified by '8046105cb767'
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.

I can resolve it by moving the app.db out of the folder and letting it recreate the database file then moving it back but now, I can't do it.

Python problems when deploying the container fresh

When I set up Metatube completly fresh, I experienced this error and couldnt figure out why it comes up.
I used this docker run command:

docker run \
  -d \
  --name metatube \
  --restart always \
  -p 6376:5000 \
  -e PORT=5000 \
  -e HOST=0.0.0.0 \
  -v /(exchanged path)/metatube/downloads:/downloads:rw \
  -v /(exchanged path)/metatube/database:/database:rw \
  -v /(exchanged path)/metatube/migrations:/config/migrations \
  jvt038/metatube:latest

This is the error message I always got:

Traceback (most recent call last):

  File "//config/metatube.py", line 9, in <module>

    app = create_app()

  File "/config/metatube/__init__.py", line 46, in create_app

    init_db(app)

  File "/config/metatube/init/__init__.py", line 11, in init

    default.init_db()

  File "/config/metatube/init/create.py", line 72, in init_db

    self.migrations()

  File "/config/metatube/init/create.py", line 80, in migrations

    stamp(directory)

  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 111, in wrapped

    f(*args, **kwargs)

  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 259, in stamp

    command.stamp(config, revision, sql=sql, tag=tag)

  File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 671, in stamp

    script.run_env()

  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 569, in run_env

    util.load_python_file(self.dir, "env.py")

  File "/usr/local/lib/python3.9/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file

    raise ImportError("Can't find Python file %s" % path)

ImportError: Can't find Python file /config/migrations/env.py

I hope you can help me find my mistake, thanks

Pip install fails thanks to gevent

Well, pip install fails.

pip logs:

> pip install -r requirements.txt
Collecting mutagen==1.45.1
  Using cached mutagen-1.45.1-py3-none-any.whl (218 kB)
Collecting requests==2.28.1
  Using cached requests-2.28.1-py3-none-any.whl (62 kB)
Collecting yt-dlp==2022.6.29
  Using cached yt_dlp-2022.6.29-py2.py3-none-any.whl (2.6 MB)
Collecting gevent==21.8.0
  Using cached gevent-21.8.0.tar.gz (6.2 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Collecting gevent-websocket==0.10.1
  Using cached gevent_websocket-0.10.1-py3-none-any.whl (22 kB)
Collecting Flask==2.1.3
  Using cached Flask-2.1.3-py3-none-any.whl (95 kB)
Collecting Flask-SocketIO==5.2.0
  Using cached Flask_SocketIO-5.2.0-py3-none-any.whl (17 kB)
Collecting Flask-Migrate==3.1.0
  Using cached Flask_Migrate-3.1.0-py3-none-any.whl (20 kB)
Collecting Flask-JSGlue2==0.3.3
  Using cached Flask-JSGlue2-0.3.3.tar.gz (2.1 kB)
  Preparing metadata (setup.py) ... done
Collecting Flask-SQLAlchemy==2.5.1
  Using cached Flask_SQLAlchemy-2.5.1-py2.py3-none-any.whl (17 kB)
Collecting musicbrainzngs==0.7.1
  Using cached musicbrainzngs-0.7.1-py2.py3-none-any.whl (25 kB)
Collecting sponsorblock.py==0.2.2
  Using cached sponsorblock.py-0.2.2-py3-none-any.whl (17 kB)
Collecting python-dateutil==2.8.2
  Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
Collecting python-dotenv==0.20.0
  Using cached python_dotenv-0.20.0-py3-none-any.whl (17 kB)
Collecting python-magic==0.4.27
  Using cached python_magic-0.4.27-py2.py3-none-any.whl (13 kB)
Collecting ffmpeg-python==0.2.0
  Using cached ffmpeg_python-0.2.0-py3-none-any.whl (25 kB)
Collecting youtube-search-python==1.6.6
  Using cached youtube_search_python-1.6.6-py3-none-any.whl (89 kB)
Collecting spotipy==2.20.0
  Using cached spotipy-2.20.0-py3-none-any.whl (27 kB)
Collecting urllib3==1.26.10
  Using cached urllib3-1.26.10-py2.py3-none-any.whl (139 kB)
Collecting deezer-python==5.3.3
  Using cached deezer_python-5.3.3-py3-none-any.whl (20 kB)
Collecting charset-normalizer<3,>=2
  Using cached charset_normalizer-2.1.1-py3-none-any.whl (39 kB)
Collecting certifi>=2017.4.17
  Using cached certifi-2022.12.7-py3-none-any.whl (155 kB)
Collecting idna<4,>=2.5
  Using cached idna-3.4-py3-none-any.whl (61 kB)
Collecting brotli
  Using cached Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.7 MB)
Collecting pycryptodomex
  Using cached pycryptodomex-3.17-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)
Collecting websockets
  Using cached websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (106 kB)
Collecting zope.event
  Using cached zope.event-4.6-py2.py3-none-any.whl (6.8 kB)
Collecting greenlet<2.0,>=1.1.0
  Using cached greenlet-1.1.3.post0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (156 kB)
Collecting zope.interface
  Using cached zope.interface-5.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (258 kB)
Requirement already satisfied: setuptools in /home/carlo/env/webyt/lib/python3.10/site-packages (from gevent==21.8.0->-r requirements.txt (line 4)) (65.5.0)
Collecting click>=8.0
  Using cached click-8.1.3-py3-none-any.whl (96 kB)
Collecting Werkzeug>=2.0
  Using cached Werkzeug-2.2.2-py3-none-any.whl (232 kB)
Collecting Jinja2>=3.0
  Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)
Collecting itsdangerous>=2.0
  Using cached itsdangerous-2.1.2-py3-none-any.whl (15 kB)
Collecting python-socketio>=5.0.2
  Using cached python_socketio-5.7.2-py3-none-any.whl (56 kB)
Collecting alembic>=0.7
  Using cached alembic-1.9.2-py3-none-any.whl (210 kB)
Collecting SQLAlchemy>=0.8.0
  Using cached SQLAlchemy-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB)
Collecting six>=1.5
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting future
  Using cached future-0.18.3.tar.gz (840 kB)
  Preparing metadata (setup.py) ... done
Collecting httpx>=0.14.2
  Using cached httpx-0.23.3-py3-none-any.whl (71 kB)
Collecting redis>=3.5.3
  Using cached redis-4.4.2-py3-none-any.whl (237 kB)
Collecting Mako
  Using cached Mako-1.2.4-py3-none-any.whl (78 kB)
Collecting rfc3986[idna2008]<2,>=1.3
  Using cached rfc3986-1.5.0-py2.py3-none-any.whl (31 kB)
Collecting sniffio
  Using cached sniffio-1.3.0-py3-none-any.whl (10 kB)
Collecting httpcore<0.17.0,>=0.15.0
  Using cached httpcore-0.16.3-py3-none-any.whl (69 kB)
Collecting MarkupSafe>=2.0
  Using cached MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Collecting bidict>=0.21.0
  Using cached bidict-0.22.1-py3-none-any.whl (35 kB)
Collecting python-engineio>=4.3.0
  Using cached python_engineio-4.3.4-py3-none-any.whl (52 kB)
Collecting async-timeout>=4.0.2
  Using cached async_timeout-4.0.2-py3-none-any.whl (5.8 kB)
Collecting typing-extensions>=4.2.0
  Using cached typing_extensions-4.4.0-py3-none-any.whl (26 kB)
Collecting anyio<5.0,>=3.0
  Using cached anyio-3.6.2-py3-none-any.whl (80 kB)
Collecting h11<0.15,>=0.13
  Using cached h11-0.14.0-py3-none-any.whl (58 kB)
Building wheels for collected packages: gevent
  Building wheel for gevent (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  ร— Building wheel for gevent (pyproject.toml) did not run successfully.
  โ”‚ exit code: 1
  โ•ฐโ”€> [350 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-cpython-310
      creating build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/util.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/events.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_util.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_socket3.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/builtins.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_ident.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/pool.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/local.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/baseserver.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/pywsgi.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/monkey.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/resolver_ares.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/resolver_thread.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_tblib.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_semaphore.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_socket2.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/core.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/threadpool.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_abstract_linkable.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/contextvars.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/ares.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_tracer.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_compat.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_imap.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/server.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_ssl3.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/subprocess.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/threading.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_fileobjectposix.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/thread.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/selectors.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_ssl2.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_waiter.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_hub_primitives.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_monitor.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_greenlet_primitives.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/win32util.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_config.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/backdoor.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_interfaces.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/signal.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_socketcommon.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_util_py2.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/exceptions.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/ssl.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/queue.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/timeout.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/hub.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/time.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/os.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/event.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_sslgte279.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/lock.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/greenlet.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_hub_local.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_fileobjectcommon.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_patcher.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/socket.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/fileobject.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/select.py -> build/lib.linux-x86_64-cpython-310/gevent
      copying src/gevent/_threading.py -> build/lib.linux-x86_64-cpython-310/gevent
      creating build/lib.linux-x86_64-cpython-310/gevent/libuv
      copying src/gevent/libuv/loop.py -> build/lib.linux-x86_64-cpython-310/gevent/libuv
      copying src/gevent/libuv/_corecffi_build.py -> build/lib.linux-x86_64-cpython-310/gevent/libuv
      copying src/gevent/libuv/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/libuv
      copying src/gevent/libuv/watcher.py -> build/lib.linux-x86_64-cpython-310/gevent/libuv
      creating build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__backdoor.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test___ident.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threadpool_executor_patched.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/known_failures.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__getaddrinfo_import.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_dns.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__GreenletExit.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_selectors.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_send_memoryview.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__systemerror.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_ssl_warning2.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_patched_local.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__refcount.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_sigchld.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__os.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/lock_tests.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__nondefaultloop.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issues461_471.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_builtins_future.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_close.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue230.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__close_backend_fd.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__greenlet.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__hub.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__subprocess.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_ssl_warning.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_timeout.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_logging.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__subprocess_poll.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__hub_join_timeout.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_imports_imports_at_top_level.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_callback.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__sleep0.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__semaphore.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_no_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_vs_settrace.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__queue.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_hub_in_thread.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_import_import_patch.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__contextvars.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/__main__.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_ex.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test___config.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_monkey_in_thread.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__signal.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__environ.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__iwait.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__server.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_ssl.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__api.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__hub_join.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__import_blocking_in_greenlet.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__import_wait.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_wsgiserver.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__greenio.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__api_timeout.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__ssl.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__doctests.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_webproxy.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_blocks_at_top_level.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__makefile_ref.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue1686.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_loop_run.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__memleak.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__ares_timeout.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_import_wait.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__lock.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue607.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__loop_callback.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_2.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__greenletset.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__real_greenlet.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__compat.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__exc_info.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__server_pywsgi.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue112.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__pywsgi.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__fileobject.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_watcher.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_module_run.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__events.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__destroy_default_loop.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_udp_server.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_select.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_async.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__examples.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__timeout.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_wsgiserver_ssl.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_ssl_warning3.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_echoserver.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_sigchld_3.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_native_before_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__joinall.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue639.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_fork.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_udp_client.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__util.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_sigchld_2.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue467.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_imports_at_top_level.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test___monitor.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__pool.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_dns6.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__order.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socket_errors.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_futures_thread.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test___monkey_patching.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_before_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__execmodules.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_timer.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threadpool.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__select.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__destroy.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__selectors.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__threading_holding_lock_while_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__socketpair.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__all__.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__resolver_dnspython.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__thread.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__core_stat.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__ares_host_result.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__greenness.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__event.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_multiple_imports.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__subprocess_interrupted.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/getaddrinfo_module.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/_import_patch.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__monkey_queue.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue330.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue6.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__local.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue_728.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__issue600.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__example_portforwarder.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test__refcount_core.py -> build/lib.linux-x86_64-cpython-310/gevent/tests
      creating build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/util.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/sysinfo.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/leakcheck.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/params.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/testcase.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/monkey_test.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/exception.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/six.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/travis.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/testrunner.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/patched_tests_setup.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/sockets.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/flaky.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/support.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/modules.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/errorhandler.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/switching.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/hub.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/timing.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/openfiles.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/resources.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      copying src/gevent/testing/skipping.py -> build/lib.linux-x86_64-cpython-310/gevent/testing
      creating build/lib.linux-x86_64-cpython-310/gevent/libev
      copying src/gevent/libev/_corecffi_build.py -> build/lib.linux-x86_64-cpython-310/gevent/libev
      copying src/gevent/libev/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/libev
      copying src/gevent/libev/corecffi.py -> build/lib.linux-x86_64-cpython-310/gevent/libev
      copying src/gevent/libev/watcher.py -> build/lib.linux-x86_64-cpython-310/gevent/libev
      creating build/lib.linux-x86_64-cpython-310/gevent/_ffi
      copying src/gevent/_ffi/loop.py -> build/lib.linux-x86_64-cpython-310/gevent/_ffi
      copying src/gevent/_ffi/callback.py -> build/lib.linux-x86_64-cpython-310/gevent/_ffi
      copying src/gevent/_ffi/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/_ffi
      copying src/gevent/_ffi/watcher.py -> build/lib.linux-x86_64-cpython-310/gevent/_ffi
      creating build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/blocking.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/dnspython.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/ares.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/thread.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/_hostsfile.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      copying src/gevent/resolver/_addresses.py -> build/lib.linux-x86_64-cpython-310/gevent/resolver
      creating build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/issue1526_no_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/__main__.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/threadpool_no_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/__init__.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/issue302monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/script.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/issue1526_with_monkey.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/monkey_package/threadpool_monkey_patches.py -> build/lib.linux-x86_64-cpython-310/gevent/tests/monkey_package
      copying src/gevent/tests/badcert.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/wrongcert.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/https_svn_python_org_root.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/badkey.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/nullcert.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/2_7_keycert.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/sha256.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/keycert.pem -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/server.crt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test_server.crt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/hosts_file.txt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/tests_that_dont_monkeypatch.txt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/tests_that_dont_do_leakchecks.txt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/tests_that_dont_use_resolver.txt -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/test_server.key -> build/lib.linux-x86_64-cpython-310/gevent/tests
      copying src/gevent/tests/server.key -> build/lib.linux-x86_64-cpython-310/gevent/tests
      creating build/lib.linux-x86_64-cpython-310/gevent/testing/coveragesite
      copying src/gevent/testing/coveragesite/sitecustomize.py -> build/lib.linux-x86_64-cpython-310/gevent/testing/coveragesite
      running build_ext
      generating cffi module 'build/temp.linux-x86_64-cpython-310/gevent.libuv._corecffi.c'
      creating build/temp.linux-x86_64-cpython-310
      Running '(cd  "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/deps/libev"  && sh ./configure -C > configure-output.txt )' in /tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799
      configure: error: in `/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/deps/libev':
      configure: error: no acceptable C compiler found in $PATH
      See `config.log' for more details
      Traceback (most recent call last):
        File "/home/carlo/env/webyt/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 351, in <module>
          main()
        File "/home/carlo/env/webyt/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 333, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/home/carlo/env/webyt/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 249, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 413, in build_wheel
          return self._build_with_temp_dir(['bdist_wheel'], '.whl',
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 398, in _build_with_temp_dir
          self.run_setup()
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 484, in run_setup
          super(_BuildMetaLegacyBackend,
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 335, in run_setup
          exec(code, locals())
        File "<string>", line 481, in <module>
        File "<string>", line 348, in run_setup
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/__init__.py", line 108, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 185, in setup
          return run_commands(dist)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
          dist.run_commands()
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
          self.run_command(cmd)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 1213, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/wheel/bdist_wheel.py", line 325, in run
          self.run_command("build")
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 1213, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/command/build.py", line 132, in run
          self.run_command(cmd_name)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 1213, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/cffi/setuptools_ext.py", line 143, in run
          ext.sources[0] = make_mod(self.build_temp, pre_run)
        File "/tmp/pip-build-env-vr5ema1s/overlay/lib/python3.10/site-packages/cffi/setuptools_ext.py", line 128, in make_mod
          pre_run(ext, ffi)
        File "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/_setuputils.py", line 364, in pre_run
          action()
        File "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/_setuplibev.py", line 55, in configure_libev
          system(libev_configure_command)
        File "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/_setuputils.py", line 195, in system
          if _system(cmd, cwd=cwd, env=env, **kwargs):
        File "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/_setuputils.py", line 191, in _system
          return check_call(cmd, cwd=cwd, env=env, **kwargs)
        File "/usr/lib/python3.10/subprocess.py", line 369, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '(cd  "/tmp/pip-install-u5u5nek1/gevent_ff668e1e3738401aa7e23cdee8bca799/deps/libev"  && sh ./configure -C > configure-output.txt )' returned non-zero exit status 1.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for gevent
Failed to build gevent
ERROR: Could not build wheels for gevent, which is required to install pyproject.toml-based projects

Suggest to loosen the dependency on spotipy

Hi, your project MetaTube(commit id: e0c4931) requires "spotipy==2.19.0" in its dependency. After analyzing the source code, we found that the following versions of spotipy can also be suitable, i.e., spotipy 2.19.0rc1, since all functions that you directly (3 APIs: spotipy.oauth2.SpotifyOauthError.init, spotipy.client.Spotify.init, spotipy.oauth2.SpotifyClientCredentials.init) or indirectly (propagate to 3 spotipy's internal APIs and 4 outsider APIs) used from the package have not been changed in these versions, thus not affecting your usage.

Therefore, we believe that it is quite safe to loose your dependency on spotipy from "spotipy==2.19.0" to "spotipy>=2.19.0rc1,<=2.19.0". This will improve the applicability of MetaTube and reduce the possibility of any further dependency conflict with other projects.

May I pull a request to further loosen the dependency on spotipy?

By the way, could you please tell us whether such an automatic tool for dependency analysis may be potentially helpful for maintaining dependencies easier during your development?

Add option to not use database

Stupid question but I'm struggling with database issues and I don't need the features related to the database, would it be possible to just remove it ?

I want to download and add metadata, I don't really see why a database is useful here.

Sorry, I know this is an "anti-feature".

Constant Boot Looping when running under Debian

After test-running MetaTube on my Win10 machine (using Docker of course) I tried setting up a VM/LXC where I can keep it permanently using the command provided in the README. Unfortunately the container seems to bootloop constantly. The log provides me with this error:

INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1802, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 732, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: database is locked

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "//config/metatube.py", line 10, in <module>
    app = create_app()
  File "/config/metatube/__init__.py", line 48, in create_app
    init_db(app)
  File "/config/metatube/init/__init__.py", line 11, in init
    default.init_db()
  File "/config/metatube/init/create.py", line 72, in init_db
    self.migrations()
  File "/config/metatube/init/create.py", line 80, in migrations
    stamp(directory)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 98, in wrapped
    f(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 244, in stamp
    command.stamp(config, revision, sql=sql, tag=tag)
  File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 613, in stamp
    script.run_env()
  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 563, in run_env
    util.load_python_file(self.dir, "env.py")
  File "/usr/local/lib/python3.9/site-packages/alembic/util/pyfiles.py", line 92, in load_python_file
    module = load_module_py(module_id, path)
  File "/usr/local/lib/python3.9/site-packages/alembic/util/pyfiles.py", line 108, in load_module_py
    spec.loader.exec_module(module)  # type: ignore
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/migrations/env.py", line 91, in <module>
    run_migrations_online()
  File "/config/migrations/env.py", line 85, in run_migrations_online
    context.run_migrations()
  File "<string>", line 8, in run_migrations
  File "/usr/local/lib/python3.9/site-packages/alembic/runtime/environment.py", line 851, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/usr/local/lib/python3.9/site-packages/alembic/runtime/migration.py", line 603, in run_migrations
    self._ensure_version_table()
  File "/usr/local/lib/python3.9/site-packages/alembic/runtime/migration.py", line 539, in _ensure_version_table
    self._version.create(self.connection, checkfirst=True)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/schema.py", line 950, in create
    bind._run_ddl_visitor(ddl.SchemaGenerator, self, checkfirst=checkfirst)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 2113, in _run_ddl_visitor
    visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/visitors.py", line 524, in traverse_single
    return meth(obj, **kw)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/ddl.py", line 893, in visit_table
    self.connection.execute(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1289, in execute
    return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/ddl.py", line 80, in _execute_on_connection
    return connection._execute_ddl(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1381, in _execute_ddl
    ret = self._execute_context(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1845, in _execute_context
    self._handle_dbapi_exception(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 2026, in _handle_dbapi_exception
    util.raise_(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1802, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 732, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked
[SQL:
CREATE TABLE alembic_version (
        version_num VARCHAR(32) NOT NULL,
        CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
)

]
(Background on this error at: https://sqlalche.me/e/14/e3q8)

[12-01-2022 19:07] WARNING [sponsorblock.py:10]: No segments found for ...

Seeing this error today after the update this morning.

[12-01-2022 19:07] INFO [sponsorblock.py:6]: Fetching sponsorblock segments for https://www.youtube.com/watch?v=123456789
[12-01-2022 19:07] WARNING [sponsorblock.py:10]: No segments found for https://www.youtube.com/watch?v=123456789
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
  File "/config/metatube/youtube.py", line 206, in fetch_video
    downloadform = downloadtemplate.render(templates=templates, segments=segments, default=defaulttemplate)
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 1291, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/config/metatube/templates/downloadform.html", line 58, in top-level template code
    {% set resolution = default.resolution.split(';') %}
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 474, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'None' has no attribute 'resolution'
2022-01-12T19:07:43Z <Thread at 0x7f7b3e5e3040: fetch_video({'id': 'RdsGnTsHjhs', 'title': 'Artiest | TruncTitle, [<Templates 0>], 'musicbrainz', None)> failed with UndefinedError

Separate the app into an API and Web UI

Is your feature request related to a problem? Please describe.
Being a monolithic project is kind of a pain. For one, it doesn't allow scalability esp. in deployments like docker.

Describe the solution you'd like
I want this project to be MetaTube-API and MetaTube-Web

Describe alternatives you've considered
None

Additional context
This may also ease up the troubleshooting for server or client specific problems. It also make me and other maintainers do #94, #84, #2, etc. Next, things like multi-user support may easily be implemented. Additionally, it allows scalability (esp for power users of Docker and other tools). And lastly, this also allows integration for selfhosted music players to have access to one's library.

Latest Version Container Crashing upon Startup

Describe the bug
Docker container with the latest version does not start.

To Reproduce
Steps to reproduce the behavior:

  1. Pull the latest image and run it.

Expected behavior
Container launches without error and stays running.

Logs

Creating directory /config/migrations ...  done
Creating directory /config/migrations/versions ...  done
Generating /config/migrations/script.py.mako ...  done
Generating /config/migrations/env.py ...  done
Generating /config/migrations/alembic.ini ...  done
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
Generating /config/migrations/README ...  done
Please edit configuration/connection/logging settings in '/config/migrations/alembic.ini' before proceeding.
ERROR [flask_migrate] Error: Can't locate revision identified by 'e935a3b14ca8'
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [flask_migrate] Error: Can't locate revision identified by 'e935a3b14ca8'
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [flask_migrate] Error: Can't locate revision identified by 'e935a3b14ca8'

Server information

  • Installation method: Docker
  • Python version: Version in container
  • Operating System: Ubuntu 22.04

Additional context
Started about 2 hours ago when the new container was published.

ImportError: cannot import name 'Markup' from 'jinja2'

Container fails to start. Removed the database, container, and image to start from fresh and get the same results. Any ideas?

Traceback (most recent call last):                                                                                                                                                                                 File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio
  File "/config/metatube/__init__.py", line 4, in <module>
    from flask_jsglue import JSGlue
  File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup                                                                                                                                                                                    ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)                                                                                               Traceback (most recent call last):                                                                                                                                                                                 File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio
  File "/config/metatube/__init__.py", line 4, in <module>
    from flask_jsglue import JSGlue
  File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup                                                                                                                                                                                    ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)                                                                                               Traceback (most recent call last):                                                                                                                                                                                 File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio
  File "/config/metatube/__init__.py", line 4, in <module>
    from flask_jsglue import JSGlue                                                                                                                                                                                File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup                                                                                                                                                                                    ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)
Traceback (most recent call last):                                                                                                                                                                                 File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio                                                                                                                                                                      File "/config/metatube/__init__.py", line 4, in <module>
    from flask_jsglue import JSGlue
  File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup
ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)                                                                                               Traceback (most recent call last):                                                                                                                                                                                 File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio
  File "/config/metatube/__init__.py", line 4, in <module>                                                                                                                                                           from flask_jsglue import JSGlue
  File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup                                                                                                                                                                                    ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)                                                                                               Traceback (most recent call last):
  File "//config/metatube.py", line 5, in <module>
    from metatube import create_app, socketio
  File "/config/metatube/__init__.py", line 4, in <module>                                                                                                                                                           from flask_jsglue import JSGlue
  File "/usr/local/lib/python3.9/site-packages/flask_jsglue.py", line 2, in <module>                                                                                                                                 from jinja2 import Markup                                                                                                                                                                                    ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.9/site-packages/jinja2/__init__.py)

Will mysql ever come to this web?

Don't have an issue with sqlite but preferer to use mysql and such as i can access it via web and such without needing to ssh incase of an error.

Import Error

My config:

docker run -d \                                                                                                                                               
  --name metatube \                                                                                                                                           
  --restart always \                                                                                                                                          
  -p 5000:5000 \                                                                                                                                              
  -e PORT=5000 \                                                                                                                                              
  -e HOST=0.0.0.0 \                                                                                                                                           
  -v metatube_config:/config \                                                                                                                                
  -v metatube_downloads:/downloads:rw \                                                                                                                       
  -v metatube_database:/database:rw \                                                                                                                         
  jvt038/metatube:latest

Error:

Traceback (most recent call last):
  File "//config/metatube.py", line 9, in <module>
    app = create_app()
  File "/config/metatube/__init__.py", line 46, in create_app
    init_db(app)
  File "/config/metatube/init/__init__.py", line 11, in init
    default.init_db()
  File "/config/metatube/init/create.py", line 72, in init_db
    self.migrations()
  File "/config/metatube/init/create.py", line 80, in migrations
    stamp(directory)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 111, in wrapped
    f(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 259, in stamp
    command.stamp(config, revision, sql=sql, tag=tag)
  File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 671, in stamp
    script.run_env()
  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 569, in run_env
    util.load_python_file(self.dir, "env.py")
  File "/usr/local/lib/python3.9/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file
    raise ImportError("Can't find Python file %s" % path)
ImportError: Can't find Python file /config/migrations/env.py

upon creating file env.py

Traceback (most recent call last):
  File "//config/metatube.py", line 9, in <module>
    app = create_app()
  File "/config/metatube/__init__.py", line 46, in create_app
    init_db(app)
  File "/config/metatube/init/__init__.py", line 11, in init
    default.init_db()
  File "/config/metatube/init/create.py", line 72, in init_db
    self.migrations()
  File "/config/metatube/init/create.py", line 81, in migrations
    migrate(directory)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 111, in wrapped
    f(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/flask_migrate/__init__.py", line 170, in migrate
    command.revision(config, message, autogenerate=True, sql=sql,
  File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 236, in revision
    scripts = [script for script in revision_context.generate_scripts()]
  File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 236, in <listcomp>
    scripts = [script for script in revision_context.generate_scripts()]
  File "/usr/local/lib/python3.9/site-packages/alembic/autogenerate/api.py", line 605, in generate_scripts
    yield self._to_script(generated_revision)
  File "/usr/local/lib/python3.9/site-packages/alembic/autogenerate/api.py", line 510, in _to_script
    return self.script_directory.generate_revision(
  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 667, in generate_revision
    self.revision_map.get_revisions(head),
  File "/usr/local/lib/python3.9/site-packages/alembic/script/revision.py", line 527, in get_revisions
    resolved_id, branch_label = self._resolve_revision_number(
  File "/usr/local/lib/python3.9/site-packages/alembic/script/revision.py", line 751, in _resolve_revision_number
    self._revision_map
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 1138, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/usr/local/lib/python3.9/site-packages/alembic/script/revision.py", line 191, in _revision_map
    for revision in self._generator():
  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 131, in _load_revisions
    for file_ in Script._list_py_dir(self, vers):
  File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 981, in _list_py_dir
    return os.listdir(path)
FileNotFoundError: [Errno 2] No such file or directory: '/config/migrations/versions'

it goes on with not finding files.

Expected behaviour:

Files are getting created upon spinning up container

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.