From 6ea66c04070050c981e9fe1c5f172f0faf70f2ac Mon Sep 17 00:00:00 2001 From: Enstrayed <48845980+Enstrayed@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:16:01 -0700 Subject: [PATCH] More repo maintenance & add Readme --- Dockerfile | 9 ---- README.md | 105 ++++++++++++++++++++++++++++++++++++++++++++ config.example.json | 41 ----------------- deprecated/cider.js | 101 ------------------------------------------ docker-compose.yml | 10 ----- package.json | 6 +-- 6 files changed, 106 insertions(+), 166 deletions(-) delete mode 100644 Dockerfile create mode 100644 README.md delete mode 100644 config.example.json delete mode 100644 deprecated/cider.js delete mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index fbcad3c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM node:20 -WORKDIR /app - -RUN git clone https://github.com/enstrayed/enstrayedapi . -RUN git config --global --add safe.directory /app -RUN git show --oneline -s >> GITVERSION -RUN npm install - -ENTRYPOINT [ "node", "index.js" ] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..de1fa55 --- /dev/null +++ b/README.md @@ -0,0 +1,105 @@ +# Enstrayed API +This repository contains the code for my personal web API written in JavaScript using the Express framework. + +## Documentation +This file contains documentation relevant for development and deployment, but not necessarily usage. Information for all endpoints is available [on my website](https://music.youtube.com/watch?v=n2LxBXS4jJM&si=ZpzGNBGvQp1cFicW). + +## Issues +If you would like to report a bug or security issue, please open a GitHub issue. If you are the operator of a service this application accesses, use the contact information provided during registration with your service to contact me directly. + +## Configuration +On startup, this application will look for two files. If either cannot be read, it will exit with an error code. +1. `config.json` contains settings required for operation and API keys used for calling external services. +2. `GITVERSION` contains the commit that was cloned when the container was built. + +
Configuration Example + +* `couchdb.host`: Hostname/IP address and port of a CouchDB server. +* `couchdb.authorization`: Username & password used to access the CouchDB server, in HTTP Basic authentication format, e.g. `username:password`. +* `blog.postsDirectory`: Directory that will be parsed when calling /blogposts. If running in Docker this directory will need to be mounted to the container. +* `blog.postsDirUrl`: Location of the posts directory on the web server. +* `nowplaying.*.target`: Set to the Last.fm/Jellyfin username to query for playback information. + +```json +{ + "startup": { + "apiPort": 8081, + "routesDir": "./routes" + }, + + "couchdb": { + "host": "hazeldale:5984", + "authorization": "" + }, + + "mailjet": { + "apiKey": "", + "senderAddress": "apinotifications@enstrayed.com", + "senderName": "API Notifications", + + "authKeysDoc": "mailjet" + }, + + "blog": { + "postsDirectory": "C:/Users/natha/Downloads/proto/posts", + "postsDirUrl": "/posts" + }, + + "nowplaying": { + "lastfm": { + "apiKey": "", + "target": "enstrayed" + }, + "jellyfin": { + "apiKey": "", + "host": "", + "target": "" + }, + "cider": { + "apiKeys": [], + "hosts": [] + } + } + +} +``` + +
+ +## Docker +In production, this application is designed to be run in Docker, and the container built by pulling the latest commit from the main branch. As such, deploying this application is just a matter of creating a directory and copying the Dockerfile: + +> [!IMPORTANT] +> Please review the Configuration section of this document for important information. By default, the `config.json` file is expected to be mounted into the container at `/app/config.json`. + +```dockerfile +FROM node:20 +WORKDIR /app + +RUN git clone https://github.com/enstrayed/enstrayedapi . +RUN git config --global --add safe.directory /app +RUN git show --oneline -s >> GITVERSION +RUN npm install + +ENTRYPOINT [ "node", "index.js" ] +``` + +
Docker Compose File + +```yaml +--- +services: + enstrayedapi: + build: + context: . + image: enstrayedapi + container_name: enstrayedapi + restart: unless-stopped + volumes: + - ./config.json:/app/config.json +``` + +
+ +## License +If for whatever reason you want to, you are free to adapt this code for your own projects or as reference. However, this software is provided as-is with no warranty or agreement to support it. \ No newline at end of file diff --git a/config.example.json b/config.example.json deleted file mode 100644 index 7725a1f..0000000 --- a/config.example.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "startup": { - "apiPort": 8081, - "routesDir": "./routes" - }, - - "couchdb": { - "host": "hazeldale:5984", - "authorization": "" - }, - - "mailjet": { - "apiKey": "", - "senderAddress": "apinotifications@enstrayed.com", - "senderName": "API Notifications", - - "authKeysDoc": "mailjet" - }, - - "blog": { - "postsDirectory": "C:/Users/natha/Downloads/proto/posts", - "postsDirUrl": "/posts" - }, - - "nowplaying": { - "lastfm": { - "apiKey": "", - "target": "enstrayed" - }, - "jellyfin": { - "apiKey": "", - "host": "", - "target": "" - }, - "cider": { - "apiKeys": [], - "hosts": [] - } - } - -} \ No newline at end of file diff --git a/deprecated/cider.js b/deprecated/cider.js deleted file mode 100644 index 048566c..0000000 --- a/deprecated/cider.js +++ /dev/null @@ -1,101 +0,0 @@ -const { app, db, globalConfig } = require("../index.js") // Get globals from index - -var timeSinceLastCiderQuery = Date.now()-2000; -var currentListening = {} -var currentListeningHtml = "" - -app.get("/cider", (rreq,rres) => { - - rres.send("Cider endpoint is temporarily unavailable.") -}) - -// app.get("/cider", (rreq,rres) => { // GET current listening from target - -// if (Date.now() < timeSinceLastCiderQuery+2000) { -// rres.send(currentListening); // If it has been <2 seconds since the last request, return the cached result. -// } else { -// getCurrentListening(globalConfig.cider.targetHosts[0],"json").then(funcRes => { -// if (funcRes == 1) { -// rres.sendStatus(503) // If there was a problem getting the upstream JSON, return 503 Service Unavailable. -// } else { -// // Required (I think?) because of CORS. -// currentListening = funcRes -// rres.send(funcRes) -// } -// }) -// } - -// }) - -// app.post("/cider", (rreq,rres) => { // POST stop listening on cider target - -// fetch(`http://${globalConfig.couchdb.host}/apiauthkeys/${globalConfig.cider.authKeysDoc}`, { -// headers: { -// "Authorization": `Basic ${btoa(globalConfig.couchdb.authorization)}` -// } -// }).then(dbRes => dbRes.json()).then(dbRes => { - -// if (dbRes.status == 404) { // If document containing cider auth keys does not exist -// console.log(`ERROR: Could not find apiauthkeys/${globalConfig.mailjet.authKeysDoc}`) -// rres.sendStatus(500) // Refuse request -// } else { -// if (dbRes["content"][rreq.get("Authorization").split("_")[0]] === rreq.get("Authorization").split("_")[1]) { - -// fetch(`http://${globalConfig.cider.targetHosts[0]}/stop`).then(fres => { // send GET /stop to cider target -// if (fres.status == 204) { -// console.log(`${rreq.get("cf-connecting-ip")} POST /cider returned 200 KEY:${rreq.get("Authorization")}`) -// rres.sendStatus(200) // if that works then 200 -// } else { -// rres.sendStatus(500) // otherwise lol -// } -// }).catch(ferror => { -// rres.sendStatus(503) // and if a problem happens its probably cause cider target is unavailable -// }) - -// } else { -// console.log(`${rreq.get("cf-connecting-ip")} POST /cider returned 401`) // log ip of unauthorized requests -// rres.sendStatus(401) // received auth key was not in database -// } -// } -// }) - -// }) - -// 2024-04-10: Retrieves currentPlayingSong JSON from specified Cider host and -// returns JSON/HTML containing the useful bits if successful, returning 1 if not. - -// async function getCurrentListening(host,contentType) { // Host should be hostname/ip & port only. -// timeSinceLastCiderQuery = Date.now(); // Save last time function was run, used to indicate when the cache needs refreshed. -// return await fetch(`http://${host}/currentPlayingSong`).then(fetchRes => { -// if (fetchRes.status == 502) { -// return 1 // If the upstream server returns 502 (Bad Gateway) then internally return 1, indicating error. -// } else { -// return fetchRes.json().then(jsonRes => { -// if (jsonRes.info.name == undefined) { -// return 1 // If Cider is running but not playing a song this check prevents an undefined variable error. -// } else { -// if (contentType === "json") { -// return { -// "songName": jsonRes.info.name, -// "artistName": jsonRes.info.artistName, -// "albumName": jsonRes.info.albumName, -// "songLinkUrl": jsonRes.info.url.songLink, -// "endtimeEpochInMs": jsonRes.info.endTime, -// "artworkUrl": jsonRes.info.artwork.url.replace("{w}", jsonRes.info.artwork.width).replace("{h}", jsonRes.info.artwork.height) -// } -// } else if (contentType === "html") { -// return `Album Art

I'm listening to

${`${jsonRes.info.name} by ${jsonRes.info.artistName}`}

from ${jsonRes.info.albumName}

song.link
` -// } else { -// return 1 -// } - -// } -// }) -// } -// }).catch(fetchError => { -// console.error("Error fetch()ing upstream Cider host: "+fetchError) -// return 1 // If something else happens then log it and return 1, indicating error. -// }) -// } - -module.exports = {app} // export routes to be imported by index for execution \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 4f58d54..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -services: - enstrayedapi: - build: - context: . - image: enstrayedapi - container_name: enstrayedapi - restart: unless-stopped - volumes: - - ./config.json:/app/config.json \ No newline at end of file diff --git a/package.json b/package.json index 633d388..6794ec1 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,8 @@ }, "name": "enstrayedapi", "version": "1.0.0", - "description": "api.enstrayed.com", + "description": "EnstrayedAPI", "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, "repository": { "type": "git", "url": "git+https://github.com/enstrayed/enstrayedapi.git" @@ -18,7 +15,6 @@ "bugs": { "url": "https://github.com/enstrayed/enstrayedapi/issues" }, - "homepage": "https://api.enstrayed.com", "devDependencies": { "@types/bun": "^1.0.12", "@types/node": "^20.12.3"