Changed routing framework from mux to Gin.

Swagger doc is now included in the application.
A fronted can now be hosted from the application.
This commit is contained in:
2022-01-29 17:52:33 +01:00
parent 512fcd0c4f
commit f9d6c24a97
43 changed files with 28760 additions and 210 deletions

View File

@@ -1,13 +0,0 @@
package main
import (
"music-server/pkg/conf"
)
func main() {
conf.SetupDb()
conf.SetupRestServer()
conf.CloseDb()
}

21
cmd/frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Här kan en webbsida vara</h1>
</body>
</html>

27073
cmd/frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

42
cmd/frontend/package.json Normal file
View File

@@ -0,0 +1,42 @@
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

28
cmd/frontend/src/App.vue Normal file
View File

@@ -0,0 +1,28 @@
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,58 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

8
cmd/frontend/src/main.js Normal file
View File

@@ -0,0 +1,8 @@
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')

20
cmd/main.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"embed"
"music-server/pkg/conf"
)
//go:embed frontend/dist
var frontend embed.FS
//go:embed swagger
var swagger embed.FS
func main() {
conf.SetupDb()
conf.SetupRestServer(frontend, swagger)
conf.CloseDb()
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

60
cmd/swagger/index.html Normal file
View File

@@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "./swagger.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
</script>
</body>
</html>

View File

@@ -0,0 +1,75 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};
isValid = qp.state === sentState;
if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
window.addEventListener('DOMContentLoaded', function () {
run();
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

327
cmd/swagger/swagger.yaml Normal file
View File

@@ -0,0 +1,327 @@
openapi: 3.0.3
info:
version: "3.0"
title: "Music Server"
description: "Changed routing framework from mux to Gin. Swagger doc is now included in the application. A fronted can now be hosted from the application."
contact:
email: "zarnor91@gmail.com"
servers:
- url: https://music.sanplex.xyz/
description: Main (production) server
- url: https://tmusic.sanplex.xyz/
description: Test server
- url: http://localhost:8080
description: Local server
tags:
- name: "Music"
description: "Endpoints for the music"
- name: "Version"
description: "Information about the application"
- name: "Sync"
description: "Sync the database with the folders"
paths:
/music:
get:
tags:
- "Music"
summary: "Get song"
description: "Get a specified song from the que, if invalid number it will be the first or the last song in que"
operationId: "getSong"
parameters:
- name: "song"
in: "query"
schema:
type: integer
description: "The number the song has in the que"
required: true
responses:
"200":
description: "The speciefied file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/first:
get:
tags:
- "Music"
summary: "Start a match"
description: "Get a sound check song and starts a new song que"
operationId: "getFisrt"
responses:
"200":
description: "A file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/rand:
get:
tags:
- "Music"
summary: "Get random song"
description: "Takes a random song from a random game"
operationId: "getRandom"
responses:
"200":
description: "A file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/rand/low:
get:
tags:
- "Music"
summary: "Get random song"
description: "Takes a random song from a random game but increases the chans for games that haven't been played"
operationId: "getRandomLow"
responses:
"200":
description: "A file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/info:
get:
tags:
- "Music"
summary: "Get info of current song"
description: "Return the info of the song currently playing"
operationId: "getInfo"
responses:
"200":
description: "Info of current song"
content:
application/json:
schema:
$ref: '#/components/schemas/info'
"500":
description: "Something wnet wrong on the server"
/music/list:
get:
tags:
- "Music"
summary: "Gets song que"
description: "Gets a list of all songs that have been fetched"
operationId: "getList"
responses:
"200":
description: "A list"
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/list'
"500":
description: "Something went wrong on the server"
/music/next:
get:
tags:
- "Music"
summary: "Get next song"
description: "Gets next song in the song que, if there is no more a new random song will be generated."
operationId: "getNext"
responses:
"200":
description: "A file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/previous:
get:
tags:
- "Music"
summary: "Get previous song"
description: "Gets previous song in the song que, if there is no more the first song will be returns."
operationId: "getPrevious"
responses:
"200":
description: "A file"
content:
audio/mpeg:
schema:
type: object
format: binary
"500":
description: "Something wnet wrong on the server"
/music/all:
get:
tags:
- "Music"
summary: "Gets all games"
description: "Gets a list of all games that is in the database"
operationId: "getAll"
responses:
"200":
description: "A list"
content:
application/json:
schema:
type: array
items:
type: string
example: ["God of War", "Final Fantasy VII"]
"500":
description: "Something went wrong on the server"
/music/all/random:
get:
tags:
- "Music"
summary: "Gets all games in random order"
description: "Gets a list of all games that is in the database in random order"
operationId: "getAllRandom"
responses:
"200":
description: "A list"
content:
application/json:
schema:
type: array
items:
type: string
example: ["Final Fantasy VII", "God of War"]
"500":
description: "Something went wrong on the server"
/music/played:
put:
tags:
- "Music"
summary: "Increase played"
description: "Increase the number of times the current game has been played"
operationId: "setPlayed"
responses:
"202":
description: "Accepted"
"401":
description: "Bad Request"
"500":
description: "Something went wrong on the server"
/music/addQue:
get:
tags:
- "Music"
summary: "Adds last song to que"
description: "Adds the last featched song to the song que"
operationId: "addQue"
responses:
"200":
description: "OK"
"401":
description: "Bad Request"
"500":
description: "Something went wrong on the server"
/music/reset:
get:
tags:
- "Music"
summary: "Resets the song que"
description: "Resets the song que for a new match"
operationId: "reset"
responses:
"200":
description: "successful operation"
"500":
description: "Something went wrong on the server"
/version:
get:
tags:
- "Version"
summary: "Returns pet inventories by status"
description: "Returns a map of status codes to quantities"
operationId: "getVersionInfo"
responses:
"200":
description: "successful operation"
content:
application/json:
schema:
$ref: '#/components/schemas/versionInfo'
/sync:
get:
tags:
- "Sync"
summary: "Sync games"
description: "Sync the database with the folders"
operationId: "sync"
responses:
"200":
description: "successful operation"
"500":
description: "Something went wrong on the server"
components:
schemas:
list:
type: object
properties:
Game:
type: string
example: God of War
Song:
type: string
example: Main Theme.mp3
CurrentlyPlaying:
type: boolean
example: true
description: Only included on the one that's playing
SongNo:
type: integer
example: 3
info:
type: object
properties:
Game:
type: string
example: God of War
GamePlayed:
type: integer
example: 10
Song:
type: string
example: Main Theme.mp3
SongPlayed:
type: integer
example: 10
SongNo:
type: integer
example: 3
versionInfo:
type: object
properties:
version:
type: string
example: 0.5.1
changelog:
type: string
example: "Added shadow to build fat jars. Added support to give property files through arguments."
history:
type: array
items:
$ref: '#/components/schemas/historyInfo'
historyInfo:
type: object
properties:
version:
type: string
example: 0.5.0
changelog:
type: string
example: "Updated kotlin version, gradle version and al libs. Added connection to database with exposed. Added new endpoints."