mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 14:17:19 +00:00
Compare commits
18 Commits
v1.1.1
...
d6250faf5f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6250faf5f | ||
|
|
db23064929 | ||
|
|
f083936aad | ||
|
|
bccbff8b33 | ||
|
|
05e3db9e42 | ||
|
|
a47153b917 | ||
|
|
df01235325 | ||
|
|
7d20447526 | ||
|
|
0dfe551b66 | ||
|
|
94171ec548 | ||
|
|
1fbe359448 | ||
|
|
84eec0c0bf | ||
|
|
ac83abaa97 | ||
|
|
ef03651ace | ||
|
|
e39ae6847d | ||
|
|
970b56b126 | ||
| 5ea87fe9b7 | |||
| a97abe4557 |
19
.gitea/workflows/build.yaml
Normal file
19
.gitea/workflows/build.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Build and push image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: self-hosted
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: /repo
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
run: git pull
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
run: |
|
||||||
|
docker build . --no-cache -t ajurna/cbwebreader
|
||||||
@@ -9,11 +9,11 @@ repos:
|
|||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- repo: https://github.com/python-poetry/poetry
|
- repo: https://github.com/python-poetry/poetry
|
||||||
rev: '1.2.0rc1' # add version here
|
rev: '1.2.1' # add version here
|
||||||
hooks:
|
hooks:
|
||||||
- id: poetry-check
|
- id: poetry-check
|
||||||
- id: poetry-export
|
- id: poetry-export
|
||||||
args: ["--without-hashes", "-f", "requirements.txt", "-o", "requirements.txt"]
|
args: ["--without-hashes", "-o", "requirements.txt"]
|
||||||
- repo: https://github.com/pycqa/flake8
|
- repo: https://github.com/pycqa/flake8
|
||||||
rev: "5.0.4"
|
rev: "5.0.4"
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
max-line-length=120
|
max-line-length=120
|
||||||
ignore-paths=.*/migrations
|
ignore-paths=.*/migrations
|
||||||
load-plugins = pylint_django
|
load-plugins = pylint_django
|
||||||
disable = missing-class-docstring,missing-function-docstring,abstract-method,missing-module-docstring,imported-auth-user
|
disable = missing-class-docstring,missing-function-docstring,abstract-method,missing-module-docstring,imported-auth-user,missing-docstring
|
||||||
good-names=pk
|
good-names=pk
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Django settings for cbreader project.
|
|||||||
import os
|
import os
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
import dj_database_url
|
import dj_database_url
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@@ -27,7 +28,7 @@ ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")
|
|||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = [
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
@@ -46,7 +47,7 @@ INSTALLED_APPS = (
|
|||||||
'django_filters',
|
'django_filters',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
# 'silk'
|
# 'silk'
|
||||||
)
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
@@ -58,8 +59,7 @@ MIDDLEWARE = [
|
|||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
# 'silk.middleware.SilkyMiddleware',
|
'csp.middleware.CSPMiddleware',
|
||||||
# 'csp.middleware.CSPMiddleware',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = "cbreader.urls"
|
ROOT_URLCONF = "cbreader.urls"
|
||||||
@@ -197,10 +197,10 @@ CSP_FONT_SRC = ("'self'",)
|
|||||||
CSP_SCRIPT_SRC = ("'self'",)
|
CSP_SCRIPT_SRC = ("'self'",)
|
||||||
CSP_CONNECT_SRC = ("'self'",)
|
CSP_CONNECT_SRC = ("'self'",)
|
||||||
CSP_INCLUDE_NONCE_IN = ['script-src']
|
CSP_INCLUDE_NONCE_IN = ['script-src']
|
||||||
CSP_SCRIPT_SRC_ATTR = ("'self'",)# "'unsafe-inline'")
|
CSP_SCRIPT_SRC_ATTR = ("'self'",) # "'unsafe-inline'")
|
||||||
|
|
||||||
|
|
||||||
PERMISSIONS_POLICY = {
|
PERMISSIONS_POLICY: Dict[str, List] = {
|
||||||
"accelerometer": [],
|
"accelerometer": [],
|
||||||
"ambient-light-sensor": [],
|
"ambient-light-sensor": [],
|
||||||
"autoplay": [],
|
"autoplay": [],
|
||||||
|
|||||||
@@ -1,30 +1,11 @@
|
|||||||
from .base import *
|
from .base import INSTALLED_APPS, MIDDLEWARE, SILK_ENABLED
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS += ["silk"]
|
||||||
"django.contrib.admin",
|
|
||||||
"django.contrib.auth",
|
|
||||||
"django.contrib.contenttypes",
|
|
||||||
"django.contrib.sessions",
|
|
||||||
"django.contrib.messages",
|
|
||||||
"django.contrib.staticfiles",
|
|
||||||
'silk',
|
|
||||||
"snowpenguin.django.recaptcha2",
|
|
||||||
'bootstrap4',
|
|
||||||
"comic",
|
|
||||||
"comic_auth",
|
|
||||||
)
|
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE += [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
||||||
"django.middleware.common.CommonMiddleware",
|
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
||||||
'silk.middleware.SilkyMiddleware',
|
'silk.middleware.SilkyMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
SILK_ENABLED = True
|
SILK_ENABLED = True # noqa: F811
|
||||||
|
|
||||||
SILKY_PYTHON_PROFILER = True
|
SILKY_PYTHON_PROFILER = True
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.syndication.views import Feed
|
from django.contrib.syndication.views import Feed
|
||||||
from django.db.models import Case, When, PositiveSmallIntegerField, F
|
from django.db.models import Case, When, PositiveSmallIntegerField, F, QuerySet
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ class RecentComicsAPI(Feed):
|
|||||||
self.user = user_misc.user
|
self.user = user_misc.user
|
||||||
return user_misc.user
|
return user_misc.user
|
||||||
|
|
||||||
def items(self) -> ComicBook:
|
def items(self) -> QuerySet[ComicBook]:
|
||||||
comics = ComicBook.objects.order_by("-date_added")
|
comics = ComicBook.objects.order_by("-date_added")
|
||||||
comics = comics.annotate(
|
comics = comics.annotate(
|
||||||
classification=Case(
|
classification=Case(
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from typing import Optional, Union
|
from typing import Optional
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
from django.core.management.base import BaseCommand, CommandParser
|
from django.core.management.base import BaseCommand, CommandParser
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from comic.models import ComicBook, Directory
|
from comic.models import Directory
|
||||||
from comic.processing import generate_directory
|
from comic.processing import generate_directory
|
||||||
|
|
||||||
|
|
||||||
@@ -27,12 +27,11 @@ class Command(BaseCommand):
|
|||||||
self.OUTPUT = options.get('out', False)
|
self.OUTPUT = options.get('out', False)
|
||||||
self.scan_directory()
|
self.scan_directory()
|
||||||
|
|
||||||
def scan_directory(self, user: Optional[User] = None, directory: Optional[Directory] = None) -> None:
|
def scan_directory(self, user: Optional[AbstractBaseUser] = None, directory: Optional[Directory] = None) -> None:
|
||||||
if not user:
|
if not user:
|
||||||
user_model = get_user_model()
|
user_model = get_user_model()
|
||||||
user = user_model.objects.first()
|
user: AbstractBaseUser = user_model.objects.first()
|
||||||
for item in generate_directory(user, directory):
|
for item in generate_directory(user, directory):
|
||||||
item: Union[Directory, ComicBook]
|
if item is Directory:
|
||||||
if item.type == 'Directory':
|
|
||||||
logger.info(item)
|
logger.info(item)
|
||||||
self.scan_directory(user, item)
|
self.scan_directory(user, item)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from typing import NamedTuple, List, Optional, Union
|
|||||||
|
|
||||||
import rarfile
|
import rarfile
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
from django.db.models import Count, Q, F, Case, When, PositiveSmallIntegerField, QuerySet, ExpressionWrapper, \
|
from django.db.models import Count, Q, F, Case, When, PositiveSmallIntegerField, QuerySet, ExpressionWrapper, \
|
||||||
IntegerField
|
IntegerField
|
||||||
|
|
||||||
@@ -14,7 +14,8 @@ from comic import models
|
|||||||
from comic.errors import NotCompatibleArchive
|
from comic.errors import NotCompatibleArchive
|
||||||
|
|
||||||
|
|
||||||
def generate_directory(user: User, directory: Optional[models.Directory] = None) -> List[QuerySet]:
|
def generate_directory(user: AbstractBaseUser, directory: Optional[models.Directory] = None) \
|
||||||
|
-> List[Union[models.Directory, models.ComicBook]]:
|
||||||
dir_path = Path(settings.COMIC_BOOK_VOLUME, directory.path) if directory else settings.COMIC_BOOK_VOLUME
|
dir_path = Path(settings.COMIC_BOOK_VOLUME, directory.path) if directory else settings.COMIC_BOOK_VOLUME
|
||||||
files = []
|
files = []
|
||||||
|
|
||||||
@@ -74,7 +75,8 @@ def clean_directories(directories: QuerySet, dir_path: Path, directory: Optional
|
|||||||
models.Directory.objects.get(name=stale_directory.name, parent=directory).delete()
|
models.Directory.objects.get(name=stale_directory.name, parent=directory).delete()
|
||||||
|
|
||||||
|
|
||||||
def clean_files(files: QuerySet, user: User, dir_path: Path, directory: Optional[models.Directory] = None) -> None:
|
def clean_files(files: QuerySet, user: AbstractBaseUser, dir_path: Path, directory: Optional[models.Directory] = None) \
|
||||||
|
-> None:
|
||||||
file_list = set(x for x in sorted(dir_path.glob('*')) if x.is_file())
|
file_list = set(x for x in sorted(dir_path.glob('*')) if x.is_file())
|
||||||
files_db_set = set(Path(dir_path, x.file_name) for x in files)
|
files_db_set = set(Path(dir_path, x.file_name) for x in files)
|
||||||
|
|
||||||
|
|||||||
10686
frontend/package-lock.json
generated
10686
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@
|
|||||||
"vue-toast-notification": "3.0",
|
"vue-toast-notification": "3.0",
|
||||||
"vuejs-paginate-next": "^1.0.2",
|
"vuejs-paginate-next": "^1.0.2",
|
||||||
"vuex": "^4.0.0",
|
"vuex": "^4.0.0",
|
||||||
"webpack": "^5.74.0"
|
"webpack": "^5.76.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.12.16",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ async function get_access_token() {
|
|||||||
let refresh = jwtDecode(store.state.jwt.refresh)
|
let refresh = jwtDecode(store.state.jwt.refresh)
|
||||||
if (access.exp - Date.now()/1000 < 5) {
|
if (access.exp - Date.now()/1000 < 5) {
|
||||||
if (refresh.exp - Date.now()/1000 < 5) {
|
if (refresh.exp - Date.now()/1000 < 5) {
|
||||||
await router.push({name: 'login', params: { username: 'eduardo' }})
|
await router.push({name: 'login'})
|
||||||
return null
|
return null
|
||||||
} else {
|
} else {
|
||||||
return store.dispatch('refreshToken').then(() => {return store.state.jwt.access})
|
return store.dispatch('refreshToken').then(() => {return store.state.jwt.access})
|
||||||
@@ -22,9 +22,9 @@ const axios_jwt = axios.create();
|
|||||||
axios_jwt.interceptors.request.use(async function (config) {
|
axios_jwt.interceptors.request.use(async function (config) {
|
||||||
let access_token = await get_access_token().catch(() => {
|
let access_token = await get_access_token().catch(() => {
|
||||||
if (router.currentRoute.value.fullPath.includes('login')){
|
if (router.currentRoute.value.fullPath.includes('login')){
|
||||||
router.push({name: 'login'})
|
router.push({name: 'login'})
|
||||||
}else {
|
}else {
|
||||||
router.push({name: 'login', query: { next: router.currentRoute.value.fullPath }})
|
router.push({name: 'login', query: { next: router.currentRoute.value.fullPath }})
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -32,9 +32,9 @@ axios_jwt.interceptors.request.use(async function (config) {
|
|||||||
Authorization: "Bearer " + access_token
|
Authorization: "Bearer " + access_token
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
// Do something with request error
|
// Do something with request error
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default axios_jwt
|
export default axios_jwt
|
||||||
|
|||||||
@@ -73,14 +73,22 @@ export default createStore({
|
|||||||
if ('next' in router.currentRoute.value.query) {
|
if ('next' in router.currentRoute.value.query) {
|
||||||
router.push(router.currentRoute.value.query.next)
|
router.push(router.currentRoute.value.query.next)
|
||||||
} else {
|
} else {
|
||||||
router.push('/')
|
router.push('browse')
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error)=>{
|
.catch((error)=>{
|
||||||
// console.log(error);
|
|
||||||
const $toast = useToast();
|
const $toast = useToast();
|
||||||
$toast.error(error.response.data.detail, {position:'top'});
|
if (error.response.data.detail) {
|
||||||
|
$toast.error(error.response.data.detail, {position:'top'});
|
||||||
|
}
|
||||||
|
if (error.response.data.username) {
|
||||||
|
$toast.error("Username: " + error.response.data.username, {position:'top'});
|
||||||
|
}
|
||||||
|
if (error.response.data.password) {
|
||||||
|
$toast.error("Password: " + error.response.data.password, {position:'top'});
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshToken(){
|
refreshToken(){
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="row" v-if="!initialSetupRequired">
|
<div class="row" v-if="!initialSetupRequired">
|
||||||
<div class="col col-lg-4" />
|
<div class="col col-lg-4" />
|
||||||
<div class="col col-lg-4" id="login-col">
|
<div class="col col-lg-4" id="login-col">
|
||||||
<form @submit="login">
|
<form @submit="login" v-on:submit.prevent="onSubmit">
|
||||||
<label class="form-label" for="username">Username</label>
|
<label class="form-label" for="username">Username</label>
|
||||||
<input id="username" placeholder="username" aria-describedby="loginFormControlInputHelpInline" class="form-control" type="text" v-model="username" />
|
<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>
|
<div class="form-text" id="loginFormControlInputHelpInline">Please enter your username</div>
|
||||||
|
|||||||
3436
poetry.lock
generated
3436
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -3,52 +3,53 @@ line_length = 119
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "cbwebreader"
|
name = "cbwebreader"
|
||||||
version = "1.1.1"
|
version = "1.1.5"
|
||||||
description = "CBR/Z Web Reader"
|
description = "CBR/Z Web Reader"
|
||||||
authors = ["ajurna <ajurna@gmail.com>"]
|
authors = ["ajurna <ajurna@gmail.com>"]
|
||||||
license = "Creative Commons Attribution-ShareAlike 4.0 International License"
|
license = "Creative Commons Attribution-ShareAlike 4.0 International License"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = "^3.10"
|
||||||
Django = "4.1.1"
|
Django = "^4.1"
|
||||||
gunicorn = "^20.0.4"
|
gunicorn = "^20.0.4"
|
||||||
dj-database-url = "^1.0.0"
|
dj-database-url = "^1.3.0"
|
||||||
python-dotenv = "^0.21.0"
|
python-dotenv = "^1.0.0"
|
||||||
loguru = "^0.6.0"
|
loguru = "^0.7.0"
|
||||||
django-silk = "^5.0.0"
|
django-silk = "^5.0.0"
|
||||||
mysqlclient = "^2.0.1"
|
mysqlclient = "^2.0.1"
|
||||||
psycopg2 = "^2.8.6"
|
psycopg2 = "^2.9.6"
|
||||||
rarfile = "^4.0"
|
rarfile = "^4.0"
|
||||||
django-extensions = "^3.2.1"
|
django-extensions = "^3.2.1"
|
||||||
Pillow = "^9.1.1"
|
Pillow = "^9.3.0"
|
||||||
django-imagekit = "^4.0.2"
|
django-imagekit = "^4.0.2"
|
||||||
PyMuPDF = "~1.20.2"
|
PyMuPDF = "~1.20.2"
|
||||||
django-bootstrap4 = "^22.1"
|
django-bootstrap4 = "^23.1"
|
||||||
django-csp = "^3.7"
|
django-csp = "^3.7"
|
||||||
django-boost = "^2.1"
|
django-boost = "^2.1"
|
||||||
django-sri = "^0.5.0"
|
django-sri = "^0.5.0"
|
||||||
django-permissions-policy = "^4.9.0"
|
django-permissions-policy = "^4.15.0"
|
||||||
djangorestframework = "^3.13.1"
|
djangorestframework = "^3.13.1"
|
||||||
django-filter = "^22.1"
|
django-filter = "^23.1"
|
||||||
django-cors-headers = "^3.13.0"
|
django-cors-headers = "^3.14.0"
|
||||||
djangorestframework-simplejwt = "^5.2.0"
|
djangorestframework-simplejwt = "^5.2.0"
|
||||||
django-webpack-loader = "^1.6.0"
|
django-webpack-loader = "^1.6.0"
|
||||||
drf-yasg = "^1.20.0"
|
drf-yasg = "^1.20.0"
|
||||||
drf-extensions = "^0.7.1"
|
drf-extensions = "^0.7.1"
|
||||||
flake8 = "^5.0.4"
|
|
||||||
flake8-annotations = "^2.9.1"
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
mypy = "^0.971"
|
mypy = "^1.2.0"
|
||||||
Werkzeug = "^2.2"
|
Werkzeug = "^2.2"
|
||||||
pyOpenSSL = "^22.0.0"
|
pyOpenSSL = "^22.0.0"
|
||||||
ipython = "^8.4.0"
|
ipython = "^8.12.0"
|
||||||
coverage = "^6.2"
|
coverage = "^7.2.3"
|
||||||
pre-commit = "^2.20.0"
|
pre-commit = "^3.2.2"
|
||||||
|
flake8 = "^6.0.0"
|
||||||
|
flake8-annotations = "^3.0.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
pylint = "^2.15.0"
|
pylint = "^2.15.0"
|
||||||
pylint-django = "^2.5.3"
|
pylint-django = "^2.5.3"
|
||||||
|
mypy = "^1.2.0"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
|||||||
@@ -1,66 +1,60 @@
|
|||||||
asgiref==3.5.2 ; python_version >= "3.10" and python_version < "4.0"
|
asgiref==3.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
attrs==22.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
autopep8==2.0.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
autopep8==1.7.0 ; python_version >= "3.10" and python_version < "4.0"
|
beautifulsoup4==4.12.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
beautifulsoup4==4.11.1 ; python_version >= "3.10" and python_version < "4.0"
|
certifi==2022.12.7 ; python_version >= "3.10" and python_version < "4"
|
||||||
certifi==2022.9.14 ; python_version >= "3.10" and python_version < "4"
|
charset-normalizer==3.1.0 ; python_version >= "3.10" and python_version < "4"
|
||||||
charset-normalizer==2.1.1 ; python_version >= "3.10" and python_version < "4"
|
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
||||||
colorama==0.4.5 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
|
||||||
coreapi==2.3.3 ; python_version >= "3.10" and python_version < "4.0"
|
coreapi==2.3.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
coreschema==0.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
coreschema==0.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
dj-database-url==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
dj-database-url==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-appconf==1.0.5 ; python_version >= "3.10" and python_version < "4.0"
|
django-appconf==1.0.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-boost==2.1 ; python_version >= "3.10" and python_version < "4.0"
|
django-boost==2.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-bootstrap4==22.2 ; python_version >= "3.10" and python_version < "4.0"
|
django-bootstrap4==23.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-cors-headers==3.13.0 ; python_version >= "3.10" and python_version < "4.0"
|
django-cors-headers==3.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-csp==3.7 ; python_version >= "3.10" and python_version < "4.0"
|
django-csp==3.7 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-extensions==3.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
django-extensions==3.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-filter==22.1 ; python_version >= "3.10" and python_version < "4.0"
|
django-filter==23.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-imagekit==4.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
django-imagekit==4.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-permissions-policy==4.13.0 ; python_version >= "3.10" and python_version < "4.0"
|
django-permissions-policy==4.15.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-silk==5.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
django-silk==5.0.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-sri==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
django-sri==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django-webpack-loader==1.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
django-webpack-loader==1.8.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
django==4.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
django==4.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
djangorestframework-simplejwt==5.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
djangorestframework-simplejwt==5.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
djangorestframework==3.13.1 ; python_version >= "3.10" and python_version < "4.0"
|
djangorestframework==3.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
drf-extensions==0.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
drf-extensions==0.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
drf-yasg==1.21.3 ; python_version >= "3.10" and python_version < "4.0"
|
drf-yasg==1.21.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
flake8-annotations==2.9.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
flake8==5.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
gprof2dot==2022.7.29 ; python_version >= "3.10" and python_version < "4.0"
|
gprof2dot==2022.7.29 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
gunicorn==20.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
gunicorn==20.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
idna==3.4 ; python_version >= "3.10" and python_version < "4"
|
idna==3.4 ; python_version >= "3.10" and python_version < "4"
|
||||||
inflection==0.5.1 ; python_version >= "3.10" and python_version < "4.0"
|
inflection==0.5.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
itypes==1.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
itypes==1.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0"
|
jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
loguru==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
loguru==0.7.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
markupsafe==2.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
markupsafe==2.1.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
mccabe==0.7.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
mysqlclient==2.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
mysqlclient==2.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
packaging==21.3 ; python_version >= "3.10" and python_version < "4.0"
|
packaging==23.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pilkit==2.0 ; python_version >= "3.10" and python_version < "4.0"
|
pilkit==2.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pillow==9.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
pillow==9.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
psycopg2==2.9.3 ; python_version >= "3.10" and python_version < "4.0"
|
psycopg2==2.9.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pycodestyle==2.9.1 ; python_version >= "3.10" and python_version < "4.0"
|
pycodestyle==2.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pyflakes==2.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
pyjwt==2.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pyjwt==2.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
pymupdf==1.20.2 ; python_version >= "3.10" and python_version < "4.0"
|
pymupdf==1.20.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pyparsing==3.0.9 ; python_version >= "3.10" and python_version < "4.0"
|
python-dotenv==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "4.0"
|
pytz==2023.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-dotenv==0.21.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
pytz==2022.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
||||||
rarfile==4.0 ; python_version >= "3.10" and python_version < "4.0"
|
rarfile==4.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
requests==2.28.1 ; python_version >= "3.10" and python_version < "4"
|
requests==2.28.2 ; python_version >= "3.10" and python_version < "4"
|
||||||
ruamel-yaml-clib==0.2.6 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.10"
|
ruamel-yaml-clib==0.2.7 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.10"
|
||||||
ruamel-yaml==0.17.21 ; python_version >= "3.10" and python_version < "4.0"
|
ruamel-yaml==0.17.21 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
setuptools==65.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
setuptools==67.6.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
|
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
soupsieve==2.3.2.post1 ; python_version >= "3.10" and python_version < "4.0"
|
soupsieve==2.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
sqlparse==0.4.2 ; python_version >= "3.10" and python_version < "4.0"
|
sqlparse==0.4.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
toml==0.10.2 ; python_version >= "3.10" and python_version < "4.0"
|
tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11"
|
||||||
tzdata==2022.2 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
typing-extensions==4.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
|
tzdata==2023.3 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
||||||
ua-parser==0.16.1 ; python_version >= "3.10" and python_version < "4.0"
|
ua-parser==0.16.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
uritemplate==4.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
uritemplate==4.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
urllib3==1.26.12 ; python_version >= "3.10" and python_version < "4"
|
urllib3==1.26.15 ; python_version >= "3.10" and python_version < "4"
|
||||||
user-agents==2.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
user-agents==2.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
win32-setctime==1.1.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
win32-setctime==1.1.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
||||||
|
|||||||
Reference in New Issue
Block a user