Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Build

on:
workflow_call:
workflow_dispatch:
push:
branches: [main, master]
paths-ignore: ["README.md", "LICENSE", ".gitignore"]
pull_request:
branches: [main, master]

permissions:
contents: read

jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
fail-fast: false

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller

- name: Build with PyInstaller
run: python bundle/pyinstaller.py

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: SpotFetch-${{ runner.os }}
path: dist/SpotFetch*
if-no-files-found: error
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Release

on:
push:
tags: ["v*"]

permissions:
contents: write

jobs:
build:
uses: ./.github/workflows/build.yml

release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: List artifacts
run: ls -R artifacts/

- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/**/*
generate_release_notes: true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ __pycache__/
.vscode/
*.pyc
cli_to_code.py
dist/
build/
*.spec
*.egg-info/
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A simple python program to download Music from various platfroms using yt-dlp (

## What it can do :

- Download Spotify playlists after exporting the playlist as a csv file from [Exportify](https://exportify.app)
- Download Spotify playlists
- batch download music from a .txt file with URLs one by line, or using a custom CSV file with headers *name,artist*
- Direct download from a Youtube url, can be a video or playlist.
- Search then download a song using its name and artist name.
Expand All @@ -19,13 +19,25 @@ A simple python program to download Music from various platfroms using yt-dlp (

# Installation :

### Requirements :
### Option 1: Standalone executable (recommended)

Download the latest `SpotFetch.exe` (Windows), `SpotFetch_macos` (macOS), or `SpotFetch_linux` (Linux) from the [Releases page](https://github.com/MrElyazid/SpotFetch/releases/latest).

#### Requirements :

- First make sure you have ffmpeg installed on your machine [Download here](https://ffmpeg.org/download.html).
- Make sure you have [Python](https://www.python.org/downloads/) installed too, and is in your system path.

That's it — just run the downloaded file.

### Option 2: Run from source with Python

#### Requirements :

- Make sure you have [Python](https://www.python.org/downloads/) installed and in your system path.
- Make sure you have ffmpeg installed on your machine [Download here](https://ffmpeg.org/download.html).
- If you dont have Git to clone the repo thats fine, you can download it as a zip file and uncompress it, see [here](.github/if_no_git.png).

### setup :
#### setup :

- Clone this repository ( or just download it as a zip file and uncompress it ):

Expand Down Expand Up @@ -58,6 +70,16 @@ It is recommended to use a virtual environement since installing requirements gl
before running `pip install -r requirements.txt` make sure you [create](https://docs.python.org/3/library/venv.html#creating-virtual-environments) and then [activate](https://docs.python.org/3/library/venv.html#how-venvs-work) a venv, and if on Windows and running powershell you might need to run `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` before activating the venv.


### Spotify API Setup (for direct Spotify downloads) :

SpotFetch can download playlists and liked songs directly from Spotify.
A built-in Client ID is provided, so no account setup is needed.

On first use, SpotFetch will open a browser window for you to log in to Spotify and authorize the app.
Your session is saved for future use (no need to log in again).

To use your own Spotify app instead (optional), set the `SPOTIFY_CLIENT_ID` environment variable.

## Some details :


Expand Down
52 changes: 52 additions & 0 deletions bundle/pyinstaller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
import os
import sys
import platform

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from PyInstaller.__main__ import run as run_pyinstaller

NAME = "SpotFetch"
ENTRY_POINT = "menu.py"

OS_NAME = sys.platform
MACHINE = platform.machine().lower()

if OS_NAME == "win32":
SUFFIX = ""
EXT = ".exe"
elif OS_NAME == "darwin":
SUFFIX = "_macos"
EXT = ""
else:
SUFFIX = "_linux"
EXT = ""

out_name = f"{NAME}{SUFFIX}{EXT}"
dist_path = os.path.join("dist", out_name)


def main():
opts = [
f"--name={NAME}",
"--noconfirm",
"--onefile",
"--console",
"--add-data=README.md:.",
*sys.argv[1:],
ENTRY_POINT,
]

print(f"Building {out_name} for {sys.platform} {MACHINE}")
print(f"Destination: {dist_path}")
print(f"PyInstaller args: {opts}\n")

run_pyinstaller(opts)

final = dist_path if os.path.exists(dist_path) else f"dist/{NAME}{EXT}"
print(f"\nDone: {final}")


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions bundle/requirements/pyinstaller.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pyinstaller>=6.0
Loading
Loading