diff --git a/README.md b/README.md index 5571495..d8879db 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,86 @@ # CICK Playlister -Tool to support data entry on CICK website. See [usage](./USAGE.md) for more information. +Tool to support data entry on the CICK site's "Create Playlist" page. See [usage](./USAGE.md) for more information on using the tool. -## Testing +## Overview -Automated testing is still outstanding. This project has limited resources and rapid output has so far been prioritised over rigorous testing. +The tool has three components: a server, a client, and a bookmarklet. -## Environment Setup +The server component manages communication with streaming service API(s) to retrieve track data for playlists, albums, and tracks. It exposes a number of endpoints that can be viewed with Swagger at [http://localhost:8123/docs/swagger/](http://localhost:8123/docs/swagger/). Credentials are required to interact with stream service API(s) (see below). + +The client component presents a simple modal to the user that accepts URLs for playlists, albums, and tracks. It communicates with the server component to retrieve track data, and fills input fields on the "Create Playlist" page. + +The bookmarklet launches the client component. It will only proceed if the current `window.location.href` is either the CICK website or a `file://` path (indicating local development). + +## Testing, CI/CD + +Automated testing is still outstanding. This project has limited resources and rapid output has so far been prioritised over rigorous testing. + +_Eventually_ automated testing and a proper CI/CD pipeline will be in place. + +## Release + +> [!NOTE] +> Requires Bash, Docker + +> [!IMPORTANT] +> A `credentials.json` file is required to provide credentials for the streaming service API(s). This must be present in `./cmd/cick-playlister` before creating a release. The format is as follows: + +```json +{ + "spotify": { + "client_id": "...", + "client_secret": "..." + } +} +``` + +Output is generated in `./dist/{today's date}` and compiled for Windows to suit the CICK station computer: + +```sh +scripts/release.sh +``` + +A file called `bookmarklet.js` in `./dist/{today's date}` contains code required for the bookmarklet that triggers the input modal. The `credentials.json` file will also be copied to the output location. + +## Development + +> [!NOTE] +> Requires Bash, Docker, Go 1.22.3, Node 20 + +### Client Component + +Start a local watch-build to transpile TypeScript to JavaScript and Less to CSS during development of the client component: -### API -The API backend is written in Go 1.22.3. ```sh -scripts/build.sh # requires Docker +scripts/watch-cilent.sh ``` -### Client -The client is written in TypeScript and assumes >= Node 20 +`./research/songs.html` provides an example of the HTML in the "Create Playlist" page and can be opened in a browser to support development. + +### Server Component + +When the server component is built it bundles the content of `./internal/client/dist` (the client component) and `internal/docs` (OpenAPI & Swagger) in the binary. The server component must be rebuilt and rerun after a change to the client or OpenAPI. To build the client locally (not using Docker, like the release build does): + +```sh +scripts/build.sh ``` -scripts/build-client.sh + +#### Debugging + +If you want to debug the server component, either for problem-solving or simply to avoid the two-step process of rebuilding _and_ rerunning the binary, the following `./vscode/launch.json` configuration can be used (debugging may require some additional tooling in VSCode). You will still have to restart the debugger after a change to the client or server component, but you will not have to explicitly rebuild it: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/cick-playlister/" + } + ] +} ``` diff --git a/USAGE.md b/USAGE.md index 6c0e1c1..bd6a983 100644 --- a/USAGE.md +++ b/USAGE.md @@ -20,7 +20,7 @@ Clicking the bookmark will bring up a window with a single text input field. Pas The tool will fetch track information and fill the playlist's `ARTIST`, `TITLE`, `ALBUM`, and `NEW` fields. > [!IMPORTANT] -> The tool cannot fill the CAN (Canadian Content) field - this is your responsibility. +> The tool cannot fill the CAN (Canadian Content) field - this is still your responsibility. ## Limitations diff --git a/research/curl.txt b/research/curl.txt deleted file mode 100755 index 651f424..0000000 --- a/research/curl.txt +++ /dev/null @@ -1,19 +0,0 @@ -curl 'https://www.smithersradio.com/node/add/station-playlist/23299' \ - -H 'authority: www.smithersradio.com' \ - -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \ - -H 'accept-language: en-US,en;q=0.9' \ - -H 'cache-control: max-age=0' \ - -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundaryb9ZdBINzBB6sb7Pz' \ - -H 'cookie: [...]' \ - -H 'origin: https://www.smithersradio.com' \ - -H 'referer: https://www.smithersradio.com/node/add/station-playlist/23299' \ - -H 'sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"' \ - -H 'sec-ch-ua-mobile: ?0' \ - -H 'sec-ch-ua-platform: "Windows"' \ - -H 'sec-fetch-dest: document' \ - -H 'sec-fetch-mode: navigate' \ - -H 'sec-fetch-site: same-origin' \ - -H 'sec-fetch-user: ?1' \ - -H 'upgrade-insecure-requests: 1' \ - -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' \ - --data-raw $'------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="changed"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="form_build_id"\r\n\r\nform-NvDe04ZYf9YisF4hk_8Wqcupc12m59e90CNFtsP_KBE\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="form_token"\r\n\r\nmblquN_St_F79AXwmNImPKIFUymDa3-6xQAu2Y6c9mI\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="form_id"\r\n\r\nstation_playlist_node_form\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="body[und][0][summary]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="body[und][0][value]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="body[und][0][format]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="files[field_playlist_photo_und_0]"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_photo[und][0][fid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_photo[und][0][display]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_photo[und][0][resup]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_station_playlist_date[und][0][value][month]"\r\n\r\n3\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_station_playlist_date[und][0][value][day]"\r\n\r\n19\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_station_playlist_date[und][0][value][year]"\r\n\r\n2024\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_station_program[und][0][nid]"\r\n\r\nFace for Radio [nid:23299]\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][0][fid]"\r\n\r\n7850\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][0][display]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][0][_weight]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="files[field_playlist_audio_und_1]"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][1][_weight]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][1][fid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][1][display]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="field_playlist_audio[und][1][resup]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][artist]"\r\n\r\nFour Tet\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][title]"\r\n\r\nThree Drums\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][album]"\r\n\r\nSingle\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[0][weight]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][artist]"\r\n\r\nFlume\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][title]"\r\n\r\nThe difference (High contrast remix)\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][album]"\r\n\r\nThe difference (remixes)\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[1][weight]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][artist]"\r\n\r\nSquarepusher\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][title]"\r\n\r\nMy red hot car\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][album]"\r\n\r\nGo plastic \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[2][weight]"\r\n\r\n2\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][artist]"\r\n\r\nHigh contrast\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][title]"\r\n\r\n20th century jungle\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][album]"\r\n\r\nAnti/thesis vol.1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[3][weight]"\r\n\r\n3\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][artist]"\r\n\r\nMac Demarco\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][title]"\r\n\r\nChamber of Reflection\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][album]"\r\n\r\nSalad Days \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][cancontrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[4][weight]"\r\n\r\n4\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][artist]"\r\n\r\nThe initiates Piece\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][title]"\r\n\r\nReal bad man, lukah, billy woods\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][album]"\r\n\r\nTemple needs water. Village needs peace \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[5][weight]"\r\n\r\n5\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][artist]"\r\n\r\nChuck Strangers\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][title]"\r\n\r\nPolish Jazz (feat. Joey Bada$$)\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][album]"\r\n\r\nA foresaken lover\'s plea\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[6][weight]"\r\n\r\n6\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][artist]"\r\n\r\nMIKE, Tony Seltzer\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][title]"\r\n\r\nSkurr\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][album]"\r\n\r\nPinball \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[7][weight]"\r\n\r\n7\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][artist]"\r\n\r\nTierra Whack\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][title]"\r\n\r\nBURNING BRAINS\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][album]"\r\n\r\nPost Touch\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[8][weight]"\r\n\r\n8\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][artist]"\r\n\r\nChanel Beads\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][title]"\r\n\r\nEmbarrassed Dog \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][album]"\r\n\r\nYour day will come\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[9][weight]"\r\n\r\n9\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][artist]"\r\n\r\nGold Era\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][title]"\r\n\r\nXFINITY\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][album]"\r\n\r\nG Miner\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][cancontrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[10][weight]"\r\n\r\n10\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][artist]"\r\n\r\nDriving with no sound\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][title]"\r\n\r\nSunday Cruise\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][album]"\r\n\r\nArt of of Reflecting \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[11][weight]"\r\n\r\n11\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][artist]"\r\n\r\nGee Tee\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][title]"\r\n\r\nSomeone Else\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][album]"\r\n\r\nRock phone\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[12][weight]"\r\n\r\n12\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][artist]"\r\n\r\nChaepter\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][title]"\r\n\r\nPost-Touch\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][album]"\r\n\r\nSingle\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[13][weight]"\r\n\r\n13\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][artist]"\r\n\r\nDrahla\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][title]"\r\n\r\nDefault Parody\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][album]"\r\n\r\nangeltape\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[14][weight]"\r\n\r\n14\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][artist]"\r\n\r\nGalt MacDermot\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][title]"\r\n\r\nPrincess Gika\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][album]"\r\n\r\nangeltape\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][cancontrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[15][weight]"\r\n\r\n15\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][artist]"\r\n\r\nWild Pink\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][title]"\r\n\r\nAir Drumming fix you\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][album]"\r\n\r\nair drumming for you \r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][newtrack]"\r\n\r\n1\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[16][weight]"\r\n\r\n16\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[17][weight]"\r\n\r\n17\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[18][weight]"\r\n\r\n18\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[19][weight]"\r\n\r\n19\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[20][weight]"\r\n\r\n20\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[21][weight]"\r\n\r\n21\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[22][weight]"\r\n\r\n22\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[23][weight]"\r\n\r\n23\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[24][weight]"\r\n\r\n24\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[25][weight]"\r\n\r\n25\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[26][weight]"\r\n\r\n26\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[27][weight]"\r\n\r\n27\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[28][weight]"\r\n\r\n28\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[29][weight]"\r\n\r\n29\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[30][weight]"\r\n\r\n30\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[31][weight]"\r\n\r\n31\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[32][weight]"\r\n\r\n32\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[33][weight]"\r\n\r\n33\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[34][weight]"\r\n\r\n34\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[35][weight]"\r\n\r\n35\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[36][weight]"\r\n\r\n36\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[37][weight]"\r\n\r\n37\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[38][weight]"\r\n\r\n38\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][artist]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][title]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][album]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][label]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][stationid]"\r\n\r\n0\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][link]"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="tracks[39][weight]"\r\n\r\n39\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="additional_settings__active_tab"\r\n\r\n\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz\r\nContent-Disposition: form-data; name="op"\r\n\r\nSave\r\n------WebKitFormBoundaryb9ZdBINzBB6sb7Pz--\r\n' \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh index 40c66ab..b790133 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,29 +3,5 @@ set -e -pushd $(dirname $0)/.. - -scripts/validate-openapi.sh -scripts/build-client.sh - -date_tag=$(date +%Y-%m-%d) -local_output_dir=$(pwd)/dist/$date_tag -mkdir -p $local_output_dir - -cp bookmarklet.js $local_output_dir/ -if [ -f cmd/cick-playlister/credentials.json ]; then - cp cmd/cick-playlister/credentials.json $local_output_dir/ -fi - -image_name="captaincoordinates/cick-playlister-builder" - -docker build \ - -t $image_name \ - -f scripts/api/Dockerfile \ - --build-arg date_tag=${date_tag} \ - . - -docker run \ - --rm \ - -v $(pwd)/dist:/src/dist:rw \ - $image_name +pushd $(dirname $0)/../cmd/cick-playlister +go build cick-playlister.go diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..40c66ab --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,31 @@ +#!/bin/bash + + +set -e + +pushd $(dirname $0)/.. + +scripts/validate-openapi.sh +scripts/build-client.sh + +date_tag=$(date +%Y-%m-%d) +local_output_dir=$(pwd)/dist/$date_tag +mkdir -p $local_output_dir + +cp bookmarklet.js $local_output_dir/ +if [ -f cmd/cick-playlister/credentials.json ]; then + cp cmd/cick-playlister/credentials.json $local_output_dir/ +fi + +image_name="captaincoordinates/cick-playlister-builder" + +docker build \ + -t $image_name \ + -f scripts/api/Dockerfile \ + --build-arg date_tag=${date_tag} \ + . + +docker run \ + --rm \ + -v $(pwd)/dist:/src/dist:rw \ + $image_name