GithubHelp home page GithubHelp logo

melipass / lastfm-to-markdown Goto Github PK

View Code? Open in Web Editor NEW
36.0 36.0 5.0 321 KB

GitHub Actions workflow that automatically updates the covers from your last.fm's weekly chart everyday, inside your profile repository's README.md file. Useful for customizing your profile in repos named after your GitHub username.

License: MIT License

Python 100.00%
api github-actions lastfm lastfm-api lastfm-collage-generator markdown python workflow

lastfm-to-markdown's Introduction

Hola ✨

Hi! My name is Melissa, my pronouns are she/her or they/them, and I'm a Computer Engineer from Santiago, Chile. I'm fluent in Spanish and English, and understand Italian, Portuguese and Català at different levels.

My latest gig was at Bending Spoons, working as a Security and Privacy Engineer. Previously worked as a Security Engineer at Evernote. In the past, I was part of Universidad Mayor's Quantum Computing research group, I've worked as a Data Engineering and Data Science Intern at Walmart Chile, and also worked on High Performance Computing for Quantum Physics at the Herrera Lab.

🎵 Albums I've listened the most this week

These album covers are automatically updated from last.fm using this GitHub Actions workflow I wrote, feel free to use it.

lastfm-to-markdown's People

Contributors

actions-user avatar helloyeew avatar melipass avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

lastfm-to-markdown's Issues

lastfm-to-markdown suggestions!

Hey! This project is pretty sick so on behalf of us music fans, I decided to make it so it would output 8 images (medium-sized) with white captions like how Last.FM collages generally do it so the cover wouldn't render in such a poor resolution for captions at the smallest size.

Here's how lastfmweekly.yml would look:

name: lastfmweekly

on:
  schedule:
    - cron: "2 0 * * *"
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  # This workflow contains a single job called "build"
  build:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - name: repo checkout
        uses: actions/checkout@v2

      - name: python setup
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'

      - name: python packages installation
        run: |
          python -m pip install --upgrade pip
          pip install -r dependencies.txt
      - name: use lastfm api
        env:
          LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }}
          LASTFM_USER: ${{ secrets.LASTFM_USER }}
          IMAGE_COUNT: 8
        run: python lastfm.py

      - name: commit changes
        continue-on-error: true
        run: |
          git config --local user.email "[email protected]"
          git config --local user.name "GitHub Action"
          git add -A
          git commit -m "Updated last.fm's weekly chart" -a
        
      - name: push changes
        continue-on-error: true
        uses: ad-m/[email protected]
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}\
          branch: main
  

Here's how lastfm.py would look

import requests 
import sys
from PIL import Image, ImageFont, ImageDraw 
import urllib.request
import os

def lastfm_request(payload):
    headers = {"user-agent": os.getenv("LASTFM_USER")}
    payload["api_key"] = os.getenv("LASTFM_API_KEY")
    payload["format"] = "json"
    payload["user"] = os.getenv("LASTFM_USER")
    response = requests.get("https://ws.audioscrobbler.com/2.0/",
                            headers=headers, params=payload)
    return response

def get_weekly_album_chart():
    payload = {"method": "user.getweeklyalbumchart"}
    data = lastfm_request(payload).json()["weeklyalbumchart"]["album"]
    artist_and_album = []
    for i in range(len(data)):
        artist_and_album.append([data[i]["artist"]["#text"],
                                data[i]["name"]])
    return artist_and_album


def get_album_covers(artist_and_album):
    images = []
    for album in artist_and_album:
        payload = {"method": "album.getinfo",
                   "artist": album[0],
                   "album": album[1]}
        request_response = lastfm_request(payload).json()
        url = request_response["album"]["image"][2]["#text"] """ this would be "[2] medium" instead of "[1] small" since readers wouldn't be able to make this out """
        link_to_album = request_response["album"]["url"]
        if (url != ""):
            images.append([album[0], album[1], url, link_to_album]) 
    return images


def update_readme(images):
    with open("README.md", "r", encoding="utf-8") as file:
        readme = file.readlines()
    lastfm_line_index = readme.index("<!-- lastfm -->\n") + 1
    lastfm_line = '<p align="center">'
    i = 0
    for img in images:
        if (i < int(os.getenv("IMAGE_COUNT"))):
            if (requests.get(img[2]).status_code == 200):   

                list = ["album-covers", "album-covers-finished"]
                for items in list:
                    os.makedirs(items, exist_ok=True)

                urllib.request.urlretrieve(img[2], f"./album-covers/album-cover_{i}.png")
                my_image = Image.open(f"./album-covers/album-cover_{i}.png")  
                image_editable = ImageDraw.Draw(my_image) 
                image_editable.text((1,1), f"{img[0]}\n{img[1]}", (252, 255, 250), font=ImageFont.truetype("./fonts/basic_sans_serif_7.ttf", 10)) """ Locally download basic_sans_serif_7.ttf into /fonts/ directory for usage """
                my_image.save(f"./album-covers-finished/album-cover_final_{i}.png")
                
                lastfm_line += f'<a href="{img[3]}"><img src="./album-covers-finished/album-cover_final_{i}.png" title="{img[0]} - {img[1]}"></a> '
                i = i + 1
            else:
                pass
        else:
            break
    if (readme[lastfm_line_index] == lastfm_line):
        sys.exit(0)
    else:
        lastfm_line = lastfm_line + "</p>\n"
        readme[lastfm_line_index] = lastfm_line
    with open("README.md", "w", encoding="utf-8") as file:
        file.writelines(readme)

update_readme(get_album_covers(get_weekly_album_chart()))

For dependencies.txt, we'd only need to download one more module:

requests==2.25.1
Pillow==9.1.1

Here's how it would look on my end. Assuming that each album I've listened to has a Lastfm page, I've removed the if os.getenv("INCLUDE_LINK") == "false": portions and action.yml

image

Thanks a lot for looking at this, and I hope that I contributed in a constructive manner!

Option for top Artists or Tracks

It'd be awesome to be able to pick top artists or tracks for the week rather than only albums. As someone who doesn't really listen to full albums (and a lot more singles or soundcloud/youtube release stuff that isn't really part of an album at all), I tend to care more about top artists rather than albums.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.