fully converted to proper bootstrap-vue, black theme styling, api routes for data retrieval,

This commit is contained in:
Xevion
2020-08-04 18:04:52 -05:00
parent a2aef9afc3
commit 5fdbe86eae
15 changed files with 393 additions and 103 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ app/data/preprocess/*.json
flaskenv
algolia.json
*.scss.css
*.scss.css.map
node_modules/**
# Byte-compiled / optimized / DLL files

View File

@@ -1,7 +0,0 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100

102
client/package-lock.json generated
View File

@@ -1122,6 +1122,16 @@
"integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
"dev": true
},
"@nuxt/opencollective": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.0.tgz",
"integrity": "sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==",
"requires": {
"chalk": "^2.4.2",
"consola": "^2.10.1",
"node-fetch": "^2.6.0"
}
},
"@soda/friendly-errors-webpack-plugin": {
"version": "1.7.1",
"resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz",
@@ -2019,7 +2029,6 @@
"version": "3.2.1",
"resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz",
"integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -2266,6 +2275,43 @@
"integrity": "sha1-oXs6jqgRBg501H0wYSJACtRJeuI=",
"dev": true
},
"axios": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
"requires": {
"follow-redirects": "1.5.10",
"is-buffer": "^2.0.2"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"is-buffer": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"babel-eslint": {
"version": "10.1.0",
"resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz",
@@ -2499,6 +2545,23 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true
},
"bootstrap": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.1.tgz",
"integrity": "sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ=="
},
"bootstrap-vue": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.16.0.tgz",
"integrity": "sha512-gLETwPmeRHCe5WHmhGxzb5PtTEuKqQPGl0TFvZ2Odbkg/7UuIHdqIexrJRerpnomP4ZzDQ+qYGL91Ls9lcQsJQ==",
"requires": {
"@nuxt/opencollective": "^0.3.0",
"bootstrap": ">=4.5.0 <5.0.0",
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"vue-functional-data-merge": "^3.1.0"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz",
@@ -2908,7 +2971,6 @@
"version": "2.4.2",
"resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1591687183344&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz",
"integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -3227,7 +3289,6 @@
"version": "1.9.3",
"resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
"integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@@ -3235,8 +3296,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
@@ -3358,6 +3418,11 @@
"integrity": "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w=",
"dev": true
},
"consola": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/consola/-/consola-2.14.0.tgz",
"integrity": "sha512-A2j1x4u8d6SIVikhZROfpFJxQZie+cZOfQMyI/tu2+hWXe8iAv7R6FW6s6x04/7zBCst94lPddztot/d6GJiuQ=="
},
"console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz",
@@ -4531,8 +4596,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627212242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
"version": "6.8.0",
@@ -5750,8 +5814,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.1",
@@ -7536,6 +7599,11 @@
"lower-case": "^1.1.1"
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"node-forge": {
"version": "0.9.0",
"resolved": "https://registry.npm.taobao.org/node-forge/download/node-forge-0.9.0.tgz",
@@ -8182,6 +8250,16 @@
"ts-pnp": "^1.1.6"
}
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portal-vue": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz",
"integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g=="
},
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.28.tgz",
@@ -10342,7 +10420,6 @@
"version": "5.5.0",
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1573220230429&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
"integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@@ -11084,6 +11161,11 @@
}
}
},
"vue-functional-data-merge": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-3.1.0.tgz",
"integrity": "sha512-leT4kdJVQyeZNY1kmnS1xiUlQ9z1B/kdBFCILIjYYQDqZgLqCLa0UhjSSeRX6c3mUe6U5qYeM8LrEqkHJ1B4LA=="
},
"vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz",

View File

@@ -8,6 +8,9 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.18.1",
"bootstrap": "^4.3.1",
"bootstrap-vue": "^2.16.0",
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
@@ -37,7 +40,14 @@
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
"rules": {
"max-len": [
2,
{
"code": 120
}
]
}
},
"browserslist": [
"> 1%",

View File

@@ -1,5 +1,23 @@
<template>
<div id="app">
<router-view/>
</div>
<div id="app">
<router-view/>
<b-container fluid=true class="py-5 px-5">
<b-row>
<b-col lg="3" xl="2" md="12">
<SeasonList></SeasonList>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import SeasonList from './components/SeasonList.vue';
export default {
name: 'App',
components: {
SeasonList,
},
};
</script>

View File

@@ -1,36 +0,0 @@
<template>
<div class="container">
<div class="row">
<div class="col-sm-10">
<h1>Books</h1>
<hr>
<br><br>
<button type="button" class="btn btn-success btn-sm">Add Book</button>
<br><br>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">Read?</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>foobar</td>
<td>
<div class="btn-group" role="group">
<button type="button" class="btn btn-warning btn-sm px-2">Update</button>
<button type="button" class="btn btn-danger btn-sm px-1">Delete</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>

View File

@@ -1,28 +0,0 @@
<script>
import axios from 'axios';
export default {
name: 'Ping',
data() {
return {
msg: '',
};
},
methods: {
getMessage() {
const path = 'http://localhost:5000/ping';
axios.get(path)
.then((res) => {
this.msg = res.data;
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
});
},
},
created() {
this.getMessage();
},
};
</script>

View File

@@ -0,0 +1,111 @@
<template>
<div class="accordion" role="tablist">
<b-card v-for="season in seasons" :key="season.season_id">
<b-card-header header-tag="header" role="tab">
<a class="no-link" v-b-toggle="'accordion-' + season.season_id">
<h5 class="mb-0 pu-0 mu-0 season-title">
Season {{ season.season_id }}
<i class="fas fa-chevron-down float-right"></i>
</h5>
</a>
</b-card-header>
<b-collapse :id="'accordion-' + season.season_id" accordion="accordion-season-list">
<b-card-body class="h-100 px-0">
<b-list-group>
<b-list-group-item v-for="episode in season.episodes" :key="episode.episode_id">
<a class="no-link" href="#">
Ep. {{ episode.episode_id }} - "{{ episode.title }}"
</a>
</b-list-group-item>
</b-list-group>
</b-card-body>
</b-collapse>
</b-card>
</div>
</template>
<style lang="scss">
body { background-color: #0a0a0a; }
.season-title { color: #888888; }
.accordion.list-group-item {
border-radius: 0;
border-width: 0 0 0 0;
border-bottom-width: 1px;
padding-left: 30px;
font-weight: 500;
&:first-child { border-top-width: 1px; }
&:last-child { border-bottom-width: 0; }
}
.accordion {
.list-group-item {
a { display: block; }
.badge { float: right; min-width: 36px; }
}
.card-body { padding: 0; }
}
a > .list-group-item { color: white; }
.card-header {
background-color: #161616;
border-bottom: 1px solid rgba(0, 0, 0, 0.88);
}
.card {
background-color: inherit;
border: 1px solid rgba(0, 0, 0, .125);
border-bottom-color: rgba(0, 0, 0, 0.125);
border-radius: 0;
}
.list-group-item {
background-color: #111111;
color: grey;
}
.no-link {
color: inherit;
text-decoration: none;
&:hover {
color: inherit;
text-decoration: none;
}
}
</style>
<script>
import axios from 'axios';
export default {
name: 'SeasonList',
data() {
return {
seasons: [],
};
},
methods: {
getSeasons() {
const path = 'http://localhost:5000/api/episodes/';
axios.get(path)
.then((res) => {
this.seasons = res.data;
})
.catch((error) => {
// eslint-disable-next-line no-console
console.error(error);
});
},
},
created() {
this.getSeasons();
},
};
</script>

View File

@@ -1,11 +1,13 @@
import 'bootstrap/dist/css/bootstrap.css';
import Vue from 'vue';
import BootstrapVue from 'bootstrap-vue';
import App from './App.vue';
import router from './router';
Vue.use(BootstrapVue);
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
render: (h) => h(App),
}).$mount('#app');

View File

@@ -1,7 +1,5 @@
import Vue from 'vue';
import Router from 'vue-router';
import Books from './components/Books.vue';
import Ping from './components/Ping.vue';
Vue.use(Router);
@@ -9,15 +7,5 @@ export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'Books',
component: Books,
},
{
path: '/ping',
name: 'Ping',
component: Ping,
},
],
});

121
package-lock.json generated
View File

@@ -2,6 +2,24 @@
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@nuxt/opencollective": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.2.2.tgz",
"integrity": "sha512-ie50SpS47L+0gLsW4yP23zI/PtjsDRglyozX2G09jeiUazC1AJlGPZo0JUs9iuCDUoIgsDEf66y7/bSfig0BpA==",
"requires": {
"chalk": "^2.4.1",
"consola": "^2.3.0",
"node-fetch": "^2.3.0"
}
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"axios": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
@@ -12,19 +30,116 @@
}
},
"bootstrap": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.1.tgz",
"integrity": "sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ=="
},
"bootstrap-vue": {
"version": "2.0.0-rc.19",
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.0-rc.19.tgz",
"integrity": "sha512-OCbRwqKb0F+RGr162m+RyKI4yNM0VjfxOGI32CMgHfCnnc0MZ0wF2Svg2E3Q7AWCq0N8LgD/EsF/K7Vg3kdDyw==",
"requires": {
"@nuxt/opencollective": "^0.2.2",
"bootstrap": "^4.3.1",
"core-js": ">=2.6.5 <3.0.0",
"popper.js": "^1.15.0",
"portal-vue": "^2.1.1",
"vue-functional-data-merge": "^2.0.7"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"consola": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/consola/-/consola-2.14.0.tgz",
"integrity": "sha512-A2j1x4u8d6SIVikhZROfpFJxQZie+cZOfQMyI/tu2+hWXe8iAv7R6FW6s6x04/7zBCst94lPddztot/d6GJiuQ=="
},
"core-js": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"follow-redirects": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
"integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg=="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portal-vue": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz",
"integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g=="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
},
"vue-functional-data-merge": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz",
"integrity": "sha512-pvLc+H+x2prwBj/uSEIITyxjz/7ZUVVK8uYbrYMmhDvMXnzh9OvQvVEwcOSBQjsubd4Eq41/CSJaWzy4hemMNQ=="
}
}
}

0
server/__init__.py Normal file
View File

View File

@@ -3,15 +3,46 @@ api.py
Provides a accessible protected backend API. JSON I/O only, CSRF protected.
"""
import json
import os
import flask_wtf
from flask import current_app, jsonify
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(BASE_DIR, 'data', 'data.json'), 'r', encoding='utf-8') as file:
data = json.load(file)
@current_app.route('/api/csrf/')
def csrf():
def api_csrf():
"""
Page used for refreshing expired CSRF tokens via AJAX.
Probably secure: https://medium.com/@iaincollins/csrf-tokens-via-ajax-a885c7305d4a
"""
return jsonify(flask_wtf.csrf.generate_csrf())
@current_app.route('/api/episodes/')
def api_episodes():
"""
Returns a list of episodes with basic information (no quotes).
Used for the left side season bar.
"""
seasons = []
copy = list(data)
for season in copy:
for episode in season.get('episodes'):
if 'scenes' in episode.keys():
del episode['scenes']
seasons.append(season)
return jsonify(seasons)
@current_app.route('/api/all/')
def api_data():
"""
Season data route
"""
return jsonify(data)

View File

@@ -15,7 +15,6 @@ from werkzeug.exceptions import HTTPException
from server.config import configs
csrf = CSRFProtect()
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
cors = CORS(resources={r'/*': {'origins': '*'}})
@@ -65,6 +64,7 @@ def create_app(env=None):
@app.context_processor
def inject_data():
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(BASE_DIR, 'data', 'data.json'), 'r', encoding='utf-8') as file:
return dict(data=json.load(file))
@@ -72,5 +72,7 @@ def create_app(env=None):
with app.app_context():
# noinspection PyUnresolvedReferences
from server import routes
# noinspection PyUnresolvedReferences
from server import api
return app

View File

@@ -54,6 +54,7 @@
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>