expose more django server config options
This commit is contained in:
parent
d016f1efb5
commit
3c3b2ee621
8 changed files with 89 additions and 37 deletions
|
@ -44,10 +44,19 @@ CONFIG_DEFAULTS: Dict[str, ConfigDefaultDict] = {
|
|||
'TIMEOUT': {'type': int, 'default': 60},
|
||||
'MEDIA_TIMEOUT': {'type': int, 'default': 3600},
|
||||
'OUTPUT_PERMISSIONS': {'type': str, 'default': '755'},
|
||||
'FOOTER_INFO': {'type': str, 'default': 'Content is hosted for personal archiving purposes only. Contact server owner for any takedown requests.'},
|
||||
'URL_BLACKLIST': {'type': str, 'default': None},
|
||||
},
|
||||
|
||||
'SERVER_CONFIG': {
|
||||
'SECRET_KEY': {'type': str, 'default': None},
|
||||
'ALLOWED_HOSTS': {'type': str, 'default': '*'},
|
||||
'DEBUG': {'type': bool, 'default': False},
|
||||
'PUBLIC_INDEX': {'type': bool, 'default': True},
|
||||
'PUBLIC_SNAPSHOTS': {'type': bool, 'default': True},
|
||||
'FOOTER_INFO': {'type': str, 'default': 'Content is hosted for personal archiving purposes only. Contact server owner for any takedown requests.'},
|
||||
'ACTIVE_THEME': {'type': str, 'default': 'default'},
|
||||
},
|
||||
|
||||
'ARCHIVE_METHOD_TOGGLES': {
|
||||
'SAVE_TITLE': {'type': bool, 'default': True, 'aliases': ('FETCH_TITLE',)},
|
||||
'SAVE_FAVICON': {'type': bool, 'default': True, 'aliases': ('FETCH_FAVICON',)},
|
||||
|
@ -313,9 +322,6 @@ def write_config_file(config: Dict[str, str], out_dir: str=None) -> ConfigDict:
|
|||
with open(config_path, 'w+') as f:
|
||||
f.write(CONFIG_HEADER)
|
||||
|
||||
if not config:
|
||||
return {}
|
||||
|
||||
config_file = ConfigParser()
|
||||
config_file.optionxform = str
|
||||
config_file.read(config_path)
|
||||
|
@ -336,6 +342,21 @@ def write_config_file(config: Dict[str, str], out_dir: str=None) -> ConfigDict:
|
|||
|
||||
config_file[section] = {**existing_config, key: val}
|
||||
|
||||
# always make sure there's a SECRET_KEY defined for Django
|
||||
existing_secret_key = None
|
||||
if 'SERVER_CONFIG' in config_file and 'SECRET_KEY' in config_file['SERVER_CONFIG']:
|
||||
existing_secret_key = config_file['SERVER_CONFIG']['SECRET_KEY']
|
||||
|
||||
if (not existing_secret_key) or ('not a valid secret' in existing_secret_key):
|
||||
from django.utils.crypto import get_random_string
|
||||
chars = 'abcdefghijklmnopqrstuvwxyz0123456789-_+!.'
|
||||
random_secret_key = get_random_string(50, chars)
|
||||
if 'SERVER_CONFIG' in config_file:
|
||||
config_file['SERVER_CONFIG']['SECRET_KEY'] = random_secret_key
|
||||
else:
|
||||
config_file['SERVER_CONFIG'] = {'SECRET_KEY': random_secret_key}
|
||||
|
||||
f.write(CONFIG_HEADER)
|
||||
config_file.write(f)
|
||||
|
||||
try:
|
||||
|
|
|
@ -22,9 +22,16 @@ class ConfigDict(BaseConfig, total=False):
|
|||
TIMEOUT: int
|
||||
MEDIA_TIMEOUT: int
|
||||
OUTPUT_PERMISSIONS: str
|
||||
FOOTER_INFO: str
|
||||
URL_BLACKLIST: Optional[str]
|
||||
|
||||
SECRET_KEY: str
|
||||
ALLOWED_HOSTS: str
|
||||
DEBUG: bool
|
||||
PUBLIC_INDEX: bool
|
||||
PUBLIC_SNAPSHOTS: bool
|
||||
FOOTER_INFO: str
|
||||
ACTIVE_THEME: str
|
||||
|
||||
SAVE_TITLE: bool
|
||||
SAVE_FAVICON: bool
|
||||
SAVE_WGET: bool
|
||||
|
|
|
@ -3,26 +3,25 @@ __package__ = 'archivebox.core'
|
|||
import os
|
||||
import sys
|
||||
|
||||
SECRET_KEY = '---------------- not a valid secret key ! ----------------'
|
||||
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
REPO_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), os.path.pardir, os.path.pardir))
|
||||
OUTPUT_DIR = os.path.abspath(os.getenv('OUTPUT_DIR', os.curdir))
|
||||
ARCHIVE_DIR = os.path.join(OUTPUT_DIR, 'archive')
|
||||
DATABASE_FILE = os.path.join(OUTPUT_DIR, 'index.sqlite3')
|
||||
from ..config import (
|
||||
OUTPUT_DIR,
|
||||
SECRET_KEY,
|
||||
DEBUG,
|
||||
ALLOWED_HOSTS,
|
||||
PYTHON_DIR,
|
||||
ACTIVE_THEME,
|
||||
SQL_INDEX_FILENAME,
|
||||
)
|
||||
|
||||
ACTIVE_THEME = 'default'
|
||||
|
||||
ALLOWED_HOSTS = ALLOWED_HOSTS.split(',')
|
||||
IS_SHELL = 'shell' in sys.argv[:3] or 'shell_plus' in sys.argv[:3]
|
||||
|
||||
APPEND_SLASH = True
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
# 'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.staticfiles',
|
||||
|
@ -40,17 +39,17 @@ MIDDLEWARE = [
|
|||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'core.urls'
|
||||
APPEND_SLASH = True
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [
|
||||
os.path.join(REPO_DIR, 'themes', ACTIVE_THEME),
|
||||
os.path.join(REPO_DIR, 'themes', 'default'),
|
||||
os.path.join(REPO_DIR, 'themes'),
|
||||
os.path.join(PYTHON_DIR, 'themes', ACTIVE_THEME),
|
||||
os.path.join(PYTHON_DIR, 'themes', 'default'),
|
||||
os.path.join(PYTHON_DIR, 'themes'),
|
||||
],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
|
@ -69,7 +68,7 @@ WSGI_APPLICATION = 'core.wsgi.application'
|
|||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': DATABASE_FILE,
|
||||
'NAME': os.path.join(OUTPUT_DIR, SQL_INDEX_FILENAME),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +103,7 @@ SHELL_PLUS_PRINT_SQL = False
|
|||
IPYTHON_ARGUMENTS = ['--no-confirm-exit', '--no-banner']
|
||||
IPYTHON_KERNEL_DISPLAY_NAME = 'ArchiveBox Django Shell'
|
||||
if IS_SHELL:
|
||||
os.environ['PYTHONSTARTUP'] = os.path.join(REPO_DIR, 'core', 'welcome_message.py')
|
||||
os.environ['PYTHONSTARTUP'] = os.path.join(PYTHON_DIR, 'core', 'welcome_message.py')
|
||||
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
@ -118,11 +117,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
|||
|
||||
STATIC_URL = '/static/'
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(REPO_DIR, 'themes', ACTIVE_THEME, 'static'),
|
||||
os.path.join(REPO_DIR, 'themes', 'default', 'static'),
|
||||
os.path.join(REPO_DIR, 'themes', 'static'),
|
||||
os.path.join(PYTHON_DIR, 'themes', ACTIVE_THEME, 'static'),
|
||||
os.path.join(PYTHON_DIR, 'themes', 'default', 'static'),
|
||||
os.path.join(PYTHON_DIR, 'themes', 'static'),
|
||||
]
|
||||
|
||||
SERVE_STATIC = True
|
||||
|
||||
|
||||
|
|
|
@ -22,8 +22,14 @@ urlpatterns = [
|
|||
path('add/', AddLinks.as_view(), name='AddLinks'),
|
||||
|
||||
path('static/<path>', views.serve),
|
||||
|
||||
path('accounts/login/', RedirectView.as_view(url='/admin/login/')),
|
||||
path('accounts/logout/', RedirectView.as_view(url='/admin/logout/')),
|
||||
|
||||
path('accounts/', include('django.contrib.auth.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
|
||||
path('', MainIndex.as_view(), name='Home'),
|
||||
]
|
||||
|
||||
|
|
|
@ -4,11 +4,18 @@ from django.shortcuts import render, redirect
|
|||
|
||||
from django.http import HttpResponse
|
||||
from django.views import View, static
|
||||
from django.conf import settings
|
||||
|
||||
from core.models import Snapshot
|
||||
|
||||
from ..index import load_main_index, load_main_index_meta
|
||||
from ..config import OUTPUT_DIR, VERSION, FOOTER_INFO
|
||||
from ..config import (
|
||||
OUTPUT_DIR,
|
||||
VERSION,
|
||||
FOOTER_INFO,
|
||||
PUBLIC_INDEX,
|
||||
PUBLIC_SNAPSHOTS,
|
||||
)
|
||||
from ..util import base_url
|
||||
|
||||
|
||||
|
@ -16,6 +23,9 @@ class MainIndex(View):
|
|||
template = 'main_index.html'
|
||||
|
||||
def get(self, request):
|
||||
if not request.user.is_authenticated and not PUBLIC_INDEX:
|
||||
return redirect(f'/admin/login/?next={request.path}')
|
||||
|
||||
all_links = load_main_index(out_dir=OUTPUT_DIR)
|
||||
meta_info = load_main_index_meta(out_dir=OUTPUT_DIR)
|
||||
|
||||
|
@ -34,6 +44,9 @@ class AddLinks(View):
|
|||
template = 'add_links.html'
|
||||
|
||||
def get(self, request):
|
||||
if not request.user.is_authenticated and not PUBLIC_INDEX:
|
||||
return redirect(f'/admin/login/?next={request.path}')
|
||||
|
||||
context = {}
|
||||
|
||||
return render(template_name=self.template, request=request, context=context)
|
||||
|
@ -54,6 +67,9 @@ class LinkDetails(View):
|
|||
if '/' not in path:
|
||||
return redirect(f'{path}/index.html')
|
||||
|
||||
if not request.user.is_authenticated and not PUBLIC_SNAPSHOTS:
|
||||
return redirect(f'/admin/login/?next={request.path}')
|
||||
|
||||
try:
|
||||
slug, archivefile = path.split('/', 1)
|
||||
except (IndexError, ValueError):
|
||||
|
|
|
@ -292,14 +292,14 @@ def init(force: bool=False, out_dir: str=OUTPUT_DIR) -> None:
|
|||
|
||||
setup_django(out_dir, check_db=False)
|
||||
from django.conf import settings
|
||||
assert settings.DATABASE_FILE == os.path.join(out_dir, SQL_INDEX_FILENAME)
|
||||
print(f' √ {settings.DATABASE_FILE}')
|
||||
DATABASE_FILE = os.path.join(out_dir, SQL_INDEX_FILENAME)
|
||||
print(f' √ {DATABASE_FILE}')
|
||||
print()
|
||||
for migration_line in apply_migrations(out_dir):
|
||||
print(f' {migration_line}')
|
||||
|
||||
|
||||
assert os.path.exists(settings.DATABASE_FILE)
|
||||
assert os.path.exists(DATABASE_FILE)
|
||||
|
||||
# from django.contrib.auth.models import User
|
||||
# if IS_TTY and not User.objects.filter(is_superuser=True).exists():
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
</div>
|
||||
<div class="col-sm-10" style="text-align: right">
|
||||
<a href="/add/">Add Links</a> |
|
||||
<a href="/admin/core/page/">Admin</a> |
|
||||
<a href="/admin/core/snapshot/">Admin</a> |
|
||||
<a href="https://github.com/pirate/ArchiveBox/wiki">Docs</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# This is the example default configiration file for ArchiveBox.
|
||||
#
|
||||
# Copy example config from here into your project's ArchiveBox.conf file,
|
||||
# Copy lines from here into your project's ArchiveBox.conf file and uncomment,
|
||||
# DO NOT EDIT THIS FILE DIRECTLY!
|
||||
#
|
||||
# See the list of all the possible options. documentation, and examples here:
|
||||
|
@ -11,10 +11,17 @@
|
|||
# ONLY_NEW = False
|
||||
# TIMEOUT = 60
|
||||
# MEDIA_TIMEOUT = 3600
|
||||
# ACTIVE_THEME = default
|
||||
# FOOTER_INFO = Content is hosted for personal archiving purposes only. Contact server owner for any takedown requests.
|
||||
# URL_BLACKLIST = (://(.*\.)?facebook\.com)|(://(.*\.)?ebay\.com)|(.*\.exe$)
|
||||
|
||||
[SERVER_CONFIG]
|
||||
# SECRET_KEY = ---------------- not a valid secret key ! ----------------
|
||||
# DEBUG = False
|
||||
# PUBLIC_INDEX = True
|
||||
# PUBLIC_SNAPSHOTS = True
|
||||
# FOOTER_INFO = Content is hosted for personal archiving purposes only. Contact server owner for any takedown requests.
|
||||
# ACTIVE_THEME = default
|
||||
|
||||
|
||||
[ARCHIVE_METHOD_TOGGLES]
|
||||
# SAVE_TITLE = True
|
||||
# SAVE_FAVICON = True
|
||||
|
|
Loading…
Reference in a new issue