mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 06:17:17 +00:00
Merge pull request #5 from apoclyps/black-formatting
[ISSUE-4] Applying black formatting
This commit is contained in:
@@ -22,10 +22,10 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
SECRET_KEY = '=3tf-@u1t7x4%$yr++59+8tspl4ao&r3&!bb6l(t&$#6@bfkwg'
|
SECRET_KEY = "=3tf-@u1t7x4%$yr++59+8tspl4ao&r3&!bb6l(t&$#6@bfkwg"
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = os.environ.get('DJANGO_DEBUG', True)
|
DEBUG = os.environ.get("DJANGO_DEBUG", True)
|
||||||
|
|
||||||
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")
|
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")
|
||||||
|
|
||||||
@@ -33,46 +33,46 @@ 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",
|
||||||
'django.contrib.sessions',
|
"django.contrib.sessions",
|
||||||
'django.contrib.messages',
|
"django.contrib.messages",
|
||||||
'django.contrib.staticfiles',
|
"django.contrib.staticfiles",
|
||||||
'snowpenguin.django.recaptcha2',
|
"snowpenguin.django.recaptcha2",
|
||||||
'comic',
|
"comic",
|
||||||
'comic_auth',
|
"comic_auth",
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
"django.middleware.security.SecurityMiddleware",
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
'django.middleware.common.CommonMiddleware',
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
'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",
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'cbreader.urls'
|
ROOT_URLCONF = "cbreader.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': ['templates'],
|
"DIRS": ["templates"],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'cbreader.wsgi.application'
|
WSGI_APPLICATION = "cbreader.wsgi.application"
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
@@ -83,20 +83,15 @@ DATABASE_URL = os.getenv("DATABASE_URL")
|
|||||||
if DATABASE_URL:
|
if DATABASE_URL:
|
||||||
DATABASES = {"default": dj_database_url.config(conn_max_age=500)}
|
DATABASES = {"default": dj_database_url.config(conn_max_age=500)}
|
||||||
else:
|
else:
|
||||||
DATABASES = {
|
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": os.path.join(BASE_DIR, "db.sqlite3")}}
|
||||||
'default': {
|
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
|
||||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-ie'
|
LANGUAGE_CODE = "en-ie"
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = "UTC"
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@@ -108,16 +103,16 @@ USE_TZ = True
|
|||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = "/static/"
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = '/comic/'
|
LOGIN_REDIRECT_URL = "/comic/"
|
||||||
|
|
||||||
LOGIN_URL = '/login/'
|
LOGIN_URL = "/login/"
|
||||||
|
|
||||||
UNRAR_TOOL = os.getenv("UNRAR_TOOL", None)
|
UNRAR_TOOL = os.getenv("UNRAR_TOOL", None)
|
||||||
|
|
||||||
CBREADER_USE_RECAPTCHA = False
|
CBREADER_USE_RECAPTCHA = False
|
||||||
RECAPTCHA_PRIVATE_KEY = ''
|
RECAPTCHA_PRIVATE_KEY = ""
|
||||||
RECAPTCHA_PUBLIC_KEY = ''
|
RECAPTCHA_PUBLIC_KEY = ""
|
||||||
|
|
||||||
COMIC_DIR = "/media/comics"
|
COMIC_DIR = "/media/comics"
|
||||||
|
|||||||
@@ -1,123 +0,0 @@
|
|||||||
"""
|
|
||||||
Django settings for cbreader project.
|
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 1.8.2.
|
|
||||||
|
|
||||||
For more information on this file, see
|
|
||||||
https://docs.djangoproject.com/en/1.8/topics/settings/
|
|
||||||
|
|
||||||
For the full list of settings and their values, see
|
|
||||||
https://docs.djangoproject.com/en/1.8/ref/settings/
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
|
||||||
import os
|
|
||||||
|
|
||||||
import dj_database_url
|
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
|
||||||
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
|
||||||
SECRET_KEY = '=3tf-@u1t7x4%$yr++59+8tspl4ao&r3&!bb6l(t&$#6@bfkwg'
|
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
|
||||||
DEBUG = os.environ.get('DJANGO_DEBUG', True)
|
|
||||||
|
|
||||||
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")
|
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
|
||||||
'django.contrib.admin',
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sessions',
|
|
||||||
'django.contrib.messages',
|
|
||||||
'django.contrib.staticfiles',
|
|
||||||
'snowpenguin.django.recaptcha2',
|
|
||||||
'comic',
|
|
||||||
'comic_auth',
|
|
||||||
)
|
|
||||||
|
|
||||||
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',
|
|
||||||
]
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'cbreader.urls'
|
|
||||||
|
|
||||||
TEMPLATES = [
|
|
||||||
{
|
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
||||||
'DIRS': ['templates'],
|
|
||||||
'APP_DIRS': True,
|
|
||||||
'OPTIONS': {
|
|
||||||
'context_processors': [
|
|
||||||
'django.template.context_processors.debug',
|
|
||||||
'django.template.context_processors.request',
|
|
||||||
'django.contrib.auth.context_processors.auth',
|
|
||||||
'django.contrib.messages.context_processors.messages',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
WSGI_APPLICATION = 'cbreader.wsgi.application'
|
|
||||||
|
|
||||||
|
|
||||||
# Database
|
|
||||||
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
|
|
||||||
|
|
||||||
DATABASE_URL = os.getenv("TEST_DATABASE_URL")
|
|
||||||
|
|
||||||
if DATABASE_URL:
|
|
||||||
DATABASES = {"default": dj_database_url.config(conn_max_age=500)}
|
|
||||||
else:
|
|
||||||
DATABASES = {
|
|
||||||
'default': {
|
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
|
||||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
|
||||||
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-ie'
|
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
|
||||||
|
|
||||||
USE_I18N = True
|
|
||||||
|
|
||||||
USE_L10N = True
|
|
||||||
|
|
||||||
USE_TZ = True
|
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
|
||||||
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = '/comic/'
|
|
||||||
|
|
||||||
LOGIN_URL = '/login/'
|
|
||||||
|
|
||||||
UNRAR_TOOL = os.getenv("UNRAR_TOOL", None)
|
|
||||||
|
|
||||||
CBREADER_USE_RECAPTCHA = False
|
|
||||||
RECAPTCHA_PRIVATE_KEY = ''
|
|
||||||
RECAPTCHA_PUBLIC_KEY = ''
|
|
||||||
|
|
||||||
COMIC_DIR = "/media/comics"
|
|
||||||
118
cbreader/tests/test_settings.py
Normal file
118
cbreader/tests/test_settings.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
"""
|
||||||
|
Django settings for cbreader project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 1.8.2.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/1.8/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
import os
|
||||||
|
|
||||||
|
import dj_database_url
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = "=3tf-@u1t7x4%$yr++59+8tspl4ao&r3&!bb6l(t&$#6@bfkwg"
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = os.environ.get("DJANGO_DEBUG", True)
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
"django.contrib.admin",
|
||||||
|
"django.contrib.auth",
|
||||||
|
"django.contrib.contenttypes",
|
||||||
|
"django.contrib.sessions",
|
||||||
|
"django.contrib.messages",
|
||||||
|
"django.contrib.staticfiles",
|
||||||
|
"snowpenguin.django.recaptcha2",
|
||||||
|
"comic",
|
||||||
|
"comic_auth",
|
||||||
|
)
|
||||||
|
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = "cbreader.urls"
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
|
"DIRS": ["templates"],
|
||||||
|
"APP_DIRS": True,
|
||||||
|
"OPTIONS": {
|
||||||
|
"context_processors": [
|
||||||
|
"django.template.context_processors.debug",
|
||||||
|
"django.template.context_processors.request",
|
||||||
|
"django.contrib.auth.context_processors.auth",
|
||||||
|
"django.contrib.messages.context_processors.messages",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = "cbreader.wsgi.application"
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASE_URL = os.getenv("TEST_DATABASE_URL")
|
||||||
|
|
||||||
|
if DATABASE_URL:
|
||||||
|
DATABASES = {"default": dj_database_url.config(conn_max_age=500)}
|
||||||
|
else:
|
||||||
|
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": os.path.join(BASE_DIR, "db.sqlite3")}}
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = "en-ie"
|
||||||
|
|
||||||
|
TIME_ZONE = "UTC"
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = "/static/"
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = "/comic/"
|
||||||
|
|
||||||
|
LOGIN_URL = "/login/"
|
||||||
|
|
||||||
|
UNRAR_TOOL = os.getenv("UNRAR_TOOL", None)
|
||||||
|
|
||||||
|
CBREADER_USE_RECAPTCHA = False
|
||||||
|
RECAPTCHA_PRIVATE_KEY = ""
|
||||||
|
RECAPTCHA_PUBLIC_KEY = ""
|
||||||
|
|
||||||
|
COMIC_DIR = "/media/comics"
|
||||||
@@ -20,11 +20,11 @@ import comic.views
|
|||||||
import comic_auth.views
|
import comic_auth.views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', comic.views.comic_redirect),
|
url(r"^$", comic.views.comic_redirect),
|
||||||
url(r'^login/', comic_auth.views.comic_login),
|
url(r"^login/", comic_auth.views.comic_login),
|
||||||
url(r'^logout/', comic_auth.views.comic_logout),
|
url(r"^logout/", comic_auth.views.comic_logout),
|
||||||
url(r'^setup/', comic.views.initial_setup),
|
url(r"^setup/", comic.views.initial_setup),
|
||||||
url(r'^comic/', include('comic.urls')),
|
url(r"^comic/", include("comic.urls")),
|
||||||
url(r'^admin/', admin.site.urls),
|
url(r"^admin/", admin.site.urls),
|
||||||
# url(r'^silk/', include('silk.urls', namespace='silk'))
|
# url(r'^silk/', include('silk.urls', namespace='silk'))
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ from comic.models import Setting, ComicBook, ComicPage, ComicStatus, Directory
|
|||||||
|
|
||||||
@admin.register(Setting)
|
@admin.register(Setting)
|
||||||
class SettingAdmin(admin.ModelAdmin):
|
class SettingAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'value')
|
list_display = ("name", "value")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(ComicBook)
|
@admin.register(ComicBook)
|
||||||
class ComicBookAdmin(admin.ModelAdmin):
|
class ComicBookAdmin(admin.ModelAdmin):
|
||||||
list_display = ['file_name', 'date_added']
|
list_display = ["file_name", "date_added"]
|
||||||
search_fields = ['file_name']
|
search_fields = ["file_name"]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(ComicPage)
|
@admin.register(ComicPage)
|
||||||
class ComicPageAdmin(admin.ModelAdmin):
|
class ComicPageAdmin(admin.ModelAdmin):
|
||||||
list_display = ('Comic', 'index', 'page_file_name', 'content_type')
|
list_display = ("Comic", "index", "page_file_name", "content_type")
|
||||||
list_filter = ['Comic']
|
list_filter = ["Comic"]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(ComicStatus)
|
@admin.register(ComicStatus)
|
||||||
class ComicStatusAdmin(admin.ModelAdmin):
|
class ComicStatusAdmin(admin.ModelAdmin):
|
||||||
list_display = ['user', 'comic', 'last_read_page', 'unread']
|
list_display = ["user", "comic", "last_read_page", "unread"]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Directory)
|
@admin.register(Directory)
|
||||||
|
|||||||
@@ -19,14 +19,14 @@ class RecentComics(Feed):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items() -> ComicBook:
|
def items() -> ComicBook:
|
||||||
return ComicBook.objects.order_by('-date_added')[:10]
|
return ComicBook.objects.order_by("-date_added")[:10]
|
||||||
|
|
||||||
def item_title(self, item: ComicBook) -> str:
|
def item_title(self, item: ComicBook) -> str:
|
||||||
return item.file_name
|
return item.file_name
|
||||||
|
|
||||||
def item_description(self, item: ComicBook) -> str:
|
def item_description(self, item: ComicBook) -> str:
|
||||||
return item.date_added.strftime('%a, %e %b %Y %H:%M')
|
return item.date_added.strftime("%a, %e %b %Y %H:%M")
|
||||||
|
|
||||||
# item_link is only needed if NewsItem has no get_absolute_url method.
|
# item_link is only needed if NewsItem has no get_absolute_url method.
|
||||||
def item_link(self, item: ComicBook) -> str:
|
def item_link(self, item: ComicBook) -> str:
|
||||||
return '/comic/read/{0}/0/'.format(urlsafe_base64_encode(item.selector.bytes))
|
return "/comic/read/{0}/0/".format(urlsafe_base64_encode(item.selector.bytes))
|
||||||
|
|||||||
213
comic/forms.py
213
comic/forms.py
@@ -7,214 +7,137 @@ from comic.models import Setting
|
|||||||
|
|
||||||
|
|
||||||
class InitialSetupForm(forms.Form):
|
class InitialSetupForm(forms.Form):
|
||||||
username = forms.CharField(help_text='Username',
|
username = forms.CharField(help_text="Username", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
widget=forms.TextInput(
|
email = forms.CharField(help_text="Email Address", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
attrs={
|
password = forms.CharField(help_text="New Password", widget=forms.PasswordInput(attrs={"class": "form-control"}))
|
||||||
'class': 'form-control',
|
password_confirm = forms.CharField(
|
||||||
}
|
help_text="New Password Confirmation", widget=forms.PasswordInput(attrs={"class": "form-control"})
|
||||||
))
|
)
|
||||||
email = forms.CharField(help_text='Email Address',
|
base_dir = forms.CharField(help_text="Base Directory", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
widget=forms.TextInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control'
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password = forms.CharField(help_text='New Password',
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password_confirm = forms.CharField(help_text='New Password Confirmation',
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
base_dir = forms.CharField(help_text='Base Directory',
|
|
||||||
widget=forms.TextInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control'
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
def clean_base_dir(self):
|
def clean_base_dir(self):
|
||||||
data = self.cleaned_data['base_dir']
|
data = self.cleaned_data["base_dir"]
|
||||||
if not path.isdir(data):
|
if not path.isdir(data):
|
||||||
raise forms.ValidationError('This is not a valid Directory')
|
raise forms.ValidationError("This is not a valid Directory")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
form_data = self.cleaned_data
|
form_data = self.cleaned_data
|
||||||
if form_data['password'] != form_data['password_confirm']:
|
if form_data["password"] != form_data["password_confirm"]:
|
||||||
raise forms.ValidationError('Passwords do not match.')
|
raise forms.ValidationError("Passwords do not match.")
|
||||||
if len(form_data['password']) < 8:
|
if len(form_data["password"]) < 8:
|
||||||
raise forms.ValidationError('Password is too short')
|
raise forms.ValidationError("Password is too short")
|
||||||
return form_data
|
return form_data
|
||||||
|
|
||||||
|
|
||||||
class AccountForm(forms.Form):
|
class AccountForm(forms.Form):
|
||||||
username = forms.CharField(help_text='Username',
|
username = forms.CharField(
|
||||||
required=False,
|
help_text="Username",
|
||||||
widget=forms.TextInput(
|
required=False,
|
||||||
attrs={
|
widget=forms.TextInput(attrs={"class": "form-control disabled", "readonly": True}),
|
||||||
'class': 'form-control disabled',
|
)
|
||||||
'readonly': True,
|
email = forms.CharField(help_text="Email Address", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
}
|
password = forms.CharField(
|
||||||
))
|
help_text="New Password", required=False, widget=forms.PasswordInput(attrs={"class": "form-control"})
|
||||||
email = forms.CharField(help_text='Email Address',
|
)
|
||||||
widget=forms.TextInput(
|
password_confirm = forms.CharField(
|
||||||
attrs={
|
help_text="New Password Confirmation",
|
||||||
'class': 'form-control'
|
required=False,
|
||||||
}
|
widget=forms.PasswordInput(attrs={"class": "form-control"}),
|
||||||
))
|
)
|
||||||
password = forms.CharField(help_text='New Password',
|
|
||||||
required=False,
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password_confirm = forms.CharField(help_text='New Password Confirmation',
|
|
||||||
required=False,
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
data = self.cleaned_data['email']
|
data = self.cleaned_data["email"]
|
||||||
user = User.objects.get(username=self.cleaned_data['username'])
|
user = User.objects.get(username=self.cleaned_data["username"])
|
||||||
if data == user.email:
|
if data == user.email:
|
||||||
return data
|
return data
|
||||||
if User.objects.filter(email=data).exists():
|
if User.objects.filter(email=data).exists():
|
||||||
raise forms.ValidationError('Email Address is in use')
|
raise forms.ValidationError("Email Address is in use")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
form_data = self.cleaned_data
|
form_data = self.cleaned_data
|
||||||
if form_data['password'] != form_data['password_confirm']:
|
if form_data["password"] != form_data["password_confirm"]:
|
||||||
raise forms.ValidationError('Passwords do not match.')
|
raise forms.ValidationError("Passwords do not match.")
|
||||||
if len(form_data['password']) < 8 & len(form_data['password']) != 0:
|
if len(form_data["password"]) < 8 & len(form_data["password"]) != 0:
|
||||||
raise forms.ValidationError('Password is too short')
|
raise forms.ValidationError("Password is too short")
|
||||||
return form_data
|
return form_data
|
||||||
|
|
||||||
|
|
||||||
class AddUserForm(forms.Form):
|
class AddUserForm(forms.Form):
|
||||||
username = forms.CharField(help_text='Username',
|
username = forms.CharField(help_text="Username", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
widget=forms.TextInput(
|
email = forms.CharField(help_text="Email Address", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
attrs={
|
password = forms.CharField(help_text="New Password", widget=forms.PasswordInput(attrs={"class": "form-control"}))
|
||||||
'class': 'form-control',
|
password_confirm = forms.CharField(
|
||||||
}
|
help_text="New Password Confirmation", widget=forms.PasswordInput(attrs={"class": "form-control"})
|
||||||
))
|
)
|
||||||
email = forms.CharField(help_text='Email Address',
|
|
||||||
widget=forms.TextInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control'
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password = forms.CharField(help_text='New Password',
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password_confirm = forms.CharField(help_text='New Password Confirmation',
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
def clean_username(self):
|
def clean_username(self):
|
||||||
data = self.cleaned_data['username']
|
data = self.cleaned_data["username"]
|
||||||
if User.objects.filter(username=data).exists():
|
if User.objects.filter(username=data).exists():
|
||||||
raise forms.ValidationError('This username Exists.')
|
raise forms.ValidationError("This username Exists.")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
data = self.cleaned_data['email']
|
data = self.cleaned_data["email"]
|
||||||
if User.objects.filter(email=data).exists():
|
if User.objects.filter(email=data).exists():
|
||||||
raise forms.ValidationError('Email Address is in use')
|
raise forms.ValidationError("Email Address is in use")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
form_data = self.cleaned_data
|
form_data = self.cleaned_data
|
||||||
if form_data['password'] != form_data['password_confirm']:
|
if form_data["password"] != form_data["password_confirm"]:
|
||||||
raise forms.ValidationError('Passwords do not match.')
|
raise forms.ValidationError("Passwords do not match.")
|
||||||
if len(form_data['password']) < 8:
|
if len(form_data["password"]) < 8:
|
||||||
raise forms.ValidationError('Password is too short')
|
raise forms.ValidationError("Password is too short")
|
||||||
return form_data
|
return form_data
|
||||||
|
|
||||||
|
|
||||||
class EditUserForm(forms.Form):
|
class EditUserForm(forms.Form):
|
||||||
username = forms.CharField(help_text='Username',
|
username = forms.CharField(
|
||||||
required=False,
|
help_text="Username",
|
||||||
widget=forms.TextInput(
|
required=False,
|
||||||
attrs={
|
widget=forms.TextInput(attrs={"class": "form-control disabled", "readonly": True}),
|
||||||
'class': 'form-control disabled',
|
)
|
||||||
'readonly': True,
|
email = forms.CharField(help_text="Email Address", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
}
|
password = forms.CharField(
|
||||||
))
|
help_text="New Password", required=False, widget=forms.PasswordInput(attrs={"class": "form-control"})
|
||||||
email = forms.CharField(help_text='Email Address',
|
)
|
||||||
widget=forms.TextInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control'
|
|
||||||
}
|
|
||||||
))
|
|
||||||
password = forms.CharField(help_text='New Password',
|
|
||||||
required=False,
|
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
# TODO: allow setting superuser on users
|
# TODO: allow setting superuser on users
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_initial_values(user):
|
def get_initial_values(user):
|
||||||
out = {
|
out = {"username": user.username, "email": user.email}
|
||||||
'username': user.username,
|
|
||||||
'email': user.email
|
|
||||||
}
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
data = self.cleaned_data['email']
|
data = self.cleaned_data["email"]
|
||||||
user = User.objects.get(username=self.cleaned_data['username'])
|
user = User.objects.get(username=self.cleaned_data["username"])
|
||||||
if data == user.email:
|
if data == user.email:
|
||||||
return data
|
return data
|
||||||
if User.objects.filter(email=data).exists():
|
if User.objects.filter(email=data).exists():
|
||||||
raise forms.ValidationError('Email Address is in use')
|
raise forms.ValidationError("Email Address is in use")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def clean_password(self):
|
def clean_password(self):
|
||||||
data = self.cleaned_data['password']
|
data = self.cleaned_data["password"]
|
||||||
if len(data) < 8 & len(data) != 0:
|
if len(data) < 8 & len(data) != 0:
|
||||||
raise forms.ValidationError('Password is too short')
|
raise forms.ValidationError("Password is too short")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
class SettingsForm(forms.Form):
|
class SettingsForm(forms.Form):
|
||||||
base_dir = forms.CharField(help_text='Base Directory',
|
base_dir = forms.CharField(help_text="Base Directory", widget=forms.TextInput(attrs={"class": "form-control"}))
|
||||||
widget=forms.TextInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control'
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
def clean_base_dir(self):
|
def clean_base_dir(self):
|
||||||
data = self.cleaned_data['base_dir']
|
data = self.cleaned_data["base_dir"]
|
||||||
if not path.isdir(data):
|
if not path.isdir(data):
|
||||||
raise forms.ValidationError('This is not a valid Directory')
|
raise forms.ValidationError("This is not a valid Directory")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_initial_values():
|
def get_initial_values():
|
||||||
base_dir, _ = Setting.objects.get_or_create(name='BASE_DIR')
|
base_dir, _ = Setting.objects.get_or_create(name="BASE_DIR")
|
||||||
|
|
||||||
initial = {
|
initial = {"base_dir": base_dir.value}
|
||||||
'base_dir': base_dir.value,
|
|
||||||
}
|
|
||||||
return initial
|
return initial
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ from comic.models import Setting, Directory, ComicBook
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Scan directories to Update Comic DB'
|
help = "Scan directories to Update Comic DB"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.base_dir = Setting.objects.get(name='BASE_DIR').value
|
self.base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
self.scan_directory()
|
self.scan_directory()
|
||||||
@@ -36,25 +36,21 @@ class Command(BaseCommand):
|
|||||||
for file in os.listdir(comic_dir):
|
for file in os.listdir(comic_dir):
|
||||||
if isdir(os.path.join(comic_dir, file)):
|
if isdir(os.path.join(comic_dir, file)):
|
||||||
if directory:
|
if directory:
|
||||||
next_directory, created = Directory.objects.get_or_create(name=file,
|
next_directory, created = Directory.objects.get_or_create(name=file, parent=directory)
|
||||||
parent=directory)
|
|
||||||
else:
|
else:
|
||||||
next_directory, created = Directory.objects.get_or_create(name=file,
|
next_directory, created = Directory.objects.get_or_create(name=file, parent__isnull=True)
|
||||||
parent__isnull=True)
|
|
||||||
if created:
|
if created:
|
||||||
next_directory.save()
|
next_directory.save()
|
||||||
self.scan_directory(next_directory)
|
self.scan_directory(next_directory)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if directory:
|
if directory:
|
||||||
book = ComicBook.objects.get(file_name=file,
|
book = ComicBook.objects.get(file_name=file, directory=directory)
|
||||||
directory=directory)
|
|
||||||
if book.version == 0:
|
if book.version == 0:
|
||||||
book.version = 1
|
book.version = 1
|
||||||
book.save()
|
book.save()
|
||||||
else:
|
else:
|
||||||
book = ComicBook.objects.get(file_name=file,
|
book = ComicBook.objects.get(file_name=file, directory__isnull=True)
|
||||||
directory__isnull=True)
|
|
||||||
if book.version == 0:
|
if book.version == 0:
|
||||||
if directory:
|
if directory:
|
||||||
book.directory = directory
|
book.directory = directory
|
||||||
|
|||||||
@@ -6,16 +6,15 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = []
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Setting',
|
name="Setting",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
|
||||||
('name', models.CharField(max_length=50)),
|
("name", models.CharField(max_length=50)),
|
||||||
('value', models.TextField()),
|
("value", models.TextField()),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0001_initial")]
|
||||||
('comic', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(model_name="setting", name="name", field=models.CharField(unique=True, max_length=50))
|
||||||
model_name='setting',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(unique=True, max_length=50),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,27 +6,25 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0002_auto_20150616_1613")]
|
||||||
('comic', '0002_auto_20150616_1613'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ComicBook',
|
name="ComicBook",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
|
||||||
('file_name', models.CharField(unique=True, max_length=100)),
|
("file_name", models.CharField(unique=True, max_length=100)),
|
||||||
('last_read_page', models.IntegerField()),
|
("last_read_page", models.IntegerField()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ComicPage',
|
name="ComicPage",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
|
||||||
('index', models.IntegerField()),
|
("index", models.IntegerField()),
|
||||||
('page_file_name', models.CharField(max_length=100)),
|
("page_file_name", models.CharField(max_length=100)),
|
||||||
('content_type', models.CharField(max_length=30)),
|
("content_type", models.CharField(max_length=30)),
|
||||||
('Comic', models.ForeignKey(to='comic.ComicBook', on_delete=models.CASCADE)),
|
("Comic", models.ForeignKey(to="comic.ComicBook", on_delete=models.CASCADE)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,15 +6,10 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0003_comicbook_comicpage")]
|
||||||
('comic', '0003_comicbook_comicpage'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comicbook',
|
model_name="comicbook", name="unread", field=models.BooleanField(default=True), preserve_default=False
|
||||||
name='unread',
|
)
|
||||||
field=models.BooleanField(default=True),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,36 +7,27 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("comic", "0004_comicbook_unread")]
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('comic', '0004_comicbook_unread'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ComicStatus',
|
name="ComicStatus",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
|
||||||
('last_read_page', models.IntegerField()),
|
("last_read_page", models.IntegerField()),
|
||||||
('unread', models.BooleanField()),
|
("unread", models.BooleanField()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="comicbook", name="last_read_page"),
|
||||||
model_name='comicbook',
|
migrations.RemoveField(model_name="comicbook", name="unread"),
|
||||||
name='last_read_page',
|
migrations.AddField(
|
||||||
),
|
model_name="comicstatus",
|
||||||
migrations.RemoveField(
|
name="comic",
|
||||||
model_name='comicbook',
|
field=models.ForeignKey(to="comic.ComicBook", on_delete=models.CASCADE),
|
||||||
name='unread',
|
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comicstatus',
|
model_name="comicstatus",
|
||||||
name='comic',
|
name="user",
|
||||||
field=models.ForeignKey(to='comic.ComicBook', on_delete=models.CASCADE),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='comicstatus',
|
|
||||||
name='user',
|
|
||||||
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE),
|
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,19 +6,9 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0005_auto_20150625_1400")]
|
||||||
('comic', '0005_auto_20150625_1400'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(model_name="comicstatus", name="last_read_page", field=models.IntegerField(default=0)),
|
||||||
model_name='comicstatus',
|
migrations.AlterField(model_name="comicstatus", name="unread", field=models.BooleanField(default=True)),
|
||||||
name='last_read_page',
|
|
||||||
field=models.IntegerField(default=0),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='comicstatus',
|
|
||||||
name='unread',
|
|
||||||
field=models.BooleanField(default=True),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0006_auto_20150625_1411")]
|
||||||
('comic', '0006_auto_20150625_1411'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(model_name="setting", name="name", field=models.CharField(unique=True, max_length=100))
|
||||||
model_name='setting',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(unique=True, max_length=100),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,39 +11,40 @@ import uuid
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0007_auto_20150626_1820")]
|
||||||
('comic', '0007_auto_20150626_1820'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Directory',
|
name="Directory",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
||||||
('name', models.CharField(max_length=100)),
|
("name", models.CharField(max_length=100)),
|
||||||
('selector', models.UUIDField(default=uuid.uuid4, null=True)),
|
("selector", models.UUIDField(default=uuid.uuid4, null=True)),
|
||||||
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comic.Directory')),
|
(
|
||||||
|
"parent",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="comic.Directory"
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comicbook',
|
model_name="comicbook",
|
||||||
name='date_added',
|
name="date_added",
|
||||||
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 3, 31, 10, 40, 30, 62170, tzinfo=utc)),
|
field=models.DateTimeField(
|
||||||
|
auto_now_add=True, default=datetime.datetime(2016, 3, 31, 10, 40, 30, 62170, tzinfo=utc)
|
||||||
|
),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comicbook',
|
model_name="comicbook", name="selector", field=models.UUIDField(default=uuid.uuid4, null=True)
|
||||||
name='selector',
|
|
||||||
field=models.UUIDField(default=uuid.uuid4, null=True),
|
|
||||||
),
|
),
|
||||||
|
migrations.AddField(model_name="comicbook", name="version", field=models.IntegerField(default=0)),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comicbook',
|
model_name="comicbook",
|
||||||
name='version',
|
name="directory",
|
||||||
field=models.IntegerField(default=0),
|
field=models.ForeignKey(
|
||||||
),
|
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="comic.Directory"
|
||||||
migrations.AddField(
|
),
|
||||||
model_name='comicbook',
|
|
||||||
name='directory',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comic.Directory'),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import uuid
|
|||||||
|
|
||||||
|
|
||||||
def gen_uuid(apps, schema_editor):
|
def gen_uuid(apps, schema_editor):
|
||||||
comicbook = apps.get_model('comic', 'comicbook')
|
comicbook = apps.get_model("comic", "comicbook")
|
||||||
for row in comicbook.objects.all():
|
for row in comicbook.objects.all():
|
||||||
row.selector = uuid.uuid4()
|
row.selector = uuid.uuid4()
|
||||||
row.save()
|
row.save()
|
||||||
directory = apps.get_model('comic', 'directory')
|
directory = apps.get_model("comic", "directory")
|
||||||
for row in directory.objects.all():
|
for row in directory.objects.all():
|
||||||
row.selector = uuid.uuid4()
|
row.selector = uuid.uuid4()
|
||||||
row.save()
|
row.save()
|
||||||
@@ -20,10 +20,6 @@ def gen_uuid(apps, schema_editor):
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0008_auto_20160331_1140")]
|
||||||
('comic', '0008_auto_20160331_1140'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop)]
|
||||||
migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -9,19 +9,13 @@ import uuid
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0009_auto_20160331_1140")]
|
||||||
('comic', '0009_auto_20160331_1140'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comicbook',
|
model_name="comicbook", name="selector", field=models.UUIDField(default=uuid.uuid4, unique=True)
|
||||||
name='selector',
|
|
||||||
field=models.UUIDField(default=uuid.uuid4, unique=True),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='directory',
|
model_name="directory", name="selector", field=models.UUIDField(default=uuid.uuid4, unique=True)
|
||||||
name='selector',
|
|
||||||
field=models.UUIDField(default=uuid.uuid4, unique=True),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,14 +7,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0010_auto_20160331_1140")]
|
||||||
('comic', '0010_auto_20160331_1140'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.AlterField(model_name="comicbook", name="version", field=models.IntegerField(default=1))]
|
||||||
migrations.AlterField(
|
|
||||||
model_name='comicbook',
|
|
||||||
name='version',
|
|
||||||
field=models.IntegerField(default=1),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -8,19 +8,17 @@ import uuid
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0011_auto_20160331_1141")]
|
||||||
('comic', '0011_auto_20160331_1141'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comicbook',
|
model_name="comicbook",
|
||||||
name='selector',
|
name="selector",
|
||||||
field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
|
field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='directory',
|
model_name="directory",
|
||||||
name='selector',
|
name="selector",
|
||||||
field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
|
field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,14 +7,8 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0012_auto_20160401_0949")]
|
||||||
('comic', '0012_auto_20160401_0949'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(model_name="comicstatus", name="finished", field=models.BooleanField(default=False))
|
||||||
model_name='comicstatus',
|
|
||||||
name='finished',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,22 +5,19 @@ from __future__ import unicode_literals
|
|||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
|
|
||||||
|
|
||||||
def set_finished(apps, schema_editor):
|
def set_finished(apps, schema_editor):
|
||||||
comicstatus = apps.get_model('comic', 'comicstatus')
|
comicstatus = apps.get_model("comic", "comicstatus")
|
||||||
comicpage = apps.get_model('comic', 'ComicPage')
|
comicpage = apps.get_model("comic", "ComicPage")
|
||||||
for row in comicstatus.objects.all():
|
for row in comicstatus.objects.all():
|
||||||
last_page = comicpage.objects.filter(Comic=row.comic).aggregate(Max('index'))
|
last_page = comicpage.objects.filter(Comic=row.comic).aggregate(Max("index"))
|
||||||
if row.last_read_page == last_page['index__max']:
|
if row.last_read_page == last_page["index__max"]:
|
||||||
row.finished = True
|
row.finished = True
|
||||||
row.save()
|
row.save()
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0013_comicstatus_finished")]
|
||||||
('comic', '0013_comicstatus_finished'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RunPython(set_finished, reverse_code=migrations.RunPython.noop)]
|
||||||
migrations.RunPython(set_finished, reverse_code=migrations.RunPython.noop),
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -7,14 +7,8 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("comic", "0014_auto_20160404_1402")]
|
||||||
('comic', '0014_auto_20160404_1402'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(model_name="comicbook", name="file_name", field=models.CharField(max_length=100))
|
||||||
model_name='comicbook',
|
|
||||||
name='file_name',
|
|
||||||
field=models.CharField(max_length=100),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [("comic", "0015_auto_20160405_1126")]
|
||||||
('comic', '0015_auto_20160405_1126'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(model_name="comicpage", name="page_file_name", field=models.CharField(max_length=200))
|
||||||
model_name='comicpage',
|
|
||||||
name='page_file_name',
|
|
||||||
field=models.CharField(max_length=200),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,19 +10,18 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("comic", "0016_auto_20160414_1335")]
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('comic', '0016_auto_20160414_1335'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='UserMisc',
|
name="UserMisc",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
||||||
('feed_id', models.UUIDField(db_index=True, default=uuid.uuid4, unique=True)),
|
("feed_id", models.UUIDField(db_index=True, default=uuid.uuid4, unique=True)),
|
||||||
(
|
(
|
||||||
'user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
"user",
|
||||||
|
models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,17 +6,13 @@ from django.db import migrations
|
|||||||
|
|
||||||
|
|
||||||
def gen_feeds(apps, schema_editor):
|
def gen_feeds(apps, schema_editor):
|
||||||
user_misc = apps.get_model('comic', 'UserMisc')
|
user_misc = apps.get_model("comic", "UserMisc")
|
||||||
User = apps.get_model('auth', 'user')
|
User = apps.get_model("auth", "user")
|
||||||
for user in User.objects.all():
|
for user in User.objects.all():
|
||||||
um = user_misc.objects.create(user=user)
|
um = user_misc.objects.create(user=user)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [("comic", "0017_usermisc")]
|
||||||
('comic', '0017_usermisc'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RunPython(gen_feeds, reverse_code=migrations.RunPython.noop)]
|
||||||
migrations.RunPython(gen_feeds, reverse_code=migrations.RunPython.noop),
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ class Setting(models.Model):
|
|||||||
|
|
||||||
class Directory(models.Model):
|
class Directory(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
parent = models.ForeignKey('Directory', null=True, blank=True, on_delete=models.CASCADE)
|
parent = models.ForeignKey("Directory", null=True, blank=True, on_delete=models.CASCADE)
|
||||||
selector = models.UUIDField(unique=True, default=uuid.uuid4, db_index=True)
|
selector = models.UUIDField(unique=True, default=uuid.uuid4, db_index=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Directory: {0}; {1}'.format(self.name, self.parent)
|
return "Directory: {0}; {1}".format(self.name, self.parent)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
@@ -83,7 +83,7 @@ class ComicBook(models.Model):
|
|||||||
return urlsafe_base64_encode(self.selector.bytes)
|
return urlsafe_base64_encode(self.selector.bytes)
|
||||||
|
|
||||||
def get_image(self, page):
|
def get_image(self, page):
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
if self.directory:
|
if self.directory:
|
||||||
archive_path = path.join(base_dir, self.directory.path, self.file_name)
|
archive_path = path.join(base_dir, self.directory.path, self.file_name)
|
||||||
else:
|
else:
|
||||||
@@ -109,11 +109,11 @@ class ComicBook(models.Model):
|
|||||||
|
|
||||||
class Navigation:
|
class Navigation:
|
||||||
next_index = 0
|
next_index = 0
|
||||||
next_path = ''
|
next_path = ""
|
||||||
prev_index = 0
|
prev_index = 0
|
||||||
prev_path = ''
|
prev_path = ""
|
||||||
cur_index = 0
|
cur_index = 0
|
||||||
cur_path = ''
|
cur_path = ""
|
||||||
q_prev_to_directory = False
|
q_prev_to_directory = False
|
||||||
q_next_to_directory = False
|
q_next_to_directory = False
|
||||||
|
|
||||||
@@ -122,10 +122,7 @@ class ComicBook(models.Model):
|
|||||||
setattr(self, arg, kwargs[arg])
|
setattr(self, arg, kwargs[arg])
|
||||||
|
|
||||||
def nav(self, page, user):
|
def nav(self, page, user):
|
||||||
out = self.Navigation(
|
out = self.Navigation(cur_index=page, cur_path=urlsafe_base64_encode(self.selector.bytes))
|
||||||
cur_index=page,
|
|
||||||
cur_path=urlsafe_base64_encode(self.selector.bytes)
|
|
||||||
)
|
|
||||||
if page == 0:
|
if page == 0:
|
||||||
out.prev_path, out.prev_index = self.nav_get_prev_comic(user)
|
out.prev_path, out.prev_index = self.nav_get_prev_comic(user)
|
||||||
if out.prev_index == -1:
|
if out.prev_index == -1:
|
||||||
@@ -144,7 +141,7 @@ class ComicBook(models.Model):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
def nav_get_prev_comic(self, user):
|
def nav_get_prev_comic(self, user):
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
if self.directory:
|
if self.directory:
|
||||||
folder = path.join(base_dir, self.directory.path)
|
folder = path.join(base_dir, self.directory.path)
|
||||||
else:
|
else:
|
||||||
@@ -155,7 +152,7 @@ class ComicBook(models.Model):
|
|||||||
if self.directory:
|
if self.directory:
|
||||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||||
else:
|
else:
|
||||||
comic_path = ''
|
comic_path = ""
|
||||||
index = -1
|
index = -1
|
||||||
else:
|
else:
|
||||||
prev_comic = dir_list[comic_index - 1]
|
prev_comic = dir_list[comic_index - 1]
|
||||||
@@ -163,11 +160,9 @@ class ComicBook(models.Model):
|
|||||||
if not path.isdir(path.join(folder, prev_comic)):
|
if not path.isdir(path.join(folder, prev_comic)):
|
||||||
try:
|
try:
|
||||||
if self.directory:
|
if self.directory:
|
||||||
book = ComicBook.objects.get(file_name=prev_comic,
|
book = ComicBook.objects.get(file_name=prev_comic, directory=self.directory)
|
||||||
directory=self.directory)
|
|
||||||
else:
|
else:
|
||||||
book = ComicBook.objects.get(file_name=prev_comic,
|
book = ComicBook.objects.get(file_name=prev_comic, directory__isnull=True)
|
||||||
directory__isnull=True)
|
|
||||||
except ComicBook.DoesNotExist:
|
except ComicBook.DoesNotExist:
|
||||||
if self.directory:
|
if self.directory:
|
||||||
book = ComicBook.process_comic_book(prev_comic, self.directory)
|
book = ComicBook.process_comic_book(prev_comic, self.directory)
|
||||||
@@ -180,12 +175,12 @@ class ComicBook(models.Model):
|
|||||||
if self.directory:
|
if self.directory:
|
||||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||||
else:
|
else:
|
||||||
comic_path = ''
|
comic_path = ""
|
||||||
index = -1
|
index = -1
|
||||||
return comic_path, index
|
return comic_path, index
|
||||||
|
|
||||||
def nav_get_next_comic(self, user):
|
def nav_get_next_comic(self, user):
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
if self.directory:
|
if self.directory:
|
||||||
folder = path.join(base_dir, self.directory.path)
|
folder = path.join(base_dir, self.directory.path)
|
||||||
else:
|
else:
|
||||||
@@ -196,11 +191,9 @@ class ComicBook(models.Model):
|
|||||||
next_comic = dir_list[comic_index + 1]
|
next_comic = dir_list[comic_index + 1]
|
||||||
try:
|
try:
|
||||||
if self.directory:
|
if self.directory:
|
||||||
book = ComicBook.objects.get(file_name=next_comic,
|
book = ComicBook.objects.get(file_name=next_comic, directory=self.directory)
|
||||||
directory=self.directory)
|
|
||||||
else:
|
else:
|
||||||
book = ComicBook.objects.get(file_name=next_comic,
|
book = ComicBook.objects.get(file_name=next_comic, directory__isnull=True)
|
||||||
directory__isnull=True)
|
|
||||||
except ComicBook.DoesNotExist:
|
except ComicBook.DoesNotExist:
|
||||||
if self.directory:
|
if self.directory:
|
||||||
book = ComicBook.process_comic_book(next_comic, self.directory)
|
book = ComicBook.process_comic_book(next_comic, self.directory)
|
||||||
@@ -215,18 +208,18 @@ class ComicBook(models.Model):
|
|||||||
if self.directory:
|
if self.directory:
|
||||||
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
comic_path = urlsafe_base64_encode(self.directory.selector.bytes)
|
||||||
else:
|
else:
|
||||||
comic_path = ''
|
comic_path = ""
|
||||||
index = -1
|
index = -1
|
||||||
return comic_path, index
|
return comic_path, index
|
||||||
|
|
||||||
class DirFile:
|
class DirFile:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = ''
|
self.name = ""
|
||||||
self.isdir = False
|
self.isdir = False
|
||||||
self.icon = ''
|
self.icon = ""
|
||||||
self.iscb = False
|
self.iscb = False
|
||||||
self.location = ''
|
self.location = ""
|
||||||
self.label = ''
|
self.label = ""
|
||||||
self.cur_page = 0
|
self.cur_page = 0
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -234,7 +227,7 @@ class ComicBook(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def pages(self):
|
def pages(self):
|
||||||
return [cp for cp in ComicPage.objects.filter(Comic=self).order_by('index')]
|
return [cp for cp in ComicPage.objects.filter(Comic=self).order_by("index")]
|
||||||
|
|
||||||
def page_name(self, index):
|
def page_name(self, index):
|
||||||
return ComicPage.objects.get(Comic=self, index=index).page_file_name
|
return ComicPage.objects.get(Comic=self, index=index).page_file_name
|
||||||
@@ -247,15 +240,14 @@ class ComicBook(models.Model):
|
|||||||
:type directory: Directory
|
:type directory: Directory
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
book = ComicBook.objects.get(file_name=comic_file_name,
|
book = ComicBook.objects.get(file_name=comic_file_name, version=0)
|
||||||
version=0)
|
|
||||||
book.directory = directory
|
book.directory = directory
|
||||||
book.version = 1
|
book.version = 1
|
||||||
book.save()
|
book.save()
|
||||||
return book
|
return book
|
||||||
except ComicBook.DoesNotExist:
|
except ComicBook.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
if directory:
|
if directory:
|
||||||
comic_full_path = path.join(base_dir, directory.get_path(), comic_file_name)
|
comic_full_path = path.join(base_dir, directory.get_path(), comic_file_name)
|
||||||
else:
|
else:
|
||||||
@@ -272,32 +264,30 @@ class ComicBook(models.Model):
|
|||||||
return comic_file_name
|
return comic_file_name
|
||||||
with atomic():
|
with atomic():
|
||||||
if directory:
|
if directory:
|
||||||
book = ComicBook(file_name=comic_file_name,
|
book = ComicBook(file_name=comic_file_name, directory=directory)
|
||||||
directory=directory)
|
|
||||||
else:
|
else:
|
||||||
book = ComicBook(file_name=comic_file_name)
|
book = ComicBook(file_name=comic_file_name)
|
||||||
book.save()
|
book.save()
|
||||||
page_index = 0
|
page_index = 0
|
||||||
for page_file_name in sorted([str(x) for x in cbx.namelist()], key=str.lower):
|
for page_file_name in sorted([str(x) for x in cbx.namelist()], key=str.lower):
|
||||||
try:
|
try:
|
||||||
dot_index = page_file_name.rindex('.') + 1
|
dot_index = page_file_name.rindex(".") + 1
|
||||||
except ValueError:
|
except ValueError:
|
||||||
continue
|
continue
|
||||||
ext = page_file_name.lower()[dot_index:]
|
ext = page_file_name.lower()[dot_index:]
|
||||||
if ext in ['jpg', 'jpeg']:
|
if ext in ["jpg", "jpeg"]:
|
||||||
content_type = 'image/jpeg'
|
content_type = "image/jpeg"
|
||||||
elif ext == 'png':
|
elif ext == "png":
|
||||||
content_type = 'image/png'
|
content_type = "image/png"
|
||||||
elif ext == 'bmp':
|
elif ext == "bmp":
|
||||||
content_type = 'image/bmp'
|
content_type = "image/bmp"
|
||||||
elif ext == 'gif':
|
elif ext == "gif":
|
||||||
content_type = 'image/gif'
|
content_type = "image/gif"
|
||||||
else:
|
else:
|
||||||
content_type = 'text/plain'
|
content_type = "text/plain"
|
||||||
page = ComicPage(Comic=book,
|
page = ComicPage(
|
||||||
index=page_index,
|
Comic=book, index=page_index, page_file_name=page_file_name, content_type=content_type
|
||||||
page_file_name=page_file_name,
|
)
|
||||||
content_type=content_type)
|
|
||||||
page.save()
|
page.save()
|
||||||
page_index += 1
|
page_index += 1
|
||||||
return book
|
return book
|
||||||
@@ -336,8 +326,12 @@ class ComicStatus(models.Model):
|
|||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'<ComicStatus:{self.user.username}:{self.comic.file_name}:{self.last_read_page}:' \
|
return (
|
||||||
f'{self.unread}:{self.finished}'
|
f"<ComicStatus:{self.user.username}:{self.comic.file_name}:{self.last_read_page}:"
|
||||||
|
f"{self.unread}:{self.finished}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO: add support to reference items last being read
|
# TODO: add support to reference items last being read
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
536
comic/rarfile.py
536
comic/rarfile.py
File diff suppressed because it is too large
Load Diff
@@ -12,9 +12,7 @@ from comic.util import generate_directory
|
|||||||
|
|
||||||
class ComicBookTests(TestCase):
|
class ComicBookTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
Setting.objects.create(
|
Setting.objects.create(name="BASE_DIR", value=path.join(os.getcwd(), "comic", "test"))
|
||||||
name="BASE_DIR", value=path.join(os.getcwd(), "comic", "test")
|
|
||||||
)
|
|
||||||
User.objects.create_user("test", "test@test.com", "test")
|
User.objects.create_user("test", "test@test.com", "test")
|
||||||
user = User.objects.first()
|
user = User.objects.first()
|
||||||
ComicBook.process_comic_book("test1.rar")
|
ComicBook.process_comic_book("test1.rar")
|
||||||
@@ -133,51 +131,34 @@ class ComicBookTests(TestCase):
|
|||||||
d = Directory.objects.get(name="test_folder", parent__isnull=True)
|
d = Directory.objects.get(name="test_folder", parent__isnull=True)
|
||||||
location = "/comic/{0}/".format(urlsafe_base64_encode(d.selector.bytes))
|
location = "/comic/{0}/".format(urlsafe_base64_encode(d.selector.bytes))
|
||||||
self.assertEqual(dir1.location, location)
|
self.assertEqual(dir1.location, location)
|
||||||
self.assertEqual(
|
self.assertEqual(dir1.label, '<center><span class="label label-default">Empty</span></center>')
|
||||||
dir1.label,
|
|
||||||
'<center><span class="label label-default">Empty</span></center>',
|
|
||||||
)
|
|
||||||
|
|
||||||
dir2 = folders[1]
|
dir2 = folders[1]
|
||||||
self.assertEqual(dir2.name, "test1.rar")
|
self.assertEqual(dir2.name, "test1.rar")
|
||||||
self.assertEqual(dir2.type, "book")
|
self.assertEqual(dir2.type, "book")
|
||||||
self.assertEqual(dir2.icon, "glyphicon-book")
|
self.assertEqual(dir2.icon, "glyphicon-book")
|
||||||
c = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
c = ComicBook.objects.get(file_name="test1.rar", directory__isnull=True)
|
||||||
location = "/comic/read/{0}/{1}/".format(
|
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "0")
|
||||||
urlsafe_base64_encode(c.selector.bytes), "0"
|
|
||||||
)
|
|
||||||
self.assertEqual(dir2.location, location)
|
self.assertEqual(dir2.location, location)
|
||||||
self.assertEqual(
|
self.assertEqual(dir2.label, '<center><span class="label label-default">Unread</span></center>')
|
||||||
dir2.label,
|
|
||||||
'<center><span class="label label-default">Unread</span></center>',
|
|
||||||
)
|
|
||||||
|
|
||||||
dir3 = folders[2]
|
dir3 = folders[2]
|
||||||
self.assertEqual(dir3.name, "test2.rar")
|
self.assertEqual(dir3.name, "test2.rar")
|
||||||
self.assertEqual(dir3.type, "book")
|
self.assertEqual(dir3.type, "book")
|
||||||
self.assertEqual(dir3.icon, "glyphicon-book")
|
self.assertEqual(dir3.icon, "glyphicon-book")
|
||||||
c = ComicBook.objects.get(file_name="test2.rar", directory__isnull=True)
|
c = ComicBook.objects.get(file_name="test2.rar", directory__isnull=True)
|
||||||
location = "/comic/read/{0}/{1}/".format(
|
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "2")
|
||||||
urlsafe_base64_encode(c.selector.bytes), "2"
|
|
||||||
)
|
|
||||||
self.assertEqual(dir3.location, location)
|
self.assertEqual(dir3.location, location)
|
||||||
self.assertEqual(
|
self.assertEqual(dir3.label, '<center><span class="label label-primary">3/4</span></center>')
|
||||||
dir3.label, '<center><span class="label label-primary">3/4</span></center>'
|
|
||||||
)
|
|
||||||
|
|
||||||
dir4 = folders[3]
|
dir4 = folders[3]
|
||||||
self.assertEqual(dir4.name, "test3.rar")
|
self.assertEqual(dir4.name, "test3.rar")
|
||||||
self.assertEqual(dir4.type, "book")
|
self.assertEqual(dir4.type, "book")
|
||||||
self.assertEqual(dir3.icon, "glyphicon-book")
|
self.assertEqual(dir3.icon, "glyphicon-book")
|
||||||
c = ComicBook.objects.get(file_name="test3.rar", directory__isnull=True)
|
c = ComicBook.objects.get(file_name="test3.rar", directory__isnull=True)
|
||||||
location = "/comic/read/{0}/{1}/".format(
|
location = "/comic/read/{0}/{1}/".format(urlsafe_base64_encode(c.selector.bytes), "0")
|
||||||
urlsafe_base64_encode(c.selector.bytes), "0"
|
|
||||||
)
|
|
||||||
self.assertEqual(dir4.location, location)
|
self.assertEqual(dir4.location, location)
|
||||||
self.assertEqual(
|
self.assertEqual(dir4.label, '<center><span class="label label-default">Unread</span></center>')
|
||||||
dir4.label,
|
|
||||||
'<center><span class="label label-default">Unread</span></center>',
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_pages(self):
|
def test_pages(self):
|
||||||
book = ComicBook.objects.get(file_name="test1.rar")
|
book = ComicBook.objects.get(file_name="test1.rar")
|
||||||
@@ -217,9 +198,7 @@ class ComicBookTests(TestCase):
|
|||||||
response = c.post("/comic/list_json/")
|
response = c.post("/comic/list_json/")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
directory = Directory.objects.first()
|
directory = Directory.objects.first()
|
||||||
response = c.post(
|
response = c.post(f"/comic/list_json/{urlsafe_base64_encode(directory.selector.bytes)}/")
|
||||||
f"/comic/list_json/{urlsafe_base64_encode(directory.selector.bytes)}/"
|
|
||||||
)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_recent_comics(self):
|
def test_recent_comics(self):
|
||||||
@@ -241,12 +220,7 @@ class ComicBookTests(TestCase):
|
|||||||
generate_directory(User.objects.first())
|
generate_directory(User.objects.first())
|
||||||
ComicStatus.objects.all().delete()
|
ComicStatus.objects.all().delete()
|
||||||
|
|
||||||
req_data = {
|
req_data = {"start": "0", "length": "10", "search[value]": "", "order[0][dir]": "desc"}
|
||||||
"start": "0",
|
|
||||||
"length": "10",
|
|
||||||
"search[value]": "",
|
|
||||||
"order[0][dir]": "desc",
|
|
||||||
}
|
|
||||||
response = c.post("/comic/recent/json/", req_data)
|
response = c.post("/comic/recent/json/", req_data)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
req_data["search[value]"] = "test1.rar"
|
req_data["search[value]"] = "test1.rar"
|
||||||
@@ -261,13 +235,11 @@ class ComicBookTests(TestCase):
|
|||||||
{
|
{
|
||||||
"date": book.date_added.strftime("%d/%m/%y-%H:%M"),
|
"date": book.date_added.strftime("%d/%m/%y-%H:%M"),
|
||||||
"icon": '<span class="glyphicon glyphicon-book"></span>',
|
"icon": '<span class="glyphicon glyphicon-book"></span>',
|
||||||
"label": '<center><span class="label '
|
"label": '<center><span class="label ' 'label-default">Unread</span></center>',
|
||||||
'label-default">Unread</span></center>',
|
|
||||||
"name": "test1.rar",
|
"name": "test1.rar",
|
||||||
"selector": urlsafe_base64_encode(book.selector.bytes),
|
"selector": urlsafe_base64_encode(book.selector.bytes),
|
||||||
"type": "book",
|
"type": "book",
|
||||||
"url": f"/comic/read/"
|
"url": f"/comic/read/" f"{urlsafe_base64_encode(book.selector.bytes)}/0/",
|
||||||
f"{urlsafe_base64_encode(book.selector.bytes)}/0/",
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"recordsFiltered": 1,
|
"recordsFiltered": 1,
|
||||||
@@ -302,11 +274,7 @@ class ComicBookTests(TestCase):
|
|||||||
response = c.get("/comic/edit/")
|
response = c.get("/comic/edit/")
|
||||||
self.assertEqual(response.status_code, 405)
|
self.assertEqual(response.status_code, 405)
|
||||||
|
|
||||||
req_data = {
|
req_data = {"comic_list_length": 10, "func": "unread", "selected": book.selector_string}
|
||||||
"comic_list_length": 10,
|
|
||||||
"func": "unread",
|
|
||||||
"selected": book.selector_string,
|
|
||||||
}
|
|
||||||
response = c.post("/comic/edit/", req_data)
|
response = c.post("/comic/edit/", req_data)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,21 @@ from django.conf.urls import url
|
|||||||
|
|
||||||
from . import feeds
|
from . import feeds
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.comic_list, name='index'),
|
url(r"^$", views.comic_list, name="index"),
|
||||||
url(r'^settings/$', views.settings_page, name='settings'),
|
url(r"^settings/$", views.settings_page, name="settings"),
|
||||||
url(r'^settings/users/$', views.users_page, name='users'),
|
url(r"^settings/users/$", views.users_page, name="users"),
|
||||||
url(r'^settings/users/(?P<user_id>[0-9]+)/$', views.user_config_page, name='users'),
|
url(r"^settings/users/(?P<user_id>[0-9]+)/$", views.user_config_page, name="users"),
|
||||||
url(r'^settings/users/add/$', views.user_add_page, name='users'),
|
url(r"^settings/users/add/$", views.user_add_page, name="users"),
|
||||||
url(r'^account/$', views.account_page, name='account'),
|
url(r"^account/$", views.account_page, name="account"),
|
||||||
url(r'^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/$', views.read_comic, name='read_comic'),
|
url(r"^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/$", views.read_comic, name="read_comic"),
|
||||||
url(r'^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/img$', views.get_image, name='get_image'),
|
url(r"^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/img$", views.get_image, name="get_image"),
|
||||||
url(r'^list_json/$', views.comic_list_json, name='comic_list_json1'),
|
url(r"^list_json/$", views.comic_list_json, name="comic_list_json1"),
|
||||||
url(r'^list_json/(?P<directory_selector>[\w-]+)/$', views.comic_list_json, name='comic_list_json2'),
|
url(r"^list_json/(?P<directory_selector>[\w-]+)/$", views.comic_list_json, name="comic_list_json2"),
|
||||||
url(r'^recent/$', views.recent_comics, name='recent_comics'),
|
url(r"^recent/$", views.recent_comics, name="recent_comics"),
|
||||||
url(r'^recent/json/$', views.recent_comics_json, name='recent_comics_json'),
|
url(r"^recent/json/$", views.recent_comics_json, name="recent_comics_json"),
|
||||||
url(r'^edit/$', views.comic_edit, name='comic_edit'),
|
url(r"^edit/$", views.comic_edit, name="comic_edit"),
|
||||||
url(r'^feed/(?P<user_selector>[\w-]+)/$', feeds.RecentComics()),
|
url(r"^feed/(?P<user_selector>[\w-]+)/$", feeds.RecentComics()),
|
||||||
url(r'^(?P<directory_selector>[\w-]+)/$', views.comic_list, name='comic_list'),
|
url(r"^(?P<directory_selector>[\w-]+)/$", views.comic_list, name="comic_list"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,32 +8,32 @@ from .models import ComicBook, Setting, ComicStatus, Directory
|
|||||||
|
|
||||||
|
|
||||||
def generate_title_from_path(file_path):
|
def generate_title_from_path(file_path):
|
||||||
if file_path == '':
|
if file_path == "":
|
||||||
return 'CBWebReader'
|
return "CBWebReader"
|
||||||
return 'CBWebReader - ' + ' - '.join(file_path.split(path.sep))
|
return "CBWebReader - " + " - ".join(file_path.split(path.sep))
|
||||||
|
|
||||||
|
|
||||||
class Menu:
|
class Menu:
|
||||||
def __init__(self, user, page=''):
|
def __init__(self, user, page=""):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:type page: str
|
:type page: str
|
||||||
"""
|
"""
|
||||||
self.menu_items = OrderedDict()
|
self.menu_items = OrderedDict()
|
||||||
self.menu_items['Browse'] = '/comic/'
|
self.menu_items["Browse"] = "/comic/"
|
||||||
self.menu_items['Recent'] = '/comic/recent/'
|
self.menu_items["Recent"] = "/comic/recent/"
|
||||||
self.menu_items['Account'] = '/comic/account/'
|
self.menu_items["Account"] = "/comic/account/"
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
self.menu_items['Settings'] = '/comic/settings/'
|
self.menu_items["Settings"] = "/comic/settings/"
|
||||||
self.menu_items['Users'] = '/comic/settings/users/'
|
self.menu_items["Users"] = "/comic/settings/users/"
|
||||||
self.menu_items['Logout'] = '/logout/'
|
self.menu_items["Logout"] = "/logout/"
|
||||||
self.current_page = page
|
self.current_page = page
|
||||||
|
|
||||||
|
|
||||||
class Breadcrumb:
|
class Breadcrumb:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = 'Home'
|
self.name = "Home"
|
||||||
self.url = '/comic/'
|
self.url = "/comic/"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -56,12 +56,12 @@ def generate_breadcrumbs_from_path(directory=False, book=False):
|
|||||||
for item in folders[::-1]:
|
for item in folders[::-1]:
|
||||||
bc = Breadcrumb()
|
bc = Breadcrumb()
|
||||||
bc.name = item.name
|
bc.name = item.name
|
||||||
bc.url = '/comic/' + urlsafe_base64_encode(item.selector.bytes)
|
bc.url = "/comic/" + urlsafe_base64_encode(item.selector.bytes)
|
||||||
output.append(bc)
|
output.append(bc)
|
||||||
if book:
|
if book:
|
||||||
bc = Breadcrumb()
|
bc = Breadcrumb()
|
||||||
bc.name = book.file_name
|
bc.name = book.file_name
|
||||||
bc.url = '/read/' + urlsafe_base64_encode(book.selector.bytes)
|
bc.url = "/read/" + urlsafe_base64_encode(book.selector.bytes)
|
||||||
output.append(bc)
|
output.append(bc)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
@@ -79,46 +79,45 @@ def generate_breadcrumbs_from_menu(paths):
|
|||||||
|
|
||||||
class DirFile:
|
class DirFile:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = ''
|
self.name = ""
|
||||||
self.icon = ''
|
self.icon = ""
|
||||||
self.location = ''
|
self.location = ""
|
||||||
self.label = ''
|
self.label = ""
|
||||||
self.type = ''
|
self.type = ""
|
||||||
self.selector = ''
|
self.selector = ""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def populate_directory(self, directory, user):
|
def populate_directory(self, directory, user):
|
||||||
self.name = directory.name
|
self.name = directory.name
|
||||||
self.icon = 'glyphicon-folder-open'
|
self.icon = "glyphicon-folder-open"
|
||||||
self.selector = urlsafe_base64_encode(directory.selector.bytes)
|
self.selector = urlsafe_base64_encode(directory.selector.bytes)
|
||||||
self.location = '/comic/{0}/'.format(self.selector)
|
self.location = "/comic/{0}/".format(self.selector)
|
||||||
self.label = generate_dir_status(user, directory)
|
self.label = generate_dir_status(user, directory)
|
||||||
self.type = 'directory'
|
self.type = "directory"
|
||||||
|
|
||||||
def populate_comic(self, comic, user):
|
def populate_comic(self, comic, user):
|
||||||
if type(comic) == str:
|
if type(comic) == str:
|
||||||
self.icon = 'glyphicon-remove'
|
self.icon = "glyphicon-remove"
|
||||||
self.name = comic
|
self.name = comic
|
||||||
self.selector = '0'
|
self.selector = "0"
|
||||||
self.location = '/'
|
self.location = "/"
|
||||||
self.label = '<center><span class="label label-danger">Error</span></center>'
|
self.label = '<center><span class="label label-danger">Error</span></center>'
|
||||||
self.type = 'book'
|
self.type = "book"
|
||||||
else:
|
else:
|
||||||
self.icon = 'glyphicon-book'
|
self.icon = "glyphicon-book"
|
||||||
self.name = comic.file_name
|
self.name = comic.file_name
|
||||||
status, created = ComicStatus.objects.get_or_create(comic=comic, user=user)
|
status, created = ComicStatus.objects.get_or_create(comic=comic, user=user)
|
||||||
if created:
|
if created:
|
||||||
status.save()
|
status.save()
|
||||||
self.selector = urlsafe_base64_encode(comic.selector.bytes)
|
self.selector = urlsafe_base64_encode(comic.selector.bytes)
|
||||||
self.location = '/comic/read/{0}/{1}/'.format(self.selector,
|
self.location = "/comic/read/{0}/{1}/".format(self.selector, status.last_read_page)
|
||||||
status.last_read_page)
|
|
||||||
self.label = generate_label(comic, status)
|
self.label = generate_label(comic, status)
|
||||||
self.type = 'book'
|
self.type = "book"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'<DirFile: {self.name}: {self.type}>'
|
return f"<DirFile: {self.name}: {self.type}>"
|
||||||
|
|
||||||
|
|
||||||
def generate_directory(user, directory=False):
|
def generate_directory(user, directory=False):
|
||||||
@@ -126,7 +125,7 @@ def generate_directory(user, directory=False):
|
|||||||
:type user: User
|
:type user: User
|
||||||
:type directory: Directory
|
:type directory: Directory
|
||||||
"""
|
"""
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
files = []
|
files = []
|
||||||
if directory:
|
if directory:
|
||||||
ordered_dir_list = listdir(path.join(base_dir, directory.path))
|
ordered_dir_list = listdir(path.join(base_dir, directory.path))
|
||||||
@@ -136,15 +135,11 @@ def generate_directory(user, directory=False):
|
|||||||
dir_list = [x for x in ordered_dir_list if path.isdir(path.join(base_dir, x))]
|
dir_list = [x for x in ordered_dir_list if path.isdir(path.join(base_dir, x))]
|
||||||
file_list = [x for x in ordered_dir_list if x not in dir_list]
|
file_list = [x for x in ordered_dir_list if x not in dir_list]
|
||||||
if directory:
|
if directory:
|
||||||
dir_list_obj = Directory.objects.filter(name__in=dir_list,
|
dir_list_obj = Directory.objects.filter(name__in=dir_list, parent=directory)
|
||||||
parent=directory)
|
file_list_obj = ComicBook.objects.filter(file_name__in=file_list, directory=directory)
|
||||||
file_list_obj = ComicBook.objects.filter(file_name__in=file_list,
|
|
||||||
directory=directory)
|
|
||||||
else:
|
else:
|
||||||
dir_list_obj = Directory.objects.filter(name__in=dir_list,
|
dir_list_obj = Directory.objects.filter(name__in=dir_list, parent__isnull=True)
|
||||||
parent__isnull=True)
|
file_list_obj = ComicBook.objects.filter(file_name__in=file_list, directory__isnull=True)
|
||||||
file_list_obj = ComicBook.objects.filter(file_name__in=file_list,
|
|
||||||
directory__isnull=True)
|
|
||||||
for directory_obj in dir_list_obj:
|
for directory_obj in dir_list_obj:
|
||||||
df = DirFile()
|
df = DirFile()
|
||||||
df.populate_directory(directory_obj, user)
|
df.populate_directory(directory_obj, user)
|
||||||
@@ -159,8 +154,7 @@ def generate_directory(user, directory=False):
|
|||||||
file_list.remove(file_obj.file_name)
|
file_list.remove(file_obj.file_name)
|
||||||
for directory_name in dir_list:
|
for directory_name in dir_list:
|
||||||
if directory:
|
if directory:
|
||||||
directory_obj = Directory(name=directory_name,
|
directory_obj = Directory(name=directory_name, parent=directory)
|
||||||
parent=directory)
|
|
||||||
else:
|
else:
|
||||||
directory_obj = Directory(name=directory_name)
|
directory_obj = Directory(name=directory_name)
|
||||||
directory_obj.save()
|
directory_obj.save()
|
||||||
@@ -168,7 +162,7 @@ def generate_directory(user, directory=False):
|
|||||||
df.populate_directory(directory_obj, user)
|
df.populate_directory(directory_obj, user)
|
||||||
files.append(df)
|
files.append(df)
|
||||||
for file_name in file_list:
|
for file_name in file_list:
|
||||||
if file_name.lower()[-4:] in ['.rar', '.zip', '.cbr', '.cbz']:
|
if file_name.lower()[-4:] in [".rar", ".zip", ".cbr", ".cbz"]:
|
||||||
book = ComicBook.process_comic_book(file_name, directory)
|
book = ComicBook.process_comic_book(file_name, directory)
|
||||||
df = DirFile()
|
df = DirFile()
|
||||||
df.populate_comic(book, user)
|
df.populate_comic(book, user)
|
||||||
@@ -184,17 +178,17 @@ def generate_label(book, status):
|
|||||||
elif (status.last_read_page + 1) == book.page_count:
|
elif (status.last_read_page + 1) == book.page_count:
|
||||||
label_text = '<center><span class="label label-success">Read</span></center>'
|
label_text = '<center><span class="label label-success">Read</span></center>'
|
||||||
else:
|
else:
|
||||||
label_text = '<center><span class="label label-primary">%s/%s</span></center>' % \
|
label_text = '<center><span class="label label-primary">%s/%s</span></center>' % (
|
||||||
(status.last_read_page + 1, book.page_count)
|
status.last_read_page + 1,
|
||||||
|
book.page_count,
|
||||||
|
)
|
||||||
return label_text
|
return label_text
|
||||||
|
|
||||||
|
|
||||||
def generate_dir_status(user, directory):
|
def generate_dir_status(user, directory):
|
||||||
cb_list = ComicBook.objects.filter(directory=directory)
|
cb_list = ComicBook.objects.filter(directory=directory)
|
||||||
total = cb_list.count()
|
total = cb_list.count()
|
||||||
total_read = ComicStatus.objects.filter(user=user,
|
total_read = ComicStatus.objects.filter(user=user, comic__in=cb_list, finished=True).count()
|
||||||
comic__in=cb_list,
|
|
||||||
finished=True).count()
|
|
||||||
if total == 0:
|
if total == 0:
|
||||||
return '<center><span class="label label-default">Empty</span></center>'
|
return '<center><span class="label label-default">Empty</span></center>'
|
||||||
elif total == total_read:
|
elif total == total_read:
|
||||||
|
|||||||
359
comic/views.py
359
comic/views.py
@@ -18,8 +18,14 @@ from django.views.decorators.http import require_POST
|
|||||||
|
|
||||||
from .forms import SettingsForm, AccountForm, EditUserForm, AddUserForm, InitialSetupForm
|
from .forms import SettingsForm, AccountForm, EditUserForm, AddUserForm, InitialSetupForm
|
||||||
from .models import Setting, ComicBook, ComicStatus, Directory, ComicPage, UserMisc
|
from .models import Setting, ComicBook, ComicStatus, Directory, ComicPage, UserMisc
|
||||||
from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu, \
|
from .util import (
|
||||||
generate_title_from_path, Menu, generate_directory, generate_label
|
generate_breadcrumbs_from_path,
|
||||||
|
generate_breadcrumbs_from_menu,
|
||||||
|
generate_title_from_path,
|
||||||
|
Menu,
|
||||||
|
generate_directory,
|
||||||
|
generate_label,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
@@ -27,11 +33,11 @@ from .util import generate_breadcrumbs_from_path, generate_breadcrumbs_from_menu
|
|||||||
@login_required
|
@login_required
|
||||||
def comic_list(request, directory_selector=False):
|
def comic_list(request, directory_selector=False):
|
||||||
try:
|
try:
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR').value
|
base_dir = Setting.objects.get(name="BASE_DIR").value
|
||||||
except Setting.DoesNotExist:
|
except Setting.DoesNotExist:
|
||||||
return redirect('/comic/settings/')
|
return redirect("/comic/settings/")
|
||||||
if not path.isdir(base_dir):
|
if not path.isdir(base_dir):
|
||||||
return redirect('/comic/settings/')
|
return redirect("/comic/settings/")
|
||||||
|
|
||||||
if directory_selector:
|
if directory_selector:
|
||||||
selector = uuid.UUID(bytes=urlsafe_base64_decode(directory_selector))
|
selector = uuid.UUID(bytes=urlsafe_base64_decode(directory_selector))
|
||||||
@@ -42,18 +48,17 @@ def comic_list(request, directory_selector=False):
|
|||||||
if directory:
|
if directory:
|
||||||
title = generate_title_from_path(directory.path)
|
title = generate_title_from_path(directory.path)
|
||||||
breadcrumbs = generate_breadcrumbs_from_path(directory)
|
breadcrumbs = generate_breadcrumbs_from_path(directory)
|
||||||
json_url = '/comic/list_json/{0}/'.format(directory_selector)
|
json_url = "/comic/list_json/{0}/".format(directory_selector)
|
||||||
else:
|
else:
|
||||||
title = generate_title_from_path('Home')
|
title = generate_title_from_path("Home")
|
||||||
breadcrumbs = generate_breadcrumbs_from_path()
|
breadcrumbs = generate_breadcrumbs_from_path()
|
||||||
json_url = '/comic/list_json/'
|
json_url = "/comic/list_json/"
|
||||||
|
|
||||||
return render(request, 'comic/comic_list.html', {
|
return render(
|
||||||
'breadcrumbs': breadcrumbs,
|
request,
|
||||||
'menu': Menu(request.user, 'Browse'),
|
"comic/comic_list.html",
|
||||||
'title': title,
|
{"breadcrumbs": breadcrumbs, "menu": Menu(request.user, "Browse"), "title": title, "json_url": json_url},
|
||||||
'json_url': json_url
|
)
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -67,100 +72,99 @@ def comic_list_json(request, directory_selector=False):
|
|||||||
directory = False
|
directory = False
|
||||||
files = generate_directory(request.user, directory)
|
files = generate_directory(request.user, directory)
|
||||||
response_data = dict()
|
response_data = dict()
|
||||||
response_data['data'] = []
|
response_data["data"] = []
|
||||||
for file in files:
|
for file in files:
|
||||||
response_data['data'].append({
|
response_data["data"].append(
|
||||||
'blank': '',
|
{
|
||||||
'selector': file.selector,
|
"blank": "",
|
||||||
'type': file.type,
|
"selector": file.selector,
|
||||||
'icon': icon_str.format(file.icon),
|
"type": file.type,
|
||||||
'name': file.name,
|
"icon": icon_str.format(file.icon),
|
||||||
'label': file.label,
|
"name": file.name,
|
||||||
'url': file.location,
|
"label": file.label,
|
||||||
})
|
"url": file.location,
|
||||||
return HttpResponse(
|
}
|
||||||
json.dumps(response_data),
|
)
|
||||||
content_type="application/json"
|
return HttpResponse(json.dumps(response_data), content_type="application/json")
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def recent_comics(request):
|
def recent_comics(request):
|
||||||
feed_id, _ = UserMisc.objects.get_or_create(user=request.user)
|
feed_id, _ = UserMisc.objects.get_or_create(user=request.user)
|
||||||
|
|
||||||
return render(request,
|
return render(
|
||||||
'comic/recent_comics.html',
|
request,
|
||||||
{
|
"comic/recent_comics.html",
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu([('Recent', '/comic/recent/')]),
|
{
|
||||||
'menu': Menu(request.user, 'Recent'),
|
"breadcrumbs": generate_breadcrumbs_from_menu([("Recent", "/comic/recent/")]),
|
||||||
'title': 'Recent Comics',
|
"menu": Menu(request.user, "Recent"),
|
||||||
'feed_id': urlsafe_base64_encode(feed_id.feed_id.bytes),
|
"title": "Recent Comics",
|
||||||
})
|
"feed_id": urlsafe_base64_encode(feed_id.feed_id.bytes),
|
||||||
|
},
|
||||||
|
|
||||||
@login_required
|
|
||||||
@require_POST
|
|
||||||
def recent_comics_json(request):
|
|
||||||
start = int(request.POST['start'])
|
|
||||||
end = start + int(request.POST['length'])
|
|
||||||
icon = '<span class="glyphicon glyphicon-book"></span>'
|
|
||||||
comics = ComicBook.objects.all()
|
|
||||||
response_data = dict()
|
|
||||||
response_data['recordsTotal'] = comics.count()
|
|
||||||
if request.POST['search[value]']:
|
|
||||||
comics = comics.filter(file_name__contains=request.POST['search[value]'])
|
|
||||||
order_string = ''
|
|
||||||
# Ordering
|
|
||||||
if request.POST['order[0][dir]'] == 'desc':
|
|
||||||
order_string += '-'
|
|
||||||
if request.POST['order[0][dir]'] == '3':
|
|
||||||
order_string += 'date_added'
|
|
||||||
elif request.POST['order[0][dir]'] == '2':
|
|
||||||
order_string += 'date_added'
|
|
||||||
else:
|
|
||||||
order_string += 'date_added'
|
|
||||||
comics = comics.order_by(order_string)
|
|
||||||
response_data['recordsFiltered'] = comics.count()
|
|
||||||
response_data['data'] = list()
|
|
||||||
for book in comics[start:end]:
|
|
||||||
status, created = ComicStatus.objects.get_or_create(comic=book,
|
|
||||||
user=request.user)
|
|
||||||
if created:
|
|
||||||
status.save()
|
|
||||||
response_data['data'].append({
|
|
||||||
'selector': urlsafe_base64_encode(book.selector.bytes),
|
|
||||||
'icon': icon,
|
|
||||||
'type': 'book',
|
|
||||||
'name': book.file_name,
|
|
||||||
'date': book.date_added.strftime('%d/%m/%y-%H:%M'),
|
|
||||||
'label': generate_label(book, status),
|
|
||||||
'url': '/comic/read/{0}/{1}/'.format(urlsafe_base64_encode(book.selector.bytes),
|
|
||||||
status.last_read_page)
|
|
||||||
})
|
|
||||||
return HttpResponse(
|
|
||||||
json.dumps(response_data),
|
|
||||||
content_type="application/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@require_POST
|
||||||
|
def recent_comics_json(request):
|
||||||
|
start = int(request.POST["start"])
|
||||||
|
end = start + int(request.POST["length"])
|
||||||
|
icon = '<span class="glyphicon glyphicon-book"></span>'
|
||||||
|
comics = ComicBook.objects.all()
|
||||||
|
response_data = dict()
|
||||||
|
response_data["recordsTotal"] = comics.count()
|
||||||
|
if request.POST["search[value]"]:
|
||||||
|
comics = comics.filter(file_name__contains=request.POST["search[value]"])
|
||||||
|
order_string = ""
|
||||||
|
# Ordering
|
||||||
|
if request.POST["order[0][dir]"] == "desc":
|
||||||
|
order_string += "-"
|
||||||
|
if request.POST["order[0][dir]"] == "3":
|
||||||
|
order_string += "date_added"
|
||||||
|
elif request.POST["order[0][dir]"] == "2":
|
||||||
|
order_string += "date_added"
|
||||||
|
else:
|
||||||
|
order_string += "date_added"
|
||||||
|
comics = comics.order_by(order_string)
|
||||||
|
response_data["recordsFiltered"] = comics.count()
|
||||||
|
response_data["data"] = list()
|
||||||
|
for book in comics[start:end]:
|
||||||
|
status, created = ComicStatus.objects.get_or_create(comic=book, user=request.user)
|
||||||
|
if created:
|
||||||
|
status.save()
|
||||||
|
response_data["data"].append(
|
||||||
|
{
|
||||||
|
"selector": urlsafe_base64_encode(book.selector.bytes),
|
||||||
|
"icon": icon,
|
||||||
|
"type": "book",
|
||||||
|
"name": book.file_name,
|
||||||
|
"date": book.date_added.strftime("%d/%m/%y-%H:%M"),
|
||||||
|
"label": generate_label(book, status),
|
||||||
|
"url": "/comic/read/{0}/{1}/".format(
|
||||||
|
urlsafe_base64_encode(book.selector.bytes), status.last_read_page
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return HttpResponse(json.dumps(response_data), content_type="application/json")
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@require_POST
|
@require_POST
|
||||||
def comic_edit(request):
|
def comic_edit(request):
|
||||||
if 'selected' not in request.POST:
|
if "selected" not in request.POST:
|
||||||
return HttpResponse(status=200)
|
return HttpResponse(status=200)
|
||||||
if request.POST['func'] == 'choose':
|
if request.POST["func"] == "choose":
|
||||||
return HttpResponse(status=200)
|
return HttpResponse(status=200)
|
||||||
selected = [uuid.UUID(bytes=urlsafe_base64_decode(item)) for item in request.POST.getlist('selected')]
|
selected = [uuid.UUID(bytes=urlsafe_base64_decode(item)) for item in request.POST.getlist("selected")]
|
||||||
comics = ComicBook.objects.filter(selector__in=selected)
|
comics = ComicBook.objects.filter(selector__in=selected)
|
||||||
with atomic():
|
with atomic():
|
||||||
for comic in comics:
|
for comic in comics:
|
||||||
status, _ = ComicStatus.objects.get_or_create(comic=comic,
|
status, _ = ComicStatus.objects.get_or_create(comic=comic, user=request.user)
|
||||||
user=request.user)
|
if request.POST["func"] == "read":
|
||||||
if request.POST['func'] == 'read':
|
|
||||||
status.unread = False
|
status.unread = False
|
||||||
status.finished = True
|
status.finished = True
|
||||||
status.last_read_page = comic.page_count - 1
|
status.last_read_page = comic.page_count - 1
|
||||||
elif request.POST['func'] == 'unread':
|
elif request.POST["func"] == "unread":
|
||||||
status.unread = True
|
status.unread = True
|
||||||
status.finished = False
|
status.finished = False
|
||||||
status.last_read_page = 0
|
status.last_read_page = 0
|
||||||
@@ -174,44 +178,37 @@ def account_page(request):
|
|||||||
if request.POST:
|
if request.POST:
|
||||||
form = AccountForm(request.POST)
|
form = AccountForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
if form.cleaned_data['email'] != request.user.email:
|
if form.cleaned_data["email"] != request.user.email:
|
||||||
request.user.email = form.cleaned_data['email']
|
request.user.email = form.cleaned_data["email"]
|
||||||
success_message.append('Email Updated.')
|
success_message.append("Email Updated.")
|
||||||
if len(form.cleaned_data['password']) != 0:
|
if len(form.cleaned_data["password"]) != 0:
|
||||||
request.user.set_password(form.cleaned_data['password'])
|
request.user.set_password(form.cleaned_data["password"])
|
||||||
success_message.append('Password Updated.')
|
success_message.append("Password Updated.")
|
||||||
request.user.save()
|
request.user.save()
|
||||||
else:
|
else:
|
||||||
form = AccountForm(initial={
|
form = AccountForm(initial={"username": request.user.username, "email": request.user.email})
|
||||||
'username': request.user.username,
|
crumbs = [("Account", "/comic/account/")]
|
||||||
'email': request.user.email,
|
|
||||||
})
|
|
||||||
crumbs = [
|
|
||||||
('Account', '/comic/account/'),
|
|
||||||
]
|
|
||||||
context = {
|
context = {
|
||||||
'form': form,
|
"form": form,
|
||||||
'menu': Menu(request.user, 'Account'),
|
"menu": Menu(request.user, "Account"),
|
||||||
'error_message': form.errors,
|
"error_message": form.errors,
|
||||||
'success_message': '</br>'.join(success_message),
|
"success_message": "</br>".join(success_message),
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu(crumbs),
|
"breadcrumbs": generate_breadcrumbs_from_menu(crumbs),
|
||||||
'title': 'CBWebReader - Account',
|
"title": "CBWebReader - Account",
|
||||||
}
|
}
|
||||||
return render(request, 'comic/settings_page.html', context)
|
return render(request, "comic/settings_page.html", context)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(lambda u: u.is_superuser)
|
@user_passes_test(lambda u: u.is_superuser)
|
||||||
def users_page(request):
|
def users_page(request):
|
||||||
users = User.objects.all()
|
users = User.objects.all()
|
||||||
crumbs = [
|
crumbs = [("Users", "/comic/settings/users/")]
|
||||||
('Users', '/comic/settings/users/'),
|
|
||||||
]
|
|
||||||
context = {
|
context = {
|
||||||
'users': users,
|
"users": users,
|
||||||
'menu': Menu(request.user, 'Users'),
|
"menu": Menu(request.user, "Users"),
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu(crumbs),
|
"breadcrumbs": generate_breadcrumbs_from_menu(crumbs),
|
||||||
}
|
}
|
||||||
return render(request, 'comic/users_page.html', context)
|
return render(request, "comic/users_page.html", context)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(lambda u: u.is_superuser)
|
@user_passes_test(lambda u: u.is_superuser)
|
||||||
@@ -221,89 +218,78 @@ def user_config_page(request, user_id):
|
|||||||
if request.POST:
|
if request.POST:
|
||||||
form = EditUserForm(request.POST)
|
form = EditUserForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
if 'password' in form.cleaned_data:
|
if "password" in form.cleaned_data:
|
||||||
if len(form.cleaned_data['password']) != 0:
|
if len(form.cleaned_data["password"]) != 0:
|
||||||
user.set_password(form.cleaned_data['password'])
|
user.set_password(form.cleaned_data["password"])
|
||||||
success_message.append('Password Updated.')
|
success_message.append("Password Updated.")
|
||||||
if form.cleaned_data['email'] != user.email:
|
if form.cleaned_data["email"] != user.email:
|
||||||
user.email = form.cleaned_data['email']
|
user.email = form.cleaned_data["email"]
|
||||||
success_message.append('Email Updated.</br>')
|
success_message.append("Email Updated.</br>")
|
||||||
user.save()
|
user.save()
|
||||||
else:
|
else:
|
||||||
form = EditUserForm(initial=EditUserForm.get_initial_values(user))
|
form = EditUserForm(initial=EditUserForm.get_initial_values(user))
|
||||||
|
|
||||||
users = User.objects.all()
|
users = User.objects.all()
|
||||||
crumbs = [
|
crumbs = [("Users", "/comic/settings/users/"), (user.username, "/comic/settings/users/" + str(user.id))]
|
||||||
('Users', '/comic/settings/users/'),
|
|
||||||
(user.username, '/comic/settings/users/' + str(user.id)),
|
|
||||||
]
|
|
||||||
context = {
|
context = {
|
||||||
'form': form,
|
"form": form,
|
||||||
'users': users,
|
"users": users,
|
||||||
'menu': Menu(request.user, 'Users'),
|
"menu": Menu(request.user, "Users"),
|
||||||
'error_message': form.errors,
|
"error_message": form.errors,
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu(crumbs),
|
"breadcrumbs": generate_breadcrumbs_from_menu(crumbs),
|
||||||
'success_message': '</br>'.join(success_message),
|
"success_message": "</br>".join(success_message),
|
||||||
'title': 'CBWebReader - Edit User - ' + user.username,
|
"title": "CBWebReader - Edit User - " + user.username,
|
||||||
}
|
}
|
||||||
return render(request, 'comic/settings_page.html', context)
|
return render(request, "comic/settings_page.html", context)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(lambda u: u.is_superuser)
|
@user_passes_test(lambda u: u.is_superuser)
|
||||||
def user_add_page(request):
|
def user_add_page(request):
|
||||||
success_message = ''
|
success_message = ""
|
||||||
if request.POST:
|
if request.POST:
|
||||||
form = AddUserForm(request.POST)
|
form = AddUserForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
user = User(
|
user = User(username=form.cleaned_data["username"], email=form.cleaned_data["email"])
|
||||||
username=form.cleaned_data['username'],
|
user.set_password(form.cleaned_data["password"])
|
||||||
email=form.cleaned_data['email'],
|
|
||||||
)
|
|
||||||
user.set_password(form.cleaned_data['password'])
|
|
||||||
user.save()
|
user.save()
|
||||||
UserMisc.objects.create(user=user)
|
UserMisc.objects.create(user=user)
|
||||||
success_message = 'User {} created.'.format(user.username)
|
success_message = "User {} created.".format(user.username)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = AddUserForm()
|
form = AddUserForm()
|
||||||
crumbs = [
|
crumbs = [("Users", "/comic/settings/users/"), ("Add", "/comic/settings/users/add/")]
|
||||||
('Users', '/comic/settings/users/'),
|
|
||||||
('Add', '/comic/settings/users/add/'),
|
|
||||||
]
|
|
||||||
context = {
|
context = {
|
||||||
'form': form,
|
"form": form,
|
||||||
'menu': Menu(request.user, 'Users'),
|
"menu": Menu(request.user, "Users"),
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu(crumbs),
|
"breadcrumbs": generate_breadcrumbs_from_menu(crumbs),
|
||||||
'error_message': form.errors,
|
"error_message": form.errors,
|
||||||
'success_message': success_message,
|
"success_message": success_message,
|
||||||
'title': 'CBWebReader - Add User',
|
"title": "CBWebReader - Add User",
|
||||||
}
|
}
|
||||||
return render(request, 'comic/settings_page.html', context)
|
return render(request, "comic/settings_page.html", context)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(lambda u: u.is_superuser)
|
@user_passes_test(lambda u: u.is_superuser)
|
||||||
def settings_page(request):
|
def settings_page(request):
|
||||||
success_message = []
|
success_message = []
|
||||||
crumbs = [
|
crumbs = [("Settings", "/comic/settings/")]
|
||||||
('Settings', '/comic/settings/'),
|
|
||||||
]
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
form = SettingsForm(request.POST)
|
form = SettingsForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
base_dir = Setting.objects.get(name='BASE_DIR')
|
base_dir = Setting.objects.get(name="BASE_DIR")
|
||||||
base_dir.value = form.cleaned_data['base_dir']
|
base_dir.value = form.cleaned_data["base_dir"]
|
||||||
base_dir.save()
|
base_dir.save()
|
||||||
success_message.append('Settings updated.')
|
success_message.append("Settings updated.")
|
||||||
form = SettingsForm(initial=SettingsForm.get_initial_values())
|
form = SettingsForm(initial=SettingsForm.get_initial_values())
|
||||||
context = {
|
context = {
|
||||||
'error_message': form.errors,
|
"error_message": form.errors,
|
||||||
'success_message': '</br>'.join(success_message),
|
"success_message": "</br>".join(success_message),
|
||||||
'form': form,
|
"form": form,
|
||||||
'menu': Menu(request.user, 'Settings'),
|
"menu": Menu(request.user, "Settings"),
|
||||||
'title': 'CBWebReader - Settings',
|
"title": "CBWebReader - Settings",
|
||||||
'breadcrumbs': generate_breadcrumbs_from_menu(crumbs),
|
"breadcrumbs": generate_breadcrumbs_from_menu(crumbs),
|
||||||
}
|
}
|
||||||
return render(request, 'comic/settings_page.html', context)
|
return render(request, "comic/settings_page.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -317,21 +303,21 @@ def read_comic(request, comic_selector, page):
|
|||||||
status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user)
|
status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user)
|
||||||
status.unread = False
|
status.unread = False
|
||||||
status.last_read_page = page
|
status.last_read_page = page
|
||||||
if ComicPage.objects.filter(Comic=book).aggregate(Max('index'))['index__max'] == status.last_read_page:
|
if ComicPage.objects.filter(Comic=book).aggregate(Max("index"))["index__max"] == status.last_read_page:
|
||||||
status.finished = True
|
status.finished = True
|
||||||
else:
|
else:
|
||||||
status.finished = False
|
status.finished = False
|
||||||
status.save()
|
status.save()
|
||||||
title = 'CBWebReader - ' + book.file_name + ' - Page: ' + str(page)
|
title = "CBWebReader - " + book.file_name + " - Page: " + str(page)
|
||||||
context = {
|
context = {
|
||||||
'book': book,
|
"book": book,
|
||||||
'orig_file_name': book.page_name(page),
|
"orig_file_name": book.page_name(page),
|
||||||
'nav': book.nav(page, request.user),
|
"nav": book.nav(page, request.user),
|
||||||
'breadcrumbs': breadcrumbs,
|
"breadcrumbs": breadcrumbs,
|
||||||
'menu': Menu(request.user),
|
"menu": Menu(request.user),
|
||||||
'title': title,
|
"title": title,
|
||||||
}
|
}
|
||||||
return render(request, 'comic/read_comic.html', context)
|
return render(request, "comic/read_comic.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -344,34 +330,29 @@ def get_image(_, comic_selector, page):
|
|||||||
|
|
||||||
def initial_setup(request):
|
def initial_setup(request):
|
||||||
if User.objects.all().exists():
|
if User.objects.all().exists():
|
||||||
return redirect('/comic/')
|
return redirect("/comic/")
|
||||||
if request.POST:
|
if request.POST:
|
||||||
form = InitialSetupForm(request.POST)
|
form = InitialSetupForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
user = User(
|
user = User(
|
||||||
username=form.cleaned_data['username'],
|
username=form.cleaned_data["username"],
|
||||||
email=form.cleaned_data['email'],
|
email=form.cleaned_data["email"],
|
||||||
is_staff=True,
|
is_staff=True,
|
||||||
is_superuser=True,
|
is_superuser=True,
|
||||||
)
|
)
|
||||||
user.set_password(form.cleaned_data['password'])
|
user.set_password(form.cleaned_data["password"])
|
||||||
user.save()
|
user.save()
|
||||||
base_dir, _ = Setting.objects.get_or_create(name='BASE_DIR')
|
base_dir, _ = Setting.objects.get_or_create(name="BASE_DIR")
|
||||||
base_dir.value = form.cleaned_data['base_dir']
|
base_dir.value = form.cleaned_data["base_dir"]
|
||||||
base_dir.save()
|
base_dir.save()
|
||||||
user = authenticate(username=form.cleaned_data['username'],
|
user = authenticate(username=form.cleaned_data["username"], password=form.cleaned_data["password"])
|
||||||
password=form.cleaned_data['password'])
|
|
||||||
login(request, user)
|
login(request, user)
|
||||||
return redirect('/comic/')
|
return redirect("/comic/")
|
||||||
else:
|
else:
|
||||||
form = InitialSetupForm()
|
form = InitialSetupForm()
|
||||||
context = {
|
context = {"form": form, "title": "CBWebReader - Setup", "error_message": form.errors}
|
||||||
'form': form,
|
return render(request, "comic/settings_page.html", context)
|
||||||
'title': 'CBWebReader - Setup',
|
|
||||||
'error_message': form.errors,
|
|
||||||
}
|
|
||||||
return render(request, 'comic/settings_page.html', context)
|
|
||||||
|
|
||||||
|
|
||||||
def comic_redirect(_):
|
def comic_redirect(_):
|
||||||
return redirect('/comic/')
|
return redirect("/comic/")
|
||||||
|
|||||||
@@ -6,26 +6,19 @@ from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget
|
|||||||
|
|
||||||
class LoginForm(forms.Form):
|
class LoginForm(forms.Form):
|
||||||
|
|
||||||
username = forms.CharField(max_length=50,
|
username = forms.CharField(
|
||||||
label='',
|
max_length=50,
|
||||||
widget=forms.TextInput(
|
label="",
|
||||||
attrs={
|
widget=forms.TextInput(
|
||||||
'class': 'form-control',
|
attrs={"class": "form-control", "placeholder": "Username", "autofocus": True, "required": True}
|
||||||
'placeholder': 'Username',
|
),
|
||||||
'autofocus': True,
|
)
|
||||||
'required': True,
|
password = forms.CharField(
|
||||||
}
|
label="Password",
|
||||||
))
|
widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "Username", "required": True}),
|
||||||
password = forms.CharField(label='Password',
|
)
|
||||||
widget=forms.PasswordInput(
|
|
||||||
attrs={
|
|
||||||
'class': 'form-control',
|
|
||||||
'placeholder': 'Username',
|
|
||||||
'required': True,
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(LoginForm, self).__init__(*args, **kwargs)
|
super(LoginForm, self).__init__(*args, **kwargs)
|
||||||
if settings.CBREADER_USE_RECAPTCHA if hasattr(settings, 'CBREADER_USE_RECAPTCHA') else False:
|
if settings.CBREADER_USE_RECAPTCHA if hasattr(settings, "CBREADER_USE_RECAPTCHA") else False:
|
||||||
self.fields['captcha'] = ReCaptchaField(widget=ReCaptchaWidget())
|
self.fields["captcha"] = ReCaptchaField(widget=ReCaptchaWidget())
|
||||||
|
|||||||
@@ -9,45 +9,28 @@ def comic_login(request):
|
|||||||
if request.POST:
|
if request.POST:
|
||||||
form = LoginForm(request.POST)
|
form = LoginForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
user = authenticate(username=form.cleaned_data['username'],
|
user = authenticate(username=form.cleaned_data["username"], password=form.cleaned_data["password"])
|
||||||
password=form.cleaned_data['password'])
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
if user.is_active:
|
if user.is_active:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
if 'next' in request.GET:
|
if "next" in request.GET:
|
||||||
return redirect(request.GET['next'])
|
return redirect(request.GET["next"])
|
||||||
else:
|
else:
|
||||||
return redirect('/comic/')
|
return redirect("/comic/")
|
||||||
else:
|
else:
|
||||||
return render(request,
|
return render(request, "comic_auth/login.html", {"error": True})
|
||||||
'comic_auth/login.html',
|
|
||||||
{
|
|
||||||
'error': True,
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
return render(request,
|
return render(request, "comic_auth/login.html", {"error": True, "form": form})
|
||||||
'comic_auth/login.html',
|
|
||||||
{
|
|
||||||
'error': True,
|
|
||||||
'form': form
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
return render(request,
|
return render(request, "comic_auth/login.html", {"error": True, "form": form})
|
||||||
'comic_auth/login.html',
|
|
||||||
{
|
|
||||||
'error': True,
|
|
||||||
'form': form
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
if not User.objects.all().exists():
|
if not User.objects.all().exists():
|
||||||
return redirect('/setup/')
|
return redirect("/setup/")
|
||||||
form = LoginForm()
|
form = LoginForm()
|
||||||
context = {
|
context = {"form": form}
|
||||||
'form': form
|
return render(request, "comic_auth/login.html", context)
|
||||||
}
|
|
||||||
return render(request, 'comic_auth/login.html', context)
|
|
||||||
|
|
||||||
|
|
||||||
def comic_logout(request):
|
def comic_logout(request):
|
||||||
logout(request)
|
logout(request)
|
||||||
return redirect('/login/')
|
return redirect("/login/")
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ services:
|
|||||||
- database
|
- database
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
volumes:
|
# volumes:
|
||||||
- ./cbreader:/src/cbreader
|
# - ./cbreader:/src/cbreader
|
||||||
- ./comic:/src/comic
|
# - ./comic:/src/comic
|
||||||
- ./comic_auth:/src/comic_auth
|
# - ./comic_auth:/src/comic_auth
|
||||||
- ${COMIC_BOOK_VOLUME}:/data
|
# - ${COMIC_BOOK_VOLUME}:/data
|
||||||
command: python manage.py runserver 0.0.0.0:8000
|
command: python manage.py runserver 0.0.0.0:8000
|
||||||
|
|
||||||
database:
|
database:
|
||||||
|
|||||||
2
pyproject.toml
Normal file
2
pyproject.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[tool.black]
|
||||||
|
line_length = 119
|
||||||
17
setup.py
17
setup.py
@@ -1,12 +1,13 @@
|
|||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='cbwebreader',
|
name="cbwebreader",
|
||||||
version='',
|
version="",
|
||||||
packages=['comic', 'comic.migrations', 'cbreader', 'comic_auth', 'comic_auth.migrations'],
|
packages=["comic", "comic.migrations", "cbreader", "comic_auth", "comic_auth.migrations"],
|
||||||
url='https://github.com/ajurna/cbwebreader',
|
url="https://github.com/ajurna/cbwebreader",
|
||||||
license='http://creativecommons.org/licenses/by-sa/4.0/',
|
license="http://creativecommons.org/licenses/by-sa/4.0/",
|
||||||
author='Ajurna',
|
author="Ajurna",
|
||||||
author_email='ajurna@gmail.com',
|
author_email="ajurna@gmail.com",
|
||||||
description='Comic Book Web Reader', requires=['django-recaptcha', 'django', 'ujson']
|
description="Comic Book Web Reader",
|
||||||
|
requires=["django-recaptcha", "django", "ujson"],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user