Browse Source

Remove torrent webui for now

dev
David Ludwig 4 years ago
parent
commit
3079710dbf
23 changed files with 0 additions and 3202 deletions
  1. +0
    -2
      services/torrent-webui/.env.example
  2. +0
    -20
      services/torrent-webui/Dockerfile
  3. +0
    -3
      services/torrent-webui/README.md
  4. +0
    -13
      services/torrent-webui/index.html
  5. +0
    -6
      services/torrent-webui/nodemon.json
  6. +0
    -44
      services/torrent-webui/package.json
  7. +0
    -6
      services/torrent-webui/postcss.config.js
  8. BIN
      services/torrent-webui/public/favicon.ico
  9. +0
    -27
      services/torrent-webui/src/app/App.vue
  10. BIN
      services/torrent-webui/src/app/assets/logo.png
  11. +0
    -65
      services/torrent-webui/src/app/components/HelloWorld.vue
  12. +0
    -5
      services/torrent-webui/src/app/index.ts
  13. +0
    -5
      services/torrent-webui/src/app/shims-vue.d.ts
  14. +0
    -3
      services/torrent-webui/src/app/styles/index.css
  15. +0
    -36
      services/torrent-webui/src/server/common.ts
  16. +0
    -86
      services/torrent-webui/src/server/index.ts
  17. +0
    -165
      services/torrent-webui/src/server/services/TorrentClientIpc.ts
  18. +0
    -18
      services/torrent-webui/tailwind.config.js
  19. +0
    -74
      services/torrent-webui/tsconfig.json
  20. +0
    -12
      services/torrent-webui/tsconfig.server.json
  21. +0
    -22
      services/torrent-webui/tsconfig.vite.json
  22. +0
    -12
      services/torrent-webui/vite.config.ts
  23. +0
    -2578
      services/torrent-webui/yarn.lock

+ 0
- 2
services/torrent-webui/.env.example View File

@ -1,2 +0,0 @@
SERVER_PORT = 3300
TORRENT_CLIENT_IPC_SOCKET = /var/autoplex/ipc/torrent_client.sock

+ 0
- 20
services/torrent-webui/Dockerfile View File

@ -1,20 +0,0 @@
FROM node:14-alpine AS base
WORKDIR /app
RUN mkdir /var/autoplex && chown node:node -R /var/autoplex
# An image containing necessary components for building
FROM base AS builder
COPY package.json yarn.lock index.html postcss.config.js tailwind.config.js vite.config.ts tsconfig.* ./
RUN rm -rf node_modules && yarn install --frozen-lockfile
COPY src src
# An image to build the app
FROM builder AS build
RUN yarn run build
# An image containing the built app and production dependencies
FROM base AS prod
COPY --from=build /app/build ./build
COPY package.json yarn.lock ./
RUN rm -rf node_modules && yarn install --production --frozen-lockfile
CMD [ "yarn", "run", "start" ]

+ 0
- 3
services/torrent-webui/README.md View File

@ -1,3 +0,0 @@
# Autoplex Torrent Web UI
A simple web interface for interfacing with the Autoplex Torrent client

+ 0
- 13
services/torrent-webui/index.html View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Autoplex Torrent</title>
</head>
<body class="bg-gray-900">
<div id="app"></div>
<script type="module" src="/src/app/index.ts"></script>
</body>
</html>

+ 0
- 6
services/torrent-webui/nodemon.json View File

@ -1,6 +0,0 @@
{
"watch": ["src/server"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --inspect=0.0.0.0:9229 -r ts-node/register src/server/index.ts"
}

+ 0
- 44
services/torrent-webui/package.json View File

@ -1,44 +0,0 @@
{
"name": "@autoplex-service/torrent-webui",
"version": "0.0.0",
"keywords": [],
"author": "David Ludwig",
"license": "ISC",
"main": "./dist/server/index.js",
"scripts": {
"clean": "rimraf ./dist",
"dev": "vite",
"build": "yarn run build:backend",
"build:backend": "tsc -p ./tsconfig.server.json",
"build:frontend": "vue-tsc --noEmit -p ./tsconfig.vite.json && vite build",
"start": "NODE_ENV=production node .",
"start:dev": "nodemon"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.3",
"fastify": "^3.14.1",
"fastify-formbody": "^5.0.0",
"fastify-http-proxy": "^5.0.0",
"fastify-multipart": "^4.0.3",
"fastify-static": "^4.0.1",
"node-ipc": "^9.1.4",
"vue": "^3.0.5",
"vue-router": "^4.0.6",
"vuedraggable": "^4.0.1",
"websocket": "^1.0.33"
},
"devDependencies": {
"@types/node-ipc": "^9.1.3",
"@vitejs/plugin-vue": "^1.2.1",
"@vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.5",
"nodemon": "^2.0.7",
"postcss": "^8.2.9",
"rimraf": "^3.0.2",
"tailwindcss": "^2.1.1",
"ts-node": "^9.1.1",
"typescript": "^4.1.3",
"vite": "^2.1.5",
"vue-tsc": "^0.0.15"
}
}

+ 0
- 6
services/torrent-webui/postcss.config.js View File

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

BIN
services/torrent-webui/public/favicon.ico View File

Before After

+ 0
- 27
services/torrent-webui/src/app/App.vue View File

@ -1,27 +0,0 @@
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
name: 'App',
components: {
HelloWorld
}
})
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

BIN
services/torrent-webui/src/app/assets/logo.png View File

Before After
Width: 200  |  Height: 200  |  Size: 6.7 KiB

+ 0
- 65
services/torrent-webui/src/app/components/HelloWorld.vue View File

@ -1,65 +0,0 @@
<template>
<h1>{{ msg }}</h1>
<p>
Recommended IDE setup:
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
+
<a
href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
target="_blank"
>Vetur</a>
or
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
(if using
<code>&lt;script setup&gt;</code>)
</p>
<p>See <code>README.md</code> for more information.</p>
<p>
<a href="https://vitejs.dev/guide/features.html" target="_blank">Vite Docs</a> |
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
</p>
<button @click="count++">count is: {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<script lang="ts">
import { ref, defineComponent } from 'vue'
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
required: true
}
},
setup: () => {
const count = ref(0)
return { count }
}
})
</script>
<style scoped>
a {
color: #42b983;
}
label {
margin: 0 0.5em;
font-weight: bold;
}
code {
background-color: #eee;
padding: 2px 4px;
border-radius: 4px;
color: #304455;
}
</style>

+ 0
- 5
services/torrent-webui/src/app/index.ts View File

@ -1,5 +0,0 @@
import { createApp } from 'vue'
import App from './App.vue'
import "./styles/index.css";
createApp(App).mount('#app');

+ 0
- 5
services/torrent-webui/src/app/shims-vue.d.ts View File

@ -1,5 +0,0 @@
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

+ 0
- 3
services/torrent-webui/src/app/styles/index.css View File

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

+ 0
- 36
services/torrent-webui/src/server/common.ts View File

@ -1,36 +0,0 @@
export interface ITorrent {
name: string,
infoHash: string,
progress: number,
state: TorrentState
}
export enum TorrentState {
Ready = 0x1,
Paused = 0x2,
Done = 0x4
}
export interface ISerializedTorrent {
name : string;
infoHash : string;
downloaded : number;
uploaded : number;
ratio : number;
size : number;
downloadSpeed: number;
uploadSpeed : number;
numPeers : number;
progress : number;
path : string;
state : TorrentState;
files : ISerializedFile[];
}
export interface ISerializedFile {
path : string;
size : number;
downloaded: number;
progress : number;
selected : boolean;
}

+ 0
- 86
services/torrent-webui/src/server/index.ts View File

@ -1,86 +0,0 @@
import fastify from "fastify";
import fastifyStatic from "fastify-static";
import fastifyHttpProxy from "fastify-http-proxy";
import fastifyMultipart from "fastify-multipart";
import fastifyFormBody from "fastify-formbody";
import assert from "assert";
import { join } from "path";
import TorrentClientIpc from "./services/TorrentClientIpc";
let ipc = new TorrentClientIpc;
ipc.boot();
// @TODO Proper typing https://www.fastify.io/docs/v1.14.x/TypeScript/
let server = fastify();
server.register(fastifyMultipart, {
limits: {
fileSize: 16*1024*1024,
files: 50
}
});
server.register(fastifyFormBody);
/**
* If the app is in production mode, serve static assets.
* If the app is in development mode, forward 404's to Vite.
* NOTE: Static assets may be moved to nginx later... not sure yet
*/
if (process.env["NODE_ENV"] == "production") {
server.register(fastifyStatic, {
root: join(__dirname, "../public")
});
server.setNotFoundHandler((request, reply) => {
console.log("Replying with default");
return reply.sendFile("index.html");
});
} else {
server.register(fastifyHttpProxy, {
upstream: "http://localhost:3000"
});
}
// API Routes --------------------------------------------------------------------------------------
server.get("/api/torrent/list", async (request, reply) => {
return await ipc.list();
});
server.get("/api/torrent/:infoHash", async (request, reply) => {
let infoHash: string = (<any>request.params)["infoHash"];
assert(infoHash !== undefined, "Invalid request");
return { result: await ipc.details(infoHash) };
});
server.post("/api/torrent/add", async (request, reply) => {
let result: string[] = [];
if (request.isMultipart()) {
let files = request.files();
for await (let file of files) {
let torrentFile = await file.toBuffer();
let infoHash = await ipc.add(torrentFile);
result.push(infoHash);
}
} else {
assert(request.body !== undefined, "Invalid request: empty body");
let links = (<any>request.body)["link"];
assert(links !== undefined, "Invalid request: empty links");
for (let link of (Array.isArray(links) ? links : [links])) {
let infoHash = await ipc.add(link);
result.push(infoHash);
}
}
return { result: result };
});
server.delete("/api/torrent/remove/:infoHash", async (request, reply) => {
let infoHash: string = (<any>request.params)["infoHash"];
assert(infoHash != undefined);
await ipc.remove(infoHash);
return {}
});
// -------------------------------------------------------------------------------------------------
console.log("Listening on port:", parseInt(<string>process.env["SERVER_PORT"]));
server.listen(parseInt(<string>process.env["SERVER_PORT"]), "0.0.0.0");

+ 0
- 165
services/torrent-webui/src/server/services/TorrentClientIpc.ts View File

@ -1,165 +0,0 @@
import ipc from "node-ipc";
import { Socket } from "net";
import { ISerializedTorrent, ITorrent } from "../common";
interface IResponse {
response?: any,
error?: string | Error
}
export default class TorrentClientIpc
{
/**
* Indicate if there is an active connection to the IPC
*/
private __isConnected: boolean;
/**
* The active IPC socket
*/
protected socket!: Socket;
/**
* Create a new IPC client for the torrent client
*/
constructor() {
ipc.config.id = "torrent_webui";
ipc.config.retry = 1500;
ipc.config.silent = true;
this.__isConnected = false;
}
/**
* Boot the torrent client IPC service
*/
public boot() {
return new Promise<void>((resolve, reject) => {
console.log(process.env["TORRENT_CLIENT_IPC_SOCKET"]);
ipc.connectTo("torrent_client", process.env["TORRENT_CLIENT_IPC_SOCKET"], () => {
this.socket = ipc.of["torrent_client"];
this.installSocketEventHandlers(this.socket);
this.installSocketMessageHandlers(this.socket);
resolve();
});
});
}
/**
* Install the event handlers for the IPC socket
*/
protected installSocketEventHandlers(socket: Socket) {
socket.on("connect", () => this.onConnect());
socket.on("error", (error: any) => this.onError(error));
socket.on("disconnect", () => this.onDisconnect());
socket.on("destroy", () => this.onDestroy());
}
protected installSocketMessageHandlers(socket: Socket) {
}
// Socket Event Handlers -----------------------------------------------------------------------
protected onConnect() {
if (!this.__isConnected) {
console.log("IPC: Connection established");
}
this.__isConnected = true;
}
protected onError(error: string | Error) {
if (this.__isConnected) {
console.log("IPC: Error occurred:", error);
}
}
protected onDisconnect() {
if (this.__isConnected) {
console.log("IPC: Disconnected");
}
this.__isConnected = false;
}
protected onDestroy() {
console.log("IPC: Destroyed");
}
// Methods -------------------------------------------------------------------------------------
/**
* Perform a general request to the torrent client
*/
protected async request(method: string, ...message: any[]) {
return new Promise<IResponse>((resolve, reject) => {
if (!this.isConnected) {
throw new Error("Not connected to torrent client");
}
let respond = (response: any) => {
clearTimeout(timeout);
resolve(response);
}
// Include timeout mechanism in the off chance something breaks
let timeout = setTimeout(() => {
this.socket.off(method, respond);
reject("Torrent client IPC request timeout")
}, 1000);
this.socket.once(method, respond);
this.socket.emit(method, message);
});
}
/**
* Add a torrent to the client
* @param torrent Magnet URI or file buffer
*/
public async add(torrent: string | Buffer) {
let response = await this.request("add", torrent);
if (response.error) {
throw new Error("Failed to add torrent");
}
return <string>response.response;
}
/**
* Remove a torrent from the client
* @param torrent Torrent info hash
*/
public async remove(torrent: string) {
let response = await this.request("remove", torrent);
if (response.error) {
throw new Error("Failed to remove torrent");
}
}
/**
* Get a list of all torrents in the client
*/
public async list() {
let response = await this.request("list");
if (response.error) {
console.error(response.error);
throw new Error("Failed to obtain torrent list");
}
console.log("Response is:", response);
return <ITorrent[]>response.response;
}
/**
* Get full details of each of the provided torrents
* @param torrentIds Array of torrent info hashes
*/
public async details(...torrentIds: string[]) {
let response = await this.request("details", torrentIds);
if (response.error) {
console.error(response.error);
throw new Error("Failed to retrieve torrent details");
}
return <ISerializedTorrent[]>response.response;
}
// Accessors -----------------------------------------------------------------------------------
get isConnected() {
return this.__isConnected;
}
}

+ 0
- 18
services/torrent-webui/tailwind.config.js View File

@ -1,18 +0,0 @@
module.exports = {
purge: ["./index.html", "src/app/*.{vue,ts}"],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
colors: {
ui: {
bg: "#191726",
fg: "#202332",
}
},
},
},
variants: {
extend: {},
},
plugins: [],
}

+ 0
- 74
services/torrent-webui/tsconfig.json View File

@ -1,74 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
// "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": [
"src"
]
}

+ 0
- 12
services/torrent-webui/tsconfig.server.json View File

@ -1,12 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"outDir": "dist/server", /* Redirect output structure to the directory. */
"sourceRoot": "src/server" /* Specify the location where debugger should locate TypeScript files instead of source locations. */
},
"exclude": [
"src/app"
]
}

+ 0
- 22
services/torrent-webui/tsconfig.vite.json View File

@ -1,22 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"jsx": "preserve",
"resolveJsonModule": true,
"lib": ["esnext", "dom"],
"types": ["vite/client"],
"sourceRoot": "src/app"
},
"include": [
"src/app/**/*.ts",
"src/app**/*.d.ts",
"src/app/**/*.tsx",
"src/app/**/*.vue"
],
"exclude": [
"src/server"
]
}

+ 0
- 12
services/torrent-webui/vite.config.ts View File

@ -1,12 +0,0 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
build: {
manifest: true,
outDir: "./build/public"
}
})

+ 0
- 2578
services/torrent-webui/yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save