From 5367ed082fc9beb0117c65e2407370899793d1e7 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 18 Sep 2020 23:15:30 -0600 Subject: [PATCH 1/8] Got lint, test, GitLab mirroring and README working --- .builds/flatpak.yml | 21 ++ .builds/gitlab-mirror-and-readme.yml | 40 ++++ .builds/lint-test.yml | 32 ++++ .builds/pypi.yml | 27 +++ .envrc | 7 + poetry.lock | 274 +++++++++++++++++++++++++++ pyproject.toml | 21 ++ sublime/ui/player_controls.py | 19 ++ 8 files changed, 441 insertions(+) create mode 100644 .builds/flatpak.yml create mode 100644 .builds/gitlab-mirror-and-readme.yml create mode 100644 .builds/lint-test.yml create mode 100644 .builds/pypi.yml create mode 100644 .envrc create mode 100644 poetry.lock diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml new file mode 100644 index 0000000..1af5d20 --- /dev/null +++ b/.builds/flatpak.yml @@ -0,0 +1,21 @@ +image: archlinux +packages: + - flatpak + - flatpak-builder +sources: + - https://git.sr.ht/~sumner/offlinemsmtp +environment: + REPO_NAME: sublime-music +# triggers: +# - action: email +# condition: failure +# to: ~sumner/sublime-music-devel@lists.sr.ht +tasks: + - setup: | + cd ${REPO_NAME} + poetry install + echo "cd ${REPO_NAME}" >> ~/.buildenv + + - build-flatpak: | + cd flatpak + ./flatpak_build.sh diff --git a/.builds/gitlab-mirror-and-readme.yml b/.builds/gitlab-mirror-and-readme.yml new file mode 100644 index 0000000..5575f58 --- /dev/null +++ b/.builds/gitlab-mirror-and-readme.yml @@ -0,0 +1,40 @@ +image: archlinux +packages: + - curl + - openssh + - python-docutils +sources: + - https://git.sr.ht/~sumner/offlinemsmtp +secrets: + # README Personal Access Token + - 2fb5fd72-fa96-46c6-ab90-6b7cabebba16 + # GitLab Mirror SSH Key + - 910786ff-96e4-4951-be00-ad99cc02f357 +environment: + REPO_NAME: sublime-music +# triggers: +# - action: email +# condition: failure +# to: ~sumner/sublime-music-devel@lists.sr.ht +tasks: + - setup: | + cd ${REPO_NAME} + echo "cd ${REPO_NAME}" >> ~/.buildenv + + # TODO + # - gitlab-mirror: | + # ssh-keyscan gitlab.com >> ~/.ssh/known_hosts + # git push --quiet --mirror git@gitlab.com:sublime-music/sublime-music.git + + # If we are on the master branch, compile the README.rst to HTML and set it + # as the README for the repo. + - readme: | + set +x + git branch --contains | grep master && + rst2html5 --no-doc-title README.rst | \ + curl -H "Content-Type: text/html" \ + -H "Authorization: Bearer $(cat ~/.readme-token)" \ + -XPUT \ + --data-binary @- \ + "https://git.sr.ht/api/repos/${PROJECT_NAME}/readme" && + echo "README set" || echo "Skipping README set because not on master" diff --git a/.builds/lint-test.yml b/.builds/lint-test.yml new file mode 100644 index 0000000..448e543 --- /dev/null +++ b/.builds/lint-test.yml @@ -0,0 +1,32 @@ +image: archlinux +packages: + - dbus + - python-poetry + - xorg-server-xvfb +sources: + - https://git.sr.ht/~sumner/offlinemsmtp +environment: + REPO_NAME: sublime-music +# triggers: +# - action: email +# condition: failure +# to: ~sumner/sublime-music-devel@lists.sr.ht +tasks: + - setup: | + cd ${REPO_NAME} + poetry install + echo "cd ${REPO_NAME}" >> ~/.buildenv + echo "source $(poetry env info -p)/bin/activate" >> ~/.buildenv + + - lint: | + python setup.py check -mrs + black --check . + flake8 + mypy sublime tests/**/*.py + cicd/custom_style_check.py + + - test: | + ./cicd/start-dbus.sh + Xvfb :119 -screen 0 1024x768x16 & + export DISPLAY=:119 + ./cicd/pytest.sh diff --git a/.builds/pypi.yml b/.builds/pypi.yml new file mode 100644 index 0000000..0784698 --- /dev/null +++ b/.builds/pypi.yml @@ -0,0 +1,27 @@ +image: archlinux +packages: + - python-poetry + - xorg-server-xvfb +sources: + - https://git.sr.ht/~sumner/offlinemsmtp +environment: + REPO_NAME: sublime-music +# triggers: +# - action: email +# condition: failure +# to: ~sumner/sublime-music-devel@lists.sr.ht +tasks: + - setup: | + cd ${REPO_NAME} + poetry install + echo "cd ${REPO_NAME}" >> ~/.buildenv + echo "source $(poetry env info -p)/bin/activate" >> ~/.buildenv + + - build: | + python setup.py sdist + + - deploy_pypi: | + echo "deploy" + + - verify_pypi: | + echo "deploy" diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3a07548 --- /dev/null +++ b/.envrc @@ -0,0 +1,7 @@ +# Run poetry install and activate the virtualenv +poetry install +source .venv/bin/activate + +watch_file pyproject.toml +watch_file poetry.lock +watch_file setup.py diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..2fb72bc --- /dev/null +++ b/poetry.lock @@ -0,0 +1,274 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "black" +version = "20.8b1" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.6,<1" +regex = ">=2020.1.8" +toml = ">=0.10.1" +typed-ast = ">=1.4.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "docutils" +version = "0.16" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "flake8" +version = "3.8.3" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "mypy" +version = "0.782" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +dmypy = ["psutil (>=4.0)"] + +[package.dependencies] +mypy-extensions = ">=0.4.3,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pathspec" +version = "0.8.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyflakes" +version = "2.2.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "regex" +version = "2020.7.14" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "termcolor" +version = "1.1.0" +description = "ANSII Color formatting for output in terminal." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "toml" +version = "0.10.1" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typing-extensions" +version = "3.7.4.3" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + +[metadata] +lock-version = "1.0" +python-versions = "^3.8" +content-hash = "1acb006656d63d11e51c7ad618ac5bada6e9c8fb1f21ed7bd57fba1259a7852e" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +black = [ + {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +docutils = [ + {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, + {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, +] +flake8 = [ + {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, + {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +mypy = [ + {file = "mypy-0.782-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:2c6cde8aa3426c1682d35190b59b71f661237d74b053822ea3d748e2c9578a7c"}, + {file = "mypy-0.782-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c7a9a7ceb2871ba4bac1cf7217a7dd9ccd44c27c2950edbc6dc08530f32ad4e"}, + {file = "mypy-0.782-cp35-cp35m-win_amd64.whl", hash = "sha256:c05b9e4fb1d8a41d41dec8786c94f3b95d3c5f528298d769eb8e73d293abc48d"}, + {file = "mypy-0.782-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:6731603dfe0ce4352c555c6284c6db0dc935b685e9ce2e4cf220abe1e14386fd"}, + {file = "mypy-0.782-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f05644db6779387ccdb468cc47a44b4356fc2ffa9287135d05b70a98dc83b89a"}, + {file = "mypy-0.782-cp36-cp36m-win_amd64.whl", hash = "sha256:b7fbfabdbcc78c4f6fc4712544b9b0d6bf171069c6e0e3cb82440dd10ced3406"}, + {file = "mypy-0.782-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:3fdda71c067d3ddfb21da4b80e2686b71e9e5c72cca65fa216d207a358827f86"}, + {file = "mypy-0.782-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7df6eddb6054d21ca4d3c6249cae5578cb4602951fd2b6ee2f5510ffb098707"}, + {file = "mypy-0.782-cp37-cp37m-win_amd64.whl", hash = "sha256:a4a2cbcfc4cbf45cd126f531dedda8485671545b43107ded25ce952aac6fb308"}, + {file = "mypy-0.782-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6bb93479caa6619d21d6e7160c552c1193f6952f0668cdda2f851156e85186fc"}, + {file = "mypy-0.782-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:81c7908b94239c4010e16642c9102bfc958ab14e36048fa77d0be3289dda76ea"}, + {file = "mypy-0.782-cp38-cp38-win_amd64.whl", hash = "sha256:5dd13ff1f2a97f94540fd37a49e5d255950ebcdf446fb597463a40d0df3fac8b"}, + {file = "mypy-0.782-py3-none-any.whl", hash = "sha256:e0b61738ab504e656d1fe4ff0c0601387a5489ca122d55390ade31f9ca0e252d"}, + {file = "mypy-0.782.tar.gz", hash = "sha256:eff7d4a85e9eea55afa34888dfeaccde99e7520b51f867ac28a48492c0b1130c"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +pathspec = [ + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, +] +regex = [ + {file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"}, + {file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"}, + {file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"}, + {file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"}, + {file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"}, + {file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a"}, + {file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"}, + {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, + {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, +] +termcolor = [ + {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, +] +toml = [ + {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, + {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +typing-extensions = [ + {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, + {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, + {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, +] diff --git a/pyproject.toml b/pyproject.toml index f4b3e4c..39f152c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,24 @@ +[tool.poetry] +name = "sublime-music" +version = "0.11.9" +description = "A native GTK *sonic client." +authors = ["Sumner Evans "] +license = "GPL-3.0-or-later" + +[tool.poetry.dependencies] +python = "^3.8" + +[tool.poetry.dev-dependencies] +black = "^20.8b1" +flake8 = "^3.8.3" +mypy = "^0.782" +termcolor = "^1.1.0" +docutils = "^0.16" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" + [tool.black] exclude = ''' ( diff --git a/sublime/ui/player_controls.py b/sublime/ui/player_controls.py index 7e0dc45..81c9246 100644 --- a/sublime/ui/player_controls.py +++ b/sublime/ui/player_controls.py @@ -211,6 +211,11 @@ class PlayerControls(Gtk.ActionBar): self.current_play_queue = app_config.state.play_queue self.current_playing_index = app_config.state.current_song_index + print("DIFF STORE") + from time import time + + s = time() + # Set the Play Queue button popup. play_queue_len = len(app_config.state.play_queue) if play_queue_len == 0: @@ -279,10 +284,13 @@ class PlayerControls(Gtk.ActionBar): if filename: self.play_queue_store[idx][1] = filename + print("A", time() - s) current_play_queue = [x[-1] for x in self.play_queue_store] if app_config.state.play_queue != current_play_queue: self.play_queue_update_order_token += 1 + print("B", time() - s) + ohea = {1: 0.0, 2: 0.0, 3: 0.0} song_details_results = [] for i, (song_id, cached_status) in enumerate( zip( @@ -290,7 +298,9 @@ class PlayerControls(Gtk.ActionBar): AdapterManager.get_cached_statuses(app_config.state.play_queue), ) ): + f = time() song_details_result = AdapterManager.get_song_details(song_id) + ohea[1] += time() - f cover_art_filename = "" label = "\n" @@ -307,6 +317,7 @@ class PlayerControls(Gtk.ActionBar): cover_art_filename = filename else: song_details_results.append((i, song_details_result)) + ohea[2] += time() - f new_store.append( [ @@ -321,8 +332,16 @@ class PlayerControls(Gtk.ActionBar): song_id, ] ) + ohea[3] += time() - f + print( + "ohea", + ohea, + list(map(lambda x: x / len(app_config.state.play_queue), ohea.values())), + ) + print("C", time() - s) util.diff_song_store(self.play_queue_store, new_store) + print("FOO", time() - s) # Do this after the diff to avoid race conditions. for idx, song_details_result in song_details_results: From 62652819558d8135bdc61605e6bbd57a1f2fe45e Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 00:01:36 -0600 Subject: [PATCH 2/8] Fix linter errors --- .builds/flatpak.yml | 6 +- .builds/gitlab-mirror-and-readme.yml | 6 +- .builds/pypi.yml | 15 ++-- cicd/run_if_tagged_with_version | 27 +++++++ setup.cfg | 3 + sublime/adapters/adapter_base.py | 4 +- sublime/adapters/api_objects.py | 4 +- sublime/adapters/configure_server_form.py | 8 +- sublime/adapters/filesystem/adapter.py | 27 ++++--- .../adapters/filesystem/sqlite_extensions.py | 5 +- sublime/adapters/manager.py | 28 ++++--- sublime/adapters/subsonic/adapter.py | 11 ++- sublime/app.py | 32 +++++--- sublime/config.py | 4 +- sublime/dbus/manager.py | 14 +++- sublime/players/manager.py | 3 +- sublime/ui/albums.py | 35 +++++--- sublime/ui/artists.py | 31 +++++--- sublime/ui/browse.py | 27 ++++--- sublime/ui/common/album_with_songs.py | 11 ++- sublime/ui/common/spinner_image.py | 2 +- sublime/ui/main.py | 43 ++++++---- sublime/ui/player_controls.py | 38 +++++---- sublime/ui/playlists.py | 23 ++++-- sublime/ui/state.py | 4 +- sublime/ui/util.py | 10 ++- tests/adapter_tests/adapter_manager_tests.py | 3 +- .../adapter_tests/filesystem_adapter_tests.py | 79 +++++++++++++------ tests/common_ui_tests.py | 5 +- 29 files changed, 346 insertions(+), 162 deletions(-) create mode 100755 cicd/run_if_tagged_with_version diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml index 1af5d20..d4a3aa4 100644 --- a/.builds/flatpak.yml +++ b/.builds/flatpak.yml @@ -12,10 +12,8 @@ environment: # to: ~sumner/sublime-music-devel@lists.sr.ht tasks: - setup: | - cd ${REPO_NAME} - poetry install - echo "cd ${REPO_NAME}" >> ~/.buildenv + pip install requirements-parser - build-flatpak: | - cd flatpak + cd ${REPO_NAME}/flatpak ./flatpak_build.sh diff --git a/.builds/gitlab-mirror-and-readme.yml b/.builds/gitlab-mirror-and-readme.yml index 5575f58..2d3d130 100644 --- a/.builds/gitlab-mirror-and-readme.yml +++ b/.builds/gitlab-mirror-and-readme.yml @@ -1,8 +1,9 @@ -image: archlinux +image: alpine/edge packages: - curl + - git - openssh - - python-docutils + - py3-docutils sources: - https://git.sr.ht/~sumner/offlinemsmtp secrets: @@ -21,7 +22,6 @@ tasks: cd ${REPO_NAME} echo "cd ${REPO_NAME}" >> ~/.buildenv - # TODO # - gitlab-mirror: | # ssh-keyscan gitlab.com >> ~/.ssh/known_hosts # git push --quiet --mirror git@gitlab.com:sublime-music/sublime-music.git diff --git a/.builds/pypi.yml b/.builds/pypi.yml index 0784698..04adcab 100644 --- a/.builds/pypi.yml +++ b/.builds/pypi.yml @@ -1,6 +1,6 @@ image: archlinux packages: - - python-poetry + - python - xorg-server-xvfb sources: - https://git.sr.ht/~sumner/offlinemsmtp @@ -13,15 +13,16 @@ environment: tasks: - setup: | cd ${REPO_NAME} - poetry install echo "cd ${REPO_NAME}" >> ~/.buildenv - echo "source $(poetry env info -p)/bin/activate" >> ~/.buildenv - build: | python setup.py sdist - - deploy_pypi: | - echo "deploy" + - deploy-pypi: | + ./cicd/run_if_tagged_with_version \ + "twine upload -r testpypi dist/*" \ + "twine upload dist/*" - - verify_pypi: | - echo "deploy" + - verify-pypi: | + ./cicd/run_if_tagged_with_version \ + "pip install ${REPO_NAME}" diff --git a/cicd/run_if_tagged_with_version b/cicd/run_if_tagged_with_version new file mode 100755 index 0000000..e6a91d0 --- /dev/null +++ b/cicd/run_if_tagged_with_version @@ -0,0 +1,27 @@ +#! /usr/bin/env python + +import re +import subprocess +import sys + +version_tag_re = re.compile(r"v\d+\.\d+\.\d+") + + +tags = ( + subprocess.run(["git", "tag", "--contains", "HEAD"], capture_output=True) + .stdout.decode() + .strip() + .split() +) + +# If one of the tags is a version tag, then run the commands specified in the +# parameters. +for tag in tags: + if match := version_tag_re.match(tag): + print(f"VERSION TAG {tag} FOUND") + + # Execute the associated commands, raising an exception if the command + # returns a non-zero value. + for arg in sys.argv[1:]: + print(f"+ {' '.join(arg.split())}") + subprocess.run(arg.split()).check_returncode() diff --git a/setup.cfg b/setup.cfg index f1f20b4..b873664 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,6 +10,9 @@ import-order-style = edited [mypy-bottle] ignore_missing_imports = True +[mypy-dataclasses_json] +ignore_missing_imports = True + [mypy-deepdiff] ignore_missing_imports = True diff --git a/sublime/adapters/adapter_base.py b/sublime/adapters/adapter_base.py index e97b10d..c563ba1 100644 --- a/sublime/adapters/adapter_base.py +++ b/sublime/adapters/adapter_base.py @@ -574,7 +574,7 @@ class Adapter(abc.ABC): """ raise self._check_can_error("get_playlists") - def get_playlist_details(self, playlist_id: str,) -> Playlist: + def get_playlist_details(self, playlist_id: str) -> Playlist: """ Get the details for the given ``playlist_id``. If the playlist_id does not exist, then this function should throw an exception. @@ -586,7 +586,7 @@ class Adapter(abc.ABC): raise self._check_can_error("get_playlist_details") def create_playlist( - self, name: str, songs: Sequence[Song] = None, + self, name: str, songs: Sequence[Song] = None ) -> Optional[Playlist]: """ Creates a playlist of the given name with the given songs. diff --git a/sublime/adapters/api_objects.py b/sublime/adapters/api_objects.py index c4cf629..d6c9730 100644 --- a/sublime/adapters/api_objects.py +++ b/sublime/adapters/api_objects.py @@ -178,7 +178,9 @@ class SearchResult: _S = TypeVar("_S") def _to_result( - self, it: Dict[str, _S], transform: Callable[[_S], Tuple[Optional[str], ...]], + self, + it: Dict[str, _S], + transform: Callable[[_S], Tuple[Optional[str], ...]], ) -> List[_S]: assert self.query all_results = [] diff --git a/sublime/adapters/configure_server_form.py b/sublime/adapters/configure_server_form.py index 1a9409b..a6b980f 100644 --- a/sublime/adapters/configure_server_form.py +++ b/sublime/adapters/configure_server_form.py @@ -111,7 +111,10 @@ class ConfigureServerForm(Gtk.Box): self.is_networked = is_networked content_grid = Gtk.Grid( - column_spacing=10, row_spacing=5, margin_left=10, margin_right=10, + column_spacing=10, + row_spacing=5, + margin_left=10, + margin_right=10, ) advanced_grid = Gtk.Grid(column_spacing=10, row_spacing=10) @@ -175,7 +178,8 @@ class ConfigureServerForm(Gtk.Box): if cpd.helptext: help_icon = Gtk.Image.new_from_icon_name( - "help-about", Gtk.IconSize.BUTTON, + "help-about", + Gtk.IconSize.BUTTON, ) help_icon.get_style_context().add_class("configure-form-help-icon") help_icon.set_tooltip_markup(cpd.helptext) diff --git a/sublime/adapters/filesystem/adapter.py b/sublime/adapters/filesystem/adapter.py index 26fb629..c8eb381 100644 --- a/sublime/adapters/filesystem/adapter.py +++ b/sublime/adapters/filesystem/adapter.py @@ -60,9 +60,7 @@ class FilesystemAdapter(CachingAdapter): def migrate_configuration(config_store: ConfigurationStore): pass - def __init__( - self, config: dict, data_directory: Path, is_cache: bool = False, - ): + def __init__(self, config: dict, data_directory: Path, is_cache: bool = False): self.data_directory = data_directory self.cover_art_dir = self.data_directory.joinpath("cover_art") self.music_dir = self.data_directory.joinpath("music") @@ -311,7 +309,9 @@ class FilesystemAdapter(CachingAdapter): def get_song_details(self, song_id: str) -> models.Song: return self._get_object_details( - models.Song, song_id, CachingAdapter.CachedDataKey.SONG, + models.Song, + song_id, + CachingAdapter.CachedDataKey.SONG, ) def get_artists(self, ignore_cache_miss: bool = False) -> Sequence[API.Artist]: @@ -429,7 +429,8 @@ class FilesystemAdapter(CachingAdapter): ), ) search_result.add_results( - "playlists", self.get_playlists(ignore_cache_miss=True), + "playlists", + self.get_playlists(ignore_cache_miss=True), ) return search_result @@ -439,7 +440,10 @@ class FilesystemAdapter(CachingAdapter): return hashlib.sha1(bytes(string, "utf8")).hexdigest() def ingest_new_data( - self, data_key: CachingAdapter.CachedDataKey, param: Optional[str], data: Any, + self, + data_key: CachingAdapter.CachedDataKey, + param: Optional[str], + data: Any, ): assert self.is_cache, "FilesystemAdapter is not in cache mode!" @@ -809,7 +813,9 @@ class FilesystemAdapter(CachingAdapter): ) song_data["_cover_art"] = ( self._do_ingest_new_data( - KEYS.COVER_ART_FILE, api_song.cover_art, data=None, + KEYS.COVER_ART_FILE, + api_song.cover_art, + data=None, ) if api_song.cover_art else None @@ -863,7 +869,9 @@ class FilesystemAdapter(CachingAdapter): return return_val if return_val is not None else cache_info def _do_invalidate_data( - self, data_key: CachingAdapter.CachedDataKey, param: Optional[str], + self, + data_key: CachingAdapter.CachedDataKey, + param: Optional[str], ): logging.debug(f"_do_invalidate_data param={param} data_key={data_key}") models.CacheInfo.update({"valid": False}).where( @@ -899,7 +907,8 @@ class FilesystemAdapter(CachingAdapter): ): logging.debug(f"_do_delete_data param={param} data_key={data_key}") cache_info = models.CacheInfo.get_or_none( - models.CacheInfo.cache_key == data_key, models.CacheInfo.parameter == param, + models.CacheInfo.cache_key == data_key, + models.CacheInfo.parameter == param, ) if data_key == KEYS.COVER_ART_FILE: diff --git a/sublime/adapters/filesystem/sqlite_extensions.py b/sublime/adapters/filesystem/sqlite_extensions.py index 585fb78..23954c6 100644 --- a/sublime/adapters/filesystem/sqlite_extensions.py +++ b/sublime/adapters/filesystem/sqlite_extensions.py @@ -70,7 +70,10 @@ class SortedManyToManyQuery(ManyToManyQuery): class SortedManyToManyFieldAccessor(ManyToManyFieldAccessor): def __get__( - self, instance: Model, instance_type: Any = None, force_query: bool = False, + self, + instance: Model, + instance_type: Any = None, + force_query: bool = False, ): if instance is not None: if not force_query and self.src_fk.backref != "+": diff --git a/sublime/adapters/manager.py b/sublime/adapters/manager.py index ec67e70..5ec6969 100644 --- a/sublime/adapters/manager.py +++ b/sublime/adapters/manager.py @@ -493,7 +493,8 @@ class AdapterManager: # Everything succeeded. if expected_size_exists: AdapterManager._instance.song_download_progress( - id, DownloadProgress(DownloadProgress.Type.DONE), + id, + DownloadProgress(DownloadProgress.Type.DONE), ) except Exception as e: if expected_size_exists and not download_cancelled: @@ -872,7 +873,9 @@ class AdapterManager: # Create a download result. future = AdapterManager._create_download_result( AdapterManager._instance.ground_truth_adapter.get_cover_art_uri( - cover_art_id, AdapterManager._get_networked_scheme(), size=size, + cover_art_id, + AdapterManager._get_networked_scheme(), + size=size, ), cover_art_id, before_download, @@ -963,7 +966,8 @@ class AdapterManager: ): AdapterManager._instance.download_limiter_semaphore.release() AdapterManager._instance.song_download_progress( - song_id, DownloadProgress(DownloadProgress.Type.CANCELLED), + song_id, + DownloadProgress(DownloadProgress.Type.CANCELLED), ) return Result("", is_download=True) @@ -977,7 +981,8 @@ class AdapterManager: ) AdapterManager._instance.download_limiter_semaphore.release() AdapterManager._instance.song_download_progress( - song_id, DownloadProgress(DownloadProgress.Type.DONE), + song_id, + DownloadProgress(DownloadProgress.Type.DONE), ) return Result("", is_download=True) except CacheMissError: @@ -1033,7 +1038,8 @@ class AdapterManager: for song_id in song_ids: # Everything succeeded. AdapterManager._instance.song_download_progress( - song_id, DownloadProgress(DownloadProgress.Type.QUEUED), + song_id, + DownloadProgress(DownloadProgress.Type.QUEUED), ) for song_id in song_ids: @@ -1057,7 +1063,8 @@ class AdapterManager: # Alert the UI that the downloads are cancelled. for song_id in song_ids: AdapterManager._instance.song_download_progress( - song_id, DownloadProgress(DownloadProgress.Type.CANCELLED), + song_id, + DownloadProgress(DownloadProgress.Type.CANCELLED), ) return Result(do_batch_download_songs, is_download=True, on_cancel=on_cancel) @@ -1070,7 +1077,8 @@ class AdapterManager: ) for song_id in song_ids: AdapterManager._instance.song_download_progress( - song_id, DownloadProgress(DownloadProgress.Type.CANCELLED), + song_id, + DownloadProgress(DownloadProgress.Type.CANCELLED), ) if AdapterManager._song_download_jobs.get(song_id): AdapterManager._song_download_jobs[song_id].cancel() @@ -1360,8 +1368,10 @@ class AdapterManager: return True try: - ground_truth_search_results = AdapterManager._instance.ground_truth_adapter.search( # noqa: E501 - query + ground_truth_search_results = ( + AdapterManager._instance.ground_truth_adapter.search( # noqa: E501 + query + ) ) search_result.update(ground_truth_search_results) search_callback(search_result) diff --git a/sublime/adapters/subsonic/adapter.py b/sublime/adapters/subsonic/adapter.py index 7183053..ccda4ed 100644 --- a/sublime/adapters/subsonic/adapter.py +++ b/sublime/adapters/subsonic/adapter.py @@ -261,7 +261,9 @@ class SubsonicAdapter(Adapter): # Try to ping the server. self._get_json( - self._make_url("ping"), timeout=timeout, is_exponential_backoff_ping=True, + self._make_url("ping"), + timeout=timeout, + is_exponential_backoff_ping=True, ) def on_offline_mode_change(self, offline_mode: bool): @@ -388,7 +390,10 @@ class SubsonicAdapter(Adapter): result = self._get_mock_data() else: result = requests.get( - url, params=params, verify=self.verify_cert, timeout=timeout, + url, + params=params, + verify=self.verify_cert, + timeout=timeout, ) if result.status_code != 200: @@ -490,7 +495,7 @@ class SubsonicAdapter(Adapter): return result def create_playlist( - self, name: str, songs: Sequence[API.Song] = None, + self, name: str, songs: Sequence[API.Song] = None ) -> Optional[API.Playlist]: return self._get_json( self._make_url("createPlaylist"), diff --git a/sublime/app.py b/sublime/app.py index bd47432..d4e9e10 100644 --- a/sublime/app.py +++ b/sublime/app.py @@ -107,7 +107,8 @@ class SublimeMusicApp(Gtk.Application): add_action("go-online", self.on_go_online) add_action("refresh-devices", self.on_refresh_devices) add_action( - "refresh-window", lambda *a: self.on_refresh_window(None, {}, True), + "refresh-window", + lambda *a: self.on_refresh_window(None, {}, True), ) add_action("mute-toggle", self.on_mute_toggle) add_action( @@ -413,7 +414,8 @@ class SublimeMusicApp(Gtk.Application): # repeat song IDs. metadatas: Iterable[Any] = [ self.dbus_manager.get_mpris_metadata( - i, self.app_config.state.play_queue, + i, + self.app_config.state.play_queue, ) for i in range(len(self.app_config.state.play_queue)) ] @@ -457,7 +459,10 @@ class SublimeMusicApp(Gtk.Application): ) def get_playlists( - index: int, max_count: int, order: str, reverse_order: bool, + index: int, + max_count: int, + order: str, + reverse_order: bool, ) -> GLib.Variant: playlists_result = AdapterManager.get_playlists() if not playlists_result.data_is_available: @@ -473,12 +478,15 @@ class SublimeMusicApp(Gtk.Application): "Modified": lambda p: p.changed, } playlists.sort( - key=sorters.get(order, lambda p: p), reverse=reverse_order, + key=sorters.get(order, lambda p: p), + reverse=reverse_order, ) def make_playlist_tuple(p: Playlist) -> GLib.Variant: cover_art_filename = AdapterManager.get_cover_art_uri( - p.cover_art, "file", allow_download=False, + p.cover_art, + "file", + allow_download=False, ).result() return (f"/playlist/{p.id}", p.name, cover_art_filename or "") @@ -570,9 +578,7 @@ class SublimeMusicApp(Gtk.Application): # ########## ACTION HANDLERS ########## # @dbus_propagate() - def on_refresh_window( - self, _, state_updates: Dict[str, Any], force: bool = False, - ): + def on_refresh_window(self, _, state_updates: Dict[str, Any], force: bool = False): if settings := state_updates.get("__settings__"): for k, v in settings.items(): setattr(self.app_config, k, v) @@ -879,9 +885,7 @@ class SublimeMusicApp(Gtk.Application): return self.app_config.state.current_song_index -= len(before_current) - self.play_song( - self.app_config.state.current_song_index, reset=True, - ) + self.play_song(self.app_config.state.current_song_index, reset=True) else: self.app_config.state.current_song_index -= len(before_current) self.update_window() @@ -1001,7 +1005,8 @@ class SublimeMusicApp(Gtk.Application): # ########## HELPER METHODS ########## # def show_configure_servers_dialog( - self, provider_config: Optional[ProviderConfiguration] = None, + self, + provider_config: Optional[ProviderConfiguration] = None, ): """Show the Connect to Server dialog.""" dialog = ConfigureProviderDialog(self.window, provider_config) @@ -1192,7 +1197,8 @@ class SublimeMusicApp(Gtk.Application): if artist := song.artist: notification_lines.append(bleach.clean(artist.name)) song_notification = Notify.Notification.new( - song.title, "\n".join(notification_lines), + song.title, + "\n".join(notification_lines), ) song_notification.add_action( "clicked", diff --git a/sublime/config.py b/sublime/config.py index 6c37680..8755a09 100644 --- a/sublime/config.py +++ b/sublime/config.py @@ -18,9 +18,7 @@ def encode_path(path: Path) -> str: dataclasses_json.cfg.global_config.decoders[Path] = Path -dataclasses_json.cfg.global_config.decoders[ - Optional[Path] # type: ignore -] = ( +dataclasses_json.cfg.global_config.decoders[Optional[Path]] = ( # type: ignore lambda p: Path(p) if p else None ) diff --git a/sublime/dbus/manager.py b/sublime/dbus/manager.py index c61633e..50d85d6 100644 --- a/sublime/dbus/manager.py +++ b/sublime/dbus/manager.py @@ -137,7 +137,13 @@ class DBusManager: return self.do_on_method_call( - connection, sender, path, interface, method, params, invocation, + connection, + sender, + path, + interface, + method, + params, + invocation, ) @staticmethod @@ -153,7 +159,8 @@ class DBusManager: if type(value) == dict: return GLib.Variant( - "a{sv}", {k: DBusManager.to_variant(v) for k, v in value.items()}, + "a{sv}", + {k: DBusManager.to_variant(v) for k, v in value.items()}, ) variant_type = {list: "as", str: "s", int: "i", float: "d", bool: "b"}.get( @@ -230,7 +237,8 @@ class DBusManager: "Rate": 1.0, "Shuffle": state.shuffle_on, "Metadata": self.get_mpris_metadata( - state.current_song_index, state.play_queue, + state.current_song_index, + state.play_queue, ) if state.current_song else {}, diff --git a/sublime/players/manager.py b/sublime/players/manager.py index b9fbc59..517b4cd 100644 --- a/sublime/players/manager.py +++ b/sublime/players/manager.py @@ -67,7 +67,8 @@ class PlayerManager: } def change_settings( - self, config: Dict[str, Dict[str, Union[Type, Tuple[str, ...]]]], + self, + config: Dict[str, Dict[str, Union[Type, Tuple[str, ...]]]], ): self.config = config for player_type, player in self.players.items(): diff --git a/sublime/ui/albums.py b/sublime/ui/albums.py index 450130e..8a23fdc 100644 --- a/sublime/ui/albums.py +++ b/sublime/ui/albums.py @@ -164,10 +164,12 @@ class AlbumsPanel(Gtk.Box): scrolled_window = Gtk.ScrolledWindow() self.grid = AlbumsGrid() self.grid.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.grid.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) self.grid.connect("cover-clicked", self.on_grid_cover_clicked) self.grid.connect("num-pages-changed", self.on_grid_num_pages_changed) @@ -195,7 +197,9 @@ class AlbumsPanel(Gtk.Box): return combo, store def populate_genre_combo( - self, app_config: AppConfiguration = None, force: bool = False, + self, + app_config: AppConfiguration = None, + force: bool = False, ): if not AdapterManager.can_get_genres(): self.updating_query = False @@ -464,13 +468,17 @@ class AlbumsPanel(Gtk.Box): def on_grid_cover_clicked(self, grid: Any, id: str): self.emit( - "refresh-window", {"selected_album_id": id}, False, + "refresh-window", + {"selected_album_id": id}, + False, ) def on_show_count_dropdown_change(self, combo: Gtk.ComboBox): show_count = int(self.get_id(combo) or 30) self.emit( - "refresh-window", {"album_page_size": show_count, "album_page": 0}, False, + "refresh-window", + {"album_page_size": show_count, "album_page": 0}, + False, ) def emit_if_not_updating(self, *args): @@ -483,7 +491,7 @@ class AlbumsGrid(Gtk.Overlay): """Defines the albums panel.""" __gsignals__ = { - "cover-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,),), + "cover-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,)), "refresh-window": ( GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, @@ -789,9 +797,7 @@ class AlbumsGrid(Gtk.Overlay): new_items_per_row = min((rect.width // 230), 7) if new_items_per_row != self.items_per_row: self.items_per_row = new_items_per_row - self.detail_box_inner.set_size_request( - self.items_per_row * 230 - 10, -1, - ) + self.detail_box_inner.set_size_request(self.items_per_row * 230 - 10, -1) self.reflow_grids( force_reload_from_master=True, @@ -899,10 +905,14 @@ class AlbumsGrid(Gtk.Overlay): # Just remove everything and re-add all of the items. It's not worth trying # to diff in this case. self.list_store_top.splice( - 0, len(self.list_store_top), window[:entries_before_fold], + 0, + len(self.list_store_top), + window[:entries_before_fold], ) self.list_store_bottom.splice( - 0, len(self.list_store_bottom), window[entries_before_fold:], + 0, + len(self.list_store_bottom), + window[entries_before_fold:], ) elif selected_index or entries_before_fold != self.page_size: # This case handles when the selection changes and the entries need to be @@ -940,7 +950,8 @@ class AlbumsGrid(Gtk.Overlay): model = self.list_store_top[relative_selected_index] detail_element = AlbumWithSongs(model.album, cover_art_size=300) detail_element.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) detail_element.connect("song-selected", lambda *a: None) diff --git a/sublime/ui/artists.py b/sublime/ui/artists.py index 37430c1..0ba7587 100644 --- a/sublime/ui/artists.py +++ b/sublime/ui/artists.py @@ -40,10 +40,12 @@ class ArtistsPanel(Gtk.Paned): self.artist_detail_panel = ArtistDetailPanel() self.artist_detail_panel.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.artist_detail_panel.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) self.pack2(self.artist_detail_panel, True, False) @@ -315,7 +317,8 @@ class ArtistDetailPanel(Gtk.Box): self.album_list_scrolledwindow = Gtk.ScrolledWindow() self.albums_list = AlbumsListWithSongs() self.albums_list.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.album_list_scrolledwindow.add(self.albums_list) self.pack_start(self.album_list_scrolledwindow, True, True, 0) @@ -408,7 +411,9 @@ class ArtistDetailPanel(Gtk.Box): self.play_shuffle_buttons.show_all() self.update_artist_artwork( - artist.artist_image_url, force=force, order_token=order_token, + artist.artist_image_url, + force=force, + order_token=order_token, ) for c in self.error_container.get_children(): @@ -489,24 +494,31 @@ class ArtistDetailPanel(Gtk.Box): # ========================================================================= def on_view_refresh_click(self, *args): self.update_artist_view( - self.artist_id, force=True, order_token=self.update_order_token, + self.artist_id, + force=True, + order_token=self.update_order_token, ) def on_download_all_click(self, _): AdapterManager.batch_download_songs( self.get_artist_song_ids(), before_download=lambda _: self.update_artist_view( - self.artist_id, order_token=self.update_order_token, + self.artist_id, + order_token=self.update_order_token, ), on_song_download_complete=lambda _: self.update_artist_view( - self.artist_id, order_token=self.update_order_token, + self.artist_id, + order_token=self.update_order_token, ), ) def on_play_all_clicked(self, _): songs = self.get_artist_song_ids() self.emit( - "song-clicked", 0, songs, {"force_shuffle_state": False}, + "song-clicked", + 0, + songs, + {"force_shuffle_state": False}, ) def on_shuffle_all_button(self, _): @@ -633,7 +645,8 @@ class AlbumsListWithSongs(Gtk.Overlay): for album in self.albums: album_with_songs = AlbumWithSongs(album, show_artist_name=False) album_with_songs.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) album_with_songs.connect("song-selected", self.on_song_selected) album_with_songs.show_all() diff --git a/sublime/ui/browse.py b/sublime/ui/browse.py index 3c347a2..098b4d6 100644 --- a/sublime/ui/browse.py +++ b/sublime/ui/browse.py @@ -37,10 +37,12 @@ class BrowsePanel(Gtk.Overlay): self.root_directory_listing = ListAndDrilldown() self.root_directory_listing.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.root_directory_listing.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) window_box.add(self.root_directory_listing) @@ -88,7 +90,8 @@ class BrowsePanel(Gtk.Overlay): while current_dir_id: try: directory = AdapterManager.get_directory( - current_dir_id, before_download=self.spinner.show, + current_dir_id, + before_download=self.spinner.show, ).result() except CacheMissError as e: directory = cast(API.Directory, e.partial_data) @@ -128,10 +131,12 @@ class ListAndDrilldown(Gtk.Paned): self.list = MusicDirectoryList() self.list.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.list.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) self.pack1(self.list, False, False) @@ -163,7 +168,8 @@ class ListAndDrilldown(Gtk.Paned): if len(children) == 0: drilldown = ListAndDrilldown() drilldown.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) drilldown.connect( "refresh-window", @@ -277,7 +283,9 @@ class MusicDirectoryList(Gtk.Box): self.directory_id = directory_id or self.directory_id self.selected_id = selected_id or self.selected_id self.update_store( - self.directory_id, force=force, order_token=self.update_order_token, + self.directory_id, + force=force, + order_token=self.update_order_token, ) if app_config: @@ -428,7 +436,8 @@ class MusicDirectoryList(Gtk.Box): # ================================================================================== def create_row(self, model: DrilldownElement) -> Gtk.ListBoxRow: row = Gtk.ListBoxRow( - action_name="app.browse-to", action_target=GLib.Variant("s", model.id), + action_name="app.browse-to", + action_target=GLib.Variant("s", model.id), ) rowbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) rowbox.add( @@ -461,7 +470,7 @@ class MusicDirectoryList(Gtk.Box): {}, ) - def on_song_button_press(self, tree: Gtk.TreeView, event: Gdk.EventButton,) -> bool: + def on_song_button_press(self, tree: Gtk.TreeView, event: Gdk.EventButton) -> bool: if event.button == 3: # Right click clicked_path = tree.get_path_at_pos(event.x, event.y) if not clicked_path: diff --git a/sublime/ui/common/album_with_songs.py b/sublime/ui/common/album_with_songs.py index 6c24cca..b8a566e 100644 --- a/sublime/ui/common/album_with_songs.py +++ b/sublime/ui/common/album_with_songs.py @@ -15,7 +15,7 @@ from .spinner_image import SpinnerImage class AlbumWithSongs(Gtk.Box): __gsignals__ = { - "song-selected": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (),), + "song-selected": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()), "song-clicked": ( GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, @@ -122,7 +122,9 @@ class AlbumWithSongs(Gtk.Box): album_details.add( Gtk.Label( - label=util.dot_join(*stats), halign=Gtk.Align.START, margin_left=10, + label=util.dot_join(*stats), + halign=Gtk.Align.START, + margin_left=10, ) ) @@ -235,7 +237,10 @@ class AlbumWithSongs(Gtk.Box): def play_btn_clicked(self, btn: Any): song_ids = [x[-1] for x in self.album_song_store] self.emit( - "song-clicked", 0, song_ids, {"force_shuffle_state": False}, + "song-clicked", + 0, + song_ids, + {"force_shuffle_state": False}, ) def shuffle_btn_clicked(self, btn: Any): diff --git a/sublime/ui/common/spinner_image.py b/sublime/ui/common/spinner_image.py index 89dfc16..35c9658 100644 --- a/sublime/ui/common/spinner_image.py +++ b/sublime/ui/common/spinner_image.py @@ -35,7 +35,7 @@ class SpinnerImage(Gtk.Overlay): self.filename = filename if self.image_size is not None and filename: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( - filename, self.image_size, self.image_size, True, + filename, self.image_size, self.image_size, True ) self.image.set_from_pixbuf(pixbuf) else: diff --git a/sublime/ui/main.py b/sublime/ui/main.py index 701024e..bb2b469 100644 --- a/sublime/ui/main.py +++ b/sublime/ui/main.py @@ -24,14 +24,14 @@ class MainWindow(Gtk.ApplicationWindow): GObject.TYPE_NONE, (int, object, object), ), - "songs-removed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,),), + "songs-removed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,)), "refresh-window": ( GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object, bool), ), - "notification-closed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (),), - "go-to": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str, str),), + "notification-closed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()), + "go-to": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str, str)), } _updating_settings: bool = False @@ -100,7 +100,8 @@ class MainWindow(Gtk.ApplicationWindow): "songs-removed", lambda _, *a: self.emit("songs-removed", *a) ) self.player_controls.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) flowbox.pack_start(self.player_controls, False, True, 0) @@ -167,7 +168,8 @@ class MainWindow(Gtk.ApplicationWindow): f"{icon_basename}-{icon_status}-symbolic" ) self.connection_status_icon.set_from_icon_name( - f"server-{icon_status}-symbolic", Gtk.IconSize.BUTTON, + f"server-{icon_status}-symbolic", + Gtk.IconSize.BUTTON, ) self.connection_status_label.set_text(status_label) self.connected_status_box.show_all() @@ -194,7 +196,10 @@ class MainWindow(Gtk.ApplicationWindow): for provider in sorted(other_providers, key=lambda p: p.name.lower()): self.provider_options_box.pack_start( - self._create_switch_provider_button(provider), False, True, 0, + self._create_switch_provider_button(provider), + False, + True, + 0, ) self.provider_options_box.show_all() @@ -489,17 +494,21 @@ class MainWindow(Gtk.ApplicationWindow): def _on_retry_all_clicked(self, _): AdapterManager.batch_download_songs( - self._failed_downloads, lambda _: None, lambda _: None, + self._failed_downloads, + lambda _: None, + lambda _: None, ) def _create_stack(self, **kwargs: Gtk.Widget) -> Gtk.Stack: stack = Gtk.Stack() for name, child in kwargs.items(): child.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) child.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) stack.add_titled(child, name.lower(), name) return stack @@ -671,7 +680,8 @@ class MainWindow(Gtk.ApplicationWindow): current_downloads_header = Gtk.Box() current_downloads_header.add( current_downloads_label := Gtk.Label( - label="Current Downloads", name="menu-header", + label="Current Downloads", + name="menu-header", ) ) current_downloads_label.get_style_context().add_class("menu-label") @@ -767,7 +777,8 @@ class MainWindow(Gtk.ApplicationWindow): vbox.add(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)) music_provider_button = self._create_model_button( - "Switch Music Provider", menu_name="switch-provider", + "Switch Music Provider", + menu_name="switch-provider", ) vbox.add(music_provider_button) @@ -858,7 +869,8 @@ class MainWindow(Gtk.ApplicationWindow): self.search_popup = Gtk.PopoverMenu(modal=False) results_scrollbox = Gtk.ScrolledWindow( - min_content_width=500, min_content_height=700, + min_content_width=500, + min_content_height=700, ) def make_search_result_header(text: str) -> Gtk.Label: @@ -867,7 +879,8 @@ class MainWindow(Gtk.ApplicationWindow): return label search_results_box = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, name="search-results", + orientation=Gtk.Orientation.VERTICAL, + name="search-results", ) self.search_results_loading = Gtk.Spinner(active=False, name="search-spinner") search_results_box.add(self.search_results_loading) @@ -1155,8 +1168,8 @@ class MainWindow(Gtk.ApplicationWindow): class DownloadStatusBox(Gtk.Box): __gsignals__ = { - "cancel-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,),), - "retry-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,),), + "cancel-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,)), + "retry-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,)), } def __init__(self, song_id: str): diff --git a/sublime/ui/player_controls.py b/sublime/ui/player_controls.py index 81c9246..ad42383 100644 --- a/sublime/ui/player_controls.py +++ b/sublime/ui/player_controls.py @@ -21,15 +21,15 @@ class PlayerControls(Gtk.ActionBar): """ __gsignals__ = { - "song-scrub": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (float,),), - "volume-change": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (float,),), - "device-update": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,),), + "song-scrub": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (float,)), + "volume-change": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (float,)), + "device-update": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (str,)), "song-clicked": ( GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (int, object, object), ), - "songs-removed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,),), + "songs-removed": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (object,)), "refresh-window": ( GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, @@ -242,12 +242,16 @@ class PlayerControls(Gtk.ActionBar): return f"{title}\n{util.dot_join(album, artist)}" def make_idle_index_capturing_function( - idx: int, order_tok: int, fn: Callable[[int, int, Any], None], + idx: int, + order_tok: int, + fn: Callable[[int, int, Any], None], ) -> Callable[[Result], None]: return lambda f: GLib.idle_add(fn, idx, order_tok, f.result()) def on_cover_art_future_done( - idx: int, order_token: int, cover_art_filename: str, + idx: int, + order_token: int, + cover_art_filename: str, ): if order_token != self.play_queue_update_order_token: return @@ -269,9 +273,7 @@ class PlayerControls(Gtk.ActionBar): # The cover art is already cached. return cover_art_result.result() - def on_song_details_future_done( - idx: int, order_token: int, song_details: Song, - ): + def on_song_details_future_done(idx: int, order_token: int, song_details: Song): if order_token != self.play_queue_update_order_token: return @@ -559,7 +561,8 @@ class PlayerControls(Gtk.ActionBar): box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.album_art = SpinnerImage( - image_name="player-controls-album-artwork", image_size=70, + image_name="player-controls-album-artwork", + image_size=70, ) box.pack_start(self.album_art, False, False, 0) @@ -691,12 +694,16 @@ class PlayerControls(Gtk.ActionBar): self.device_popover.set_relative_to(self.device_button) device_popover_box = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, name="device-popover-box", + orientation=Gtk.Orientation.VERTICAL, + name="device-popover-box", ) device_popover_header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.popover_label = Gtk.Label( - label="Devices", use_markup=True, halign=Gtk.Align.START, margin=5, + label="Devices", + use_markup=True, + halign=Gtk.Align.START, + margin=5, ) device_popover_header.add(self.popover_label) @@ -748,7 +755,8 @@ class PlayerControls(Gtk.ActionBar): play_queue_loading_overlay = Gtk.Overlay() play_queue_scrollbox = Gtk.ScrolledWindow( - min_content_height=600, min_content_width=400, + min_content_height=600, + min_content_width=400, ) self.play_queue_store = Gtk.ListStore( @@ -759,7 +767,9 @@ class PlayerControls(Gtk.ActionBar): str, # song ID ) self.play_queue_list = Gtk.TreeView( - model=self.play_queue_store, reorderable=True, headers_visible=False, + model=self.play_queue_store, + reorderable=True, + headers_visible=False, ) selection = self.play_queue_list.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) diff --git a/sublime/ui/playlists.py b/sublime/ui/playlists.py index d8c985a..a7dfc8e 100644 --- a/sublime/ui/playlists.py +++ b/sublime/ui/playlists.py @@ -104,10 +104,12 @@ class PlaylistsPanel(Gtk.Paned): self.playlist_detail_panel = PlaylistDetailPanel() self.playlist_detail_panel.connect( - "song-clicked", lambda _, *args: self.emit("song-clicked", *args), + "song-clicked", + lambda _, *args: self.emit("song-clicked", *args), ) self.playlist_detail_panel.connect( - "refresh-window", lambda _, *args: self.emit("refresh-window", *args), + "refresh-window", + lambda _, *args: self.emit("refresh-window", *args), ) self.pack2(self.playlist_detail_panel, True, False) @@ -158,7 +160,7 @@ class PlaylistList(Gtk.Box): loading_new_playlist = Gtk.ListBox() - self.loading_indicator = Gtk.ListBoxRow(activatable=False, selectable=False,) + self.loading_indicator = Gtk.ListBoxRow(activatable=False, selectable=False) loading_spinner = Gtk.Spinner(name="playlist-list-spinner", active=True) self.loading_indicator.add(loading_spinner) loading_new_playlist.add(self.loading_indicator) @@ -364,13 +366,17 @@ class PlaylistDetailPanel(Gtk.Overlay): ) self.play_all_button = IconButton( - "media-playback-start-symbolic", label="Play All", relief=True, + "media-playback-start-symbolic", + label="Play All", + relief=True, ) self.play_all_button.connect("clicked", self.on_play_all_clicked) self.play_shuffle_buttons.pack_start(self.play_all_button, False, False, 0) self.shuffle_all_button = IconButton( - "media-playlist-shuffle-symbolic", label="Shuffle All", relief=True, + "media-playlist-shuffle-symbolic", + label="Shuffle All", + relief=True, ) self.shuffle_all_button.connect("clicked", self.on_shuffle_all_button) self.play_shuffle_buttons.pack_start(self.shuffle_all_button, False, False, 5) @@ -908,7 +914,7 @@ class PlaylistDetailPanel(Gtk.Overlay): self.playlist_artwork.set_loading(False) self.playlist_view_loading_box.hide() - def make_label(self, text: str = None, name: str = None, **params,) -> Gtk.Label: + def make_label(self, text: str = None, name: str = None, **params) -> Gtk.Label: return Gtk.Label( label=text, name=name, @@ -919,7 +925,10 @@ class PlaylistDetailPanel(Gtk.Overlay): @util.async_callback(AdapterManager.get_playlist_details) def _update_playlist_order( - self, playlist: API.Playlist, app_config: AppConfiguration, **kwargs, + self, + playlist: API.Playlist, + app_config: AppConfiguration, + **kwargs, ): self.playlist_view_loading_box.show_all() update_playlist_future = AdapterManager.update_playlist( diff --git a/sublime/ui/state.py b/sublime/ui/state.py index 260214a..98a8511 100644 --- a/sublime/ui/state.py +++ b/sublime/ui/state.py @@ -87,7 +87,9 @@ class UIState: self.name = "Rock" current_album_search_query: AlbumSearchQuery = AlbumSearchQuery( - AlbumSearchQuery.Type.RANDOM, genre=_DefaultGenre(), year_range=(2010, 2020), + AlbumSearchQuery.Type.RANDOM, + genre=_DefaultGenre(), + year_range=(2010, 2020), ) active_playlist_id: Optional[str] = None diff --git a/sublime/ui/util.py b/sublime/ui/util.py index 48c29e4..6dae4af 100644 --- a/sublime/ui/util.py +++ b/sublime/ui/util.py @@ -45,7 +45,7 @@ def format_song_duration(duration_secs: Union[int, timedelta, None]) -> str: return f"{duration_secs // 60}:{duration_secs % 60:02}" -def pluralize(string: str, number: int, pluralized_form: str = None,) -> str: +def pluralize(string: str, number: int, pluralized_form: str = None) -> str: """ Pluralize the given string given the count as a number. @@ -205,7 +205,8 @@ def show_song_popover( def do_on_remove_downloads_click(_: Any): AdapterManager.cancel_download_songs(song_ids) AdapterManager.batch_delete_cached_songs( - song_ids, on_song_delete=on_download_state_change, + song_ids, + on_song_delete=on_download_state_change, ) on_remove_downloads_click() @@ -438,7 +439,10 @@ def async_callback( GLib.idle_add(fn) result: Result = future_fn( - *args, before_download=on_before_download, force=force, **kwargs, + *args, + before_download=on_before_download, + force=force, + **kwargs, ) result.add_done_callback( functools.partial(future_callback, result.data_is_available) diff --git a/tests/adapter_tests/adapter_manager_tests.py b/tests/adapter_tests/adapter_manager_tests.py index afc6f35..93e8b8c 100644 --- a/tests/adapter_tests/adapter_manager_tests.py +++ b/tests/adapter_tests/adapter_manager_tests.py @@ -170,7 +170,8 @@ def test_search_result_update(): search_results2 = SearchResult(query="foo") search_results2.add_results( - "artists", [SubsonicAPI.ArtistAndArtistInfo(id="3", name="foo2")], + "artists", + [SubsonicAPI.ArtistAndArtistInfo(id="3", name="foo2")], ) search_results1.update(search_results2) diff --git a/tests/adapter_tests/filesystem_adapter_tests.py b/tests/adapter_tests/filesystem_adapter_tests.py index 84bd960..5761986 100644 --- a/tests/adapter_tests/filesystem_adapter_tests.py +++ b/tests/adapter_tests/filesystem_adapter_tests.py @@ -90,7 +90,8 @@ def cache_adapter(tmp_path: Path): def mock_data_files( - request_name: str, mode: str = "r", + request_name: str, + mode: str = "r", ) -> Generator[Tuple[Path, Any], None, None]: """ Yields all of the files in the mock_data directory that start with ``request_name``. @@ -272,7 +273,9 @@ def test_caching_get_playlist_then_details(cache_adapter: FilesystemAdapter): # Simulate getting playlist details for id=1, then id=2 cache_adapter.ingest_new_data( - KEYS.PLAYLIST_DETAILS, "1", SubsonicAPI.Playlist("1", "test1"), + KEYS.PLAYLIST_DETAILS, + "1", + SubsonicAPI.Playlist("1", "test1"), ) cache_adapter.ingest_new_data( @@ -308,7 +311,9 @@ def test_invalidate_playlist(cache_adapter: FilesystemAdapter): [SubsonicAPI.Playlist("1", "test1"), SubsonicAPI.Playlist("2", "test2")], ) cache_adapter.ingest_new_data( - KEYS.COVER_ART_FILE, "pl_test1", MOCK_ALBUM_ART, + KEYS.COVER_ART_FILE, + "pl_test1", + MOCK_ALBUM_ART, ) cache_adapter.ingest_new_data( KEYS.PLAYLIST_DETAILS, @@ -316,7 +321,9 @@ def test_invalidate_playlist(cache_adapter: FilesystemAdapter): SubsonicAPI.Playlist("2", "test2", cover_art="pl_2", songs=[]), ) cache_adapter.ingest_new_data( - KEYS.COVER_ART_FILE, "pl_2", MOCK_ALBUM_ART2, + KEYS.COVER_ART_FILE, + "pl_2", + MOCK_ALBUM_ART2, ) stale_uri_1 = cache_adapter.get_cover_art_uri("pl_test1", "file", size=300) @@ -362,7 +369,9 @@ def test_invalidate_song_file(cache_adapter: FilesystemAdapter): cache_adapter.ingest_new_data(KEYS.SONG, "2", MOCK_SUBSONIC_SONGS[0]) cache_adapter.ingest_new_data(KEYS.SONG, "1", MOCK_SUBSONIC_SONGS[1]) cache_adapter.ingest_new_data( - KEYS.COVER_ART_FILE, "s1", MOCK_ALBUM_ART, + KEYS.COVER_ART_FILE, + "s1", + MOCK_ALBUM_ART, ) cache_adapter.ingest_new_data(KEYS.SONG_FILE, "1", (None, MOCK_SONG_FILE, None)) cache_adapter.ingest_new_data(KEYS.SONG_FILE, "2", (None, MOCK_SONG_FILE2, None)) @@ -430,7 +439,9 @@ def test_delete_playlists(cache_adapter: FilesystemAdapter): SubsonicAPI.Playlist("2", "test1", cover_art="pl_2", songs=[]), ) cache_adapter.ingest_new_data( - KEYS.COVER_ART_FILE, "pl_1", MOCK_ALBUM_ART, + KEYS.COVER_ART_FILE, + "pl_1", + MOCK_ALBUM_ART, ) # Deleting a playlist should get rid of it entirely. @@ -451,7 +462,8 @@ def test_delete_playlists(cache_adapter: FilesystemAdapter): # Even if the cover art failed to be deleted, it should cache miss. shutil.copy( - MOCK_ALBUM_ART, str(cache_adapter.cover_art_dir.joinpath(MOCK_ALBUM_ART_HASH)), + MOCK_ALBUM_ART, + str(cache_adapter.cover_art_dir.joinpath(MOCK_ALBUM_ART_HASH)), ) try: cache_adapter.get_cover_art_uri("pl_1", "file", size=300) @@ -464,7 +476,9 @@ def test_delete_song_data(cache_adapter: FilesystemAdapter): cache_adapter.ingest_new_data(KEYS.SONG, "1", MOCK_SUBSONIC_SONGS[1]) cache_adapter.ingest_new_data(KEYS.SONG_FILE, "1", (None, MOCK_SONG_FILE, None)) cache_adapter.ingest_new_data( - KEYS.COVER_ART_FILE, "s1", MOCK_ALBUM_ART, + KEYS.COVER_ART_FILE, + "s1", + MOCK_ALBUM_ART, ) music_file_path = cache_adapter.get_song_file_uri("1", "file") @@ -747,14 +761,18 @@ def test_caching_get_artist(cache_adapter: FilesystemAdapter): ) artist = cache_adapter.get_artist("1") - assert artist.artist_image_url and ( - artist.id, - artist.name, - artist.album_count, - artist.artist_image_url, - artist.biography, - artist.music_brainz_id, - ) == ("1", "Bar", 1, "image", "this is a bio", "mbid") + assert ( + artist.artist_image_url + and ( + artist.id, + artist.name, + artist.album_count, + artist.artist_image_url, + artist.biography, + artist.music_brainz_id, + ) + == ("1", "Bar", 1, "image", "this is a bio", "mbid") + ) assert artist.similar_artists == [ SubsonicAPI.ArtistAndArtistInfo(id="A", name="B"), SubsonicAPI.ArtistAndArtistInfo(id="C", name="D"), @@ -787,14 +805,18 @@ def test_caching_get_artist(cache_adapter: FilesystemAdapter): ) artist = cache_adapter.get_artist("1") - assert artist.artist_image_url and ( - artist.id, - artist.name, - artist.album_count, - artist.artist_image_url, - artist.biography, - artist.music_brainz_id, - ) == ("1", "Foo", 2, "image2", "this is a bio2", "mbid2") + assert ( + artist.artist_image_url + and ( + artist.id, + artist.name, + artist.album_count, + artist.artist_image_url, + artist.biography, + artist.music_brainz_id, + ) + == ("1", "Foo", 2, "image2", "this is a bio2", "mbid2") + ) assert artist.similar_artists == [ SubsonicAPI.ArtistAndArtistInfo(id="A", name="B"), SubsonicAPI.ArtistAndArtistInfo(id="E", name="F"), @@ -837,7 +859,14 @@ def test_caching_get_album(cache_adapter: FilesystemAdapter): album.song_count, album.year, album.play_count, - ) == ("a1", "foo", "c", 2, 2020, 20,) + ) == ( + "a1", + "foo", + "c", + 2, + 2020, + 20, + ) assert album.artist assert (album.artist.id, album.artist.name) == ("art1", "cool") assert album.songs diff --git a/tests/common_ui_tests.py b/tests/common_ui_tests.py index 368a318..732592e 100755 --- a/tests/common_ui_tests.py +++ b/tests/common_ui_tests.py @@ -41,7 +41,10 @@ def test_song_list_column(): def test_spinner_image(): initial_size = 300 image = common.SpinnerImage( - loading=False, image_name="test", spinner_name="ohea", image_size=initial_size, + loading=False, + image_name="test", + spinner_name="ohea", + image_size=initial_size, ) image.set_from_file(None) assert image.image.get_pixbuf() is None From 37d693d553ffbed3b18c9ac67701b960dc3780b0 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 00:36:35 -0600 Subject: [PATCH 3/8] Add deps --- .builds/flatpak.yml | 3 ++- .builds/gitlab-mirror-and-readme.yml | 2 +- .builds/lint-test.yml | 6 ++++-- .builds/pypi.yml | 11 ++++++----- cicd/run_if_tagged_with_version | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml index d4a3aa4..3e97f01 100644 --- a/.builds/flatpak.yml +++ b/.builds/flatpak.yml @@ -2,8 +2,9 @@ image: archlinux packages: - flatpak - flatpak-builder + - python-pip sources: - - https://git.sr.ht/~sumner/offlinemsmtp + - https://git.sr.ht/~sumner/sublime-music environment: REPO_NAME: sublime-music # triggers: diff --git a/.builds/gitlab-mirror-and-readme.yml b/.builds/gitlab-mirror-and-readme.yml index 2d3d130..e723e32 100644 --- a/.builds/gitlab-mirror-and-readme.yml +++ b/.builds/gitlab-mirror-and-readme.yml @@ -5,7 +5,7 @@ packages: - openssh - py3-docutils sources: - - https://git.sr.ht/~sumner/offlinemsmtp + - https://git.sr.ht/~sumner/sublime-music secrets: # README Personal Access Token - 2fb5fd72-fa96-46c6-ab90-6b7cabebba16 diff --git a/.builds/lint-test.yml b/.builds/lint-test.yml index 448e543..e66dc5f 100644 --- a/.builds/lint-test.yml +++ b/.builds/lint-test.yml @@ -1,10 +1,13 @@ image: archlinux packages: - dbus + - gobject-introspection + - python-cairo + - python-gobject - python-poetry - xorg-server-xvfb sources: - - https://git.sr.ht/~sumner/offlinemsmtp + - https://git.sr.ht/~sumner/sublime-music environment: REPO_NAME: sublime-music # triggers: @@ -26,7 +29,6 @@ tasks: cicd/custom_style_check.py - test: | - ./cicd/start-dbus.sh Xvfb :119 -screen 0 1024x768x16 & export DISPLAY=:119 ./cicd/pytest.sh diff --git a/.builds/pypi.yml b/.builds/pypi.yml index 04adcab..cfe3391 100644 --- a/.builds/pypi.yml +++ b/.builds/pypi.yml @@ -1,9 +1,10 @@ -image: archlinux +image: alpine/edge packages: - - python - - xorg-server-xvfb + - py3-pip + - py3-setuptools + - py3-twine sources: - - https://git.sr.ht/~sumner/offlinemsmtp + - https://git.sr.ht/~sumner/sublime-music environment: REPO_NAME: sublime-music # triggers: @@ -16,7 +17,7 @@ tasks: echo "cd ${REPO_NAME}" >> ~/.buildenv - build: | - python setup.py sdist + python3 setup.py sdist - deploy-pypi: | ./cicd/run_if_tagged_with_version \ diff --git a/cicd/run_if_tagged_with_version b/cicd/run_if_tagged_with_version index e6a91d0..d17c6a8 100755 --- a/cicd/run_if_tagged_with_version +++ b/cicd/run_if_tagged_with_version @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 import re import subprocess From 5300ab15ef9583a9be86cb157285984f7611859d Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 01:11:47 -0600 Subject: [PATCH 4/8] Fix tests; add more info to pyproject.toml --- .builds/flatpak.yml | 2 +- .builds/lint-test.yml | 2 +- poetry.lock | 838 ++++++++++++++++++++++++++- pyproject.toml | 46 +- setup.cfg | 3 - sublime/adapters/subsonic/adapter.py | 4 +- 6 files changed, 883 insertions(+), 12 deletions(-) diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml index 3e97f01..28c3e56 100644 --- a/.builds/flatpak.yml +++ b/.builds/flatpak.yml @@ -17,4 +17,4 @@ tasks: - build-flatpak: | cd ${REPO_NAME}/flatpak - ./flatpak_build.sh + REPO=repo ./flatpak_build.sh diff --git a/.builds/lint-test.yml b/.builds/lint-test.yml index e66dc5f..59f8a50 100644 --- a/.builds/lint-test.yml +++ b/.builds/lint-test.yml @@ -31,4 +31,4 @@ tasks: - test: | Xvfb :119 -screen 0 1024x768x16 & export DISPLAY=:119 - ./cicd/pytest.sh + pytest diff --git a/poetry.lock b/poetry.lock index 2fb72bc..cf371b9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,6 +6,29 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +marker = "sys_platform == \"win32\"" + +[[package]] +name = "attrs" +version = "20.2.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + [[package]] name = "black" version = "20.8b1" @@ -28,6 +51,66 @@ toml = ">=0.10.1" typed-ast = ">=1.4.0" typing-extensions = ">=3.7.4" +[[package]] +name = "bleach" +version = "3.2.1" +description = "An easy safelist-based HTML-sanitizing tool." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +packaging = "*" +six = ">=1.9.0" +webencodings = "*" + +[[package]] +name = "bottle" +version = "0.12.18" +description = "Fast and simple WSGI-framework for small web-applications." +category = "main" +optional = true +python-versions = "*" + +[[package]] +name = "casttube" +version = "0.2.1" +description = "YouTube chromecast api" +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +requests = "*" + +[[package]] +name = "certifi" +version = "2020.6.20" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "cffi" +version = "1.14.3" +description = "Foreign Function Interface for Python calling C code." +category = "main" +optional = true +python-versions = "*" +marker = "sys_platform == \"linux\"" + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "click" version = "7.1.2" @@ -36,6 +119,77 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "colorama" +version = "0.4.3" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +marker = "sys_platform == \"win32\"" + +[[package]] +name = "coverage" +version = "5.3" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "cryptography" +version = "3.1" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" +optional = true +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +marker = "sys_platform == \"linux\"" + +[package.extras] +docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0,<3.1.0 || >3.1.0,<3.1.1 || >3.1.1)", "sphinx-rtd-theme"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] + +[package.dependencies] +cffi = ">=1.8,<1.11.3 || >1.11.3" +six = ">=1.4.1" + +[[package]] +name = "dataclasses-json" +version = "0.5.2" +description = "Easily serialize dataclasses to and from JSON" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["pytest", "ipython", "mypy (>=0.710)", "hypothesis", "portray", "flake8", "simplejson"] + +[package.dependencies] +marshmallow = ">=3.3.0,<4.0.0" +marshmallow-enum = ">=1.5.1,<2.0.0" +stringcase = "1.2.0" +typing-inspect = ">=0.4.0" + +[[package]] +name = "deepdiff" +version = "5.0.2" +description = "Deep Difference and Search of any Python object/data." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +murmur = ["mmh3"] + +[package.dependencies] +ordered-set = ">=4.0.1" + [[package]] name = "docutils" version = "0.16" @@ -57,6 +211,95 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.6.0a1,<2.7.0" pyflakes = ">=2.2.0,<2.3.0" +[[package]] +name = "fuzzywuzzy" +version = "0.18.0" +description = "Fuzzy string matching in python" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +speedup = ["python-levenshtein (>=0.12)"] + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "ifaddr" +version = "0.1.7" +description = "Cross-platform network interface and IP address enumeration library" +category = "main" +optional = true +python-versions = "*" + +[[package]] +name = "iniconfig" +version = "1.0.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "jeepney" +version = "0.4.3" +description = "Low-level, pure Python DBus protocol wrapper." +category = "main" +optional = true +python-versions = ">=3.5" +marker = "sys_platform == \"linux\"" + +[package.extras] +dev = ["testpath"] + +[[package]] +name = "keyring" +version = "21.4.0" +description = "Store and access your passwords safely." +category = "main" +optional = true +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy"] + +[package.dependencies] +jeepney = ">=0.4.2" +pywin32-ctypes = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1" +SecretStorage = ">=3" + +[[package]] +name = "marshmallow" +version = "3.8.0" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["pytest", "pytz", "simplejson", "mypy (0.782)", "flake8 (3.8.3)", "flake8-bugbear (20.1.4)", "pre-commit (>=2.4,<3.0)", "tox"] +docs = ["sphinx (3.2.1)", "sphinx-issues (1.2.0)", "alabaster (0.7.12)", "sphinx-version-warning (1.1.2)", "autodocsumm (0.2.0)"] +lint = ["mypy (0.782)", "flake8 (3.8.3)", "flake8-bugbear (20.1.4)", "pre-commit (>=2.4,<3.0)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "marshmallow-enum" +version = "1.5.1" +description = "Enum field for Marshmallow" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +marshmallow = ">=2.0.0" + [[package]] name = "mccabe" version = "0.6.1" @@ -65,6 +308,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "more-itertools" +version = "8.5.0" +description = "More routines for operating on iterables, beyond itertools" +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "mypy" version = "0.782" @@ -85,10 +336,30 @@ typing-extensions = ">=3.7.4" name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" +category = "main" optional = false python-versions = "*" +[[package]] +name = "ordered-set" +version = "4.0.2" +description = "A set that remembers its order, and allows looking up its items by their index in that order." +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "packaging" +version = "20.4" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + [[package]] name = "pathspec" version = "0.8.0" @@ -97,6 +368,67 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "peewee" +version = "3.13.3" +description = "a little orm" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "protobuf" +version = "3.13.0" +description = "Protocol Buffers" +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +setuptools = "*" +six = ">=1.9" + +[[package]] +name = "py" +version = "1.9.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pycairo" +version = "1.19.1" +description = "Python interface for cairo" +category = "main" +optional = false +python-versions = ">=3.5, <4" + +[[package]] +name = "pychromecast" +version = "7.3.0" +description = "Python module to talk to Google Chromecast." +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +casttube = ">=0.2.0" +protobuf = ">=3.0.0" +requests = ">=2.0" +zeroconf = ">=0.25.1" + [[package]] name = "pycodestyle" version = "2.6.0" @@ -105,6 +437,15 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycparser" +version = "2.20" +description = "C parser in Python" +category = "main" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +marker = "sys_platform == \"linux\"" + [[package]] name = "pyflakes" version = "2.2.0" @@ -113,6 +454,105 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pygobject" +version = "3.38.0" +description = "Python bindings for GObject Introspection" +category = "main" +optional = false +python-versions = ">=3.5, <4" + +[package.dependencies] +pycairo = ">=1.11.1" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pytest" +version = "6.0.2" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +checkqa_mypy = ["mypy (0.780)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +iniconfig = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.8.2" +toml = "*" + +[[package]] +name = "pytest-cov" +version = "2.10.1" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"] + +[package.dependencies] +coverage = ">=4.4" +pytest = ">=4.6" + +[[package]] +name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-levenshtein" +version = "0.12.0" +description = "Python extension for computing string edit distances and similarities." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "python-mpv" +version = "0.5.2" +description = "A python interface to the mpv media player" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +screenshot_raw = ["pillow"] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "main" +optional = true +python-versions = "*" +marker = "sys_platform == \"win32\"" + [[package]] name = "regex" version = "2020.7.14" @@ -121,6 +561,61 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "requests" +version = "2.24.0" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[[package]] +name = "secretstorage" +version = "3.1.2" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "main" +optional = true +python-versions = ">=3.5" +marker = "sys_platform == \"linux\"" + +[package.dependencies] +cryptography = "*" +jeepney = ">=0.4.2" + +[[package]] +name = "semver" +version = "2.10.2" +description = "Python helper for Semantic Versioning (http://semver.org/)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "stringcase" +version = "1.2.0" +description = "String case converter." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "termcolor" version = "1.1.0" @@ -149,27 +644,214 @@ python-versions = "*" name = "typing-extensions" version = "3.7.4.3" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "dev" +category = "main" optional = false python-versions = "*" +[[package]] +name = "typing-inspect" +version = "0.6.0" +description = "Runtime inspection utilities for typing module." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "urllib3" +version = "1.25.10" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "zeroconf" +version = "0.28.5" +description = "Pure Python Multicast DNS Service Discovery Library (Bonjour/Avahi compatible)" +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +ifaddr = ">=0.1.7" + +[extras] +keyring = ["keyring"] +chromecast = ["pychromecast"] +server = ["bottle"] + [metadata] lock-version = "1.0" python-versions = "^3.8" -content-hash = "1acb006656d63d11e51c7ad618ac5bada6e9c8fb1f21ed7bd57fba1259a7852e" +content-hash = "b205eec2da8442d64ad3e77af6740a626b5e79e32b22709e5954a5d49fc8d72b" [metadata.files] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, + {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, +] black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] +bleach = [ + {file = "bleach-3.2.1-py2.py3-none-any.whl", hash = "sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd"}, + {file = "bleach-3.2.1.tar.gz", hash = "sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080"}, +] +bottle = [ + {file = "bottle-0.12.18-py3-none-any.whl", hash = "sha256:43157254e88f32c6be16f8d9eb1f1d1472396a4e174ebd2bf62544854ecf37e7"}, + {file = "bottle-0.12.18.tar.gz", hash = "sha256:0819b74b145a7def225c0e83b16a4d5711fde751cd92bae467a69efce720f69e"}, +] +casttube = [ + {file = "casttube-0.2.1-py3-none-any.whl", hash = "sha256:36f118007f9eead3959cf30de03c1640b53a263569ff2a3971c0521826c835b2"}, + {file = "casttube-0.2.1.tar.gz", hash = "sha256:54d2af8c7949aa9c5db87fb11ef0a478a5d3e7ac6d2d2ac8dd1711e3a516fc82"}, +] +certifi = [ + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, +] +cffi = [ + {file = "cffi-1.14.3-2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc"}, + {file = "cffi-1.14.3-2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768"}, + {file = "cffi-1.14.3-2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d"}, + {file = "cffi-1.14.3-2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1"}, + {file = "cffi-1.14.3-2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca"}, + {file = "cffi-1.14.3-2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730"}, + {file = "cffi-1.14.3-cp27-cp27m-win32.whl", hash = "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d"}, + {file = "cffi-1.14.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4"}, + {file = "cffi-1.14.3-cp35-cp35m-win32.whl", hash = "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d"}, + {file = "cffi-1.14.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537"}, + {file = "cffi-1.14.3-cp36-cp36m-win32.whl", hash = "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0"}, + {file = "cffi-1.14.3-cp36-cp36m-win_amd64.whl", hash = "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394"}, + {file = "cffi-1.14.3-cp37-cp37m-win32.whl", hash = "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc"}, + {file = "cffi-1.14.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9"}, + {file = "cffi-1.14.3-cp38-cp38-win32.whl", hash = "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522"}, + {file = "cffi-1.14.3-cp38-cp38-win_amd64.whl", hash = "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c"}, + {file = "cffi-1.14.3-cp39-cp39-win32.whl", hash = "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b"}, + {file = "cffi-1.14.3-cp39-cp39-win_amd64.whl", hash = "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3"}, + {file = "cffi-1.14.3.tar.gz", hash = "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, ] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +coverage = [ + {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, + {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, + {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, + {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, + {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, + {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, + {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, + {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, + {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, + {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, + {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, + {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, + {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, + {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, + {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, + {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, + {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, + {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, + {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, +] +cryptography = [ + {file = "cryptography-3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:969ae512a250f869c1738ca63be843488ff5cc031987d302c1f59c7dbe1b225f"}, + {file = "cryptography-3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:b45ab1c6ece7c471f01c56f5d19818ca797c34541f0b2351635a5c9fe09ac2e0"}, + {file = "cryptography-3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:247df238bc05c7d2e934a761243bfdc67db03f339948b1e2e80c75d41fc7cc36"}, + {file = "cryptography-3.1-cp27-cp27m-win32.whl", hash = "sha256:10c9775a3f31610cf6b694d1fe598f2183441de81cedcf1814451ae53d71b13a"}, + {file = "cryptography-3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:9f734423eb9c2ea85000aa2476e0d7a58e021bc34f0a373ac52a5454cd52f791"}, + {file = "cryptography-3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e7563eb7bc5c7e75a213281715155248cceba88b11cb4b22957ad45b85903761"}, + {file = "cryptography-3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:94191501e4b4009642be21dde2a78bd3c2701a81ee57d3d3d02f1d99f8b64a9e"}, + {file = "cryptography-3.1-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:dc3f437ca6353979aace181f1b790f0fc79e446235b14306241633ab7d61b8f8"}, + {file = "cryptography-3.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:725875681afe50b41aee7fdd629cedbc4720bab350142b12c55c0a4d17c7416c"}, + {file = "cryptography-3.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:321761d55fb7cb256b771ee4ed78e69486a7336be9143b90c52be59d7657f50f"}, + {file = "cryptography-3.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:2a27615c965173c4c88f2961cf18115c08fedfb8bdc121347f26e8458dc6d237"}, + {file = "cryptography-3.1-cp35-cp35m-win32.whl", hash = "sha256:e7dad66a9e5684a40f270bd4aee1906878193ae50a4831922e454a2a457f1716"}, + {file = "cryptography-3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4005b38cd86fc51c955db40b0f0e52ff65340874495af72efabb1bb8ca881695"}, + {file = "cryptography-3.1-cp36-abi3-win32.whl", hash = "sha256:cc6096c86ec0de26e2263c228fb25ee01c3ff1346d3cfc219d67d49f303585af"}, + {file = "cryptography-3.1-cp36-abi3-win_amd64.whl", hash = "sha256:2e26223ac636ca216e855748e7d435a1bf846809ed12ed898179587d0cf74618"}, + {file = "cryptography-3.1-cp36-cp36m-win32.whl", hash = "sha256:7a63e97355f3cd77c94bd98c59cb85fe0efd76ea7ef904c9b0316b5bbfde6ed1"}, + {file = "cryptography-3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:4b9e96543d0784acebb70991ebc2dbd99aa287f6217546bb993df22dd361d41c"}, + {file = "cryptography-3.1-cp37-cp37m-win32.whl", hash = "sha256:eb80a288e3cfc08f679f95da72d2ef90cb74f6d8a8ba69d2f215c5e110b2ca32"}, + {file = "cryptography-3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:180c9f855a8ea280e72a5d61cf05681b230c2dce804c48e9b2983f491ecc44ed"}, + {file = "cryptography-3.1-cp38-cp38-win32.whl", hash = "sha256:fa7fbcc40e2210aca26c7ac8a39467eae444d90a2c346cbcffd9133a166bcc67"}, + {file = "cryptography-3.1-cp38-cp38-win_amd64.whl", hash = "sha256:548b0818e88792318dc137d8b1ec82a0ab0af96c7f0603a00bb94f896fbf5e10"}, + {file = "cryptography-3.1.tar.gz", hash = "sha256:26409a473cc6278e4c90f782cd5968ebad04d3911ed1c402fc86908c17633e08"}, +] +dataclasses-json = [ + {file = "dataclasses-json-0.5.2.tar.gz", hash = "sha256:56ec931959ede74b5dedf65cf20772e6a79764d20c404794cce0111c88c085ff"}, + {file = "dataclasses_json-0.5.2-py3-none-any.whl", hash = "sha256:b746c48d9d8e884e2a0ffa59c6220a1b21f94d4f9f12c839da0a8a0efd36dc19"}, +] +deepdiff = [ + {file = "deepdiff-5.0.2-py3-none-any.whl", hash = "sha256:273b18d32bb9b956548290b2e3ddf79c515def2dd5738965f4348ae813e710c5"}, + {file = "deepdiff-5.0.2.tar.gz", hash = "sha256:e2b74af4da0ef9cd338bb6e8c97242c1ec9d81fcb28298d7bb24acdc19ea79d7"}, +] docutils = [ {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, @@ -178,10 +860,46 @@ flake8 = [ {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, ] +fuzzywuzzy = [ + {file = "fuzzywuzzy-0.18.0-py2.py3-none-any.whl", hash = "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993"}, + {file = "fuzzywuzzy-0.18.0.tar.gz", hash = "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +ifaddr = [ + {file = "ifaddr-0.1.7-py2.py3-none-any.whl", hash = "sha256:d1f603952f0a71c9ab4e705754511e4e03b02565bc4cec7188ad6415ff534cd3"}, + {file = "ifaddr-0.1.7.tar.gz", hash = "sha256:1f9e8a6ca6f16db5a37d3356f07b6e52344f6f9f7e806d618537731669eb1a94"}, +] +iniconfig = [ + {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, + {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, +] +jeepney = [ + {file = "jeepney-0.4.3-py3-none-any.whl", hash = "sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf"}, + {file = "jeepney-0.4.3.tar.gz", hash = "sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e"}, +] +keyring = [ + {file = "keyring-21.4.0-py3-none-any.whl", hash = "sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d"}, + {file = "keyring-21.4.0.tar.gz", hash = "sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466"}, +] +marshmallow = [ + {file = "marshmallow-3.8.0-py2.py3-none-any.whl", hash = "sha256:2272273505f1644580fbc66c6b220cc78f893eb31f1ecde2af98ad28011e9811"}, + {file = "marshmallow-3.8.0.tar.gz", hash = "sha256:47911dd7c641a27160f0df5fd0fe94667160ffe97f70a42c3cc18388d86098cc"}, +] +marshmallow-enum = [ + {file = "marshmallow-enum-1.5.1.tar.gz", hash = "sha256:38e697e11f45a8e64b4a1e664000897c659b60aa57bfa18d44e226a9920b6e58"}, + {file = "marshmallow_enum-1.5.1-py2.py3-none-any.whl", hash = "sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] +more-itertools = [ + {file = "more-itertools-8.5.0.tar.gz", hash = "sha256:6f83822ae94818eae2612063a5101a7311e68ae8002005b5e05f03fd74a86a20"}, + {file = "more_itertools-8.5.0-py3-none-any.whl", hash = "sha256:9b30f12df9393f0d28af9210ff8efe48d10c94f73e5daf886f10c4b0b0b4f03c"}, +] mypy = [ {file = "mypy-0.782-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:2c6cde8aa3426c1682d35190b59b71f661237d74b053822ea3d748e2c9578a7c"}, {file = "mypy-0.782-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c7a9a7ceb2871ba4bac1cf7217a7dd9ccd44c27c2950edbc6dc08530f32ad4e"}, @@ -202,18 +920,96 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +ordered-set = [ + {file = "ordered-set-4.0.2.tar.gz", hash = "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95"}, +] +packaging = [ + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] pathspec = [ {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, ] +peewee = [ + {file = "peewee-3.13.3.tar.gz", hash = "sha256:1269a9736865512bd4056298003aab190957afe07d2616cf22eaf56cb6398369"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +protobuf = [ + {file = "protobuf-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9c2e63c1743cba12737169c447374fab3dfeb18111a460a8c1a000e35836b18c"}, + {file = "protobuf-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1e834076dfef9e585815757a2c7e4560c7ccc5962b9d09f831214c693a91b463"}, + {file = "protobuf-3.13.0-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:df3932e1834a64b46ebc262e951cd82c3cf0fa936a154f0a42231140d8237060"}, + {file = "protobuf-3.13.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8c35bcbed1c0d29b127c886790e9d37e845ffc2725cc1db4bd06d70f4e8359f4"}, + {file = "protobuf-3.13.0-cp35-cp35m-win32.whl", hash = "sha256:339c3a003e3c797bc84499fa32e0aac83c768e67b3de4a5d7a5a9aa3b0da634c"}, + {file = "protobuf-3.13.0-cp35-cp35m-win_amd64.whl", hash = "sha256:361acd76f0ad38c6e38f14d08775514fbd241316cce08deb2ce914c7dfa1184a"}, + {file = "protobuf-3.13.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9edfdc679a3669988ec55a989ff62449f670dfa7018df6ad7f04e8dbacb10630"}, + {file = "protobuf-3.13.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5db9d3e12b6ede5e601b8d8684a7f9d90581882925c96acf8495957b4f1b204b"}, + {file = "protobuf-3.13.0-cp36-cp36m-win32.whl", hash = "sha256:c8abd7605185836f6f11f97b21200f8a864f9cb078a193fe3c9e235711d3ff1e"}, + {file = "protobuf-3.13.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4d1174c9ed303070ad59553f435846a2f877598f59f9afc1b89757bdf846f2a7"}, + {file = "protobuf-3.13.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0bba42f439bf45c0f600c3c5993666fcb88e8441d011fad80a11df6f324eef33"}, + {file = "protobuf-3.13.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c0c5ab9c4b1eac0a9b838f1e46038c3175a95b0f2d944385884af72876bd6bc7"}, + {file = "protobuf-3.13.0-cp37-cp37m-win32.whl", hash = "sha256:f68eb9d03c7d84bd01c790948320b768de8559761897763731294e3bc316decb"}, + {file = "protobuf-3.13.0-cp37-cp37m-win_amd64.whl", hash = "sha256:91c2d897da84c62816e2f473ece60ebfeab024a16c1751aaf31100127ccd93ec"}, + {file = "protobuf-3.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3dee442884a18c16d023e52e32dd34a8930a889e511af493f6dc7d4d9bf12e4f"}, + {file = "protobuf-3.13.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:e7662437ca1e0c51b93cadb988f9b353fa6b8013c0385d63a70c8a77d84da5f9"}, + {file = "protobuf-3.13.0-py2.py3-none-any.whl", hash = "sha256:d69697acac76d9f250ab745b46c725edf3e98ac24763990b24d58c16c642947a"}, + {file = "protobuf-3.13.0.tar.gz", hash = "sha256:6a82e0c8bb2bf58f606040cc5814e07715b2094caeba281e2e7d0b0e2e397db5"}, +] +py = [ + {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, + {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, +] +pycairo = [ + {file = "pycairo-1.19.1.tar.gz", hash = "sha256:2c143183280feb67f5beb4e543fd49990c28e7df427301ede04fc550d3562e84"}, +] +pychromecast = [ + {file = "PyChromecast-7.3.0-py2.py3-none-any.whl", hash = "sha256:182ee414f7de227f2e55d6444bd59d31282bac4d1d63f0f3ca1f19725c5ba4bf"}, + {file = "PyChromecast-7.3.0.tar.gz", hash = "sha256:f594231efb34b86eeb463611662bca21a6962793885d3ad68195286940f7473d"}, +] pycodestyle = [ {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, ] +pycparser = [ + {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, + {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, +] pyflakes = [ {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] +pygobject = [ + {file = "PyGObject-3.38.0.tar.gz", hash = "sha256:051b950f509f2e9f125add96c1493bde987c527f7a0c15a1f7b69d6d1c3cd8e6"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"}, + {file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"}, +] +pytest-cov = [ + {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, + {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] +python-levenshtein = [ + {file = "python-Levenshtein-0.12.0.tar.gz", hash = "sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1"}, +] +python-mpv = [ + {file = "python-mpv-0.5.2.tar.gz", hash = "sha256:10c7ae61eff441602c7188595108391cdede153c15454772d8811c2bcb9e6823"}, +] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] regex = [ {file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"}, {file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"}, @@ -237,6 +1033,25 @@ regex = [ {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, ] +requests = [ + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] +secretstorage = [ + {file = "SecretStorage-3.1.2-py3-none-any.whl", hash = "sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b"}, + {file = "SecretStorage-3.1.2.tar.gz", hash = "sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6"}, +] +semver = [ + {file = "semver-2.10.2-py2.py3-none-any.whl", hash = "sha256:21e80ca738975ed513cba859db0a0d2faca2380aef1962f48272ebf9a8a44bd4"}, + {file = "semver-2.10.2.tar.gz", hash = "sha256:c0a4a9d1e45557297a722ee9bac3de2ec2ea79016b6ffcaca609b0bc62cf4276"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +stringcase = [ + {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, +] termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] @@ -272,3 +1087,20 @@ typing-extensions = [ {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, ] +typing-inspect = [ + {file = "typing_inspect-0.6.0-py2-none-any.whl", hash = "sha256:de08f50a22955ddec353876df7b2545994d6df08a2f45d54ac8c05e530372ca0"}, + {file = "typing_inspect-0.6.0-py3-none-any.whl", hash = "sha256:3b98390df4d999a28cf5b35d8b333425af5da2ece8a4ea9e98f71e7591347b4f"}, + {file = "typing_inspect-0.6.0.tar.gz", hash = "sha256:8f1b1dd25908dbfd81d3bebc218011531e7ab614ba6e5bf7826d887c834afab7"}, +] +urllib3 = [ + {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, + {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, +] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] +zeroconf = [ + {file = "zeroconf-0.28.5-py3-none-any.whl", hash = "sha256:f69cc7f9cc3b2a85c7f2cdafe2bb7fb00cf01604bc3df392f7ed5e3c303d7705"}, + {file = "zeroconf-0.28.5.tar.gz", hash = "sha256:c08dbb90c116626cb6c5f19ebd14cd4846cffe7151f338c19215e6938d334980"}, +] diff --git a/pyproject.toml b/pyproject.toml index 39f152c..145282b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,18 +2,60 @@ name = "sublime-music" version = "0.11.9" description = "A native GTK *sonic client." -authors = ["Sumner Evans "] license = "GPL-3.0-or-later" +authors = ["Sumner Evans "] +readme = "README.rst" +homepage = "https://sublimemusic.app" +repository = "https://sr.ht/~sumner/sublime-music" +documentation = "https://sublime-music.gitlab.io/sublime-music/" +keywords = ["airsonic", "music", "chromecast", "subsonic"] +classifiers = [ + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + "Development Status :: 3 - Alpha", + "Intended Audience :: End Users/Desktop", + "Operating System :: POSIX", +] + +# TODO +exclude = ["tests"] + +[tool.poetry.urls] +"Bug Tracker" = "https://todo.sr.ht/~sumner/sublime-music" + +[tool.poetry.scripts] +sublime-music = 'sublime.__main__:main' [tool.poetry.dependencies] python = "^3.8" +bleach = "^3.2.1" +dataclasses-json = "^0.5.2" +deepdiff = "^5.0.2" +fuzzywuzzy = "^0.18.0" +peewee = "^3.13.3" +PyGObject = "^3.38.0" +python-dateutil = "^2.8.1" +python-Levenshtein = "^0.12.0" +python-mpv = "^0.5.2" +requests = "^2.24.0" +semver = "^2.10.2" +bottle = {version = "^0.12.18", optional = true} +keyring = {version = "^21.4.0", optional = true} +pychromecast = {version = "^7.3.0", optional = true} [tool.poetry.dev-dependencies] black = "^20.8b1" +docutils = "^0.16" flake8 = "^3.8.3" mypy = "^0.782" +pytest-cov = "^2.10.1" termcolor = "^1.1.0" -docutils = "^0.16" + +[tool.poetry.extras] +chromecast = ["pychromecast"] +keyring = ["keyring"] +server = ["bottle"] [build-system] requires = ["poetry>=0.12"] diff --git a/setup.cfg b/setup.cfg index b873664..f1f20b4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,9 +10,6 @@ import-order-style = edited [mypy-bottle] ignore_missing_imports = True -[mypy-dataclasses_json] -ignore_missing_imports = True - [mypy-deepdiff] ignore_missing_imports = True diff --git a/sublime/adapters/subsonic/adapter.py b/sublime/adapters/subsonic/adapter.py index ccda4ed..714f323 100644 --- a/sublime/adapters/subsonic/adapter.py +++ b/sublime/adapters/subsonic/adapter.py @@ -474,10 +474,10 @@ class SubsonicAdapter(Adapter): raise data if hasattr(data, "__next__"): if d := next(data): - logging.info("MOCK DATA", d) + logging.info("MOCK DATA: %s", d) return MockResult(d) - logging.info("MOCK DATA", data) + logging.info("MOCK DATA: %s", data) return MockResult(data) self._get_mock_data = get_mock_data From c9769bdb8c77aaae39c0a9eba2d44bfa352d142c Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 01:23:47 -0600 Subject: [PATCH 5/8] Comment out flatpak build --- .builds/flatpak.yml | 2 +- .builds/lint-test.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml index 28c3e56..cc8de3c 100644 --- a/.builds/flatpak.yml +++ b/.builds/flatpak.yml @@ -17,4 +17,4 @@ tasks: - build-flatpak: | cd ${REPO_NAME}/flatpak - REPO=repo ./flatpak_build.sh + # REPO=repo ./flatpak_build.sh diff --git a/.builds/lint-test.yml b/.builds/lint-test.yml index 59f8a50..0262f9d 100644 --- a/.builds/lint-test.yml +++ b/.builds/lint-test.yml @@ -2,6 +2,8 @@ image: archlinux packages: - dbus - gobject-introspection + - gtk3 + - mpv - python-cairo - python-gobject - python-poetry From c74e775ed8cba1c0f13f624b0d588a2619710fc2 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 01:44:26 -0600 Subject: [PATCH 6/8] Consolidate the build to one manifest --- .builds/{lint-test.yml => build.yml} | 24 +++++++++++++++++++---- .builds/flatpak.yml | 20 ------------------- .builds/pypi.yml | 29 ---------------------------- poetry.lock | 16 +++++++++++++-- pyproject.toml | 1 + 5 files changed, 35 insertions(+), 55 deletions(-) rename .builds/{lint-test.yml => build.yml} (54%) delete mode 100644 .builds/flatpak.yml delete mode 100644 .builds/pypi.yml diff --git a/.builds/lint-test.yml b/.builds/build.yml similarity index 54% rename from .builds/lint-test.yml rename to .builds/build.yml index 0262f9d..1ded96e 100644 --- a/.builds/lint-test.yml +++ b/.builds/build.yml @@ -12,10 +12,10 @@ sources: - https://git.sr.ht/~sumner/sublime-music environment: REPO_NAME: sublime-music -# triggers: -# - action: email -# condition: failure -# to: ~sumner/sublime-music-devel@lists.sr.ht +triggers: + - action: email + condition: failure + to: ~sumner/sublime-music-devel@lists.sr.ht tasks: - setup: | cd ${REPO_NAME} @@ -34,3 +34,19 @@ tasks: Xvfb :119 -screen 0 1024x768x16 & export DISPLAY=:119 pytest + + - build: | + python setup.py sdist + + - build-flatpak: | + cd ${REPO_NAME}/flatpak + # REPO=repo ./flatpak_build.sh + + - deploy-pypi: | + ./cicd/run_if_tagged_with_version \ + "twine upload -r testpypi dist/*" \ + "twine upload dist/*" + + - verify-pypi: | + ./cicd/run_if_tagged_with_version \ + "pip install ${REPO_NAME}" diff --git a/.builds/flatpak.yml b/.builds/flatpak.yml deleted file mode 100644 index cc8de3c..0000000 --- a/.builds/flatpak.yml +++ /dev/null @@ -1,20 +0,0 @@ -image: archlinux -packages: - - flatpak - - flatpak-builder - - python-pip -sources: - - https://git.sr.ht/~sumner/sublime-music -environment: - REPO_NAME: sublime-music -# triggers: -# - action: email -# condition: failure -# to: ~sumner/sublime-music-devel@lists.sr.ht -tasks: - - setup: | - pip install requirements-parser - - - build-flatpak: | - cd ${REPO_NAME}/flatpak - # REPO=repo ./flatpak_build.sh diff --git a/.builds/pypi.yml b/.builds/pypi.yml deleted file mode 100644 index cfe3391..0000000 --- a/.builds/pypi.yml +++ /dev/null @@ -1,29 +0,0 @@ -image: alpine/edge -packages: - - py3-pip - - py3-setuptools - - py3-twine -sources: - - https://git.sr.ht/~sumner/sublime-music -environment: - REPO_NAME: sublime-music -# triggers: -# - action: email -# condition: failure -# to: ~sumner/sublime-music-devel@lists.sr.ht -tasks: - - setup: | - cd ${REPO_NAME} - echo "cd ${REPO_NAME}" >> ~/.buildenv - - - build: | - python3 setup.py sdist - - - deploy-pypi: | - ./cicd/run_if_tagged_with_version \ - "twine upload -r testpypi dist/*" \ - "twine upload dist/*" - - - verify-pypi: | - ./cicd/run_if_tagged_with_version \ - "pip install ${REPO_NAME}" diff --git a/poetry.lock b/poetry.lock index cf371b9..8a2a2e5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -579,6 +579,14 @@ chardet = ">=3.0.2,<4" idna = ">=2.5,<3" urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" +[[package]] +name = "requirements-parser" +version = "0.2.0" +description = "Parses Pip requirement files" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "secretstorage" version = "3.1.2" @@ -693,14 +701,14 @@ python-versions = "*" ifaddr = ">=0.1.7" [extras] -keyring = ["keyring"] chromecast = ["pychromecast"] +keyring = ["keyring"] server = ["bottle"] [metadata] lock-version = "1.0" python-versions = "^3.8" -content-hash = "b205eec2da8442d64ad3e77af6740a626b5e79e32b22709e5954a5d49fc8d72b" +content-hash = "8cc15955b68459eeec39b5401c1433195033006da356b290b3a0f49e58f8bf06" [metadata.files] appdirs = [ @@ -1037,6 +1045,10 @@ requests = [ {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, ] +requirements-parser = [ + {file = "requirements-parser-0.2.0.tar.gz", hash = "sha256:5963ee895c2d05ae9f58d3fc641082fb38021618979d6a152b6b1398bd7d4ed4"}, + {file = "requirements_parser-0.2.0-py2-none-any.whl", hash = "sha256:76650b4a9d98fc65edf008a7920c076bb2a76c08eaae230ce4cfc6f51ea6a773"}, +] secretstorage = [ {file = "SecretStorage-3.1.2-py3-none-any.whl", hash = "sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b"}, {file = "SecretStorage-3.1.2.tar.gz", hash = "sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6"}, diff --git a/pyproject.toml b/pyproject.toml index 145282b..7e26103 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ flake8 = "^3.8.3" mypy = "^0.782" pytest-cov = "^2.10.1" termcolor = "^1.1.0" +requirements-parser = "^0.2.0" [tool.poetry.extras] chromecast = ["pychromecast"] From aec54f8a1d1f6d91ca9e87f2428984beb14fca14 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 09:52:28 -0600 Subject: [PATCH 7/8] Rename package --- pyproject.toml | 4 ++-- {sublime => sublime_music}/__init__.py | 0 {sublime => sublime_music}/__main__.py | 0 {sublime => sublime_music}/adapters/__init__.py | 0 {sublime => sublime_music}/adapters/adapter_base.py | 0 {sublime => sublime_music}/adapters/api_objects.py | 0 .../adapters/configure_server_form.py | 0 .../adapters/filesystem/__init__.py | 0 .../adapters/filesystem/adapter.py | 0 .../adapters/filesystem/models.py | 0 .../adapters/filesystem/sqlite_extensions.py | 0 .../adapters/icons/config-error-symbolic.svg | 0 .../adapters/icons/config-ok-symbolic.svg | 0 .../adapters/images/default-album-art.png | Bin .../adapters/images/default-album-art.svg | 0 {sublime => sublime_music}/adapters/manager.py | 0 .../adapters/subsonic/__init__.py | 0 .../adapters/subsonic/adapter.py | 0 .../adapters/subsonic/api_objects.py | 0 .../subsonic/api_specs/subsonic-rest-api-1.1.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.1.1.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.10.2.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.11.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.12.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.13.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.14.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.15.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.16.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.16.1.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.2.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.3.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.4.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.5.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.6.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.7.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.8.0.xsd | 0 .../subsonic/api_specs/subsonic-rest-api-1.9.0.xsd | 0 .../subsonic/icons/subsonic-connected-symbolic.svg | 0 .../subsonic/icons/subsonic-error-symbolic.svg | 0 .../subsonic/icons/subsonic-offline-symbolic.svg | 0 .../adapters/subsonic/icons/subsonic-symbolic.svg | 0 {sublime => sublime_music}/app.py | 0 {sublime => sublime_music}/config.py | 0 {sublime => sublime_music}/dbus/__init__.py | 0 {sublime => sublime_music}/dbus/manager.py | 0 .../mpris_specs/org.mpris.MediaPlayer2.Player.xml | 0 .../org.mpris.MediaPlayer2.Playlists.xml | 0 .../org.mpris.MediaPlayer2.TrackList.xml | 0 .../dbus/mpris_specs/org.mpris.MediaPlayer2.xml | 0 {sublime => sublime_music}/players/__init__.py | 0 {sublime => sublime_music}/players/base.py | 0 {sublime => sublime_music}/players/chromecast.py | 0 {sublime => sublime_music}/players/manager.py | 0 {sublime => sublime_music}/players/mpv.py | 0 {sublime => sublime_music}/ui/__init__.py | 0 {sublime => sublime_music}/ui/albums.py | 0 {sublime => sublime_music}/ui/app_styles.css | 0 {sublime => sublime_music}/ui/artists.py | 0 {sublime => sublime_music}/ui/browse.py | 0 {sublime => sublime_music}/ui/common/__init__.py | 0 .../ui/common/album_with_songs.py | 0 {sublime => sublime_music}/ui/common/icon_button.py | 0 {sublime => sublime_music}/ui/common/load_error.py | 0 .../ui/common/song_list_column.py | 0 .../ui/common/spinner_image.py | 0 {sublime => sublime_music}/ui/configure_provider.py | 0 .../ui/icons/chromecast-connected-symbolic.svg | 0 .../ui/icons/chromecast-connecting-0-symbolic.svg | 0 .../ui/icons/chromecast-connecting-1-symbolic.svg | 0 .../ui/icons/chromecast-connecting-2-symbolic.svg | 0 .../ui/icons/chromecast-symbolic.svg | 0 .../ui/icons/cloud-offline-symbolic.svg | 0 .../ui/icons/queue-back-symbolic.svg | 0 .../ui/icons/queue-front-symbolic.svg | 0 .../ui/icons/server-connected-symbolic.svg | 0 .../ui/icons/server-error-symbolic.svg | 0 .../ui/icons/server-offline-symbolic.svg | 0 .../ui/images/play-queue-play.png | Bin .../ui/images/play-queue-play.svg | 0 {sublime => sublime_music}/ui/main.py | 0 {sublime => sublime_music}/ui/player_controls.py | 0 {sublime => sublime_music}/ui/playlists.py | 0 {sublime => sublime_music}/ui/state.py | 0 {sublime => sublime_music}/ui/util.py | 0 {sublime => sublime_music}/util.py | 0 85 files changed, 2 insertions(+), 2 deletions(-) rename {sublime => sublime_music}/__init__.py (100%) rename {sublime => sublime_music}/__main__.py (100%) rename {sublime => sublime_music}/adapters/__init__.py (100%) rename {sublime => sublime_music}/adapters/adapter_base.py (100%) rename {sublime => sublime_music}/adapters/api_objects.py (100%) rename {sublime => sublime_music}/adapters/configure_server_form.py (100%) rename {sublime => sublime_music}/adapters/filesystem/__init__.py (100%) rename {sublime => sublime_music}/adapters/filesystem/adapter.py (100%) rename {sublime => sublime_music}/adapters/filesystem/models.py (100%) rename {sublime => sublime_music}/adapters/filesystem/sqlite_extensions.py (100%) rename {sublime => sublime_music}/adapters/icons/config-error-symbolic.svg (100%) rename {sublime => sublime_music}/adapters/icons/config-ok-symbolic.svg (100%) rename {sublime => sublime_music}/adapters/images/default-album-art.png (100%) rename {sublime => sublime_music}/adapters/images/default-album-art.svg (100%) rename {sublime => sublime_music}/adapters/manager.py (100%) rename {sublime => sublime_music}/adapters/subsonic/__init__.py (100%) rename {sublime => sublime_music}/adapters/subsonic/adapter.py (100%) rename {sublime => sublime_music}/adapters/subsonic/api_objects.py (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.1.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.1.1.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.10.2.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.11.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.12.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.13.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.14.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.15.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.16.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.16.1.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.2.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.3.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.4.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.5.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.6.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.7.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.8.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/api_specs/subsonic-rest-api-1.9.0.xsd (100%) rename {sublime => sublime_music}/adapters/subsonic/icons/subsonic-connected-symbolic.svg (100%) rename {sublime => sublime_music}/adapters/subsonic/icons/subsonic-error-symbolic.svg (100%) rename {sublime => sublime_music}/adapters/subsonic/icons/subsonic-offline-symbolic.svg (100%) rename {sublime => sublime_music}/adapters/subsonic/icons/subsonic-symbolic.svg (100%) rename {sublime => sublime_music}/app.py (100%) rename {sublime => sublime_music}/config.py (100%) rename {sublime => sublime_music}/dbus/__init__.py (100%) rename {sublime => sublime_music}/dbus/manager.py (100%) rename {sublime => sublime_music}/dbus/mpris_specs/org.mpris.MediaPlayer2.Player.xml (100%) rename {sublime => sublime_music}/dbus/mpris_specs/org.mpris.MediaPlayer2.Playlists.xml (100%) rename {sublime => sublime_music}/dbus/mpris_specs/org.mpris.MediaPlayer2.TrackList.xml (100%) rename {sublime => sublime_music}/dbus/mpris_specs/org.mpris.MediaPlayer2.xml (100%) rename {sublime => sublime_music}/players/__init__.py (100%) rename {sublime => sublime_music}/players/base.py (100%) rename {sublime => sublime_music}/players/chromecast.py (100%) rename {sublime => sublime_music}/players/manager.py (100%) rename {sublime => sublime_music}/players/mpv.py (100%) rename {sublime => sublime_music}/ui/__init__.py (100%) rename {sublime => sublime_music}/ui/albums.py (100%) rename {sublime => sublime_music}/ui/app_styles.css (100%) rename {sublime => sublime_music}/ui/artists.py (100%) rename {sublime => sublime_music}/ui/browse.py (100%) rename {sublime => sublime_music}/ui/common/__init__.py (100%) rename {sublime => sublime_music}/ui/common/album_with_songs.py (100%) rename {sublime => sublime_music}/ui/common/icon_button.py (100%) rename {sublime => sublime_music}/ui/common/load_error.py (100%) rename {sublime => sublime_music}/ui/common/song_list_column.py (100%) rename {sublime => sublime_music}/ui/common/spinner_image.py (100%) rename {sublime => sublime_music}/ui/configure_provider.py (100%) rename {sublime => sublime_music}/ui/icons/chromecast-connected-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/chromecast-connecting-0-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/chromecast-connecting-1-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/chromecast-connecting-2-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/chromecast-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/cloud-offline-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/queue-back-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/queue-front-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/server-connected-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/server-error-symbolic.svg (100%) rename {sublime => sublime_music}/ui/icons/server-offline-symbolic.svg (100%) rename {sublime => sublime_music}/ui/images/play-queue-play.png (100%) rename {sublime => sublime_music}/ui/images/play-queue-play.svg (100%) rename {sublime => sublime_music}/ui/main.py (100%) rename {sublime => sublime_music}/ui/player_controls.py (100%) rename {sublime => sublime_music}/ui/playlists.py (100%) rename {sublime => sublime_music}/ui/state.py (100%) rename {sublime => sublime_music}/ui/util.py (100%) rename {sublime => sublime_music}/util.py (100%) diff --git a/pyproject.toml b/pyproject.toml index 7e26103..fd734ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = "sublime-music" +name = "sublime_music" version = "0.11.9" description = "A native GTK *sonic client." license = "GPL-3.0-or-later" @@ -25,7 +25,7 @@ exclude = ["tests"] "Bug Tracker" = "https://todo.sr.ht/~sumner/sublime-music" [tool.poetry.scripts] -sublime-music = 'sublime.__main__:main' +sublime-music = 'sublime_music.__main__:main' [tool.poetry.dependencies] python = "^3.8" diff --git a/sublime/__init__.py b/sublime_music/__init__.py similarity index 100% rename from sublime/__init__.py rename to sublime_music/__init__.py diff --git a/sublime/__main__.py b/sublime_music/__main__.py similarity index 100% rename from sublime/__main__.py rename to sublime_music/__main__.py diff --git a/sublime/adapters/__init__.py b/sublime_music/adapters/__init__.py similarity index 100% rename from sublime/adapters/__init__.py rename to sublime_music/adapters/__init__.py diff --git a/sublime/adapters/adapter_base.py b/sublime_music/adapters/adapter_base.py similarity index 100% rename from sublime/adapters/adapter_base.py rename to sublime_music/adapters/adapter_base.py diff --git a/sublime/adapters/api_objects.py b/sublime_music/adapters/api_objects.py similarity index 100% rename from sublime/adapters/api_objects.py rename to sublime_music/adapters/api_objects.py diff --git a/sublime/adapters/configure_server_form.py b/sublime_music/adapters/configure_server_form.py similarity index 100% rename from sublime/adapters/configure_server_form.py rename to sublime_music/adapters/configure_server_form.py diff --git a/sublime/adapters/filesystem/__init__.py b/sublime_music/adapters/filesystem/__init__.py similarity index 100% rename from sublime/adapters/filesystem/__init__.py rename to sublime_music/adapters/filesystem/__init__.py diff --git a/sublime/adapters/filesystem/adapter.py b/sublime_music/adapters/filesystem/adapter.py similarity index 100% rename from sublime/adapters/filesystem/adapter.py rename to sublime_music/adapters/filesystem/adapter.py diff --git a/sublime/adapters/filesystem/models.py b/sublime_music/adapters/filesystem/models.py similarity index 100% rename from sublime/adapters/filesystem/models.py rename to sublime_music/adapters/filesystem/models.py diff --git a/sublime/adapters/filesystem/sqlite_extensions.py b/sublime_music/adapters/filesystem/sqlite_extensions.py similarity index 100% rename from sublime/adapters/filesystem/sqlite_extensions.py rename to sublime_music/adapters/filesystem/sqlite_extensions.py diff --git a/sublime/adapters/icons/config-error-symbolic.svg b/sublime_music/adapters/icons/config-error-symbolic.svg similarity index 100% rename from sublime/adapters/icons/config-error-symbolic.svg rename to sublime_music/adapters/icons/config-error-symbolic.svg diff --git a/sublime/adapters/icons/config-ok-symbolic.svg b/sublime_music/adapters/icons/config-ok-symbolic.svg similarity index 100% rename from sublime/adapters/icons/config-ok-symbolic.svg rename to sublime_music/adapters/icons/config-ok-symbolic.svg diff --git a/sublime/adapters/images/default-album-art.png b/sublime_music/adapters/images/default-album-art.png similarity index 100% rename from sublime/adapters/images/default-album-art.png rename to sublime_music/adapters/images/default-album-art.png diff --git a/sublime/adapters/images/default-album-art.svg b/sublime_music/adapters/images/default-album-art.svg similarity index 100% rename from sublime/adapters/images/default-album-art.svg rename to sublime_music/adapters/images/default-album-art.svg diff --git a/sublime/adapters/manager.py b/sublime_music/adapters/manager.py similarity index 100% rename from sublime/adapters/manager.py rename to sublime_music/adapters/manager.py diff --git a/sublime/adapters/subsonic/__init__.py b/sublime_music/adapters/subsonic/__init__.py similarity index 100% rename from sublime/adapters/subsonic/__init__.py rename to sublime_music/adapters/subsonic/__init__.py diff --git a/sublime/adapters/subsonic/adapter.py b/sublime_music/adapters/subsonic/adapter.py similarity index 100% rename from sublime/adapters/subsonic/adapter.py rename to sublime_music/adapters/subsonic/adapter.py diff --git a/sublime/adapters/subsonic/api_objects.py b/sublime_music/adapters/subsonic/api_objects.py similarity index 100% rename from sublime/adapters/subsonic/api_objects.py rename to sublime_music/adapters/subsonic/api_objects.py diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.1.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.1.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.1.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.1.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.1.1.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.1.1.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.1.1.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.1.1.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.10.2.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.10.2.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.10.2.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.10.2.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.11.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.11.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.11.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.11.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.12.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.12.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.12.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.12.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.13.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.13.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.13.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.13.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.14.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.14.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.14.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.14.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.15.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.15.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.15.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.15.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.16.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.16.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.16.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.16.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.16.1.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.16.1.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.16.1.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.16.1.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.2.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.2.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.2.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.2.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.3.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.3.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.3.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.3.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.4.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.4.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.4.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.4.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.5.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.5.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.5.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.5.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.6.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.6.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.6.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.6.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.7.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.7.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.7.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.7.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.8.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.8.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.8.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.8.0.xsd diff --git a/sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.9.0.xsd b/sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.9.0.xsd similarity index 100% rename from sublime/adapters/subsonic/api_specs/subsonic-rest-api-1.9.0.xsd rename to sublime_music/adapters/subsonic/api_specs/subsonic-rest-api-1.9.0.xsd diff --git a/sublime/adapters/subsonic/icons/subsonic-connected-symbolic.svg b/sublime_music/adapters/subsonic/icons/subsonic-connected-symbolic.svg similarity index 100% rename from sublime/adapters/subsonic/icons/subsonic-connected-symbolic.svg rename to sublime_music/adapters/subsonic/icons/subsonic-connected-symbolic.svg diff --git a/sublime/adapters/subsonic/icons/subsonic-error-symbolic.svg b/sublime_music/adapters/subsonic/icons/subsonic-error-symbolic.svg similarity index 100% rename from sublime/adapters/subsonic/icons/subsonic-error-symbolic.svg rename to sublime_music/adapters/subsonic/icons/subsonic-error-symbolic.svg diff --git a/sublime/adapters/subsonic/icons/subsonic-offline-symbolic.svg b/sublime_music/adapters/subsonic/icons/subsonic-offline-symbolic.svg similarity index 100% rename from sublime/adapters/subsonic/icons/subsonic-offline-symbolic.svg rename to sublime_music/adapters/subsonic/icons/subsonic-offline-symbolic.svg diff --git a/sublime/adapters/subsonic/icons/subsonic-symbolic.svg b/sublime_music/adapters/subsonic/icons/subsonic-symbolic.svg similarity index 100% rename from sublime/adapters/subsonic/icons/subsonic-symbolic.svg rename to sublime_music/adapters/subsonic/icons/subsonic-symbolic.svg diff --git a/sublime/app.py b/sublime_music/app.py similarity index 100% rename from sublime/app.py rename to sublime_music/app.py diff --git a/sublime/config.py b/sublime_music/config.py similarity index 100% rename from sublime/config.py rename to sublime_music/config.py diff --git a/sublime/dbus/__init__.py b/sublime_music/dbus/__init__.py similarity index 100% rename from sublime/dbus/__init__.py rename to sublime_music/dbus/__init__.py diff --git a/sublime/dbus/manager.py b/sublime_music/dbus/manager.py similarity index 100% rename from sublime/dbus/manager.py rename to sublime_music/dbus/manager.py diff --git a/sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.Player.xml b/sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.Player.xml similarity index 100% rename from sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.Player.xml rename to sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.Player.xml diff --git a/sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.Playlists.xml b/sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.Playlists.xml similarity index 100% rename from sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.Playlists.xml rename to sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.Playlists.xml diff --git a/sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.TrackList.xml b/sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.TrackList.xml similarity index 100% rename from sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.TrackList.xml rename to sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.TrackList.xml diff --git a/sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.xml b/sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.xml similarity index 100% rename from sublime/dbus/mpris_specs/org.mpris.MediaPlayer2.xml rename to sublime_music/dbus/mpris_specs/org.mpris.MediaPlayer2.xml diff --git a/sublime/players/__init__.py b/sublime_music/players/__init__.py similarity index 100% rename from sublime/players/__init__.py rename to sublime_music/players/__init__.py diff --git a/sublime/players/base.py b/sublime_music/players/base.py similarity index 100% rename from sublime/players/base.py rename to sublime_music/players/base.py diff --git a/sublime/players/chromecast.py b/sublime_music/players/chromecast.py similarity index 100% rename from sublime/players/chromecast.py rename to sublime_music/players/chromecast.py diff --git a/sublime/players/manager.py b/sublime_music/players/manager.py similarity index 100% rename from sublime/players/manager.py rename to sublime_music/players/manager.py diff --git a/sublime/players/mpv.py b/sublime_music/players/mpv.py similarity index 100% rename from sublime/players/mpv.py rename to sublime_music/players/mpv.py diff --git a/sublime/ui/__init__.py b/sublime_music/ui/__init__.py similarity index 100% rename from sublime/ui/__init__.py rename to sublime_music/ui/__init__.py diff --git a/sublime/ui/albums.py b/sublime_music/ui/albums.py similarity index 100% rename from sublime/ui/albums.py rename to sublime_music/ui/albums.py diff --git a/sublime/ui/app_styles.css b/sublime_music/ui/app_styles.css similarity index 100% rename from sublime/ui/app_styles.css rename to sublime_music/ui/app_styles.css diff --git a/sublime/ui/artists.py b/sublime_music/ui/artists.py similarity index 100% rename from sublime/ui/artists.py rename to sublime_music/ui/artists.py diff --git a/sublime/ui/browse.py b/sublime_music/ui/browse.py similarity index 100% rename from sublime/ui/browse.py rename to sublime_music/ui/browse.py diff --git a/sublime/ui/common/__init__.py b/sublime_music/ui/common/__init__.py similarity index 100% rename from sublime/ui/common/__init__.py rename to sublime_music/ui/common/__init__.py diff --git a/sublime/ui/common/album_with_songs.py b/sublime_music/ui/common/album_with_songs.py similarity index 100% rename from sublime/ui/common/album_with_songs.py rename to sublime_music/ui/common/album_with_songs.py diff --git a/sublime/ui/common/icon_button.py b/sublime_music/ui/common/icon_button.py similarity index 100% rename from sublime/ui/common/icon_button.py rename to sublime_music/ui/common/icon_button.py diff --git a/sublime/ui/common/load_error.py b/sublime_music/ui/common/load_error.py similarity index 100% rename from sublime/ui/common/load_error.py rename to sublime_music/ui/common/load_error.py diff --git a/sublime/ui/common/song_list_column.py b/sublime_music/ui/common/song_list_column.py similarity index 100% rename from sublime/ui/common/song_list_column.py rename to sublime_music/ui/common/song_list_column.py diff --git a/sublime/ui/common/spinner_image.py b/sublime_music/ui/common/spinner_image.py similarity index 100% rename from sublime/ui/common/spinner_image.py rename to sublime_music/ui/common/spinner_image.py diff --git a/sublime/ui/configure_provider.py b/sublime_music/ui/configure_provider.py similarity index 100% rename from sublime/ui/configure_provider.py rename to sublime_music/ui/configure_provider.py diff --git a/sublime/ui/icons/chromecast-connected-symbolic.svg b/sublime_music/ui/icons/chromecast-connected-symbolic.svg similarity index 100% rename from sublime/ui/icons/chromecast-connected-symbolic.svg rename to sublime_music/ui/icons/chromecast-connected-symbolic.svg diff --git a/sublime/ui/icons/chromecast-connecting-0-symbolic.svg b/sublime_music/ui/icons/chromecast-connecting-0-symbolic.svg similarity index 100% rename from sublime/ui/icons/chromecast-connecting-0-symbolic.svg rename to sublime_music/ui/icons/chromecast-connecting-0-symbolic.svg diff --git a/sublime/ui/icons/chromecast-connecting-1-symbolic.svg b/sublime_music/ui/icons/chromecast-connecting-1-symbolic.svg similarity index 100% rename from sublime/ui/icons/chromecast-connecting-1-symbolic.svg rename to sublime_music/ui/icons/chromecast-connecting-1-symbolic.svg diff --git a/sublime/ui/icons/chromecast-connecting-2-symbolic.svg b/sublime_music/ui/icons/chromecast-connecting-2-symbolic.svg similarity index 100% rename from sublime/ui/icons/chromecast-connecting-2-symbolic.svg rename to sublime_music/ui/icons/chromecast-connecting-2-symbolic.svg diff --git a/sublime/ui/icons/chromecast-symbolic.svg b/sublime_music/ui/icons/chromecast-symbolic.svg similarity index 100% rename from sublime/ui/icons/chromecast-symbolic.svg rename to sublime_music/ui/icons/chromecast-symbolic.svg diff --git a/sublime/ui/icons/cloud-offline-symbolic.svg b/sublime_music/ui/icons/cloud-offline-symbolic.svg similarity index 100% rename from sublime/ui/icons/cloud-offline-symbolic.svg rename to sublime_music/ui/icons/cloud-offline-symbolic.svg diff --git a/sublime/ui/icons/queue-back-symbolic.svg b/sublime_music/ui/icons/queue-back-symbolic.svg similarity index 100% rename from sublime/ui/icons/queue-back-symbolic.svg rename to sublime_music/ui/icons/queue-back-symbolic.svg diff --git a/sublime/ui/icons/queue-front-symbolic.svg b/sublime_music/ui/icons/queue-front-symbolic.svg similarity index 100% rename from sublime/ui/icons/queue-front-symbolic.svg rename to sublime_music/ui/icons/queue-front-symbolic.svg diff --git a/sublime/ui/icons/server-connected-symbolic.svg b/sublime_music/ui/icons/server-connected-symbolic.svg similarity index 100% rename from sublime/ui/icons/server-connected-symbolic.svg rename to sublime_music/ui/icons/server-connected-symbolic.svg diff --git a/sublime/ui/icons/server-error-symbolic.svg b/sublime_music/ui/icons/server-error-symbolic.svg similarity index 100% rename from sublime/ui/icons/server-error-symbolic.svg rename to sublime_music/ui/icons/server-error-symbolic.svg diff --git a/sublime/ui/icons/server-offline-symbolic.svg b/sublime_music/ui/icons/server-offline-symbolic.svg similarity index 100% rename from sublime/ui/icons/server-offline-symbolic.svg rename to sublime_music/ui/icons/server-offline-symbolic.svg diff --git a/sublime/ui/images/play-queue-play.png b/sublime_music/ui/images/play-queue-play.png similarity index 100% rename from sublime/ui/images/play-queue-play.png rename to sublime_music/ui/images/play-queue-play.png diff --git a/sublime/ui/images/play-queue-play.svg b/sublime_music/ui/images/play-queue-play.svg similarity index 100% rename from sublime/ui/images/play-queue-play.svg rename to sublime_music/ui/images/play-queue-play.svg diff --git a/sublime/ui/main.py b/sublime_music/ui/main.py similarity index 100% rename from sublime/ui/main.py rename to sublime_music/ui/main.py diff --git a/sublime/ui/player_controls.py b/sublime_music/ui/player_controls.py similarity index 100% rename from sublime/ui/player_controls.py rename to sublime_music/ui/player_controls.py diff --git a/sublime/ui/playlists.py b/sublime_music/ui/playlists.py similarity index 100% rename from sublime/ui/playlists.py rename to sublime_music/ui/playlists.py diff --git a/sublime/ui/state.py b/sublime_music/ui/state.py similarity index 100% rename from sublime/ui/state.py rename to sublime_music/ui/state.py diff --git a/sublime/ui/util.py b/sublime_music/ui/util.py similarity index 100% rename from sublime/ui/util.py rename to sublime_music/ui/util.py diff --git a/sublime/util.py b/sublime_music/util.py similarity index 100% rename from sublime/util.py rename to sublime_music/util.py From 74e792c270d32bab32f0e7ba82c527fb15e63e35 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Sat, 19 Sep 2020 09:58:18 -0600 Subject: [PATCH 8/8] Update some paths --- .builds/build.yml | 2 +- setup.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.builds/build.yml b/.builds/build.yml index 1ded96e..cf7e874 100644 --- a/.builds/build.yml +++ b/.builds/build.yml @@ -27,7 +27,7 @@ tasks: python setup.py check -mrs black --check . flake8 - mypy sublime tests/**/*.py + mypy sublime_music tests/**/*.py cicd/custom_style_check.py - test: | diff --git a/setup.py b/setup.py index 9ad0740..a5c0821 100644 --- a/setup.py +++ b/setup.py @@ -8,19 +8,19 @@ with open(here.joinpath("README.rst"), encoding="utf-8") as f: long_description = f.read() # Find the version -with open(here.joinpath("sublime", "__init__.py")) as f: +with open(here.joinpath("sublime_music", "__init__.py")) as f: for line in f: if line.startswith("__version__"): version = eval(line.split()[-1]) break package_data_dirs = [ - here.joinpath("sublime", "adapters", "icons"), - here.joinpath("sublime", "adapters", "images"), - here.joinpath("sublime", "adapters", "subsonic", "icons"), - here.joinpath("sublime", "dbus", "mpris_specs"), - here.joinpath("sublime", "ui", "icons"), - here.joinpath("sublime", "ui", "images"), + here.joinpath("sublime_music", "adapters", "icons"), + here.joinpath("sublime_music", "adapters", "images"), + here.joinpath("sublime_music", "adapters", "subsonic", "icons"), + here.joinpath("sublime_music", "dbus", "mpris_specs"), + here.joinpath("sublime_music", "ui", "icons"), + here.joinpath("sublime_music", "ui", "images"), ] package_data_files = [] for data_dir in package_data_dirs: @@ -28,7 +28,7 @@ for data_dir in package_data_dirs: package_data_files.append(str(file)) setup( - name="sublime-music", + name="sublime_music", version=version, url="https://gitlab.com/sublime-music/sublime-music", description="A native GTK *sonic client.", @@ -51,7 +51,7 @@ setup( ], keywords="airsonic subsonic libresonic gonic music", packages=find_packages(exclude=["tests"]), - package_data={"sublime": ["ui/app_styles.css", *package_data_files]}, + package_data={"sublime_music": ["ui/app_styles.css", *package_data_files]}, install_requires=[ "bleach", "dataclasses-json",