Remove coreui (#76)

* adding typing and flake8

* removing coreui. ComicCard.vue finished

* removing coreui. ConfirmButton.vue finished

* removing coreui. more pages finished.

* removing coreui. all pages finished

* removing coreui. all pages finished

* version bump and update python deps.

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/InitialSetup.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheAccountForm.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheAccountForm.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ConfirmButton.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/vue.config.js

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheNavbar.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update TheNavbar.vue

Co-authored-by: Peter Dwyer <peter.dwyer@clanwilliamhealth.com>
Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>
This commit is contained in:
2022-09-07 15:14:03 +01:00
committed by GitHub
parent 2af8e18f0a
commit 01e73cc9b3
27 changed files with 1574 additions and 1518 deletions

View File

@@ -12,7 +12,6 @@ repos:
rev: '1.2.0rc1' # add version here
hooks:
- id: poetry-check
- id: poetry-lock
- id: poetry-export
args: ["--without-hashes", "-f", "requirements.txt", "-o", "requirements.txt"]
- repo: https://github.com/pycqa/flake8

View File

@@ -415,7 +415,7 @@ class ActionViewSet(viewsets.GenericViewSet):
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
def get_comics(self, selectors: Iterable[str, UUID]) -> List[str]:
def get_comics(self, selectors: Iterable[Union[str, UUID]]) -> List[str]:
data = set()
data = data.union(
set(models.ComicBook.objects.filter(selector__in=selectors).values_list('selector', flat=True)))

File diff suppressed because it is too large Load Diff

View File

@@ -4,34 +4,26 @@
"private": true,
"scripts": {
"serve": "webpack-dev-server --config webpack.dev.js",
"build": "npx webpack --config webpack.prod.js",
"build": "webpack --config webpack.prod.js",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@coreui/coreui": "^4.2.0",
"@coreui/vue": "^4.3.0",
"@fortawesome/fontawesome-svg-core": "^6.1.2",
"@fortawesome/free-solid-svg-icons": "^6.1.2",
"@fortawesome/vue-fontawesome": "^3.0.1",
"axios": "^0.27.2",
"axios-jwt": "^1.8.0",
"bootstrap": "^4.6.2",
"core-js": "^3.8.3",
"bootstrap": "^5.2.0",
"hammerjs": "^2.0.8",
"jwt-decode": "^3.1.2",
"pdfvuer": "^2.0.1",
"reveal.js": "^4.3.1",
"reveal.js-menu": "^2.1.0",
"style-loader": "^3.3.1",
"timeago.js": "^4.0.2",
"vue": "^3.2.13",
"vue-loader": "^17.0.0",
"vue-router": "^4.0.3",
"vue-toast-notification": "3.0",
"vuejs-paginate-next": "^1.0.2",
"vuex": "^4.0.0",
"webpack": "^5.74.0",
"webpack-bundle-tracker": "^1.6.0"
"webpack": "^5.74.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@@ -45,7 +37,12 @@
"eslint-plugin-vue": "^8.0.3",
"jshint": "^2.13.5",
"mini-css-extract-plugin": "^2.6.1",
"webpack-cli": "^4.10.0"
"terser-webpack-plugin": "^5.3.6",
"webpack-bundle-analyzer": "^4.6.1",
"webpack-cli": "^4.10.0",
"webpack-bundle-tracker": "^1.6.0",
"style-loader": "^3.3.1",
"vue-loader": "^17.0.0"
},
"eslintConfig": {
"root": true,
@@ -62,9 +59,6 @@
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
"defaults"
]
}

View File

@@ -1,41 +1,43 @@
<template>
<CButton color="secondary" @click="visible = true">Add User</CButton>
<CModal :visible="visible" @close="visible = false">
<CModalHeader>
<CModalTitle>Add user</CModalTitle>
</CModalHeader>
<CForm @submit="addUser">
<CModalBody>
<CFormInput
type="text"
label="Username"
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
</CModalBody>
<CModalFooter>
<CButton color="secondary" @click="visible = false">
Close
</CButton>
<CButton color="primary" type="submit">Submit</CButton>
</CModalFooter>
</CForm>
</CModal>
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#addUserModal">Add User</button>
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add user</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form @submit="addUser">
<div class="modal-body">
<div class="mb-3">
<label for="usernameInput" class="form-label">Username</label>
<input type="text" class="form-control" id="usernameInput" aria-describedby="usernameHelp" v-model="username">
<div id="usernameHelp" class="form-text">Please enter a unique username</div>
</div>
<div class="mb-3">
<label for="emailInput" class="form-label">Email address</label>
<input type="email" class="form-control" id="emailInput" aria-describedby="emailHelp" v-model="email">
<div id="emailHelp" class="form-text">Must be 8-20 characters long.</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import api from "@/api";
import 'bootstrap/js/dist/modal'
export default {
name: "AddUser",
data() {
return {
visible: false,
username: '',
email: ''
}
@@ -58,7 +60,6 @@ export default {
color: 'success',
text: 'New user "' + response.data.username + '" created with password "' + response2.data.password + '".'
})
this.visible=false
this.$emit('user-added')
})
}).catch(err => {
@@ -66,7 +67,6 @@ export default {
color: 'danger',
text: 'Cannot create user "' + this.username + '" with error "' + (err.response.data.username? err.response.data.username: err.response.data.email) + '".'
})
this.visible = false
})
}
},

View File

@@ -1,7 +1,8 @@
<template>
<CAlert :color="message.color" dismissible v-for="message in messages" :key="message.text">
<div class="alert alert-dismissible fade show" :class="'alert-'+message.color" role="alert" v-for="message in messages" :key="message.text">
{{message.text}}
</CAlert>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</template>
<script>

View File

@@ -1,66 +1,77 @@
<template>
<CCol>
<CCard class="">
<CCardImage orientation="top" :src="thumbnail"/>
<CCardBody class="pb-0 pt-0 pl-1 pr-1 card-img-overlay d-flex" @click="$router.push((data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }}))">
<div class="col">
<div class="card">
<div class="card card-body p-0" @click="$router.push((data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }}))">
<img :src="thumbnail" class="card-img-top" :alt="data.title">
<span class="badge rounded-pill bg-primary unread-badge" v-if="this.unread > 0 && data.type === 'Directory'">{{ this.unread }}</span>
<span class="badge rounded-pill bg-warning classification-badge" v-if="card_type === 'Directory'" >{{ this.$store.state.classifications.find(i => i.value === classification).label }}</span>
<CCardTitle class="align-self-end text-break" style="">
<h5 class="card-title text-break mb-0">
<router-link :to="(data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }})">{{ data.title }}</router-link>
</CCardTitle>
</CCardBody>
<CCardFooter class="pl-0 pr-0 pt-0">
<CProgress class="mb-1 position-relative" >
<CProgressBar :value="progressPercentCalc" />
</h5>
</div>
<div class="card-footer px-0 pb-0">
<div class="progress position-relative">
<div class="progress-bar" role="progressbar" aria-label="Basic example" :style="'width: '+ progressPercentCalc +'%;'" :aria-valuenow="progressPercentCalc" aria-valuemin="0" aria-valuemax="100"></div>
<small class="justify-content-center d-flex position-absolute w-100 h-100" style="line-height: normal">{{ progressCalc }} / {{data.total}}</small>
</CProgress>
<CButtonGroup class="w-100">
<CButton color="primary" @click="updateComic('mark_unread')" ><font-awesome-icon icon='book' /></CButton>
<CButton color="primary" @click="updateComic('mark_read')" ><font-awesome-icon icon='book-open' /></CButton>
<CDropdown variant="btn-group">
<CDropdownToggle color="primary"><font-awesome-icon icon='edit' /></CDropdownToggle>
<CDropdownMenu>
<CDropdownItem @click="updateComic('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</CDropdownItem>
<CDropdownItem @click="updateComic('mark_read')"><font-awesome-icon icon='book-open' />Mark read</CDropdownItem>
<CDropdownItem v-if="data.type === 'ComicBook'" @click="$emit('markPreviousRead', data.selector)"><font-awesome-icon icon='book' /><font-awesome-icon icon='turn-up' />Mark previous comics read</CDropdownItem>
<CDropdownItem v-if="data.type === 'Directory'" @click="editDirectoryVisible = true"><font-awesome-icon icon='edit' />Edit comic</CDropdownItem>
</CDropdownMenu>
</CDropdown>
</CButtonGroup>
</CCardFooter>
</CCard>
<CModal :visible="editDirectoryVisible" @close="editDirectoryVisible = false">
<CModalHeader>
<CModalTitle>{{ data.title }}</CModalTitle>
</CModalHeader>
<CForm @submit="updateDirectory">
<CModalBody>
<CFormSelect
label="Classification"
aria-label="Set Classification"
v-model="new_classification"
:options="[...this.$store.state.classifications]">
</CFormSelect>
<CFormCheck
label="Recursive"
class="mt-2"
v-model="recursive"
/>
</CModalBody>
<CModalFooter>
<CButton color="secondary" @click="editDirectoryVisible = false ">
Close
</CButton>
<CButton color="primary" type="submit">Save changes</CButton>
</CModalFooter>
</CForm>
</CModal>
</CCol>
</div>
<div class="btn-group w-100 pt-1" role="group" aria-label="Basic example">
<button type="button" class="btn btn-primary" @click="updateComic('mark_unread')"><font-awesome-icon icon='book' /></button>
<button type="button" class="btn btn-primary" @click="updateComic('mark_read')" ><font-awesome-icon icon='book-open' /></button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<font-awesome-icon icon='edit' />
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" @click="updateComic('mark_unread')"><font-awesome-icon icon='book' /> Mark Un-read</a></li>
<li><a class="dropdown-item" @click="updateComic('mark_read')"><font-awesome-icon icon='book-open' /> Mark read</a></li>
<li><a class="dropdown-item" v-if="data.type === 'ComicBook'" @click="$emit('markPreviousRead', data.selector)"><font-awesome-icon icon='book' /><font-awesome-icon icon='turn-up' />Mark previous comics read</a></li>
<li><a class="dropdown-item" v-if="data.type === 'Directory'" data-bs-toggle="modal" :data-bs-target="'#'+data.selector"><font-awesome-icon icon='edit' />Edit comic</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" :id="data.selector" tabindex="-1" :aria-labelledby="data.selector+'-label'" aria-hidden="true" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" :id="data.selector+'-label'">{{ data.title }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form @submit="updateDirectory">
<div class="modal-body">
<div class="mb-3">
<label class="form-check-label mb-1" :for="data.selector+'-classification'" >
Classification
</label>
<select class="form-select" :id="data.selector+'-classification'" v-model="new_classification">
<option v-for="class_options in [...this.$store.state.classifications]" :key="class_options.value" :value="class_options.value">{{class_options.label}}</option>
</select>
</div>
<div class="mb-3">
<input class="form-check-input" type="checkbox" value="" :id="data.selector+'-recursive'" v-model="recursive">
<label class="form-check-label px-1" :for="data.selector+'-recursive'" >
Recursive
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import {useToast} from "vue-toast-notification";
import api from "@/api";
import 'bootstrap/js/dist/modal'
export default {
name: "ComicCard",
@@ -160,15 +171,12 @@ export default {
.card-title a {
color: white;
text-shadow: .2rem .2rem .3rem black ;
}
h5.card-title {
margin-bottom: 75px;
position: absolute;
bottom: 0;
left: 0;
text-decoration: none;
background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent);
}
h5.card-title::before {
filter: blur(12px);
width: 100%;
}
.card .unread-badge {

View File

@@ -0,0 +1,73 @@
<template>
<ul class="list-group list-group-horizontal">
<li class="list-group-item" @click="this.$emit('prevComic')">Prev&nbsp;Comic</li>
<li class="list-group-item" @click="prevPage">Prev</li>
<template v-for="ind in visible_pages" :key="ind">
<li class="list-group-item" :class="(ind===modelValue ? 'list-group-item-primary': '')" @click="setPage(ind)">{{ ind }}</li>
</template>
<li class="list-group-item" @click="nextPage">Next</li>
<li class="list-group-item" @click="this.$emit('nextComic')">Next&nbsp;Comic</li>
</ul>
</template>
<script>
export default {
name: "ComicPaginate",
props: {
page_count: Number,
modelValue: Number,
},
emits: ['update:modelValue', 'setPage', 'prevComic', 'nextComic'],
methods: {
setPage(evt) {
if (evt !== '...'){
this.$emit("setPage", evt)
}
},
nextPage(){
if (this.modelValue === this.page_count){
this.$emit('nextComic')
} else {
this.setPage(this.modelValue + 1)
}
},
prevPage(){
if (this.modelValue === 1) {
this.$emit('prevComic')
} else {
this.setPage(this.modelValue - 1)
}
}
},
computed: {
visible_pages(){
let out = []
if (this.page_count <= 5) {
for (let i = 1; i <= this.page_count; i++){
out.push(i)
}
return out
}
let min = Math.max(1, this.modelValue - 2)
let max = Math.min(this.page_count, this.modelValue + 2)
for (let i = min; i <= max; i++){
out.push(i)
}
if (out[0] !== 1) {
out.splice(0, 1, ...[1, "..."])
}
if (out[out.length - 1] !==this.page_count){
out.splice(out.length - 1, 1, ...["...", this.page_count])
}
return out
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,16 +1,13 @@
<template>
<CButtonGroup>
<CButton :color="color" v-if="!confirm" @click="confirm = !confirm">{{ label }}</CButton>
<CButton color="success" class="text-nowrap" v-if="confirm" variant="outline" @click="performAction">
<font-awesome-icon icon='check' class=""/>
Yes
</CButton>
<CButton color="danger" class="text-nowrap" v-if="confirm" variant="outline"
@click="confirm = !confirm">
<font-awesome-icon icon='times' class=""/>
No
</CButton>
</CButtonGroup>
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn" :class="'btn-'+color" v-if="!confirm" @click="confirm = !confirm">{{ label }}</button>
<button type="button" class="btn btn-outline-success text-nowrap" v-if="confirm" @click="performAction">
<font-awesome-icon icon="check" class="" />Yes
</button>
<button type="button" class="btn btn-outline-danger text-nowrap" v-if="confirm" @click="confirm = !confirm">
<font-awesome-icon icon='times' class=""/>No
</button>
</div>
</template>
<script>
export default {

View File

@@ -1,58 +0,0 @@
<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>

View File

@@ -1,30 +1,20 @@
<template>
<h1>Create your admin account.</h1>
<CForm @submit="saveForm">
<CFormInput
type="text"
label="Username"
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
<CFormInput
type="password"
label="Password"
v-model="password"
/>
<CFormInput
type="password"
label="Confirm Password"
v-model="confirm_password"
/>
<CButton color="primary" type="submit" class="mr-5 mt-2">Save</CButton>
</CForm>
<form @submit="saveForm">
<label class="form-label">Username</label>
<input class="form-control" type="text" v-model="username" />
<label class="form-label">Email address</label>
<input class="form-control" type="email" v-model="email">
<label class="form-label">Password</label>
<input class="form-control" type="password" v-model="password">
<label class="form-label">Confirm Password</label>
<input class="form-control" type="password" v-model="confirm_password">
<button class="btn btn-primary mr-5 mt-2" type="submit">Save</button>
</form>
</template>
<script>

View File

@@ -1,66 +1,35 @@
<template>
<CContainer>
<CForm @submit="updateAccount">
<CFormInput
type="text"
label="Username"
readonly
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
:placeholder="email"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
:valid="validateEmail(email)"
/>
<CFormInput
type="password"
label="Current Password"
placeholder="Enter Current Password"
text="Must enter current password to change settings."
v-model="current_password"
feedback-invalid="Wrong Password."
:valid="current_password.length > 0"
/>
<CFormInput
type="password"
label="New Password"
placeholder="Enter New Password"
text="Must be at least 9 characters long."
v-model="new_password"
feedback-invalid="Password is not complex enough."
:valid="checkNewPassword(new_password)"
/>
<CFormInput
type="password"
label="New Password Confirm"
placeholder="Enter New Password"
text="Must be at least 9 characters long."
v-model="new_password_confirm"
feedback-invalid="New passwords should match."
:valid="new_password === new_password_confirm && new_password.length > 8"
/>
<CButton color="primary" type="submit">Save</CButton>
</CForm>
</CContainer>
<div class="container">
<form @submit="updateAccount">
<label class="form-label">Username</label>
<input class="form-control" readonly type="text" v-model="username" />
<label class="form-label">Email address</label>
<input placeholder="" class="form-control" type="email" v-model="email" />
<label class="form-label">Current Password</label>
<input placeholder="Enter Current Password" class="form-control" type="password" v-model="current_password"/>
<div class="form-text">Must enter current password to change settings.</div>
<label class="form-label">New Password</label><input placeholder="Enter New Password" class="form-control" type="password" v-model="new_password"/>
<div class="form-text">Must be at least 9 characters long.</div>
<label class="form-label">New Password Confirm</label><input placeholder="Enter New Password" class="form-control" type="password" v-model="new_password_confirm"/>
<div class="form-text">Must be at least 9 characters long.</div>
<button class="btn btn-primary" type="submit">Save</button>
</form>
</div>
</template>
<script>
import {CForm, CFormInput, CContainer, CButton} from "@coreui/vue";
import api from "@/api";
import {useToast} from "vue-toast-notification";
const toast = useToast();
export default {
name: "TheAccountForm",
components: {
CForm,
CFormInput,
CContainer,
CButton
},
components: {},
data () {
return {
username: '',
@@ -87,7 +56,10 @@ export default {
updateAccount () {
if (!this.current_password) {
toast.error('Please enter your current password.', {position:'top'});
} else if (this.email === this.$store.state.user.email && this.new_password.length === 0){
toast.error('No changes detected', {position:'top'});
} else {
console.log(this.email === this.$store.state.user.email)
if (this.email !== this.$store.state.user.email) {
let payload = {
username: this.username,
@@ -101,7 +73,7 @@ export default {
toast.error(error.response.data.errors)
})
}
if (this.new_password === this.new_password_confirm) {
if (this.new_password === this.new_password_confirm && this.new_password.length > 0) {
let payload = {
username: this.username,
old_password: this.current_password,
@@ -119,12 +91,6 @@ export default {
}
},
validateEmail(mail){
return (/\S+@\S+\.\S+/.test(mail))
},
checkNewPassword(pass){
return (pass.length >= 9)
}
}
}
</script>

View File

@@ -1,32 +1,30 @@
<template>
<CBreadcrumb>
<nav aria-label="breadcrumb" class="px-5">
<ol class="breadcrumb " >
<template v-for="(item, index) in crumbs" :key="item.id">
<template v-if="index !== crumbs.length - 1">
<CBreadcrumbItem v-if="item.selector">
<li class="breadcrumb-item" v-if="item.selector">
<router-link :to="{'name': 'browse', params: { selector: item.selector }}">{{ item.name }}</router-link>
</CBreadcrumbItem>
<CBreadcrumbItem v-else-if="item.route">
</li>
<li class="breadcrumb-item" v-else-if="item.route">
<router-link :to="item.route">{{ item.name }}</router-link>
</CBreadcrumbItem>
<CBreadcrumbItem v-else>
</li>
<li class="breadcrumb-item" v-else>
<router-link :to="{'name': 'browse'}">{{ item.name }}</router-link>
</CBreadcrumbItem>
</li>
</template>
<CBreadcrumbItem v-else active>{{ item.name }}</CBreadcrumbItem>
<li class="breadcrumb-item active" aria-current="page" v-else>{{ item.name }}</li>
</template>
</CBreadcrumb>
</ol>
</nav>
</template>
<script>
import { CBreadcrumbItem, CBreadcrumb } from '@coreui/vue'
import api from "@/api";
export default {
name: "TheBreadcrumbs",
components: {
CBreadcrumb,
CBreadcrumbItem,
},
components: { },
data () {
return {
crumbs: []
@@ -68,5 +66,10 @@ export default {
</script>
<style scoped>
.breadcrumb-item a {
text-decoration: none;
}
nav {
background: lightgrey;
}
</style>

View File

@@ -1,26 +1,24 @@
<template>
<CContainer fluid>
<CRow>
<CInputGroup>
<CFormInput placeholder="Search" aria-label="Filter comics by name" v-model="this.filters.search_string"/>
<CButton type="button" :color="(!filters.filter_read && !filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=false; filters.filter_unread=false">All</CButton>
<CButton type="button" :color="(filters.filter_read && !filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=true; filters.filter_unread=false">Read</CButton>
<CButton type="button" :color="(!filters.filter_read && filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=false; filters.filter_unread=true">Un-read</CButton>
<CDropdown variant="input-group">
<CDropdownToggle color="secondary" variant="outline">Action</CDropdownToggle>
<CDropdownMenu>
<CDropdownItem @click="markAll('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</CDropdownItem>
<CDropdownItem @click="markAll('mark_read')"><font-awesome-icon icon='book-open' />Mark read</CDropdownItem>
</CDropdownMenu>
</CDropdown>
</CInputGroup>
</CRow>
<div class="container-fluid">
<div class="row">
<div class="input-group">
<input class="form-control" aria-label="Filter comics by name" placeholder="Search" v-model="this.filters.search_string">
<button type="button" class="btn" :class="(!filters.filter_read && !filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=false; filters.filter_unread=false">All</button>
<button type="button" class="btn" :class="(filters.filter_read && !filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=true; filters.filter_unread=false">Read</button>
<button type="button" class="btn" :class="(!filters.filter_read && filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=false; filters.filter_unread=true">Un-read</button>
<button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Action</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" @click="markAll('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</a></li>
<li><a class="dropdown-item" @click="markAll('mark_read')"><font-awesome-icon icon='book-open' />Mark read</a></li>
</ul>
</div>
</div>
<div class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-6 row-cols-xl-auto mt-1" >
<template v-if="loading">
<div class="col-12 col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12">
<CProgress class="mt-3" >
<CProgressBar color="success" variant="striped" animated :value="100"/>
</CProgress>
<div class="progress mt-3">
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" aria-label="Loading data" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
</div>
</template>
<template v-else>
@@ -29,7 +27,7 @@
</template>
</template>
</div>
</CContainer>
</div>
</template>
<script>

View File

@@ -6,34 +6,27 @@
</section>
</div>
</div>
<CRow class="navButtons pb-2">
<CListGroup :layout="'horizontal'">
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="prevComic">Prev&nbsp;Comic</CListGroupItem>
<paginate
v-model="paginate_page"
:page-count="pages.length"
:click-handler="this.setPage"
:prev-text="'Prev'"
:next-text="'Next'"
:container-class="'pagination'"
>
</paginate>
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="nextComic">Next&nbsp;Comic</CListGroupItem>
</CListGroup>
</CRow>
<div class="row navButtons pb-2">
<comic-paginate
v-model="paginate_page"
:page_count="pages.length"
@setPage="this.setPage"
@prevComic="prevComic"
@nextComic="nextComic"
/>
</div>
</template>
<script>
import Reveal from "reveal.js";
import api from "@/api";
import 'reveal.js-menu/menu.css'
import Paginate from "vuejs-paginate-next";
import * as Hammer from 'hammerjs'
import ComicPaginate from "@/components/ComicPaginate";
export default {
name: "TheComicReader",
components: {Paginate},
components: {ComicPaginate},
data () {
return {
current_page: 0,
@@ -185,7 +178,4 @@ export default {
section {
padding-bottom: 60px;
}
.list-group-item {
/*padding: 0;*/
}
</style>

View File

@@ -1,46 +1,39 @@
<template>
<CNavbar expand="lg" color-scheme="light" class="bg-light">
<CContainer fluid>
<CNavbarBrand href="#"><img src="/static/img/logo.svg" width="35" class="d-inline-block align-top" alt="CB"> Web Reader</CNavbarBrand>
<CNavbarToggler @click="visible = !visible"/>
<CCollapse class="navbar-collapse" :visible="visible">
<CNavbarNav>
<CNavItem>
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img src="/static/img/logo.svg" width="35" class="d-inline-block align-top" alt="CB"> Web Reader</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<router-link :to="{name: 'browse'}" class="nav-link" >Browse</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'recent'}" class="nav-link" >Recent</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'account'}" class="nav-link" >Account</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'user'}" class="nav-link" v-if="this.$store.getters.is_superuser">Users</router-link>
</CNavItem>
<CNavItem>
<CNavLink @click="logout">Log Out</CNavLink>
</CNavItem>
</CNavbarNav>
</CCollapse>
</CContainer>
</CNavbar>
</li>
<li class="nav-item">
<a class="nav-link" @click="logout">Log Out</a>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script>
import { CNavbar, CNavbarNav, CContainer, CNavbarBrand, CNavbarToggler, CCollapse, CNavItem, CNavLink } from '@coreui/vue'
import store from "@/store";
import router from "@/router";
import 'bootstrap/js/dist/collapse'
export default {
name: "TheNavbar",
components: {
CNavbar,
CNavbarNav,
CContainer,
CNavbarBrand,
CNavbarToggler,
CCollapse,
CNavItem,
CNavLink
},
components: { },
data() {
return {
visible: false

View File

@@ -1,41 +1,35 @@
<template>
<CContainer ref="pdfContainer">
<CRow class="w-100 pb-5 mb-5" v-if="loaded" >
<pdf :src="pdfdata" :page="page" ref="pdfWindow" :resize="true">
<template v-slot:loading>
loading content here...
</template>
</pdf>
</CRow>
</CContainer>
<CRow class="navButtons pb-2">
<CListGroup :layout="'horizontal'">
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="prevComic">Prev&nbsp;Comic</CListGroupItem>
<paginate
v-model="page"
:page-count="numPages"
:click-handler="this.setPage"
:prev-text="'Prev'"
:next-text="'Next'"
:container-class="'pagination'"
>
</paginate>
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="nextComic">Next&nbsp;Comic</CListGroupItem>
</CListGroup>
</CRow>
<div class="container" ref="pdfContainer">
<div class="row w-100 pb-5 mb-5" v-if="loaded">
<pdf :src="pdfdata" :page="page" ref="pdfWindow" :resize="true">
<template v-slot:loading>
loading content here...
</template>
</pdf>
</div>
</div>
<div class="row navButtons pb-2">
<comic-paginate
v-model="page"
:page_count="numPages"
@setPage="setPage"
@prevComic="prevComic"
@nextComic="nextComic"
/>
</div>
</template>
<script>
import pdfvuer from 'pdfvuer'
import api from "@/api";
import Paginate from "vuejs-paginate-next";
import * as Hammer from 'hammerjs'
import ComicPaginate from "@/components/ComicPaginate";
export default {
name: "ThePdfReader",
components: {
pdf: pdfvuer, Paginate
ComicPaginate,
pdf: pdfvuer
},
data () {
return {
@@ -83,7 +77,7 @@ export default {
this.setReadPage(this.page)
this.next_comic = response.data.next_comic
this.prev_comic = response.data.prev_comic
this.hammertime = new Hammer(this.$refs.pdfContainer.$el, {})
this.hammertime = new Hammer(this.$refs.pdfContainer, {})
this.hammertime.on('swipeleft', (_e, self=this) => {
self.nextPage()
})
@@ -130,7 +124,7 @@ export default {
this.setReadPage(this.page)
},
setReadPage(num){
this.$refs.pdfContainer.$el.scrollIntoView()
this.$refs.pdfContainer.scrollIntoView()
let payload = {
page: num-1
}

View File

@@ -1,65 +1,68 @@
<template>
<CContainer>
<CRow>
<CCol>
<div class="container">
<div class="row">
<div class="col d-flex align-items-center">
<form class="form-inline ">
<label class="my-1 mr-2" for="selectChoices">Show</label>
<label class="my-1 px-1" for="selectChoices">Show</label>
<select class="custom-select my-1 mr-sm-2 " id="selectChoices" v-model="this.page_size" @change="this.setPage(this.page)">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<label class="my-1 mr-2" for="selectChoices">entries</label>
<label class="my-1 px-1" for="selectChoices">entries</label>
</form>
</CCol>
<CCol class="d-flex justify-content-end">
</div>
<div class="col d-flex justify-content-end">
<form class="form-inline">
<label for="searchText" class="my-1 mr-2">Search</label>
<input type="text" id="searchText" class="form-control my-1 mr-sm-2" v-model="search_text" @keyup="this.debounceInput()">
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" v-model="search_text" @keyup="this.debounceInput()">
<label for="floatingInput">Search</label>
</div>
</form>
</CCol>
</CRow>
<CRow>
</div>
</div>
<div class="row">
<caption>
<h2>Recent Comics - <a :href="'/feed/' + this.feed_id + '/'">Feed</a></h2>
Mark selected issues as:
<select name="func" id="func_selector" @change="this.performFunction()" v-model="func_selected">
<select class="form-select-sm" name="func" id="func_selector" @change="this.performFunction()" v-model="func_selected">
<option value="choose">Choose...</option>
<option value="mark_read">Read</option>
<option value="mark_unread">Un-Read</option>
</select>
</caption>
</CRow>
<CRow>
<CTable striped bordered>
<CTableHead>
<CTableRow>
<CTableHeaderCell scope="col"><input class="form-check-input m-0 position-relative mt-1" type="checkbox" value="" ref="select-all"></CTableHeaderCell>
<CTableHeaderCell scope="col"></CTableHeaderCell>
<CTableHeaderCell scope="col">Comic</CTableHeaderCell>
<CTableHeaderCell scope="col">Date Added</CTableHeaderCell>
<CTableHeaderCell scope="col">status</CTableHeaderCell>
</CTableRow>
</CTableHead>
<CTableBody>
</div>
<div class="row">
<table class="table table-striped table-bordered">
<caption>Recent Comics</caption>
<thead>
<tr>
<th scope="col"><input class="form-check-input m-0 position-relative mt-1" type="checkbox" value="" ref="select-all"></th>
<th scope="col"></th>
<th scope="col">Comic</th>
<th scope="col">Date Added</th>
<th scope="col">status</th>
</tr>
</thead>
<tbody>
<template v-for="item in comics" :key="item.id">
<CTableRow>
<CTableHeaderCell scope="row"><input ref="comic_selector" class="form-check-input m-0 position-relative mt-1" type="checkbox" :value="item.selector"></CTableHeaderCell>
<CTableDataCell class=""><font-awesome-icon icon='book' class="" /></CTableDataCell>
<CTableDataCell><router-link :to="{name: 'read', params: { selector: item.selector }}" class="" >{{ item.file_name }}</router-link></CTableDataCell>
<CTableDataCell>{{ timeago(item.date_added) }}</CTableDataCell>
<CTableDataCell>{{ get_status(item) }}</CTableDataCell>
</CTableRow>
<tr>
<th scope="row"><input ref="comic_selector" class="form-check-input m-0 position-relative mt-1" type="checkbox" :value="item.selector"></th>
<td class=""><font-awesome-icon icon='book' class="" /></td>
<td><router-link :to="{name: 'read', params: { selector: item.selector }}" class="" >{{ item.file_name }}</router-link></td>
<td>{{ timeago(item.date_added) }}</td>
<td>{{ get_status(item) }}</td>
</tr>
</template>
</CTableBody>
</CTable>
</CRow>
<CRow>
<CCol>
</tbody>
</table>
</div>
<div class="row">
<div class="col">
Showing page {{ this.page }} of {{ this.page_count }} pages.
</CCol>
<CCol class="d-flex justify-content-end">
</div>
<div class="col d-flex justify-content-end">
<paginate
v-model="this.page"
:page-count="this.page_count"
@@ -69,9 +72,9 @@
:container-class="'pagination '"
>
</paginate>
</CCol>
</CRow>
</CContainer>
</div>
</div>
</div>
</template>
<script>

View File

@@ -1,35 +1,26 @@
<template>
<CContainer>
<CForm @submit="saveForm">
<CFormInput
type="text"
label="Username"
readonly
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
:placeholder="user.email"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
<CFormSelect
aria-label="Default select example"
v-model="classification"
:options="[...this.$store.state.classifications]">
</CFormSelect>
<CRow class="mt-2">
<CCol>
<CButton color="primary" type="submit" class="mr-5">Save</CButton>
<confirm-button class="mr-5" label="Reset Password" :action="resetPassword" />
<confirm-button label="Delete User" :action="deleteUser" />
</CCol>
</CRow>
<div class="container">
<form @submit="saveForm">
<label class="form-label">Username</label>
<input class="form-control" readonly="" type="text" v-model="username" />
</CForm>
</CContainer>
<label class="form-label">Email address</label>
<input placeholder="" class="form-control" type="email" v-model="email"/>
<label class="form-label">Classification</label>
<select aria-label="Default select example" class="form-select" v-model="classification">
<option v-for="class_opt in [...this.$store.state.classifications]" :key="class_opt.value" :value="class_opt.value">{{class_opt.label}}</option>
</select>
<div class="row mt-2">
<div class="col">
<button type="submit" class="btn btn-primary me-5">Save</button>
<confirm-button class="me-5" label="Reset Password" :action="resetPassword" />
<confirm-button label="Delete User" :action="deleteUser" />
</div>
</div>
</form>
</div>
</template>
<script>
@@ -111,4 +102,3 @@ export default {
}
}
</script>

View File

@@ -1,28 +1,29 @@
<template>
<CTable striped bordered>
<CTableHead>
<CTableRow>
<CTableHeaderCell scope="col">#</CTableHeaderCell>
<CTableHeaderCell scope="col">Username</CTableHeaderCell>
<CTableHeaderCell scope="col">Email</CTableHeaderCell>
<CTableHeaderCell scope="col">Superuser</CTableHeaderCell>
<CTableHeaderCell scope="col">Classification</CTableHeaderCell>
</CTableRow>
</CTableHead>
<CTableBody>
<table class="table table-striped table-bordered">
<caption>User list</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Username</th>
<th scope="col">Email</th>
<th scope="col">Superuser</th>
<th scope="col">Classification</th>
</tr>
</thead>
<tbody>
<template v-for="item in users" :key="item.id">
<CTableRow>
<CTableHeaderCell scope="row">{{ item.id }}</CTableHeaderCell>
<CTableDataCell class="">
<tr>
<th scope="row">{{ item.id }}</th>
<td class="">
<router-link :to="{'name': 'user', params: { userid: item.id }}">{{ item.username }}</router-link>
</CTableDataCell>
<CTableDataCell>{{ item.email }}</CTableDataCell>
<CTableDataCell>{{ item.is_superuser }}</CTableDataCell>
<CTableDataCell>{{ this.$store.state.classifications.find(i => i.value === item.classification.toString()).label }}</CTableDataCell>
</CTableRow>
</td>
<td>{{ item.email }}</td>
<td>{{ item.is_superuser }}</td>
<td>{{ this.$store.state.classifications.find(i => i.value === item.classification.toString()).label }}</td>
</tr>
</template>
</CTableBody>
</CTable>
</tbody>
</table>
</template>
<script>

View File

@@ -1,12 +1,13 @@
import * as Vue from 'vue'
import App from './App.vue'
import ToastPlugin from 'vue-toast-notification';
import CoreuiVue from '@coreui/vue';
import '@coreui/coreui/dist/css/coreui.min.css'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'vue-toast-notification/dist/theme-default.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/js/dist/dropdown'
/* import the fontawesome core */
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -14,14 +15,13 @@ import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
/* import specific icons */
import {faBook, faBookOpen, faEdit, faTurnUp} from '@fortawesome/free-solid-svg-icons'
library.add(faBook, faBookOpen, faEdit, faTurnUp)
import {faBook, faBookOpen, faEdit, faTurnUp, faTimes, faCheck} from '@fortawesome/free-solid-svg-icons'
library.add(faBook, faBookOpen, faEdit, faTurnUp, faTimes, faCheck)
import router from './router'
import store from './store'
Vue.createApp(App)
.use(CoreuiVue)
.use(ToastPlugin)
.use(store)
.use(router)

View File

@@ -1,36 +1,25 @@
<template>
<CContainer>
<CRow v-if="!initialSetupRequired">
<CCol lg="4"/>
<CCol lg="4" id="login-col">
<CForm @submit="login">
<CFormInput
type="username"
id="username"
label="Username"
placeholder="username"
text="Please enter your username"
aria-describedby="loginFormControlInputHelpInline"
v-model="username"
/>
<CFormInput
type="password"
id="password"
label="password"
placeholder="password"
text="Please enter your password"
aria-describedby="loginFormControlInputHelpInline"
v-model="password"
@keyup.enter="login"
/>
<CButton color="primary" class="mb-3">Login</CButton>
</CForm>
</CCol>
</CRow>
<CRow>
<div class="container">
<div class="row" v-if="!initialSetupRequired">
<div class="col col-lg-4" />
<div class="col col-lg-4" id="login-col">
<form @submit="login">
<label class="form-label" for="username">Username</label>
<input id="username" placeholder="username" aria-describedby="loginFormControlInputHelpInline" class="form-control" type="text" v-model="username" />
<div class="form-text" id="loginFormControlInputHelpInline">Please enter your username</div>
<label class="form-label" for="password">password</label>
<input id="password" placeholder="password" aria-describedby="loginFormControlInputHelpInline" class="form-control" type="password" v-model="password"/>
<div class="form-text" id="loginFormControlInputHelpInline">Please enter your password</div>
<button class="btn btn-primary mb-3" type="submit">Login</button>
</form>
</div>
</div>
<div class="row">
<initial-setup v-if="initialSetupRequired" />
</CRow>
</CContainer>
</div>
</div>
</template>
<script>

View File

@@ -1,11 +1,11 @@
<template>
<the-breadcrumbs :manual_crumbs="this.crumbs" />
<CContainer>
<div class="container">
<alert-messages :messages="messages" />
<user-list :users="users" v-if="!userid"/>
<user-edit v-if="user_data" :user="user_data" @add-message="addMessage"/>
<add-user v-if="!userid" @user-added="updateUsers" @add-message="addMessage"/>
</CContainer>
</div>
</template>
<script>

View File

@@ -1,4 +1,10 @@
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
module.exports = defineConfig({
transpileDependencies: true
transpileDependencies: true,
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
},
})

View File

@@ -2,7 +2,7 @@ const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const BundleTracker = require('webpack-bundle-tracker');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const webpack = require('webpack')
@@ -12,7 +12,7 @@ module.exports = (env = {}) => {
return {
mode: 'production',
devtool: false,
devtool: 'hidden-source-map',
entry: path.resolve(__dirname, './src/main.js'),
output: {
path: path.resolve(__dirname, './dist/bundles/'),
@@ -56,6 +56,8 @@ module.exports = (env = {}) => {
}),
new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }),
new MiniCssExtractPlugin(),
// new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {

151
poetry.lock generated
View File

@@ -19,7 +19,7 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "astroid"
version = "2.12.5"
version = "2.12.9"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false
@@ -55,9 +55,9 @@ optional = false
python-versions = ">=3.5"
[package.extras]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope-interface"]
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope-interface"]
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope-interface"]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
[[package]]
@@ -179,7 +179,7 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
version = "37.0.4"
version = "38.0.1"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
category = "dev"
optional = false
@@ -192,7 +192,7 @@ cffi = ">=1.12"
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
sdist = ["setuptools_rust (>=0.11.4)"]
sdist = ["setuptools-rust (>=0.11.4)"]
ssh = ["bcrypt (>=3.1.5)"]
test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"]
@@ -235,7 +235,7 @@ python-versions = "*"
Django = ">3.2"
[[package]]
name = "django"
name = "Django"
version = "4.0.7"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
category = "main"
@@ -537,7 +537,7 @@ tornado = ["tornado (>=0.2)"]
[[package]]
name = "identify"
version = "2.5.3"
version = "2.5.5"
description = "File identification library for Python"
category = "dev"
optional = false
@@ -564,7 +564,7 @@ python-versions = ">=3.5"
[[package]]
name = "ipython"
version = "8.4.0"
version = "8.5.0"
description = "IPython: Productive Interactive Computing"
category = "dev"
optional = false
@@ -579,9 +579,8 @@ jedi = ">=0.16"
matplotlib-inline = "*"
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
pickleshare = "*"
prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
prompt-toolkit = ">3.0.1,<3.1.0"
pygments = ">=2.4.0"
setuptools = ">=18.5"
stack-data = "*"
traitlets = ">=5"
@@ -636,7 +635,7 @@ qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "jinja2"
name = "Jinja2"
version = "3.1.2"
description = "A very fast and expressive template engine."
category = "main"
@@ -673,7 +672,7 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
[[package]]
name = "markupsafe"
name = "MarkupSafe"
version = "2.1.1"
description = "Safely add untrusted strings to HTML/XML markup."
category = "main"
@@ -795,7 +794,7 @@ optional = false
python-versions = "*"
[[package]]
name = "pillow"
name = "Pillow"
version = "9.2.0"
description = "Python Imaging Library (Fork)"
category = "main"
@@ -836,7 +835,7 @@ virtualenv = ">=20.0.8"
[[package]]
name = "prompt-toolkit"
version = "3.0.30"
version = "3.0.31"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
@@ -897,7 +896,7 @@ optional = false
python-versions = ">=3.6"
[[package]]
name = "pygments"
name = "Pygments"
version = "2.13.0"
description = "Pygments is a syntax highlighting package written in Python."
category = "dev"
@@ -908,7 +907,7 @@ python-versions = ">=3.6"
plugins = ["importlib-metadata"]
[[package]]
name = "pyjwt"
name = "PyJWT"
version = "2.4.0"
description = "JSON Web Token implementation in Python"
category = "main"
@@ -917,20 +916,20 @@ python-versions = ">=3.6"
[package.extras]
crypto = ["cryptography (>=3.3.1)"]
dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope-interface"]
docs = ["sphinx", "sphinx-rtd-theme", "zope-interface"]
dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"]
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
[[package]]
name = "pylint"
version = "2.15.0"
version = "2.15.2"
description = "python code static checker"
category = "dev"
optional = false
python-versions = ">=3.7.2"
[package.dependencies]
astroid = ">=2.12.4,<=2.14.0-dev0"
astroid = ">=2.12.9,<=2.14.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = ">=0.2"
isort = ">=4.2.5,<6"
@@ -957,7 +956,7 @@ pylint-plugin-utils = ">=0.7"
[package.extras]
for_tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"]
with_django = ["django"]
with_django = ["Django"]
[[package]]
name = "pylint-plugin-utils"
@@ -971,7 +970,7 @@ python-versions = ">=3.6.2"
pylint = ">=1.7"
[[package]]
name = "pymupdf"
name = "PyMuPDF"
version = "1.18.19"
description = "Python bindings for the PDF toolkit and renderer MuPDF"
category = "main"
@@ -979,7 +978,7 @@ optional = false
python-versions = "*"
[[package]]
name = "pyopenssl"
name = "pyOpenSSL"
version = "22.0.0"
description = "Python wrapper module around the OpenSSL library"
category = "dev"
@@ -1035,7 +1034,7 @@ optional = false
python-versions = "*"
[[package]]
name = "pyyaml"
name = "PyYAML"
version = "6.0"
description = "YAML parser and emitter for Python"
category = "dev"
@@ -1069,7 +1068,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "ruamel-yaml"
name = "ruamel.yaml"
version = "0.17.21"
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
category = "main"
@@ -1084,7 +1083,7 @@ docs = ["ryd"]
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
[[package]]
name = "ruamel-yaml-clib"
name = "ruamel.yaml.clib"
version = "0.2.6"
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
category = "main"
@@ -1101,8 +1100,8 @@ python-versions = ">=3.7"
[package.extras]
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "six"
@@ -1261,7 +1260,7 @@ optional = false
python-versions = "*"
[[package]]
name = "werkzeug"
name = "Werkzeug"
version = "2.0.3"
description = "The comprehensive WSGI web application library."
category = "dev"
@@ -1305,8 +1304,8 @@ asgiref = [
{file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"},
]
astroid = [
{file = "astroid-2.12.5-py3-none-any.whl", hash = "sha256:d612609242996c4365aeb0345e61edba34363eaaba55f1c0addf6a98f073bef6"},
{file = "astroid-2.12.5.tar.gz", hash = "sha256:396c88d0a58d7f8daadf730b2ce90838bf338c6752558db719ec6f99c18ec20e"},
{file = "astroid-2.12.9-py3-none-any.whl", hash = "sha256:27a22f40e45af6d362498647a0940e8ae9c35f71cb572a1b6f8f810122a11918"},
{file = "astroid-2.12.9.tar.gz", hash = "sha256:0dafbfcf4ebdecd3c8f6d742c9d9c88508229ca823d5c98ab872d964f3321e56"},
]
asttokens = [
{file = "asttokens-2.0.8-py2.py3-none-any.whl", hash = "sha256:e3305297c744ae53ffa032c45dc347286165e4ffce6875dc662b205db0623d86"},
@@ -1471,28 +1470,32 @@ coverage = [
{file = "coverage-6.4.4.tar.gz", hash = "sha256:e16c45b726acb780e1e6f88b286d3c10b3914ab03438f32117c4aa52d7f30d58"},
]
cryptography = [
{file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884"},
{file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6"},
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046"},
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5"},
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b"},
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8"},
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280"},
{file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3"},
{file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59"},
{file = "cryptography-37.0.4-cp36-abi3-win32.whl", hash = "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157"},
{file = "cryptography-37.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327"},
{file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b"},
{file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"},
{file = "cryptography-37.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67"},
{file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d"},
{file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282"},
{file = "cryptography-37.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa"},
{file = "cryptography-37.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441"},
{file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596"},
{file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a"},
{file = "cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"},
{file = "cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"},
{file = "cryptography-38.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:10d1f29d6292fc95acb597bacefd5b9e812099d75a6469004fd38ba5471a977f"},
{file = "cryptography-38.0.1-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3fc26e22840b77326a764ceb5f02ca2d342305fba08f002a8c1f139540cdfaad"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3b72c360427889b40f36dc214630e688c2fe03e16c162ef0aa41da7ab1455153"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:194044c6b89a2f9f169df475cc167f6157eb9151cc69af8a2a163481d45cc407"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca9f6784ea96b55ff41708b92c3f6aeaebde4c560308e5fbbd3173fbc466e94e"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:16fa61e7481f4b77ef53991075de29fc5bacb582a1244046d2e8b4bb72ef66d0"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d4ef6cc305394ed669d4d9eebf10d3a101059bdcf2669c366ec1d14e4fb227bd"},
{file = "cryptography-38.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3261725c0ef84e7592597606f6583385fed2a5ec3909f43bc475ade9729a41d6"},
{file = "cryptography-38.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:0297ffc478bdd237f5ca3a7dc96fc0d315670bfa099c04dc3a4a2172008a405a"},
{file = "cryptography-38.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:89ed49784ba88c221756ff4d4755dbc03b3c8d2c5103f6d6b4f83a0fb1e85294"},
{file = "cryptography-38.0.1-cp36-abi3-win32.whl", hash = "sha256:ac7e48f7e7261207d750fa7e55eac2d45f720027d5703cd9007e9b37bbb59ac0"},
{file = "cryptography-38.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ad7353f6ddf285aeadfaf79e5a6829110106ff8189391704c1d8801aa0bae45a"},
{file = "cryptography-38.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:896dd3a66959d3a5ddcfc140a53391f69ff1e8f25d93f0e2e7830c6de90ceb9d"},
{file = "cryptography-38.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d3971e2749a723e9084dd507584e2a2761f78ad2c638aa31e80bc7a15c9db4f9"},
{file = "cryptography-38.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:79473cf8a5cbc471979bd9378c9f425384980fcf2ab6534b18ed7d0d9843987d"},
{file = "cryptography-38.0.1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:d9e69ae01f99abe6ad646947bba8941e896cb3aa805be2597a0400e0764b5818"},
{file = "cryptography-38.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5067ee7f2bce36b11d0e334abcd1ccf8c541fc0bbdaf57cdd511fdee53e879b6"},
{file = "cryptography-38.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:3e3a2599e640927089f932295a9a247fc40a5bdf69b0484532f530471a382750"},
{file = "cryptography-38.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2e5856248a416767322c8668ef1845ad46ee62629266f84a8f007a317141013"},
{file = "cryptography-38.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:64760ba5331e3f1794d0bcaabc0d0c39e8c60bf67d09c93dc0e54189dfd7cfe5"},
{file = "cryptography-38.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b6c9b706316d7b5a137c35e14f4103e2115b088c412140fdbd5f87c73284df61"},
{file = "cryptography-38.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0163a849b6f315bf52815e238bc2b2346604413fa7c1601eea84bcddb5fb9ac"},
{file = "cryptography-38.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d1a5bd52d684e49a36582193e0b89ff267704cd4025abefb9e26803adeb3e5fb"},
{file = "cryptography-38.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:765fa194a0f3372d83005ab83ab35d7c5526c4e22951e46059b8ac678b44fa5a"},
{file = "cryptography-38.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:52e7bee800ec869b4031093875279f1ff2ed12c1e2f74923e8f49c916afd1d3b"},
{file = "cryptography-38.0.1.tar.gz", hash = "sha256:1db3d807a14931fa317f96435695d9ec386be7b84b618cc61cfa5d08b0ae33d7"},
]
decorator = [
{file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
@@ -1510,7 +1513,7 @@ dj-database-url = [
{file = "dj-database-url-1.0.0.tar.gz", hash = "sha256:ccf3e8718f75ddd147a1e212fca88eecdaa721759ee48e38b485481c77bca3dc"},
{file = "dj_database_url-1.0.0-py3-none-any.whl", hash = "sha256:cd354a3b7a9136d78d64c17b2aec369e2ae5616fbca6bfbe435ef15bb372ce39"},
]
django = [
Django = [
{file = "Django-4.0.7-py3-none-any.whl", hash = "sha256:41bd65a9e5f8a89cdbfa7a7bba45cd7431ae89e750af82dea8a35fd1a7ecbe66"},
{file = "Django-4.0.7.tar.gz", hash = "sha256:9c6d5ad36be798e562ddcaa6b17b1c3ff2d3c4f529a47432b69fb9a30f847461"},
]
@@ -1603,8 +1606,8 @@ gunicorn = [
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
]
identify = [
{file = "identify-2.5.3-py2.py3-none-any.whl", hash = "sha256:25851c8c1370effb22aaa3c987b30449e9ff0cece408f810ae6ce408fdd20893"},
{file = "identify-2.5.3.tar.gz", hash = "sha256:887e7b91a1be152b0d46bbf072130235a8117392b9f1828446079a816a05ef44"},
{file = "identify-2.5.5-py2.py3-none-any.whl", hash = "sha256:ef78c0d96098a3b5fe7720be4a97e73f439af7cf088ebf47b620aeaa10fadf97"},
{file = "identify-2.5.5.tar.gz", hash = "sha256:322a5699daecf7c6fd60e68852f36f2ecbb6a36ff6e6e973e0d2bb6fca203ee6"},
]
idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
@@ -1615,8 +1618,8 @@ inflection = [
{file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"},
]
ipython = [
{file = "ipython-8.4.0-py3-none-any.whl", hash = "sha256:7ca74052a38fa25fe9bedf52da0be7d3fdd2fb027c3b778ea78dfe8c212937d1"},
{file = "ipython-8.4.0.tar.gz", hash = "sha256:f2db3a10254241d9b447232cec8b424847f338d9d36f9a577a6192c332a46abd"},
{file = "ipython-8.5.0-py3-none-any.whl", hash = "sha256:6f090e29ab8ef8643e521763a4f1f39dc3914db643122b1e9d3328ff2e43ada2"},
{file = "ipython-8.5.0.tar.gz", hash = "sha256:097bdf5cd87576fd066179c9f7f208004f7a6864ee1b20f37d346c0bcb099f84"},
]
isort = [
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
@@ -1630,7 +1633,7 @@ jedi = [
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
]
jinja2 = [
Jinja2 = [
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
]
@@ -1677,7 +1680,7 @@ loguru = [
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
]
markupsafe = [
MarkupSafe = [
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
@@ -1788,7 +1791,7 @@ pickleshare = [
pilkit = [
{file = "pilkit-2.0.tar.gz", hash = "sha256:ddb30c2f0198a147e56b151476c3bb9fe045fbfd5b0a0fa2a3148dba62d1559f"},
]
pillow = [
Pillow = [
{file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"},
{file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"},
{file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"},
@@ -1857,8 +1860,8 @@ pre-commit = [
{file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"},
{file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"},
{file = "prompt_toolkit-3.0.31-py3-none-any.whl", hash = "sha256:9696f386133df0fc8ca5af4895afe5d78f5fcfe5258111c2a79a1c3e41ffa96d"},
{file = "prompt_toolkit-3.0.31.tar.gz", hash = "sha256:9ada952c9d1787f52ff6d5f3484d0b4df8952787c087edf6a1f7c2cb1ea88148"},
]
psycopg2 = [
{file = "psycopg2-2.9.3-cp310-cp310-win32.whl", hash = "sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362"},
@@ -1893,17 +1896,17 @@ pyflakes = [
{file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"},
{file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"},
]
pygments = [
Pygments = [
{file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"},
{file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"},
]
pyjwt = [
PyJWT = [
{file = "PyJWT-2.4.0-py3-none-any.whl", hash = "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf"},
{file = "PyJWT-2.4.0.tar.gz", hash = "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"},
]
pylint = [
{file = "pylint-2.15.0-py3-none-any.whl", hash = "sha256:4b124affc198b7f7c9b5f9ab690d85db48282a025ef9333f51d2d7281b92a6c3"},
{file = "pylint-2.15.0.tar.gz", hash = "sha256:4f3f7e869646b0bd63b3dfb79f3c0f28fc3d2d923ea220d52620fd625aed92b0"},
{file = "pylint-2.15.2-py3-none-any.whl", hash = "sha256:cc3da458ba810c49d330e09013dec7ced5217772dec8f043ccdd34dae648fde8"},
{file = "pylint-2.15.2.tar.gz", hash = "sha256:f63404a2547edb5247da263748771ac9a806ed1de4174cda01293c08ddbc2999"},
]
pylint-django = [
{file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"},
@@ -1913,7 +1916,7 @@ pylint-plugin-utils = [
{file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"},
{file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"},
]
pymupdf = [
PyMuPDF = [
{file = "PyMuPDF-1.18.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ee8cc8aadaa818c9a5e2fb2a944c99a98822a7a3bc618d9c5d32f126874c0635"},
{file = "PyMuPDF-1.18.19-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:03ebf6fce6889df4708061a499b912909ead5e7bf1066f05b94458dcf164e3c3"},
{file = "PyMuPDF-1.18.19-cp310-cp310-win32.whl", hash = "sha256:f4bc63b0696c2f276703fadf3232d7ccaa01ab7548d1541fbc3762c573d3e1b5"},
@@ -1939,7 +1942,7 @@ pymupdf = [
{file = "PyMuPDF-1.18.19-cp39-cp39-win_amd64.whl", hash = "sha256:439b972026fbe8636aed0fe9d2cabb321542fa92bc48cd4c96dbdd2508fc41ee"},
{file = "PyMuPDF-1.18.19.tar.gz", hash = "sha256:ecc684e9c45bd4072f538cc42998cfda4d00f066ba009226e8a212b112d9992c"},
]
pyopenssl = [
pyOpenSSL = [
{file = "pyOpenSSL-22.0.0-py2.py3-none-any.whl", hash = "sha256:ea252b38c87425b64116f808355e8da644ef9b07e429398bfece610f893ee2e0"},
{file = "pyOpenSSL-22.0.0.tar.gz", hash = "sha256:660b1b1425aac4a1bea1d94168a85d99f0b3144c869dd4390d27629d0087f1bf"},
]
@@ -1959,7 +1962,7 @@ pytz = [
{file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
{file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
]
pyyaml = [
PyYAML = [
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
@@ -2002,11 +2005,11 @@ requests = [
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
]
ruamel-yaml = [
"ruamel.yaml" = [
{file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"},
{file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"},
]
ruamel-yaml-clib = [
"ruamel.yaml.clib" = [
{file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"},
{file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:066f886bc90cc2ce44df8b5f7acfc6a7e2b2e672713f027136464492b0c34d7c"},
{file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"},
@@ -2106,7 +2109,7 @@ wcwidth = [
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
]
werkzeug = [
Werkzeug = [
{file = "Werkzeug-2.0.3-py3-none-any.whl", hash = "sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8"},
{file = "Werkzeug-2.0.3.tar.gz", hash = "sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"},
]

View File

@@ -3,7 +3,7 @@ line_length = 119
[tool.poetry]
name = "cbwebreader"
version = "1.0.5"
version = "1.0.6"
description = "CBR/Z Web Reader"
authors = ["ajurna <ajurna@gmail.com>"]
license = "Creative Commons Attribution-ShareAlike 4.0 International License"