expose more django server config options

This commit is contained in:
Nick Sweeting 2019-05-02 19:15:16 -04:00
parent d016f1efb5
commit 3c3b2ee621
8 changed files with 89 additions and 37 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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'),
]

View file

@ -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):

View file

@ -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():

View file

@ -190,7 +190,7 @@
</div>
<div class="col-sm-10" style="text-align: right">
<a href="/add/">Add Links</a> &nbsp; | &nbsp;
<a href="/admin/core/page/">Admin</a> &nbsp; | &nbsp;
<a href="/admin/core/snapshot/">Admin</a> &nbsp; | &nbsp;
<a href="https://github.com/pirate/ArchiveBox/wiki">Docs</a>
</div>
</div>

View file

@ -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