{"id":18421886,"url":"https://github.com/mihaiolteanu/lastfm","last_synced_at":"2026-02-04T18:01:21.794Z","repository":{"id":83101421,"uuid":"191360166","full_name":"mihaiolteanu/lastfm","owner":"mihaiolteanu","description":"Last.fm API for Common Lisp ","archived":false,"fork":false,"pushed_at":"2019-08-29T09:21:31.000Z","size":54,"stargazers_count":16,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-10T15:07:20.622Z","etag":null,"topics":["api","common-lisp","lastfm"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mihaiolteanu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-11T11:43:10.000Z","updated_at":"2024-07-29T09:30:09.000Z","dependencies_parsed_at":"2024-01-07T09:00:25.420Z","dependency_job_id":null,"html_url":"https://github.com/mihaiolteanu/lastfm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mihaiolteanu/lastfm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaiolteanu%2Flastfm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaiolteanu%2Flastfm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaiolteanu%2Flastfm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaiolteanu%2Flastfm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mihaiolteanu","download_url":"https://codeload.github.com/mihaiolteanu/lastfm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaiolteanu%2Flastfm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29092707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","common-lisp","lastfm"],"created_at":"2024-11-06T04:27:12.070Z","updated_at":"2026-02-04T18:01:21.774Z","avatar_url":"https://github.com/mihaiolteanu.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lastfm\nInterface for the [last.fm](https://www.last.fm) [API](https://www.last.fm/api),\nincluding the services that need authentication and song generators for extra\nfunctionality.\n\n# Installation\n\n## 1. Install the library\n\nUsing quickload\n```common-lisp\n(ql:quickload :lastfm)\n```\n\nOr clone it to local-projects \n```bash\ngit clone https://github.com/mihaiolteanu/lastfm ~/quicklisp/local-projects/lastfm\n```\n\n```common-lisp\n; Register the new project\n(ql:register-local-projects)\n```\n\n## 2. Obtain the last.fm API key\nTo use this library, a last.fm API Key is needed. For that you need a last.fm\naccount and then an API account. Follow the instructions from the official\n[documentation](https://www.last.fm/api) page and you will receive and api-key\nand a shared secret. Write them down.\n\n## 3. Create or update the config file with the API key\nCreate a config file with the info received from last.fm on step one.\n\n```common-lisp\n;; .lastfmrc\n(CONFIG\n :API-KEY \"yout-api-key-string\"\n :SHARED-SECRET \"your-shared-secret-string\"\n :USERNAME \"your-last-fm-username\")\n```\n\nThis file is usually located at `~/.config/.lastfmrc`. If you want to be\nabsolutely sure, evaluate `(xdg-config-home)` to find out where your config\nfolder is located. Then create the `.lastfmrc` config file there with the\ncontents from above.\n\nOne thing missing from this config file is the secret key (SK) which will be\nadded by this library after the authentication process (see below) is\ncompleted. The authentication only needs to be done once.\n\n## 4. Generate the session key\n\nLoad the library and generate the session key by calling the appropriate interface.\n```common-lisp\n(ql:quickload :lastfm)\n(lastfm:generate-session-key)\n```\nThis will open up the [last.fm/api/auth](last.fm/api/auth) page in your\nfavorite browser and put a breakpoint in the code (My app is called muse, in\nthis case. Yours might differ).\n \n \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\n \u003cimg\n src=\"https://user-images.githubusercontent.com/8273519/59293481-f4614600-8c87-11e9-9320-7f97bb135c44.png\"\n alt=\"grant permission to last.fm\" width=\"600px\"/\u003e\n\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n \nYou will need to grant this\n `lastfm` library permission to use your last.fm account ([step\n 3](https://www.last.fm/api/desktopauth) in the official last.fm authentication\n process). \n \n \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\n \u003cimg\n src=\"https://user-images.githubusercontent.com/8273519/59293493-f7f4cd00-8c87-11e9-8ea3-ebee572bf53f.png\"\n alt=\"permission granted\" width=\"600px\"/\u003e\n\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n \nAfter that, return to your editor (Emacs) and continue from breakpoint.\n \n \u003cimg\n src=\"https://user-images.githubusercontent.com/8273519/59293499-fa572700-8c87-11e9-87a6-0cdaea1efbb9.png\"\n alt=\"continue from breakpoint\"/\u003e\n \nIf this step is succesful, the secret key will be added to your\nconfig file, which should now look like this:\n```common-lisp\n;; ~/.lastfmrc\n(CONFIG\n :API-KEY \"yout-api-key-string\"\n :SHARED-SECRET \"your-shared-secret-string\"\n :USERNAME \"your-last-fm-username\"\n :SK \"your-secret-key-generated-at-step-four\")\n``` \n\nIf you don't follow this step, the lastfm services that need\nauthentication (love/unlove track, scrobble track) won't work.\n\nKeep this file in a safe place. The next time you install lastfm on a\nnew computer, you only need to copy this file into the correct\nlocation and skip all these authentication steps.\n\n# Usage\n\n```common-lisp\n; Get the first top tracks for the given artist.\n(artist-gettoptracks \"anathema\" 5)\n    =\u003e (\"Fragile Dreams\" \"One Last Goodbye\" \"A Natural Disaster\" \"Flying\" \"Deep\")\n```\n\n```common-lisp\n; Get the best ten artist from the 80s.\n(tag-gettopartists \"80s\" 10)\n    =\u003e (\"Duran Duran\" \"a-ha\" \"Hall \u0026 Oates\" \"Cyndi Lauper\" \"Eurythmics\" \"Erasure\"\n        \"Wham!\" \"Alphaville\" \"Men at Work\" \"Bonnie Tyler\")\n```\n\n```common-lisp\n; If step four was done, this will add the song to your last.fm loved tracks.\n(track-love \"alphaville\" \"forever young\")\n```\n\n```common-lisp\n;; Extra functionality not covered by the last.fm API\n(ql:quickload :generators)\n\n; Get a generator with the first 5 toptracks from the artist\n(defparameter *anathema*\n  (artist-songs \"anathema\" 5 T))\n  \n; Calling next on the generator will return a random song. The list is\n; infinite. If the random parameter is nil instead of T, the generator is\n; circular, but still infinite\n(next *anathema*)\n    =\u003e (\"anathema\" \"Fragile Dreams\")\n(next *anathema*)\n    =\u003e (\"anathema\" \"One Last Goodbye\")\n(next *anathema*)\n    =\u003e (\"anathema\" \"Fragile Dreams\") \n```\n\n# API\n\n## last.fm API interfaces\nThe following last.fm API interfaces are implemented by this library. `limit`\nmeans the number of items to return. Browse the official [last.fm\nAPI](www.last.fm/api) page for further details. All interfaces that don't need\nauthentication are memoized. A second call with the exact same parameters will\nbe much faster and it won't result in a fresh last.fm request.\n\n**album-getinfo** _artist album_\n\n**artist-getinfo** _artist_\n\n**artist-getsimilar** _artist limit_\n\n**artist-gettoptags** _artist_\n\n**artist-gettopalbums** _artist limit_\n\n**artist-gettoptracks** _artist limit_\n\n**artist-search** _artist limit_\n\n    Search for a given artist and return limit number of matches as best guesses.\n\n**tag-getinfo** _tag_\n\n**tag-gettoptracks** _tag limit_\n\n**tag-gettopartists** _tag limit_\n\n**user-getlovedtracks** _user limit_\n\n**track-love** _artist track_\n    \n    Add this track to the list of user's loved track. The username is the one\n    specified in the .lastfmrc config file. Authentication needed (step 4)\n\n**track-unlove** _artist track_\n\n    Remove this track to the list of user's loved track. The username is the one\n    specified in the .lastfmrc config file. Authentication needed (step 4).\n\n**track-scrobble** _artist track timestamp_ \n\n    Authentication needed (step 4)\n    Timestamp must be in UNIX timestamp format. For example\n    \n    (ql:quickload :local-time)\n    (track-scrobble \"anathema\" \"one last goodbye\"\n        (local-time:timestamp-to-unix (local-time:now)))\n\n## Random items\nExtra useful functionality not covered by the last.fm API, but built on top of\nit and that you might find useful.\n\n**song-youtube-url** _artist song_\n\n    Since there is no youtube link available through the last.fm API,\n    try and get it from the last.fm song's page.\n\n**random-artist-song** _artist \u0026optional (limit 20)_\n\n**random-similar-artist** _artist \u0026optional (limit 20)_\n\n**random-user-loved-song** _user \u0026optional (limit 20)_\n\n**random-tag-song** _tag \u0026optional (limit 20)_\n\n**random-tag-artist** _tag \u0026optional (limit 20)_\n\n## Generators\nThese will return generators that can be used by calling next on\nthem. On each call, a new item is received. If the `random` parameter, where\navailable, is specified as T, a random elemenent is received on each\ncall. Otherwise, the elements are returned in order, as they appear on their\nrespective last.fm page. After the last element is returned, the `next` call\nwill again return the first one (i.e. the generator is cyclic). You need to\nuse the [generators](http://quickdocs.org/generators/) library for\nthat. `nparameters` specify the number of elements to be taken into\nconsideration, similar to the `limit` parameter in the last.fm API case.\n\n**artist-songs** _artist nsongs random_\n\n    A generator for the artist's first best nsongs \n\n**album-songs** _artist album_\n\n    Return a non-random generator with all the songs on the artist's album.\n\n**tag-songs** _tagname nsongs random_\n\n    Best nsongs generators for the given tag.\n\n**user-songs** _username nsongs random_\n\n    Return a generator with songs from a user of your choice.\n    \n**my-loved-songs** _nsongs random_\n    \n    Return a generator with the current user loved songs. The username is the\n    one specified in the .lastfmrc config file.\n\n**artist-similar-artists-songs** _artist nartists nsongs_\n\n    Each call will first pick a random artist from the list of similar artists\n    and then pick a random song from this chosen artist. This is a random generator.\n\n**tag-similar-artists-songs** _tag nartists nsongs_\n\n    Each call will first pick a random artist from the list of top artists for this tag\n    and then pick a random song from this chosen artist. This is a random generator.\n\n## Authors\nCopyright (c) 2019 [Mihai Olteanu](www.mihaiolteanu.me)\n\nLicensed under the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmihaiolteanu%2Flastfm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmihaiolteanu%2Flastfm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmihaiolteanu%2Flastfm/lists"}