{"id":28180037,"url":"https://github.com/rubbaboy/qilletni","last_synced_at":"2025-05-16T02:14:38.601Z","repository":{"id":287626834,"uuid":"778053402","full_name":"RubbaBoy/Qilletni","owner":"RubbaBoy","description":"A highly capable Domain Specific Language to programmatically create platform agnostic music queues and playlists","archived":false,"fork":false,"pushed_at":"2025-04-30T22:40:45.000Z","size":1591,"stargazers_count":6,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-08T08:09:07.517Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://qilletni.dev/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RubbaBoy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2024-03-27T01:37:10.000Z","updated_at":"2025-04-30T22:40:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"364f0a60-81fd-4237-981f-5fb6f13e4710","html_url":"https://github.com/RubbaBoy/Qilletni","commit_stats":null,"previous_names":["rubbaboy/qilletni"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubbaBoy%2FQilletni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubbaBoy%2FQilletni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubbaBoy%2FQilletni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubbaBoy%2FQilletni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RubbaBoy","download_url":"https://codeload.github.com/RubbaBoy/Qilletni/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453528,"owners_count":22073618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2025-05-16T02:14:34.246Z","updated_at":"2025-05-16T02:14:38.589Z","avatar_url":"https://github.com/RubbaBoy.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  Qilletni\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e\n    \u003ca href=\"https://qilletni.dev/\"\u003eWebsite\u003c/a\u003e •\n    \u003ca href=\"https://docs.qilletni.dev/\"\u003eLanguage Docs\u003c/a\u003e •\n    \u003ca href=\"https://api.qilletni.dev/\"\u003eNative API Docs\u003c/a\u003e\n  \u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ci\u003e\n    A high-performance DSL for curating music queues and playlists — declarative, composable, and music service-agnostic.\n  \u003c/i\u003e\n\u003c/p\u003e\n\n---\n\n## Overview\n\nQilletni is a **Domain-Specific Language** (DSL) designed to orchestrate and manipulate music queues, playlists, and metadata across multiple streaming platforms.\n\nUnlike traditional API SDKs that require verbose REST wrappers, Qilletni lets you treat songs, playlists, and APIs as native constructs — with type safety, cross-provider conversion, and built-in playlist logic like weighted selection. Extension of the language is easy with a package system, and native methods that seamlessly invoke Java methods. Qilletni is a statically typed, object-oriented language with a familiar C-style syntax that leverages composition over inheritance.\n\n\u003e [!NOTE]\n\u003e Qilletni is currently in beta, so some documentation is still being worked on. Please make an issue if you think something should be added\n\n---\n\n## Key Features\n\n### Music as a First-Class Citizen\n\n- Native types: `song`, `album`, `collection`, `artist`, `weights`\n- The `play` keyword can put songs in your queue, add it to a list, or invoke a callback\n- Streamlined definitions:  \n  ```\n  song mySong = \"Impulse\" by \"Harroway\"\n  album myAlbum = mySong.getAlbum()\n  collection myMix = \"My Playlist\" collection by \"RubbaBoy\"\n  \n  play mySong\n  ```\n\n[Native Types →](https://qilletni.dev/language/types/built_in_types/)\n\n### Intelligent Weighted Playlists\n\n- Weighted selection by percentage or multiplier\n\n- Nested, shuffled, sequential, and function-backed weights\n\n- Custom orchestration logic per playlist, like:\n\n  ```\n  weights myWeights =\n      | 25% \"Track A\" by \"Artist\"   // Play 25% of every song picked from weightedCollection\n      | 5x  \"Track B\" by \"Artist\"   // When shuffling, play 5x more than normal\n      | 10% \"Inner Playlist\" collection by \"username\"    // 10% of every song, play a song from \"Inner Playlist\"\n      |~ 15% someFunctionReturningSong()    // 15% of every song, pick one from this method. Dont do this twice in a row \n  \n  collection weightedCollection = \"My Playlist\" collection by \"username\" weights[myWeights]\n  play weightedCollection limit[5]\n  ```\n\n[Weights →](https://qilletni.dev/language/types/built_in_types/#weights)\n\n### Platform-Agnostic Playback\n\n- Seamlessly switch service providers mid-execution\n\n- Automatic cross-platform conversion for songs and other music types, only when needed\n\n- Example:\n\n  ```\n  provider \"lastfm\"\n  \n  song top = getTopTracks(\"adam\").data[0]  // Get your top song from Last.Fm\n  \n  provider \"spotify\"\n  \n  play top  // Auto-converted \u0026 queued on your Spotify account\n  ```\n\n### Familiar Syntax\n\n- C-style syntax, with some modern additions\n- Object-oriented with [Entities →](https://qilletni.dev/language/types/entities/)\n- Example:\n\n```\nfun generateUniqueRecommendations(alreadyRecommended) {\n    Recommender recommender = new Recommender()\n            ..seedTracks = [\"Truth Serum\" by \"Gutter King\",\n                            \"Spiral\" by \"Feyn Entity\"]\n            ..targetEnergy = 1.0\n            ..targetPopularity = 10\n\n    song[] recs = recommender.recommend(100)\n    Stack recommendations = new Stack()\n\n    for (rec : recs) {\n        if (!alreadyRecommended.containsArtist(rec.getArtist())) {\n            recommendations.push(rec)\n        }\n    }\n    \n    print(\"Generated %d unique recommendations\".format([recommendations.size()]))\n    return recommendations\n}\n```\n\n[Introduction →](https://qilletni.dev/language/introduction/)\n\n### Java + HTTP + Database Interop\n\n- Bind native Java methods to Qilletni functions [Native Bindings →](https://qilletni.dev/native_binding/introduction/)\n- Native `http` and `json` libraries for API integrations\n- `postgres` support with simplified SQL output parsing\n\n------\n\n## Supported Packages\n\nQilletni has modular, versioned packages. Some key official packages include:\n\n| Package                                                  | Description                                                |\n| -------------------------------------------------------- | ---------------------------------------------------------- |\n| [`spotify`](https://qilletni.dev/docs/library/spotify)   | Spotify control, search, queueing, playlist management     |\n| [`lastfm`](https://qilletni.dev/docs/library/lastfm)     | Recent tracks, top artists, listening history              |\n| [`http`](https://qilletni.dev/docs/library/http)         | Basic and advanced HTTP requests                           |\n| [`json`](https://qilletni.dev/docs/library/json)         | Read/write JSON objects and arrays                         |\n| [`postgres`](https://qilletni.dev/docs/library/postgres) | Run queries, bind results to Qilletni objects              |\n| [`metadata`](https://qilletni.dev/docs/library/metadata) | Access and modify song metadata tags, stored in a database |\n\nMore packages are in development and will be distributed via **QPM**, the Qilletni Package Manager (coming soon).\n\n------\n\n## Installation\n\n### 1. Start Postgres (for caching)\n\n```bash\ndocker run -d \\\n  --name qilletni-db \\\n  -p 5435:5432 \\\n  -e POSTGRES_USER=qilletni \\\n  -e POSTGRES_PASSWORD=pass \\\n  -e POSTGRES_DB=qilletni \\\n  -v ~/.qilletni/cache:/var/lib/postgresql/data \\\n  postgres\n```\n\n### 2. Install Qilletni (local or Docker)\n\n**Local (requires Java 22):**\n\n```bash\ncurl https://raw.githubusercontent.com/RubbaBoy/QilletniToolchain/refs/heads/master/scripts/install.sh | bash\nsource ~/.bashrc\nqilletni run your_script.ql\n```\n\n**Docker:**\n\n```bash\ndocker run --rm \\\n  --network host \\\n  -v qilletni-docker:/root \\\n  -v \"$(pwd)\":/data \\\n  ghcr.io/rubbaboy/qilletni:latest \\\n  run your_script.ql\n```\n\nSee [Getting Started →](https://qilletni.dev/quickstart/getting_started/)\n\n------\n\n## Examples\n\nBelow are a couple quick examples. A lot more can be found on the Examples page of the docs [here](https://qilletni.dev/examples/).\n\n### Build and Play a Weighted Playlist\n\n```qilletni\n// Assign songs to weights — \"Track A\" gets played 50% of the time\nweights myMix =\n    | 50% \"Track A\" by \"Artist One\"\n    | 25% \"Track B\" by \"Artist Two\"\n    | 5x  \"Track C\" by \"Artist Three\"\n\n// Use a Spotify playlist with those weights and shuffle order\ncollection source = \"My Spotify Playlist\" collection by \"username\" weights[myMix] order[shuffle]\n\n// Play 20 songs based on weights\nplay source limit[20]\n```\n\nSee [Built-in Types →](https://qilletni.dev/language/types/built_in_types/)\n\n### Cross-Platform Top Songs\n\n```qilletni\nimport \"lastfm:lastfm.ql\"\nimport \"spotify:playlist_tools.ql\"\n\nprovider \"lastfm\"  // All music data is in Last.Fm\n\nPage page = new Page()\n                ..page = 1\n                ..count = 100\n\nLastFmResult result = getTopTracks(\"RubbaBoy\", \"3month\", page)\n\nif (result.isError()) {\n    printf(\"Error: %s\", [result.errorMessage])\n    exit(1)\n}\n\nfor (track : result.wrappedData.getValue()) {  // Print out how many plays per song\n    printf(\"%s\\t plays  %s\", [track.playCount, track.track])\n}\n\nprovider \"spotify\"  // All music data is converted to Spotify when needed\n\ncollection newPlaylist = createPlaylist(\"Top Song Playlist\")  // Create a Spotify playlist\naddToPlaylist(newPlaylist, result.data)  // result.data is a song[]\n\nprint(\"Created a playlist with %s songs\".format([result.data.size()]))\n```\n\nSee [Service Providers →](https://qilletni.dev/language/service_providers/)\n\n------\n\n## Project Structure\n\nQilletni supports both apps and libraries.\n\n```bash\n# Initialize app\nqilletni init my_project/\n\n# Or library\nqilletni init -t library my_library/\n```\n\nEach project includes:\n\n```\nmy_project/\n└── qilletni-src/\n    ├── my_project.ql\n    └── qilletni_info.yml\n```\n\nSee [Project Structure →](https://qilletni.dev/project_structure/)\n\n## Related Repositories\n\nQilletni is broken into a handful of repositories. The standard library and Spotify service provider are in the main repo here, but additional functionality is separated.\n\n[QilletniToolchain](https://github.com/RubbaBoy/QilletniToolchain): The CLI and wrapper for the implementation. This is where the language is packaged and released.\n\n[QilletniDocgen](https://github.com/RubbaBoy/QilletniDocgen): The generator for language docs, hosted at: https://docs.qilletni.dev/\n\n[QilletniDocs](https://github.com/RubbaBoy/QilletniDocs): The markdown docs of the main website, using mkdocs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubbaboy%2Fqilletni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubbaboy%2Fqilletni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubbaboy%2Fqilletni/lists"}