Compare commits
	
		
			34 Commits
		
	
	
		
			feat/cooki
			...
			feat/types
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 379e025ab6 | |||
| 628ed52012 | |||
| 1815a429b0 | |||
| cfbd4965db | |||
| 31c4b8b7df | |||
| a4b2e8f51c | |||
| 11fb803838 | |||
| b2d2b0025c | |||
| ae9f3044bc | |||
| 0eab680527 | |||
| 4204515e91 | |||
| 19e99e8c43 | |||
| 007d34f994 | |||
| 5a1e18b839 | |||
| 56262a45c8 | |||
| 0efc109992 | |||
| 851af204ab | |||
| ccebf0d7b0 | |||
| 76fe986f39 | |||
| fbf1ae8dec | |||
| 9164b592bd | |||
| d77b427c3c | |||
| b56b1f6c0c | |||
| c8477fabaa | |||
| 014cac8b06 | |||
| 20d74cafb9 | |||
| 1690bbcdd0 | |||
| 7094aa2bb5 | |||
| 3660e88acf | |||
| d8f7f82127 | |||
| 0a4248bf30 | |||
| 92d139a156 | |||
| 5578bf854a | |||
| 5648b8fffa | 
| Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										1
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| **/node_modules | ||||
							
								
								
									
										111
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| --- | ||||
| kind: pipeline | ||||
| type: docker | ||||
| name: seasoned api build | ||||
|  | ||||
| platform: | ||||
|   os: linux | ||||
|   arch: amd64 | ||||
|  | ||||
| volumes: | ||||
|   - name: cache | ||||
|     host: | ||||
|       path: /tmp/cache | ||||
|  | ||||
| steps: | ||||
|   - name: Load cached packages | ||||
|     image: sinlead/drone-cache:1.0.0 | ||||
|     settings: | ||||
|       action: load | ||||
|       key: yarn.lock | ||||
|       mount: node_modules | ||||
|       prefix: yarn-modules-seasoned_api | ||||
|     volumes: | ||||
|       - name: cache | ||||
|         path: /cache | ||||
|  | ||||
|   - name: Install dependencies | ||||
|     image: node:18.2.0 | ||||
|     commands: | ||||
|       - node -v | ||||
|       - yarn --version | ||||
|       - yarn | ||||
|  | ||||
|   - name: Cache packages | ||||
|     image: sinlead/drone-cache:1.0.0 | ||||
|     settings: | ||||
|       action: save | ||||
|       key: yarn.lock | ||||
|       mount: node_modules | ||||
|       prefix: yarn-modules-seasoned_api | ||||
|     volumes: | ||||
|       - name: cache | ||||
|         path: /cache | ||||
|  | ||||
|   # - name: Compile typescript | ||||
|   #   image: node:18.2.0 | ||||
|   #   commands: | ||||
|   #     - yarn build:ts | ||||
|  | ||||
|   - name: Run test suite | ||||
|     image: node:18.2.0 | ||||
|     commands: | ||||
|       - yarn test | ||||
|     failure: ignore | ||||
|  | ||||
|   - name: Lint project using eslint | ||||
|     image: node:18.2.0 | ||||
|     commands: | ||||
|       - yarn lint | ||||
|     failure: ignore | ||||
|  | ||||
|   - name: Build and publish docker image | ||||
|     image: plugins/docker | ||||
|     settings: | ||||
|       registry: ghcr.io | ||||
|       repo: ghcr.io/kevinmidboe/seasoned_shows | ||||
|       dockerfile: Dockerfile | ||||
|       username: | ||||
|         from_secret: GITHUB_USERNAME | ||||
|       password: | ||||
|         from_secret: GITHUB_PASSWORD | ||||
|       tags: latest | ||||
|     environment: | ||||
|       TMDB_APIKEY: | ||||
|         from_secret: TMDB_APIKEY | ||||
|       PLEX_IP: | ||||
|         from_secret: PLEX_IP | ||||
|       PLEX_TOKEN: | ||||
|         from_secret: PLEX_TOKEN | ||||
|     when: | ||||
|       event: | ||||
|         - push | ||||
|       branch: | ||||
|         - master | ||||
|  | ||||
|   # - name: deploy | ||||
|   #   image: appleboy/drone-ssh | ||||
|   #   pull: true | ||||
|   #   secrets: | ||||
|   #     - ssh_key | ||||
|   #   when: | ||||
|   #     event: | ||||
|   #       - push | ||||
|   #     branch: | ||||
|   #       - master | ||||
|   #       - drone-test | ||||
|   #     status: success | ||||
|   #   settings: | ||||
|   #     host: 10.0.0.54 | ||||
|   #     username: root | ||||
|   #     key: | ||||
|   #       from_secret: ssh_key | ||||
|   #     command_timeout: 600s | ||||
|   #     script: | ||||
|   #       - /home/kevin/deploy/seasoned.sh | ||||
|  | ||||
| trigger: | ||||
|   event: | ||||
|     include: | ||||
|       - push | ||||
|       # - pull_request | ||||
							
								
								
									
										35
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| { | ||||
| 	"root": true, | ||||
| 	"parserOptions": { | ||||
| 		"parser": "@typescript-eslint/parser", | ||||
| 		"ecmaVersion": 2020, | ||||
| 		"sourceType": "module" | ||||
| 	}, | ||||
| 	"extends": [ | ||||
| 		"eslint-config-airbnb-base", | ||||
| 		"plugin:@typescript-eslint/recommended", | ||||
| 		"plugin:prettier/recommended" | ||||
| 	], | ||||
| 	"plugins": ["mocha", "@typescript-eslint"], | ||||
| 	"rules": { | ||||
| 		"lines-between-class-members": [ | ||||
| 			"error", | ||||
| 			"always", | ||||
| 			{ "exceptAfterSingleLine": true } | ||||
| 		], | ||||
| 		"max-classes-per-file": 1, | ||||
| 		"no-empty": [ | ||||
| 			2, | ||||
| 			{ | ||||
| 				"allowEmptyCatch": true | ||||
| 			} | ||||
| 		], | ||||
| 		"no-promise-executor-return": 1, | ||||
| 		"no-shadow": "off", | ||||
| 		"no-underscore-dangle": "off", | ||||
| 		"@typescript-eslint/no-var-requires": "off" | ||||
| 	}, | ||||
| 	"env": { | ||||
| 		"mocha": true | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										0
									
								
								_config.yml → .github/_config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								_config.yml → .github/_config.yml
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,12 @@ | ||||
| .DS_Store | ||||
|  | ||||
| development.json | ||||
| env | ||||
| configurations/development.json | ||||
| configurations/production.json | ||||
| .env | ||||
| shows.db | ||||
| lib/ | ||||
|  | ||||
| node_modules | ||||
| */package-lock.json | ||||
| .nyc_output | ||||
| yarn-error.log | ||||
|   | ||||
							
								
								
									
										10
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +0,0 @@ | ||||
| # Docs : https://git-scm.com/book/en/v2/Git-Tools-Submodules | ||||
|  | ||||
| [submodule "torrent_search"] | ||||
| 	path = torrent_search | ||||
| 	url = https://github.com/KevinMidboe/torrent_search.git | ||||
| 	branch = master | ||||
|  | ||||
| [submodule "delugeClient"] | ||||
| 	path = delugeClient | ||||
| 	url = https://github.com/KevinMidboe/delugeClient.git | ||||
| @@ -5,6 +5,5 @@ | ||||
|   "singleQuote": false, | ||||
|   "bracketSpacing": true, | ||||
|   "arrowParens": "avoid", | ||||
|   "vueIndentScriptAndStyle": false, | ||||
|   "trailingComma": "none" | ||||
| } | ||||
|   | ||||
							
								
								
									
										21
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| FROM node:18 | ||||
|  | ||||
| RUN mkdir -p /opt/seasonedShows/src | ||||
|  | ||||
| WORKDIR /opt/seasonedShows | ||||
|  | ||||
| COPY src/ src | ||||
| COPY configurations/ configurations | ||||
| COPY package.json . | ||||
| COPY yarn.lock . | ||||
|  | ||||
| RUN apt update | ||||
| RUN apt install node-pre-gyp -y | ||||
| RUN yarn | ||||
| RUN cp configurations/development.json.example configurations/production.json | ||||
|  | ||||
| EXPOSE 31459 | ||||
|  | ||||
| CMD ["yarn", "start"] | ||||
|  | ||||
| LABEL org.opencontainers.image.source https://github.com/kevinmidboe/seasoned | ||||
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							| @@ -6,16 +6,19 @@ | ||||
| <h4 align="center"> Season your media library with the shows and movies that you and your friends want.</h4> | ||||
|  | ||||
| <p align="center"> | ||||
|   <a href="https://travis-ci.org/KevinMidboe/seasonedShows"> | ||||
|     <img src="https://travis-ci.org/KevinMidboe/seasonedShows.svg?branch=master" | ||||
|          alt="Travis CI"> | ||||
|   <a href="https://drone.schleppe.cloud/KevinMidboe/seasonedShows"> | ||||
|     <img src="https://drone.schleppe.cloud/api/badges/KevinMidboe/seasonedShows/status.svg" | ||||
|          alt="Drone CI"> | ||||
|   </a> | ||||
|  | ||||
|   <a href="https://coveralls.io/github/KevinMidboe/seasonedShows?branch=api/v2"> | ||||
|     <img src="https://coveralls.io/repos/github/KevinMidboe/seasonedShows/badge.svg?branch=api/v2" alt=""> | ||||
|   </a> | ||||
|   <a href="https://snyk.io/test/github/KevinMidboe/seasonedShows?targetFile=seasoned_api/package.json"> | ||||
|     <img src="https://snyk.io/test/github/KevinMidboe/seasonedShows/badge.svg?targetFile=seasoned_api/package.json" alt=""> | ||||
|    | ||||
|   <a href="https://snyk.io/test/github/KevinMidboe/seasonedShows?targetFile=package.json"> | ||||
|     <img src="https://snyk.io/test/github/KevinMidboe/seasonedShows/badge.svg?targetFile=package.json" alt=""> | ||||
|   </a> | ||||
|    | ||||
|   <a href="https://opensource.org/licenses/MIT"> | ||||
|     <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt=""> | ||||
|   </a> | ||||
|   | ||||
| @@ -2,6 +2,10 @@ | ||||
|   "database": { | ||||
|     "host": "../shows.db" | ||||
|   }, | ||||
|   "redis": { | ||||
|     "host": "localhost", | ||||
|     "port": 6379 | ||||
|   }, | ||||
|   "webserver": { | ||||
|     "port": 31459, | ||||
|     "origins": [] | ||||
| @@ -10,7 +14,8 @@ | ||||
|     "apiKey": "" | ||||
|   }, | ||||
|   "plex": { | ||||
|     "ip": "" | ||||
|     "ip": "localhost", | ||||
|     "token": "" | ||||
|   }, | ||||
|   "tautulli": { | ||||
|     "apiKey": "", | ||||
							
								
								
									
										31
									
								
								configurations/test.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								configurations/test.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| { | ||||
| 	"database": { | ||||
| 		"host": ":memory:" | ||||
| 	}, | ||||
| 	"redis": { | ||||
| 		"host": "localhost", | ||||
| 		"port": 6379 | ||||
| 	}, | ||||
| 	"webserver": { | ||||
| 		"port": 31400, | ||||
| 		"origins": [] | ||||
| 	}, | ||||
| 	"tmdb": { | ||||
| 		"apiKey": "bogus-api-key" | ||||
| 	}, | ||||
| 	"plex": { | ||||
| 		"ip": "localhost", | ||||
| 		"token": "" | ||||
| 	}, | ||||
| 	"tautulli": { | ||||
| 		"apiKey": "", | ||||
| 		"ip": "", | ||||
| 		"port": "" | ||||
| 	}, | ||||
| 	"raven": { | ||||
| 		"DSN": "" | ||||
| 	}, | ||||
| 	"authentication": { | ||||
| 		"secret": "secret" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										60
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| { | ||||
|   "name": "seasoned-api", | ||||
|   "description": "Packages needed to build and commands to run seasoned api node server.", | ||||
|   "license": { | ||||
|     "type": "MIT", | ||||
|     "url": "https://www.opensource.org/licenses/mit-license.php" | ||||
|   }, | ||||
|   "main": "webserver/server.js", | ||||
|   "scripts": { | ||||
|     "start": "SEASONED_CONFIG=configurations/production.json NODE_ENV=production node lib/webserver/server.js", | ||||
|     "dev": "SEASONED_CONFIG=configurations/development.json NODE_ENV=development node src/webserver/server.js", | ||||
|     "test": "SEASONED_CONFIG=configurations/test.json mocha --recursive tests/unit tests/system", | ||||
|     "build": "yarn tsc", | ||||
|     "coverage:upload": "SEASONED_CONFIG=configurations/test.json mocha --recursive tests/unit && nyc report --reporter=text-lcov | coveralls", | ||||
|     "coverage": "SEASONED_CONFIG=configurations/test.json mocha --recursive tests/unit && nyc report", | ||||
|     "lint": "eslint src tests", | ||||
|     "update": "SEASONED_CONFIG=configurations/production.json node scripts/updateRequestsInPlex.js", | ||||
|     "docs": "yarn apiDocs; yarn classDocs", | ||||
|     "apiDocs": "", | ||||
|     "classDocs": "scripts/generate-class-docs.sh", | ||||
|     "postbuild": "cp -r src/database/schemas lib/database" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "bcrypt": "^5.0.1", | ||||
|     "body-parser": "~1.18.2", | ||||
|     "cookie-parser": "^1.4.6", | ||||
|     "express": "~4.16.0", | ||||
|     "form-data": "^2.5.1", | ||||
|     "jsonwebtoken": "^8.5.1", | ||||
|     "km-moviedb": "^0.2.12", | ||||
|     "python-shell": "^0.5.0", | ||||
|     "raven": "^2.4.2", | ||||
|     "redis": "^3.0.2", | ||||
|     "sqlite3": "^5.0.1", | ||||
|     "typescript": "^4.7.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@babel/core": "^7.5.5", | ||||
|     "@babel/preset-env": "^7.5.5", | ||||
|     "@babel/register": "^7.5.5", | ||||
|     "@types/node": "^18.7.8", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.33.1", | ||||
|     "@typescript-eslint/parser": "^5.33.1", | ||||
|     "chai": "^4.3.6", | ||||
|     "chai-http": "^4.3.0", | ||||
|     "coveralls": "^3.0.5", | ||||
|     "documentation": "^12.0.3", | ||||
|     "eslint": "^8.22.0", | ||||
|     "eslint-config-airbnb-base": "^15.0.0", | ||||
|     "eslint-config-prettier": "^8.5.0", | ||||
|     "eslint-plugin-import": "^2.8.0", | ||||
|     "eslint-plugin-mocha": "10.1.0", | ||||
|     "eslint-plugin-prettier": "^4.2.1", | ||||
|     "istanbul": "^0.4.5", | ||||
|     "mocha": "8.4.0", | ||||
|     "mocha-lcov-reporter": "^1.3.0", | ||||
|     "nyc": "15.1.0", | ||||
|     "prettier": "^2.7.1" | ||||
|   } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| { | ||||
|     "extends": [ | ||||
| 	   "airbnb-base"  | ||||
|     ], | ||||
|     "rules": {  | ||||
|     	"indent": ["error", 3], | ||||
| 	"prefer-destructuring": 0, | ||||
| 	"camelcase": 0, | ||||
| 	"import/no-unresolved": 0, | ||||
| 	"import/no-extraneous-dependencies": 0, | ||||
| 	"object-shorthand": 0, | ||||
| 	"comma-dangle": 0 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								seasoned_api/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										66
									
								
								seasoned_api/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,66 +0,0 @@ | ||||
| # Logs | ||||
| logs | ||||
| *.log | ||||
| npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
|  | ||||
| # Runtime data | ||||
| pids | ||||
| *.pid | ||||
| *.seed | ||||
| *.pid.lock | ||||
|  | ||||
| # Directory for instrumented libs generated by jscoverage/JSCover | ||||
| lib-cov | ||||
|  | ||||
| # Coverage directory used by tools like istanbul | ||||
| coverage | ||||
|  | ||||
| # nyc test coverage | ||||
| .nyc_output | ||||
|  | ||||
| # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||||
| .grunt | ||||
|  | ||||
| # Bower dependency directory (https://bower.io/) | ||||
| bower_components | ||||
|  | ||||
| # node-waf configuration | ||||
| .lock-wscript | ||||
|  | ||||
| # Compiled binary addons (https://nodejs.org/api/addons.html) | ||||
| build/Release | ||||
|  | ||||
| # Dependency directories | ||||
| node_modules/ | ||||
| jspm_packages/ | ||||
|  | ||||
| # Typescript v1 declaration files | ||||
| typings/ | ||||
|  | ||||
| # Optional npm cache directory | ||||
| .npm | ||||
|  | ||||
| # Optional eslint cache | ||||
| .eslintcache | ||||
|  | ||||
| # Optional REPL history | ||||
| .node_repl_history | ||||
|  | ||||
| # Output of 'npm pack' | ||||
| *.tgz | ||||
|  | ||||
| # Yarn Integrity file | ||||
| .yarn-integrity | ||||
|  | ||||
| # dotenv environment variables file | ||||
| .env | ||||
|  | ||||
|  | ||||
| # - - - - -  | ||||
| # My own gitignore files and folders | ||||
| shows.db | ||||
| conf/development.json | ||||
|  | ||||
| # conf/development-prod.json | ||||
| @@ -1,20 +0,0 @@ | ||||
| { | ||||
| 	"database": { | ||||
| 		"host": ":memory:" | ||||
| 	}, | ||||
| 	"webserver": { | ||||
| 		"port": 31400 | ||||
| 	}, | ||||
| 	"tmdb": { | ||||
| 		"apiKey": "bogus-api-key" | ||||
| 	}, | ||||
| 	"plex": { | ||||
| 		"ip": "0.0.0.0" | ||||
| 	}, | ||||
| 	"raven": { | ||||
| 		"DSN": "" | ||||
| 	}, | ||||
| 	"authentication": { | ||||
|     		"secret": "secret" | ||||
|     	} | ||||
| } | ||||
| @@ -1,57 +0,0 @@ | ||||
| { | ||||
|   "name": "seasoned-api", | ||||
|   "description": "Packages needed to build and commands to run seasoned api node server.", | ||||
|   "license": { | ||||
|     "type": "MIT", | ||||
|     "url": "https://www.opensource.org/licenses/mit-license.php" | ||||
|   }, | ||||
|   "main": "webserver/server.js", | ||||
|   "scripts": { | ||||
|     "start": "cross-env SEASONED_CONFIG=conf/development.json NODE_ENV=production NODE_PATH=. babel-node src/webserver/server.js", | ||||
|     "test": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. mocha --require @babel/register --recursive test/unit test/system", | ||||
|     "coverage": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. nyc mocha --require @babel/register --recursive test && nyc report --reporter=text-lcov | coveralls", | ||||
|     "lint": "./node_modules/.bin/eslint src/", | ||||
|     "update": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node scripts/updateRequestsInPlex.js", | ||||
|     "docs": "yarn apiDocs; yarn classDocs", | ||||
|     "apiDocs": "", | ||||
|     "classDocs": "./script/generate-class-docs.sh" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "axios": "^0.18.0", | ||||
|     "bcrypt": "^5.0.1", | ||||
|     "body-parser": "~1.18.2", | ||||
|     "cookie-parser": "^1.4.6", | ||||
|     "cross-env": "~5.1.4", | ||||
|     "express": "~4.16.0", | ||||
|     "form-data": "^2.5.1", | ||||
|     "jsonwebtoken": "^8.5.1", | ||||
|     "km-moviedb": "^0.2.12", | ||||
|     "node-cache": "^4.1.1", | ||||
|     "node-fetch": "^2.6.0", | ||||
|     "python-shell": "^0.5.0", | ||||
|     "raven": "^2.4.2", | ||||
|     "redis": "^3.0.2", | ||||
|     "request": "^2.87.0", | ||||
|     "request-promise": "^4.2", | ||||
|     "sqlite3": "^5.0.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@babel/core": "^7.5.5", | ||||
|     "@babel/node": "^7.5.5", | ||||
|     "@babel/preset-env": "^7.5.5", | ||||
|     "@babel/register": "^7.5.5", | ||||
|     "@types/node": "^12.6.8", | ||||
|     "coveralls": "^3.0.5", | ||||
|     "documentation": "^12.0.3", | ||||
|     "eslint": "^4.9.0", | ||||
|     "eslint-config-airbnb-base": "^12.1.0", | ||||
|     "eslint-plugin-import": "^2.8.0", | ||||
|     "istanbul": "^0.4.5", | ||||
|     "mocha": "^6.2.0", | ||||
|     "mocha-lcov-reporter": "^1.3.0", | ||||
|     "nyc": "^11.6.0", | ||||
|     "supertest": "^3.0.0", | ||||
|     "supertest-as-promised": "^4.0.1", | ||||
|     "typescript": "^3.5.3" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										52
									
								
								seasoned_api/src/cache/redis.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								seasoned_api/src/cache/redis.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,52 +0,0 @@ | ||||
| const redis = require("redis") | ||||
| const client = redis.createClient() | ||||
|  | ||||
| class Cache { | ||||
|   /** | ||||
|    * Retrieve an unexpired cache entry by key. | ||||
|    * @param {String} key of the cache entry | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|   get(key) { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       client.get(key, (error, reply) => { | ||||
|         if (reply == null) { | ||||
|           return reject(); | ||||
|         } | ||||
|  | ||||
|         resolve(JSON.parse(reply)); | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Insert cache entry with key and value. | ||||
|    * @param {String} key of the cache entry | ||||
|    * @param {String} value of the cache entry | ||||
|    * @param {Number} timeToLive the number of seconds before entry expires | ||||
|    * @returns {Object} | ||||
|    */ | ||||
|   set(key, value, timeToLive = 10800) { | ||||
|     if (value == null || key == null) return null; | ||||
|  | ||||
|     const json = JSON.stringify(value); | ||||
|     client.set(key, json, (error, reply) => { | ||||
|       if (reply == "OK") { | ||||
|         // successfully set value with key, now set TTL for key | ||||
|         client.expire(key, timeToLive, e => { | ||||
|           if (e) | ||||
|             console.error( | ||||
|               "Unexpected error while setting expiration for key:", | ||||
|               key, | ||||
|               ". Error:", | ||||
|               error | ||||
|             ); | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     return value; | ||||
|   } | ||||
| } | ||||
|  | ||||
| module.exports = Cache; | ||||
| @@ -1,43 +0,0 @@ | ||||
| const path = require('path'); | ||||
| const Field = require('./field.js'); | ||||
|  | ||||
| let instance = null; | ||||
|  | ||||
| class Config { | ||||
|    constructor() { | ||||
|       this.location = Config.determineLocation(); | ||||
|       this.fields = require(`${this.location}`); | ||||
|    } | ||||
|  | ||||
|    static getInstance() { | ||||
|       if (instance == null) { | ||||
|          instance = new Config(); | ||||
|       } | ||||
|       return instance; | ||||
|    } | ||||
|  | ||||
|    static determineLocation() { | ||||
|       return path.join(__dirname, '..', '..', process.env.SEASONED_CONFIG); | ||||
|    } | ||||
|  | ||||
|    get(section, option) { | ||||
|       if (this.fields[section] === undefined || this.fields[section][option] === undefined) { | ||||
|          throw new Error(`Field "${section} => ${option}" does not exist.`); | ||||
|       } | ||||
|  | ||||
|       const field = new Field(this.fields[section][option]); | ||||
|  | ||||
|       if (field.value === '') { | ||||
|          const envField = process.env[[section.toUpperCase(), option.toUpperCase()].join('_')]; | ||||
|          if (envField !== undefined && envField.length !== 0) { return envField; } | ||||
|       } | ||||
|  | ||||
|       if (field.value === undefined) { | ||||
|          throw new Error(`${section} => ${option} is empty.`); | ||||
|       } | ||||
|  | ||||
|       return field.value; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Config; | ||||
| @@ -1,15 +0,0 @@ | ||||
| class EnvironmentVariables { | ||||
|    constructor(variables) { | ||||
|       this.variables = variables || process.env; | ||||
|    } | ||||
|  | ||||
|    get(variable) { | ||||
|       return this.variables[variable]; | ||||
|    } | ||||
|  | ||||
|    has(variable) { | ||||
|       return this.get(variable) !== undefined; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = EnvironmentVariables; | ||||
| @@ -1,49 +0,0 @@ | ||||
| const Filters = require('./filters.js'); | ||||
| const EnvironmentVariables = require('./environmentVariables.js'); | ||||
|  | ||||
| class Field { | ||||
|    constructor(rawValue, environmentVariables) { | ||||
|       this.rawValue = rawValue; | ||||
|       this.filters = new Filters(rawValue); | ||||
|       this.valueWithoutFilters = this.filters.removeFiltersFromValue(); | ||||
|       this.environmentVariables = new EnvironmentVariables(environmentVariables); | ||||
|    } | ||||
|  | ||||
|    get value() { | ||||
|       if (this.filters.isEmpty()) { | ||||
|          return this.valueWithoutFilters; | ||||
|       } | ||||
|  | ||||
|       if (this.filters.has('base64') && !this.filters.has('env')) { | ||||
|          return Field.base64Decode(this.valueWithoutFilters); | ||||
|       } | ||||
|  | ||||
|       if (this.environmentVariables.has(this.valueWithoutFilters) && | ||||
|           this.environmentVariables.get(this.valueWithoutFilters) === '') { | ||||
|          return undefined; | ||||
|       } | ||||
|  | ||||
|       if (!this.filters.has('base64') && this.filters.has('env')) { | ||||
|          if (this.environmentVariables.has(this.valueWithoutFilters)) { | ||||
|             return this.environmentVariables.get(this.valueWithoutFilters); | ||||
|          } | ||||
|          return undefined; | ||||
|       } | ||||
|  | ||||
|       if (this.filters.has('env') && this.filters.has('base64')) { | ||||
|          if (this.environmentVariables.has(this.valueWithoutFilters)) { | ||||
|             const encodedEnvironmentVariable = this.environmentVariables.get(this.valueWithoutFilters); | ||||
|             return Field.base64Decode(encodedEnvironmentVariable); | ||||
|          } | ||||
|          return undefined; | ||||
|       } | ||||
|  | ||||
|       return this.valueWithoutFilters; | ||||
|    } | ||||
|  | ||||
|    static base64Decode(string) { | ||||
|       return new Buffer(string, 'base64').toString('utf-8'); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Field; | ||||
| @@ -1,34 +0,0 @@ | ||||
| class Filters { | ||||
|    constructor(value) { | ||||
|       this.value = value; | ||||
|       this.delimiter = '|'; | ||||
|    } | ||||
|  | ||||
|    get filters() { | ||||
|       return this.value.split(this.delimiter).slice(0, -1); | ||||
|    } | ||||
|  | ||||
|    isEmpty() { | ||||
|       return !this.hasValidType() || this.value.length === 0; | ||||
|    } | ||||
|  | ||||
|    has(filter) { | ||||
|       return this.filters.includes(filter); | ||||
|    } | ||||
|  | ||||
|    hasValidType() { | ||||
|       return (typeof this.value === 'string'); | ||||
|    } | ||||
|  | ||||
|    removeFiltersFromValue() { | ||||
|       if (this.hasValidType() === false) { | ||||
|          return this.value; | ||||
|       } | ||||
|  | ||||
|       let filtersCombined = this.filters.join(this.delimiter); | ||||
|       filtersCombined += this.filters.length >= 1 ? this.delimiter : ''; | ||||
|       return this.value.replace(filtersCombined, ''); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Filters; | ||||
| @@ -1,14 +0,0 @@ | ||||
| const configuration = require('src/config/configuration').getInstance(); | ||||
| const SqliteDatabase = require('src/database/sqliteDatabase'); | ||||
|  | ||||
| const database = new SqliteDatabase(configuration.get('database', 'host')); | ||||
| /** | ||||
|  * This module establishes a connection to the database | ||||
|  * specified in the confgiuration file. It tries to setup | ||||
|  * the required tables after successfully connecting. | ||||
|  * If the tables already exists, it simply proceeds. | ||||
|  */ | ||||
| Promise.resolve() | ||||
|    .then(() => database.setUp()); | ||||
|  | ||||
| module.exports = database; | ||||
| @@ -1,120 +0,0 @@ | ||||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
| const sqlite3 = require('sqlite3').verbose(); | ||||
|  | ||||
| class SqliteDatabase { | ||||
|    constructor(host) { | ||||
|       this.host = host; | ||||
|       this.connection = new sqlite3.Database(this.host); | ||||
|       this.execute('pragma foreign_keys = on;'); | ||||
|       this.schemaDirectory = path.join(__dirname, 'schemas'); | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Connect to the database. | ||||
|    * @returns {Promise} succeeds if connection was established | ||||
|    */ | ||||
|    // connect() { | ||||
|    //    let database = ; | ||||
|    //    this.connection = database; | ||||
|    //    return database; | ||||
|    // } | ||||
|  | ||||
|    /** | ||||
|    * Run a SQL query against the database. | ||||
|    * @param {String} sql SQL query | ||||
|    * @param {Array} parameters in the SQL query | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    run(sql, parameters) { | ||||
|       return new Promise((resolve, reject) => { | ||||
|          this.connection.run(sql, parameters, (error, result) => { | ||||
|             if (error) | ||||
|                reject(error); | ||||
|             resolve(result) | ||||
|          }); | ||||
|       }); | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Run a SQL query against the database and retrieve all the rows. | ||||
|    * @param {String} sql SQL query | ||||
|    * @param {Array} parameters in the SQL query | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    all(sql, parameters) { | ||||
|       return new Promise((resolve, reject) => { | ||||
|          this.connection.all(sql, parameters, (err, rows) => { | ||||
|             if (err) { | ||||
|                reject(err); | ||||
|             } | ||||
|             resolve(rows); | ||||
|          }) | ||||
|       }) | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Run a SQL query against the database and retrieve one row. | ||||
|    * @param {String} sql SQL query | ||||
|    * @param {Array} parameters in the SQL query | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    get(sql, parameters) { | ||||
|       return new Promise((resolve, reject) => { | ||||
|          this.connection.get(sql, parameters, (err, rows) => { | ||||
|             if (err) { | ||||
|                reject(err); | ||||
|             } | ||||
|             resolve(rows); | ||||
|          }) | ||||
|       }) | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Run a SQL query against the database and retrieve the status. | ||||
|    * @param {String} sql SQL query | ||||
|    * @param {Array} parameters in the SQL query | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    execute(sql) { | ||||
|       return new Promise(resolve => { | ||||
|          this.connection.exec(sql, (err, database) => { | ||||
|              if (err) { | ||||
|                console.log('ERROR: ', err); | ||||
|                reject(err); | ||||
|             } | ||||
|             resolve(); | ||||
|          }) | ||||
|       }) | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Setup the database by running setup.sql file in schemas/. | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    setUp() { | ||||
|       const setupSchema = this.readSqlFile('setup.sql'); | ||||
|       return Promise.resolve(this.execute(setupSchema)); | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Tears down the database by running tearDown.sql file in schemas/. | ||||
|    * @returns {Promise} | ||||
|    */ | ||||
|    tearDown() { | ||||
|       const tearDownSchema = this.readSqlFile('teardown.sql'); | ||||
|       return Promise.resolve(this.execute(tearDownSchema)); | ||||
|    } | ||||
|  | ||||
|    /** | ||||
|    * Returns the file contents of a SQL file in schemas/. | ||||
|    * @returns {String} | ||||
|    */ | ||||
|    readSqlFile(filename) { | ||||
|       const schemaPath = path.join(this.schemaDirectory, filename); | ||||
|       const schema = fs.readFileSync(schemaPath).toString('utf-8'); | ||||
|       return schema; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = SqliteDatabase; | ||||
| @@ -1,9 +0,0 @@ | ||||
|  | ||||
| class GitRepository { | ||||
|    static dumpHook(body) { | ||||
|       /* eslint-disable no-console */ | ||||
|       console.log(body); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = GitRepository; | ||||
| @@ -1,19 +0,0 @@ | ||||
|  | ||||
| class Media { | ||||
|    constructor(title, year, type) { | ||||
|       this.title = title; | ||||
|       this.year = year; | ||||
|       this.type = type; | ||||
|    } | ||||
|  | ||||
|    toString() { | ||||
|       return `N: ${this.title} | Y: ${this.year} | T: ${this.type}`; | ||||
|    } | ||||
|  | ||||
|    print() { | ||||
|       /* eslint-disable no-console */ | ||||
|       console.log(this.toString()); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Media; | ||||
| @@ -1,15 +0,0 @@ | ||||
| class MediaInfo { | ||||
|    constructor() { | ||||
|       this.duration = undefined; | ||||
|       this.height = undefined; | ||||
|       this.width = undefined; | ||||
|       this.bitrate = undefined; | ||||
|       this.resolution = undefined; | ||||
|       this.framerate = undefined; | ||||
|       this.protocol = undefined; | ||||
|       this.container = undefined; | ||||
|       this.audioCodec = undefined; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = MediaInfo; | ||||
| @@ -1,12 +0,0 @@ | ||||
| class Player { | ||||
|    constructor(device, address) { | ||||
|       this.device = device; | ||||
|       this.ip = address; | ||||
|       this.platform = undefined; | ||||
|       this.product = undefined; | ||||
|       this.title = undefined; | ||||
|       this.state = undefined; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Player; | ||||
| @@ -1,22 +0,0 @@ | ||||
|  | ||||
| const Media = require('src/media_classes/media'); | ||||
|  | ||||
| class Plex extends Media { | ||||
|    constructor(title, year, type, summary, poster_path, background_path, added, seasons, episodes) { | ||||
|       super(title, year, type); | ||||
|  | ||||
|       this.summary = summary; | ||||
|       this.poster_path = poster_path; | ||||
|       this.background_path = background_path; | ||||
|       this.added = added; | ||||
|  | ||||
|       this.seasons = seasons; | ||||
|       this.episodes = episodes; | ||||
|    } | ||||
|  | ||||
|    print() { | ||||
|       super.print(); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = Plex; | ||||
| @@ -1,33 +0,0 @@ | ||||
|  | ||||
| const Media = require('src/media_classes/media'); | ||||
|  | ||||
| class TMDB extends Media { | ||||
|    // constructor(...args) { | ||||
|    constructor(title, year, type, id, summary, poster_path, background_path, popularity, score, release_status, tagline, seasons, episodes) { | ||||
|       super(title, year, type); | ||||
|  | ||||
|       this.id = id; | ||||
|       this.summary = summary; | ||||
|       this.poster_path = poster_path; | ||||
|       this.background_path = background_path; | ||||
|       this.popularity = popularity; | ||||
|       this.score = score; | ||||
|  | ||||
|       this.release_status = release_status; | ||||
|       this.tagline = tagline; | ||||
|  | ||||
|       this.seasons = seasons; | ||||
|       this.episodes = episodes; | ||||
|    } | ||||
|  | ||||
|    toString() { | ||||
|       return `${super.toString()} | ID: ${this.id}`; | ||||
|    } | ||||
|  | ||||
|    print() { | ||||
|       /* eslint-disable no-console */ | ||||
|       console.log(this.toString()); | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = TMDB; | ||||
| @@ -1,8 +0,0 @@ | ||||
| class User { | ||||
|    constructor(id, title) { | ||||
|       this.id = id; | ||||
|       this.title = title; | ||||
|    } | ||||
| } | ||||
|  | ||||
| module.exports = User; | ||||
| @@ -1,35 +0,0 @@ | ||||
| const request = require("request"); | ||||
| const configuration = require('src/config/configuration').getInstance(); | ||||
|  | ||||
| const sendSMS = (message) => { | ||||
|   const apiKey = configuration.get('sms', 'apikey') | ||||
|  | ||||
|   if (!apiKey) { | ||||
|     console.warning("api key for sms not set, cannot send sms.") | ||||
|     return null | ||||
|   } | ||||
|  | ||||
|   const sender = configuration.get('sms', 'sender') | ||||
|   const recipient = configuration.get('sms', 'recipient') | ||||
|  | ||||
|   return new Promise((resolve, reject) => { | ||||
|   request.post( | ||||
|     { | ||||
|       url: `https://gatewayapi.com/rest/mtsms?token=${apiKey}`, | ||||
|       json: true, | ||||
|       body: { | ||||
|         sender, | ||||
|         message, | ||||
|         recipients: [{ msisdn: `47${recipient}` }] | ||||
|       } | ||||
|     }, | ||||
|     function(err, r, body) { | ||||
|       console.log(err ? err : body); | ||||
|       console.log("sms provider response:", body) | ||||
|       resolve() | ||||
|     } | ||||
|   ); | ||||
|   }) | ||||
| } | ||||
|  | ||||
| module.exports = { sendSMS } | ||||
| @@ -1,24 +0,0 @@ | ||||
| const Plex = require('src/media_classes/plex'); | ||||
|  | ||||
| function translateAdded(date_string) { | ||||
|    return new Date(date_string * 1000); | ||||
| } | ||||
|  | ||||
| function convertPlexToSeasoned(plex) { | ||||
|    const title = plex.title; | ||||
|    const year = plex.year; | ||||
|    const type = plex.type; | ||||
|    const summary = plex.summary; | ||||
|    const poster_path = plex.thumb; | ||||
|    const background_path = plex.art; | ||||
|    const added = translateAdded(plex.addedAt); | ||||
|    // const genre = plex.genre; | ||||
|    const seasons = plex.childCount; | ||||
|    const episodes = plex.leafCount; | ||||
|  | ||||
|    const seasoned = new Plex(title, year, type, summary, poster_path, background_path, added, seasons, episodes); | ||||
|    // seasoned.print(); | ||||
|    return seasoned; | ||||
| } | ||||
|  | ||||
| module.exports = convertPlexToSeasoned; | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user