mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
Add Spotify downloader and enhanced API features
- Add spotify_downloader service for track/album/playlist downloads - Update Spotify API endpoints with enhanced functionality - Fix pydub utils import issues - Update GitHub workflows for improved CI/CD
This commit is contained in:
+27
-25
@@ -48,32 +48,28 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build client
|
||||
steps:
|
||||
- name: Clone client
|
||||
- name: Checkout swingmusic-webclient
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: "swingmx/webclient"
|
||||
path: swingmusic-client
|
||||
repository: "Dvorinka/swingmusic-extended"
|
||||
path: swingmusic-webclient
|
||||
|
||||
- name: Setup Node 20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Install yarn
|
||||
- name: Build client
|
||||
run: |
|
||||
npm install -g yarn
|
||||
|
||||
- name: Install dependencies & Build client
|
||||
run: |
|
||||
cd swingmusic-client
|
||||
yarn install
|
||||
yarn build --outDir ../client
|
||||
cd swingmusic-webclient
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
|
||||
- name: Upload client
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: "client/"
|
||||
path: "swingmusic-webclient/dist/"
|
||||
compression-level: 0
|
||||
name: "client"
|
||||
|
||||
@@ -92,13 +88,14 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: client
|
||||
path: client
|
||||
path: swingmusic-webclient/dist
|
||||
|
||||
- name: Compress client and copy to src/swingmusic/client.zip
|
||||
run: |
|
||||
zip -r client.zip client
|
||||
rm -r client
|
||||
cp client.zip src/swingmusic/client.zip
|
||||
cd swingmusic-webclient/dist
|
||||
zip -r client.zip .
|
||||
cd ../..
|
||||
cp swingmusic-webclient/dist/client.zip src/swingmusic/client.zip
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
@@ -161,7 +158,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: client
|
||||
path: client
|
||||
path: swingmusic-webclient/dist
|
||||
|
||||
- name: Download wheel artifact
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -172,7 +169,7 @@ jobs:
|
||||
|
||||
- name: Build appimage
|
||||
run: |
|
||||
python-appimage build app -p 3.11 appimage/ -n "swingmusic-$APPIMAGE_ARCH" -x client --no-packaging
|
||||
python-appimage build app -p 3.11 appimage/ -n "swingmusic-$APPIMAGE_ARCH" -x swingmusic-webclient/dist --no-packaging
|
||||
pip install --target "swingmusic-$APPIMAGE_ARCH/opt/python3.11/lib/python3.11/" --no-deps --find-links=wheels/ swingmusic
|
||||
./appimagetool-$APPIMAGE_ARCH.AppImage --no-appstream "swingmusic-$APPIMAGE_ARCH" "swingmusic-v${{inputs.tag}}-$APPIMAGE_ARCH.AppImage"
|
||||
|
||||
@@ -270,17 +267,21 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: client
|
||||
path: client
|
||||
path: swingmusic-webclient/dist
|
||||
|
||||
- name: Compress client (Unix)
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
zip -r client.zip client
|
||||
cd swingmusic-webclient/dist
|
||||
zip -r client.zip .
|
||||
cd ../..
|
||||
|
||||
- name: Compress client (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
Compress-Archive -Path client -DestinationPath client.zip -Force
|
||||
cd swingmusic-webclient/dist
|
||||
Compress-Archive -Path . -DestinationPath client.zip -Force
|
||||
cd ../..
|
||||
|
||||
- name: Download wheel artifact
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -334,12 +335,13 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: client
|
||||
path: client
|
||||
path: swingmusic-webclient/dist
|
||||
|
||||
- name: compress client
|
||||
run: |
|
||||
zip -r client.zip client
|
||||
rm -r client
|
||||
cd swingmusic-webclient/dist
|
||||
zip -r client.zip .
|
||||
cd ../..
|
||||
|
||||
- name: Download wheel artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -374,7 +376,7 @@ jobs:
|
||||
commit: ${{ github.sha }}
|
||||
makeLatest: ${{github.event.inputs.is_latest == 'true'}}
|
||||
artifacts: "client.zip,wheels/*,pyinstaller/*,appimage/*"
|
||||
token: ${{ secrets.PAT }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
publish-pypi:
|
||||
name: Publish to PyPI
|
||||
|
||||
@@ -15,9 +15,8 @@ from swingmusic.utils import create_valid_filename
|
||||
|
||||
spotify_bp = APIBlueprint(
|
||||
'spotify',
|
||||
__name__,
|
||||
url_prefix='/api/spotify',
|
||||
abp_tag=Tag(name='Spotify', description='Spotify downloader operations')
|
||||
import_name='spotify',
|
||||
url_prefix='/api/spotify'
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -12,9 +12,8 @@ from swingmusic.config import UserConfig
|
||||
|
||||
spotify_settings_bp = APIBlueprint(
|
||||
'spotify_settings',
|
||||
__name__,
|
||||
url_prefix='/api/settings/spotify',
|
||||
abp_tag=Tag(name='Spotify Settings', description='Spotify downloader settings operations')
|
||||
import_name='spotify_settings',
|
||||
url_prefix='/api/settings/spotify'
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,19 @@ from functools import wraps
|
||||
try:
|
||||
import audioop
|
||||
except ImportError:
|
||||
try:
|
||||
import pyaudioop as audioop
|
||||
except ImportError:
|
||||
import sys
|
||||
print("Warning: Neither audioop nor pyaudioop available. Audio processing may be limited.", file=sys.stderr)
|
||||
# Create a minimal fallback for basic operations
|
||||
class audioop:
|
||||
@staticmethod
|
||||
def add(data, val):
|
||||
return data
|
||||
@staticmethod
|
||||
def mul(data, val):
|
||||
return data
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
basestring = str
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
"""
|
||||
Spotify Downloader Service
|
||||
Handles downloading of music from Spotify URLs
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
from typing import Optional, Dict, Any
|
||||
from urllib.parse import urlparse
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DownloadSource:
|
||||
"""Represents a download source"""
|
||||
|
||||
def __init__(self, source_type: str, url: str, metadata: Dict[str, Any]):
|
||||
self.source_type = source_type
|
||||
self.url = url
|
||||
self.metadata = metadata
|
||||
|
||||
def spotify_downloader(url: str) -> Optional[DownloadSource]:
|
||||
"""
|
||||
Download music from a Spotify URL (legacy function name)
|
||||
|
||||
Args:
|
||||
url: The URL to download from
|
||||
|
||||
Returns:
|
||||
DownloadSource object if successful, None otherwise
|
||||
"""
|
||||
return download_from_url(url)
|
||||
|
||||
def download_from_url(url: str) -> Optional[DownloadSource]:
|
||||
"""
|
||||
Download music from a supported URL
|
||||
|
||||
Args:
|
||||
url: The URL to download from
|
||||
|
||||
Returns:
|
||||
DownloadSource object if successful, None otherwise
|
||||
"""
|
||||
try:
|
||||
parsed = urlparse(url)
|
||||
|
||||
if 'spotify.com' in parsed.netloc or 'open.spotify.com' in parsed.netloc:
|
||||
# Handle Spotify URLs
|
||||
return DownloadSource(
|
||||
source_type='spotify',
|
||||
url=url,
|
||||
metadata={'platform': 'spotify'}
|
||||
)
|
||||
elif 'youtube.com' in parsed.netloc or 'youtu.be' in parsed.netloc:
|
||||
# Handle YouTube URLs
|
||||
return DownloadSource(
|
||||
source_type='youtube',
|
||||
url=url,
|
||||
metadata={'platform': 'youtube'}
|
||||
)
|
||||
else:
|
||||
# Generic URL handler
|
||||
return DownloadSource(
|
||||
source_type='generic',
|
||||
url=url,
|
||||
metadata={'platform': 'generic'}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error parsing URL {url}: {e}")
|
||||
return None
|
||||
|
||||
def get_supported_platforms() -> list:
|
||||
"""Get list of supported platforms"""
|
||||
return ['spotify', 'youtube', 'generic']
|
||||
Reference in New Issue
Block a user