mirror of
https://github.com/yaronzz/Tidal-Media-Downloader.git
synced 2026-06-13 12:15:12 +03:00
Compare commits
359 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f4854f4b74 | |||
| 8352f0f6e2 | |||
| a8da5c0ff3 | |||
| df7c444487 | |||
| d88dca4da6 | |||
| 88b5b61328 | |||
| 56c9cf5695 | |||
| 379eca8458 | |||
| 7d6f9fc6e1 | |||
| 87eabab36f | |||
| 288c75bcc7 | |||
| 62d83b5975 | |||
| 251af9e745 | |||
| 0751c37b35 | |||
| 4f32b14441 | |||
| 97928ef207 | |||
| 9edd5967f0 | |||
| 8449b85d81 | |||
| 2f4ad82421 | |||
| 513be57c3d | |||
| 3eb11252c2 | |||
| b972f7cda8 | |||
| b1b643109c | |||
| c15ad63542 | |||
| 09321db35e | |||
| 132e516250 | |||
| a771c598ae | |||
| db76e84123 | |||
| 7eb4419177 | |||
| df3c405667 | |||
| 951fd102ad | |||
| 252076f6dd | |||
| 11828a0e8e | |||
| 93f363f405 | |||
| 12a96d8a46 | |||
| 238b2da4b3 | |||
| 76313d68c9 | |||
| 4e8751ceb1 | |||
| 2dfcbad8f0 | |||
| 07d18ce2d6 | |||
| 7fdd307176 | |||
| 11805382cc | |||
| 044a847e78 | |||
| 6e49253e99 | |||
| 0c83717469 | |||
| 7f1afb27f1 | |||
| 18efb49213 | |||
| a275275cb6 | |||
| 7e5b6d22c4 | |||
| 96742046ba | |||
| 3199dcedc6 | |||
| 2cf59b3195 | |||
| be84a3631a | |||
| 9ce35af72f | |||
| 9d904a0fea | |||
| 5e05afd775 | |||
| dece506d58 | |||
| c2cc170988 | |||
| 3cab9ea295 | |||
| 5cf094d227 | |||
| 2e1e15ed3f | |||
| 7434470216 | |||
| 2ce2a310ae | |||
| dfc7af7796 | |||
| 63bf063dd3 | |||
| 3e8a3436b4 | |||
| e08e5efc88 | |||
| 7f3758e18c | |||
| 3e2d74a37f | |||
| 69ccd65025 | |||
| 81b82e6c29 | |||
| 346befda6d | |||
| 450102bfea | |||
| a966b3d93d | |||
| 55df515256 | |||
| 242747719a | |||
| e3c5886a02 | |||
| 33c49b83db | |||
| ed13b9b92d | |||
| e45f649e46 | |||
| 0172301769 | |||
| a7aa38e563 | |||
| fd97a2b966 | |||
| e1ee47b93c | |||
| 61b9dd3af8 | |||
| 628a42b058 | |||
| 2c392f0e22 | |||
| dc57d4d01d | |||
| 8ed83b1672 | |||
| 3099820956 | |||
| d643de43e9 | |||
| 39db4730c5 | |||
| 937aa7ca8f | |||
| 84b9f6f6bc | |||
| b1ebd6f0b2 | |||
| e1562ba30e | |||
| 8876be13b6 | |||
| 30a6c8c55a | |||
| eb01de7f3a | |||
| e652556de2 | |||
| 00ef2f906f | |||
| aba9493201 | |||
| c78a56fff0 | |||
| 56bf0f9510 | |||
| 2ebf80869c | |||
| bb5be5e5fb | |||
| 5c2a13d4d1 | |||
| c61be4bbf3 | |||
| a969583d79 | |||
| 9f9a4f9aef | |||
| 3b3af6a174 | |||
| 166961297e | |||
| 1f5343569f | |||
| 9e9d47f470 | |||
| 6870a8c37f | |||
| 4d368dd04d | |||
| 64b98ee117 | |||
| 5ec77efb19 | |||
| 65da2f7272 | |||
| a5fb92db92 | |||
| 81e244f230 | |||
| 6a1b931340 | |||
| 8a21b01c1d | |||
| 96f46c2b59 | |||
| ffe335c17e | |||
| 79b537c186 | |||
| a806785609 | |||
| 06ff60ca74 | |||
| b34013129e | |||
| f1a5b1d764 | |||
| d52980506c | |||
| 34bab40d3d | |||
| 747d06c7b4 | |||
| 41573b7b39 | |||
| d7e078db2e | |||
| 363a854428 | |||
| ad00099c9d | |||
| 6676a380e1 | |||
| bab13ff718 | |||
| 9707c5c276 | |||
| 48206d675a | |||
| f877c184bb | |||
| 59b360b285 | |||
| 1a09571788 | |||
| 2484a8d4d8 | |||
| 5e73ad35fa | |||
| 8503a622b0 | |||
| ab479300ea | |||
| 96fb847479 | |||
| 5484669333 | |||
| e366edbbea | |||
| e8ef25183d | |||
| c94c5283a7 | |||
| 77803c0b41 | |||
| b5bd4af56d | |||
| 0a28baad64 | |||
| 6a1cd1d1d1 | |||
| 25e72aa45e | |||
| 90f869fcdb | |||
| 72a2cb804a | |||
| 752fb9e719 | |||
| ac745e1434 | |||
| cbb4480d1e | |||
| a410370f45 | |||
| b8c4333d4e | |||
| 7e165f6c17 | |||
| c9ae7bfebd | |||
| 1d5b8cd8f6 | |||
| d41c8ddcae | |||
| 3d4b143c74 | |||
| 5892525593 | |||
| ff0e794b8c | |||
| 5f42afa31a | |||
| 2a56bee611 | |||
| 685b7cb1f8 | |||
| b0df00c0a3 | |||
| 30917d1b0f | |||
| 3848c4cf89 | |||
| 753b6f6f76 | |||
| d6739dc63e | |||
| 4e14fb0501 | |||
| 397ad9f823 | |||
| d2218c58c1 | |||
| 7627c2a0f7 | |||
| 69a7ff6813 | |||
| 133def9722 | |||
| 1b3afaabd0 | |||
| 9cb690378b | |||
| dd4b7254d9 | |||
| 394506e40d | |||
| 6399cab7c4 | |||
| ba1a559a4b | |||
| 41d7e30df5 | |||
| 94139c9f79 | |||
| 5d4f8fb314 | |||
| beae239007 | |||
| f20c84eb6e | |||
| 588482707a | |||
| 2ebb283119 | |||
| 3bfa300fad | |||
| 8ca30f65f3 | |||
| fa6a9fbbf8 | |||
| 8af25e0600 | |||
| 944b98c4b4 | |||
| 8254a61389 | |||
| d016c433ff | |||
| 5e0b4303fd | |||
| dc1ba689c4 | |||
| fc96331c1c | |||
| 6cc1805c48 | |||
| fa05a63adf | |||
| de26068faf | |||
| 273fef3526 | |||
| 66b24c90e8 | |||
| 07e20b0f3d | |||
| 133dd93dda | |||
| 4bbd54a3b0 | |||
| 49714129b1 | |||
| 6fd2ec4a48 | |||
| f9f510fca1 | |||
| d65d474462 | |||
| d8db1a4136 | |||
| 953edfc174 | |||
| 580c707369 | |||
| b56973e7b3 | |||
| 17ad5aed6e | |||
| e84185febb | |||
| ec9a4f2d90 | |||
| c0088b04ce | |||
| ae3347fc70 | |||
| ffa342d69e | |||
| 7676a7000d | |||
| 38ea6c307f | |||
| 2fc3140d26 | |||
| 97efe6ba99 | |||
| 27cca38398 | |||
| ece21c126f | |||
| d035a7e01c | |||
| 859503f518 | |||
| 3cce1077b8 | |||
| da9a50829e | |||
| 67f8337a7d | |||
| 79df599882 | |||
| 5ca25ac55d | |||
| a2eb174b68 | |||
| aedfa6cfda | |||
| 5b403f7342 | |||
| 2f9b972157 | |||
| a7e49ed0c3 | |||
| eafae6a2f7 | |||
| 93af46ca6d | |||
| a71586b100 | |||
| 0f2a829405 | |||
| f4a40ea1bd | |||
| a90cc7f0d3 | |||
| 2b166bddd3 | |||
| 81312d979e | |||
| 37c10f6887 | |||
| 8bce18d142 | |||
| d0d854c88c | |||
| 6487568646 | |||
| 23f8f1a75c | |||
| eacd1d09b6 | |||
| 9d903f6f15 | |||
| 44eeeb89f1 | |||
| f4d8a89336 | |||
| af6f9706fb | |||
| ac2671cdf0 | |||
| 67aec8be03 | |||
| b23b292749 | |||
| e38a3c4b50 | |||
| 99e2039e1e | |||
| 96a2c10548 | |||
| 7392b24c0b | |||
| b9a919ca55 | |||
| 158ea422e9 | |||
| 72dffe5822 | |||
| 13d2e70a43 | |||
| 33673d612e | |||
| 6aeac3ddb5 | |||
| 75ca800dce | |||
| cae74e8ebd | |||
| ca3f544fc6 | |||
| 2ace7ce319 | |||
| 659f0a1fa6 | |||
| 8e26911fd4 | |||
| 7a2267eb7b | |||
| 3127d281fa | |||
| fdac054187 | |||
| fc2e899cdc | |||
| 2b1f9198a5 | |||
| eb8b0ee57d | |||
| 23638ecc80 | |||
| 1e2423f7a1 | |||
| c245903066 | |||
| 927554a56c | |||
| 0f43ca96b1 | |||
| 42db8237e7 | |||
| f165976c8b | |||
| 75f840c6f8 | |||
| 537eeebc04 | |||
| 5dc30f430e | |||
| f5de0125a4 | |||
| 026ddac8a5 | |||
| 05b900ec4c | |||
| 7453dab3e2 | |||
| 2c7f5b479f | |||
| a7d47ca728 | |||
| dc4d3565b9 | |||
| 6f8d2b0949 | |||
| 3774497c09 | |||
| cfc7809327 | |||
| fcfdb11b1e | |||
| eccedb9a45 | |||
| 71d1c32114 | |||
| 73e3d20f0b | |||
| 4e9532d51e | |||
| 4754ac264b | |||
| 4028f69875 | |||
| 521881fc44 | |||
| fa8958af57 | |||
| e7d9f8223e | |||
| 7efbf57fd2 | |||
| 68fe880d77 | |||
| 42ba56f9fc | |||
| 5602fab50f | |||
| 2a87764019 | |||
| 50f0b234d0 | |||
| 3a11633ad9 | |||
| b1bb8191f0 | |||
| c89e39c4e6 | |||
| 63e9ace797 | |||
| 5f9a985fca | |||
| e6cf8dbba1 | |||
| 8f14c87f5f | |||
| f262ebf0a3 | |||
| 1ab94e4659 | |||
| 00fc75342e | |||
| 581650d68f | |||
| da82076632 | |||
| 9d4745fd14 | |||
| e8ffdd08b7 | |||
| fabb23c313 | |||
| 7bbd0d0fcf | |||
| 5a007d4ef3 | |||
| 9951c0a200 | |||
| 0ab3b1d6f4 | |||
| b551f35337 | |||
| f6e44d4a34 | |||
| 2ba8765e77 | |||
| 973d06b02a | |||
| e59a5d1b8e | |||
| 6915c658ff | |||
| 5418403887 | |||
| 05646cfdf3 | |||
| 1ea18455f9 | |||
| 39dab5b134 | |||
| 93368cc4ac | |||
| 273fc96e10 |
+1
-1
@@ -3,7 +3,7 @@
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
ko_fi: yaronzz
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
name: Bug Report
|
||||
description: Create a bug report to help us improve.
|
||||
title: "[BUG]: "
|
||||
labels: bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search for this issue in issues-page first. Avoid duplication.
|
||||
Please read Wiki first.
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader/wiki
|
||||
- type: textarea
|
||||
id: which-tool
|
||||
attributes:
|
||||
label: Which tool
|
||||
description: Describe which tool has been used.
|
||||
placeholder: |
|
||||
tidal-gui or tidal-dl
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Describe the version of the tool.
|
||||
placeholder: |
|
||||
eg 2019.12.1.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform
|
||||
description: Describe the platform on which the tool has been used.
|
||||
placeholder: |
|
||||
Windows\Linux\Macos\Android
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: describe-bug
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: Describe the bug as accurately as possible.
|
||||
placeholder: |
|
||||
How to reappear this bug?
|
||||
Which albumID\trackID\artistID?
|
||||
Please describe in detail.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Add screenshots
|
||||
description: Please add screenshots if available.
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a bug report to help us improve
|
||||
title: "[BUG] xxxxxxxxxxxxx"
|
||||
labels: bug
|
||||
---
|
||||
<!-- Please search for this issue in issues-page first. Avoid duplication. -->
|
||||
<!-- Please read Wiki first. -->
|
||||
<!-- https://github.com/yaronzz/Tidal-Media-Downloader/wiki -->
|
||||
|
||||
**Which tool**
|
||||
<!-- tidal-gui or tidal-dl -->
|
||||
|
||||
**Version**
|
||||
<!-- eg 2019.12.1.0 -->
|
||||
|
||||
**Platform**
|
||||
<!-- Windows\Linux\Macos\Android -->
|
||||
|
||||
**Bug description**
|
||||
<!-- How to reappear this bug?
|
||||
Which albumID\trackID\artistID?
|
||||
Please describe in detail. -->
|
||||
|
||||
**Screenshot**
|
||||
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Feature Request
|
||||
description: Open a feature request to Tidal-Media-Downloader.
|
||||
title: "[FEATURE]: "
|
||||
labels: feature request
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search for this issue in issues-page first. Avoid duplication.
|
||||
Please read Wiki first.
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader/wiki
|
||||
- type: textarea
|
||||
id: which-tool
|
||||
attributes:
|
||||
label: Which tool
|
||||
description: Describe for which tool you want a feature to be added.
|
||||
placeholder: |
|
||||
tidal-gui or tidal-dl
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Describe the feature
|
||||
description: Describe the feature as accurately as possible.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Add screenshots
|
||||
description: Please add screenshots if available.
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Open a feature request to Tidal-Media-Downloader
|
||||
title: "[FEATURE] xxxxxxxxxxxxx"
|
||||
labels: feature request
|
||||
---
|
||||
<!-- Please search for this issue in issues-page first. Avoid duplication. -->
|
||||
<!-- Please read Wiki first. -->
|
||||
<!-- https://github.com/yaronzz/Tidal-Media-Downloader/wiki -->
|
||||
|
||||
**Which tool**
|
||||
<!-- tidal-gui or tidal-dl -->
|
||||
|
||||
**Which feature**
|
||||
<!-- eg. Support IOS -->
|
||||
|
||||
**Description**
|
||||
<!-- Please describe in detail. Screenshot-->
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Questions
|
||||
description: Question for the tool.
|
||||
title: "[QUESTION]: "
|
||||
labels: question
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search for this issue in issues-page first. Avoid duplication.
|
||||
Please read Wiki first.
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader/wiki
|
||||
- type: textarea
|
||||
id: which-tool
|
||||
attributes:
|
||||
label: Which tool
|
||||
description: Describe which tool the question is about.
|
||||
placeholder: |
|
||||
tidal-gui or tidal-dl
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Describe your question
|
||||
description: Describe your question as accurately as possible.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Add screenshots
|
||||
description: Please add screenshots if available.
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Question for the tool
|
||||
title: "[QUESTION] xxxxxxxxxxxxx"
|
||||
labels: question
|
||||
---
|
||||
<!-- Please search for this issue in issues-page first. Avoid duplication. -->
|
||||
<!-- Please read Wiki first. -->
|
||||
<!--
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader/wiki
|
||||
https://yaronzz.top/post/tidal_dl_installation/
|
||||
-->
|
||||
|
||||
**Which tool**
|
||||
<!-- tidal-gui or tidal-dl -->
|
||||
|
||||
**Question**
|
||||
@@ -0,0 +1,28 @@
|
||||
# # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
# #
|
||||
# # You can adjust the behavior by modifying this file.
|
||||
# # For more information, see:
|
||||
# # https://github.com/actions/stale
|
||||
# name: Mark stale issues and pull requests
|
||||
|
||||
# on:
|
||||
# schedule:
|
||||
# - cron: '45 15 * * *'
|
||||
|
||||
# jobs:
|
||||
# stale:
|
||||
|
||||
# runs-on: ubuntu-latest
|
||||
# permissions:
|
||||
# issues: write
|
||||
# pull-requests: write
|
||||
|
||||
# steps:
|
||||
# - uses: actions/stale@v6
|
||||
# with:
|
||||
# repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity.'
|
||||
# stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity.'
|
||||
# stale-issue-label: 'no-issue-activity'
|
||||
# stale-pr-label: 'no-pr-activity'
|
||||
# operations-per-run: 60
|
||||
@@ -0,0 +1,77 @@
|
||||
name: Build exe
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
pip3 install wheel
|
||||
pip3 install pyinstaller
|
||||
pip3 install PyQt5
|
||||
pip3 install -r requirements.txt --upgrade
|
||||
working-directory: TIDALDL-PY
|
||||
|
||||
- name: Clean directory
|
||||
shell: bash
|
||||
run: |
|
||||
rm -rf dist
|
||||
rm -rf build
|
||||
rm -rf tidal_dl.egg-info
|
||||
rm -rf tidal_gui.egg-info
|
||||
rm -rf MANIFEST.in
|
||||
working-directory: TIDALDL-PY
|
||||
|
||||
- name: Build tidal-dl
|
||||
run: |
|
||||
pyinstaller -F tidal_dl/__init__.py -n tidal-dl
|
||||
working-directory: TIDALDL-PY
|
||||
|
||||
# - name: Build tidal-gui-macOs
|
||||
# shell: bash
|
||||
# if: ${{ matrix.os == 'macos-latest' }}
|
||||
# run: |
|
||||
# cp -rf guiStatic.in MANIFEST.in
|
||||
# pyinstaller -F tidal_gui/__init__.py -w -n tidal-gui
|
||||
# cp -rf tidal_gui/resource dist/
|
||||
# working-directory: TIDALDL-PY
|
||||
|
||||
# - name: Build tidal-gui
|
||||
# shell: bash
|
||||
# if: ${{ matrix.os != 'macos-latest' }}
|
||||
# run: |
|
||||
# cp -rf guiStatic.in MANIFEST.in
|
||||
# pyinstaller -D tidal_gui/__init__.py -w -n tidal-gui
|
||||
# working-directory: TIDALDL-PY
|
||||
|
||||
# - name: Gzip tidal-gui
|
||||
# shell: bash
|
||||
# if: ${{ matrix.os != 'macos-latest' }}
|
||||
# run: |
|
||||
# cp -rf ../tidal_gui/resource ./tidal-gui/
|
||||
# tar -zcvf tidal-gui.tar.gz tidal-gui
|
||||
# rm -rf tidal-gui
|
||||
# working-directory: TIDALDL-PY/dist
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: tidal-dl-${{ runner.os }}
|
||||
path: |
|
||||
TIDALDL-PY/dist/*
|
||||
|
||||
|
||||
|
||||
+31
@@ -147,3 +147,34 @@ download/Playlist/Boy Bands- K-Pop Kings/Tmp0/19.part
|
||||
download/Playlist/Boy Bands- K-Pop Kings/Tmp0/20.part
|
||||
download/Playlist/Boy Bands- K-Pop Kings/Tmp0/21.part
|
||||
download/Playlist/Boy Bands- K-Pop Kings/Tmp0/22.part
|
||||
/TIDALDL-GUI
|
||||
/.vscode/.env
|
||||
/.vscode/settings.json
|
||||
/TIDALDL-PY/test/track.json
|
||||
/TIDALDL-PY/test/video.json
|
||||
/__init__.spec
|
||||
/test.py
|
||||
/TIDALDL-GUI-CROSS/MANIFEST.in
|
||||
/TIDALDL-GUI-CROSS/__init__.spec
|
||||
/TIDALDL-GUI-CROSS/workspace.code-workspace
|
||||
/TIDALDL-GUI-CROSS/.idea
|
||||
/TIDALDL-GUI-CROSS/tidal_gui/__pycache__
|
||||
/TIDALDL-GUI-CROSS/tidal_gui/.tidal-dl.log
|
||||
.idea
|
||||
tidal_dl-BAK
|
||||
/TIDALDL-PY2/tidal_dl
|
||||
/TIDALDL-GUI-CROSS/tidal_gui/view/__pycache__
|
||||
/TIDALDL-GUI-CROSS/tidal_gui/viewModel/__pycache__
|
||||
/TIDALDL-GUI-CROSS/tidal_gui/control/__pycache__
|
||||
__pycache__
|
||||
clean.sh
|
||||
TIDALDL-PY/MANIFEST.in
|
||||
TIDALDL-PY/exe/resource
|
||||
TIDALDL-PY/exe/tidal_dl_win.tar.gz
|
||||
.github/workflows/continuous-integration-workflow copy.yml
|
||||
TIDALDL-PY/tidal-gui.spec
|
||||
.history/
|
||||
.gitignore
|
||||
/TIDALDL-PY/tidal_dl_old
|
||||
/TIDALDL-PY/tidal_gui_old
|
||||
/TIDALDL-PY/tidal_gui
|
||||
|
||||
Vendored
+25
-9
@@ -4,6 +4,7 @@
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
{
|
||||
"name": "Python: current",
|
||||
@@ -11,10 +12,11 @@
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"pythonPath": "python.exe",
|
||||
// "python": "python3",
|
||||
"env": {
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/"
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/tidal_dl/"
|
||||
},
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "Python: common line",
|
||||
@@ -22,17 +24,18 @@
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/TIDALDL-PY/tidal_dl/__init__.py",
|
||||
"console": "integratedTerminal",
|
||||
"pythonPath": "python.exe",
|
||||
// "python": "python3",
|
||||
"env": {
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/"
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/tidal_dl/"
|
||||
},
|
||||
"args": [
|
||||
"--link",
|
||||
"https://tidal.com/browse/track/153955724",
|
||||
"https://tidal.com/browse/track/70973230",
|
||||
"-o",
|
||||
"./download/",
|
||||
"e:\\test",
|
||||
"-q",
|
||||
"0"
|
||||
"0",
|
||||
"-g"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -41,9 +44,22 @@
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/TIDALDL-PY/tidal_dl/__init__.py",
|
||||
"console": "integratedTerminal",
|
||||
"pythonPath": "python.exe",
|
||||
// "python": "python3",
|
||||
"env": {
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/"
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/tidal_dl/"
|
||||
},
|
||||
"justMyCode": false
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Python: gui",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/TIDALDL-PY/tidal_gui/__init__.py",
|
||||
"console": "integratedTerminal",
|
||||
// "python": "python3",
|
||||
"env": {
|
||||
"PYTHONPATH": "${workspaceRoot}/TIDALDL-PY/tidal_dl/"
|
||||
},
|
||||
"justMyCode": false
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"//token":"MbjR4DLXz1ghC4rV",
|
||||
"token":"wc8j_yBJd20zOmx0",
|
||||
"//token_phone": "pl4Vc0hemlAXD0mN",
|
||||
"//token_phone2" : "hZ9wuySZCmpLLiui",
|
||||
"token_phone": "wc8j_yBJd20zOmx0"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<br>
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader-PRO">[GUI-REPOSITORY]</a>
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
|
||||
<div align="center">
|
||||
<h1>Tidal-Media-Downloader</h1>
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader/blob/master/LICENSE">
|
||||
@@ -18,29 +22,41 @@
|
||||
<a href="https://pypi.org/project/tidal-dl/">
|
||||
<img src="https://img.shields.io/pypi/dm/tidal-dl?label=tidal-dl%20download" alt="">
|
||||
</a>
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader/actions/workflows/build.yml">
|
||||
<img src="https://github.com/yaronzz/Tidal-Media-Downloader/actions/workflows/build.yml/badge.svg" alt="">
|
||||
</a>
|
||||
</div>
|
||||
<p align="center">
|
||||
«Tidal-Media-Downloader» is an application that lets you download videos and tracks from Tidal. It supports two version: tidal-dl and tidal-gui. (This repository only contains tidal-dl, and the release isn't the newest gui version.)
|
||||
<br>
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader-PRO/releases">Download</a> |
|
||||
<a href="https://yaronzz.top/post/tidal_dl_installation/">Documentation</a> |
|
||||
<a href="https://yaronzz.top/post/tidal_dl_installation_chn/">中文文档</a> |
|
||||
<a href="https://t.me/Tidal_Media_Downloader">Channel</a>
|
||||
<a href="https://doc.yaronzz.com/post/tidal_dl_installation/">Documentation</a> |
|
||||
<a href="https://doc.yaronzz.com/post/tidal_dl_installation_chn/">中文文档</a> |
|
||||
<br>
|
||||
</p>
|
||||
|
||||
## 📺 Installation
|
||||
| Name | platform | Install |
|
||||
| -------------- | --------------------------------- | ------------------------------------------------------------ |
|
||||
| tidal-gui | Windows | [GUI Repository](https://github.com/yaronzz/Tidal-Media-Downloader-PRO) |
|
||||
| tidal-dl (cli) | Windows \ Linux \ Macos \ Android | ```pip3 install tidal-dl --upgrade```<br />[Detailed Description](https://yaronzz.top/post/tidal_dl_installation/#Install) |
|
||||
|
||||
**Renewal cycle:** Once a month. (25th to 30th)
|
||||
```shell
|
||||
pip3 install tidal-dl --upgrade
|
||||
```
|
||||
|
||||
## 📡 Telegram
|
||||
| USE | FUNCTION |
|
||||
| ----------------------------------------------------- | -------------------------- |
|
||||
| tidal-dl | Show interactive interface |
|
||||
| tidal-dl -h | Show help-message |
|
||||
| tidal-dl -l "https://tidal.com/browse/track/70973230" | Download link |
|
||||
| tidal-dl -g | Show simple-gui |
|
||||
|
||||
- [Group](https://t.me/tidal_group) : Feed back
|
||||
- [Channel](https://t.me/Tidal_Media_Downloader) : Notify the new version
|
||||
If you are using windows system, you can use [tidal-pro](https://github.com/yaronzz/Tidal-Media-Downloader-PRO)
|
||||
|
||||
### Nightly Builds
|
||||
|
||||
|Download nightly builds from continuous integration: | [![Build Status][Build]][Actions]
|
||||
|-------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|
||||
[Actions]: https://github.com/yaronzz/Tidal-Media-Downloader/actions
|
||||
[Build]: https://github.com/yaronzz/Tidal-Media-Downloader/workflows/Tidal%20Media%20Downloader/badge.svg
|
||||
|
||||
## 🤖 Features
|
||||
- Download album \ track \ video \ playlist \ artist-albums
|
||||
@@ -53,8 +69,60 @@
|
||||
|
||||
<img src="https://i.loli.net/2020/08/19/gqW6zHI1SrKlomC.png" alt="image" style="zoom: 50%;" />
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Settings - Possible Tags
|
||||
|
||||
### Album
|
||||
|
||||
| Tag | Example value |
|
||||
| ----------------- | ------------------------------------ |
|
||||
| {ArtistName} | The Beatles |
|
||||
| {AlbumArtistName} | The Beatles |
|
||||
| {Flag} | M/A/E (Master/Dolby Atmos/Explicit) |
|
||||
| {AlbumID} | 55163243 |
|
||||
| {AlbumYear} | 1963 |
|
||||
| {AlbumTitle} | Please Please Me (Remastered) |
|
||||
| {AudioQuality} | LOSSLESS |
|
||||
| {DurationSeconds} | 1919 |
|
||||
| {Duration} | 31:59 |
|
||||
| {NumberOfTracks} | 14 |
|
||||
| {NumberOfVideos} | 0 |
|
||||
| {NumberOfVolumes} | 1 |
|
||||
| {ReleaseDate} | 1963-03-22 |
|
||||
| {RecordType} | ALBUM |
|
||||
| {None} | |
|
||||
|
||||
### Track
|
||||
|
||||
| Tag | Example Value |
|
||||
| ----------------- | ------------------------------------------ |
|
||||
| {TrackNumber} | 01 |
|
||||
| {ArtistName} | The Beatles |
|
||||
| {ArtistsName} | The Beatles |
|
||||
| {TrackTitle} | I Saw Her Standing There (Remastered 2009) |
|
||||
| {ExplicitFlag} | (*Explicit*) |
|
||||
| {AlbumYear} | 1963 |
|
||||
| {AlbumTitle} | Please Please Me (Remastered) |
|
||||
| {AudioQuality} | LOSSLESS |
|
||||
| {DurationSeconds} | 173 |
|
||||
| {Duration} | 02:53 |
|
||||
| {TrackID} | 55163244 |
|
||||
|
||||
### Video
|
||||
|
||||
| Tag | Example Value |
|
||||
| ----------------- | ------------------------------------------ |
|
||||
| {VideoNumber} | 00 |
|
||||
| {ArtistName} | DMX |
|
||||
| {ArtistsName} | DMX, Westside Gunn |
|
||||
| {VideoTitle} | Hood Blues |
|
||||
| {ExplicitFlag} | (*Explicit*) |
|
||||
| {VideoYear} | 2021 |
|
||||
| {TrackID} | 188932980 |
|
||||
|
||||
## ☕ Support
|
||||
|
||||
If you really like my projects and want to support me, you can buy me a coffee and star this project.
|
||||
@@ -63,16 +131,26 @@ If you really like my projects and want to support me, you can buy me a coffee a
|
||||
|
||||
## 🎂 Contributors
|
||||
This project exists thanks to all the people who contribute.
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader/graphs/contributors"><img src="https://opencollective.com/Tidal-Media-Downloader/contributors.svg?width=890" /></a>
|
||||
|
||||
<a href="https://github.com/yaronzz/Tidal-Media-Downloader/graphs/contributors"><img src="https://contributors-img.web.app/image?repo=yaronzz/Tidal-Media-Downloader" /></a>
|
||||
|
||||
## 🎨 Libraries and reference
|
||||
|
||||
- [aigpy](https://github.com/yaronzz/AIGPY)
|
||||
- [python-tidal](https://github.com/tamland/python-tidal)
|
||||
- [redsea](https://github.com/redsudo/RedSea)
|
||||
- [tidal-wiki](https://github.com/Fokka-Engineering/TIDAL/wiki)
|
||||
|
||||
## 📜 Disclaimer
|
||||
- Private use only.
|
||||
- Need a Tidal-HIFI subscription.
|
||||
- You should not use this method to distribute or pirate music.
|
||||
- It may be illegal to use this in your country, so be informed.
|
||||
|
||||
## Developing
|
||||
|
||||
```shell
|
||||
pip3 uninstall tidal-dl
|
||||
pip3 install -r requirements.txt --user
|
||||
python3 setup.py install
|
||||
```
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
include tidal_gui/resource/themeDefault.qss
|
||||
include tidal_gui/resource/svg/*.svg
|
||||
include tidal_gui/resource/svg/*/*.svg
|
||||
@@ -1,4 +1,12 @@
|
||||
prettytable==0.7.2
|
||||
requests==2.20.0
|
||||
aigpy==2020.10.9.1
|
||||
pycryptodome==3.9.8
|
||||
requests==2.31.0
|
||||
colorama==0.4.4
|
||||
prettytable==3.1.1
|
||||
mutagen==1.45.1
|
||||
psutil==5.9.0
|
||||
pycryptodome==3.14.1
|
||||
aigpy==2022.7.8.1
|
||||
lyricsgenius==3.0.1
|
||||
pydub==0.25.1
|
||||
PyQt5==5.15.7
|
||||
qt-material==2.12
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
from setuptools import setup, find_packages
|
||||
setup(
|
||||
name = 'tidal-gui',
|
||||
version = '2022.01.18.3',
|
||||
license = "Apache2",
|
||||
description = "Tidal Music Downloader-GUI.",
|
||||
|
||||
author = 'YaronH',
|
||||
author_email = "yaronhuang@foxmail.com",
|
||||
|
||||
packages=find_packages(exclude=['tidal_dl*']),
|
||||
include_package_data = True,
|
||||
platforms = "any",
|
||||
install_requires=["tidal-dl"],
|
||||
entry_points={'console_scripts': [ 'tidal-gui = tidal_gui:main', ]}
|
||||
)
|
||||
+17
-11
@@ -1,17 +1,23 @@
|
||||
from setuptools import setup, find_packages
|
||||
from tidal_dl.printf import VERSION
|
||||
|
||||
setup(
|
||||
name = 'tidal-dl',
|
||||
version = VERSION,
|
||||
license = "Apache2",
|
||||
description = "Tidal Music Downloader.",
|
||||
name='tidal-dl',
|
||||
version=VERSION,
|
||||
license="Apache2",
|
||||
description="Tidal Music Downloader.",
|
||||
|
||||
author = 'YaronH',
|
||||
author_email = "yaronhuang@foxmail.com",
|
||||
author='YaronH',
|
||||
author_email="yaronhuang@foxmail.com",
|
||||
|
||||
packages = find_packages(),
|
||||
include_package_data = True,
|
||||
platforms = "any",
|
||||
install_requires=["aigpy>=2020.10.9.1", "requests", "pycryptodome", "pydub", "prettytable"],
|
||||
entry_points={'console_scripts': [ 'tidal-dl = tidal_dl:main', ]}
|
||||
packages=find_packages(exclude=['tidal_gui*']),
|
||||
include_package_data=False,
|
||||
platforms="any",
|
||||
install_requires=["aigpy>=2022.7.8.1",
|
||||
"requests>=2.22.0",
|
||||
"pycryptodome",
|
||||
"pydub",
|
||||
"prettytable",
|
||||
"lxml"],
|
||||
entry_points={'console_scripts': ['tidal-dl = tidal_dl:main', ]}
|
||||
)
|
||||
|
||||
+162
-259
@@ -1,259 +1,162 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : __init__.py
|
||||
@Time : 2020/11/06
|
||||
@Author : Yaronzz
|
||||
@Version : 2.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
'''
|
||||
import os
|
||||
import requests
|
||||
import prettytable
|
||||
import ssl
|
||||
import sys
|
||||
import getopt
|
||||
import time
|
||||
|
||||
from aigpy.stringHelper import isNull
|
||||
from aigpy.pathHelper import mkdirs
|
||||
from aigpy.pipHelper import getLastVersion
|
||||
from aigpy.versionHelper import cmpVersion
|
||||
|
||||
from tidal_dl.tidal import TidalAPI
|
||||
from tidal_dl.settings import Settings, UserSettings
|
||||
from tidal_dl.printf import Printf, VERSION
|
||||
from tidal_dl.download import start
|
||||
from tidal_dl.enum import AudioQuality, VideoQuality
|
||||
from tidal_dl.lang.language import getLang, setLang, initLang
|
||||
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
API = TidalAPI()
|
||||
USER = UserSettings.read()
|
||||
CONF = Settings.read()
|
||||
LANG = initLang(CONF.language)
|
||||
|
||||
def displayTime(seconds, granularity=2):
|
||||
result = []
|
||||
intervals = (
|
||||
('weeks', 604800),
|
||||
('days', 86400),
|
||||
('hours', 3600),
|
||||
('minutes', 60),
|
||||
('seconds', 1),
|
||||
)
|
||||
|
||||
for name, count in intervals:
|
||||
value = seconds // count
|
||||
if value:
|
||||
seconds -= value * count
|
||||
if value == 1:
|
||||
name = name.rstrip('s')
|
||||
result.append("{} {}".format(value, name))
|
||||
return ', '.join(result[:granularity])
|
||||
|
||||
def login():
|
||||
print(LANG.AUTH_START_LOGIN)
|
||||
msg, check = API.getDeviceCode()
|
||||
if check == False:
|
||||
Printf.err(msg)
|
||||
return
|
||||
|
||||
print(LANG.AUTH_LOGIN_CODE.format(API.key.userCode))
|
||||
print(LANG.AUTH_NEXT_STEP.format(API.key.verificationUrl, displayTime(API.key.authCheckTimeout)))
|
||||
print(LANG.AUTH_WAITING)
|
||||
start = time.time()
|
||||
elapsed = 0
|
||||
while elapsed < API.key.authCheckTimeout:
|
||||
elapsed = time.time() - start
|
||||
msg, check = API.checkAuthStatus()
|
||||
if check == False:
|
||||
if msg == "pending":
|
||||
time.sleep(API.key.authCheckInterval)
|
||||
continue
|
||||
Printf.err(msg)
|
||||
break
|
||||
if check == True:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
USER.userid = API.key.userId
|
||||
USER.countryCode = API.key.countryCode
|
||||
USER.accessToken = API.key.accessToken
|
||||
USER.refreshToken = API.key.refreshToken
|
||||
USER.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
UserSettings.save(USER)
|
||||
break
|
||||
if elapsed >= API.key.authCheckTimeout:
|
||||
Printf.err(LANG.AUTH_TIMEOUT)
|
||||
return
|
||||
|
||||
def checkLogin():
|
||||
if not isNull(USER.accessToken):
|
||||
#print('Checking Access Token...') #add to translations
|
||||
msg, check = API.verifyAccessToken(USER.accessToken)
|
||||
if check == True:
|
||||
Printf.info(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(USER.expiresAfter - time.time()))))
|
||||
return
|
||||
else:
|
||||
Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
|
||||
msg, check = API.refreshAccessToken(USER.refreshToken)
|
||||
if check == True:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
USER.userid = API.key.userId
|
||||
USER.countryCode = API.key.countryCode
|
||||
USER.accessToken = API.key.accessToken
|
||||
USER.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
UserSettings.save(USER)
|
||||
return
|
||||
else:
|
||||
Printf.err(msg)
|
||||
tmp = UserSettings() #clears saved tokens
|
||||
UserSettings.save(tmp)
|
||||
login()
|
||||
return
|
||||
|
||||
def changeSettings():
|
||||
global LANG
|
||||
|
||||
Printf.settings(CONF)
|
||||
choice = Printf.enter(LANG.CHANGE_START_SETTINGS)
|
||||
if choice == '0':
|
||||
return
|
||||
|
||||
while True:
|
||||
choice = Printf.enter(LANG.CHANGE_DOWNLOAD_PATH)
|
||||
if choice == '0':
|
||||
choice = CONF.downloadPath
|
||||
elif not os.path.isdir(choice):
|
||||
if not mkdirs(choice):
|
||||
Printf.err(LANG.MSG_PATH_ERR)
|
||||
continue
|
||||
CONF.downloadPath = choice
|
||||
break
|
||||
while True:
|
||||
choice = Printf.enter(LANG.CHANGE_AUDIO_QUALITY)
|
||||
if choice != '1' and choice != '2' and choice != '3' and choice != '0':
|
||||
Printf.err(LANG.MSG_INPUT_ERR)
|
||||
continue
|
||||
if choice == '0':
|
||||
CONF.audioQuality = AudioQuality.Normal
|
||||
if choice == '1':
|
||||
CONF.audioQuality = AudioQuality.High
|
||||
if choice == '2':
|
||||
CONF.audioQuality = AudioQuality.HiFi
|
||||
if choice == '3':
|
||||
CONF.audioQuality = AudioQuality.Master
|
||||
break
|
||||
while True:
|
||||
choice = Printf.enter(LANG.CHANGE_VIDEO_QUALITY)
|
||||
if choice != '1' and choice != '2' and choice != '3' and choice != '0':
|
||||
Printf.err(LANG.MSG_INPUT_ERR)
|
||||
continue
|
||||
if choice == '0':
|
||||
CONF.videoQuality = VideoQuality.P1080
|
||||
if choice == '1':
|
||||
CONF.videoQuality = VideoQuality.P720
|
||||
if choice == '2':
|
||||
CONF.videoQuality = VideoQuality.P480
|
||||
if choice == '3':
|
||||
CONF.videoQuality = VideoQuality.P360
|
||||
break
|
||||
CONF.onlyM4a = Printf.enter(LANG.CHANGE_ONLYM4A) == '1'
|
||||
# CONF.addExplicitTag = Printf.enter(LANG.CHANGE_ADD_EXPLICIT_TAG) == '1'
|
||||
# CONF.addHyphen = Printf.enter(LANG.CHANGE_ADD_HYPHEN) == '1'
|
||||
# CONF.addYear = Printf.enter(LANG.CHANGE_ADD_YEAR) == '1'
|
||||
# CONF.useTrackNumber = Printf.enter(LANG.CHANGE_USE_TRACK_NUM) == '1'
|
||||
CONF.checkExist = Printf.enter(LANG.CHANGE_CHECK_EXIST) == '1'
|
||||
# CONF.artistBeforeTitle = Printf.enter(LANG.CHANGE_ARTIST_BEFORE_TITLE) == '1'
|
||||
CONF.includeEP = Printf.enter(LANG.CHANGE_INCLUDE_EP) == '1'
|
||||
# CONF.addAlbumIDBeforeFolder = Printf.enter(LANG.CHANGE_ALBUMID_BEFORE_FOLDER) == '1'
|
||||
CONF.saveCovers = Printf.enter(LANG.CHANGE_SAVE_COVERS) == '1'
|
||||
CONF.showProgress = Printf.enter(LANG.CHANGE_SHOW_PROGRESS) == '1'
|
||||
CONF.language = Printf.enter(LANG.CHANGE_LANGUAGE +
|
||||
"('0'-English,'1'-中文,'2'-Turkish,'3'-Italiano,'4'-Czech,'5'-Arabic,'6'-Russian,'7'-Filipino,'8'-Croatian,'9'-Spanish,'10'-Portuguese,'11'-Ukrainian,'12'-Vietnamese,'13'-French,'14'-German):")
|
||||
albumFolderFormat = Printf.enter(LANG.CHANGE_ALBUM_FOLDER_FORMAT)
|
||||
if albumFolderFormat == '0':
|
||||
albumFolderFormat = CONF.albumFolderFormat
|
||||
else:
|
||||
CONF.albumFolderFormat = albumFolderFormat
|
||||
trackFileFormat = Printf.enter(LANG.CHANGE_TRACK_FILE_FORMAT)
|
||||
if trackFileFormat == '0':
|
||||
trackFileFormat = CONF.trackFileFormat
|
||||
else:
|
||||
CONF.trackFileFormat = trackFileFormat
|
||||
|
||||
|
||||
LANG = setLang(CONF.language)
|
||||
Settings.save(CONF)
|
||||
|
||||
|
||||
def mainCommand():
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvl:o:q:r:", ["help", "version", "link=", "output=", "quality", "resolution"])
|
||||
except getopt.GetoptError as errmsg:
|
||||
Printf.err(vars(errmsg)['msg'] + ". Use 'tidal-dl -h' for useage.")
|
||||
return
|
||||
|
||||
for opt, val in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
Printf.usage()
|
||||
return
|
||||
if opt in ('-v', '--version'):
|
||||
Printf.logo()
|
||||
return
|
||||
if opt in ('-l', '--link'):
|
||||
checkLogin()
|
||||
start(USER, CONF, val)
|
||||
return
|
||||
if opt in ('-o', '--output'):
|
||||
CONF.downloadPath = val
|
||||
Settings.save(CONF)
|
||||
return
|
||||
if opt in ('-q', '--quality'):
|
||||
CONF.audioQuality = Settings.getAudioQuality(val)
|
||||
Settings.save(CONF)
|
||||
return
|
||||
if opt in ('-r', '--resolution'):
|
||||
CONF.videoQuality = Settings.getVideoQuality(val)
|
||||
Settings.save(CONF)
|
||||
return
|
||||
|
||||
if not mkdirs(CONF.downloadPath):
|
||||
Printf.err(LANG.MSG_PATH_ERR + CONF.downloadPath)
|
||||
return
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
mainCommand()
|
||||
return
|
||||
|
||||
Printf.logo()
|
||||
Printf.settings(CONF)
|
||||
|
||||
checkLogin()
|
||||
|
||||
onlineVer = getLastVersion('tidal-dl')
|
||||
if not isNull(onlineVer):
|
||||
icmp = cmpVersion(onlineVer, VERSION)
|
||||
if icmp > 0:
|
||||
Printf.info(LANG.PRINT_LATEST_VERSION + ' ' + onlineVer)
|
||||
|
||||
while True:
|
||||
Printf.choices()
|
||||
choice = Printf.enter(LANG.PRINT_ENTER_CHOICE)
|
||||
if choice == "0":
|
||||
return
|
||||
elif choice == "1":
|
||||
checkLogin()
|
||||
elif choice == "2":
|
||||
changeSettings()
|
||||
else:
|
||||
start(USER, CONF, choice)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# test example
|
||||
# track 70973230
|
||||
# video 155608351
|
||||
# album 58138532 77803199 21993753 79151897 56288918
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : __init__.py
|
||||
@Time : 2020/11/08
|
||||
@Author : Yaronzz
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
'''
|
||||
import sys
|
||||
import getopt
|
||||
import aigpy
|
||||
|
||||
from events import *
|
||||
from settings import *
|
||||
from gui import startGui
|
||||
from printf import Printf
|
||||
|
||||
|
||||
def mainCommand():
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hvgl:o:q:r:",
|
||||
["help", "version", "gui", "link=", "output=", "quality", "resolution"])
|
||||
except getopt.GetoptError as errmsg:
|
||||
Printf.err(vars(errmsg)['msg'] + ". Use 'tidal-dl -h' for usage.")
|
||||
return
|
||||
|
||||
link = None
|
||||
showGui = False
|
||||
|
||||
for opt, val in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
Printf.usage()
|
||||
return
|
||||
if opt in ('-v', '--version'):
|
||||
Printf.logo()
|
||||
return
|
||||
if opt in ('-g', '--gui'):
|
||||
showGui = True
|
||||
continue
|
||||
if opt in ('-l', '--link'):
|
||||
link = val
|
||||
continue
|
||||
if opt in ('-o', '--output'):
|
||||
SETTINGS.downloadPath = val
|
||||
SETTINGS.save()
|
||||
continue
|
||||
if opt in ('-q', '--quality'):
|
||||
SETTINGS.audioQuality = SETTINGS.getAudioQuality(val)
|
||||
SETTINGS.save()
|
||||
continue
|
||||
if opt in ('-r', '--resolution'):
|
||||
SETTINGS.videoQuality = SETTINGS.getVideoQuality(val)
|
||||
SETTINGS.save()
|
||||
continue
|
||||
|
||||
if not aigpy.path.mkdirs(SETTINGS.downloadPath):
|
||||
Printf.err(LANG.select.MSG_PATH_ERR + SETTINGS.downloadPath)
|
||||
return
|
||||
|
||||
if showGui:
|
||||
startGui()
|
||||
return
|
||||
|
||||
if link is not None:
|
||||
if not loginByConfig():
|
||||
loginByWeb()
|
||||
Printf.info(LANG.select.SETTING_DOWNLOAD_PATH + ':' + SETTINGS.downloadPath)
|
||||
start(link)
|
||||
|
||||
def main():
|
||||
SETTINGS.read(getProfilePath())
|
||||
TOKEN.read(getTokenPath())
|
||||
TIDAL_API.apiKey = apiKey.getItem(SETTINGS.apiKeyIndex)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
mainCommand()
|
||||
return
|
||||
|
||||
Printf.logo()
|
||||
Printf.settings()
|
||||
|
||||
if not apiKey.isItemValid(SETTINGS.apiKeyIndex):
|
||||
changeApiKey()
|
||||
loginByWeb()
|
||||
elif not loginByConfig():
|
||||
loginByWeb()
|
||||
|
||||
Printf.checkVersion()
|
||||
|
||||
while True:
|
||||
Printf.choices()
|
||||
choice = Printf.enter(LANG.select.PRINT_ENTER_CHOICE)
|
||||
if choice == "0":
|
||||
return
|
||||
elif choice == "1":
|
||||
if not loginByConfig():
|
||||
loginByWeb()
|
||||
elif choice == "2":
|
||||
loginByWeb()
|
||||
elif choice == "3":
|
||||
loginByAccessToken()
|
||||
elif choice == "4":
|
||||
changePathSettings()
|
||||
elif choice == "5":
|
||||
changeQualitySettings()
|
||||
elif choice == "6":
|
||||
changeSettings()
|
||||
elif choice == "7":
|
||||
if changeApiKey():
|
||||
loginByWeb()
|
||||
else:
|
||||
start(choice)
|
||||
|
||||
|
||||
def test():
|
||||
SETTINGS.read(getProfilePath())
|
||||
TOKEN.read(getTokenPath())
|
||||
|
||||
if not loginByConfig():
|
||||
loginByWeb()
|
||||
|
||||
SETTINGS.audioQuality = AudioQuality.Master
|
||||
SETTINGS.videoFileFormat = VideoQuality.P240
|
||||
SETTINGS.checkExist = False
|
||||
SETTINGS.includeEP = True
|
||||
SETTINGS.saveCovers = True
|
||||
SETTINGS.lyricFile = True
|
||||
SETTINGS.showProgress = True
|
||||
SETTINGS.showTrackInfo = True
|
||||
SETTINGS.saveAlbumInfo = True
|
||||
SETTINGS.downloadVideos = True
|
||||
SETTINGS.downloadPath = "./download/"
|
||||
SETTINGS.usePlaylistFolder = True
|
||||
SETTINGS.albumFolderFormat = R"{ArtistName}/{Flag} {AlbumTitle} [{AlbumID}] [{AlbumYear}]"
|
||||
SETTINGS.playlistFolderFormat = R"Playlist/{PlaylistName} [{PlaylistUUID}]"
|
||||
SETTINGS.trackFileFormat = R"{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
SETTINGS.videoFileFormat = R"{VideoNumber} - {ArtistName} - {VideoTitle}{ExplicitFlag}"
|
||||
SETTINGS.multiThread = False
|
||||
SETTINGS.apiKeyIndex = 4
|
||||
SETTINGS.checkExist = False
|
||||
|
||||
Printf.settings()
|
||||
|
||||
TIDAL_API.getPlaylistSelf()
|
||||
# test example
|
||||
# https://tidal.com/browse/track/70973230
|
||||
# track 70973230 77798028 212657
|
||||
start('242700165')
|
||||
# album 58138532 77803199 21993753 79151897 56288918
|
||||
# start('58138532')
|
||||
# playlist 98235845-13e8-43b4-94e2-d9f8e603cee7
|
||||
# start('98235845-13e8-43b4-94e2-d9f8e603cee7')
|
||||
# video 155608351 188932980 https://tidal.com/browse/track/55130637
|
||||
# start("155608351")https://tidal.com/browse/track/199683732
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# test()
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
@File : apiKey.py
|
||||
@Date : 2021/11/30
|
||||
@Author : Yaronzz
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import json
|
||||
import requests
|
||||
|
||||
__KEYS_JSON__ = '''
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"keys": [
|
||||
{
|
||||
"platform": "Fire TV",
|
||||
"formats": "Normal/High/HiFi(No Master)",
|
||||
"clientId": "OmDtrzFgyVVL6uW56OnFA2COiabqm",
|
||||
"clientSecret": "zxen1r3pO0hgtOC7j6twMo9UAqngGrmRiWpV7QC1zJ8=",
|
||||
"valid": "False",
|
||||
"from": "Fokka-Engineering (https://github.com/Fokka-Engineering/libopenTIDAL/blob/655528e26e4f3ee2c426c06ea5b8440cf27abc4a/README.md#example)"
|
||||
},
|
||||
{
|
||||
"platform": "Fire TV",
|
||||
"formats": "Master-Only(Else Error)",
|
||||
"clientId": "7m7Ap0JC9j1cOM3n",
|
||||
"clientSecret": "vRAdA108tlvkJpTsGZS8rGZ7xTlbJ0qaZ2K9saEzsgY=",
|
||||
"valid": "True",
|
||||
"from": "Dniel97 (https://github.com/Dniel97/RedSea/blob/4ba02b88cee33aeb735725cb854be6c66ff372d4/config/settings.example.py#L68)"
|
||||
},
|
||||
{
|
||||
"platform": "Android TV",
|
||||
"formats": "Normal/High/HiFi(No Master)",
|
||||
"clientId": "Pzd0ExNVHkyZLiYN",
|
||||
"clientSecret": "W7X6UvBaho+XOi1MUeCX6ewv2zTdSOV3Y7qC3p3675I=",
|
||||
"valid": "False",
|
||||
"from": ""
|
||||
},
|
||||
{
|
||||
"platform": "TV",
|
||||
"formats": "Normal/High/HiFi/Master",
|
||||
"clientId": "8SEZWa4J1NVC5U5Y",
|
||||
"clientSecret": "owUYDkxddz+9FpvGX24DlxECNtFEMBxipU0lBfrbq60=",
|
||||
"valid": "False",
|
||||
"from": "morguldir (https://github.com/morguldir/python-tidal/commit/50f1afcd2079efb2b4cf694ef5a7d67fdf619d09)"
|
||||
},
|
||||
{
|
||||
"platform": "Android Auto",
|
||||
"formats": "Normal/High/HiFi/Master",
|
||||
"clientId": "zU4XHVVkc2tDPo4t",
|
||||
"clientSecret": "VJKhDFqJPqvsPVNBV6ukXTJmwlvbttP7wlMlrc72se4=",
|
||||
"valid": "True",
|
||||
"from": "1nikolas (https://github.com/yaronzz/Tidal-Media-Downloader/pull/840)"
|
||||
}
|
||||
]
|
||||
}
|
||||
'''
|
||||
__API_KEYS__ = json.loads(__KEYS_JSON__)
|
||||
__ERROR_KEY__ = {
|
||||
'platform': 'None',
|
||||
'formats': '',
|
||||
'clientId': '',
|
||||
'clientSecret': '',
|
||||
'valid': 'False',
|
||||
},
|
||||
|
||||
|
||||
def getNum():
|
||||
return len(__API_KEYS__['keys'])
|
||||
|
||||
|
||||
def getItem(index: int):
|
||||
if index < 0 or index >= len(__API_KEYS__['keys']):
|
||||
return __ERROR_KEY__
|
||||
return __API_KEYS__['keys'][index]
|
||||
|
||||
|
||||
def isItemValid(index: int):
|
||||
item = getItem(index)
|
||||
return item['valid'] == 'True'
|
||||
|
||||
|
||||
def getItems():
|
||||
return __API_KEYS__['keys']
|
||||
|
||||
|
||||
def getLimitIndexs():
|
||||
array = []
|
||||
for i in range(len(__API_KEYS__['keys'])):
|
||||
array.append(str(i))
|
||||
return array
|
||||
|
||||
|
||||
def getVersion():
|
||||
return __API_KEYS__['version']
|
||||
|
||||
|
||||
# Load from gist
|
||||
try:
|
||||
respond = requests.get('https://api.github.com/gists/48d01f5a24b4b7b37f19443977c22cd6')
|
||||
if respond.status_code == 200:
|
||||
content = respond.json()['files']['tidal-api-key.json']['content']
|
||||
__API_KEYS__ = json.loads(content)
|
||||
except:
|
||||
pass
|
||||
+162
-367
@@ -2,66 +2,38 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : download.py
|
||||
@Time : 2020/08/18
|
||||
@Time : 2020/11/08
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
@Desc :
|
||||
'''
|
||||
import os
|
||||
|
||||
import aigpy.m3u8Helper as m3u8Helper
|
||||
from aigpy.tagHelper import TagTool
|
||||
from aigpy.netHelper import downloadFile, downloadFileMultiThread
|
||||
from aigpy.stringHelper import isNull, getSubOnlyEnd
|
||||
from aigpy.pathHelper import replaceLimitChar, getFileName, remove
|
||||
from aigpy.fileHelper import getFileContent, getFileSize
|
||||
import aigpy.netHelper as netHelper
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from tidal_dl.settings import Settings
|
||||
from tidal_dl.tidal import TidalAPI
|
||||
from tidal_dl.enum import Type, AudioQuality, VideoQuality
|
||||
from tidal_dl.printf import Printf
|
||||
from tidal_dl.decryption import decrypt_security_token
|
||||
from tidal_dl.decryption import decrypt_file
|
||||
|
||||
API = TidalAPI()
|
||||
|
||||
def __loadAPI__(user):
|
||||
API.key.accessToken = user.accessToken
|
||||
API.key.userId = user.userid
|
||||
API.key.countryCode = user.countryCode
|
||||
#API.key.sessionId = user.sessionid1
|
||||
from decryption import *
|
||||
from printf import *
|
||||
from tidal import *
|
||||
|
||||
|
||||
def __loadVideoAPI__(user):
|
||||
API.key.accessToken = user.accessToken
|
||||
API.key.userId = user.userid
|
||||
API.key.countryCode = user.countryCode
|
||||
#API.key.sessionId = user.sessionid2 if not isNull(user.sessionid2) else user.sessionid1
|
||||
def __isSkip__(finalpath, url):
|
||||
if not SETTINGS.checkExist:
|
||||
return False
|
||||
curSize = aigpy.file.getSize(finalpath)
|
||||
if curSize <= 0:
|
||||
return False
|
||||
netSize = aigpy.net.getSize(url)
|
||||
return curSize >= netSize
|
||||
|
||||
|
||||
def __encrypted__(stream, srcPath, descPath):
|
||||
if aigpy.string.isNull(stream.encryptionKey):
|
||||
os.replace(srcPath, descPath)
|
||||
else:
|
||||
key, nonce = decrypt_security_token(stream.encryptionKey)
|
||||
decrypt_file(srcPath, descPath, key, nonce)
|
||||
os.remove(srcPath)
|
||||
|
||||
def __getIndexStr__(index):
|
||||
pre = "0"
|
||||
if index < 10:
|
||||
return pre+str(index)
|
||||
if index < 99:
|
||||
return str(index)
|
||||
return str(index)
|
||||
|
||||
def __getExtension__(url):
|
||||
if '.flac' in url:
|
||||
return '.flac'
|
||||
if '.mp4' in url:
|
||||
return '.mp4'
|
||||
return '.m4a'
|
||||
|
||||
def __getArtists__(array):
|
||||
ret = []
|
||||
for item in array:
|
||||
ret.append(item.name)
|
||||
return ret
|
||||
|
||||
def __parseContributors__(roleType, Contributors):
|
||||
if Contributors is None:
|
||||
@@ -76,352 +48,175 @@ def __parseContributors__(roleType, Contributors):
|
||||
return None
|
||||
|
||||
|
||||
def __setMetaData__(track, album, filepath, contributors):
|
||||
obj = TagTool(filepath)
|
||||
def __setMetaData__(track: Track, album: Album, filepath, contributors, lyrics):
|
||||
obj = aigpy.tag.TagTool(filepath)
|
||||
obj.album = track.album.title
|
||||
obj.title = track.title
|
||||
obj.artist = __getArtists__(track.artists)
|
||||
if not aigpy.string.isNull(track.version):
|
||||
obj.title += ' (' + track.version + ')'
|
||||
|
||||
obj.artist = list(map(lambda artist: artist.name, track.artists))
|
||||
obj.copyright = track.copyRight
|
||||
obj.tracknumber = track.trackNumber
|
||||
obj.discnumber = track.volumeNumber
|
||||
obj.composer = __parseContributors__('Composer', contributors)
|
||||
obj.isrc = track.isrc
|
||||
obj.albumartist = __getArtists__(album.artists)
|
||||
|
||||
obj.albumartist = list(map(lambda artist: artist.name, album.artists))
|
||||
obj.date = album.releaseDate
|
||||
obj.totaldisc = album.numberOfVolumes
|
||||
obj.lyrics = lyrics
|
||||
if obj.totaldisc <= 1:
|
||||
obj.totaltrack = album.numberOfTracks
|
||||
coverpath = API.getCoverUrl(album.cover, "1280", "1280")
|
||||
coverpath = TIDAL_API.getCoverUrl(album.cover, "1280", "1280")
|
||||
obj.save(coverpath)
|
||||
return
|
||||
|
||||
def __convertToM4a__(filepath, codec):
|
||||
if 'ac4' in codec or 'mha1' in codec:
|
||||
return filepath
|
||||
if '.mp4' not in filepath:
|
||||
return filepath
|
||||
newpath = filepath.replace('.mp4', '.m4a')
|
||||
remove(newpath)
|
||||
os.rename(filepath, newpath)
|
||||
return newpath
|
||||
|
||||
|
||||
# "{ArtistName}/{Flag} [{AlbumID}] [{AlbumYear}] {AlbumTitle}"
|
||||
def __getAlbumPath__(conf: Settings, album):
|
||||
base = conf.downloadPath + '/Album/'
|
||||
artist = replaceLimitChar(album.artists[0].name, '-')
|
||||
# album folder pre: [ME][ID]
|
||||
flag = API.getFlag(album, Type.Album, True, "")
|
||||
if conf.audioQuality != AudioQuality.Master:
|
||||
flag = flag.replace("M", "")
|
||||
if not isNull(flag):
|
||||
flag = "[" + flag + "] "
|
||||
|
||||
sid = str(album.id)
|
||||
#album and addyear
|
||||
albumname = replaceLimitChar(album.title, '-')
|
||||
year = getSubOnlyEnd(album.releaseDate, '-')
|
||||
# retpath
|
||||
retpath = conf.albumFolderFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = Settings.getDefualtAlbumFolderFormat()
|
||||
retpath = retpath.replace(R"{ArtistName}", artist)
|
||||
retpath = retpath.replace(R"{Flag}", flag)
|
||||
retpath = retpath.replace(R"{AlbumID}", sid)
|
||||
retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
retpath = retpath.replace(R"{AlbumTitle}", albumname)
|
||||
retpath = retpath.strip()
|
||||
return base + retpath
|
||||
|
||||
|
||||
def __getAlbumPath2__(conf, album):
|
||||
# outputdir/Album/artist/
|
||||
artist = replaceLimitChar(album.artists[0].name, '-')
|
||||
base = conf.downloadPath + '/Album/' + artist + '/'
|
||||
|
||||
# album folder pre: [ME][ID]
|
||||
flag = API.getFlag(album, Type.Album, True, "")
|
||||
if conf.audioQuality != AudioQuality.Master:
|
||||
flag = flag.replace("M", "")
|
||||
if not isNull(flag):
|
||||
flag = "[" + flag + "] "
|
||||
|
||||
sid = "[" + str(album.id) + "] " if conf.addAlbumIDBeforeFolder else ""
|
||||
|
||||
#album and addyear
|
||||
albumname = replaceLimitChar(album.title, '-')
|
||||
year = ""
|
||||
if conf.addYear:
|
||||
year = "[" + getSubOnlyEnd(album.releaseDate, '-') + "] "
|
||||
return base + flag + sid + year + albumname + '/'
|
||||
|
||||
|
||||
def __getPlaylistPath__(conf, playlist):
|
||||
# outputdir/Playlist/
|
||||
base = conf.downloadPath + '/Playlist/'
|
||||
# name
|
||||
name = replaceLimitChar(playlist.title, '-')
|
||||
return base + name + '/'
|
||||
|
||||
# "{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
|
||||
|
||||
def __getTrackPath__(conf: Settings, track, stream, album=None, playlist=None):
|
||||
if album is not None:
|
||||
base = __getAlbumPath__(conf, album) + '/'
|
||||
if album.numberOfVolumes > 1:
|
||||
base += 'CD' + str(track.volumeNumber) + '/'
|
||||
if playlist is not None:
|
||||
base = __getPlaylistPath__(conf, playlist)
|
||||
# number
|
||||
number = __getIndexStr__(track.trackNumber)
|
||||
if playlist is not None:
|
||||
number = __getIndexStr__(track.trackNumberOnPlaylist)
|
||||
# artist
|
||||
artist = replaceLimitChar(track.artists[0].name, '-')
|
||||
# title
|
||||
title = track.title
|
||||
if not isNull(track.version):
|
||||
title += ' (' + track.version + ')'
|
||||
title = replaceLimitChar(title, '-')
|
||||
# get explicit
|
||||
explicit = "(Explicit)" if conf.addExplicitTag and track.explicit else ''
|
||||
#album and addyear
|
||||
albumname = replaceLimitChar(album.title, '-')
|
||||
year = getSubOnlyEnd(album.releaseDate, '-')
|
||||
# extension
|
||||
extension = __getExtension__(stream.url)
|
||||
retpath = conf.trackFileFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = Settings.getDefualtTrackFileFormat()
|
||||
retpath = retpath.replace(R"{TrackNumber}", number)
|
||||
retpath = retpath.replace(R"{ArtistName}", artist)
|
||||
retpath = retpath.replace(R"{TrackTitle}", title)
|
||||
retpath = retpath.replace(R"{ExplicitFlag}", explicit)
|
||||
retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
retpath = retpath.replace(R"{AlbumTitle}", albumname)
|
||||
retpath = retpath.strip()
|
||||
return base + retpath + extension
|
||||
|
||||
|
||||
def __getTrackPath2__(conf, track, stream, album=None, playlist=None):
|
||||
if album is not None:
|
||||
base = __getAlbumPath__(conf, album)
|
||||
if album.numberOfVolumes > 1:
|
||||
base += 'CD' + str(track.volumeNumber) + '/'
|
||||
if playlist is not None:
|
||||
base = __getPlaylistPath__(conf, playlist)
|
||||
|
||||
# hyphen
|
||||
hyphen = ' - ' if conf.addHyphen else ' '
|
||||
# get number
|
||||
number = ''
|
||||
if conf.useTrackNumber:
|
||||
number = __getIndexStr__(track.trackNumber) + hyphen
|
||||
if playlist is not None:
|
||||
number = __getIndexStr__(track.trackNumberOnPlaylist) + hyphen
|
||||
# get artist
|
||||
artist = ''
|
||||
if conf.artistBeforeTitle:
|
||||
artist = replaceLimitChar(track.artists[0].name, '-') + hyphen
|
||||
# get explicit
|
||||
explicit = "(Explicit)" if conf.addExplicitTag and track.explicit else ''
|
||||
# title
|
||||
title = track.title
|
||||
if not isNull(track.version):
|
||||
title += ' - ' + track.version
|
||||
title = replaceLimitChar(title, '-')
|
||||
# extension
|
||||
extension = __getExtension__(stream.url)
|
||||
return base + number + artist + title + explicit + extension
|
||||
|
||||
|
||||
def __getVideoPath__(conf, video, album=None, playlist=None):
|
||||
if album is not None and album.title is not None:
|
||||
base = __getAlbumPath__(conf, album)
|
||||
elif playlist is not None:
|
||||
base = __getPlaylistPath__(conf, playlist)
|
||||
else:
|
||||
base = conf.downloadPath + '/Video/'
|
||||
|
||||
# hyphen
|
||||
hyphen = ' - ' if conf.addHyphen else ' '
|
||||
# get number
|
||||
number = ''
|
||||
if conf.useTrackNumber:
|
||||
number = __getIndexStr__(video.trackNumber) + hyphen
|
||||
# get artist
|
||||
artist = ''
|
||||
if conf.artistBeforeTitle:
|
||||
artist = replaceLimitChar(video.artists[0].name, '-') + hyphen
|
||||
# get explicit
|
||||
explicit = "(Explicit)" if conf.addExplicitTag and video.explicit else ''
|
||||
# title
|
||||
title = replaceLimitChar(video.title, '-')
|
||||
# extension
|
||||
extension = ".mp4"
|
||||
return base + number + artist + title + explicit + extension
|
||||
|
||||
|
||||
def __isNeedDownload__(path, url):
|
||||
curSize = getFileSize(path)
|
||||
if curSize <= 0:
|
||||
return True
|
||||
netSize = netHelper.getFileSize(url)
|
||||
if curSize >= netSize:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def __downloadVideo__(conf, video, album=None, playlist=None):
|
||||
msg, stream = API.getVideoStreamUrl(video.id, conf.videoQuality)
|
||||
if not isNull(msg):
|
||||
Printf.err(video.title + "." + msg)
|
||||
def downloadCover(album):
|
||||
if album is None:
|
||||
return
|
||||
path = __getVideoPath__(conf, video, album, playlist)
|
||||
if m3u8Helper.download(stream.m3u8Url, path):
|
||||
Printf.success(getFileName(path))
|
||||
else:
|
||||
Printf.err("\nDownload failed!" + getFileName(path))
|
||||
path = getAlbumPath(album) + '/cover.jpg'
|
||||
url = TIDAL_API.getCoverUrl(album.cover, "1280", "1280")
|
||||
aigpy.net.downloadFile(url, path)
|
||||
|
||||
|
||||
def __downloadTrack__(conf: Settings, track, album=None, playlist=None):
|
||||
def downloadAlbumInfo(album, tracks):
|
||||
if album is None:
|
||||
return
|
||||
|
||||
path = getAlbumPath(album)
|
||||
aigpy.path.mkdirs(path)
|
||||
|
||||
path += '/AlbumInfo.txt'
|
||||
infos = ""
|
||||
infos += "[ID] %s\n" % (str(album.id))
|
||||
infos += "[Title] %s\n" % (str(album.title))
|
||||
infos += "[Artists] %s\n" % (TIDAL_API.getArtistsName(album.artists))
|
||||
infos += "[ReleaseDate] %s\n" % (str(album.releaseDate))
|
||||
infos += "[SongNum] %s\n" % (str(album.numberOfTracks))
|
||||
infos += "[Duration] %s\n" % (str(album.duration))
|
||||
infos += '\n'
|
||||
|
||||
for index in range(0, album.numberOfVolumes):
|
||||
volumeNumber = index + 1
|
||||
infos += f"===========CD {volumeNumber}=============\n"
|
||||
for item in tracks:
|
||||
if item.volumeNumber != volumeNumber:
|
||||
continue
|
||||
infos += '{:<8}'.format("[%d]" % item.trackNumber)
|
||||
infos += "%s\n" % item.title
|
||||
aigpy.file.write(path, infos, "w+")
|
||||
|
||||
|
||||
def downloadVideo(video: Video, album: Album = None, playlist: Playlist = None):
|
||||
try:
|
||||
msg, stream = API.getStreamUrl(track.id, conf.audioQuality)
|
||||
if not isNull(msg) or stream is None:
|
||||
Printf.err(track.title + "." + msg)
|
||||
return
|
||||
path = __getTrackPath__(conf, track, stream, album, playlist)
|
||||
stream = TIDAL_API.getVideoStreamUrl(video.id, SETTINGS.videoQuality)
|
||||
path = getVideoPath(video, album, playlist)
|
||||
|
||||
Printf.video(video, stream)
|
||||
logging.info("[DL Video] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.m3u8Url)
|
||||
|
||||
m3u8content = requests.get(stream.m3u8Url).content
|
||||
if m3u8content is None:
|
||||
Printf.err(f"DL Video[{video.title}] getM3u8 failed.{str(e)}")
|
||||
return False, f"GetM3u8 failed.{str(e)}"
|
||||
|
||||
urls = aigpy.m3u8.parseTsUrls(m3u8content)
|
||||
if len(urls) <= 0:
|
||||
Printf.err(f"DL Video[{video.title}] getTsUrls failed.{str(e)}")
|
||||
return False, "GetTsUrls failed.{str(e)}"
|
||||
|
||||
check, msg = aigpy.m3u8.downloadByTsUrls(urls, path)
|
||||
if check:
|
||||
Printf.success(video.title)
|
||||
return True
|
||||
else:
|
||||
Printf.err(f"DL Video[{video.title}] failed.{msg}")
|
||||
return False, msg
|
||||
except Exception as e:
|
||||
Printf.err(f"DL Video[{video.title}] failed.{str(e)}")
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, partSize=1048576):
|
||||
try:
|
||||
stream = TIDAL_API.getStreamUrl(track.id, SETTINGS.audioQuality)
|
||||
path = getTrackPath(track, stream, album, playlist)
|
||||
|
||||
if SETTINGS.showTrackInfo and not SETTINGS.multiThread:
|
||||
Printf.track(track, stream)
|
||||
|
||||
if userProgress is not None:
|
||||
userProgress.updateStream(stream)
|
||||
|
||||
# check exist
|
||||
if conf.checkExist and __isNeedDownload__(path, stream.url) == False:
|
||||
Printf.success(getFileName(path) + " (skip:already exists!)")
|
||||
return
|
||||
if __isSkip__(path, stream.url):
|
||||
Printf.success(aigpy.path.getFileName(path) + " (skip:already exists!)")
|
||||
return True, ''
|
||||
|
||||
# Printf.info("Download \"" + track.title + "\" Codec: " + stream.codec)
|
||||
if conf.multiThreadDownload:
|
||||
check, err = downloadFileMultiThread(stream.url, path + '.part',
|
||||
stimeout=20, showprogress=conf.showProgress)
|
||||
else:
|
||||
check, err = downloadFile(stream.url, path + '.part', stimeout=20, showprogress=conf.showProgress)
|
||||
# download
|
||||
logging.info("[DL Track] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.url)
|
||||
|
||||
tool = aigpy.download.DownloadTool(path + '.part', stream.urls)
|
||||
tool.setUserProgress(userProgress)
|
||||
tool.setPartSize(partSize)
|
||||
check, err = tool.start(SETTINGS.showProgress and not SETTINGS.multiThread)
|
||||
if not check:
|
||||
Printf.err("Download failed!" + getFileName(path) + ' (' + str(err) + ')')
|
||||
return
|
||||
# encrypted -> decrypt and remove encrypted file
|
||||
if isNull(stream.encryptionKey):
|
||||
os.replace(path + '.part', path)
|
||||
else:
|
||||
key, nonce = decrypt_security_token(stream.encryptionKey)
|
||||
decrypt_file(path + '.part', path, key, nonce)
|
||||
os.remove(path + '.part')
|
||||
Printf.err(f"DL Track '{track.title}' failed: {str(err)}")
|
||||
return False, str(err)
|
||||
|
||||
path = __convertToM4a__(path, stream.codec)
|
||||
# encrypted -> decrypt and remove encrypted file
|
||||
__encrypted__(stream, path + '.part', path)
|
||||
|
||||
# contributors
|
||||
contributors = API.getTrackContributors(track.id)
|
||||
__setMetaData__(track, album, path, contributors)
|
||||
Printf.success(getFileName(path))
|
||||
try:
|
||||
contributors = TIDAL_API.getTrackContributors(track.id)
|
||||
except:
|
||||
contributors = None
|
||||
|
||||
# lyrics
|
||||
try:
|
||||
lyrics = TIDAL_API.getLyrics(track.id).subtitles
|
||||
if SETTINGS.lyricFile:
|
||||
lrcPath = path.rsplit(".", 1)[0] + '.lrc'
|
||||
aigpy.file.write(lrcPath, lyrics, 'w')
|
||||
except:
|
||||
lyrics = ''
|
||||
|
||||
__setMetaData__(track, album, path, contributors, lyrics)
|
||||
Printf.success(track.title)
|
||||
|
||||
return True, ''
|
||||
except Exception as e:
|
||||
Printf.err("Download failed!" + track.title + ' (' + str(e) + ')')
|
||||
Printf.err(f"DL Track '{track.title}' failed: {str(e)}")
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def __downloadCover__(conf, album):
|
||||
if album == None:
|
||||
return
|
||||
path = __getAlbumPath__(conf, album) + '/cover.jpg'
|
||||
url = API.getCoverUrl(album.cover, "1280", "1280")
|
||||
if url is not None:
|
||||
downloadFile(url, path)
|
||||
def downloadTracks(tracks, album: Album = None, playlist: Playlist = None):
|
||||
def __getAlbum__(item: Track):
|
||||
album = TIDAL_API.getAlbum(item.album.id)
|
||||
if SETTINGS.saveCovers and not SETTINGS.usePlaylistFolder:
|
||||
downloadCover(album)
|
||||
return album
|
||||
|
||||
if not SETTINGS.multiThread:
|
||||
for index, item in enumerate(tracks):
|
||||
itemAlbum = album
|
||||
if itemAlbum is None:
|
||||
itemAlbum = __getAlbum__(item)
|
||||
item.trackNumberOnPlaylist = index + 1
|
||||
downloadTrack(item, itemAlbum, playlist)
|
||||
else:
|
||||
thread_pool = ThreadPoolExecutor(max_workers=5)
|
||||
for index, item in enumerate(tracks):
|
||||
itemAlbum = album
|
||||
if itemAlbum is None:
|
||||
itemAlbum = __getAlbum__(item)
|
||||
item.trackNumberOnPlaylist = index + 1
|
||||
thread_pool.submit(downloadTrack, item, itemAlbum, playlist)
|
||||
thread_pool.shutdown(wait=True)
|
||||
|
||||
|
||||
def __album__(conf, obj):
|
||||
Printf.album(obj)
|
||||
msg, tracks, videos = API.getItems(obj.id, Type.Album)
|
||||
if not isNull(msg):
|
||||
Printf.err(msg)
|
||||
return
|
||||
if conf.saveCovers:
|
||||
__downloadCover__(conf, obj)
|
||||
for item in tracks:
|
||||
__downloadTrack__(conf, item, obj)
|
||||
def downloadVideos(videos, album: Album, playlist=None):
|
||||
for item in videos:
|
||||
__downloadVideo__(conf, item, obj)
|
||||
|
||||
|
||||
def __track__(conf, obj):
|
||||
Printf.track(obj)
|
||||
msg, album = API.getAlbum(obj.album.id)
|
||||
if conf.saveCovers:
|
||||
__downloadCover__(conf, album)
|
||||
__downloadTrack__(conf, obj, album)
|
||||
|
||||
|
||||
def __video__(conf, obj):
|
||||
Printf.video(obj)
|
||||
__downloadVideo__(conf, obj, obj.album)
|
||||
|
||||
|
||||
def __artist__(conf, obj):
|
||||
msg, albums = API.getArtistAlbums(obj.id, conf.includeEP)
|
||||
Printf.artist(obj, len(albums))
|
||||
if not isNull(msg):
|
||||
Printf.err(msg)
|
||||
return
|
||||
for item in albums:
|
||||
__album__(conf, item)
|
||||
|
||||
|
||||
def __playlist__(conf, obj):
|
||||
Printf.playlist(obj)
|
||||
msg, tracks, videos = API.getItems(obj.uuid, Type.Playlist)
|
||||
if not isNull(msg):
|
||||
Printf.err(msg)
|
||||
return
|
||||
|
||||
for index, item in enumerate(tracks):
|
||||
mag, album = API.getAlbum(item.album.id)
|
||||
item.trackNumberOnPlaylist = index + 1
|
||||
__downloadTrack__(conf, item, album, obj)
|
||||
for item in videos:
|
||||
__downloadVideo__(conf, item, None)
|
||||
|
||||
|
||||
def __file__(user, conf, string):
|
||||
txt = getFileContent(string)
|
||||
if isNull(txt):
|
||||
Printf.err("Nothing can read!")
|
||||
return
|
||||
array = txt.split('\n')
|
||||
for item in array:
|
||||
if isNull(item):
|
||||
continue
|
||||
if item[0] == '#':
|
||||
continue
|
||||
if item[0] == '[':
|
||||
continue
|
||||
start(user, conf, item)
|
||||
|
||||
|
||||
def start(user, conf, string):
|
||||
__loadAPI__(user)
|
||||
|
||||
if os.path.exists(string):
|
||||
__file__(user, conf, string)
|
||||
return
|
||||
|
||||
msg, etype, obj = API.getByString(string)
|
||||
if etype == Type.Null or not isNull(msg):
|
||||
Printf.err(msg)
|
||||
return
|
||||
|
||||
if etype == Type.Album:
|
||||
__album__(conf, obj)
|
||||
if etype == Type.Track:
|
||||
__track__(conf, obj)
|
||||
if etype == Type.Video:
|
||||
__loadVideoAPI__(user)
|
||||
__video__(conf, obj)
|
||||
if etype == Type.Artist:
|
||||
__artist__(conf, obj)
|
||||
if etype == Type.Playlist:
|
||||
__playlist__(conf, obj)
|
||||
downloadVideo(item, album, playlist)
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : enum.py
|
||||
@File : enums.py
|
||||
@Time : 2020/08/08
|
||||
@Author : Yaronzz
|
||||
@Version : 2.0
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
'''
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class AudioQuality(Enum):
|
||||
Normal = 0
|
||||
High = 1
|
||||
HiFi = 2
|
||||
Master = 3
|
||||
Max = 4
|
||||
|
||||
|
||||
class VideoQuality(Enum):
|
||||
P240 = 240
|
||||
@@ -23,10 +26,12 @@ class VideoQuality(Enum):
|
||||
P720 = 720
|
||||
P1080 = 1080
|
||||
|
||||
|
||||
class Type(Enum):
|
||||
Album = 0
|
||||
Artist = 1
|
||||
Playlist = 2
|
||||
Track = 3
|
||||
Video = 4
|
||||
Null = 5
|
||||
Track = 1
|
||||
Video = 2
|
||||
Playlist = 3
|
||||
Artist = 4
|
||||
Mix = 5
|
||||
Null = 6
|
||||
@@ -0,0 +1,320 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
@File : events.py
|
||||
@Date : 2022/06/10
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
|
||||
from download import *
|
||||
|
||||
'''
|
||||
=================================
|
||||
START DOWNLOAD
|
||||
=================================
|
||||
'''
|
||||
|
||||
|
||||
def start_album(obj: Album):
|
||||
Printf.album(obj)
|
||||
tracks, videos = TIDAL_API.getItems(obj.id, Type.Album)
|
||||
if SETTINGS.saveAlbumInfo:
|
||||
downloadAlbumInfo(obj, tracks)
|
||||
if SETTINGS.saveCovers and obj.cover is not None:
|
||||
downloadCover(obj)
|
||||
downloadTracks(tracks, obj)
|
||||
if SETTINGS.downloadVideos:
|
||||
downloadVideos(videos, obj)
|
||||
|
||||
|
||||
def start_track(obj: Track):
|
||||
album = TIDAL_API.getAlbum(obj.album.id)
|
||||
if SETTINGS.saveCovers:
|
||||
downloadCover(album)
|
||||
downloadTrack(obj, album)
|
||||
|
||||
|
||||
def start_video(obj: Video):
|
||||
downloadVideo(obj, obj.album)
|
||||
|
||||
|
||||
def start_artist(obj: Artist):
|
||||
albums = TIDAL_API.getArtistAlbums(obj.id, SETTINGS.includeEP)
|
||||
Printf.artist(obj, len(albums))
|
||||
for item in albums:
|
||||
start_album(item)
|
||||
|
||||
|
||||
def start_playlist(obj: Playlist):
|
||||
Printf.playlist(obj)
|
||||
tracks, videos = TIDAL_API.getItems(obj.uuid, Type.Playlist)
|
||||
downloadTracks(tracks, None, obj)
|
||||
if SETTINGS.downloadVideos:
|
||||
downloadVideos(videos, None, obj)
|
||||
|
||||
|
||||
def start_mix(obj: Mix):
|
||||
Printf.mix(obj)
|
||||
downloadTracks(obj.tracks, None, None)
|
||||
downloadVideos(obj.videos, None, None)
|
||||
|
||||
|
||||
def start_file(string):
|
||||
txt = aigpy.file.getContent(string)
|
||||
if aigpy.string.isNull(txt):
|
||||
Printf.err("Nothing can read!")
|
||||
return
|
||||
array = txt.split('\n')
|
||||
for item in array:
|
||||
if aigpy.string.isNull(item):
|
||||
continue
|
||||
if item[0] == '#':
|
||||
continue
|
||||
if item[0] == '[':
|
||||
continue
|
||||
start(item)
|
||||
|
||||
|
||||
def start_type(etype: Type, obj):
|
||||
if etype == Type.Album:
|
||||
start_album(obj)
|
||||
elif etype == Type.Track:
|
||||
start_track(obj)
|
||||
elif etype == Type.Video:
|
||||
start_video(obj)
|
||||
elif etype == Type.Artist:
|
||||
start_artist(obj)
|
||||
elif etype == Type.Playlist:
|
||||
start_playlist(obj)
|
||||
elif etype == Type.Mix:
|
||||
start_mix(obj)
|
||||
|
||||
|
||||
def start(string):
|
||||
if aigpy.string.isNull(string):
|
||||
Printf.err('Please enter something.')
|
||||
return
|
||||
|
||||
strings = string.split(" ")
|
||||
for item in strings:
|
||||
if aigpy.string.isNull(item):
|
||||
continue
|
||||
if os.path.exists(item):
|
||||
start_file(item)
|
||||
return
|
||||
|
||||
try:
|
||||
etype, obj = TIDAL_API.getByString(item)
|
||||
except Exception as e:
|
||||
Printf.err(str(e) + " [" + item + "]")
|
||||
return
|
||||
|
||||
try:
|
||||
start_type(etype, obj)
|
||||
except Exception as e:
|
||||
Printf.err(str(e))
|
||||
|
||||
|
||||
'''
|
||||
=================================
|
||||
CHANGE SETTINGS
|
||||
=================================
|
||||
'''
|
||||
|
||||
|
||||
def changePathSettings():
|
||||
Printf.settings()
|
||||
SETTINGS.downloadPath = Printf.enterPath(
|
||||
LANG.select.CHANGE_DOWNLOAD_PATH,
|
||||
LANG.select.MSG_PATH_ERR,
|
||||
'0',
|
||||
SETTINGS.downloadPath)
|
||||
SETTINGS.albumFolderFormat = Printf.enterFormat(
|
||||
LANG.select.CHANGE_ALBUM_FOLDER_FORMAT,
|
||||
SETTINGS.albumFolderFormat,
|
||||
SETTINGS.getDefaultPathFormat(Type.Album))
|
||||
SETTINGS.playlistFolderFormat = Printf.enterFormat(
|
||||
LANG.select.CHANGE_PLAYLIST_FOLDER_FORMAT,
|
||||
SETTINGS.playlistFolderFormat,
|
||||
SETTINGS.getDefaultPathFormat(Type.Playlist))
|
||||
SETTINGS.trackFileFormat = Printf.enterFormat(
|
||||
LANG.select.CHANGE_TRACK_FILE_FORMAT,
|
||||
SETTINGS.trackFileFormat,
|
||||
SETTINGS.getDefaultPathFormat(Type.Track))
|
||||
SETTINGS.videoFileFormat = Printf.enterFormat(
|
||||
LANG.select.CHANGE_VIDEO_FILE_FORMAT,
|
||||
SETTINGS.videoFileFormat,
|
||||
SETTINGS.getDefaultPathFormat(Type.Video))
|
||||
SETTINGS.save()
|
||||
|
||||
|
||||
def changeQualitySettings():
|
||||
Printf.settings()
|
||||
SETTINGS.audioQuality = AudioQuality(
|
||||
int(Printf.enterLimit(LANG.select.CHANGE_AUDIO_QUALITY,
|
||||
LANG.select.MSG_INPUT_ERR,
|
||||
['0', '1', '2', '3', '4'])))
|
||||
SETTINGS.videoQuality = VideoQuality(
|
||||
int(Printf.enterLimit(LANG.select.CHANGE_VIDEO_QUALITY,
|
||||
LANG.select.MSG_INPUT_ERR,
|
||||
['1080', '720', '480', '360'])))
|
||||
SETTINGS.save()
|
||||
|
||||
|
||||
def changeSettings():
|
||||
Printf.settings()
|
||||
SETTINGS.showProgress = Printf.enterBool(LANG.select.CHANGE_SHOW_PROGRESS)
|
||||
SETTINGS.showTrackInfo = Printf.enterBool(LANG.select.CHANGE_SHOW_TRACKINFO)
|
||||
SETTINGS.checkExist = Printf.enterBool(LANG.select.CHANGE_CHECK_EXIST)
|
||||
SETTINGS.includeEP = Printf.enterBool(LANG.select.CHANGE_INCLUDE_EP)
|
||||
SETTINGS.saveCovers = Printf.enterBool(LANG.select.CHANGE_SAVE_COVERS)
|
||||
SETTINGS.saveAlbumInfo = Printf.enterBool(LANG.select.CHANGE_SAVE_ALBUM_INFO)
|
||||
SETTINGS.downloadVideos = Printf.enterBool(LANG.select.CHANGE_DOWNLOAD_VIDEOS)
|
||||
SETTINGS.lyricFile = Printf.enterBool(LANG.select.CHANGE_ADD_LRC_FILE)
|
||||
SETTINGS.multiThread = Printf.enterBool(LANG.select.CHANGE_MULITHREAD_DOWNLOAD)
|
||||
SETTINGS.usePlaylistFolder = Printf.enterBool(LANG.select.SETTING_USE_PLAYLIST_FOLDER + "('0'-No,'1'-Yes):")
|
||||
SETTINGS.downloadDelay = Printf.enterBool(LANG.select.CHANGE_USE_DOWNLOAD_DELAY)
|
||||
SETTINGS.language = Printf.enter(LANG.select.CHANGE_LANGUAGE + "(" + LANG.getLangChoicePrint() + "):")
|
||||
LANG.setLang(SETTINGS.language)
|
||||
SETTINGS.save()
|
||||
|
||||
|
||||
def changeApiKey():
|
||||
item = apiKey.getItem(SETTINGS.apiKeyIndex)
|
||||
ver = apiKey.getVersion()
|
||||
|
||||
Printf.info(f'Current APIKeys: {str(SETTINGS.apiKeyIndex)} {item["platform"]}-{item["formats"]}')
|
||||
Printf.info(f'Current Version: {str(ver)}')
|
||||
Printf.apikeys(apiKey.getItems())
|
||||
index = int(Printf.enterLimit("APIKEY index:", LANG.select.MSG_INPUT_ERR, apiKey.getLimitIndexs()))
|
||||
|
||||
if index != SETTINGS.apiKeyIndex:
|
||||
SETTINGS.apiKeyIndex = index
|
||||
SETTINGS.save()
|
||||
TIDAL_API.apiKey = apiKey.getItem(index)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
'''
|
||||
=================================
|
||||
LOGIN
|
||||
=================================
|
||||
'''
|
||||
|
||||
|
||||
def __displayTime__(seconds, granularity=2):
|
||||
if seconds <= 0:
|
||||
return "unknown"
|
||||
|
||||
result = []
|
||||
intervals = (
|
||||
('weeks', 604800),
|
||||
('days', 86400),
|
||||
('hours', 3600),
|
||||
('minutes', 60),
|
||||
('seconds', 1),
|
||||
)
|
||||
|
||||
for name, count in intervals:
|
||||
value = seconds // count
|
||||
if value:
|
||||
seconds -= value * count
|
||||
if value == 1:
|
||||
name = name.rstrip('s')
|
||||
result.append("{} {}".format(value, name))
|
||||
return ', '.join(result[:granularity])
|
||||
|
||||
|
||||
def loginByWeb():
|
||||
try:
|
||||
print(LANG.select.AUTH_START_LOGIN)
|
||||
# get device code
|
||||
url = TIDAL_API.getDeviceCode()
|
||||
|
||||
print(LANG.select.AUTH_NEXT_STEP.format(
|
||||
aigpy.cmd.green(url),
|
||||
aigpy.cmd.yellow(__displayTime__(TIDAL_API.key.authCheckTimeout))))
|
||||
print(LANG.select.AUTH_WAITING)
|
||||
|
||||
start = time.time()
|
||||
elapsed = 0
|
||||
while elapsed < TIDAL_API.key.authCheckTimeout:
|
||||
elapsed = time.time() - start
|
||||
if not TIDAL_API.checkAuthStatus():
|
||||
time.sleep(TIDAL_API.key.authCheckInterval + 1)
|
||||
continue
|
||||
|
||||
Printf.success(LANG.select.MSG_VALID_ACCESSTOKEN.format(
|
||||
__displayTime__(int(TIDAL_API.key.expiresIn))))
|
||||
|
||||
TOKEN.userid = TIDAL_API.key.userId
|
||||
TOKEN.countryCode = TIDAL_API.key.countryCode
|
||||
TOKEN.accessToken = TIDAL_API.key.accessToken
|
||||
TOKEN.refreshToken = TIDAL_API.key.refreshToken
|
||||
TOKEN.expiresAfter = time.time() + int(TIDAL_API.key.expiresIn)
|
||||
TOKEN.save()
|
||||
return True
|
||||
|
||||
raise Exception(LANG.select.AUTH_TIMEOUT)
|
||||
except Exception as e:
|
||||
Printf.err(f"Login failed.{str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def loginByConfig():
|
||||
try:
|
||||
if aigpy.string.isNull(TOKEN.accessToken):
|
||||
return False
|
||||
|
||||
if TIDAL_API.verifyAccessToken(TOKEN.accessToken):
|
||||
Printf.info(LANG.select.MSG_VALID_ACCESSTOKEN.format(
|
||||
__displayTime__(int(TOKEN.expiresAfter - time.time()))))
|
||||
|
||||
TIDAL_API.key.countryCode = TOKEN.countryCode
|
||||
TIDAL_API.key.userId = TOKEN.userid
|
||||
TIDAL_API.key.accessToken = TOKEN.accessToken
|
||||
return True
|
||||
|
||||
Printf.info(LANG.select.MSG_INVALID_ACCESSTOKEN)
|
||||
if TIDAL_API.refreshAccessToken(TOKEN.refreshToken):
|
||||
Printf.success(LANG.select.MSG_VALID_ACCESSTOKEN.format(
|
||||
__displayTime__(int(TIDAL_API.key.expiresIn))))
|
||||
|
||||
TOKEN.userid = TIDAL_API.key.userId
|
||||
TOKEN.countryCode = TIDAL_API.key.countryCode
|
||||
TOKEN.accessToken = TIDAL_API.key.accessToken
|
||||
TOKEN.expiresAfter = time.time() + int(TIDAL_API.key.expiresIn)
|
||||
TOKEN.save()
|
||||
return True
|
||||
else:
|
||||
TokenSettings().save()
|
||||
return False
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
|
||||
def loginByAccessToken():
|
||||
try:
|
||||
print("-------------AccessToken---------------")
|
||||
token = Printf.enter("accessToken('0' go back):")
|
||||
if token == '0':
|
||||
return
|
||||
TIDAL_API.loginByAccessToken(token, TOKEN.userid)
|
||||
except Exception as e:
|
||||
Printf.err(str(e))
|
||||
return
|
||||
|
||||
print("-------------RefreshToken---------------")
|
||||
refreshToken = Printf.enter("refreshToken('0' to skip):")
|
||||
if refreshToken == '0':
|
||||
refreshToken = TOKEN.refreshToken
|
||||
|
||||
TOKEN.accessToken = token
|
||||
TOKEN.refreshToken = refreshToken
|
||||
TOKEN.expiresAfter = 0
|
||||
TOKEN.countryCode = TIDAL_API.key.countryCode
|
||||
TOKEN.save()
|
||||
@@ -0,0 +1,300 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
@File : test.py
|
||||
@Date : 2022/03/28
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import importlib
|
||||
import sys
|
||||
import _thread
|
||||
|
||||
from events import *
|
||||
from printf import *
|
||||
|
||||
|
||||
def enableGui():
|
||||
try:
|
||||
importlib.import_module('PyQt5')
|
||||
importlib.import_module('qt_material')
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
|
||||
if not enableGui():
|
||||
def startGui():
|
||||
Printf.err("Not support gui. Please type: `pip3 install PyQt5 qt_material`")
|
||||
else:
|
||||
from PyQt5.QtCore import Qt, QObject
|
||||
from PyQt5.QtGui import QTextCursor, QKeyEvent
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5 import QtWidgets
|
||||
from qt_material import apply_stylesheet
|
||||
|
||||
class EmittingStream(QObject):
|
||||
textWritten = pyqtSignal(str)
|
||||
|
||||
def write(self, text):
|
||||
self.textWritten.emit(str(text))
|
||||
|
||||
class MainView(QtWidgets.QWidget):
|
||||
s_downloadEnd = pyqtSignal(str, bool, str)
|
||||
|
||||
def __init__(self, ) -> None:
|
||||
super().__init__()
|
||||
self.initView()
|
||||
self.setMinimumSize(800, 620)
|
||||
self.setWindowTitle("TIDAL-DL")
|
||||
|
||||
def __info__(self, msg):
|
||||
QtWidgets.QMessageBox.information(self, 'Info', msg, QtWidgets.QMessageBox.Yes)
|
||||
|
||||
def __output__(self, text):
|
||||
cursor = self.c_printTextEdit.textCursor()
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.insertText(text)
|
||||
self.c_printTextEdit.setTextCursor(cursor)
|
||||
self.c_printTextEdit.ensureCursorVisible()
|
||||
|
||||
def initView(self):
|
||||
self.c_lineSearch = QtWidgets.QLineEdit()
|
||||
self.c_btnSearch = QtWidgets.QPushButton("Search")
|
||||
self.c_btnDownload = QtWidgets.QPushButton("Download")
|
||||
self.c_combType = QtWidgets.QComboBox()
|
||||
self.c_combTQuality = QtWidgets.QComboBox()
|
||||
self.c_combVQuality = QtWidgets.QComboBox()
|
||||
|
||||
# Supported types for search
|
||||
self.m_supportType = [Type.Album, Type.Playlist, Type.Track, Type.Video, Type.Artist]
|
||||
for item in self.m_supportType:
|
||||
self.c_combType.addItem(item.name, item)
|
||||
|
||||
for item in AudioQuality:
|
||||
self.c_combTQuality.addItem(item.name, item)
|
||||
for item in VideoQuality:
|
||||
self.c_combVQuality.addItem(item.name, item)
|
||||
self.c_combTQuality.setCurrentText(SETTINGS.audioQuality.name)
|
||||
self.c_combVQuality.setCurrentText(SETTINGS.videoQuality.name)
|
||||
|
||||
# init table
|
||||
columnNames = ['#', 'Title', 'Artists', 'Quality']
|
||||
self.c_tableInfo = QtWidgets.QTableWidget()
|
||||
self.c_tableInfo.setColumnCount(len(columnNames))
|
||||
self.c_tableInfo.setRowCount(0)
|
||||
self.c_tableInfo.setShowGrid(False)
|
||||
self.c_tableInfo.verticalHeader().setVisible(False)
|
||||
self.c_tableInfo.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||
self.c_tableInfo.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.c_tableInfo.horizontalHeader().setStretchLastSection(True)
|
||||
self.c_tableInfo.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
|
||||
self.c_tableInfo.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||
self.c_tableInfo.setFocusPolicy(Qt.NoFocus)
|
||||
for index, name in enumerate(columnNames):
|
||||
item = QtWidgets.QTableWidgetItem(name)
|
||||
self.c_tableInfo.setHorizontalHeaderItem(index, item)
|
||||
|
||||
# Create Tree View for playlists.
|
||||
self.tree_playlists = QtWidgets.QTreeWidget()
|
||||
self.tree_playlists.setAnimated(False)
|
||||
self.tree_playlists.setIndentation(20)
|
||||
self.tree_playlists.setSortingEnabled(True)
|
||||
self.tree_playlists.setFixedWidth(200)
|
||||
self.tree_playlists.setColumnCount(1)
|
||||
self.tree_playlists.setHeaderLabels(("User Playlists",))
|
||||
# self.tree_playlists.setColumnWidth(0, 100)
|
||||
self.tree_playlists.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
|
||||
# print
|
||||
self.c_printTextEdit = QtWidgets.QTextEdit()
|
||||
self.c_printTextEdit.setReadOnly(True)
|
||||
self.c_printTextEdit.setFixedHeight(100)
|
||||
sys.stdout = EmittingStream(textWritten=self.__output__)
|
||||
sys.stderr = EmittingStream(textWritten=self.__output__)
|
||||
|
||||
# layout
|
||||
self.lineGrid = QtWidgets.QHBoxLayout()
|
||||
self.lineGrid.addWidget(self.c_combType)
|
||||
self.lineGrid.addWidget(self.c_lineSearch)
|
||||
self.lineGrid.addWidget(self.c_btnSearch)
|
||||
|
||||
self.line2Grid = QtWidgets.QHBoxLayout()
|
||||
self.line2Grid.addWidget(QtWidgets.QLabel("QUALITY:"))
|
||||
self.line2Grid.addWidget(self.c_combTQuality)
|
||||
self.line2Grid.addWidget(self.c_combVQuality)
|
||||
self.line2Grid.addStretch(4)
|
||||
self.line2Grid.addWidget(self.c_btnDownload)
|
||||
|
||||
self.funcGrid = QtWidgets.QVBoxLayout()
|
||||
self.funcGrid.addLayout(self.lineGrid)
|
||||
self.funcGrid.addWidget(self.c_tableInfo)
|
||||
self.funcGrid.addLayout(self.line2Grid)
|
||||
self.funcGrid.addWidget(self.c_printTextEdit)
|
||||
|
||||
self.mainGrid = QtWidgets.QHBoxLayout(self)
|
||||
self.mainGrid.addWidget(self.tree_playlists)
|
||||
self.mainGrid.addLayout(self.funcGrid)
|
||||
|
||||
# connect
|
||||
self.c_btnSearch.clicked.connect(self.search)
|
||||
self.c_lineSearch.returnPressed.connect(self.search)
|
||||
self.c_btnDownload.clicked.connect(self.download)
|
||||
self.s_downloadEnd.connect(self.downloadEnd)
|
||||
self.c_combTQuality.currentIndexChanged.connect(self.changeTQuality)
|
||||
self.c_combVQuality.currentIndexChanged.connect(self.changeVQuality)
|
||||
self.tree_playlists.itemClicked.connect(self.__displayTracks__)
|
||||
|
||||
def keyPressEvent(self, event: QKeyEvent):
|
||||
if event.modifiers() & Qt.MetaModifier and event.key() == Qt.Key_A:
|
||||
self.c_tableInfo.selectAll()
|
||||
|
||||
def addItem(self, rowIdx: int, colIdx: int, text):
|
||||
if isinstance(text, str):
|
||||
item = QtWidgets.QTableWidgetItem(text)
|
||||
self.c_tableInfo.setItem(rowIdx, colIdx, item)
|
||||
|
||||
def search(self):
|
||||
self.c_tableInfo.setRowCount(0)
|
||||
self.s_type = self.c_combType.currentData()
|
||||
self.s_text = self.c_lineSearch.text()
|
||||
|
||||
if self.s_text.startswith('http'):
|
||||
tmpType, tmpId = TIDAL_API.parseUrl(self.s_text)
|
||||
if tmpType == Type.Null:
|
||||
self.__info__('Url not support!')
|
||||
return
|
||||
elif tmpType not in self.m_supportType:
|
||||
self.__info__(f'Type[{tmpType.name}] not support!')
|
||||
return
|
||||
|
||||
tmpData = TIDAL_API.getTypeData(tmpId, tmpType)
|
||||
if tmpData is None:
|
||||
self.__info__('Url is wrong!')
|
||||
return
|
||||
self.s_type = tmpType
|
||||
self.s_array = [tmpData]
|
||||
self.s_result = None
|
||||
self.c_combType.setCurrentText(tmpType.name)
|
||||
else:
|
||||
self.s_result = TIDAL_API.search(self.s_text, self.s_type)
|
||||
self.s_array = TIDAL_API.getSearchResultItems(self.s_result, self.s_type)
|
||||
|
||||
if len(self.s_array) <= 0:
|
||||
self.__info__('No result!')
|
||||
return
|
||||
|
||||
self.setSearchResults(self.s_array, self.s_type)
|
||||
|
||||
def setSearchResults(self, s_array, s_type):
|
||||
self.c_tableInfo.clearSelection()
|
||||
self.c_tableInfo.setRowCount(len(s_array))
|
||||
|
||||
for index, item in enumerate(s_array):
|
||||
self.addItem(index, 0, str(index + 1))
|
||||
if s_type in [Type.Album, Type.Track]:
|
||||
self.addItem(index, 1, item.title)
|
||||
self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists))
|
||||
self.addItem(index, 3, item.audioQuality)
|
||||
elif s_type in [Type.Video]:
|
||||
self.addItem(index, 1, item.title)
|
||||
self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists))
|
||||
self.addItem(index, 3, item.quality)
|
||||
elif s_type in [Type.Playlist]:
|
||||
self.addItem(index, 1, item.title)
|
||||
self.addItem(index, 2, '')
|
||||
self.addItem(index, 3, '')
|
||||
elif s_type in [Type.Artist]:
|
||||
self.addItem(index, 1, item.name)
|
||||
self.addItem(index, 2, '')
|
||||
self.addItem(index, 3, '')
|
||||
self.c_tableInfo.viewport().update()
|
||||
|
||||
def download(self):
|
||||
if self.c_tableInfo.selectionModel().hasSelection() == False:
|
||||
self.__info__('Please select a row first.')
|
||||
return
|
||||
|
||||
rows = self.c_tableInfo.selectionModel().selectedRows()
|
||||
items = []
|
||||
for row in rows:
|
||||
items.append(self.s_array[row.row()])
|
||||
|
||||
self.__downloadFunc__(items)
|
||||
|
||||
def __downloadFunc__(self, items):
|
||||
self.c_btnDownload.setEnabled(False)
|
||||
|
||||
def __thread_download__(model: MainView, items):
|
||||
itemTitle = ''
|
||||
type = model.s_type
|
||||
try:
|
||||
for item in items:
|
||||
if isinstance(item, Artist):
|
||||
itemTitle = item.name
|
||||
else:
|
||||
itemTitle = item.title
|
||||
start_type(type, item)
|
||||
model.s_downloadEnd.emit('Download Success!', True, '')
|
||||
except Exception as e:
|
||||
model.s_downloadEnd.emit(itemTitle, False, str(e))
|
||||
|
||||
_thread.start_new_thread(__thread_download__, (self, items))
|
||||
|
||||
def downloadEnd(self, title, result, msg):
|
||||
self.c_btnDownload.setEnabled(True)
|
||||
self.c_btnDownload.setText(f"Download")
|
||||
|
||||
if result:
|
||||
self.__info__(f"Download finished.")
|
||||
else:
|
||||
self.__info__(f"Download '{title}' failed:{msg}")
|
||||
|
||||
def checkLogin(self):
|
||||
if not loginByConfig():
|
||||
self.__info__('Login failed. Please log in using the command line first.')
|
||||
else:
|
||||
self.__showSelfPlaylists__()
|
||||
|
||||
def changeTQuality(self, index):
|
||||
SETTINGS.audioQuality = self.c_combTQuality.itemData(index)
|
||||
SETTINGS.save()
|
||||
|
||||
def changeVQuality(self, index):
|
||||
SETTINGS.videoQuality = self.c_combVQuality.itemData(index)
|
||||
SETTINGS.save()
|
||||
|
||||
def __showSelfPlaylists__(self):
|
||||
playlists = TIDAL_API.getPlaylistSelf()
|
||||
|
||||
for playlist in playlists:
|
||||
item = QtWidgets.QTreeWidgetItem(self.tree_playlists)
|
||||
item.setText(0, playlist.title)
|
||||
item.setText(1, str(playlist.numberOfTracks))
|
||||
item.setText(2, playlist.uuid)
|
||||
|
||||
def __displayTracks__(self, item, column):
|
||||
tracks, videos = TIDAL_API.getItems(item.text(2), Type.Playlist)
|
||||
self.s_array = tracks
|
||||
self.s_type = Type.Track
|
||||
|
||||
self.setSearchResults(tracks, Type.Track)
|
||||
|
||||
def startGui():
|
||||
aigpy.cmd.enableColor(False)
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
apply_stylesheet(app, theme='dark_blue.xml')
|
||||
|
||||
window = MainView()
|
||||
window.show()
|
||||
window.checkLogin()
|
||||
|
||||
app.exec_()
|
||||
|
||||
if __name__ == '__main__':
|
||||
SETTINGS.read(getProfilePath())
|
||||
TOKEN.read(getTokenPath())
|
||||
startGui()
|
||||
@@ -9,6 +9,7 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangArabic(object):
|
||||
SETTING = "الاعدادت"
|
||||
VALUE = "القيمة"
|
||||
@@ -29,8 +30,20 @@ class LangArabic(object):
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "خيار"
|
||||
FUNCTION = "وظيفة"
|
||||
@@ -39,8 +52,10 @@ class LangArabic(object):
|
||||
CHOICE_EXIT = "اخرج"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "الاعدادات"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "اعداد AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "اعداد AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "التحميل عبر الرابط او رقم التتبع"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[خطأ]"
|
||||
PRINT_INFO = "[معلومة]"
|
||||
@@ -48,13 +63,13 @@ class LangArabic(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "ادخل الخيار:"
|
||||
PRINT_LATEST_VERSION = "آخر اصدر:"
|
||||
#PRINT_USERNAME = "اسم المستخدم:"
|
||||
#PRINT_PASSWORD = "رمز الدخول:"
|
||||
|
||||
# PRINT_USERNAME = "اسم المستخدم:"
|
||||
# PRINT_PASSWORD = "رمز الدخول:"
|
||||
|
||||
CHANGE_START_SETTINGS = "بدء الاعدادات('0'-Return,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_PATH = "مجلد التنزيل('0' not modify):"
|
||||
CHANGE_AUDIO_QUALITY = "دقة الصوت('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "دقة الفديو('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "دقة الصوت('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "دقة الفديو(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "تحويل M4a الى mp4('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "اضافة توقيع الفنان('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_HYPHEN = "استخدم السطور التحتية بدل الفراغات('0'-No,'1'-Yes):"
|
||||
@@ -66,9 +81,20 @@ class LangArabic(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "اضف رقم التتبع قبل اسم مجلد الالبوم('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_COVERS = "حفظ صورة الالبوم('0'-No,'1'-Yes):"
|
||||
CHANGE_LANGUAGE = "اختر لغة"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
@@ -76,9 +102,9 @@ class LangArabic(object):
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "!مجلد التنزيل خاطئ"
|
||||
MSG_INPUT_ERR = "!ادخال خاطئ"
|
||||
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangChinese(object):
|
||||
SETTING = "设置"
|
||||
VALUE = "值"
|
||||
SETTING_DOWNLOAD_PATH = "下载目录"
|
||||
SETTING_ONLY_M4A = "转换mp4为m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "文件名添加脏话标签Explicit"
|
||||
SETTING_ADD_EXPLICIT_TAG = "文件名添加脏标Explicit"
|
||||
SETTING_ADD_HYPHEN = "文件名用'-'代替空格"
|
||||
SETTING_ADD_YEAR = "专辑文件夹添加年代标签"
|
||||
SETTING_USE_TRACK_NUM = "歌曲名称添加序号"
|
||||
@@ -29,18 +30,32 @@ class LangChinese(object):
|
||||
SETTING_USE_PLAYLIST_FOLDER = "将歌单下载到歌单目录"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "多线程下载"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "专辑目录格式"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "歌曲文件名格式"
|
||||
SETTING_VIDEO_FILE_FORMAT = "视频文件格式"
|
||||
SETTING_SHOW_PROGRESS = "显示进度条"
|
||||
SETTING_SHOW_TRACKINFO = "显示歌曲信息"
|
||||
SETTING_SAVE_ALBUMINFO = "保存AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "添加歌词"
|
||||
SETTING_LYRICS_SERVER_PROXY = "歌词服务器代理"
|
||||
SETTING_ADD_LRC_FILE = "保存歌词文件 (.lrc file)"
|
||||
SETTING_PATH = "配置文件目录"
|
||||
SETTING_APIKEY = "APIKey支持"
|
||||
SETTING_ADD_TYPE_FOLDER = "添加类型文件夹"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "选项"
|
||||
FUNCTION = "功能"
|
||||
CHOICE_ENTER = "输入"
|
||||
CHOICE_ENTER_URLID = "输入 'Url或ID':"
|
||||
CHOICE_EXIT = "退出"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "检查AccessToken"
|
||||
CHOICE_SETTINGS = "配置"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "设置AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "设置AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "通过链接或ID下载"
|
||||
CHOICE_LOGOUT = "注销"
|
||||
CHOICE_APIKEY = "选择APIKey"
|
||||
|
||||
PRINT_ERR = "[错误]"
|
||||
PRINT_INFO = "[提示]"
|
||||
@@ -48,13 +63,13 @@ class LangChinese(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "输入选项:"
|
||||
PRINT_LATEST_VERSION = "最新版本:"
|
||||
#PRINT_USERNAME = "用户:"
|
||||
#PRINT_PASSWORD = "密码:"
|
||||
# PRINT_USERNAME = "用户:"
|
||||
# PRINT_PASSWORD = "密码:"
|
||||
|
||||
CHANGE_START_SETTINGS = "开始设置('0'-返回,'1'-是):"
|
||||
CHANGE_DOWNLOAD_PATH = "下载路径('0' 不修改):"
|
||||
CHANGE_AUDIO_QUALITY = "音频质量('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "视频质量('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "音频质量('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "视频质量(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "将Mp4格式的音频转为M4a('0'-不,'1'-是):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "歌名后添加脏话标签('0'-不,'1'-是):"
|
||||
CHANGE_ADD_HYPHEN = "文件名中用'-'代替空格('0'-不,'1'-是):"
|
||||
@@ -67,8 +82,19 @@ class LangChinese(object):
|
||||
CHANGE_SAVE_COVERS = "保存封面('0'-不,'1'-是):"
|
||||
CHANGE_LANGUAGE = "选择语言"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "专辑目录格式('0' 不修改):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "歌曲文件名格式('0' 不修改):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "视频文件名格式('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "显示进度条('0'-不,'1'-是):"
|
||||
CHANGE_SHOW_TRACKINFO = "显示歌曲信息('0'-否,'1'-是):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "保存AlbumInfo.txt('0'-否,'1'-是):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "添加歌词('0'-否,'1'-是):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "歌词服务器代理('0' 不修改):"
|
||||
CHANGE_ADD_LRC_FILE = "保存歌词文件 ('0'-否,'1'-是):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "多线程下载('0'-否,'1'-是):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "开始启动登录..."
|
||||
@@ -76,9 +102,9 @@ class LangChinese(object):
|
||||
AUTH_NEXT_STEP = "请打开 {} 并在 {} 之内完成操作."
|
||||
AUTH_WAITING = "等待登录验证..."
|
||||
AUTH_TIMEOUT = "操作超时."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken保质期为 {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "AccessToken失效. 正在尝试更新它."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken有效期为 {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken失效. 正在尝试更新它."
|
||||
MSG_PATH_ERR = "路径错误!"
|
||||
MSG_INPUT_ERR = "输入错误!"
|
||||
|
||||
@@ -93,7 +119,7 @@ class LangChinese(object):
|
||||
MODEL_VIDEO_NUMBER = '视频数量'
|
||||
MODEL_RELEASE_DATE = '发布时间'
|
||||
MODEL_VERSION = '版本'
|
||||
MODEL_EXPLICIT = '脏话标志'
|
||||
MODEL_EXPLICIT = '脏标'
|
||||
MODEL_ALBUM = '专辑'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = '名称'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# !/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : croatian.py
|
||||
@@ -10,6 +9,7 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangCroatian(object):
|
||||
SETTING = "POSTAVKE"
|
||||
VALUE = "VRIJEDNOST"
|
||||
@@ -30,8 +30,20 @@ class LangCroatian(object):
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "ODABIR"
|
||||
FUNCTION = "FUNKCIJA"
|
||||
@@ -40,8 +52,10 @@ class LangCroatian(object):
|
||||
CHOICE_EXIT = "Izlaz"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Postavke"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Postavi AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Postavi AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Preuzmi po url-u ili ID-u"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
@@ -49,13 +63,13 @@ class LangCroatian(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Unesi odabir:"
|
||||
PRINT_LATEST_VERSION = "Posljednja verzija:"
|
||||
#PRINT_USERNAME = "korisnik:"
|
||||
#PRINT_PASSWORD = "lozinka:"
|
||||
|
||||
# PRINT_USERNAME = "korisnik:"
|
||||
# PRINT_PASSWORD = "lozinka:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Pokreni postavke (0'-Izlaz,'1'-Da):"
|
||||
CHANGE_DOWNLOAD_PATH = "Putanja preuzimanja('0' ne mijenjaj):"
|
||||
CHANGE_AUDIO_QUALITY = "Kvaliteta zvuka('0'-Normalna,'1'-Visoka,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Kvaliteta videozapisa('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "Kvaliteta zvuka('0'-Normalna,'1'-Visoka,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Kvaliteta videozapisa(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Pretvori mp4 u m4a('0'-Ne,'1'-Da):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Dodaj eksplicitni znak u imeni datoteke('0'-Ne,'1'-Da):"
|
||||
CHANGE_ADD_HYPHEN = "Koristi crtice umjesto razmaka u imeni datoteke ('0'-Ne,'1'-Da):"
|
||||
@@ -67,9 +81,20 @@ class LangCroatian(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Dodaj ID oznaku prije imena albuma u datoteci('0'-Ne,'1'-Da):"
|
||||
CHANGE_SAVE_COVERS = "Spremi ilustracije albuma('0'-Ne,'1'-Da):"
|
||||
CHANGE_LANGUAGE = "Odaberi jezik"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
@@ -77,9 +102,9 @@ class LangCroatian(object):
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Pogreska putanje!"
|
||||
MSG_INPUT_ERR = "Pogreska unosa!"
|
||||
|
||||
|
||||
@@ -2,98 +2,124 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : czech.py
|
||||
@Time : 2020/08/20
|
||||
@Author : Tomikk
|
||||
@Version : 1.0
|
||||
@Contact : justtomikk@gmail.com
|
||||
@Time : 2022/11/13
|
||||
@Author : Tomikk & Sweder
|
||||
@Version : 1.2
|
||||
@Contact : justtomikk@gmail.com & djsweder@gmail.com
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangCzech(object):
|
||||
SETTING = "Nastavení"
|
||||
VALUE = "Hodnota"
|
||||
SETTING_DOWNLOAD_PATH = "Umístění staženého souboru"
|
||||
SETTING_ONLY_M4A = "Konvertovat mp4 na m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Přidat explicitní značku"
|
||||
SETTING_ADD_HYPHEN = "Používat pomlčky místo mezer"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Přidat označení explicity"
|
||||
SETTING_ADD_HYPHEN = "Místo mezer použít pomlčky"
|
||||
SETTING_ADD_YEAR = "Přidat rok před jméno složky"
|
||||
SETTING_USE_TRACK_NUM = "Přidat číslo skladby"
|
||||
SETTING_AUDIO_QUALITY = "Kvalita hudby"
|
||||
SETTING_VIDEO_QUALITY = "Kvalita videa"
|
||||
SETTING_CHECK_EXIST = "Zkontrolovat jestli soubor již existuje"
|
||||
SETTING_CHECK_EXIST = "Zkontrolovat existenci souboru"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Jméno interpreta před jménem skladby"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id před složkou alba"
|
||||
SETTING_INCLUDE_EP = "Zahrnout single&ep"
|
||||
SETTING_INCLUDE_EP = "Zahrnout singly & EP"
|
||||
SETTING_SAVE_COVERS = "Uložit obal alba"
|
||||
SETTING_LANGUAGE = "Změna jazyka"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Používat složku playlistu"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Stahování více vlákny"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Formát názvu složky alba"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Formát názvu souboru skladby"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Formát názvu souboru videa"
|
||||
SETTING_SHOW_PROGRESS = "Zobrazit indikátor stavu stahování"
|
||||
SETTING_SHOW_TRACKINFO = "Zobrazit informace o skladbě"
|
||||
SETTING_SAVE_ALBUMINFO = "Uložit soubor AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Přidat texty skladeb"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Server proxy pro texty skladeb"
|
||||
SETTING_ADD_LRC_FILE = "Uložit slova skladby s časováním (soubor .lrc)"
|
||||
SETTING_PATH = "Cesta k souboru s nastavením"
|
||||
SETTING_APIKEY = "APIKey podporuje"
|
||||
SETTING_ADD_TYPE_FOLDER = "Složky dle typu obsahu"
|
||||
SETTING_DOWNLOAD_DELAY = "Stahovat s časovou prodlevou"
|
||||
|
||||
CHOICE = "Výběr"
|
||||
FUNCTION = "Funkce"
|
||||
CHOICE_ENTER = "Enter"
|
||||
CHOICE_ENTER = "Zvolit"
|
||||
CHOICE_ENTER_URLID = "Vložit 'Url/ID':"
|
||||
CHOICE_EXIT = "Ukončit"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Zkontrolovat přístupový token"
|
||||
CHOICE_SETTINGS = "Nastavení"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Nastavit přístupový token"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Stáhnout buď url nebo id"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Nastavit přístupový token"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Stáhnout buď dle URL nebo ID"
|
||||
CHOICE_LOGOUT = "Odhlásit"
|
||||
CHOICE_APIKEY = "Vybrat APIKey"
|
||||
|
||||
PRINT_ERR = "[Error]"
|
||||
PRINT_ERR = "[Chyba]"
|
||||
PRINT_INFO = "[Info]"
|
||||
PRINT_SUCCESS = "[Staženo]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Zvolit volbu:"
|
||||
PRINT_LATEST_VERSION = "Nejnovější verze:"
|
||||
#PRINT_USERNAME = "přihlašovací jméno:"
|
||||
#PRINT_PASSWORD = "heslo"
|
||||
|
||||
CHANGE_START_SETTINGS = "Start settings('0'-Zpět,'1'-Ano):"
|
||||
CHANGE_DOWNLOAD_PATH = "Cesta stažení('0' not modify):"
|
||||
CHANGE_AUDIO_QUALITY = "Kvalita hudby('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Kvalita videa('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "Konvertovat mp4 na m4a('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Přidat explicitní značku k souborům('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_HYPHEN = "V názvech souborů používat místo mezer pomlčky('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_YEAR = "Přidat rok vydání do názvu složky('0'-Ne,'1'-Ano):"
|
||||
CHANGE_USE_TRACK_NUM = "Přidat číslo skladby před název skladby('0'-Ne,'1'-Ano):"
|
||||
CHANGE_CHECK_EXIST = "Zkontrolovat existujicí soubor před stažením('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Přidat jméno interpreta před názvem skladby('0'-Ne,'1'-Ano):"
|
||||
CHANGE_INCLUDE_EP = "Při stahování alba interpreta zahrnout singly a EP('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Přidat ID před složku do alba('0'-Ne,'1'-Ano):"
|
||||
CHANGE_SAVE_COVERS = "Uložit obaly alb('0'-Ne,'1'-Ano):"
|
||||
# PRINT_USERNAME = "přihlašovací jméno:"
|
||||
# PRINT_PASSWORD = "heslo"
|
||||
|
||||
CHANGE_START_SETTINGS = "Spustit nastavení ('0'-Zpět,'1'-Ano):"
|
||||
CHANGE_DOWNLOAD_PATH = "Umístění stažených souborů ('0' beze změny):"
|
||||
CHANGE_AUDIO_QUALITY = "Kvalita hudby ('0'-Normální,'1'-Vysoká,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Kvalita videa (1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Konvertovat mp4 na m4a ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Přidat označení explicity k souborům ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_HYPHEN = "V názvech souborů používat místo mezer pomlčky ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_YEAR = "Přidat rok vydání do názvu složky ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_USE_TRACK_NUM = "Přidat číslo skladby před název skladby ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_CHECK_EXIST = "Zkontrolovat existenci souboru před stažením ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Přidat jméno interpreta před název skladby ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_INCLUDE_EP = "Při stahování alb interpreta zahrnout singly a EP ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Přidat ID před název složky s albem ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_SAVE_COVERS = "Uložit obaly alb ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_LANGUAGE = "Zvolit jazyk"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Formát názvu složky alba ('0' beze změny):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Formát názvu složky skladny ('0' beze změny):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Formát názvu souboru videa ('0'-beze změny,'default'-pro nastavení výchozího názvu):"
|
||||
CHANGE_SHOW_PROGRESS = "Zobrazit indikátor stavu stahování ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_SHOW_TRACKINFO = "Zobrazit info o skladbě ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Uložit soubor AlbumInfo.txt ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Přidat texty skladeb ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Server proxy pro texty skladeb ('0' beze změny):"
|
||||
CHANGE_ADD_LRC_FILE = "Uložit slova skladby s časováním do souboru .lrc) ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Ukládat do složek dle typu obsahu, např. Album/Video/Playlist ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Více vláken pro stahování ('0'-Ne,'1'-Ano):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Stahovat s časovou prodlevou('0'-Ne,'1'-Ano):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Cesta neexistuje!"
|
||||
MSG_INPUT_ERR = "Chyba vstupu!"
|
||||
AUTH_START_LOGIN = "Spouštění přihlašovacího procesu..."
|
||||
AUTH_LOGIN_CODE = "Váš přihlašovací kód je {}"
|
||||
AUTH_NEXT_STEP = "K dokončení nastavení přejděte na stránku {} během následujích {}."
|
||||
AUTH_WAITING = "Čeká se na autorizaci..."
|
||||
AUTH_TIMEOUT = "Vypršel časový limit procesu."
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-PROPERTY"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-PROPERTY"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-PROPERTY"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIST-PROPERTY"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-PROPERTY"
|
||||
MSG_VALID_ACCESSTOKEN = "Přístupový token fukční pro {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Platnost přístupového tokenu vypršela. Pokouším se o obnovení."
|
||||
MSG_PATH_ERR = "Cesta neexistuje!"
|
||||
MSG_INPUT_ERR = "Chyba zadání!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-VLASTNOSTI"
|
||||
MODEL_TRACK_PROPERTY = "SKLADBA-VLASTNOSTI"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-VLASTNOSTI"
|
||||
MODEL_ARTIST_PROPERTY = "INTERPRET-VLASTNOSTI"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-VLASTNOSTI"
|
||||
|
||||
MODEL_TITLE = 'Název skladby'
|
||||
MODEL_TRACK_NUMBER = 'Číslo skladby'
|
||||
MODEL_VIDEO_NUMBER = 'Číslo videa'
|
||||
MODEL_RELEASE_DATE = 'Datum vydání'
|
||||
MODEL_VERSION = 'Verze'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_EXPLICIT = 'Explicitní'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Jméno'
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : danish.py
|
||||
@Time : 2021/03/25
|
||||
@Author : KB885
|
||||
@Version : 1.0
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangDanish(object):
|
||||
SETTING = "INDSTILLINGER"
|
||||
VALUE = "Værdi"
|
||||
SETTING_DOWNLOAD_PATH = "Download sti"
|
||||
SETTING_ONLY_M4A = "Konverter mp4 til m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Tilføj eksplicit tag"
|
||||
SETTING_ADD_HYPHEN = "Tilføj bindestreg"
|
||||
SETTING_ADD_YEAR = "Tilføj år før album mappe"
|
||||
SETTING_USE_TRACK_NUM = "Tilføj titelnummer"
|
||||
SETTING_AUDIO_QUALITY = "Lydkvalitet"
|
||||
SETTING_VIDEO_QUALITY = "Videokvalitet"
|
||||
SETTING_CHECK_EXIST = "Kontroller eksistens"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Kunstnernavn før titelnummer"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id før album mappe"
|
||||
SETTING_INCLUDE_EP = "Inkluder single&ep"
|
||||
SETTING_SAVE_COVERS = "Gem omslag"
|
||||
SETTING_LANGUAGE = "Sprog"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Brug afspilningsmappen"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Flertråede download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Albummappens format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Spillelistemappens format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Musiknummerets filformat"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Vis fremskridt"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "VALG"
|
||||
FUNCTION = "FUNKTION"
|
||||
CHOICE_ENTER = "Indtast"
|
||||
CHOICE_ENTER_URLID = "Indtast 'Url/ID':"
|
||||
CHOICE_EXIT = "Afslut"
|
||||
CHOICE_LOGIN = "Kontroller AccessToken"
|
||||
CHOICE_SETTINGS = "Indstillinger"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Sæt AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Download via url eller id"
|
||||
CHOICE_LOGOUT = "Log ud"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[FEJL]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Indtast Valg:"
|
||||
PRINT_LATEST_VERSION = "Seneste version:"
|
||||
# PRINT_USERNAME = "username:"
|
||||
# PRINT_PASSWORD = "password:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Start indstillinger('0'-Tilbage,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_PATH = "Download stil('0' ændrer ikke):"
|
||||
CHANGE_AUDIO_QUALITY = "Lydkvalitet('0'-Normal,'1'-Høj,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Videokvalitet(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Konverter mp4 til m4a('0'-Nej,'1'-Ja):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Tilføj eksplicit tag til filnavne('0'-Nej,'1'-Ja):"
|
||||
CHANGE_ADD_HYPHEN = "Brug bindestreger i stedet for mellemrum i filnavne('0'-Nej,'1'-Ja):"
|
||||
CHANGE_ADD_YEAR = "Tilføj år til albumnavne('0'-Nej,'1'-Ja):"
|
||||
CHANGE_USE_TRACK_NUM = "Tilføj titelnummer før filnavne('0'-Nej,'1'-Ja):"
|
||||
CHANGE_CHECK_EXIST = "Kontrollér filens eksistens før download('0'-Nej,'1'-Ja):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Tilføj kunsternavn før titlenummer('0'-Nej,'1'-Ja):"
|
||||
CHANGE_INCLUDE_EP = "Inkluder singler og EP'er når der downloades en kunstners album('0'-Nej,'1'-Ja):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Tilføj id før albummappe('0'-Nej,'1'-Ja):"
|
||||
CHANGE_SAVE_COVERS = "Gem omslag('0'-Nej,'1'-Ja):"
|
||||
CHANGE_LANGUAGE = "Vælg sprog"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Albummappeformat('0' Ændrer ikke, 'default' for at indstille som standard):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Spillelistemappeformat('0' Ændrer ikke, 'default' for at indstille som standard):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Musiknummerets filformat('0' Ændrer ikke, 'default' for at indstille som standard):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Vis fremskridt('0'-Nej,'1'-Ja):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starter login-processen."
|
||||
AUTH_LOGIN_CODE = "Din login kode er {}"
|
||||
AUTH_NEXT_STEP = "Gå til {} inden for de næste {} for at afslutte opsætningen."
|
||||
AUTH_WAITING = "Venter på godkendelse..."
|
||||
AUTH_TIMEOUT = "Tiden løb ud."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken tilgængelig for {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken udløb. Forsøger at opdatere"
|
||||
MSG_PATH_ERR = "Sti fejl!"
|
||||
MSG_INPUT_ERR = "Indtastningsfejl!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-PROPERTY"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-PROPERTY"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-PROPERTY"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIST-PROPERTY"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-PROPERTY"
|
||||
|
||||
MODEL_TITLE = 'Titel'
|
||||
MODEL_TRACK_NUMBER = 'Titelnummer'
|
||||
MODEL_VIDEO_NUMBER = 'Videonummer'
|
||||
MODEL_RELEASE_DATE = 'Udgivelses dato'
|
||||
MODEL_VERSION = 'Version'
|
||||
MODEL_EXPLICIT = 'Eksplicit'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Navn'
|
||||
MODEL_TYPE = 'Type'
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : dutch.py
|
||||
@Time : 2022/03/01
|
||||
@Author : bladeoner
|
||||
@Version : 1.0
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangDutch(object):
|
||||
SETTING = "INSTELLINGEN"
|
||||
VALUE = "WAARDE"
|
||||
SETTING_DOWNLOAD_PATH = "Download pad"
|
||||
SETTING_ONLY_M4A = "mp4 naar m4a converteren"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Expliciete tag toevoegen"
|
||||
SETTING_ADD_HYPHEN = "Koppelteken toevoegen"
|
||||
SETTING_ADD_YEAR = "Jaar voor albummap toevoegen"
|
||||
SETTING_USE_TRACK_NUM = "Tracknummer gebruiker toevoegen"
|
||||
SETTING_AUDIO_QUALITY = "Audiokwaliteit"
|
||||
SETTING_VIDEO_QUALITY = "Videokwaliteit"
|
||||
SETTING_CHECK_EXIST = "Controleer of al bestaat"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Artiestnaam voor tracktitel"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID voor albummap"
|
||||
SETTING_INCLUDE_EP = "Inclusief singles en EP's"
|
||||
SETTING_SAVE_COVERS = "Bewaar covers"
|
||||
SETTING_LANGUAGE = "Taal"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Afspeellijst gebruiken"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Downloaden met meerdere threads"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Indeling albummap"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Bestandsindeling bijhouden"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Videobestandsindeling"
|
||||
SETTING_SHOW_PROGRESS = "Toon voortgang"
|
||||
SETTING_SHOW_TRACKINFO = "Toon trackinfo"
|
||||
SETTING_SAVE_ALBUMINFO = "AlbumInfo.txt opslaan"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Songtekst toevoegen"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Tekst server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Getimede songteksten opslaan (.lrc-bestand)"
|
||||
SETTING_PATH = "Instellingen pad"
|
||||
SETTING_APIKEY = "APIKey-ondersteuning"
|
||||
SETTING_ADD_TYPE_FOLDER = "Typemap toevoegen"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "KEUZE"
|
||||
FUNCTION = "FUNCTIE"
|
||||
CHOICE_ENTER = "Voer in"
|
||||
CHOICE_ENTER_URLID = "Vul 'Url/ID' in:"
|
||||
CHOICE_EXIT = "Verlaten"
|
||||
CHOICE_LOGIN = "Toegangstoken controleren"
|
||||
CHOICE_SETTINGS = "Instellingen"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Toegangstoken instellen"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Downloaden via url of ID"
|
||||
CHOICE_LOGOUT = "Uitloggen"
|
||||
CHOICE_APIKEY = "Selecteer APIKey"
|
||||
|
||||
PRINT_ERR = "[FOUT]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCESS]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Voer keuze in:"
|
||||
PRINT_LATEST_VERSION = "Laatste versie:"
|
||||
# PRINT_USERNAME = "gebruikersnaam:"
|
||||
# PRINT_PASSWORD = "wachtwoord:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Start instellingen('0'-Terugkeren,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_PATH = "Downloadpad('0'-niet wijzigen):"
|
||||
CHANGE_AUDIO_QUALITY = "Audiokwaliteit('0'-Normaal,'1'-Hoog,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Videokwaliteit (1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Converteer mp4 naar m4a('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Expliciete tag toevoegen aan bestandsnamen('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ADD_HYPHEN = "Gebruik koppeltekens in plaats van spaties in bestandsnamen ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ADD_YEAR = "Jaar toevoegen aan albummapnamen ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_USE_TRACK_NUM = "Voeg tracknummer toe voor bestandsnamen ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_CHECK_EXIST = "Controleer het bestaande bestand voordat u de track downloadt('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Voeg artiestnaam toe voor de tracktitel ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_INCLUDE_EP = "Voeg singles en EP's toe bij het downloaden van de albums van een artiest('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "ID toevoegen voor albummap ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_SAVE_COVERS = "Covers opslaan('0'-Nee,'1'-Ja):"
|
||||
CHANGE_LANGUAGE = "Selecteer taal"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Albummapindeling ('0'-niet wijzigen,'default'-om standaard in te stellen):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Afspeellijstmapindeling format('0'-niet wijzigen,'default'-om standaard in te stellen):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Bestandsformaat bijhouden ('0'-niet wijzigen,'default'-om standaard in te stellen):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Videobestandsindeling('0'-niet wijzigen,'default'-om standaard in te stellen):"
|
||||
CHANGE_SHOW_PROGRESS = "Voortgang weergeven('0'-Nee,'1'-Ja):"
|
||||
CHANGE_SHOW_TRACKINFO = "Toon trackinfo('0'-Nee,'1'-Ja):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Bewaar AlbumInfo.txt('0'-Nee,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Songtekst toevoegen('0'-Nee,'1'-Ja):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Songtekst proxyserver('0'-niet wijzigen):"
|
||||
CHANGE_ADD_LRC_FILE = "Sla getimede songtekst .lrc-bestand op ('0'-Nee,'1'-Ja):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Type-map toevoegen, bijv. Album/Video/Playlist('0'-Nee,'1'-Ja):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Inlogproces starten..."
|
||||
AUTH_LOGIN_CODE = "Uw inlogcode is {}"
|
||||
AUTH_NEXT_STEP = "Ga naar {} in de volgende {} om de installatie te voltooien."
|
||||
AUTH_WAITING = "Wachten op toestemming..."
|
||||
AUTH_TIMEOUT = "Operatie time-out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "Toegangstoken goed voor {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Verlopen AccessToken. Poging om het te vernieuwen."
|
||||
MSG_PATH_ERR = "Pad is incorrect!"
|
||||
MSG_INPUT_ERR = "Invoerfout!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-EIGENSCHAP"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-EIGENSCHAP"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-EIGENSCHAP"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIEST-EIGENSCHAP"
|
||||
MODEL_PLAYLIST_PROPERTY = "AFSPEELLIJST-EIGENSCHAP"
|
||||
|
||||
MODEL_TITLE = 'Titel'
|
||||
MODEL_TRACK_NUMBER = 'Tracknummer'
|
||||
MODEL_VIDEO_NUMBER = 'Videonummer'
|
||||
MODEL_RELEASE_DATE = 'Publicatiedatum'
|
||||
MODEL_VERSION = 'Versie'
|
||||
MODEL_EXPLICIT = 'Expliciet'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Naam'
|
||||
MODEL_TYPE = 'Type'
|
||||
@@ -2,13 +2,14 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : english.py
|
||||
@Time : 2020/08/19
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Time : 2021/11/24
|
||||
@Author : Yaronzz & jee019
|
||||
@Version : 1.2
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangEnglish(object):
|
||||
SETTING = "SETTINGS"
|
||||
VALUE = "VALUE"
|
||||
@@ -23,14 +24,26 @@ class LangEnglish(object):
|
||||
SETTING_CHECK_EXIST = "Check exist"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "ArtistName before track-title"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id before album-folder"
|
||||
SETTING_INCLUDE_EP = "Include single&ep"
|
||||
SETTING_INCLUDE_EP = "Include singles & EPs"
|
||||
SETTING_SAVE_COVERS = "Save covers"
|
||||
SETTING_LANGUAGE = "Language"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "CHOICE"
|
||||
FUNCTION = "FUNCTION"
|
||||
@@ -39,8 +52,10 @@ class LangEnglish(object):
|
||||
CHOICE_EXIT = "Exit"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Settings"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Set AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Download by url or id"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Set AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Download by url or ID"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
@@ -48,37 +63,48 @@ class LangEnglish(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Enter Choice:"
|
||||
PRINT_LATEST_VERSION = "Latest version:"
|
||||
#PRINT_USERNAME = "username:"
|
||||
#PRINT_PASSWORD = "password:"
|
||||
|
||||
# PRINT_USERNAME = "username:"
|
||||
# PRINT_PASSWORD = "password:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Start settings('0'-Return,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_PATH = "Download path('0' not modify):"
|
||||
CHANGE_AUDIO_QUALITY = "Audio quailty('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Video quailty('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_DOWNLOAD_PATH = "Download path('0'-not modify):"
|
||||
CHANGE_AUDIO_QUALITY = "Audio quality('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Video quality(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Convert mp4 to m4a('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Add explicit tag to file names('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_HYPHEN = "Use hyphens instead of spaces in file names('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_YEAR = "Add year to album folder names('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_TRACK_NUM = "Add track number before file names('0'-No,'1'-Yes):"
|
||||
CHANGE_CHECK_EXIST = "Check exist file befor download track('0'-No,'1'-Yes):"
|
||||
CHANGE_CHECK_EXIST = "Check exist file before download track('0'-No,'1'-Yes):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Add artistName before track title('0'-No,'1'-Yes):"
|
||||
CHANGE_INCLUDE_EP = "Include singles and EPs when downloading an artist's albums('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Add id before album folder('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_COVERS = "Save covers('0'-No,'1'-Yes):"
|
||||
CHANGE_LANGUAGE = "Select language"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Path is error!"
|
||||
MSG_INPUT_ERR = "Input error!"
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangFilipino(object):
|
||||
SETTING = "SETTINGS"
|
||||
VALUE = "VALUE"
|
||||
@@ -29,8 +30,20 @@ class LangFilipino(object):
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "PAGPIPILIAN"
|
||||
FUNCTION = "SILBI"
|
||||
@@ -39,8 +52,10 @@ class LangFilipino(object):
|
||||
CHOICE_EXIT = "Mag Exit"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Settings"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "I-set ang AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "I-set ang AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Mag download gamit ang url o id"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
@@ -48,13 +63,13 @@ class LangFilipino(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Pumili ng sagot:"
|
||||
PRINT_LATEST_VERSION = "Pinakabagong Version:"
|
||||
#PRINT_USERNAME = "username:"
|
||||
#PRINT_PASSWORD = "password:"
|
||||
|
||||
# PRINT_USERNAME = "username:"
|
||||
# PRINT_PASSWORD = "password:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Simulan ang settings('0'-Bumalik,'1'-Oo):"
|
||||
CHANGE_DOWNLOAD_PATH = "Paroroonan ng Download('0' walang babaguhin):"
|
||||
CHANGE_AUDIO_QUALITY = "Kalidad ng Audio('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Kalidad ng Audio Video('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "Kalidad ng Audio('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Kalidad ng Audio Video(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "I-convert ang mp4 bilang m4a('0'-Hindi,'1'-Oo):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Lagyan ng explicit tag sa pangalan ng files('0'-Hindi,'1'-Oo):"
|
||||
CHANGE_ADD_HYPHEN = "Gamitin ang hyphens kesa sa spaces sa pangalan ng files('0'-Hindi,'1'-Oo):"
|
||||
@@ -66,9 +81,20 @@ class LangFilipino(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Lagyan ng id bago ang album folder('0'-Hindi,'1'-Oo):"
|
||||
CHANGE_SAVE_COVERS = "I-save ang mga covers('0'-Hindi,'1'-Oo):"
|
||||
CHANGE_LANGUAGE = "Pumili ng lenggwahe"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify,'default'-to set default):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify,'default'-to set default):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
@@ -76,9 +102,9 @@ class LangFilipino(object):
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "May error sa paroroonan ng download!"
|
||||
MSG_INPUT_ERR = "May error sa pag-input!"
|
||||
|
||||
|
||||
+126
-100
@@ -1,100 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : french.py
|
||||
@Time : 2020/10/25
|
||||
@Authors : flamme-demon & joyel24
|
||||
@Version : 0.3
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
class LangFrench(object):
|
||||
SETTING = "RÉGLAGES"
|
||||
VALUE = "VALEUR"
|
||||
SETTING_DOWNLOAD_PATH = "Emplacement des téléchargements"
|
||||
SETTING_ONLY_M4A = "Convertir mp4 en m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Ajout du tag Explicit - Dossier"
|
||||
SETTING_ADD_HYPHEN = "Ajouter un trait d'union"
|
||||
SETTING_ADD_YEAR = "Ajouter l'année avant le nom de l'album - Dossier"
|
||||
SETTING_USE_TRACK_NUM = "Ajouter le numéro de piste de l'album"
|
||||
SETTING_AUDIO_QUALITY = "Qualité Audio"
|
||||
SETTING_VIDEO_QUALITY = "Qualité Video"
|
||||
SETTING_CHECK_EXIST = "Vérifier l'existence"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Nom de l'artiste avant le titre du morceau - Fichier"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id avant le nom d'album - Dossier"
|
||||
SETTING_INCLUDE_EP = "Inclure les singles & EPs"
|
||||
SETTING_SAVE_COVERS = "Sauvegarder les couvertures"
|
||||
SETTING_LANGUAGE = "Langue"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Utiliser dossier de playlist"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Téléchargement multithread"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Format du dossier d'album"
|
||||
SETTING_TRACK_FILE_FORMAT = "Format du fichier de tracklist"
|
||||
SETTING_SHOW_PROGRESS = "Afficher la Progression"
|
||||
|
||||
CHOICE = "CHOIX"
|
||||
FUNCTION = "FONCTION"
|
||||
CHOICE_ENTER = "Saisir"
|
||||
CHOICE_ENTER_URLID = "Saisir 'Url/ID':"
|
||||
CHOICE_EXIT = "Quitter"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Réglages"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Définir le jeton d'accès"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Téléchargement par url ou id"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Saisir le choix:"
|
||||
PRINT_LATEST_VERSION = "Dernière version:"
|
||||
#PRINT_USERNAME = "Utilisateur:"
|
||||
#PRINT_PASSWORD = "Mot de passe:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Commencer les réglages ('0'-Retour,'1'-Oui):"
|
||||
CHANGE_DOWNLOAD_PATH = "Emplacement des téléchargements('0' ne pas modifier):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualité audio('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualité Video('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "Convertir mp4 en m4a('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Ajout du tag Explicit - Fichier('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_HYPHEN = "Utilisez des traits d'union au lieu d'espaces dans les noms de fichiers('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_YEAR = "Ajouter l'année aux noms des dossiers des albums('0'-Non,'1'-Oui):"
|
||||
CHANGE_USE_TRACK_NUM = "Ajouter le numéro de piste avant le nom des fichiers('0'-Non,'1'-Oui):"
|
||||
CHANGE_CHECK_EXIST = "Vérifier l'existence du fichier avant le téléchargement('0'-Non,'1'-Oui):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Ajouter le nom de l'artiste avant le titre de la piste('0'-Non,'1'-Oui):"
|
||||
CHANGE_INCLUDE_EP = "Inclure les singles et les EPs lors du téléchargement des albums d'un artiste('0'-Non,'1'-Oui):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Ajouter un identifiant avant le dossier album('0'-Non,'1'-Oui):"
|
||||
CHANGE_SAVE_COVERS = "Sauvegarder les couvertures('0'-Non,'1'-Oui):"
|
||||
CHANGE_LANGUAGE = "Sélectionnez une langue"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Format du dossier d'album('0' ne pas modifier):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Format du fichier de tracklist('0' ne pas modifier):"
|
||||
CHANGE_SHOW_PROGRESS = "Afficher la progression('0'-Non,'1'-Oui):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Erreur du chemin d'accès"
|
||||
MSG_INPUT_ERR = "Erreur de saisie !"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "PROPRIETES-ALBUM"
|
||||
MODEL_TRACK_PROPERTY = "PROPRIETES-PISTES-AUDIO"
|
||||
MODEL_VIDEO_PROPERTY = "PROPRIETES-VIDEO"
|
||||
MODEL_ARTIST_PROPERTY = "PROPRIETES-ARTISTE"
|
||||
MODEL_PLAYLIST_PROPERTY = "PROPERTES-PLAYLIST"
|
||||
|
||||
MODEL_TITLE = 'Titre'
|
||||
MODEL_TRACK_NUMBER = 'Numéro de piste'
|
||||
MODEL_VIDEO_NUMBER = 'Numéro de la vidéo'
|
||||
MODEL_RELEASE_DATE = 'Date de publication'
|
||||
MODEL_VERSION = 'Version'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Nom'
|
||||
MODEL_TYPE = 'Type'
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : french.py
|
||||
@Time : 2020/10/25
|
||||
@Authors : flamme-demon & joyel24
|
||||
@Version : 0.3
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangFrench(object):
|
||||
SETTING = "RÉGLAGES"
|
||||
VALUE = "VALEUR"
|
||||
SETTING_DOWNLOAD_PATH = "Emplacement des téléchargements"
|
||||
SETTING_ONLY_M4A = "Convertir mp4 en m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Ajout du tag Explicit - Dossier"
|
||||
SETTING_ADD_HYPHEN = "Ajouter un trait d'union"
|
||||
SETTING_ADD_YEAR = "Ajouter l'année avant le nom de l'album - Dossier"
|
||||
SETTING_USE_TRACK_NUM = "Ajouter le numéro de piste de l'album"
|
||||
SETTING_AUDIO_QUALITY = "Qualité Audio"
|
||||
SETTING_VIDEO_QUALITY = "Qualité Video"
|
||||
SETTING_CHECK_EXIST = "Vérifier l'existence"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Nom de l'artiste avant le titre du morceau - Fichier"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id avant le nom d'album - Dossier"
|
||||
SETTING_INCLUDE_EP = "Inclure les singles & EPs"
|
||||
SETTING_SAVE_COVERS = "Sauvegarder les couvertures"
|
||||
SETTING_LANGUAGE = "Langue"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Utiliser dossier de playlist"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Téléchargement multithread"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Format du dossier d'album"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Format du fichier de tracklist"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Afficher la Progression"
|
||||
SETTING_SHOW_TRACKINFO = "Afficher les information de la musique"
|
||||
SETTING_SAVE_ALBUMINFO = "Enregistrer AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Inclure les paroles"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Proxy du serveur de paroles"
|
||||
SETTING_ADD_LRC_FILE = "Enregistrer les paroles synchronisées (fichier .lrc)"
|
||||
SETTING_PATH = "Emplacement des paramètres"
|
||||
SETTING_APIKEY = "Prise en charge de la clé API"
|
||||
SETTING_ADD_TYPE_FOLDER = "Ajouter un dossier de type"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "CHOIX"
|
||||
FUNCTION = "FONCTION"
|
||||
CHOICE_ENTER = "Saisir"
|
||||
CHOICE_ENTER_URLID = "Saisir 'Url/ID':"
|
||||
CHOICE_EXIT = "Quitter"
|
||||
CHOICE_LOGIN = "Vérifier le token d'accès"
|
||||
CHOICE_SETTINGS = "Réglages"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Définir le jeton d'accès"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Téléchargement par url ou id"
|
||||
CHOICE_LOGOUT = "Déconnexion"
|
||||
CHOICE_APIKEY = "Choisir la clé d'API"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Saisir le choix:"
|
||||
PRINT_LATEST_VERSION = "Dernière version:"
|
||||
# PRINT_USERNAME = "Utilisateur:"
|
||||
# PRINT_PASSWORD = "Mot de passe:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Commencer les réglages ('0'-Retour,'1'-Oui):"
|
||||
CHANGE_DOWNLOAD_PATH = "Emplacement des téléchargements('0' ne pas modifier):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualité audio('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualité Video(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Convertir mp4 en m4a('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Ajout du tag Explicit - Fichier('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_HYPHEN = "Utilisez des traits d'union au lieu d'espaces dans les noms de fichiers('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_YEAR = "Ajouter l'année aux noms des dossiers des albums('0'-Non,'1'-Oui):"
|
||||
CHANGE_USE_TRACK_NUM = "Ajouter le numéro de piste avant le nom des fichiers('0'-Non,'1'-Oui):"
|
||||
CHANGE_CHECK_EXIST = "Vérifier l'existence du fichier avant le téléchargement('0'-Non,'1'-Oui):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Ajouter le nom de l'artiste avant le titre de la piste('0'-Non,'1'-Oui):"
|
||||
CHANGE_INCLUDE_EP = "Inclure les singles et les EPs lors du téléchargement des albums d'un artiste('0'-Non,'1'-Oui):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Ajouter un identifiant avant le dossier album('0'-Non,'1'-Oui):"
|
||||
CHANGE_SAVE_COVERS = "Sauvegarder les couvertures('0'-Non,'1'-Oui):"
|
||||
CHANGE_LANGUAGE = "Sélectionnez une langue"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Format du dossier d'album('0' ne pas modifier):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Format du fichier de tracklist('0' ne pas modifier):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Afficher la progression('0'-Non,'1'-Oui):"
|
||||
CHANGE_SHOW_TRACKINFO = "Afficher les information de la piste ('0'-Non,'1'-Oui):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Enregistrer AlbumInfo.txt('0'-Non,'1'-Oui):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Ajouter les paroles ('0'-Non,'1'-Oui):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Proxy du serveur de paroles('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Enregistrer les paroles synchronisées (fichier.lrc) ('0'-Non,'1'-Oui):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Ajouter un dossier de type,Ex: Album/Video/Playlist('0'-Non,'1'-Oui):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-Non,'1'-Oui):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Démarrage du processus de connexion..."
|
||||
AUTH_LOGIN_CODE = "Votre code de connection est le suivant: {}"
|
||||
AUTH_NEXT_STEP = "Allez à {} avant {} pour finir la configuration."
|
||||
AUTH_WAITING = "En attente d'autorisation..."
|
||||
AUTH_TIMEOUT = "Temps écoulé."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "Token d'accès valable {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Token d'accès expiré. Tentative de renouvellement automatique."
|
||||
MSG_PATH_ERR = "Erreur du chemin d'accès"
|
||||
MSG_INPUT_ERR = "Erreur de saisie !"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "PROPRIETES-ALBUM"
|
||||
MODEL_TRACK_PROPERTY = "PROPRIETES-PISTES-AUDIO"
|
||||
MODEL_VIDEO_PROPERTY = "PROPRIETES-VIDEO"
|
||||
MODEL_ARTIST_PROPERTY = "PROPRIETES-ARTISTE"
|
||||
MODEL_PLAYLIST_PROPERTY = "PROPERTES-PLAYLIST"
|
||||
|
||||
MODEL_TITLE = 'Titre'
|
||||
MODEL_TRACK_NUMBER = 'Numéro de piste'
|
||||
MODEL_VIDEO_NUMBER = 'Numéro de la vidéo'
|
||||
MODEL_RELEASE_DATE = 'Date de publication'
|
||||
MODEL_VERSION = 'Version'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Nom'
|
||||
MODEL_TYPE = 'Type'
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : german.py
|
||||
@Time : 2020/10/01
|
||||
@Author : Sematre
|
||||
@Version : 1.0
|
||||
@Time : 2022/11/8
|
||||
@Authors : Sematre, MineClashTV, Click1701
|
||||
@Version : 1.1
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangGerman(object):
|
||||
SETTING = "EINSTELLUNG"
|
||||
VALUE = "WERT"
|
||||
@@ -22,71 +23,96 @@ class LangGerman(object):
|
||||
SETTING_VIDEO_QUALITY = "Videoqualität"
|
||||
SETTING_CHECK_EXIST = "Existenz überprüfen"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Künstlername vor Songtitel"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id vor Album-Ordner"
|
||||
SETTING_INCLUDE_EP = "Einschließlich single&ep"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID vor Album-Ordner"
|
||||
SETTING_INCLUDE_EP = "Singles & EPs einschließen"
|
||||
SETTING_SAVE_COVERS = "Cover speichern"
|
||||
SETTING_LANGUAGE = "Sprache"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Playlist-Ordner verwenden"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi-Thread-Download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi-Thread Download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album-Ordnerformat"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist-Ordnerformat"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track-Dateiformat"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video-Dateiformat"
|
||||
SETTING_SHOW_PROGRESS = "Fortschritt anzeigen"
|
||||
SETTING_SHOW_TRACKINFO = "Titelinformationen anzeigen"
|
||||
SETTING_SAVE_ALBUMINFO = "AlbumInfo.txt speichern"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Songtexte hinzufügen"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Songtext Proxy-Server"
|
||||
SETTING_ADD_LRC_FILE = "Songtext mit Zeitcode speichern (.lrc Datei)"
|
||||
SETTING_PATH = "Speicherort der Einstellungen"
|
||||
SETTING_APIKEY = "APIKey Unterstützung"
|
||||
SETTING_ADD_TYPE_FOLDER = "Unterordner für jede Kategorie erstellen"
|
||||
SETTING_DOWNLOAD_DELAY = "Downloads zeitverzögert starten"
|
||||
|
||||
CHOICE = "AUSWAHL"
|
||||
FUNCTION = "FUNKTION"
|
||||
CHOICE_ENTER = "Mit"
|
||||
CHOICE_ENTER_URLID = "'Url/ID' eingeben:"
|
||||
CHOICE_EXIT = "Beenden"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "AccessToken überprüfen"
|
||||
CHOICE_SETTINGS = "Einstellungen"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "AccessToken setzen"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Herunterladen per URL oder ID"
|
||||
CHOICE_SET_ACCESS_TOKEN = "AccessToken setzen"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Download per URL oder ID"
|
||||
CHOICE_LOGOUT = "Ausloggen"
|
||||
CHOICE_APIKEY = "APIKey Auswahl"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_ERR = "[FEHLER]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCESS]"
|
||||
PRINT_SUCCESS = "[ERFOLG]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Auswahl:"
|
||||
PRINT_LATEST_VERSION = "Neueste Version:"
|
||||
#PRINT_USERNAME = "Benutzername:"
|
||||
#PRINT_PASSWORD = "Passwort:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Einstellungen starten ('0'-Zurück,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_PATH = "Download Pfad ('0' nicht ändern):"
|
||||
CHANGE_AUDIO_QUALITY = "Tonqualität ('0'-Normal,'1'-Hoch,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Videoqualität ('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "mp4 in m4a konvertieren ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Explicit Tag zum Dateiname hinzufügen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_ADD_HYPHEN = "Verwende Bindestriche statt Leerzeichen im Dateiname ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_ADD_YEAR = "Jahr zu Album-Ordnernamen hinzufügen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_USE_TRACK_NUM = "Titelnummer vor Dateinamen hinzufügen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_CHECK_EXIST = "Vor dem Download überprüfen, ob die Datei existiert ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Künstlername vor den Songtitel hinzufügen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_INCLUDE_EP = "Singles und EPs beim Download von Alben eines Künstlers einbeziehen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "ID vor Album-Ordner hinzufügen ('0'-Nein,'1'-Ja):"
|
||||
CHANGE_SAVE_COVERS = "Cover speichern ('0'-Nein,'1'-Ja):"
|
||||
# PRINT_USERNAME = "Benutzername:"
|
||||
# PRINT_PASSWORD = "Passwort:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Einstellungen starten ('0'-Zurück, '1'-Ja):"
|
||||
CHANGE_DOWNLOAD_PATH = "Downloadpfad ('0' nicht ändern):"
|
||||
CHANGE_AUDIO_QUALITY = "Tonqualität ('0'-Normal, '1'-Hoch, '2'-HiFi, '3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Videoqualität (1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "mp4 in m4a konvertieren ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Explicit Tag zum Dateiname hinzufügen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ADD_HYPHEN = "Im Dateinamen Bindestriche statt Leerzeichen verwenden ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ADD_YEAR = "Jahr zu Album-Ordnernamen hinzufügen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_USE_TRACK_NUM = "Titelnummer vor Dateinamen hinzufügen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_CHECK_EXIST = "Vor dem Download überprüfen, ob die Datei existiert ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Künstlername vor den Songtitel hinzufügen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_INCLUDE_EP = "Singles und EPs beim Download von Alben eines Künstlers einbeziehen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "ID vor Album-Ordner hinzufügen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_SAVE_COVERS = "Cover speichern ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_LANGUAGE = "Sprache auswählen"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album-Ordnerformat ('0' überspringen):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist Ordner-Format ('0'-nicht ändern, 'default'-für Standard):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track-Dateiformat ('0' überspringen):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video-Dateiformat ('0'-nicht ändern, 'default'-für Standard):"
|
||||
CHANGE_SHOW_PROGRESS = "Fortschritt anzeigen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_SHOW_TRACKINFO = "Song-Informationen anzeigen ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "AlbumInfo.txt speichern ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Songtexte hinzufügen ('0'-No, '1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Songtext Proxy-Server ('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Songtexte mit Zeitcode speichern (.lrc Datei) ('0'-Nein, '1'-Ja):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Unterordner für jede Kategorie erstellen, Z.B. Album/Video/Playlist('0'-Nein, '1'-Ja):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi-Thread Download('0'-Nein, '1'-Ja):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Downloads zeitverzögert starten ('0'-nein, '1'-ja):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Path is error!"
|
||||
MSG_INPUT_ERR = "Input error!"
|
||||
AUTH_START_LOGIN = "Starte Loginprozess..."
|
||||
AUTH_LOGIN_CODE = "Dein Logincode ist {}"
|
||||
AUTH_NEXT_STEP = "Gehe auf {} in den nächsten {} um das Setup abzuschließen."
|
||||
AUTH_WAITING = "Warte auf Autorisierung..."
|
||||
AUTH_TIMEOUT = "Zeitüberschreitung der Operation."
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-PROPERTY"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-PROPERTY"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-PROPERTY"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIST-PROPERTY"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-PROPERTY"
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken gültig für {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken abgelaufen. Er muss erneuert werden."
|
||||
MSG_PATH_ERR = "Ungültiger Pfad!"
|
||||
MSG_INPUT_ERR = "Eingabefehler!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-EIGENSCHAFT"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-EIGENSCHAFT"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-EIGENSCHAFT"
|
||||
MODEL_ARTIST_PROPERTY = "KÜNSTLER-EIGENSCHAFT"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-EIGENSCHAFT"
|
||||
|
||||
MODEL_TITLE = 'Titel'
|
||||
MODEL_TRACK_NUMBER = 'Titelnummer'
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : hungarian.py
|
||||
@Time : 2022/08/01
|
||||
@Author : Shanahan
|
||||
@Version : 1.2
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangHungarian(object):
|
||||
SETTING = "BEÁLLÍTÁSOK"
|
||||
VALUE = "ÉRTÉK"
|
||||
SETTING_DOWNLOAD_PATH = "Letöltési útvonal"
|
||||
SETTING_ONLY_M4A = "mp4 konvertálása m4a-ra"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Explicit tag hozzáadása"
|
||||
SETTING_ADD_HYPHEN = "Kötőjel hozzáadása"
|
||||
SETTING_ADD_YEAR = "Év hozzáadása az album-mappa előtt"
|
||||
SETTING_USE_TRACK_NUM = "Add user track number"
|
||||
SETTING_AUDIO_QUALITY = "Audió minősége"
|
||||
SETTING_VIDEO_QUALITY = "Videó minősége"
|
||||
SETTING_CHECK_EXIST = "Ellenőrizze, hogy létezik-e"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Előadó neve a szám címe előtt"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Azonosító (ID) az album-mappa előtt"
|
||||
SETTING_INCLUDE_EP = "Tartalmazza a single&ep"
|
||||
SETTING_SAVE_COVERS = "Borítókép mentése"
|
||||
SETTING_LANGUAGE = "Nyelv"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Lejátszási lista mappa használata"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Többszálú letöltés"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album mappa formátum"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track fájlformátum"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Videó fájlformátum"
|
||||
SETTING_SHOW_PROGRESS = "Haladás megjelenítése"
|
||||
SETTING_SHOW_TRACKINFO = "Track infók megjelenítése"
|
||||
SETTING_SAVE_ALBUMINFO = "AlbumInfo.txt mentése"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Dalszöveg hozzáadása"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Dalszöveg kiszolgáló proxy"
|
||||
SETTING_ADD_LRC_FILE = "Dalszövegek mentése (.lrc fájl)"
|
||||
SETTING_PATH = "Beállítási útvonal"
|
||||
SETTING_APIKEY = "APIKey támogatás"
|
||||
SETTING_ADD_TYPE_FOLDER = "Mappa típus hozzáadása"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "VÁLASZTÁS"
|
||||
FUNCTION = "FUNKCIÓ"
|
||||
CHOICE_ENTER = "Írja be a"
|
||||
CHOICE_ENTER_URLID = "Adja meg az 'Url/ID'-t:"
|
||||
CHOICE_EXIT = "Kilépés"
|
||||
CHOICE_LOGIN = "AccessToken ellenőrzése"
|
||||
CHOICE_SETTINGS = "Beállítások"
|
||||
CHOICE_SET_ACCESS_TOKEN = "AccessToken beállítása"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Letöltés URL vagy ID alapján"
|
||||
CHOICE_LOGOUT = "Kijelentkezés"
|
||||
CHOICE_APIKEY = "APIKey kiválasztása"
|
||||
|
||||
PRINT_ERR = "[HIBA]"
|
||||
PRINT_INFO = "[INFÓ]"
|
||||
PRINT_SUCCESS = "[SIKERES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Válasszon:"
|
||||
PRINT_LATEST_VERSION = "Legújabb verzió:"
|
||||
# PRINT_USERNAME = "felhasználónév:"
|
||||
# PRINT_PASSWORD = "jelszó:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Beállítások indítása('0'- Vissza, '1'-Igen):"
|
||||
CHANGE_DOWNLOAD_PATH = "Letöltési útvonal('0' nincs módosítás):"
|
||||
CHANGE_AUDIO_QUALITY = "Audió minőség('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Videó minőség(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "mp4 átalakítása m4a-ra('0'-Nem,'1'-Igen):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Explicit tag hozzáadása a fájlnevekhez('0'-Nem,'1'-Igen):"
|
||||
CHANGE_ADD_HYPHEN = "Kötőjel használata szóköz helyett a fájlnevekben('0'-Nem,'1'-Igen):"
|
||||
CHANGE_ADD_YEAR = "Évszám hozzáadása az album mappanevekhez('0'-Nem,'1'-Igen):"
|
||||
CHANGE_USE_TRACK_NUM = "Track szám hozzáadása a fájlnevek előtt('0'-Nem,'1'-Igen):"
|
||||
CHANGE_CHECK_EXIST = "Létező fájl ellenőrzése letöltés előtt('0'-Nem,'1'-Igen):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Előadó hozzáadása a szám címe előtt('0'-Nem,'1'-Igen):"
|
||||
CHANGE_INCLUDE_EP = "A kislemezek és EP-k letöltése('0'-Nem, '1'-Igen):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Azonosító (ID) az album mappa előtt('0'-Nem,'1'-Igen):"
|
||||
CHANGE_SAVE_COVERS = "Borító mentése('0'-Nem, '1'-Igen):"
|
||||
CHANGE_LANGUAGE = "Nyelv kiválasztása"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album mappa formátum('0' nincs módosítás,'default' az alapértelmezett beállításhoz):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track fájl neve('0' nincs módosítás,'default' az alapértelmezett beállításhoz):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-nincs módosítás,'default' az alapértelmezett beállításhoz):"
|
||||
CHANGE_SHOW_PROGRESS = "Haladás megjelenítése('0'-Nem, '1'-Igen):"
|
||||
CHANGE_SHOW_TRACKINFO = "Track infók megjelenítése('0'-Nem,'1'-Igen):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "AlbumInfo.txt mentése('0'-Nem, '1'-Igen):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Dalszöveg hozzáadása('0'-Nem,'1'-Igen):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Dalszöveg kiszolgáló proxy('0' nincs módosítás):"
|
||||
CHANGE_ADD_LRC_FILE = "Dalszöveg mentése időbélyeggel .lrc fájl('0'-Nem,'1'-Igen):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Mappa típus hozzáadása, pl. Album/Video/Playlist('0'-Nem,'1'-Igen):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Többszálas letöltés('0'-Nem,'1'-Igen):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Bejelentkezési folyamat elindítása..."
|
||||
AUTH_LOGIN_CODE = "A bejelentkezési kódod {}"
|
||||
AUTH_NEXT_STEP = "Menj a {} a következő {} a beállítás befejezéséhez."
|
||||
AUTH_WAITING = "Engedélyre várva..."
|
||||
AUTH_TIMEOUT = "A művelet leállt."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken érvényessége {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Lejárt AccessToken. Megpróbálom frissíteni."
|
||||
MSG_PATH_ERR = "Az útvonal hibás!"
|
||||
MSG_INPUT_ERR = "Beviteli hiba!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-INFÓ"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-INFÓ"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-INFÓ"
|
||||
MODEL_ARTIST_PROPERTY = "ELŐADÓ-INFÓ"
|
||||
MODEL_PLAYLIST_PROPERTY = "LEJÁTSZÁSI LISTA-INFÓ"
|
||||
|
||||
MODEL_TITLE = 'Cím'
|
||||
MODEL_TRACK_NUMBER = 'Track száma'
|
||||
MODEL_VIDEO_NUMBER = 'Videó száma'
|
||||
MODEL_RELEASE_DATE = 'Megjelenés dátuma'
|
||||
MODEL_VERSION = 'Verzió'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Név'
|
||||
MODEL_TYPE = 'Típus'
|
||||
@@ -9,6 +9,7 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangItalian(object):
|
||||
SETTING = "IMPOSTAZIONI"
|
||||
VALUE = "VALORE"
|
||||
@@ -29,8 +30,20 @@ class LangItalian(object):
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "SCELTA"
|
||||
FUNCTION = "FUNZIONE"
|
||||
@@ -39,8 +52,10 @@ class LangItalian(object):
|
||||
CHOICE_EXIT = "Uscita"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Impostazioni"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Imposta AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Imposta AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Scarica per URL o Id"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
@@ -48,13 +63,13 @@ class LangItalian(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Inserire scelta:"
|
||||
PRINT_LATEST_VERSION = "Ultima versione:"
|
||||
#PRINT_USERNAME = "username:"
|
||||
#PRINT_PASSWORD = "password:"
|
||||
# PRINT_USERNAME = "username:"
|
||||
# PRINT_PASSWORD = "password:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Impostazioni all'avvio ('0'-Ritorna,'1'-Sì):"
|
||||
CHANGE_DOWNLOAD_PATH = "Percorso Download ('0' non modificare):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualità Audio ('0'-Normale, '1'-Alta, '2'-HiFi, '3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualità Video ('0'-1080, '1'-720, '2'-480, '3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualità Audio ('0'-Normale, '1'-Alta, '2'-HiFi, '3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualità Video (1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Convertire mp4 in m4a ('0'-No,'1'-):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Aggiungi tag 'Contenuto Esplicito' ai nomi dei file ('0'-No,'1'-Sì):"
|
||||
CHANGE_ADD_HYPHEN = "Usare trattini al posto degli spazi nei nomi dei file ('0'-No,'1'-Sì):"
|
||||
@@ -66,9 +81,20 @@ class LangItalian(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Aggiungere ID prima del nome della cartella per l'album ('0'-No,'1'-Sì):"
|
||||
CHANGE_SAVE_COVERS = "Salve copertine ('0'-No,'1'-Sì):"
|
||||
CHANGE_LANGUAGE = "Selezionare lingua"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify,'default'-to set default):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify,'default'-to set default):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
@@ -76,9 +102,9 @@ class LangItalian(object):
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "Percorso errato!"
|
||||
MSG_INPUT_ERR = "Inserimento errato!"
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : japanese.py
|
||||
@Time : 2021/11/30
|
||||
@Author : jee019
|
||||
@Version : 1.0
|
||||
@Contact : qwer010910@gmail.com
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangJapanese(object):
|
||||
SETTING = "設定"
|
||||
VALUE = "値"
|
||||
SETTING_DOWNLOAD_PATH = "ダウンロードパス"
|
||||
SETTING_ONLY_M4A = "mp4をm4aに変換する"
|
||||
SETTING_ADD_EXPLICIT_TAG = "explicitタグ付けする"
|
||||
SETTING_ADD_HYPHEN = "ハイフンを追加"
|
||||
SETTING_ADD_YEAR = "Add year before album-folder"
|
||||
SETTING_USE_TRACK_NUM = "ユーザートラック番号を追加"
|
||||
SETTING_AUDIO_QUALITY = "オーディオ品質"
|
||||
SETTING_VIDEO_QUALITY = "ビデオ品質"
|
||||
SETTING_CHECK_EXIST = "Check exist"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "ArtistName before track-title"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id before album-folder"
|
||||
SETTING_INCLUDE_EP = "含む singles & EPs"
|
||||
SETTING_SAVE_COVERS = "カバーを保存"
|
||||
SETTING_LANGUAGE = "言語"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "歌詞を追加"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "設定パス"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "選択"
|
||||
FUNCTION = "関数"
|
||||
CHOICE_ENTER = "エンター"
|
||||
CHOICE_ENTER_URLID = "エンター 'Url/ID':"
|
||||
CHOICE_EXIT = "エグジット"
|
||||
CHOICE_LOGIN = "AccessTokenを確認してください"
|
||||
CHOICE_SETTINGS = "セッティング"
|
||||
CHOICE_SET_ACCESS_TOKEN = "AccessTokenを設定する"
|
||||
CHOICE_DOWNLOAD_BY_URL = "UrlまたはIDでダウンロード"
|
||||
CHOICE_LOGOUT = "ログアウト"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[エラー]"
|
||||
PRINT_INFO = "[情報]"
|
||||
PRINT_SUCCESS = "[サクセス]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "エンター 選択:"
|
||||
PRINT_LATEST_VERSION = "最新バージョン:"
|
||||
# PRINT_USERNAME = "ユーザー名:"
|
||||
# PRINT_PASSWORD = "パスワード:"
|
||||
|
||||
CHANGE_START_SETTINGS = "設定を開始('0'-戻る,'1'-はい):"
|
||||
CHANGE_DOWNLOAD_PATH = "ダウンロードパス('0'-変更しない):"
|
||||
CHANGE_AUDIO_QUALITY = "オーディオ品質('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "ビデオ品質(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "mp4をm4aに変換する('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Add explicit tag to file names('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ADD_HYPHEN = "Use hyphens instead of spaces in file names('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ADD_YEAR = "Add year to album folder names('0'-いいえ,'1'-はい):"
|
||||
CHANGE_USE_TRACK_NUM = "Add track number before file names('0'-いいえ,'1'-はい):"
|
||||
CHANGE_CHECK_EXIST = "Check exist file before download track('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Add artistName before track title('0'-いいえ,'1'-はい):"
|
||||
CHANGE_INCLUDE_EP = "Include singles and EPs when downloading an artist's albums('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Add id before album folder('0'-いいえ,'1'-はい):"
|
||||
CHANGE_SAVE_COVERS = "カバーを保存('0'-いいえ,'1'-はい):"
|
||||
CHANGE_LANGUAGE = "言語を選択する"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0'-変更しない,'default'-デフォルトを設定するには):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0'-変更しない,'default'-デフォルトを設定するには):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-いいえ,'1'-はい):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-いいえ,'1'-はい):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-いいえ,'1'-はい):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "歌詞を追加('0'-いいえ,'1'-はい):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-変更しない):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-いいえ,'1'-はい):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "パスはエラーです!"
|
||||
MSG_INPUT_ERR = "入力エラー!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "アルバム-情報"
|
||||
MODEL_TRACK_PROPERTY = "トラック-情報"
|
||||
MODEL_VIDEO_PROPERTY = "ビデオ-情報"
|
||||
MODEL_ARTIST_PROPERTY = "アーティスト-情報"
|
||||
MODEL_PLAYLIST_PROPERTY = "プレイリスト-情報"
|
||||
|
||||
MODEL_TITLE = '題名'
|
||||
MODEL_TRACK_NUMBER = 'トラック番号'
|
||||
MODEL_VIDEO_NUMBER = 'ビデオ番号'
|
||||
MODEL_RELEASE_DATE = '発売日'
|
||||
MODEL_VERSION = 'バージョン'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = 'アルバム'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = '名前'
|
||||
MODEL_TYPE = 'タイプ'
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : korean.py
|
||||
@Time : 2021/11/24
|
||||
@Author : jee019
|
||||
@Version : 1.1
|
||||
@Contact : qwer010910@gmail.com
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangKorean(object):
|
||||
SETTING = "설정"
|
||||
VALUE = "값"
|
||||
SETTING_DOWNLOAD_PATH = "다운로드 경로"
|
||||
SETTING_ONLY_M4A = "mp4를 m4a로 변환"
|
||||
SETTING_ADD_EXPLICIT_TAG = "explicit 태그 추가"
|
||||
SETTING_ADD_HYPHEN = "하이픈 추가"
|
||||
SETTING_ADD_YEAR = "앨범 폴더 앞에 연도 추가"
|
||||
SETTING_USE_TRACK_NUM = "사용자 트랙 번호 추가"
|
||||
SETTING_AUDIO_QUALITY = "음질"
|
||||
SETTING_VIDEO_QUALITY = "영상 화질"
|
||||
SETTING_CHECK_EXIST = "존재 유무 확인"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "트랙 제목 앞 아티스트 이름"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "앨범 폴더 앞 ID"
|
||||
SETTING_INCLUDE_EP = "싱글 및 EP 포함"
|
||||
SETTING_SAVE_COVERS = "커버 저장"
|
||||
SETTING_LANGUAGE = "언어"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "재생목록 폴더 사용"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "다중 스레드 다운로드"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "앨범 폴더 형식"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "트랙 파일 형식"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "진행 상태 표시"
|
||||
SETTING_SHOW_TRACKINFO = "트랙 정보 표시"
|
||||
SETTING_SAVE_ALBUMINFO = "AlbumInfo.txt 저장"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "가사 추가"
|
||||
SETTING_LYRICS_SERVER_PROXY = "가사 서버 프록시"
|
||||
SETTING_ADD_LRC_FILE = "timed 가사 저장 (.lrc 파일)"
|
||||
SETTING_PATH = "설정 경로"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "선택"
|
||||
FUNCTION = "기능"
|
||||
CHOICE_ENTER = "엔터"
|
||||
CHOICE_ENTER_URLID = "'Url/ID' 입력:"
|
||||
CHOICE_EXIT = "종료"
|
||||
CHOICE_LOGIN = "액세스 토큰 확인"
|
||||
CHOICE_SETTINGS = "설정"
|
||||
CHOICE_SET_ACCESS_TOKEN = "액세스 토큰 설정"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Url 또는 id로 다운로드"
|
||||
CHOICE_LOGOUT = "로그아웃"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[에러]"
|
||||
PRINT_INFO = "[정보]"
|
||||
PRINT_SUCCESS = "[성공]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "선택 입력:"
|
||||
PRINT_LATEST_VERSION = "최신 버전:"
|
||||
# PRINT_USERNAME = "유저 이름:"
|
||||
# PRINT_PASSWORD = "비밀번호:"
|
||||
|
||||
CHANGE_START_SETTINGS = "설정 시작('0'-뒤로가기,'1'-예):"
|
||||
CHANGE_DOWNLOAD_PATH = "다운로드 경로('0'-변경 안 함):"
|
||||
CHANGE_AUDIO_QUALITY = "음질('0'-보통,'1'-높음,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "영상 화질(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "mp4를 m4a로 변환('0'-아니요,'1'-예):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "파일 이름에 explicit 태그 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_ADD_HYPHEN = "파일 이름에 공백 대신 하이픈 사용('0'-아니요,'1'-예):"
|
||||
CHANGE_ADD_YEAR = "앨범 폴더 이름에 연도 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_USE_TRACK_NUM = "파일 이름 앞에 트랙 번호 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_CHECK_EXIST = "다운로드 트랙 전에 존재하는 파일 확인('0'-아니요,'1'-예):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "트랙 제목 앞에 아티스트 이름 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_INCLUDE_EP = "아티스트 앨범 다운로드시 싱글 및 EP 포함('0'-아니요,'1'-예):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "앨범 폴더 앞에 ID 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_SAVE_COVERS = "커버 저장('0'-아니요,'1'-예):"
|
||||
CHANGE_LANGUAGE = "언어 선택"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "앨범 폴더 형식('0'-변경 안 함,'default'-기본 설정):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "트랙 파일 형식('0'-변경 안 함,'default'-기본 설정):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "진행 상태 표시('0'-아니요,'1'-예):"
|
||||
CHANGE_SHOW_TRACKINFO = "트랙 정보 표시('0'-아니요,'1'-예):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "AlbumInfo.txt 저장('0'-아니요,'1'-예):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "가사 추가('0'-아니요,'1'-예):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "가사 서버 프록시('0'-변경 안 함):"
|
||||
CHANGE_ADD_LRC_FILE = "timed 가사 .lrc 파일 저장 ('0'-아니요,'1'-예):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "로그인 중..."
|
||||
AUTH_LOGIN_CODE = "로그인 코드는 다음과 같습니다. {}"
|
||||
AUTH_NEXT_STEP = "설치를 완료하려면 {}로 이동하십시오. 다음 {} 내에 있습니다."
|
||||
AUTH_WAITING = "승인 대기 중..."
|
||||
AUTH_TIMEOUT = "작업 시간 초과"
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "{}에 대해 액세스 토큰이 유효합니다."
|
||||
MSG_INVALID_ACCESSTOKEN = "만료된 액세스 토큰입니다. 새로 고침 중입니다."
|
||||
MSG_PATH_ERR = "경로 오류!"
|
||||
MSG_INPUT_ERR = "입력 오류!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "앨범-정보"
|
||||
MODEL_TRACK_PROPERTY = "트랙-정보"
|
||||
MODEL_VIDEO_PROPERTY = "영상-정보"
|
||||
MODEL_ARTIST_PROPERTY = "아티스트-정보"
|
||||
MODEL_PLAYLIST_PROPERTY = "재생목록-정보"
|
||||
|
||||
MODEL_TITLE = '제목'
|
||||
MODEL_TRACK_NUMBER = '트랙 넘버'
|
||||
MODEL_VIDEO_NUMBER = '영상 넘버'
|
||||
MODEL_RELEASE_DATE = '발매일'
|
||||
MODEL_VERSION = '버전'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = '앨범'
|
||||
MODEL_ID = '아이디'
|
||||
MODEL_NAME = '이름'
|
||||
MODEL_TYPE = '형식'
|
||||
@@ -6,100 +6,90 @@
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
from tidal_dl.lang.english import LangEnglish
|
||||
from tidal_dl.lang.chinese import LangChinese
|
||||
from tidal_dl.lang.turkish import LangTurkish
|
||||
from tidal_dl.lang.italian import LangItalian
|
||||
from tidal_dl.lang.czech import LangCzech
|
||||
from tidal_dl.lang.arabic import LangArabic
|
||||
from tidal_dl.lang.russian import LangRussian
|
||||
from tidal_dl.lang.filipino import LangFilipino
|
||||
from tidal_dl.lang.croatian import LangCroatian
|
||||
from tidal_dl.lang.spanish import LangSpanish
|
||||
from tidal_dl.lang.portuguese import LangPortuguese
|
||||
from tidal_dl.lang.ukrainian import LangUkrainian
|
||||
from tidal_dl.lang.vietnamese import LangVietnamese
|
||||
from tidal_dl.lang.french import LangFrench
|
||||
from tidal_dl.lang.german import LangGerman
|
||||
from lang.arabic import LangArabic
|
||||
from lang.chinese import LangChinese
|
||||
from lang.croatian import LangCroatian
|
||||
from lang.czech import LangCzech
|
||||
from lang.danish import LangDanish
|
||||
from lang.dutch import LangDutch
|
||||
from lang.english import LangEnglish
|
||||
from lang.filipino import LangFilipino
|
||||
from lang.french import LangFrench
|
||||
from lang.german import LangGerman
|
||||
from lang.hungarian import LangHungarian
|
||||
from lang.italian import LangItalian
|
||||
from lang.norwegian import LangNorwegian
|
||||
from lang.polish import LangPolish
|
||||
from lang.portuguese import LangPortuguese
|
||||
from lang.russian import LangRussian
|
||||
from lang.spanish import LangSpanish
|
||||
from lang.turkish import LangTurkish
|
||||
from lang.ukrainian import LangUkrainian
|
||||
from lang.vietnamese import LangVietnamese
|
||||
from lang.korean import LangKorean
|
||||
from lang.japanese import LangJapanese
|
||||
|
||||
LANG = None
|
||||
_ALL_LANGUAGE_ = [
|
||||
['English', LangEnglish()],
|
||||
['中文', LangChinese()],
|
||||
['Turkish', LangTurkish()],
|
||||
['Italian', LangItalian()],
|
||||
['Czech', LangCzech()],
|
||||
['Arabic', LangArabic()],
|
||||
['Russian', LangRussian()],
|
||||
['Filipino', LangFilipino()],
|
||||
['Croatian', LangCroatian()],
|
||||
['Spanish', LangSpanish()],
|
||||
['Portuguese', LangPortuguese()],
|
||||
['Ukrainian', LangUkrainian()],
|
||||
['Vietnamese', LangVietnamese()],
|
||||
['French', LangFrench()],
|
||||
['German', LangGerman()],
|
||||
['Danish', LangDanish()],
|
||||
['Hungarian', LangHungarian()],
|
||||
['Korean', LangKorean()],
|
||||
['Japanese', LangJapanese()],
|
||||
['Dutch', LangDutch()],
|
||||
['Polish', LangPolish()],
|
||||
['Norwegian', LangNorwegian()],
|
||||
]
|
||||
|
||||
def initLang(index): # 初始化
|
||||
global LANG
|
||||
return setLang(index)
|
||||
class Language(object):
|
||||
def __init__(self) -> None:
|
||||
self.select = LangEnglish()
|
||||
|
||||
def setLang(index):
|
||||
global LANG
|
||||
if str(index) == '0':
|
||||
LANG = LangEnglish()
|
||||
elif str(index) == '1':
|
||||
LANG = LangChinese()
|
||||
elif str(index) == '2':
|
||||
LANG = LangTurkish()
|
||||
elif str(index) == '3':
|
||||
LANG = LangItalian()
|
||||
elif str(index) == '4':
|
||||
LANG = LangCzech()
|
||||
elif str(index) == '5':
|
||||
LANG = LangArabic()
|
||||
elif str(index) == '6':
|
||||
LANG = LangRussian()
|
||||
elif str(index) == '7':
|
||||
LANG = LangFilipino()
|
||||
elif str(index) == '8':
|
||||
LANG = LangCroatian()
|
||||
elif str(index) == '9':
|
||||
LANG = LangSpanish()
|
||||
elif str(index) == '10':
|
||||
LANG = LangPortuguese()
|
||||
elif str(index) == '11':
|
||||
LANG = LangUkrainian()
|
||||
elif str(index) == '12':
|
||||
LANG = LangVietnamese()
|
||||
elif str(index) == '13':
|
||||
LANG = LangFrench()
|
||||
elif str(index) == '14':
|
||||
LANG = LangGerman()
|
||||
else:
|
||||
LANG = LangEnglish()
|
||||
return LANG
|
||||
def __toInt__(self, str):
|
||||
try:
|
||||
return int(str)
|
||||
except:
|
||||
return 0
|
||||
|
||||
def getLang():
|
||||
global LANG
|
||||
return LANG
|
||||
def setLang(self, index):
|
||||
index = self.__toInt__(index)
|
||||
if index >= 0 and index < len(_ALL_LANGUAGE_):
|
||||
self.select = _ALL_LANGUAGE_[index][1]
|
||||
else:
|
||||
self.select = LangEnglish()
|
||||
|
||||
def getLangName(index):
|
||||
if str(index) == '0':
|
||||
return "English"
|
||||
if str(index) == '1':
|
||||
return "中文"
|
||||
if str(index) == '2':
|
||||
return "Turkish"
|
||||
if str(index) == '3':
|
||||
return "Italian"
|
||||
if str(index) == '4':
|
||||
return "Czech"
|
||||
if str(index) == '5':
|
||||
return "Arabic"
|
||||
if str(index) == '6':
|
||||
return "Russian"
|
||||
if str(index) == '7':
|
||||
return "Filipino"
|
||||
if str(index) == '8':
|
||||
return "Croatian"
|
||||
if str(index) == '9':
|
||||
return "Spanish"
|
||||
if str(index) == '10':
|
||||
return "Portuguese"
|
||||
if str(index) == '11':
|
||||
return "Ukrainian"
|
||||
if str(index) == '12':
|
||||
return "Vietnamese"
|
||||
if str(index) == '13':
|
||||
return "French"
|
||||
if str(index) == '14':
|
||||
return "German"
|
||||
return "English"
|
||||
def getLangName(self, index):
|
||||
index = self.__toInt__(index)
|
||||
if index >= 0 and index < len(_ALL_LANGUAGE_):
|
||||
return _ALL_LANGUAGE_[index][0]
|
||||
return ""
|
||||
|
||||
def getLangChoicePrint(self):
|
||||
array = []
|
||||
index = 0
|
||||
while True:
|
||||
name = self.getLangName(index)
|
||||
if name == "":
|
||||
break
|
||||
array.append('\'' + str(index) + '\'-' + name)
|
||||
index += 1
|
||||
return ','.join(array)
|
||||
|
||||
|
||||
LANG = Language()
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : norwegian.py
|
||||
@Time : 2021/03/25
|
||||
@Author : roberts91
|
||||
@Version : 1.0
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangNorwegian(object):
|
||||
SETTING = "INNSTILLINGER"
|
||||
VALUE = "Verdi"
|
||||
SETTING_DOWNLOAD_PATH = "Nedlastingssti"
|
||||
SETTING_ONLY_M4A = "Konverter MP4 til M4A"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Legg til eksplisitt tag"
|
||||
SETTING_ADD_HYPHEN = "Legg til bindestrek"
|
||||
SETTING_ADD_YEAR = "Legg til år før albummappenavn"
|
||||
SETTING_USE_TRACK_NUM = "Legg til spornummer"
|
||||
SETTING_AUDIO_QUALITY = "Lydkvalitet"
|
||||
SETTING_VIDEO_QUALITY = "Videokvalitet"
|
||||
SETTING_CHECK_EXIST = "Kontroller eksistens"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Artistnavn før spornummer"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id før album mappe"
|
||||
SETTING_INCLUDE_EP = "Inkluder single&EP"
|
||||
SETTING_SAVE_COVERS = "Lagre cover"
|
||||
SETTING_LANGUAGE = "Språk"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Bruk spillelistemappe"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Last ned flere samtidig"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Albummappens format"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Spillelistemappens format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Spor filformat"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video filformat"
|
||||
SETTING_SHOW_PROGRESS = "Vis fremgang"
|
||||
SETTING_SHOW_TRACKINFO = "Vis sporinformasjon"
|
||||
SETTING_SAVE_ALBUMINFO = "Lagre AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Last ned video"
|
||||
SETTING_ADD_LYRICS = "Legg til sangtekst"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Sangtekst server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Lagre sangtekster med tidsreferanser (.lrc fil)"
|
||||
SETTING_PATH = "Innstillinger sti"
|
||||
SETTING_APIKEY = "API-nøkkel støtte"
|
||||
SETTING_ADD_TYPE_FOLDER = "Legg til Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "VALG"
|
||||
FUNCTION = "FUNKSJON"
|
||||
CHOICE_ENTER = "Tast inn"
|
||||
CHOICE_ENTER_URLID = "Tast inn 'Url/ID':"
|
||||
CHOICE_EXIT = "Avslutt"
|
||||
CHOICE_LOGIN = "Kontroller AccessToken"
|
||||
CHOICE_SETTINGS = "Innstillinger"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Sett AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Last ned via URL eller ID"
|
||||
CHOICE_LOGOUT = "Logg ut"
|
||||
CHOICE_APIKEY = "Velg APIKey"
|
||||
|
||||
PRINT_ERR = "[FEIL]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUCCES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Tast inn valg:"
|
||||
PRINT_LATEST_VERSION = "Seneste versjon:"
|
||||
# PRINT_USERNAME = "username:"
|
||||
# PRINT_PASSWORD = "password:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Start innstillinger('0'-Tilbake,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_PATH = "Nedlastingssti('0'-ikke endre):"
|
||||
CHANGE_AUDIO_QUALITY = "Lydkvalitet('0'-Normal,'1'-Høy,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Videokvalitet(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Konverter MP4 til M4A('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Legg til eksplisitt tag i filnavn('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ADD_HYPHEN = "Bruk bindestreker i stedet for mellomrom i filnavn('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ADD_YEAR = "Legg til år i albumnavn('0'-Nei,'1'-Ja):"
|
||||
CHANGE_USE_TRACK_NUM = "Legg til spornummer før filnavn('0'-Nei,'1'-Ja):"
|
||||
CHANGE_CHECK_EXIST = "Kontrollér filens eksistens før nedlasting('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Legg til artistnavn før sportittel('0'-Nei,'1'-Ja):"
|
||||
CHANGE_INCLUDE_EP = "Inkluder singler og EP'er når man laster ned en artists album('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Legg til ID før albummappe('0'-Nei,'1'-Ja):"
|
||||
CHANGE_SAVE_COVERS = "Lagre cover('0'-Nei,'1'-Ja):"
|
||||
CHANGE_LANGUAGE = "Velg språk"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Albummappe format('0'-ikke endre, 'default'-for å sette til standardverdi):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Spillelistemappe format('0'-ikke endre, 'default'-for å sette til standardverdi):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Sportittel filformat('0'-ikke endre, 'default'-for å sette til standardverdi):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Videofil format('0'-ikke endre, 'default'-for å sette til standardverdi):"
|
||||
CHANGE_SHOW_PROGRESS = "Vis fremgang('0'-Nei,'1'-Ja):"
|
||||
CHANGE_SHOW_TRACKINFO = "Vis sporinformasjon('0'-Nei,'1'-Ja):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Lagre AlbumInfo.txt('0'-Nei,'1'-Ja):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Last ned videers (i spillelister, album, mikser)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Legg til sangtekst('0'-Nei,'1'-Ja):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Sangtekst server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Lagre sangtekster med tidsreferanser .lrc fil ('0'-Nei,'1'-Ja):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Legg til Type-mappe, f.eks. Album/Video/Spilleliste('0'-Nei,'1'-Ja):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Last ned flere samtidig('0'-Nei,'1'-Ja):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starter login-prosessen."
|
||||
AUTH_LOGIN_CODE = "Din login kode er {}"
|
||||
AUTH_NEXT_STEP = "Gå til {} innen de neste {} for å avslutte setup."
|
||||
AUTH_WAITING = "Venter på godkjennelse..."
|
||||
AUTH_TIMEOUT = "Tiden gikk ut."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken tilgjengelig for {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken utløpt. Forøsker å oppdatere"
|
||||
MSG_PATH_ERR = "Sti feil!"
|
||||
MSG_INPUT_ERR = "Inntastningsfeol!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-PROPERTY"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-PROPERTY"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-PROPERTY"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIST-PROPERTY"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-PROPERTY"
|
||||
|
||||
MODEL_TITLE = 'Tittel'
|
||||
MODEL_TRACK_NUMBER = 'Spornummer'
|
||||
MODEL_VIDEO_NUMBER = 'Videonummer'
|
||||
MODEL_RELEASE_DATE = 'Utgivelsesdato'
|
||||
MODEL_VERSION = 'Versjon'
|
||||
MODEL_EXPLICIT = 'Eksplisitt'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Navn'
|
||||
MODEL_TYPE = 'Type'
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : polish.py
|
||||
@Time : 2022/03/04
|
||||
@Author : PatrykMis
|
||||
@Version : 1.0
|
||||
@Contact : patryk.mis@member.fsf.org
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangPolish(object):
|
||||
SETTING = "USTAWIENIA"
|
||||
VALUE = "WARTOŚĆ"
|
||||
SETTING_DOWNLOAD_PATH = "Ścieżka pobierania"
|
||||
SETTING_ONLY_M4A = "Konwertuj mp4 do m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Dodaj tag jednoznaczne"
|
||||
SETTING_ADD_HYPHEN = "Dodaj myslnik"
|
||||
SETTING_ADD_YEAR = "Dodaj rok porzed folderem albumu"
|
||||
SETTING_USE_TRACK_NUM = "Dodaj numer utworu użytkownika"
|
||||
SETTING_AUDIO_QUALITY = "Jakość audio"
|
||||
SETTING_VIDEO_QUALITY = "Jakość wideo"
|
||||
SETTING_CHECK_EXIST = "Sprawdź istnienie"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Nazwa artysty przed tytułem utworu"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Id przed folderem albumu"
|
||||
SETTING_INCLUDE_EP = "Uwzględnij single i EP"
|
||||
SETTING_SAVE_COVERS = "Zapisz okładki"
|
||||
SETTING_LANGUAGE = "Język"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Użyj folder playlisty"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Pobieranie wielowątkowe"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Format folderu albumu"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Format pliku utworu"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Pokaż postęp"
|
||||
SETTING_SHOW_TRACKINFO = "Pokaż informacje o utworze"
|
||||
SETTING_SAVE_ALBUMINFO = "Zapisz AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Dodaj teksty utworów"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Serwer proxy dla tekstów"
|
||||
SETTING_ADD_LRC_FILE = "Zapisz czasowe teksty utworów (plik .lrc)"
|
||||
SETTING_PATH = "Ścieżka ustawień"
|
||||
SETTING_APIKEY = "Obsługa APIKey"
|
||||
SETTING_ADD_TYPE_FOLDER = "Dodaj folder typu"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "WYBÓR"
|
||||
FUNCTION = "FUNKCJA"
|
||||
CHOICE_ENTER = "Wpisz"
|
||||
CHOICE_ENTER_URLID = "Wpisz 'Url/ID':"
|
||||
CHOICE_EXIT = "Wyjdź"
|
||||
CHOICE_LOGIN = "Sprawdź AccessToken"
|
||||
CHOICE_SETTINGS = "Ustawienia"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Ustaw AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Pobierz według adresu URL lub ID"
|
||||
CHOICE_LOGOUT = "Wyloguj"
|
||||
CHOICE_APIKEY = "Wybierz APIKey"
|
||||
|
||||
PRINT_ERR = "[BŁĄD]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[SUKCES]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Wprowadź Wybór:"
|
||||
PRINT_LATEST_VERSION = "Najnowsza wersja:"
|
||||
# PRINT_USERNAME = "nazwa użytkownika:"
|
||||
# PRINT_PASSWORD = "hasło:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Uruchomić ustawienia('0'-Powrót,'1'-Tak):"
|
||||
CHANGE_DOWNLOAD_PATH = "Ścieżka pobierania('0'-bez zmian):"
|
||||
CHANGE_AUDIO_QUALITY = "Jakość audio('0'-Normalna,'1'-Wysoka,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Jakość wideo(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Konwertuj mp4 do m4a('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Dodaj tag jednoznaczne do nazwy pliku('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ADD_HYPHEN = "Używaj myślników zamiast spacji w nazwach plików('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ADD_YEAR = "Dodaj rok do nazw folderów albumów('0'-Nie,'1'-Tak):"
|
||||
CHANGE_USE_TRACK_NUM = "Dodaj numer utworu przed nazwami plików('0'-Nie,'1'-Tak):"
|
||||
CHANGE_CHECK_EXIST = "Sprawdź istniejący plik przed pobraniem utworu('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Dodaj nazwę artysty przed tytułem utworu('0'-Nie,'1'-Tak):"
|
||||
CHANGE_INCLUDE_EP = "Uwzględnij single i EP podczas pobierania albumów wykonawcy('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Dodaj ID przed folderem albumu('0'-Nie,'1'-Tak):"
|
||||
CHANGE_SAVE_COVERS = "Zapisz okładki('0'-Nie,'1'-Tak):"
|
||||
CHANGE_LANGUAGE = "Wybierz język"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Format folderu albumu('0'-nie modyfikuj,'default'-by ustawić domyślny):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Format pliku utworu('0'-nie modyfikuj,'default'-by ustawić domyślny):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Pokaż postęp('0'-Nie,'1'-Tak):"
|
||||
CHANGE_SHOW_TRACKINFO = "Pokaż informacje o utworze('0'-Nie,'1'-Tak):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Zapisz AlbumInfo.txt('0'-Nie,'1'-Tak):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Dodaj teksty utworów('0'-Nie,'1'-Tak):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Serwer proxy dla tekstów('0'-nie modyfikuj):"
|
||||
CHANGE_ADD_LRC_FILE = "Zapisz plik .lrc czasowych tekstów utworów ('0'-Nie,'1'-Tak):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Dodaj folder typu, np. Album/wideo/lista odtwarzania('0'-Nie,'1'-Tak):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Rozpoczęcie procesu logowania..."
|
||||
AUTH_LOGIN_CODE = "Twój kod logowania to {}"
|
||||
AUTH_NEXT_STEP = "Przejdź do {} w ciągu następnych {} aby zakończyć konfigurację."
|
||||
AUTH_WAITING = "Oczekiwanie na autoryzację..."
|
||||
AUTH_TIMEOUT = "Przekroczono limit czasu operacji."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken dobry przez {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken wygasł. Próba jego odświeżenia."
|
||||
MSG_PATH_ERR = "Ścieżka jest błędna!"
|
||||
MSG_INPUT_ERR = "Błąd wejścia!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-WŁAŚCIWOŚĆ"
|
||||
MODEL_TRACK_PROPERTY = "UTWÓR-WŁAŚCIWOŚĆ"
|
||||
MODEL_VIDEO_PROPERTY = "WIDEO-WŁAŚCIWOŚĆ"
|
||||
MODEL_ARTIST_PROPERTY = "ARTYSTA-WŁAŚCIWOŚĆ"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLISTA-WŁAŚCIWOŚĆ"
|
||||
|
||||
MODEL_TITLE = 'Tytuł'
|
||||
MODEL_TRACK_NUMBER = 'Numer Utworu'
|
||||
MODEL_VIDEO_NUMBER = 'Numer Wideo'
|
||||
MODEL_RELEASE_DATE = 'Data Wydania'
|
||||
MODEL_VERSION = 'Wersja'
|
||||
MODEL_EXPLICIT = 'Jednoznaczny'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'Nazwa'
|
||||
MODEL_TYPE = 'Typ'
|
||||
@@ -9,6 +9,7 @@
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangPortuguese(object):
|
||||
SETTING = "Configurações"
|
||||
VALUE = "VALOR"
|
||||
@@ -26,21 +27,35 @@ class LangPortuguese(object):
|
||||
SETTING_INCLUDE_EP = "Incluir Single & EP"
|
||||
SETTING_SAVE_COVERS = "Salvar Capas"
|
||||
SETTING_LANGUAGE = "idioma"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Usar pasta de lista de reprodução"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Download de vários tópicos"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Formato da pasta do álbum"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Mostrar progresso"
|
||||
SETTING_SHOW_TRACKINFO = "Mostrar informações da faixa"
|
||||
SETTING_SAVE_ALBUMINFO = "Salvar AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Adicionar Letra da Música"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Proxy do servidor de letras"
|
||||
SETTING_ADD_LRC_FILE = "Salvar letras cronometradas (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "Suporte APIKey"
|
||||
SETTING_ADD_TYPE_FOLDER = "Adicionar tipo de pasta"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "ESCOLHER"
|
||||
FUNCTION = "FUNÇÃO"
|
||||
CHOICE_ENTER = "Entrar"
|
||||
CHOICE_ENTER_URLID = "ADICIONAR 'Url/ID':"
|
||||
CHOICE_EXIT = "SAIR"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Verificar o token de acesso"
|
||||
CHOICE_SETTINGS = "Configurações"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Adicionar Token de Acesso"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Adicionar Token de Acesso"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Download Por url ou id"
|
||||
CHOICE_LOGOUT = "Logout"
|
||||
CHOICE_APIKEY = "Selecione a APIKey"
|
||||
|
||||
PRINT_ERR = "[ERRO]"
|
||||
PRINT_INFO = "[INFORMAÇÕES]"
|
||||
@@ -48,13 +63,13 @@ class LangPortuguese(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Entrar em Escolher:"
|
||||
PRINT_LATEST_VERSION = "Última Versão:"
|
||||
#PRINT_USERNAME = "Nome De Usuário:"
|
||||
#PRINT_PASSWORD = "Senha:"
|
||||
|
||||
# PRINT_USERNAME = "Nome De Usuário:"
|
||||
# PRINT_PASSWORD = "Senha:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Configurações Iniciais('0'-Retornar,'1'-Sim):"
|
||||
CHANGE_DOWNLOAD_PATH = "Caminho do download('0' Não Modificar):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualidade De Áudio('0'-Normal,'1'-Alta,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualidade Do Vídeo('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "Qualidade De Áudio('0'-Normal,'1'-Alta,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Qualidade Do Vídeo(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Converter mp4 para m4a('0'-Não,'1'-Sim):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Adicionar Etiqueta Explícito para os nomes dos arquivos('0'-Não,'1'-Sim):"
|
||||
CHANGE_ADD_HYPHEN = "Usar hífen em vez de espaços nos nomes dos arquivos('0'-Não,'1'-Sim):"
|
||||
@@ -66,19 +81,30 @@ class LangPortuguese(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Adicionar id antes no nome da pasta do álbum('0'-Não,'1'-Sim):"
|
||||
CHANGE_SAVE_COVERS = "Salvar Capas('0'-Não,'1'-Sim):"
|
||||
CHANGE_LANGUAGE = "Selecionar idioma"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Formato da pasta do álbum ('0' não modificar)"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Formato do arquivo de trilha ('0' não modificar):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Mostrar progresso('0'-Não,'1'-Sim):"
|
||||
CHANGE_SHOW_TRACKINFO = "Mostrar informações da faixa('0'-Não,'1'-Sim):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Salvar AlbumInfo.txt('0'-Não,'1'-Sim):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Adicionar letras('0'-Não,'1'-Sim):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Proxy do servidor de letras ('0' não modificar):"
|
||||
CHANGE_ADD_LRC_FILE = "Salvar arquivo .lrc de letras cronometradas ('0'-Não,'1'-Sim):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Adicionar Tipo de Pasta, por exemplo, Álbum/Vídeo/Lista de Reprodução('0'-Não,'1'-Sim):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
AUTH_START_LOGIN = "Iniciando o processo de login..."
|
||||
AUTH_LOGIN_CODE = "Seu código de login é {}"
|
||||
AUTH_NEXT_STEP = "Vá para {} no próximo {} para concluir a configuração."
|
||||
AUTH_WAITING = "Espera da autorização..."
|
||||
AUTH_TIMEOUT = "A operação expirou."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "Token de acesso bom por {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Token de acesso expirado. Tentando atualizá-lo."
|
||||
MSG_PATH_ERR = "Erro no local de salvamento dos arquivos!"
|
||||
MSG_INPUT_ERR = "Erro de Entrada!"
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : russian.py
|
||||
@Time : 2020/08/19
|
||||
@Time : 2020/11/29
|
||||
@Author : sergey.seve-s
|
||||
@Version : 1.0
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangRussian(object):
|
||||
SETTING = "НАСТРОЙКА"
|
||||
VALUE = "УСТАНОВКА"
|
||||
@@ -26,21 +27,35 @@ class LangRussian(object):
|
||||
SETTING_INCLUDE_EP = "Включить сингл и миньон"
|
||||
SETTING_SAVE_COVERS = "Добавлять обложку"
|
||||
SETTING_LANGUAGE = "Язык"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Плейлисты в отдельную папку"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Многопоточная загрузка"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Маска имени альбома"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Маска имени трека"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Показывать процесс загрузки"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Сохранять AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Добавлять текст песень"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Прокси сервер для текстов песен"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Путь для настроек"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "ВЫБРАТЬ"
|
||||
FUNCTION = "ФУНКЦИИ"
|
||||
CHOICE_ENTER = "Ввод"
|
||||
CHOICE_ENTER_URLID = "Ввод 'Url/ID':"
|
||||
CHOICE_EXIT = "Выход"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Проверить AccessToken"
|
||||
CHOICE_SETTINGS = "Настройки"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Применить AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Применить AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Использовать ссылку для загрузки"
|
||||
CHOICE_LOGOUT = "Переподключение"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[ОШИБКА]"
|
||||
PRINT_INFO = "[СВЕДЕНИЯ]"
|
||||
@@ -48,13 +63,13 @@ class LangRussian(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Выбор функции:"
|
||||
PRINT_LATEST_VERSION = "Последняя версия:"
|
||||
#PRINT_USERNAME = "Имя:"
|
||||
#PRINT_PASSWORD = "Пароль:"
|
||||
|
||||
# PRINT_USERNAME = "Имя:"
|
||||
# PRINT_PASSWORD = "Пароль:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Начальная настройка('0'-Отмена,'1'-Да):"
|
||||
CHANGE_DOWNLOAD_PATH = "Место сохранения('0'-Отмена):"
|
||||
CHANGE_AUDIO_QUALITY = "Качество аудио('0'-Стандарт,'1'-Высокое,'2'-HiFi,'3'-MQA):"
|
||||
CHANGE_VIDEO_QUALITY = "Качество видео('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_AUDIO_QUALITY = "Качество аудио('0'-Стандарт,'1'-Высокое,'2'-HiFi,'3'-MQA,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Качество видео(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Сохранять mp4 как m4a('0'-Нет,'1'-Да):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Добавить тег 'Нецензурно' ('0'-Нет,'1'-Да):"
|
||||
CHANGE_ADD_HYPHEN = "Использовать дефис вместо пробела в имени трека('0'-Нет,'1'-Да):"
|
||||
@@ -66,19 +81,30 @@ class LangRussian(object):
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Добавить ID перед названием альбома('0'-Нет,'1'-Да):"
|
||||
CHANGE_SAVE_COVERS = "Сохранять обложки('0'-Нет,'1'-Да):"
|
||||
CHANGE_LANGUAGE = "Выбрать язык"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Маска имени альбома('0' не менять):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Маска имени трека('0' не менять):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Показывать процесс загрузки('0'-Нет,'1'-Да):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Сохранять AlbumInfo.txt('0'-Нет,'1'-Да):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Добавлять тексты песень ('0'-Нет,'1'-Да):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Прокси для сервера с текстом песень('0' не менять):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
AUTH_START_LOGIN = "Входим в сервис..."
|
||||
AUTH_LOGIN_CODE = "Ваш код для входа {}"
|
||||
AUTH_NEXT_STEP = "Перейдите к {} в течении {}, для завершения настройки."
|
||||
AUTH_WAITING = "Ожидание авторизации..."
|
||||
AUTH_TIMEOUT = "Закончилось время ожидания."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken успешно применён {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Срок действия AccessToken истек. Попытка обновления."
|
||||
MSG_PATH_ERR = "Неверное место!"
|
||||
MSG_INPUT_ERR = "Ошибка ввода!"
|
||||
|
||||
|
||||
@@ -2,19 +2,20 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : spanish.py
|
||||
@Time : 2020/08/21
|
||||
@Author : JavierSC
|
||||
@Version : 1.0
|
||||
@Time : 2022/07/07
|
||||
@Author : Frikilinux & JavierSC
|
||||
@Version : 2.3
|
||||
@Contact :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangSpanish(object):
|
||||
SETTING = "AJUSTES"
|
||||
VALUE = "VALORES"
|
||||
SETTING_DOWNLOAD_PATH = "Ruta de descarga"
|
||||
SETTING_ONLY_M4A = "Convertir mp4 a m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Añadir tag de 'Contenido explícito'"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Agregar etiqueta de 'Contenido explícito'"
|
||||
SETTING_ADD_HYPHEN = "Agregar guión"
|
||||
SETTING_ADD_YEAR = "Agregar año en la carpeta del álbum"
|
||||
SETTING_USE_TRACK_NUM = "Agregar número de la pista"
|
||||
@@ -23,64 +24,89 @@ class LangSpanish(object):
|
||||
SETTING_CHECK_EXIST = "Verificar si existe"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Nombre del artista en el título de la pista"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "Añadir ID de la carpeta del álbum"
|
||||
SETTING_INCLUDE_EP = "Incluir Sencillos y EPs"
|
||||
SETTING_INCLUDE_EP = "Incluir sencillos y EPs"
|
||||
SETTING_SAVE_COVERS = "Guardar carátulas"
|
||||
SETTING_LANGUAGE = "Idioma"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Usar directorio de la lista de reproducción"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Descarga Multi-hilo"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Formato del nombre de carpeta del álbum"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Formato del nombre de archivo de la pista"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Mostrar progreso"
|
||||
SETTING_SHOW_TRACKINFO = "Mostrar información de pista"
|
||||
SETTING_SAVE_ALBUMINFO = "Guardar AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Añadir letras"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Proxy del servidor de letras"
|
||||
SETTING_ADD_LRC_FILE = "Añadir letras cronometradas (archivo .lrc)"
|
||||
SETTING_PATH = "Ruta de ajustes"
|
||||
SETTING_APIKEY = "Soporte de la APIKey"
|
||||
SETTING_ADD_TYPE_FOLDER = "Añadir tipo de carpeta"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "SELECCIÓN"
|
||||
FUNCTION = "FUNCIÓN"
|
||||
CHOICE_ENTER = "Ingresar"
|
||||
CHOICE_ENTER_URLID = "Ingresar 'Url/ID':"
|
||||
CHOICE_EXIT = "Salir"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Verificar el token de acceso"
|
||||
CHOICE_SETTINGS = "Ajustes"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Establecer AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Establecer AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Descargar por Url o ID"
|
||||
CHOICE_LOGOUT = "Cerrar sesión"
|
||||
CHOICE_APIKEY = "Seleccionar APIKey"
|
||||
|
||||
PRINT_ERR = "[ERR]"
|
||||
PRINT_ERR = "[ERROR]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_SUCCESS = "[EXITO]"
|
||||
PRINT_SUCCESS = "[ÉXITO]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Ingresar Selección:"
|
||||
PRINT_LATEST_VERSION = "Ultima versión:"
|
||||
#PRINT_USERNAME = "nombre de usuario:"
|
||||
#PRINT_PASSWORD = "contraseña:"
|
||||
PRINT_LATEST_VERSION = "Última versión:"
|
||||
# PRINT_USERNAME = "nombre de usuario:"
|
||||
# PRINT_PASSWORD = "contraseña:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Iniciar ajustes('0'-Volver,'1'-Si):"
|
||||
CHANGE_DOWNLOAD_PATH = "Ruta de descarga('0' No modificar):"
|
||||
CHANGE_AUDIO_QUALITY = "Calidad de audio('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Calidad de video('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "Convertir mp4 a m4a('0'-No,'1'-Si):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Agregar tag de contenido explícito a los nombres de archivo('0'-No,'1'-Si):"
|
||||
CHANGE_ADD_HYPHEN = "Usar guiones en lugar de espacios en el nombre de los archivos('0'-No,'1'-Si):"
|
||||
CHANGE_ADD_YEAR = "Agregar año a el nombre de las carpetas del álbum('0'-No,'1'-Si):"
|
||||
CHANGE_USE_TRACK_NUM = "Agregar número de la pista('0'-No,'1'-Si):"
|
||||
CHANGE_CHECK_EXIST = "Verificar si el archivo existe antes de descargar la pista('0'-No,'1'-Si):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Añadir el nombre del artista en el título de la pista('0'-No,'1'-Si):"
|
||||
CHANGE_INCLUDE_EP = "Incluir Sencillos y EPs al descargar el álbum del artista('0'-No,'1'-Si):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Añadir ID de la carpeta del álbum('0'-No,'1'-Si):"
|
||||
CHANGE_SAVE_COVERS = "Guardar carátulas('0'-No,'1'-Si):"
|
||||
CHANGE_START_SETTINGS = "¿Iniciar ajustes? ('0'-Volver,'1'-Sí):"
|
||||
CHANGE_DOWNLOAD_PATH = "Ruta de descarga ('0' No modificar):"
|
||||
CHANGE_AUDIO_QUALITY = "Calidad de audio ('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Calidad de video (1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "¿Convertir mp4 a m4a? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "¿Agregar etiqueta de contenido explícito a los nombres de archivo? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ADD_HYPHEN = "¿Usar guiones en lugar de espacios en el nombre de los archivos? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ADD_YEAR = "¿Agregar año a el nombre de las carpetas del álbum? ('0'-No,'1'-Sí):"
|
||||
CHANGE_USE_TRACK_NUM = "¿Agregar número de la pista? ('0'-No,'1'-Sí):"
|
||||
CHANGE_CHECK_EXIST = "¿Verificar si el archivo existe antes de descargar la pista? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "¿Añadir el nombre del artista en el título de la pista? ('0'-No,'1'-Sí):"
|
||||
CHANGE_INCLUDE_EP = "¿Incluir Sencillos y EPs al descargar el álbum del artista? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "¿Añadir ID de la carpeta del álbum? ('0'-No,'1'-Sí):"
|
||||
CHANGE_SAVE_COVERS = "¿Guardar carátulas?('0'-No,'1'-Sí):"
|
||||
CHANGE_LANGUAGE = "Seleccione el idioma"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Formato del nombre de carpeta del álbum('0' No modificar):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Formato del nombre de archivo de la pista('0' No modificar):"
|
||||
CHANGE_SHOW_PROGRESS = "Mostrar progreso('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Formato del nombre de carpeta del álbum ('0' No modificar):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Formato del nombre de archivo de la pista ('0' No modificar):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Formato del archivo de video('0'-No modificar,'default'-por defecto):"
|
||||
CHANGE_SHOW_PROGRESS = "¿Mostrar progreso? ('0'-No,'1'-Sí):"
|
||||
CHANGE_SHOW_TRACKINFO = "¿Mostrar información de pista?('0'-No,'1'-Sí):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "¿Guardar AlbumInfo.txt?('0'-No,'1'-Sí):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "¿Añadir letras?('0'-No,'1'-Sí):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "¿Proxy del servidor de letras?('0' no modificar):"
|
||||
CHANGE_ADD_LRC_FILE = "¿Añadir letras cronometradas en un archivo .lrc? ('0'-No,'1'-Sí):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Añadir tipo de carpeta, ej: Album/Video/Playlist('0'-No,'1'-Sí):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "¿Descarga Multi-hilo?('0'-No,'1'-Sí:"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "La ruta no es correcta!"
|
||||
MSG_INPUT_ERR = "Error de entrada!"
|
||||
AUTH_START_LOGIN = "Iniciando sesión..."
|
||||
AUTH_LOGIN_CODE = "Su código para autorizar la sesión es {}"
|
||||
AUTH_NEXT_STEP = "Diríjase a {} en los próximos {} para completar la autorización."
|
||||
AUTH_WAITING = "Esperando la autorización..."
|
||||
AUTH_TIMEOUT = "Se superó el tiempo de espera."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "Token de acceso válido por {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "El token de acceso ha expirado. Tratando de renovarlo."
|
||||
MSG_PATH_ERR = "¡La ruta no es correcta!"
|
||||
MSG_INPUT_ERR = "¡Error de entrada!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "PROPIEDAD-DE-ÁLBUM"
|
||||
MODEL_TRACK_PROPERTY = "PROPIEDAD-DE-PISTA"
|
||||
@@ -89,8 +115,8 @@ class LangSpanish(object):
|
||||
MODEL_PLAYLIST_PROPERTY = "PROPIEDAD-DE-PLAYLIST"
|
||||
|
||||
MODEL_TITLE = 'Título'
|
||||
MODEL_TRACK_NUMBER = 'Numero de pista'
|
||||
MODEL_VIDEO_NUMBER = 'Numero de video'
|
||||
MODEL_TRACK_NUMBER = 'Número de pistas'
|
||||
MODEL_VIDEO_NUMBER = 'Número de videos'
|
||||
MODEL_RELEASE_DATE = 'Fecha de lanzamiento'
|
||||
MODEL_VERSION = 'Versión'
|
||||
MODEL_EXPLICIT = 'Explícito'
|
||||
|
||||
+126
-100
@@ -1,100 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : turkish.py
|
||||
@Time : 2020/09/13
|
||||
@Author : Gorgeous & shhade for hack & Mutlu ŞEN
|
||||
@Version : 1.0
|
||||
@Contact : realmutlusen@gmail.com
|
||||
@Desc : Yanlış çeviri ya da düzenleme için 'realmutlusen@gmail.com'a mail atabilirsiniz.
|
||||
'''
|
||||
|
||||
class LangTurkish(object):
|
||||
SETTING = "AYARLAR"
|
||||
VALUE = "VERİLER"
|
||||
SETTING_DOWNLOAD_PATH = "İndirme konumu:"
|
||||
SETTING_ONLY_M4A = ".mp4 uzantısı m4a'ya çevrilsin:"
|
||||
SETTING_ADD_EXPLICIT_TAG = "'Küfürlü' etiketi eklensin:"
|
||||
SETTING_ADD_HYPHEN = "Boşluk yerine '-' eklensin:"
|
||||
SETTING_ADD_YEAR = "Yıl eklensin:"
|
||||
SETTING_USE_TRACK_NUM = "Artist numarası eklensin:"
|
||||
SETTING_AUDIO_QUALITY = "Ses kalitesi:"
|
||||
SETTING_VIDEO_QUALITY = "Video kalitesi:"
|
||||
SETTING_CHECK_EXIST = "İndirilmiş mi diye kontrol edilsin:"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Artist adı eklensin:"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID eklensin:"
|
||||
SETTING_INCLUDE_EP = "Single'leri ve EP'leri dahil edisin:"
|
||||
SETTING_SAVE_COVERS = "Albüm kapağı indirilsin:"
|
||||
SETTING_LANGUAGE = "Kullanılan lisan:"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Albümler klasör halinde indirilsin mi ?"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Şarkılar tek tek indirilsin mi?"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Klasör ismi formatı:"
|
||||
SETTING_TRACK_FILE_FORMAT = "Dosya ismi formatı:"
|
||||
SETTING_SHOW_PROGRESS = "İndirme Çubuğu Görüntüleme:"
|
||||
|
||||
CHOICE = "Seçim"
|
||||
FUNCTION = "İşlemler"
|
||||
CHOICE_ENTER = "Enter"
|
||||
CHOICE_ENTER_URLID = "'Url/ID' Gir:"
|
||||
CHOICE_EXIT = "Çıkış"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_SETTINGS = "Ayarlar'ı Düzenle"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "'AccessToken' Gir"
|
||||
CHOICE_DOWNLOAD_BY_URL = "URL ya da ID ile indir"
|
||||
|
||||
PRINT_ERR = "[HATA OLUŞTU]"
|
||||
PRINT_INFO = "[BİLGİ]"
|
||||
PRINT_SUCCESS = "[İNDİRİLDİ]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Seçim Gir: "
|
||||
PRINT_LATEST_VERSION = "Güncelleme Mevcut:"
|
||||
#PRINT_USERNAME = "Kullanıcı Adı ya da Mail Adresi:"
|
||||
#PRINT_PASSWORD = "Şifre:"
|
||||
|
||||
CHANGE_START_SETTINGS = ">>> Ayarları düzenlemek istediğine emin misin ? ('0'-Geri Dön,'1'-Evet): "
|
||||
CHANGE_DOWNLOAD_PATH = ">>> İndirme Konumu ('0' aynı kalsın): "
|
||||
CHANGE_AUDIO_QUALITY = ">>> Ses Kalitesi ('0'-Normal,'1'-Yüksek,'2'-HiFi,'3'-[M]aster): "
|
||||
CHANGE_VIDEO_QUALITY = ">>> Video Kalitesi ('0'-1080P,'1'-720P,'2'-480P,'3'-360P): "
|
||||
CHANGE_ONLYM4A = ">>> .mp4 uzantılı dosyalar .m4a'ya çevrilsin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_EXPLICIT_TAG = ">>> 'Explicit' yani 'küfürlü' etiketi eklensin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_HYPHEN = ">>> Şarkı dosyasının isminde boşluk yerine '-' eklensin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_YEAR = ">>> Albüm klasörünün isminde yıl olsun mu ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_USE_TRACK_NUM = ">>> Şarkı dosyasının isminde albümdeki sırası yazsın mı ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_CHECK_EXIST = ">>> Dosya daha önce indirilmiş mi diye kontrol edilsin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ARTIST_BEFORE_TITLE = ">>> Şarkı dosyasının ismine sanatçının adı eklensin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_INCLUDE_EP = ">>> Artist'in tüm albümlerini indirirken Single'leri ve EP'leri de dahil edilsin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = ">>> Albüm klasörünün ismine ID eklensin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_SAVE_COVERS = ">>> Albüm kapağı indirilsin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_LANGUAGE = ">>> Lisan Seç "
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Albüm Klasör İsmi Formatı('0' aynı kalsın):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Dosya İsmi Formatı('0' aynı kalsın):"
|
||||
CHANGE_SHOW_PROGRESS = "İndirme Çubuğu Görüntülensin mi?('0'-Hayır,'1'-Evet):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "İndirme konumu ile alakalı bir sorun var! ('/storage/emulated/0/Download/' şeklinde girebilirsiniz.)"
|
||||
MSG_INPUT_ERR = "Giriş Hatalı!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBÜM-BİLGİLERİ"
|
||||
MODEL_TRACK_PROPERTY = "ŞARKI-BİLGİLERİ"
|
||||
MODEL_VIDEO_PROPERTY = "VİDEO-BİLGİLERİ"
|
||||
MODEL_ARTIST_PROPERTY = "ARTİST-BİLGİLERİ"
|
||||
MODEL_PLAYLIST_PROPERTY = "OYNATMA LİSTESİ-BİLGİLERİ"
|
||||
|
||||
MODEL_TITLE = 'Şarkı/Albüm Adı:'
|
||||
MODEL_TRACK_NUMBER = 'Şarkı Sayısı'
|
||||
MODEL_VIDEO_NUMBER = 'Video Sayısı'
|
||||
MODEL_RELEASE_DATE = 'Çıkış Yılı:'
|
||||
MODEL_VERSION = 'Versiyon'
|
||||
MODEL_EXPLICIT = 'Küfürlü'
|
||||
MODEL_ALBUM = 'Albüm'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'İsim'
|
||||
MODEL_TYPE = 'Türü'
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : turkish.py
|
||||
@Time : 2020/09/13
|
||||
@Author : Gorgeous & shhade for hack & Mutlu ŞEN
|
||||
@Version : 1.0
|
||||
@Contact : realmutlusen@gmail.com
|
||||
@Desc : Yanlış çeviri ya da düzenleme için 'realmutlusen@gmail.com'a mail atabilirsiniz.
|
||||
'''
|
||||
|
||||
|
||||
class LangTurkish(object):
|
||||
SETTING = "AYARLAR"
|
||||
VALUE = "VERİLER"
|
||||
SETTING_DOWNLOAD_PATH = "İndirme konumu:"
|
||||
SETTING_ONLY_M4A = ".mp4 uzantısı m4a'ya çevrilsin:"
|
||||
SETTING_ADD_EXPLICIT_TAG = "'Küfürlü' etiketi eklensin:"
|
||||
SETTING_ADD_HYPHEN = "Boşluk yerine '-' eklensin:"
|
||||
SETTING_ADD_YEAR = "Yıl eklensin:"
|
||||
SETTING_USE_TRACK_NUM = "Artist numarası eklensin:"
|
||||
SETTING_AUDIO_QUALITY = "Ses kalitesi:"
|
||||
SETTING_VIDEO_QUALITY = "Video kalitesi:"
|
||||
SETTING_CHECK_EXIST = "İndirilmiş mi diye kontrol edilsin:"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Artist adı eklensin:"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID eklensin:"
|
||||
SETTING_INCLUDE_EP = "Single'leri ve EP'leri dahil edisin:"
|
||||
SETTING_SAVE_COVERS = "Albüm kapağı indirilsin:"
|
||||
SETTING_LANGUAGE = "Kullanılan lisan:"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Albümler klasör halinde indirilsin mi ?"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Şarkılar tek tek indirilsin mi?"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Klasör ismi formatı:"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Dosya ismi formatı:"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "İndirme Çubuğu Görüntüleme:"
|
||||
SETTING_SHOW_TRACKINFO = "Show Track Info"
|
||||
SETTING_SAVE_ALBUMINFO = "Save AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Add lyrics"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Lyrics server proxy"
|
||||
SETTING_ADD_LRC_FILE = "Save timed lyrics (.lrc file)"
|
||||
SETTING_PATH = "Settings path"
|
||||
SETTING_APIKEY = "APIKey support"
|
||||
SETTING_ADD_TYPE_FOLDER = "Add Type-Folder"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "Seçim"
|
||||
FUNCTION = "İşlemler"
|
||||
CHOICE_ENTER = "Enter"
|
||||
CHOICE_ENTER_URLID = "'Url/ID' Gir:"
|
||||
CHOICE_EXIT = "Çıkış"
|
||||
CHOICE_LOGIN = "AccessToken kontrolü"
|
||||
CHOICE_SETTINGS = "Ayarlar'ı Düzenle"
|
||||
CHOICE_SET_ACCESS_TOKEN = "'AccessToken' Gir"
|
||||
CHOICE_DOWNLOAD_BY_URL = "URL ya da ID ile indir"
|
||||
CHOICE_LOGOUT = "Çıkış"
|
||||
CHOICE_APIKEY = "Select APIKey"
|
||||
|
||||
PRINT_ERR = "[HATA OLUŞTU]"
|
||||
PRINT_INFO = "[BİLGİ]"
|
||||
PRINT_SUCCESS = "[İNDİRİLDİ]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Seçim Gir: "
|
||||
PRINT_LATEST_VERSION = "Güncelleme Mevcut:"
|
||||
# PRINT_USERNAME = "Kullanıcı Adı ya da Mail Adresi:"
|
||||
# PRINT_PASSWORD = "Şifre:"
|
||||
|
||||
CHANGE_START_SETTINGS = ">>> Ayarları düzenlemek istediğine emin misin ? ('0'-Geri Dön,'1'-Evet): "
|
||||
CHANGE_DOWNLOAD_PATH = ">>> İndirme Konumu ('0' aynı kalsın): "
|
||||
CHANGE_AUDIO_QUALITY = ">>> Ses Kalitesi ('0'-Normal,'1'-Yüksek,'2'-HiFi,'3'-[M]aster,'4'-Max): "
|
||||
CHANGE_VIDEO_QUALITY = ">>> Video Kalitesi (1080, 720, 480, 360): "
|
||||
CHANGE_ONLYM4A = ">>> .mp4 uzantılı dosyalar .m4a'ya çevrilsin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_EXPLICIT_TAG = ">>> 'Explicit' yani 'küfürlü' etiketi eklensin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_HYPHEN = ">>> Şarkı dosyasının isminde boşluk yerine '-' eklensin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ADD_YEAR = ">>> Albüm klasörünün isminde yıl olsun mu ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_USE_TRACK_NUM = ">>> Şarkı dosyasının isminde albümdeki sırası yazsın mı ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_CHECK_EXIST = ">>> Dosya daha önce indirilmiş mi diye kontrol edilsin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ARTIST_BEFORE_TITLE = ">>> Şarkı dosyasının ismine sanatçının adı eklensin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_INCLUDE_EP = ">>> Artist'in tüm albümlerini indirirken Single'leri ve EP'leri de dahil edilsin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = ">>> Albüm klasörünün ismine ID eklensin mi ?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_SAVE_COVERS = ">>> Albüm kapağı indirilsin mi?('0'-Hayır,'1'-Evet): "
|
||||
CHANGE_LANGUAGE = ">>> Lisan Seç "
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Albüm Klasör İsmi Formatı('0' aynı kalsın):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Dosya İsmi Formatı('0' aynı kalsın):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "İndirme Çubuğu Görüntülensin mi?('0'-Hayır,'1'-Evet):"
|
||||
CHANGE_SHOW_TRACKINFO = "Show track info('0'-No,'1'-Yes):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Save AlbumInfo.txt('0'-No,'1'-Yes):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Add lyrics('0'-No,'1'-Yes):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Lyrics server proxy('0'-not modify):"
|
||||
CHANGE_ADD_LRC_FILE = "Save timed lyrics .lrc file ('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Add Type-Folder,eg Album/Video/Playlist('0'-No,'1'-Yes):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Giriş işlemleri başlatıldı..."
|
||||
AUTH_LOGIN_CODE = "Girmen gereken kod: {}"
|
||||
AUTH_NEXT_STEP = "Bu siteden {} hesabınıza giriş yapınız ve üstteki kodu giriniz. ({} dakikanız var.)"
|
||||
AUTH_WAITING = "İşlemleri tamamlamanız bekleniyor..."
|
||||
AUTH_TIMEOUT = "Lütfen size verilen süre içerisinde işlemleriniz tamamlayınız."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
MSG_PATH_ERR = "İndirme konumu ile alakalı bir sorun var! ('/storage/emulated/0/Download/' şeklinde girebilirsiniz.)"
|
||||
MSG_INPUT_ERR = "Giriş Hatalı!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBÜM-BİLGİLERİ"
|
||||
MODEL_TRACK_PROPERTY = "ŞARKI-BİLGİLERİ"
|
||||
MODEL_VIDEO_PROPERTY = "VİDEO-BİLGİLERİ"
|
||||
MODEL_ARTIST_PROPERTY = "ARTİST-BİLGİLERİ"
|
||||
MODEL_PLAYLIST_PROPERTY = "OYNATMA LİSTESİ-BİLGİLERİ"
|
||||
|
||||
MODEL_TITLE = 'Şarkı/Albüm Adı:'
|
||||
MODEL_TRACK_NUMBER = 'Şarkı Sayısı'
|
||||
MODEL_VIDEO_NUMBER = 'Video Sayısı'
|
||||
MODEL_RELEASE_DATE = 'Çıkış Yılı:'
|
||||
MODEL_VERSION = 'Versiyon'
|
||||
MODEL_EXPLICIT = 'Küfürlü'
|
||||
MODEL_ALBUM = 'Albüm'
|
||||
MODEL_ID = 'ID'
|
||||
MODEL_NAME = 'İsim'
|
||||
MODEL_TYPE = 'Türü'
|
||||
|
||||
@@ -2,45 +2,60 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : ukrainian.py
|
||||
@Time : 2020/09/07
|
||||
@Author : Montyzzz
|
||||
@Version : 1.0
|
||||
@Time : 2022/02/20
|
||||
@Author : Montyzzz & 9uyone
|
||||
@Version : 1.2
|
||||
@Contact : ---
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangUkrainian(object):
|
||||
SETTING = "НАЛАШТУВАННЯ"
|
||||
VALUE = "ЗНАЧЕННЯ"
|
||||
SETTING_DOWNLOAD_PATH = "Шлях завантаження"
|
||||
SETTING_ONLY_M4A = "Перетворити mp4 на m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Додати тег Нецензурно"
|
||||
SETTING_ADD_HYPHEN = "Додати дефіс"
|
||||
SETTING_ADD_YEAR = "Додати рік перед ім'ям папки-альбому"
|
||||
SETTING_USE_TRACK_NUM = "Додати номер треку"
|
||||
SETTING_ONLY_M4A = "Перетворювати mp4 на m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Додавати тег Нецензурно"
|
||||
SETTING_ADD_HYPHEN = "Додавати дефіс"
|
||||
SETTING_ADD_YEAR = "Додавати рік перед ім'ям папки альбому"
|
||||
SETTING_USE_TRACK_NUM = "Додавати номер треку"
|
||||
SETTING_AUDIO_QUALITY = "Якість аудіо"
|
||||
SETTING_VIDEO_QUALITY = "Якість відео"
|
||||
SETTING_CHECK_EXIST = "Перевіряти наявність"
|
||||
SETTING_ARTIST_BEFORE_TITLE = "Виконавець перед назвою треку"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID перед назвою теки"
|
||||
SETTING_INCLUDE_EP = "Включити сингл і міньйон"
|
||||
SETTING_SAVE_COVERS = "Зберегти обкладинки"
|
||||
SETTING_ALBUMID_BEFORE_FOLDER = "ID перед назвою папки"
|
||||
SETTING_INCLUDE_EP = "Включати сингли та міньйони (EP)"
|
||||
SETTING_SAVE_COVERS = "Зберігати обкладинки"
|
||||
SETTING_LANGUAGE = "Мова"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Use playlist folder"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Multi thread download"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Використовувати папку плейлиста"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Багатопоточне завантаження"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Формат папки альбому"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Формат файлу треку"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Показувати прогрес"
|
||||
SETTING_SHOW_TRACKINFO = "Показувати інформацію про трек"
|
||||
SETTING_SAVE_ALBUMINFO = "Зберігати AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Додавати тексти пісень"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Проксі для сервера з текстами пісень"
|
||||
SETTING_ADD_LRC_FILE = "Зберігати тексти з відмітками часу (.lrc файл)"
|
||||
SETTING_PATH = "Шлях налаштувань"
|
||||
SETTING_APIKEY = "Підтримка ключа API"
|
||||
SETTING_ADD_TYPE_FOLDER = "Додавати папку-тип"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "ВИБІР"
|
||||
FUNCTION = "ФУНКЦІЇ"
|
||||
CHOICE_ENTER = "Ввід"
|
||||
CHOICE_ENTER_URLID = "Ввід 'Url/ID':"
|
||||
CHOICE_ENTER_URLID = "Ввід 'URL/ID':"
|
||||
CHOICE_EXIT = "Вихід"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Перевірити AccessToken"
|
||||
CHOICE_SETTINGS = "Налаштування"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Застосувати AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Застосувати власний AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Завантажити за URL-адресою або ідентифікатором"
|
||||
CHOICE_LOGOUT = "Деавторизація"
|
||||
CHOICE_APIKEY = "Вибрати ключ API"
|
||||
|
||||
PRINT_ERR = "[ПОМИЛКА]"
|
||||
PRINT_INFO = "[ІНФОРМАЦІЯ]"
|
||||
@@ -48,45 +63,56 @@ class LangUkrainian(object):
|
||||
|
||||
PRINT_ENTER_CHOICE = "Вибір вводу:"
|
||||
PRINT_LATEST_VERSION = "Остання версія:"
|
||||
#PRINT_USERNAME = "ім'я користувача:"
|
||||
#PRINT_PASSWORD = "пароль:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Налаштування запуску('0'-повернення,'1'-так):"
|
||||
CHANGE_DOWNLOAD_PATH = "Шлях завантаження('0' не змінювати):"
|
||||
CHANGE_AUDIO_QUALITY = "Якість аудіо('0'-Звичайна,'1'-Висока,'2'-HiFi,'3'-MQA):"
|
||||
CHANGE_VIDEO_QUALITY = "Якість відео('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "Перетворити mp4 на m4a('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Додати тег 'Нецензурно' ('0'-Ні,'1'-Так):"
|
||||
# PRINT_USERNAME = "ім'я користувача:"
|
||||
# PRINT_PASSWORD = "пароль:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Запуск налаштувань('0'-Повернутися,'1'-Так):"
|
||||
CHANGE_DOWNLOAD_PATH = "Шлях завантаження('0'-не змінювати):"
|
||||
CHANGE_AUDIO_QUALITY = "Якість аудіо('0'-Звичайна,'1'-Висока,'2'-HiFi,'3'-MQA,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Якість відео(1080,720,480,360):"
|
||||
CHANGE_ONLYM4A = "Перетворювати mp4 на m4a('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Додавати тег 'Нецензурно'('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_HYPHEN = "Використати дефіс замість пробілів в іменах файлів('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_YEAR = "Додавати рік до назв тек альбомів ('0'-Ні,'1'-Так):"
|
||||
CHANGE_USE_TRACK_NUM = "Додавати номер доріжки перед назвами файлів ('0'-Ні,'1'-Так):"
|
||||
CHANGE_CHECK_EXIST = "Перевіряти наявний файл перед завантаженням треку ('0'-Ні,'1'-Так):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Додати ім’я виконавця перед заголовком треку ('0'-Ні,'1'-Так):"
|
||||
CHANGE_INCLUDE_EP = "Включати сингли та міньйони під час завантаження альбомів виконавця ('0'-Ні,'1'-Так):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Додати ідентифікатор перед текою альбому ('0'-Ні,'1'-Так):"
|
||||
CHANGE_SAVE_COVERS = "Зберігати обкладинки ('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_YEAR = "Додавати рік до назв тек альбомів('0'-Ні,'1'-Так):"
|
||||
CHANGE_USE_TRACK_NUM = "Додавати номер доріжки перед назвами файлів('0'-Ні,'1'-Так):"
|
||||
CHANGE_CHECK_EXIST = "Перевіряти наявний файл перед завантаженням треку('0'-Ні,'1'-Так):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Додати ім’я виконавця перед заголовком треку('0'-Ні,'1'-Так):"
|
||||
CHANGE_INCLUDE_EP = "Включати сингли та міньйони під час завантаження альбомів виконавця('0'-Ні,'1'-Так):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Додати ідентифікатор перед текою альбому('0'-Ні,'1'-Так):"
|
||||
CHANGE_SAVE_COVERS = "Зберігати обкладинки('0'-Ні,'1'-Так):"
|
||||
CHANGE_LANGUAGE = "Обрати мову"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Формат теки альбому('0'-не змінювати):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Формат файлу треку('0'-не змінювати):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Показувати прогрес('0'-Ні,'1'-Так):"
|
||||
CHANGE_SHOW_TRACKINFO = "Показувати інформацію про трек('0'-Ні,'1'-Так):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Зберігати AlbumInfo.txt('0'-Ні,'1'-Так):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Додавати тексти пісень('0'-Ні,'1'-Так):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Проксі для сервера з текстами пісень('0'-не змінювати):"
|
||||
CHANGE_ADD_LRC_FILE = "Зберігати тексти пісень з відмітками часу в .lrc файл('0'-Ні,'1'-Так):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Додавати теку-тип,наприклад Альбом/Відео/Плейлист('0'-Ні,'1'-Так):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
AUTH_START_LOGIN = "Початок процесу авторизації..."
|
||||
AUTH_LOGIN_CODE = "Ваш логін-код: {}"
|
||||
AUTH_NEXT_STEP = "Зайдіть на {} протягом наступних {} для завершення налаштування."
|
||||
AUTH_WAITING = "Очікування авторизації..."
|
||||
AUTH_TIMEOUT = "Час очікування минув."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken хороший упродовж {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "Термін дії AccessToken'а закінчився. Пробуємо оновити його."
|
||||
MSG_PATH_ERR = "Невірний шлях!"
|
||||
MSG_INPUT_ERR = "Помилка введення!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "ALBUM-PROPERTY"
|
||||
MODEL_TRACK_PROPERTY = "TRACK-PROPERTY"
|
||||
MODEL_VIDEO_PROPERTY = "VIDEO-PROPERTY"
|
||||
MODEL_ARTIST_PROPERTY = "ARTIST-PROPERTY"
|
||||
MODEL_PLAYLIST_PROPERTY = "PLAYLIST-PROPERTY"
|
||||
MODEL_ALBUM_PROPERTY = "АЛЬБОМ-ВЛАСТИВІСТЬ"
|
||||
MODEL_TRACK_PROPERTY = "ТРЕК-ВЛАСТИВІСТЬ"
|
||||
MODEL_VIDEO_PROPERTY = "ВІДЕО-ВЛАСТИВІСТЬ"
|
||||
MODEL_ARTIST_PROPERTY = "АРТИСТ-ВЛАСТИВІСТЬ"
|
||||
MODEL_PLAYLIST_PROPERTY = "ПЛЕЙЛИСТ-ВЛАСТИВІСТЬ"
|
||||
|
||||
MODEL_TITLE = 'Назва'
|
||||
MODEL_TRACK_NUMBER = 'Номер доріжки'
|
||||
|
||||
@@ -2,22 +2,23 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : vietnamese.py
|
||||
@Time : 2020/09/16
|
||||
@Author : MinhNgo
|
||||
@Time : 2022/2/9
|
||||
@Author : MinhNgo, CDzungx
|
||||
@Version : 1.0
|
||||
@Contact : iam.minhnc@outlook.com
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
|
||||
class LangVietnamese(object):
|
||||
SETTING = "THIẾT LẬP"
|
||||
VALUE = "GIÁ TRỊ"
|
||||
SETTING_DOWNLOAD_PATH = "Đường dẫn tải về"
|
||||
SETTING_ONLY_M4A = "Đổi mp4 qua m4a"
|
||||
SETTING_ONLY_M4A = "Đổi mp4 sang m4a"
|
||||
SETTING_ADD_EXPLICIT_TAG = "Thêm tag explicit"
|
||||
SETTING_ADD_HYPHEN = "Thêm dấu nối"
|
||||
SETTING_ADD_YEAR = "Thêm năm trước thư mục album"
|
||||
SETTING_USE_TRACK_NUM = "Thêm STT track"
|
||||
SETTING_USE_TRACK_NUM = "Thêm số thứ tự bài"
|
||||
SETTING_AUDIO_QUALITY = "Chất lượng âm thanh"
|
||||
SETTING_VIDEO_QUALITY = "Chất lượng video"
|
||||
SETTING_CHECK_EXIST = "Kiểm tra tồn tại"
|
||||
@@ -28,71 +29,96 @@ class LangVietnamese(object):
|
||||
SETTING_LANGUAGE = "Ngôn ngữ"
|
||||
SETTING_USE_PLAYLIST_FOLDER = "Thư mục cho danh sách phát"
|
||||
SETTING_MULITHREAD_DOWNLOAD = "Tải về đa luồng"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Album folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Track file format"
|
||||
SETTING_SHOW_PROGRESS = "Show progress"
|
||||
SETTING_ALBUM_FOLDER_FORMAT = "Định dạng thư mục album"
|
||||
SETTING_PLAYLIST_FOLDER_FORMAT = "Playlist folder format"
|
||||
SETTING_TRACK_FILE_FORMAT = "Định dạng tên tệp nhạc"
|
||||
SETTING_VIDEO_FILE_FORMAT = "Video file format"
|
||||
SETTING_SHOW_PROGRESS = "Hiện tiến trình"
|
||||
SETTING_SHOW_TRACKINFO = "Hiện thông tin bài"
|
||||
SETTING_SAVE_ALBUMINFO = "Lưu AlbumInfo.txt"
|
||||
SETTING_DOWNLOAD_VIDEOS = "Download videos"
|
||||
SETTING_ADD_LYRICS = "Thêm lời bài hát"
|
||||
SETTING_LYRICS_SERVER_PROXY = "Máy chủ proxy cho lyrics"
|
||||
SETTING_ADD_LRC_FILE = "Lưu timed lyrics (tệp .lrc)"
|
||||
SETTING_PATH = "Đường dẫn cài đặt"
|
||||
SETTING_APIKEY = "Hỗ trợ APIKey"
|
||||
SETTING_ADD_TYPE_FOLDER = "Thêm Loại-Thư mục"
|
||||
SETTING_DOWNLOAD_DELAY = "Use Download Delay"
|
||||
|
||||
CHOICE = "LỰA CHỌN"
|
||||
FUNCTION = "CHỨC NĂNG"
|
||||
CHOICE_ENTER = "Nhập"
|
||||
CHOICE_ENTER_URLID = "Nhập 'Url/ID':"
|
||||
CHOICE_EXIT = "Thoát"
|
||||
CHOICE_LOGIN = "Check AccessToken"
|
||||
CHOICE_LOGIN = "Kiểm tra AccessToken"
|
||||
CHOICE_SETTINGS = "Thiết lập"
|
||||
#CHOICE_SET_ACCESS_TOKEN = "Nhập AccessToken"
|
||||
CHOICE_SET_ACCESS_TOKEN = "Nhập AccessToken"
|
||||
CHOICE_DOWNLOAD_BY_URL = "Tải về qua url hoặc id"
|
||||
CHOICE_LOGOUT = "Đăng xuất"
|
||||
CHOICE_APIKEY = "Chọn APIKey"
|
||||
|
||||
PRINT_ERR = "[LỖI]"
|
||||
PRINT_INFO = "[INFO]"
|
||||
PRINT_INFO = "[THÔNG TIN]"
|
||||
PRINT_SUCCESS = "[XONG]"
|
||||
|
||||
PRINT_ENTER_CHOICE = "Nhập lựa chọn:"
|
||||
PRINT_LATEST_VERSION = "Bản mới nhất:"
|
||||
#PRINT_USERNAME = "tên đăng nhập:"
|
||||
#PRINT_PASSWORD = "mật khẩu:"
|
||||
|
||||
# PRINT_USERNAME = "tên đăng nhập:"
|
||||
# PRINT_PASSWORD = "mật khẩu:"
|
||||
|
||||
CHANGE_START_SETTINGS = "Bắt đầu thiết lập('0'-Về,'1'-Có):"
|
||||
CHANGE_DOWNLOAD_PATH = "Đường dẫn tải về('0' không đổi):"
|
||||
CHANGE_AUDIO_QUALITY = "Chất lượng âm thanh('0'-Normal,'1'-High,'2'-HiFi,'3'-Master):"
|
||||
CHANGE_VIDEO_QUALITY = "Chất lượng video('0'-1080,'1'-720,'2'-480,'3'-360):"
|
||||
CHANGE_ONLYM4A = "Đổi mp4 qua m4a('0'-Không,'1'-Có):"
|
||||
CHANGE_AUDIO_QUALITY = "Chất lượng âm thanh('0'-Normal,'1'-High,'2'-HiFi,'3'-Master,'4'-Max):"
|
||||
CHANGE_VIDEO_QUALITY = "Chất lượng video(1080, 720, 480, 360):"
|
||||
CHANGE_ONLYM4A = "Đổi mp4 sang m4a('0'-Không,'1'-Có):"
|
||||
CHANGE_ADD_EXPLICIT_TAG = "Thêm tag explicit vào tên tệp('0'-Không,'1'-Có):"
|
||||
CHANGE_ADD_HYPHEN = "Dùng gạch nối thay vì spaces trong tên tệp('0'-Không,'1'-Có):"
|
||||
CHANGE_ADD_HYPHEN = "Dùng gạch nối thay vì dấu cách trong tên tệp('0'-Không,'1'-Có):"
|
||||
CHANGE_ADD_YEAR = "Thêm năm phía trước tên thư mục album('0'-Không,'1'-Có):"
|
||||
CHANGE_USE_TRACK_NUM = "Thêm STT track đầu tên tệp('0'-Không,'1'-Có):"
|
||||
CHANGE_USE_TRACK_NUM = "Thêm số thứ tự bài ở đầu tên tệp('0'-Không,'1'-Có):"
|
||||
CHANGE_CHECK_EXIST = "Kiểm tra tệp đã tồn tại chưa trước khi tải('0'-Không,'1'-Có):"
|
||||
CHANGE_ARTIST_BEFORE_TITLE = "Thêm tên nghệ sĩ trước tựa đề('0'-Không,'1'-Có):"
|
||||
CHANGE_INCLUDE_EP = "Bao gồm đĩa đơn và EPs khi tải tất cả nhạc của nghệ sĩ('0'-Không,'1'-Có):"
|
||||
CHANGE_ALBUMID_BEFORE_FOLDER = "Thêm id phía trước tên thư mục album('0'-Không,'1'-Có):"
|
||||
CHANGE_SAVE_COVERS = "Tải ảnh bìa('0'-Không,'1'-Có):"
|
||||
CHANGE_LANGUAGE = "Chọn ngôn ngữ"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Album folder format('0' not modify):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Track file format('0' not modify):"
|
||||
CHANGE_SHOW_PROGRESS = "Show progress('0'-No,'1'-Yes):"
|
||||
CHANGE_ALBUM_FOLDER_FORMAT = "Định dạng thư mục album('0' không đổi,'default' để đặt về mặc định):"
|
||||
CHANGE_PLAYLIST_FOLDER_FORMAT = "Playlist folder format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_TRACK_FILE_FORMAT = "Định dạng tên tệp nhạc('0' không đổi,'default' để đặt về mặc định):"
|
||||
CHANGE_VIDEO_FILE_FORMAT = "Video file format('0'-not modify,'default'-to set default):"
|
||||
CHANGE_SHOW_PROGRESS = "Hiện tiến trình('0'-Không,'1'-Có):"
|
||||
CHANGE_SHOW_TRACKINFO = "Hiện thông tin bài('0'-Không,'1'-Có):"
|
||||
CHANGE_SAVE_ALBUM_INFO = "Lưu AlbumInfo.txt('0'-Không,'1'-Có):"
|
||||
CHANGE_DOWNLOAD_VIDEOS = "Download videos (when downloading playlists, albums, mixes)('0'-No,'1'-Yes):"
|
||||
CHANGE_ADD_LYRICS = "Thêm lời bài hát('0'-Không,'1'-Có):"
|
||||
CHANGE_LYRICS_SERVER_PROXY = "Máy chủ proxy cho lyrics('0' không đổi):"
|
||||
CHANGE_ADD_LRC_FILE = "Lưu timed lyrics tệp .lrc ('0'-Không,'1'-Có):"
|
||||
CHANGE_ADD_TYPE_FOLDER = "Thêm Loại-Thư mục, ví dụ Album/Video/Playlist('0'-Không,'1'-Có):"
|
||||
CHANGE_MULITHREAD_DOWNLOAD = "Multi thread download('0'-No,'1'-Yes):"
|
||||
CHANGE_USE_DOWNLOAD_DELAY = "Use Download Delay('0'-No,'1'-Yes):"
|
||||
|
||||
# {} are required in these strings
|
||||
AUTH_START_LOGIN = "Starting login process..."
|
||||
AUTH_LOGIN_CODE = "Your login code is {}"
|
||||
AUTH_NEXT_STEP = "Go to {} within the next {} to complete setup."
|
||||
AUTH_WAITING = "Waiting for authorization..."
|
||||
AUTH_TIMEOUT = "Operation timed out."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken good for {}."
|
||||
MSG_INVAILD_ACCESSTOKEN = "Expired AccessToken. Attempting to refresh it."
|
||||
AUTH_START_LOGIN = "Đang bắt đầu đăng nhập..."
|
||||
AUTH_LOGIN_CODE = "Mã đăng nhập của bạn là {}"
|
||||
AUTH_NEXT_STEP = "Vào trang {} trong vòng {} để hoàn tất thiết lập."
|
||||
AUTH_WAITING = "Đang chờ xác minh..."
|
||||
AUTH_TIMEOUT = "Đã vượt quá thời gian chờ."
|
||||
|
||||
MSG_VALID_ACCESSTOKEN = "AccessToken vẫn tốt trong {}."
|
||||
MSG_INVALID_ACCESSTOKEN = "AccessToken hết hạn. Đang cố làm mới."
|
||||
MSG_PATH_ERR = "Lỗi đường dẫn!"
|
||||
MSG_INPUT_ERR = "Lỗi nhập!"
|
||||
|
||||
MODEL_ALBUM_PROPERTY = "THÔNG TIN ALBUM"
|
||||
MODEL_TRACK_PROPERTY = "THÔNG TIN TRACK"
|
||||
MODEL_VIDEO_PROPERTY = "THÔNG TIN VIDEO"
|
||||
MODEL_ARTIST_PROPERTY = "THÔNG TIN NGHỆ SĨ"
|
||||
MODEL_PLAYLIST_PROPERTY = "THÔNG TIN PLAYLIST"
|
||||
MODEL_ALBUM_PROPERTY = "THÔNG-TIN-ALBUM"
|
||||
MODEL_TRACK_PROPERTY = "THÔNG-TIN-BÀI"
|
||||
MODEL_VIDEO_PROPERTY = "THÔNG-TIN-VIDEO"
|
||||
MODEL_ARTIST_PROPERTY = "THÔNG-TIN-NGHỆ-SĨ"
|
||||
MODEL_PLAYLIST_PROPERTY = "THÔNG-TIN-DANH-SÁCH-PHÁT"
|
||||
|
||||
MODEL_TITLE = 'Tựa đề'
|
||||
MODEL_TRACK_NUMBER = 'STT Track'
|
||||
MODEL_VIDEO_NUMBER = 'STT Video'
|
||||
MODEL_RELEASE_DATE = 'Ngày phát hành'
|
||||
MODEL_VERSION = 'Phiên bản'
|
||||
MODEL_TITLE = 'Tựa Đề'
|
||||
MODEL_TRACK_NUMBER = 'Số Bài'
|
||||
MODEL_VIDEO_NUMBER = 'Số Video'
|
||||
MODEL_RELEASE_DATE = 'Ngày Phát Hành'
|
||||
MODEL_VERSION = 'Phiên Bản'
|
||||
MODEL_EXPLICIT = 'Explicit'
|
||||
MODEL_ALBUM = 'Album'
|
||||
MODEL_ID = 'ID'
|
||||
|
||||
+194
-75
@@ -4,86 +4,205 @@
|
||||
@File : model.py
|
||||
@Time : 2020/08/08
|
||||
@Author : Yaronzz
|
||||
@Version : 2.0
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
'''
|
||||
import aigpy
|
||||
|
||||
class StreamUrl(object):
|
||||
trackid = None
|
||||
url = None
|
||||
codec = None
|
||||
encryptionKey = None
|
||||
soundQuality = None
|
||||
|
||||
class VideoStreamUrl(object):
|
||||
codec = None
|
||||
resolution = None
|
||||
resolutions = None
|
||||
m3u8Url = None
|
||||
|
||||
class Artist(object):
|
||||
id = None
|
||||
name = None
|
||||
type = None
|
||||
picture = None
|
||||
|
||||
class Album(object):
|
||||
id = None
|
||||
title = None
|
||||
duration = 0
|
||||
numberOfTracks = 0
|
||||
numberOfVideos = 0
|
||||
numberOfVolumes = 0
|
||||
releaseDate = None
|
||||
type = None
|
||||
version = None
|
||||
cover = None
|
||||
explicit = False
|
||||
audioQuality = None
|
||||
artist = Artist()
|
||||
artists = Artist()
|
||||
|
||||
class Track(object):
|
||||
id = None
|
||||
title = None
|
||||
duration = 0
|
||||
trackNumber = 0
|
||||
volumeNumber = 0
|
||||
trackNumberOnPlaylist = 0
|
||||
version = None
|
||||
isrc = None
|
||||
explicit = False
|
||||
audioQuality = None
|
||||
copyRight = None
|
||||
artist = Artist()
|
||||
artists = Artist()
|
||||
album = Album()
|
||||
|
||||
class Video(object):
|
||||
id = None
|
||||
title = None
|
||||
duration = 0
|
||||
imageID = None
|
||||
trackNumber = 0
|
||||
releaseDate = None
|
||||
version = None
|
||||
quality = None
|
||||
explicit = False
|
||||
artist = Artist()
|
||||
artists = Artist()
|
||||
album = Album()
|
||||
|
||||
class Playlist(object):
|
||||
uuid = None
|
||||
title = None
|
||||
numberOfTracks = 0
|
||||
numberOfVideos = 0
|
||||
description = None
|
||||
duration = 0
|
||||
image = None
|
||||
squareImage = None
|
||||
class StreamUrl(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.trackid = None
|
||||
self.url = None
|
||||
self.urls = None
|
||||
self.codec = None
|
||||
self.encryptionKey = None
|
||||
self.soundQuality = None
|
||||
|
||||
|
||||
class VideoStreamUrl(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.codec = None
|
||||
self.resolution = None
|
||||
self.resolutions = None
|
||||
self.m3u8Url = None
|
||||
|
||||
|
||||
class Artist(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.id = None
|
||||
self.name = None
|
||||
self.type = None
|
||||
self.picture = None
|
||||
|
||||
|
||||
class Album(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.id = None
|
||||
self.title = None
|
||||
self.duration = 0
|
||||
self.numberOfTracks = 0
|
||||
self.numberOfVideos = 0
|
||||
self.numberOfVolumes = 0
|
||||
self.releaseDate = None
|
||||
self.type = None
|
||||
self.version = None
|
||||
self.cover = None
|
||||
self.explicit = False
|
||||
self.audioQuality = None
|
||||
self.audioModes = None
|
||||
self.artist = Artist()
|
||||
self.artists = Artist()
|
||||
|
||||
|
||||
class Playlist(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.uuid = None
|
||||
self.title = None
|
||||
self.numberOfTracks = 0
|
||||
self.numberOfVideos = 0
|
||||
self.description = None
|
||||
self.duration = 0
|
||||
self.image = None
|
||||
self.squareImage = None
|
||||
|
||||
|
||||
class Track(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.id = None
|
||||
self.title = None
|
||||
self.duration = 0
|
||||
self.trackNumber = 0
|
||||
self.volumeNumber = 0
|
||||
self.trackNumberOnPlaylist = 0
|
||||
self.version = None
|
||||
self.isrc = None
|
||||
self.explicit = False
|
||||
self.audioQuality = None
|
||||
self.copyRight = None
|
||||
self.artist = Artist()
|
||||
self.artists = Artist()
|
||||
self.album = Album()
|
||||
self.allowStreaming = False
|
||||
self.playlist = None
|
||||
|
||||
|
||||
class Video(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.id = None
|
||||
self.title = None
|
||||
self.duration = 0
|
||||
self.imageID = None
|
||||
self.trackNumber = 0
|
||||
self.releaseDate = None
|
||||
self.version = None
|
||||
self.quality = None
|
||||
self.explicit = False
|
||||
self.artist = Artist()
|
||||
self.artists = Artist()
|
||||
self.album = Album()
|
||||
self.allowStreaming = False
|
||||
self.playlist = None
|
||||
|
||||
|
||||
class Mix(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.id = None
|
||||
self.tracks = Track()
|
||||
self.videos = Video()
|
||||
|
||||
|
||||
class Lyrics(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.trackId = None
|
||||
self.lyricsProvider = None
|
||||
self.providerCommontrackId = None
|
||||
self.providerLyricsId = None
|
||||
self.lyrics = None
|
||||
self.subtitles = None
|
||||
|
||||
|
||||
class SearchDataBase(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.limit = 0
|
||||
self.offset = 0
|
||||
self.totalNumberOfItems = 0
|
||||
|
||||
|
||||
class SearchAlbums(SearchDataBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.items = Album()
|
||||
|
||||
|
||||
class SearchArtists(SearchDataBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.items = Artist()
|
||||
|
||||
|
||||
class SearchTracks(SearchDataBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.items = Track()
|
||||
|
||||
|
||||
class SearchVideos(SearchDataBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.items = Video()
|
||||
|
||||
|
||||
class SearchPlaylists(SearchDataBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.items = Playlist()
|
||||
|
||||
|
||||
class SearchResult(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.artists = SearchArtists()
|
||||
self.albums = SearchAlbums()
|
||||
self.tracks = SearchTracks()
|
||||
self.videos = SearchVideos()
|
||||
self.playlists = SearchPlaylists()
|
||||
|
||||
|
||||
class LoginKey(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.deviceCode = None
|
||||
self.userCode = None
|
||||
self.verificationUrl = None
|
||||
self.authCheckTimeout = None
|
||||
self.authCheckInterval = None
|
||||
self.userId = None
|
||||
self.countryCode = None
|
||||
self.accessToken = None
|
||||
self.refreshToken = None
|
||||
self.expiresIn = None
|
||||
|
||||
|
||||
class StreamRespond(aigpy.model.ModelBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.trackid = None
|
||||
self.videoid = None
|
||||
self.streamType = None
|
||||
self.assetPresentation = None
|
||||
self.audioMode = None
|
||||
self.audioQuality = None
|
||||
self.videoQuality = None
|
||||
self.manifestMimeType = None
|
||||
self.manifest = None
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
@File : paths.py
|
||||
@Date : 2022/06/10
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import os
|
||||
import aigpy
|
||||
import datetime
|
||||
|
||||
from tidal import *
|
||||
from settings import *
|
||||
|
||||
|
||||
def __fixPath__(name: str):
|
||||
return aigpy.path.replaceLimitChar(name, '-').strip()
|
||||
|
||||
|
||||
def __getYear__(releaseDate: str):
|
||||
if releaseDate is None or releaseDate == '':
|
||||
return ''
|
||||
return aigpy.string.getSubOnlyEnd(releaseDate, '-')
|
||||
|
||||
|
||||
def __getDurationStr__(seconds):
|
||||
time_string = str(datetime.timedelta(seconds=seconds))
|
||||
if time_string.startswith('0:'):
|
||||
time_string = time_string[2:]
|
||||
return time_string
|
||||
|
||||
|
||||
def __getExtension__(stream: StreamUrl):
|
||||
if '.flac' in stream.url:
|
||||
return '.flac'
|
||||
if '.mp4' in stream.url:
|
||||
if 'ac4' in stream.codec or 'mha1' in stream.codec:
|
||||
return '.mp4'
|
||||
elif 'flac' in stream.codec:
|
||||
return '.flac'
|
||||
return '.m4a'
|
||||
return '.m4a'
|
||||
|
||||
|
||||
def getAlbumPath(album):
|
||||
artistName = __fixPath__(TIDAL_API.getArtistsName(album.artists))
|
||||
albumArtistName = __fixPath__(album.artist.name) if album.artist is not None else ""
|
||||
|
||||
# album folder pre: [ME]
|
||||
flag = TIDAL_API.getFlag(album, Type.Album, True, "")
|
||||
if SETTINGS.audioQuality != AudioQuality.Master and SETTINGS.audioQuality != AudioQuality.Max:
|
||||
flag = flag.replace("M", "")
|
||||
if flag != "":
|
||||
flag = "[" + flag + "] "
|
||||
|
||||
# album and addyear
|
||||
albumName = __fixPath__(album.title)
|
||||
year = __getYear__(album.releaseDate)
|
||||
|
||||
# retpath
|
||||
retpath = SETTINGS.albumFolderFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = SETTINGS.getDefaultAlbumFolderFormat()
|
||||
retpath = retpath.replace(R"{ArtistName}", artistName)
|
||||
retpath = retpath.replace(R"{AlbumArtistName}", albumArtistName)
|
||||
retpath = retpath.replace(R"{Flag}", flag)
|
||||
retpath = retpath.replace(R"{AlbumID}", str(album.id))
|
||||
retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
retpath = retpath.replace(R"{AlbumTitle}", albumName)
|
||||
retpath = retpath.replace(R"{AudioQuality}", album.audioQuality)
|
||||
retpath = retpath.replace(R"{DurationSeconds}", str(album.duration))
|
||||
retpath = retpath.replace(R"{Duration}", __getDurationStr__(album.duration))
|
||||
retpath = retpath.replace(R"{NumberOfTracks}", str(album.numberOfTracks))
|
||||
retpath = retpath.replace(R"{NumberOfVideos}", str(album.numberOfVideos))
|
||||
retpath = retpath.replace(R"{NumberOfVolumes}", str(album.numberOfVolumes))
|
||||
retpath = retpath.replace(R"{ReleaseDate}", str(album.releaseDate))
|
||||
retpath = retpath.replace(R"{RecordType}", album.type)
|
||||
retpath = retpath.replace(R"{None}", "")
|
||||
retpath = retpath.strip()
|
||||
return f"{SETTINGS.downloadPath}/{retpath}"
|
||||
|
||||
def getPlaylistPath(playlist):
|
||||
playlistName = __fixPath__(playlist.title)
|
||||
|
||||
# retpath
|
||||
retpath = SETTINGS.playlistFolderFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = SETTINGS.getDefaultPlaylistFolderFormat()
|
||||
retpath = retpath.replace(R"{PlaylistUUID}", str(playlist.uuid))
|
||||
retpath = retpath.replace(R"{PlaylistName}", playlistName)
|
||||
return f"{SETTINGS.downloadPath}/{retpath}"
|
||||
|
||||
|
||||
def getTrackPath(track, stream, album=None, playlist=None):
|
||||
base = './'
|
||||
number = str(track.trackNumber).rjust(2, '0')
|
||||
if album is not None:
|
||||
base = getAlbumPath(album)
|
||||
if album.numberOfVolumes > 1:
|
||||
base += f'/CD{str(track.volumeNumber)}'
|
||||
|
||||
if playlist is not None and SETTINGS.usePlaylistFolder:
|
||||
base = getPlaylistPath(playlist)
|
||||
number = str(track.trackNumberOnPlaylist).rjust(2, '0')
|
||||
|
||||
# artist
|
||||
artists = __fixPath__(TIDAL_API.getArtistsName(track.artists))
|
||||
artist = __fixPath__(track.artist.name) if track.artist is not None else ""
|
||||
|
||||
# title
|
||||
title = __fixPath__(track.title)
|
||||
if not aigpy.string.isNull(track.version):
|
||||
title += f' ({__fixPath__(track.version)})'
|
||||
|
||||
# explicit
|
||||
explicit = "(Explicit)" if track.explicit else ''
|
||||
|
||||
# album and addyear
|
||||
albumName = __fixPath__(album.title) if album is not None else ''
|
||||
year = __getYear__(album.releaseDate) if album is not None else ''
|
||||
|
||||
# extension
|
||||
extension = __getExtension__(stream)
|
||||
|
||||
retpath = SETTINGS.trackFileFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = SETTINGS.getDefaultTrackFileFormat()
|
||||
retpath = retpath.replace(R"{TrackNumber}", number)
|
||||
retpath = retpath.replace(R"{ArtistName}", artist)
|
||||
retpath = retpath.replace(R"{ArtistsName}", artists)
|
||||
retpath = retpath.replace(R"{TrackTitle}", title)
|
||||
retpath = retpath.replace(R"{ExplicitFlag}", explicit)
|
||||
retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
retpath = retpath.replace(R"{AlbumTitle}", albumName)
|
||||
retpath = retpath.replace(R"{AudioQuality}", track.audioQuality)
|
||||
retpath = retpath.replace(R"{DurationSeconds}", str(track.duration))
|
||||
retpath = retpath.replace(R"{Duration}", __getDurationStr__(track.duration))
|
||||
retpath = retpath.replace(R"{TrackID}", str(track.id))
|
||||
retpath = retpath.strip()
|
||||
return f"{base}/{retpath}{extension}"
|
||||
|
||||
|
||||
def getVideoPath(video, album=None, playlist=None):
|
||||
base = SETTINGS.downloadPath + '/Video/'
|
||||
if album is not None and album.title is not None:
|
||||
base = getAlbumPath(album)
|
||||
elif playlist is not None:
|
||||
base = getPlaylistPath(playlist)
|
||||
|
||||
# get number
|
||||
number = str(video.trackNumber).rjust(2, '0')
|
||||
|
||||
# get artist
|
||||
artists = __fixPath__(TIDAL_API.getArtistsName(video.artists))
|
||||
artist = __fixPath__(video.artist.name) if video.artist is not None else ""
|
||||
|
||||
# explicit
|
||||
explicit = "(Explicit)" if video.explicit else ''
|
||||
|
||||
# title and year and extension
|
||||
title = __fixPath__(video.title)
|
||||
year = __getYear__(video.releaseDate)
|
||||
extension = ".mp4"
|
||||
|
||||
retpath = SETTINGS.videoFileFormat
|
||||
if retpath is None or len(retpath) <= 0:
|
||||
retpath = SETTINGS.getDefaultVideoFileFormat()
|
||||
retpath = retpath.replace(R"{VideoNumber}", number)
|
||||
retpath = retpath.replace(R"{ArtistName}", artist)
|
||||
retpath = retpath.replace(R"{ArtistsName}", artists)
|
||||
retpath = retpath.replace(R"{VideoTitle}", title)
|
||||
retpath = retpath.replace(R"{ExplicitFlag}", explicit)
|
||||
retpath = retpath.replace(R"{VideoYear}", year)
|
||||
retpath = retpath.replace(R"{VideoID}", str(video.id))
|
||||
retpath = retpath.strip()
|
||||
return f"{base}/{retpath}{extension}"
|
||||
|
||||
|
||||
def __getHomePath__():
|
||||
if "XDG_CONFIG_HOME" in os.environ:
|
||||
return os.environ['XDG_CONFIG_HOME']
|
||||
elif "HOME" in os.environ:
|
||||
return os.environ['HOME']
|
||||
elif "HOMEDRIVE" in os.environ and "HOMEPATH" in os.environ:
|
||||
return os.environ['HOMEDRIVE'] + os.environ['HOMEPATH']
|
||||
else:
|
||||
return os.path.abspath("./")
|
||||
|
||||
def getLogPath():
|
||||
return __getHomePath__() + '/.tidal-dl.log'
|
||||
|
||||
def getTokenPath():
|
||||
return __getHomePath__() + '/.tidal-dl.token.json'
|
||||
|
||||
def getProfilePath():
|
||||
return __getHomePath__() + '/.tidal-dl.json'
|
||||
+242
-114
@@ -4,17 +4,26 @@
|
||||
@File : printf.py
|
||||
@Time : 2020/08/16
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
@Desc :
|
||||
'''
|
||||
from pickle import GLOBAL
|
||||
import threading
|
||||
import aigpy
|
||||
import logging
|
||||
import prettytable
|
||||
from aigpy.cmdHelper import red, green, blue, yellow, myprint, myinput, TextColor
|
||||
from tidal_dl.lang.language import getLangName, getLang
|
||||
from tidal_dl.settings import Settings
|
||||
from tidal_dl.model import Album, Track, Video, Playlist, Artist
|
||||
|
||||
__LOGO__ = '''
|
||||
import apiKey as apiKey
|
||||
|
||||
from model import *
|
||||
from paths import *
|
||||
from settings import *
|
||||
from lang.language import *
|
||||
|
||||
|
||||
VERSION = '2022.10.31.1'
|
||||
__LOGO__ = f'''
|
||||
/$$$$$$$$ /$$ /$$ /$$ /$$ /$$
|
||||
|__ $$__/|__/ | $$ | $$ | $$| $$
|
||||
| $$ /$$ /$$$$$$$ /$$$$$$ | $$ /$$$$$$$| $$
|
||||
@@ -23,159 +32,278 @@ __LOGO__ = '''
|
||||
| $$ | $$| $$ | $$ /$$__ $$| $$ | $$ | $$| $$
|
||||
| $$ | $$| $$$$$$$| $$$$$$$| $$ | $$$$$$$| $$
|
||||
|__/ |__/ \_______/ \_______/|__/ \_______/|__/
|
||||
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader
|
||||
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader
|
||||
|
||||
{VERSION}
|
||||
'''
|
||||
VERSION = '2020.10.22.1'
|
||||
|
||||
print_mutex = threading.Lock()
|
||||
|
||||
|
||||
class Printf(object):
|
||||
|
||||
@staticmethod
|
||||
def logo():
|
||||
print(__LOGO__)
|
||||
print(' v' + VERSION)
|
||||
logging.info(__LOGO__)
|
||||
|
||||
@staticmethod
|
||||
def __gettable__(columns, rows):
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = list(aigpy.cmd.green(item) for item in columns)
|
||||
tb.align = 'l'
|
||||
for item in rows:
|
||||
tb.add_row(item)
|
||||
return tb
|
||||
|
||||
@staticmethod
|
||||
def usage():
|
||||
print("=============TIDAL-DL HELP==============")
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green("OPTION"), green("DESC")]
|
||||
tb.align = 'l'
|
||||
tb.add_row(["-h or --help", "show help-message"])
|
||||
tb.add_row(["-v or --version", "show version"])
|
||||
tb.add_row(["-o or --output", "download path"])
|
||||
tb.add_row(["-l or --link", "url/id/filePath"])
|
||||
tb.add_row(["-q or --quality", "track quality('Normal','High,'HiFi','Master')"])
|
||||
tb.add_row(["-r or --resolution", "video resolution('P1080', 'P720', 'P480', 'P360')"])
|
||||
#tb.add_row(["-u or --username", "account-email"])
|
||||
#tb.add_row(["-p or --password", "account-password"])
|
||||
#tb.add_row(["-a or --accessToken", "account-accessToken"])
|
||||
tb = Printf.__gettable__(["OPTION", "DESC"], [
|
||||
["-h or --help", "show help-message"],
|
||||
["-v or --version", "show version"],
|
||||
["-g or --gui", "show simple-gui"],
|
||||
["-o or --output", "download path"],
|
||||
["-l or --link", "url/id/filePath"],
|
||||
["-q or --quality", "track quality('Normal','High,'HiFi','Master')"],
|
||||
["-r or --resolution", "video resolution('P1080', 'P720', 'P480', 'P360')"]
|
||||
])
|
||||
print(tb)
|
||||
|
||||
@staticmethod
|
||||
def settings(data:Settings):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.SETTING), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.SETTING_DOWNLOAD_PATH, data.downloadPath])
|
||||
tb.add_row([LANG.SETTING_ONLY_M4A, data.onlyM4a])
|
||||
# tb.add_row([LANG.SETTING_ADD_EXPLICIT_TAG, data.addExplicitTag])
|
||||
# tb.add_row([LANG.SETTING_ADD_HYPHEN, data.addHyphen])
|
||||
# tb.add_row([LANG.SETTING_ADD_YEAR, data.addYear])
|
||||
# tb.add_row([LANG.SETTING_USE_TRACK_NUM, data.useTrackNumber])
|
||||
tb.add_row([LANG.SETTING_AUDIO_QUALITY, data.audioQuality])
|
||||
tb.add_row([LANG.SETTING_VIDEO_QUALITY, data.videoQuality])
|
||||
tb.add_row([LANG.SETTING_CHECK_EXIST, data.checkExist])
|
||||
tb.add_row([LANG.SETTING_SHOW_PROGRESS, data.showProgress])
|
||||
# tb.add_row([LANG.SETTING_ARTIST_BEFORE_TITLE, data.artistBeforeTitle])
|
||||
# tb.add_row([LANG.SETTING_ALBUMID_BEFORE_FOLDER, data.addAlbumIDBeforeFolder])
|
||||
tb.add_row([LANG.SETTING_INCLUDE_EP, data.includeEP])
|
||||
tb.add_row([LANG.SETTING_SAVE_COVERS, data.saveCovers])
|
||||
tb.add_row([LANG.SETTING_LANGUAGE, getLangName(data.language)])
|
||||
tb.add_row([LANG.SETTING_USE_PLAYLIST_FOLDER, data.usePlaylistFolder])
|
||||
tb.add_row([LANG.SETTING_MULITHREAD_DOWNLOAD, data.multiThreadDownload])
|
||||
tb.add_row([LANG.SETTING_ALBUM_FOLDER_FORMAT, data.albumFolderFormat])
|
||||
tb.add_row([LANG.SETTING_TRACK_FILE_FORMAT, data.trackFileFormat])
|
||||
def checkVersion():
|
||||
onlineVer = aigpy.pip.getLastVersion('tidal-dl')
|
||||
if onlineVer is not None:
|
||||
icmp = aigpy.system.cmpVersion(onlineVer, VERSION)
|
||||
if icmp > 0:
|
||||
Printf.info(LANG.select.PRINT_LATEST_VERSION + ' ' + onlineVer)
|
||||
|
||||
@staticmethod
|
||||
def settings():
|
||||
data = SETTINGS
|
||||
tb = Printf.__gettable__([LANG.select.SETTING, LANG.select.VALUE], [
|
||||
#settings - path and format
|
||||
[LANG.select.SETTING_PATH, getProfilePath()],
|
||||
[LANG.select.SETTING_DOWNLOAD_PATH, data.downloadPath],
|
||||
[LANG.select.SETTING_ALBUM_FOLDER_FORMAT, data.albumFolderFormat],
|
||||
[LANG.select.SETTING_PLAYLIST_FOLDER_FORMAT, data.playlistFolderFormat],
|
||||
[LANG.select.SETTING_TRACK_FILE_FORMAT, data.trackFileFormat],
|
||||
[LANG.select.SETTING_VIDEO_FILE_FORMAT, data.videoFileFormat],
|
||||
|
||||
#settings - quality
|
||||
[LANG.select.SETTING_AUDIO_QUALITY, data.audioQuality],
|
||||
[LANG.select.SETTING_VIDEO_QUALITY, data.videoQuality],
|
||||
|
||||
#settings - else
|
||||
[LANG.select.SETTING_USE_PLAYLIST_FOLDER, data.usePlaylistFolder],
|
||||
[LANG.select.SETTING_CHECK_EXIST, data.checkExist],
|
||||
[LANG.select.SETTING_SHOW_PROGRESS, data.showProgress],
|
||||
[LANG.select.SETTING_SHOW_TRACKINFO, data.showTrackInfo],
|
||||
[LANG.select.SETTING_SAVE_ALBUMINFO, data.saveAlbumInfo],
|
||||
[LANG.select.SETTING_DOWNLOAD_VIDEOS, data.downloadVideos],
|
||||
[LANG.select.SETTING_SAVE_COVERS, data.saveCovers],
|
||||
[LANG.select.SETTING_INCLUDE_EP, data.includeEP],
|
||||
[LANG.select.SETTING_LANGUAGE, LANG.getLangName(data.language)],
|
||||
[LANG.select.SETTING_ADD_LRC_FILE, data.lyricFile],
|
||||
[LANG.select.SETTING_MULITHREAD_DOWNLOAD, data.multiThread],
|
||||
[LANG.select.SETTING_APIKEY, f"[{data.apiKeyIndex}]" + apiKey.getItem(data.apiKeyIndex)['formats']],
|
||||
[LANG.select.SETTING_DOWNLOAD_DELAY, data.downloadDelay],
|
||||
])
|
||||
print(tb)
|
||||
|
||||
@staticmethod
|
||||
def choices():
|
||||
LANG = getLang()
|
||||
print("====================================================")
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [LANG.CHOICE, LANG.FUNCTION]
|
||||
tb.align = 'l'
|
||||
tb = Printf.__gettable__([LANG.select.CHOICE, LANG.select.FUNCTION], [
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '0':"), LANG.select.CHOICE_EXIT],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '1':"), LANG.select.CHOICE_LOGIN],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '2':"), LANG.select.CHOICE_LOGOUT],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '3':"), LANG.select.CHOICE_SET_ACCESS_TOKEN],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '4':"), LANG.select.CHOICE_SETTINGS + '-Path'],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '5':"), LANG.select.CHOICE_SETTINGS + '-Quality'],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '6':"), LANG.select.CHOICE_SETTINGS + '-Else'],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER + " '7':"), LANG.select.CHOICE_APIKEY],
|
||||
[aigpy.cmd.green(LANG.select.CHOICE_ENTER_URLID), LANG.select.CHOICE_DOWNLOAD_BY_URL],
|
||||
])
|
||||
tb.set_style(prettytable.PLAIN_COLUMNS)
|
||||
tb.add_row([green(LANG.CHOICE_ENTER + " '0':"), LANG.CHOICE_EXIT])
|
||||
tb.add_row([green(LANG.CHOICE_ENTER + " '1':"), LANG.CHOICE_LOGIN])
|
||||
tb.add_row([green(LANG.CHOICE_ENTER + " '2':"), LANG.CHOICE_SETTINGS])
|
||||
#tb.add_row([green(LANG.CHOICE_ENTER + " '3':"), LANG.CHOICE_SET_ACCESS_TOKEN])
|
||||
tb.add_row([green(LANG.CHOICE_ENTER_URLID), LANG.CHOICE_DOWNLOAD_BY_URL])
|
||||
print(tb)
|
||||
print("====================================================")
|
||||
|
||||
@staticmethod
|
||||
def enter(string):
|
||||
myprint(string, TextColor.Yellow, None)
|
||||
ret = myinput("")
|
||||
aigpy.cmd.colorPrint(string, aigpy.cmd.TextColor.Yellow, None)
|
||||
ret = input("")
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def enterBool(string):
|
||||
aigpy.cmd.colorPrint(string, aigpy.cmd.TextColor.Yellow, None)
|
||||
ret = input("")
|
||||
return ret == '1'
|
||||
|
||||
@staticmethod
|
||||
def enterPath(string, errmsg, retWord='0', default=""):
|
||||
while True:
|
||||
ret = aigpy.cmd.inputPath(aigpy.cmd.yellow(string), retWord)
|
||||
if ret == retWord:
|
||||
return default
|
||||
elif ret == "":
|
||||
print(aigpy.cmd.red(LANG.select.PRINT_ERR + " ") + errmsg)
|
||||
else:
|
||||
break
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def enterLimit(string, errmsg, limit=[]):
|
||||
while True:
|
||||
ret = aigpy.cmd.inputLimit(aigpy.cmd.yellow(string), limit)
|
||||
if ret is None:
|
||||
print(aigpy.cmd.red(LANG.select.PRINT_ERR + " ") + errmsg)
|
||||
else:
|
||||
break
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def enterFormat(string, current, default):
|
||||
ret = Printf.enter(string)
|
||||
if ret == '0' or aigpy.string.isNull(ret):
|
||||
return current
|
||||
if ret.lower() == 'default':
|
||||
return default
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def err(string):
|
||||
LANG = getLang()
|
||||
print(red(LANG.PRINT_ERR + " ") + string)
|
||||
|
||||
global print_mutex
|
||||
print_mutex.acquire()
|
||||
print(aigpy.cmd.red(LANG.select.PRINT_ERR + " ") + string)
|
||||
# logging.error(string)
|
||||
print_mutex.release()
|
||||
|
||||
@staticmethod
|
||||
def info(string):
|
||||
LANG = getLang()
|
||||
print(blue(LANG.PRINT_INFO + " ") + string)
|
||||
global print_mutex
|
||||
print_mutex.acquire()
|
||||
print(aigpy.cmd.blue(LANG.select.PRINT_INFO + " ") + string)
|
||||
print_mutex.release()
|
||||
|
||||
@staticmethod
|
||||
def success(string):
|
||||
LANG = getLang()
|
||||
print(green(LANG.PRINT_SUCCESS + " ") + string)
|
||||
global print_mutex
|
||||
print_mutex.acquire()
|
||||
print(aigpy.cmd.green(LANG.select.PRINT_SUCCESS + " ") + string)
|
||||
print_mutex.release()
|
||||
|
||||
@staticmethod
|
||||
def album(data: Album):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.MODEL_ALBUM_PROPERTY), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.MODEL_TITLE, data.title])
|
||||
tb.add_row(["ID", data.id])
|
||||
tb.add_row([LANG.MODEL_TRACK_NUMBER, data.numberOfTracks])
|
||||
tb.add_row([LANG.MODEL_VIDEO_NUMBER, data.numberOfVideos])
|
||||
tb.add_row([LANG.MODEL_RELEASE_DATE, data.releaseDate])
|
||||
tb.add_row([LANG.MODEL_VERSION, data.version])
|
||||
tb.add_row([LANG.MODEL_EXPLICIT, data.explicit])
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_ALBUM_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_TITLE, data.title],
|
||||
["ID", data.id],
|
||||
[LANG.select.MODEL_TRACK_NUMBER, data.numberOfTracks],
|
||||
[LANG.select.MODEL_VIDEO_NUMBER, data.numberOfVideos],
|
||||
[LANG.select.MODEL_RELEASE_DATE, data.releaseDate],
|
||||
[LANG.select.MODEL_VERSION, data.version],
|
||||
[LANG.select.MODEL_EXPLICIT, data.explicit],
|
||||
])
|
||||
print(tb)
|
||||
logging.info("====album " + str(data.id) + "====\n" +
|
||||
"title:" + data.title + "\n" +
|
||||
"track num:" + str(data.numberOfTracks) + "\n" +
|
||||
"video num:" + str(data.numberOfVideos) + "\n" +
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def track(data:Track):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.MODEL_TRACK_PROPERTY), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.MODEL_TITLE, data.title])
|
||||
tb.add_row(["ID", data.id])
|
||||
tb.add_row([LANG.MODEL_ALBUM, data.album.title])
|
||||
tb.add_row([LANG.MODEL_VERSION, data.version])
|
||||
tb.add_row([LANG.MODEL_EXPLICIT, data.explicit])
|
||||
print(tb)
|
||||
|
||||
@staticmethod
|
||||
def video(data):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.MODEL_VIDEO_PROPERTY), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.MODEL_TITLE, data.title])
|
||||
tb.add_row([LANG.MODEL_ALBUM, data.album.title if data.album != None else None])
|
||||
tb.add_row([LANG.MODEL_VERSION, data.version])
|
||||
tb.add_row([LANG.MODEL_EXPLICIT, data.explicit])
|
||||
def track(data: Track, stream: StreamUrl = None):
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_TRACK_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_TITLE, data.title],
|
||||
["ID", data.id],
|
||||
[LANG.select.MODEL_ALBUM, data.album.title],
|
||||
[LANG.select.MODEL_VERSION, data.version],
|
||||
[LANG.select.MODEL_EXPLICIT, data.explicit],
|
||||
["Max-Q", data.audioQuality],
|
||||
])
|
||||
if stream is not None:
|
||||
tb.add_row(["Get-Q", str(stream.soundQuality)])
|
||||
tb.add_row(["Get-Codec", str(stream.codec)])
|
||||
print(tb)
|
||||
logging.info("====track " + str(data.id) + "====\n" + \
|
||||
"title:" + data.title + "\n" + \
|
||||
"version:" + str(data.version) + "\n" + \
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def artist(data:Artist, num):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.MODEL_ARTIST_PROPERTY), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.MODEL_ID, data.id])
|
||||
tb.add_row([LANG.MODEL_NAME, data.name])
|
||||
tb.add_row(["Number of albums", num])
|
||||
tb.add_row([LANG.MODEL_TYPE, str(data.type)])
|
||||
def video(data: Video, stream: VideoStreamUrl = None):
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_VIDEO_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_TITLE, data.title],
|
||||
[LANG.select.MODEL_ALBUM, data.album.title if data.album != None else None],
|
||||
[LANG.select.MODEL_VERSION, data.version],
|
||||
[LANG.select.MODEL_EXPLICIT, data.explicit],
|
||||
["Max-Q", data.quality],
|
||||
])
|
||||
if stream is not None:
|
||||
tb.add_row(["Get-Q", str(stream.resolution)])
|
||||
tb.add_row(["Get-Codec", str(stream.codec)])
|
||||
print(tb)
|
||||
logging.info("====video " + str(data.id) + "====\n" +
|
||||
"title:" + data.title + "\n" +
|
||||
"version:" + str(data.version) + "\n" +
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def artist(data: Artist, num):
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_ARTIST_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_ID, data.id],
|
||||
[LANG.select.MODEL_NAME, data.name],
|
||||
["Number of albums", num],
|
||||
[LANG.select.MODEL_TYPE, str(data.type)],
|
||||
])
|
||||
print(tb)
|
||||
logging.info("====artist " + str(data.id) + "====\n" +
|
||||
"name:" + data.name + "\n" +
|
||||
"album num:" + str(num) + "\n" +
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def playlist(data):
|
||||
LANG = getLang()
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [green(LANG.MODEL_PLAYLIST_PROPERTY), green(LANG.VALUE)]
|
||||
tb.align = 'l'
|
||||
tb.add_row([LANG.MODEL_TITLE, data.title])
|
||||
tb.add_row([LANG.MODEL_TRACK_NUMBER, data.numberOfTracks])
|
||||
tb.add_row([LANG.MODEL_VIDEO_NUMBER, data.numberOfVideos])
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_PLAYLIST_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_TITLE, data.title],
|
||||
[LANG.select.MODEL_TRACK_NUMBER, data.numberOfTracks],
|
||||
[LANG.select.MODEL_VIDEO_NUMBER, data.numberOfVideos],
|
||||
])
|
||||
print(tb)
|
||||
logging.info("====playlist " + str(data.uuid) + "====\n" +
|
||||
"title:" + data.title + "\n" +
|
||||
"track num:" + str(data.numberOfTracks) + "\n" +
|
||||
"video num:" + str(data.numberOfVideos) + "\n" +
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def mix(data):
|
||||
tb = Printf.__gettable__([LANG.select.MODEL_PLAYLIST_PROPERTY, LANG.select.VALUE], [
|
||||
[LANG.select.MODEL_ID, data.id],
|
||||
[LANG.select.MODEL_TRACK_NUMBER, len(data.tracks)],
|
||||
[LANG.select.MODEL_VIDEO_NUMBER, len(data.videos)],
|
||||
])
|
||||
print(tb)
|
||||
logging.info("====Mix " + str(data.id) + "====\n" +
|
||||
"track num:" + str(len(data.tracks)) + "\n" +
|
||||
"video num:" + str(len(data.videos)) + "\n" +
|
||||
"==================================")
|
||||
|
||||
@staticmethod
|
||||
def apikeys(items):
|
||||
print("-------------API-KEYS---------------")
|
||||
tb = prettytable.PrettyTable()
|
||||
tb.field_names = [aigpy.cmd.green('Index'),
|
||||
aigpy.cmd.green('Valid'),
|
||||
aigpy.cmd.green('Platform'),
|
||||
aigpy.cmd.green('Formats'), ]
|
||||
tb.align = 'l'
|
||||
|
||||
for index, item in enumerate(items):
|
||||
tb.add_row([str(index),
|
||||
aigpy.cmd.green('True') if item["valid"] == "True" else aigpy.cmd.red('False'),
|
||||
item["platform"],
|
||||
item["formats"]])
|
||||
print(tb)
|
||||
|
||||
+109
-100
@@ -2,122 +2,131 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@File : settings.py
|
||||
@Time : 2020/11/05
|
||||
@Time : 2020/11/08
|
||||
@Author : Yaronzz
|
||||
@Version : 1.1
|
||||
@Version : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
@Desc :
|
||||
'''
|
||||
import json
|
||||
import aigpy
|
||||
import base64
|
||||
from aigpy.fileHelper import getFileContent, write
|
||||
from aigpy.modelHelper import dictToModel, modelToDict
|
||||
from tidal_dl.enum import AudioQuality, VideoQuality
|
||||
|
||||
from lang.language import *
|
||||
from enums import *
|
||||
|
||||
|
||||
class Settings(aigpy.model.ModelBase):
|
||||
checkExist = True
|
||||
includeEP = True
|
||||
saveCovers = True
|
||||
language = 0
|
||||
lyricFile = False
|
||||
apiKeyIndex = 0
|
||||
showProgress = True
|
||||
showTrackInfo = True
|
||||
saveAlbumInfo = False
|
||||
downloadVideos = True
|
||||
multiThread = False
|
||||
downloadDelay = True
|
||||
|
||||
def __encode__(string):
|
||||
sw = bytes(string, 'utf-8')
|
||||
st = base64.b64encode(sw)
|
||||
return st
|
||||
downloadPath = "./download/"
|
||||
audioQuality = AudioQuality.Normal
|
||||
videoQuality = VideoQuality.P360
|
||||
usePlaylistFolder = True
|
||||
albumFolderFormat = R"{ArtistName}/{Flag} {AlbumTitle} [{AlbumID}] [{AlbumYear}]"
|
||||
playlistFolderFormat = R"Playlist/{PlaylistName} [{PlaylistUUID}]"
|
||||
trackFileFormat = R"{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
videoFileFormat = R"{VideoNumber} - {ArtistName} - {VideoTitle}{ExplicitFlag}"
|
||||
|
||||
def __decode__(string):
|
||||
try:
|
||||
sr = base64.b64decode(string)
|
||||
st = sr.decode()
|
||||
return st
|
||||
except:
|
||||
return string
|
||||
def getDefaultPathFormat(self, type: Type):
|
||||
if type == Type.Album:
|
||||
return R"{ArtistName}/{Flag} {AlbumTitle} [{AlbumID}] [{AlbumYear}]"
|
||||
elif type == Type.Playlist:
|
||||
return R"Playlist/{PlaylistName} [{PlaylistUUID}]"
|
||||
elif type == Type.Track:
|
||||
return R"{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
elif type == Type.Video:
|
||||
return R"{VideoNumber} - {ArtistName} - {VideoTitle}{ExplicitFlag}"
|
||||
return ""
|
||||
|
||||
class UserSettings(object):
|
||||
def getAudioQuality(self, value):
|
||||
for item in AudioQuality:
|
||||
if item.name == value:
|
||||
return item
|
||||
return AudioQuality.Normal
|
||||
|
||||
def getVideoQuality(self, value):
|
||||
for item in VideoQuality:
|
||||
if item.name == value:
|
||||
return item
|
||||
return VideoQuality.P360
|
||||
|
||||
def read(self, path):
|
||||
self._path_ = path
|
||||
txt = aigpy.file.getContent(self._path_)
|
||||
if len(txt) > 0:
|
||||
data = json.loads(txt)
|
||||
if aigpy.model.dictToModel(data, self) is None:
|
||||
return
|
||||
|
||||
self.audioQuality = self.getAudioQuality(self.audioQuality)
|
||||
self.videoQuality = self.getVideoQuality(self.videoQuality)
|
||||
|
||||
if self.albumFolderFormat is None:
|
||||
self.albumFolderFormat = self.getDefaultPathFormat(Type.Album)
|
||||
if self.trackFileFormat is None:
|
||||
self.trackFileFormat = self.getDefaultPathFormat(Type.Track)
|
||||
if self.playlistFolderFormat is None:
|
||||
self.playlistFolderFormat = self.getDefaultPathFormat(Type.Playlist)
|
||||
if self.videoFileFormat is None:
|
||||
self.videoFileFormat = self.getDefaultPathFormat(Type.Video)
|
||||
if self.apiKeyIndex is None:
|
||||
self.apiKeyIndex = 0
|
||||
|
||||
LANG.setLang(self.language)
|
||||
|
||||
def save(self):
|
||||
data = aigpy.model.modelToDict(self)
|
||||
data['audioQuality'] = self.audioQuality.name
|
||||
data['videoQuality'] = self.videoQuality.name
|
||||
txt = json.dumps(data)
|
||||
aigpy.file.write(self._path_, txt, 'w+')
|
||||
|
||||
|
||||
class TokenSettings(aigpy.model.ModelBase):
|
||||
userid = None
|
||||
countryCode = None
|
||||
accessToken = None
|
||||
refreshToken = None
|
||||
expiresAfter = 0
|
||||
|
||||
@staticmethod
|
||||
def read():
|
||||
txt = getFileContent('./usersettings.json', True)
|
||||
if txt == "":
|
||||
return UserSettings()
|
||||
txt = __decode__(txt)
|
||||
data = json.loads(txt)
|
||||
ret = dictToModel(data, UserSettings())
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def save(model):
|
||||
data = modelToDict(model)
|
||||
def __encode__(self, string):
|
||||
sw = bytes(string, 'utf-8')
|
||||
st = base64.b64encode(sw)
|
||||
return st
|
||||
|
||||
def __decode__(self, string):
|
||||
try:
|
||||
sr = base64.b64decode(string)
|
||||
st = sr.decode()
|
||||
return st
|
||||
except:
|
||||
return string
|
||||
|
||||
def read(self, path):
|
||||
self._path_ = path
|
||||
txt = aigpy.file.getContent(self._path_)
|
||||
if len(txt) > 0:
|
||||
data = json.loads(self.__decode__(txt))
|
||||
aigpy.model.dictToModel(data, self)
|
||||
|
||||
def save(self):
|
||||
data = aigpy.model.modelToDict(self)
|
||||
txt = json.dumps(data)
|
||||
txt = __encode__(txt)
|
||||
write('./usersettings.json', txt, 'wb')
|
||||
aigpy.file.write(self._path_, self.__encode__(txt), 'wb')
|
||||
|
||||
class Settings(object):
|
||||
downloadPath = "./download/"
|
||||
onlyM4a = False
|
||||
addExplicitTag = True
|
||||
addHyphen = True
|
||||
addYear = False
|
||||
useTrackNumber = True
|
||||
audioQuality = AudioQuality.Normal
|
||||
videoQuality = VideoQuality.P360
|
||||
checkExist = True
|
||||
artistBeforeTitle = False
|
||||
includeEP = True
|
||||
addAlbumIDBeforeFolder = False
|
||||
saveCovers = True
|
||||
language = 0
|
||||
usePlaylistFolder = True
|
||||
multiThreadDownload = True
|
||||
albumFolderFormat = R"{ArtistName}/{Flag} {AlbumTitle} [{AlbumID}] [{AlbumYear}]"
|
||||
trackFileFormat = R"{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
showProgress = True
|
||||
|
||||
@staticmethod
|
||||
def getDefualtAlbumFolderFormat():
|
||||
return R"{ArtistName}/{Flag} {AlbumTitle} [{AlbumID}] [{AlbumYear}]"
|
||||
|
||||
@staticmethod
|
||||
def getDefualtTrackFileFormat():
|
||||
return R"{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
|
||||
@staticmethod
|
||||
def read():
|
||||
txt = getFileContent('./settings.json')
|
||||
if txt == "":
|
||||
return Settings()
|
||||
data = json.loads(txt)
|
||||
ret = dictToModel(data, Settings())
|
||||
ret.audioQuality = Settings.getAudioQuality(ret.audioQuality)
|
||||
ret.videoQuality = Settings.getVideoQuality(ret.videoQuality)
|
||||
ret.usePlaylistFolder = ret.usePlaylistFolder == True or ret.usePlaylistFolder is None
|
||||
ret.multiThreadDownload = ret.multiThreadDownload == True or ret.multiThreadDownload is None
|
||||
if ret.albumFolderFormat is None:
|
||||
ret.albumFolderFormat = Settings.getDefualtAlbumFolderFormat()
|
||||
if ret.trackFileFormat is None:
|
||||
ret.trackFileFormat = Settings.getDefualtTrackFileFormat()
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def save(model):
|
||||
data = modelToDict(model)
|
||||
data['audioQuality'] = model.audioQuality.name
|
||||
data['videoQuality'] = model.videoQuality.name
|
||||
txt = json.dumps(data)
|
||||
write('./settings.json', txt, 'w+')
|
||||
|
||||
@staticmethod
|
||||
def getAudioQuality(value):
|
||||
for item in AudioQuality:
|
||||
if item.name == value:
|
||||
return item
|
||||
return AudioQuality.Normal
|
||||
|
||||
@staticmethod
|
||||
def getVideoQuality(value):
|
||||
for item in VideoQuality:
|
||||
if item.name == value:
|
||||
return item
|
||||
return VideoQuality.P360
|
||||
|
||||
# Singleton
|
||||
SETTINGS = Settings()
|
||||
TOKEN = TokenSettings()
|
||||
|
||||
+346
-255
@@ -4,241 +4,368 @@
|
||||
@File : tidal.py
|
||||
@Time : 2019/02/27
|
||||
@Author : Yaronzz
|
||||
@VERSION : 2.0
|
||||
@VERSION : 3.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc : tidal api
|
||||
'''
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import uuid
|
||||
import time
|
||||
from typing import List
|
||||
from xml.etree import ElementTree
|
||||
|
||||
import requests
|
||||
import json
|
||||
import base64
|
||||
import aigpy.stringHelper as stringHelper
|
||||
import aigpy.systemHelper as systemHelper
|
||||
import aigpy.fileHelper as fileHelper
|
||||
from aigpy.modelHelper import dictToModel
|
||||
from aigpy.stringHelper import isNull
|
||||
from tidal_dl.model import Album, Track, Video, Artist, Playlist, StreamUrl, VideoStreamUrl
|
||||
from tidal_dl.enum import Type, AudioQuality, VideoQuality
|
||||
|
||||
__VERSION__ = '1.9.1'
|
||||
__URL_PRE__ = 'https://api.tidalhifi.com/v1/'
|
||||
__AUTH_URL__ = 'https://auth.tidal.com/v1/oauth2'
|
||||
__API_KEY__ = {'clientId': 'aR7gUaTK1ihpXOEP', 'clientSecret': 'eVWBEkuL2FCjxgjOkR3yK0RYZEbcrMXRc2l8fU3ZCdE='} #known API key for Fire Stick HD(MQA, Dolby Vision enabled)
|
||||
|
||||
class LoginKey(object):
|
||||
def __init__(self):
|
||||
self.deviceCode = None
|
||||
self.userCode = None
|
||||
self.verificationUrl = None
|
||||
self.authCheckTimeout = None
|
||||
self.authCheckInterval = None
|
||||
self.userId = None
|
||||
self.countryCode = None
|
||||
self.accessToken = None
|
||||
self.refreshToken = None
|
||||
self.expiresIn = None
|
||||
|
||||
class __StreamRespon__(object):
|
||||
trackid = None
|
||||
videoid = None
|
||||
streamType = None
|
||||
assetPresentation = None
|
||||
audioMode = None
|
||||
audioQuality = None
|
||||
videoQuality = None
|
||||
manifestMimeType = None
|
||||
manifest = None
|
||||
from model import *
|
||||
from settings import *
|
||||
|
||||
# SSL Warnings | retry number
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
requests.adapters.DEFAULT_RETRIES = 5
|
||||
|
||||
|
||||
class TidalAPI(object):
|
||||
def __init__(self):
|
||||
self.key = LoginKey()
|
||||
self.apiKey = {'clientId': '7m7Ap0JC9j1cOM3n',
|
||||
'clientSecret': 'vRAdA108tlvkJpTsGZS8rGZ7xTlbJ0qaZ2K9saEzsgY='}
|
||||
|
||||
def __get__(self, path, params={}, retry=3):
|
||||
#deprecate the sessionId
|
||||
#header = {'X-Tidal-SessionId': self.key.sessionId}
|
||||
if not isNull(self.key.accessToken):
|
||||
header = {'authorization': 'Bearer {}'.format(self.key.accessToken)}
|
||||
|
||||
def __get__(self, path, params={}, urlpre='https://api.tidalhifi.com/v1/'):
|
||||
header = {}
|
||||
header = {'authorization': f'Bearer {self.key.accessToken}'}
|
||||
params['countryCode'] = self.key.countryCode
|
||||
result = requests.get(__URL_PRE__ + path, headers=header, params=params).json()
|
||||
if 'status' in result:
|
||||
if 'userMessage' in result and result['userMessage'] is not None:
|
||||
return result['userMessage'], None
|
||||
else:
|
||||
return "Get operation err!", None
|
||||
return None, result
|
||||
errmsg = "Get operation err!"
|
||||
for index in range(0, 3):
|
||||
try:
|
||||
respond = requests.get(urlpre + path, headers=header, params=params)
|
||||
if respond.url.find("playbackinfopostpaywall") != -1 and SETTINGS.downloadDelay is not False:
|
||||
# random sleep between 0.5 and 5 seconds and print it
|
||||
sleep_time = random.randint(500, 5000) / 1000
|
||||
print(
|
||||
f"Sleeping for {sleep_time} seconds, to mimic human behaviour and prevent too many requests error")
|
||||
time.sleep(sleep_time)
|
||||
|
||||
def __getItems__(self, path, params={}, retry = 3):
|
||||
if respond.status_code == 429:
|
||||
print('Too many requests, waiting for 20 seconds...')
|
||||
# Loop countdown 20 seconds and print the remaining time
|
||||
for i in range(20, 0, -1):
|
||||
time.sleep(1)
|
||||
print(i, end=' ')
|
||||
print('')
|
||||
continue
|
||||
|
||||
result = json.loads(respond.text)
|
||||
if 'status' not in result:
|
||||
return result
|
||||
|
||||
if 'userMessage' in result and result['userMessage'] is not None:
|
||||
errmsg += result['userMessage']
|
||||
break
|
||||
except Exception as e:
|
||||
if index >= 3:
|
||||
errmsg += respond.text
|
||||
|
||||
raise Exception(errmsg)
|
||||
|
||||
def __getItems__(self, path, params={}):
|
||||
params['limit'] = 50
|
||||
params['offset'] = 0
|
||||
total = 0
|
||||
ret = []
|
||||
while True:
|
||||
msg, data = self.__get__(path, params, retry)
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
num = 0
|
||||
for item in data["items"]:
|
||||
num += 1
|
||||
ret.append(item)
|
||||
data = self.__get__(path, params)
|
||||
if 'totalNumberOfItems' in data:
|
||||
total = data['totalNumberOfItems']
|
||||
if total > 0 and total <= len(ret):
|
||||
return ret
|
||||
|
||||
ret += data["items"]
|
||||
num = len(data["items"])
|
||||
if num < 50:
|
||||
break
|
||||
params['offset'] += num
|
||||
return None, ret
|
||||
return ret
|
||||
|
||||
def __getQualityString__(self, quality:AudioQuality):
|
||||
if quality == AudioQuality.Normal:
|
||||
return "LOW"
|
||||
if quality == AudioQuality.High:
|
||||
return "HIGH"
|
||||
if quality == AudioQuality.HiFi:
|
||||
return "LOSSLESS"
|
||||
return "HI_RES"
|
||||
|
||||
def __getResolutionList__(self, url):
|
||||
ret = []
|
||||
txt = requests.get(url).text
|
||||
array = txt.split("#EXT-X-STREAM-INF")
|
||||
txt = requests.get(url).content.decode('utf-8')
|
||||
# array = txt.split("#EXT-X-STREAM-INF")
|
||||
array = txt.split("#")
|
||||
for item in array:
|
||||
if "RESOLUTION=" not in item:
|
||||
continue
|
||||
if "EXT-X-STREAM-INF:" not in item:
|
||||
continue
|
||||
stream = VideoStreamUrl()
|
||||
stream.codec = stringHelper.getSub(item, "CODECS=\"", "\"")
|
||||
stream.m3u8Url = "http" + stringHelper.getSubOnlyStart(item, "http").strip()
|
||||
stream.resolution = stringHelper.getSub(item, "RESOLUTION=", "http").strip()
|
||||
stream.codec = aigpy.string.getSub(item, "CODECS=\"", "\"")
|
||||
stream.m3u8Url = "http" + aigpy.string.getSubOnlyStart(item, "http").strip()
|
||||
stream.resolution = aigpy.string.getSub(item, "RESOLUTION=", "http").strip()
|
||||
stream.resolution = stream.resolution.split(',')[0]
|
||||
stream.resolutions = stream.resolution.split("x")
|
||||
ret.append(stream)
|
||||
return ret
|
||||
|
||||
def getDeviceCode(self):
|
||||
def __post__(self, path, data, auth=None, urlpre='https://auth.tidal.com/v1/oauth2'):
|
||||
for index in range(3):
|
||||
try:
|
||||
result = requests.post(urlpre + path, data=data, auth=auth, verify=False).json()
|
||||
return result
|
||||
except Exception as e:
|
||||
if index == 2:
|
||||
raise e
|
||||
|
||||
def getDeviceCode(self) -> str:
|
||||
data = {
|
||||
'client_id': __API_KEY__['clientId'],
|
||||
'client_id': self.apiKey['clientId'],
|
||||
'scope': 'r_usr+w_usr+w_sub'
|
||||
}
|
||||
result = requests.post(__AUTH_URL__ + '/device_authorization', data=data).json()
|
||||
}
|
||||
result = self.__post__('/device_authorization', data)
|
||||
if 'status' in result and result['status'] != 200:
|
||||
return "Device authorization failed. Please try again.", False
|
||||
|
||||
raise Exception("Device authorization failed. Please choose another apikey.")
|
||||
|
||||
self.key.deviceCode = result['deviceCode']
|
||||
self.key.userCode = result['userCode']
|
||||
self.key.verificationUrl = result['verificationUri']
|
||||
self.key.authCheckTimeout = result['expiresIn']
|
||||
self.key.authCheckInterval = result['interval']
|
||||
return None, True
|
||||
|
||||
def checkAuthStatus(self):
|
||||
return "http://" + self.key.verificationUrl + "/" + self.key.userCode
|
||||
|
||||
def checkAuthStatus(self) -> bool:
|
||||
data = {
|
||||
'client_id': __API_KEY__['clientId'],
|
||||
'client_id': self.apiKey['clientId'],
|
||||
'device_code': self.key.deviceCode,
|
||||
'grant_type': 'urn:ietf:params:oauth:grant-type:device_code',
|
||||
'scope': 'r_usr+w_usr+w_sub'
|
||||
}
|
||||
result = requests.post(__AUTH_URL__ + '/token', data=data, auth=(__API_KEY__['clientId'], __API_KEY__['clientSecret'])).json()
|
||||
}
|
||||
auth = (self.apiKey['clientId'], self.apiKey['clientSecret'])
|
||||
result = self.__post__('/token', data, auth)
|
||||
if 'status' in result and result['status'] != 200:
|
||||
if result['status'] == 400 and result['sub_status'] == 1002:
|
||||
return "pending", False
|
||||
return False
|
||||
else:
|
||||
return "Error while checking for authorization. Trying again...", False
|
||||
|
||||
#if auth is successful:
|
||||
raise Exception("Error while checking for authorization. Trying again...")
|
||||
|
||||
# if auth is successful:
|
||||
self.key.userId = result['user']['userId']
|
||||
self.key.countryCode = result['user']['countryCode']
|
||||
self.key.accessToken = result['access_token']
|
||||
self.key.refreshToken = result['refresh_token']
|
||||
self.key.expiresIn = result['expires_in']
|
||||
return None, True
|
||||
|
||||
def verifyAccessToken(self, accessToken):
|
||||
return True
|
||||
|
||||
def verifyAccessToken(self, accessToken) -> bool:
|
||||
header = {'authorization': 'Bearer {}'.format(accessToken)}
|
||||
result = requests.get('https://api.tidal.com/v1/sessions', headers=header).json()
|
||||
|
||||
if 'status' in result and result['status'] != 200:
|
||||
return "Login failed!", False
|
||||
return None, True
|
||||
|
||||
def refreshAccessToken(self, refreshToken):
|
||||
return False
|
||||
return True
|
||||
|
||||
def refreshAccessToken(self, refreshToken) -> bool:
|
||||
data = {
|
||||
'client_id': __API_KEY__['clientId'],
|
||||
'client_id': self.apiKey['clientId'],
|
||||
'refresh_token': refreshToken,
|
||||
'grant_type': 'refresh_token',
|
||||
'scope': 'r_usr+w_usr+w_sub'
|
||||
}
|
||||
result = requests.post(__AUTH_URL__ + '/token', data=data, auth=(__API_KEY__['clientId'], __API_KEY__['clientSecret'])).json()
|
||||
}
|
||||
auth = (self.apiKey['clientId'], self.apiKey['clientSecret'])
|
||||
result = self.__post__('/token', data, auth)
|
||||
if 'status' in result and result['status'] != 200:
|
||||
return "Refresh failed. Please log in again.", False
|
||||
|
||||
#if auth is successful:
|
||||
return False
|
||||
|
||||
# if auth is successful:
|
||||
self.key.userId = result['user']['userId']
|
||||
self.key.countryCode = result['user']['countryCode']
|
||||
self.key.accessToken = result['access_token']
|
||||
self.key.expiresIn = result['expires_in']
|
||||
return None, True
|
||||
return True
|
||||
|
||||
def getAlbum(self, id):
|
||||
msg, data = self.__get__('albums/' + str(id))
|
||||
return msg, dictToModel(data, Album())
|
||||
def loginByAccessToken(self, accessToken, userid=None):
|
||||
header = {'authorization': 'Bearer {}'.format(accessToken)}
|
||||
result = requests.get('https://api.tidal.com/v1/sessions', headers=header).json()
|
||||
if 'status' in result and result['status'] != 200:
|
||||
raise Exception("Login failed!")
|
||||
|
||||
def getPlaylist(self, id):
|
||||
msg, data = self.__get__('playlists/' + str(id))
|
||||
return msg, dictToModel(data, Playlist())
|
||||
if not aigpy.string.isNull(userid):
|
||||
if str(result['userId']) != str(userid):
|
||||
raise Exception("User mismatch! Please use your own accesstoken.", )
|
||||
|
||||
def getArtist(self, id):
|
||||
msg, data = self.__get__('artists/' + str(id))
|
||||
return msg, dictToModel(data, Artist())
|
||||
self.key.userId = result['userId']
|
||||
self.key.countryCode = result['countryCode']
|
||||
self.key.accessToken = accessToken
|
||||
|
||||
def getTrack(self, id):
|
||||
msg, data = self.__get__('tracks/' + str(id))
|
||||
return msg, dictToModel(data, Track())
|
||||
return
|
||||
|
||||
def getVideo(self, id):
|
||||
msg, data = self.__get__('videos/' + str(id))
|
||||
return msg, dictToModel(data, Video())
|
||||
def getAlbum(self, id) -> Album:
|
||||
return aigpy.model.dictToModel(self.__get__('albums/' + str(id)), Album())
|
||||
|
||||
def getItems(self, id, type:Type):
|
||||
def getPlaylist(self, id) -> Playlist:
|
||||
return aigpy.model.dictToModel(self.__get__('playlists/' + str(id)), Playlist())
|
||||
|
||||
def getPlaylistSelf(self) -> List[Playlist]:
|
||||
ret = self.__get__(f'users/{self.key.userId}/playlists')
|
||||
playlists = []
|
||||
for item in ret['items']:
|
||||
playlists.append(aigpy.model.dictToModel(item, Playlist()))
|
||||
return playlists
|
||||
|
||||
def getArtist(self, id) -> Artist:
|
||||
return aigpy.model.dictToModel(self.__get__('artists/' + str(id)), Artist())
|
||||
|
||||
def getTrack(self, id) -> Track:
|
||||
return aigpy.model.dictToModel(self.__get__('tracks/' + str(id)), Track())
|
||||
|
||||
def getVideo(self, id) -> Video:
|
||||
return aigpy.model.dictToModel(self.__get__('videos/' + str(id)), Video())
|
||||
|
||||
def getMix(self, id) -> Mix:
|
||||
mix = Mix()
|
||||
mix.id = id
|
||||
mix.tracks, mix.videos = self.getItems(id, Type.Mix)
|
||||
return None, mix
|
||||
|
||||
def getTypeData(self, id, type: Type):
|
||||
if type == Type.Album:
|
||||
return self.getAlbum(id)
|
||||
if type == Type.Artist:
|
||||
return self.getArtist(id)
|
||||
if type == Type.Track:
|
||||
return self.getTrack(id)
|
||||
if type == Type.Video:
|
||||
return self.getVideo(id)
|
||||
if type == Type.Playlist:
|
||||
msg, data = self.__getItems__('playlists/' + str(id) + "/items")
|
||||
return self.getPlaylist(id)
|
||||
if type == Type.Mix:
|
||||
return self.getMix(id)
|
||||
return None
|
||||
|
||||
def search(self, text: str, type: Type, offset: int = 0, limit: int = 10) -> SearchResult:
|
||||
typeStr = type.name.upper() + "S"
|
||||
|
||||
if type == Type.Null:
|
||||
typeStr = "ARTISTS,ALBUMS,TRACKS,VIDEOS,PLAYLISTS"
|
||||
|
||||
params = {"query": text,
|
||||
"offset": offset,
|
||||
"limit": limit,
|
||||
"types": typeStr}
|
||||
return aigpy.model.dictToModel(self.__get__('search', params=params), SearchResult())
|
||||
|
||||
def getSearchResultItems(self, result: SearchResult, type: Type):
|
||||
if type == Type.Track:
|
||||
return result.tracks.items
|
||||
if type == Type.Video:
|
||||
return result.videos.items
|
||||
if type == Type.Album:
|
||||
return result.albums.items
|
||||
if type == Type.Artist:
|
||||
return result.artists.items
|
||||
if type == Type.Playlist:
|
||||
return result.playlists.items
|
||||
return []
|
||||
|
||||
def getLyrics(self, id) -> Lyrics:
|
||||
data = self.__get__(f'tracks/{str(id)}/lyrics', urlpre='https://listen.tidal.com/v1/')
|
||||
return aigpy.model.dictToModel(data, Lyrics())
|
||||
|
||||
def getItems(self, id, type: Type):
|
||||
if type == Type.Playlist:
|
||||
data = self.__getItems__('playlists/' + str(id) + "/items")
|
||||
elif type == Type.Album:
|
||||
msg, data = self.__getItems__('albums/' + str(id) + "/items")
|
||||
data = self.__getItems__('albums/' + str(id) + "/items")
|
||||
elif type == Type.Mix:
|
||||
data = self.__getItems__('mixes/' + str(id) + '/items')
|
||||
else:
|
||||
return "invalid Type!", None, None
|
||||
if msg is not None:
|
||||
return msg, None, None
|
||||
raise Exception("invalid Type!")
|
||||
|
||||
tracks = []
|
||||
videos = []
|
||||
for item in data:
|
||||
if item['type'] == 'track':
|
||||
tracks.append(dictToModel(item['item'], Track()))
|
||||
if item['type'] == 'track' and item['item']['streamReady']:
|
||||
tracks.append(aigpy.model.dictToModel(item['item'], Track()))
|
||||
else:
|
||||
videos.append(dictToModel(item['item'], Video()))
|
||||
return msg, tracks, videos
|
||||
videos.append(aigpy.model.dictToModel(item['item'], Video()))
|
||||
return tracks, videos
|
||||
|
||||
def getArtistAlbums(self, id, includeEP = False):
|
||||
albums = []
|
||||
msg, data = self.__getItems__('artists/' + str(id) + "/albums")
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
for item in data:
|
||||
albums.append(dictToModel(item, Album()))
|
||||
if includeEP == False:
|
||||
return None, albums
|
||||
msg, data = self.__getItems__('artists/' + str(id) + "/albums", {"filter": "EPSANDSINGLES"})
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
for item in data:
|
||||
albums.append(dictToModel(item, Album()))
|
||||
return None, albums
|
||||
def getArtistAlbums(self, id, includeEP=False):
|
||||
data = self.__getItems__(f'artists/{str(id)}/albums')
|
||||
albums = list(aigpy.model.dictToModel(item, Album()) for item in data)
|
||||
if not includeEP:
|
||||
return albums
|
||||
|
||||
data = self.__getItems__(f'artists/{str(id)}/albums', {"filter": "EPSANDSINGLES"})
|
||||
albums += list(aigpy.model.dictToModel(item, Album()) for item in data)
|
||||
return albums
|
||||
|
||||
# from https://github.com/Dniel97/orpheusdl-tidal/blob/master/interface.py#L582
|
||||
def parse_mpd(self, xml: bytes) -> list:
|
||||
# Removes default namespace definition, don't do that!
|
||||
xml = re.sub(r'xmlns="[^"]+"', '', xml, count=1)
|
||||
root = ElementTree.fromstring(xml)
|
||||
|
||||
# List of AudioTracks
|
||||
tracks = []
|
||||
|
||||
for period in root.findall('Period'):
|
||||
for adaptation_set in period.findall('AdaptationSet'):
|
||||
for rep in adaptation_set.findall('Representation'):
|
||||
# Check if representation is audio
|
||||
content_type = adaptation_set.get('contentType')
|
||||
if content_type != 'audio':
|
||||
raise ValueError('Only supports audio MPDs!')
|
||||
|
||||
# Codec checks
|
||||
codec = rep.get('codecs').upper()
|
||||
if codec.startswith('MP4A'):
|
||||
codec = 'AAC'
|
||||
|
||||
# Segment template
|
||||
seg_template = rep.find('SegmentTemplate')
|
||||
# Add init file to track_urls
|
||||
track_urls = [seg_template.get('initialization')]
|
||||
start_number = int(seg_template.get('startNumber') or 1)
|
||||
|
||||
# https://dashif-documents.azurewebsites.net/Guidelines-TimingModel/master/Guidelines-TimingModel.html#addressing-explicit
|
||||
# Also see example 9
|
||||
seg_timeline = seg_template.find('SegmentTimeline')
|
||||
if seg_timeline is not None:
|
||||
seg_time_list = []
|
||||
cur_time = 0
|
||||
|
||||
for s in seg_timeline.findall('S'):
|
||||
# Media segments start time
|
||||
if s.get('t'):
|
||||
cur_time = int(s.get('t'))
|
||||
|
||||
# Segment reference
|
||||
for i in range((int(s.get('r') or 0) + 1)):
|
||||
seg_time_list.append(cur_time)
|
||||
# Add duration to current time
|
||||
cur_time += int(s.get('d'))
|
||||
|
||||
# Create list with $Number$ indices
|
||||
seg_num_list = list(range(start_number, len(seg_time_list) + start_number))
|
||||
# Replace $Number$ with all the seg_num_list indices
|
||||
track_urls += [seg_template.get('media').replace('$Number$', str(n)) for n in seg_num_list]
|
||||
|
||||
tracks.append(track_urls)
|
||||
return tracks
|
||||
|
||||
def getStreamUrl(self, id, quality: AudioQuality):
|
||||
squality = self.__getQualityString__(quality)
|
||||
squality = "HI_RES"
|
||||
if quality == AudioQuality.Normal:
|
||||
squality = "LOW"
|
||||
elif quality == AudioQuality.High:
|
||||
squality = "HIGH"
|
||||
elif quality == AudioQuality.HiFi:
|
||||
squality = "LOSSLESS"
|
||||
elif quality == AudioQuality.Max:
|
||||
squality = "HI_RES_LOSSLESS"
|
||||
|
||||
paras = {"audioquality": squality, "playbackmode": "STREAM", "assetpresentation": "FULL"}
|
||||
msg, data = self.__get__('tracks/' + str(id) + "/playbackinfopostpaywall", paras)
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
resp = dictToModel(data, __StreamRespon__())
|
||||
|
||||
data = self.__get__(f'tracks/{str(id)}/playbackinfopostpaywall', paras)
|
||||
resp = aigpy.model.dictToModel(data, StreamRespond())
|
||||
|
||||
if "vnd.tidal.bt" in resp.manifestMimeType:
|
||||
manifest = json.loads(base64.b64decode(resp.manifest).decode('utf-8'))
|
||||
ret = StreamUrl()
|
||||
@@ -247,150 +374,114 @@ class TidalAPI(object):
|
||||
ret.codec = manifest['codecs']
|
||||
ret.encryptionKey = manifest['keyId'] if 'keyId' in manifest else ""
|
||||
ret.url = manifest['urls'][0]
|
||||
return "", ret
|
||||
return "Can't get the streamUrl, type is " + resp.manifestMimeType, None
|
||||
ret.urls = [ret.url]
|
||||
return ret
|
||||
elif "dash+xml" in resp.manifestMimeType:
|
||||
xmldata = base64.b64decode(resp.manifest).decode('utf-8')
|
||||
ret = StreamUrl()
|
||||
ret.trackid = resp.trackid
|
||||
ret.soundQuality = resp.audioQuality
|
||||
ret.codec = aigpy.string.getSub(xmldata, 'codecs="', '"')
|
||||
ret.encryptionKey = "" # manifest['keyId'] if 'keyId' in manifest else ""
|
||||
ret.urls = self.parse_mpd(xmldata)[0]
|
||||
if len(ret.urls) > 0:
|
||||
ret.url = ret.urls[0]
|
||||
return ret
|
||||
|
||||
raise Exception("Can't get the streamUrl, type is " + resp.manifestMimeType)
|
||||
|
||||
def getVideoStreamUrl(self, id, quality: VideoQuality):
|
||||
paras = {"videoquality": "HIGH", "playbackmode": "STREAM", "assetpresentation": "FULL"}
|
||||
msg, data = self.__get__('videos/' + str(id) + "/playbackinfopostpaywall", paras)
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
resp = dictToModel(data, __StreamRespon__())
|
||||
|
||||
data = self.__get__(f'videos/{str(id)}/playbackinfopostpaywall', paras)
|
||||
resp = aigpy.model.dictToModel(data, StreamRespond())
|
||||
|
||||
if "vnd.tidal.emu" in resp.manifestMimeType:
|
||||
manifest = json.loads(base64.b64decode(resp.manifest).decode('utf-8'))
|
||||
array = self.__getResolutionList__(manifest['urls'][0])
|
||||
icmp = int(quality.value)
|
||||
index = 0
|
||||
for item in array:
|
||||
if icmp >= int(item.resolutions[1]):
|
||||
if icmp <= int(item.resolutions[1]):
|
||||
break
|
||||
index += 1
|
||||
if index >= len(array):
|
||||
index = len(array) - 1
|
||||
return "", array[index]
|
||||
return "Can't get the streamUrl, type is " + resp.manifestMimeType, None
|
||||
|
||||
return array[index]
|
||||
raise Exception("Can't get the streamUrl, type is " + resp.manifestMimeType)
|
||||
|
||||
def getTrackContributors(self, id):
|
||||
msg, data = self.__get__('tracks/' + str(id) + "/contributors")
|
||||
if msg is not None:
|
||||
return msg, None
|
||||
return None,data
|
||||
return self.__get__(f'tracks/{str(id)}/contributors')
|
||||
|
||||
def getCoverUrl(self, sid, width="320", height="320"):
|
||||
if sid is None or sid == "":
|
||||
return None
|
||||
return "https://resources.tidal.com/images/" + sid.replace("-", "/") + "/" + width + "x" + height + ".jpg"
|
||||
if sid is None:
|
||||
return ""
|
||||
return f"https://resources.tidal.com/images/{sid.replace('-', '/')}/{width}x{height}.jpg"
|
||||
|
||||
def getArtistsName(self, artists = []):
|
||||
array = []
|
||||
for item in artists:
|
||||
array.append(item.name)
|
||||
return " / ".join(array)
|
||||
def getCoverData(self, sid, width="320", height="320"):
|
||||
url = self.getCoverUrl(sid, width, height)
|
||||
try:
|
||||
return requests.get(url).content
|
||||
except:
|
||||
return ''
|
||||
|
||||
def getFlag(self, data, type : Type, short = True, separator = " / "):
|
||||
def getArtistsName(self, artists=[]):
|
||||
array = list(item.name for item in artists)
|
||||
return ", ".join(array)
|
||||
|
||||
def getFlag(self, data, type: Type, short=True, separator=" / "):
|
||||
master = False
|
||||
atmos = False
|
||||
explicit = False
|
||||
if type == Type.Album or type == Type.Track:
|
||||
if data.audioQuality == "HI_RES":
|
||||
master = True
|
||||
if data.explicit == True:
|
||||
if type == Type.Album and "DOLBY_ATMOS" in data.audioModes:
|
||||
atmos = True
|
||||
if data.explicit is True:
|
||||
explicit = True
|
||||
if type == Type.Video:
|
||||
if data.explicit == True:
|
||||
if data.explicit is True:
|
||||
explicit = True
|
||||
if master == False and explicit == False:
|
||||
if not master and not atmos and not explicit:
|
||||
return ""
|
||||
array = []
|
||||
if master:
|
||||
array.append("M" if short else "Master")
|
||||
if atmos:
|
||||
array.append("A" if short else "Dolby Atmos")
|
||||
if explicit:
|
||||
array.append("E" if short else "Explicit")
|
||||
return separator.join(array)
|
||||
|
||||
def parseUrl(self, url):
|
||||
etype = Type.Null
|
||||
sid = ""
|
||||
if "tidal.com" not in url:
|
||||
return etype, sid
|
||||
return Type.Null, url
|
||||
|
||||
url = url.lower()
|
||||
if 'artist' in url:
|
||||
etype = Type.Artist
|
||||
if 'album' in url:
|
||||
etype = Type.Album
|
||||
if 'track' in url:
|
||||
etype = Type.Track
|
||||
if 'video' in url:
|
||||
etype = Type.Video
|
||||
if 'playlist' in url:
|
||||
etype = Type.Playlist
|
||||
|
||||
if etype == Type.Null:
|
||||
return etype, sid
|
||||
|
||||
sid = stringHelper.getSub(url, etype.name.lower() + '/', '/')
|
||||
return etype, sid
|
||||
for index, item in enumerate(Type):
|
||||
if item.name.lower() in url:
|
||||
etype = item
|
||||
return etype, aigpy.string.getSub(url, etype.name.lower() + '/', '/')
|
||||
return Type.Null, url
|
||||
|
||||
def getByString(self, string):
|
||||
etype = Type.Null
|
||||
if aigpy.string.isNull(string):
|
||||
raise Exception("Please enter something.")
|
||||
|
||||
obj = None
|
||||
|
||||
if isNull(string):
|
||||
return "Please enter something.", etype, obj
|
||||
etype, sid = self.parseUrl(string)
|
||||
if isNull(sid):
|
||||
sid = string
|
||||
for index, item in enumerate(Type):
|
||||
if etype != Type.Null and etype != item:
|
||||
continue
|
||||
if item == Type.Null:
|
||||
continue
|
||||
try:
|
||||
obj = self.getTypeData(sid, item)
|
||||
return item, obj
|
||||
except:
|
||||
continue
|
||||
|
||||
if obj is None and (etype == Type.Null or etype == Type.Album):
|
||||
msg, obj = self.getAlbum(sid)
|
||||
if obj is None and (etype == Type.Null or etype == Type.Artist):
|
||||
msg, obj = self.getArtist(sid)
|
||||
if obj is None and (etype == Type.Null or etype == Type.Track):
|
||||
msg, obj = self.getTrack(sid)
|
||||
if obj is None and (etype == Type.Null or etype == Type.Video):
|
||||
msg, obj = self.getVideo(sid)
|
||||
if obj is None and (etype == Type.Null or etype == Type.Playlist):
|
||||
msg, obj = self.getPlaylist(sid)
|
||||
raise Exception("No result.")
|
||||
|
||||
if obj is None or etype != Type.Null:
|
||||
return msg, etype, obj
|
||||
if obj.__class__ == Album:
|
||||
etype = Type.Album
|
||||
if obj.__class__ == Artist:
|
||||
etype = Type.Artist
|
||||
if obj.__class__ == Track:
|
||||
etype = Type.Track
|
||||
if obj.__class__ == Video:
|
||||
etype = Type.Video
|
||||
if obj.__class__ == Playlist:
|
||||
etype = Type.Playlist
|
||||
return msg, etype, obj
|
||||
|
||||
"""
|
||||
def getToken(self):
|
||||
token1 = "MbjR4DLXz1ghC4rV"
|
||||
token2 = "pl4Vc0hemlAXD0mN" # only lossless
|
||||
try:
|
||||
msg = requests.get( "https://cdn.jsdelivr.net/gh/yaronzz/CDN@latest/app/tidal/tokens.json", timeout=(20.05, 27.05))
|
||||
tokens = json.loads(msg.text)
|
||||
token1 = tokens['token']
|
||||
token2 = tokens['token2']
|
||||
except Exception as e:
|
||||
pass
|
||||
return token1,token2
|
||||
"""
|
||||
|
||||
def getFileContent(self,path, isBin=False):
|
||||
mode = 'r'
|
||||
if isBin:
|
||||
mode = 'rb'
|
||||
try:
|
||||
size = fileHelper.getFileSize(path)
|
||||
if size <= 0:
|
||||
return ""
|
||||
with open(path, mode, encoding="utf-8") as fd:
|
||||
content = fd.read(size)
|
||||
return content
|
||||
except Exception as e:
|
||||
return ""
|
||||
# Singleton
|
||||
TIDAL_API = TidalAPI()
|
||||
|
||||
+210
-20
@@ -1,60 +1,188 @@
|
||||
TYPE tidal-dl
|
||||
USE pip3 install tidal-dl --upgrade
|
||||
|
||||
#### v2022-10-31
|
||||
|
||||
- [X] Add delay setting by @grzekru
|
||||
|
||||
#### v2022-08-29
|
||||
|
||||
- [X] Fix #931
|
||||
|
||||
#### v2022-07-06
|
||||
|
||||
- [X] Mulithread download
|
||||
|
||||
#### v2022-06-23
|
||||
|
||||
- [X] remove redundant configuration
|
||||
- [X] add simple-gui
|
||||
- [X] optimize code
|
||||
|
||||
#### v2022-03-04
|
||||
|
||||
- [X] fix "file name contain *" #844
|
||||
- [X] Update Vietnamese
|
||||
- [X] update Hungarian
|
||||
- [X] Update Ukrainian
|
||||
- [X] Update Dutch
|
||||
- [X] fix bug of setting path
|
||||
|
||||
#### v2022-02-07
|
||||
|
||||
- [X] update api key by 1nikolas
|
||||
|
||||
#### v2022-01-21
|
||||
|
||||
- [X] update api key by @morguldir
|
||||
- [X] Fix bug of "ReleaseDate"
|
||||
|
||||
#### v2022-01-18
|
||||
|
||||
- [X] Gui: search view
|
||||
- [X] Gui: download view
|
||||
|
||||
#### v2022-01-11
|
||||
|
||||
- [X] Settings: add type-folder(eg Album/Video/Playlist)
|
||||
- [X] Album folder format support: {None}
|
||||
|
||||
#### v2021-11-30
|
||||
|
||||
- [X] Add language:Japanese
|
||||
- [X] Support select apikey(Different keys support different formats)
|
||||
|
||||
#### v2021-11-15
|
||||
|
||||
- [X] Add language:Korean
|
||||
- [X] Update vietnamese
|
||||
- [X] Additional tags for album path and track name
|
||||
|
||||
#### v2021-09-23
|
||||
|
||||
- [X] Get lyrics from tidal
|
||||
- [X] Support mixes
|
||||
|
||||
#### v2021-09-10
|
||||
|
||||
- [X] Add settings: show track-info
|
||||
- [X] Fix bug of "Illegal characters in path"
|
||||
|
||||
#### v2021-05-31
|
||||
|
||||
- [X] Add lyrics
|
||||
|
||||
#### v2021-04-30
|
||||
|
||||
- [X] Add 'album info.txt'
|
||||
- [X] Fix bug of download video
|
||||
|
||||
#### v2021-04-23
|
||||
|
||||
- [X] Show get-quality
|
||||
- [X] Update language
|
||||
- [X] Update settings: usePlaylistFolder
|
||||
|
||||
#### v2021-03-24
|
||||
|
||||
- [X] Fix bug of download video
|
||||
- [X] Fix bug of 'Command line download'
|
||||
|
||||
#### v2021-02-20
|
||||
|
||||
- [X] Add log
|
||||
|
||||
#### v2020-12-17
|
||||
|
||||
- [X] Show DOLBY_ATMOS flag [A]
|
||||
- [X] Fix bug of "Connection aborted"(Linux platform)
|
||||
- [X] Fix bug of download failed "stat: path should be string, bytes, os.PathLike or integer, not list"
|
||||
|
||||
#### v2020-12-10
|
||||
|
||||
- [X] Add feature: set the accessToken manually
|
||||
|
||||
#### v2020-12-01
|
||||
|
||||
- [X] Fix bug of settings-path
|
||||
- [X] Ability to download multiple urls at a time.
|
||||
|
||||
#### v2020-11-13
|
||||
|
||||
- [X] Change settings-file save path: XDG_CONFIG_HOME or HOME
|
||||
- [X] Fix bug of multiThreadDownload
|
||||
- [X] Choice: logout
|
||||
|
||||
#### v2020-11-09
|
||||
|
||||
- [X] New login-method: get the accessToken by opening the link, accessToken good for one week and auto refresh
|
||||
|
||||
#### v2020-10-22
|
||||
- [x] Settings: album folder format、track file format
|
||||
- [x] Settings: show progress
|
||||
- [x] Support language: german
|
||||
- [x] Tag: composer
|
||||
- [X] Add command opts: username\password\accessToken\quality\resolution
|
||||
|
||||
- [X] Settings: album folder format、track file format
|
||||
- [X] Settings: show progress
|
||||
- [X] Support language: german
|
||||
- [X] Tag: composer
|
||||
- [X] Add command opts: username\password\accessToken\quality\resolution
|
||||
|
||||
#### v2020-09-26
|
||||
- [x] Fix: download video failed. Resolution parse error.
|
||||
- [x] Windows: auto get accessToken from tidaldesktop cache
|
||||
- [x] Download playlist to playlist folder
|
||||
- [x] Fix: check exist
|
||||
- [x] Support language vietnamese
|
||||
- [x] Fix: download cover error (no album-cover)
|
||||
- [x] Settings: usePlaylistFolder、 multiThreadDownload
|
||||
- [x] Support language french
|
||||
|
||||
- [X] Fix: download video failed. Resolution parse error.
|
||||
- [X] Windows: auto get accessToken from tidal-desktop cache
|
||||
- [X] Download playlist to playlist folder
|
||||
- [X] Fix: check exist
|
||||
- [X] Support language vietnamese
|
||||
- [X] Fix: download cover error (no album-cover)
|
||||
- [X] Settings: usePlaylistFolder、 multiThreadDownload
|
||||
- [X] Support language french
|
||||
|
||||
#### v2020-09-06
|
||||
|
||||
- usage by command: tidal-dl --help
|
||||
|
||||
#### v2020-08-30
|
||||
|
||||
- support language portuguese
|
||||
- multithreading download a track
|
||||
|
||||
#### v2020-08-24
|
||||
|
||||
- add errmessage when downloading failed
|
||||
- fix: macos - downlod failed
|
||||
- fix: macos - download failed
|
||||
|
||||
#### v2020-08-22
|
||||
|
||||
- support language spanish\croatian
|
||||
|
||||
|
||||
#### v2020-08-21
|
||||
|
||||
- fix: get album path
|
||||
- support download by file
|
||||
- support language arabic\czech\itlian\russian\turkish\filipino
|
||||
|
||||
#### v2020-08-20
|
||||
|
||||
- fix: download playlist
|
||||
- fix: settings
|
||||
- fix: lack of multi-language module
|
||||
|
||||
#### v2020-08-19
|
||||
|
||||
- code rebuild
|
||||
- multi-language
|
||||
|
||||
#### v2020-07-16
|
||||
|
||||
- Enter 10:Set AccessToken(authorization)
|
||||
|
||||
#### v2020-07-03
|
||||
|
||||
- Add label [E] before albumtitle #264
|
||||
- Volume to CD
|
||||
- Fix bug of ssl
|
||||
|
||||
#### v2020-06-28
|
||||
|
||||
- Fix bug of download-playlist
|
||||
- ArtistName before title(settings)
|
||||
- AlbumID before AlbumFolderName(settings)
|
||||
@@ -62,6 +190,7 @@ USE pip3 install tidal-dl --upgrade
|
||||
- Add errmessage when download err
|
||||
|
||||
#### v2020-06-14
|
||||
|
||||
- Reduce the number of logins
|
||||
- Use another login method(from Redsea)
|
||||
- Download Dolby Atmos(AC4 Codec\Low Quality\Mp4 format)
|
||||
@@ -70,41 +199,51 @@ USE pip3 install tidal-dl --upgrade
|
||||
- Fixed the bug of Download-HIRES
|
||||
|
||||
#### v2020-05-31
|
||||
|
||||
- Use CDN request
|
||||
- Fix bug of redownload(download artist-albums)
|
||||
- Add errmessage when login-err
|
||||
- Fix bug of save-cover MacOs
|
||||
|
||||
#### v2020-05-19
|
||||
|
||||
- by Command(eg. tidal-dl https://tidal.com/browse/track/70973230)
|
||||
- Add label [M] before albumtitle
|
||||
- Update token
|
||||
|
||||
#### v2020-05-15
|
||||
|
||||
- Cloud token
|
||||
|
||||
#### v2020-05-14
|
||||
|
||||
- Update token
|
||||
|
||||
#### v2020-05-04
|
||||
|
||||
- Hide password
|
||||
|
||||
#### v2020-03-23
|
||||
|
||||
- Fix downloading redirects that can be obtained through the
|
||||
/playbackinfopostpaywall method.
|
||||
- When downloading, download to a .part file, which is then
|
||||
either decrypted or renamed into place, to avoid leaving broken files.
|
||||
|
||||
#### v2020-3-17
|
||||
#### v2020-3-17
|
||||
|
||||
- Fix bug of download ArtistAlbum
|
||||
|
||||
#### v2020-03-11
|
||||
|
||||
- Fix bug of 'Asset is not ready for playback'
|
||||
|
||||
#### v2020-03-10
|
||||
|
||||
- Update token
|
||||
|
||||
|
||||
#### v2020-02-28
|
||||
|
||||
- Fix bug of savepath
|
||||
- Add Year: before/After
|
||||
- save covers(settings)
|
||||
@@ -112,17 +251,20 @@ USE pip3 install tidal-dl --upgrade
|
||||
- Fix:no version in Tag
|
||||
|
||||
#### v2020-02-14
|
||||
|
||||
- Fix bug of download track
|
||||
- ByUrl: add artist
|
||||
- ByUrl: support 'https://tidal.com/browse/'
|
||||
|
||||
#### v2020-01-22
|
||||
|
||||
- Download artist album include singles(settings)
|
||||
- Download by file include artist
|
||||
- Fix english typos
|
||||
- Fix bug of tracknumber(download playlist)
|
||||
|
||||
#### v2020-01-17
|
||||
|
||||
- Artists hyphen ';' to ', '
|
||||
- Fix bug of download playlist
|
||||
- Fix bug of download artwork
|
||||
@@ -131,123 +273,157 @@ USE pip3 install tidal-dl --upgrade
|
||||
- Playlist: add tracknum before tracktitle
|
||||
|
||||
#### v2019-10-26
|
||||
|
||||
- Download playlist by url
|
||||
- Config 'AddYear' before album dir
|
||||
- Download playlist track-picture
|
||||
|
||||
#### v2019-09-27
|
||||
|
||||
- Add skip switch when download atrist/file
|
||||
- Fix bug of download playlist
|
||||
|
||||
#### v2019-09-10
|
||||
|
||||
- Fix bug of download videos
|
||||
- Add version to title
|
||||
- Add hyphen between number and title(settings)
|
||||
|
||||
#### v2019-09-02
|
||||
|
||||
- Fix bug of parse link
|
||||
- Download by file
|
||||
|
||||
#### v2019-08-19
|
||||
|
||||
- Show Config
|
||||
- Tag: add composer
|
||||
|
||||
#### v2019-08-17
|
||||
|
||||
- Download ArtistAlbum: Add EP&Singles
|
||||
|
||||
#### v2019-08-12
|
||||
|
||||
- Fix bug of tag
|
||||
- Add setting-showprogress (Only enable when threadnum=1)
|
||||
|
||||
#### v2019-08-11
|
||||
|
||||
- Fix tag of title
|
||||
- Download album videos
|
||||
|
||||
#### v2019-08-07
|
||||
- Fix Bug: login;threadnum
|
||||
|
||||
- Fix Bug: login;threadnum
|
||||
|
||||
#### v2019-08-05
|
||||
|
||||
- Support python 2.7
|
||||
|
||||
#### v2019-07-30
|
||||
|
||||
- Add Setting-OnlyM4a(auto covert mp4 To m4a)
|
||||
- Fix some bug when first login
|
||||
- Check ffmpeg status
|
||||
|
||||
#### v2019-07-23
|
||||
|
||||
- CLI: add a serial number before the file name
|
||||
|
||||
#### v2019-07-22
|
||||
|
||||
- Fix Some Bug
|
||||
|
||||
#### v2019-07-18
|
||||
|
||||
- Fix Bug: Set Metadata
|
||||
|
||||
#### v2019-07-12
|
||||
|
||||
- Fix Some Bug
|
||||
|
||||
#### v2019-07-11
|
||||
|
||||
- Add Func:Download By Url
|
||||
|
||||
#### v2019-07-01
|
||||
|
||||
- Add HI_RES Quality
|
||||
|
||||
#### v2019-06-24
|
||||
|
||||
- Fix Bug When Downloading Playlist
|
||||
|
||||
#### v2019-06-16
|
||||
- Fix Bug Of Track Tag
|
||||
|
||||
- Fix Bug Of Track Tag
|
||||
|
||||
#### v2019-06-01
|
||||
|
||||
- Fix Encoding BUG
|
||||
- Add Cover To Track
|
||||
|
||||
#### v2019-05-08
|
||||
|
||||
- Update FFmpegTool
|
||||
|
||||
#### v2019-05-06
|
||||
|
||||
- Change 'Track' TargetDir
|
||||
- Download 'Playlist'&'Track' Image
|
||||
- Fuc: Download ArtistAlbums
|
||||
|
||||
#### v2019-04-23
|
||||
|
||||
- Add 'Resolution' To Config
|
||||
- Change Playlist Items TrackNum
|
||||
|
||||
#### v2019-04-22
|
||||
|
||||
- Download Album: Track Title Append Version
|
||||
|
||||
#### v2019-04-16
|
||||
|
||||
- Change Album TargetDir
|
||||
- Add 'ReleaseDate' to Track Metadata
|
||||
- Remove BUG:Playlist Path
|
||||
|
||||
#### v2019-04-11
|
||||
|
||||
- Remove BUG:Download Playlist Video
|
||||
|
||||
#### v2019-04-08
|
||||
|
||||
- Change Tmp File Flag
|
||||
|
||||
#### v2019-04-02
|
||||
|
||||
- Highlight(Only Linux)
|
||||
|
||||
#### v2019-04-01
|
||||
|
||||
- Remove Encoding Err
|
||||
|
||||
#### v2019-03-29
|
||||
|
||||
- Dl Album:If Exist TrackFile. Support ReDownload Or Ignore
|
||||
|
||||
#### v2019-03-28
|
||||
|
||||
- Check After Set Metadata
|
||||
|
||||
#### v2019-03-13
|
||||
|
||||
- Deal Err: Get pip version failed
|
||||
|
||||
#### v2019-03-11
|
||||
|
||||
- Check Files After Download Playlist
|
||||
- Show Last Version
|
||||
|
||||
#### v2019-03-06
|
||||
|
||||
- Add Config 'ThreadNum'
|
||||
- Support Linux
|
||||
- Add 'requirements.txt'
|
||||
@@ -255,52 +431,66 @@ USE pip3 install tidal-dl --upgrade
|
||||
- Set Metadata in Linux
|
||||
|
||||
#### v2019-03-04
|
||||
|
||||
- Simplified Code
|
||||
|
||||
#### v2019-02-27
|
||||
|
||||
- Download FavoriteVideos
|
||||
|
||||
#### v2019-02-26
|
||||
|
||||
- Download Playlist:Deal with err 'Too Big Page'
|
||||
|
||||
#### v2019-02-25
|
||||
|
||||
- Playlist LimitNum = 9999
|
||||
- Download FavoriteTracks
|
||||
|
||||
#### v2019-02-19
|
||||
|
||||
- Print more err message
|
||||
|
||||
#### v2019-02-19
|
||||
|
||||
- Download AlbumCover
|
||||
- Set Track Metadata
|
||||
|
||||
#### v2019-02-14
|
||||
|
||||
- Set music-filetype by StreamUrlInfo
|
||||
|
||||
#### v2019-01-28
|
||||
|
||||
- Add decryption.py -- Download LOSSLESS music
|
||||
|
||||
#### v2018-12-28
|
||||
- Add Progressbar - Download Video
|
||||
|
||||
- Add Progressbar - Download Video
|
||||
|
||||
#### v2018-12-19
|
||||
|
||||
- Update ffmpegHelper
|
||||
- Simplified Code
|
||||
|
||||
#### v2018-12-11
|
||||
|
||||
- Fuc: Download Playlist Video
|
||||
|
||||
#### v2018-12-01
|
||||
|
||||
- Optimized Code
|
||||
- Multithreading Download Video
|
||||
- Fuc: Download Playlist
|
||||
|
||||
#### v2018-11-22
|
||||
|
||||
- Multithreading Download
|
||||
- Fuc: Download Track
|
||||
- Fuc: Download Video
|
||||
|
||||
#### v2018-11-21
|
||||
|
||||
- Func: Download Album
|
||||
- Func: Get SessionID By Account
|
||||
- Upload Version To PIP Server : pip install tidal-dl
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
rm -rf dist
|
||||
rm -rf build
|
||||
rm -rf exe
|
||||
rm -rf tidal_dl.egg-info
|
||||
mkdir exe
|
||||
|
||||
# pack
|
||||
python setup.py sdist bdist_wheel
|
||||
# creat exe file
|
||||
pyinstaller -F tidal_dl/__init__.py
|
||||
# rename exe name
|
||||
mv dist/__init__.exe exe/tidal-dl.exe
|
||||
|
||||
pip uninstall -y tidal-dl
|
||||
|
||||
# creat requirements.txt
|
||||
# pipreqs ./ --force
|
||||
|
||||
# python setup.py install
|
||||
|
||||
# upload
|
||||
twine upload dist/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# powershell
|
||||
cd TIDALDL-PY
|
||||
Remove-Item dist -recurse -Force
|
||||
Remove-Item build -recurse -Force
|
||||
Remove-Item exe -recurse -Force
|
||||
Remove-Item tidal_dl.egg-info -recurse -Force
|
||||
md exe
|
||||
|
||||
# pack
|
||||
python setup.py sdist bdist_wheel
|
||||
# creat exe file
|
||||
pyinstaller -F tidal_dl/__init__.py
|
||||
#pyinstaller -F -i ../logo.ico tidal_dl/__init__.py
|
||||
# rename exe name
|
||||
cp dist/__init__.exe exe/tidal-dl.exe
|
||||
rm dist/__init__.exe
|
||||
|
||||
pip uninstall -y tidal-dl
|
||||
|
||||
# creat requirements.txt
|
||||
# pipreqs ./ --force
|
||||
|
||||
# python setup.py install
|
||||
|
||||
# upload
|
||||
twine upload dist/*
|
||||
|
||||
[TEST-VERSION]
|
||||
TYPE tidal-dl
|
||||
USE pip3 install tidal-dl --upgrade
|
||||
#### v2020-10-13
|
||||
- [x] Settings: album folder format、track file format
|
||||
|
||||
If there are any bugs or suggestions, please post to this link:
|
||||
https://github.com/yaronzz/Tidal-Media-Downloader/issues/491
|
||||
@@ -0,0 +1,20 @@
|
||||
rm -rf dist
|
||||
rm -rf build
|
||||
rm -rf __init__.spec
|
||||
|
||||
cd TIDALDL-PY
|
||||
rm -rf __init__.spec
|
||||
rm -rf dist
|
||||
rm -rf build
|
||||
rm -rf exe
|
||||
rm -rf MANIFEST.in
|
||||
rm -rf *.egg-info
|
||||
|
||||
python setup.py sdist bdist_wheel
|
||||
pyinstaller -F tidal_dl/__init__.py
|
||||
mkdir exe
|
||||
mv dist/__init__.exe exe/tidal-dl.exe
|
||||
|
||||
pip uninstall -y tidal-dl
|
||||
|
||||
cd ..
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.9 KiB |
Reference in New Issue
Block a user