Skip to content
Open
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
36 changes: 36 additions & 0 deletions .github/workflows/update-formula.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Update Homebrew Formula

on:
release:
types: [published]

jobs:
update-formula:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version
id: release
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Download tarball and compute SHA256
run: |
curl -sL https://github.com/${{ github.repository }}/archive/refs/tags/v${{ steps.release.outputs.version }}.tar.gz -o tarball.tar.gz
SHA256=$(shasum -a 256 tarball.tar.gz | cut -d' ' -f1)
echo "sha256=$SHA256" >> $GITHUB_ENV
sed -i "s|v1\.0\.2|v${{ steps.release.outputs.version }}|g" Formula/songfetch.rb
sed -i "s|PLACEHOLDER_SHA256|$SHA256|" Formula/songfetch.rb
- name: Commit and push changes
run: |
git add Formula/songfetch.rb
if git diff --cached --quiet; then
echo "No changes to commit"
else
git config --global user.name 'GitHub Actions'
git config --global user.email '[email protected]'
git commit -m "Update formula to v${{ steps.release.outputs.version }}"
git push
fi
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ venv/

# Python cache
__pycache__/

# egg
*.egg-info/
17 changes: 17 additions & 0 deletions Formula/songfetch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Songfetch < Formula
desc "A CLI tool that displays current song information in the terminal"
homepage "https://github.com/fwtwoo/songfetch"
url "https://github.com/fwtwoo/songfetch/archive/refs/tags/v1.0.2.tar.gz"
sha256 "1b4c73283d7b5981b314ae3f77b6150947077aa505ab8869bb12bce0df6f7bf4"
license "GPL-2.0"

depends_on "[email protected]"

def install
system "python3", "-m", "pip", "install", "--prefix=#{prefix}", "."
end

test do
system "#{bin}/songfetch", "--help"
end
end
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ Then install the full program:
yay -S songfetch
```

## Installation (Homebrew/MacOS):

```bash
brew tap fwtwoo/songfetch https://github.com/fwtwoo/songfetch
brew install songfetch
```

## Dependencies:
```bash
python
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
]

[project.scripts]
Expand Down
10 changes: 10 additions & 0 deletions src/songfetch/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import platform

if platform.system() == 'Darwin':
from .player_utils_mac import *
elif platform.system() == 'Linux':
from .player_utils_linux import *
else:
# Fallback to Linux for other systems
from .player_utils_linux import *

21 changes: 14 additions & 7 deletions src/songfetch/ascii_convert.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import ascii_magic as magic, urllib.parse, urllib.request, tempfile
import ascii_magic as magic
import urllib.parse
import urllib.request
import tempfile
from importlib import resources


def default_art(file="../assets/default_art.txt"):
# Get the default music note art from file
with resources.files("songfetch.assets").joinpath("default_art.txt").open("r", encoding="utf-8") as f:
with resources.files("songfetch.assets").joinpath(
"default_art.txt"
).open("r", encoding="utf-8") as f:
return f.read().split('\n')

# Art to ASCII


def convert(art_uri):
# Init variables
ascii_art_lines = None
# Check file type
if art_uri is None or art_uri.strip() == "": # If return empty string
if art_uri is None or art_uri.strip() == "": # If return empty string
return default_art()

# We need to check each URI type
Expand All @@ -22,7 +30,7 @@ def convert(art_uri):
# Decode to get rid of possible "%20%20..."
ascii_art = magic.from_image(urllib.parse.unquote(new_uri))
# Convert to ascii
ascii_string = ascii_art.to_ascii(columns = 60, width_ratio = 2.2)
ascii_string = ascii_art.to_ascii(columns=60, width_ratio=2.2)
ascii_art_lines = ascii_string.split('\n')

# Catch the error
Expand All @@ -39,11 +47,11 @@ def convert(art_uri):
urllib.request.urlretrieve(art_uri, temp.name)
ascii_art = magic.from_image(temp.name)
# Convert to ascii
ascii_string = ascii_art.to_ascii(columns = 60, width_ratio = 2.2)
ascii_string = ascii_art.to_ascii(columns=60, width_ratio=2.2)
ascii_art_lines = ascii_string.split('\n')

# Catch the error
except Exception as e :
except Exception as e:
return default_art()

# Edge cases
Expand All @@ -55,4 +63,3 @@ def convert(art_uri):
return ascii_art_lines
else:
return default_art()

Empty file.
77 changes: 46 additions & 31 deletions src/songfetch/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
from songfetch.ascii_convert import convert
from songfetch.player_utils import (
from songfetch import (
get_art,
get_loop,
get_shuffle,
Expand All @@ -18,6 +18,7 @@
get_position
)


def progress_bar():
# Calculate percentage
pos = get_position()
Expand Down Expand Up @@ -46,6 +47,7 @@ def progress_bar():

return fprint + eprint + display_str


def get_info_line():
# Get some strings to use later
line = f"\033[34m─────────────────────────────────────────\033[0m"
Expand All @@ -65,34 +67,36 @@ def get_info_line():
# Here we concatenate all the info into one list
# Use ANSI escape sequences to style the colors
info_lines = [
# Print username and track data
f"\033[1;34m{get_user()}\033[0m@\033[1;34m{get_player_name()}\033[0m",
line, f"\033[97m{now_playing}\033[0m", line,
f"\033[34mTitle\033[0m: {get_title()}",
f"\033[34mArtist\033[0m: {get_artist()}",
f"\033[34mAlbum\033[0m: {get_album()}",
f"\033[34mDuration\033[0m: {get_duration_formatted()}",
f"\033[34m{progress_bar()}\033[0m",

# Print player data
line, f"\033[97m{playback_info}\033[0m", line,
f"\033[34mStatus\033[0m: {get_status()}",
f"\033[34mVolume\033[0m: {get_volume()}",
f"\033[34mLoop\033[0m: {get_loop()}",
f"\033[34mShuffle\033[0m: {get_shuffle()}",
f"\033[34mPlayer\033[0m: {get_player_name()}",
f"\033[34mURL\033[0m: {get_url()}",

# Print system data
line, f"\033[97m{audio_system}\033[0m", line,
f"\033[34mBackend\033[0m: {get_backend()}",
"",
# Print palette
normal, bright
]
# Print username and track data
f"\033[1;34m{get_user()}\033[0m@\033[1;34m{get_player_name()}\033[0m",
line, f"\033[97m{now_playing}\033[0m", line,
f"\033[34mTitle\033[0m: {get_title()}",
f"\033[34mArtist\033[0m: {get_artist()}",
f"\033[34mAlbum\033[0m: {get_album()}",
f"\033[34mDuration\033[0m: {get_duration_formatted()}",
f"\033[34m{progress_bar()}\033[0m",

# Print player data
line, f"\033[97m{playback_info}\033[0m", line,
f"\033[34mStatus\033[0m: {get_status()}",
f"\033[34mVolume\033[0m: {get_volume()}",
f"\033[34mLoop\033[0m: {get_loop()}",
f"\033[34mShuffle\033[0m: {get_shuffle()}",
f"\033[34mPlayer\033[0m: {get_player_name()}",
f"\033[34mURL\033[0m: {get_url()}",

# Print system data
line, f"\033[97m{audio_system}\033[0m", line,
f"\033[34mBackend\033[0m: {get_backend()}",
"",
# Print palette
normal, bright
]
return info_lines

# Main function


def main():
# Get terminal size
columns = os.get_terminal_size().columns
Expand All @@ -107,25 +111,36 @@ def main():
else:
art_col = convert(get_art())
# Find the longest line in both column lists
max_art = max(len(x) for x in art_col)
if art_col:
max_art = max(len(x) for x in art_col)
else:
max_art = 0

# Always get info lines though
info_col = get_info_line()
max_info = max(len(y) for y in info_col[:-2])
if len(info_col) > 2:
max_info = max(len(y) for y in info_col[:-2])
else:
max_info = 0

# Ensure minimum widths, caused crashes by empty art/info
art_width = max(1, max_art - 2)
info_width = max(1, max_info)

# Print lists next to each other when one list may be longer than the other:
# Print lists next to each other when one may be longer
if len(art_col) > len(info_col): # Compare lenghts
# Replace but with added padding (spaces)
new_info_col = info_col + [''] * (len(art_col) - len(info_col))
# Loop through all lines in art
for i in range(len(art_col)):
print(f"{art_col[i]:{max_art-2}}{new_info_col[i]:{max_info}}")
print(f"{art_col[i]:{art_width}}{new_info_col[i]:{info_width}}")
else:
# Pad but the othre way around
new_art_col = art_col + [''] * (len(info_col) - len(art_col))
# Loop all lines in info
for j in range(len(info_col)):
print(f"{new_art_col[j]:{max_art-2}}{info_col[j]:{max_info}}")
print(f"{new_art_col[j]:{art_width}}{info_col[j]:{info_width}}")


# Run the program
if __name__ == "__main__":
Expand Down
File renamed without changes.
Loading