Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardizing the use of settings directly #5632

Merged
merged 11 commits into from May 9, 2019
21 changes: 8 additions & 13 deletions readthedocs/api/v2/client.py
Expand Up @@ -12,11 +12,6 @@

log = logging.getLogger(__name__)

PRODUCTION_DOMAIN = settings.PRODUCTION_DOMAIN
API_HOST = settings.SLUMBER_API_HOST
USER = settings.SLUMBER_USERNAME
PASS = settings.SLUMBER_PASSWORD


class DrfJsonSerializer(serialize.JsonSerializer):

Expand All @@ -31,7 +26,7 @@ def dumps(self, data):

def setup_api():
session = requests.Session()
if API_HOST.startswith('https'):
if settings.SLUMBER_API_HOST.startswith('https'):
# Only use the HostHeaderSSLAdapter for HTTPS connections
adapter_class = host_header_ssl.HostHeaderSSLAdapter
else:
Expand All @@ -50,12 +45,12 @@ def setup_api():
)

session.mount(
API_HOST,
settings.SLUMBER_API_HOST,
adapter_class(max_retries=retry),
)
session.headers.update({'Host': PRODUCTION_DOMAIN})
session.headers.update({'Host': settings.PRODUCTION_DOMAIN})
api_config = {
'base_url': '%s/api/v2/' % API_HOST,
'base_url': '%s/api/v2/' % settings.SLUMBER_API_HOST,
'serializer': serialize.Serializer(
default='json-drf',
serializers=[
Expand All @@ -65,13 +60,13 @@ def setup_api():
),
'session': session,
}
if USER and PASS:
if settings.SLUMBER_USERNAME and settings.SLUMBER_PASSWORD:
log.debug(
'Using slumber v2 with user %s, pointed at %s',
USER,
API_HOST,
settings.SLUMBER_USERNAME,
settings.SLUMBER_API_HOST,
)
session.auth = (USER, PASS)
session.auth = (settings.SLUMBER_USERNAME, settings.SLUMBER_PASSWORD)
else:
log.warning('SLUMBER_USERNAME/PASSWORD settings are not set')
return API(**api_config)
Expand Down
4 changes: 1 addition & 3 deletions readthedocs/builds/models.py
Expand Up @@ -50,8 +50,6 @@
from .version_slug import VersionSlugField


DEFAULT_VERSION_PRIVACY_LEVEL = settings.DEFAULT_VERSION_PRIVACY_LEVEL

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -102,7 +100,7 @@ class Version(models.Model):
_('Privacy Level'),
max_length=20,
choices=PRIVACY_CHOICES,
default=DEFAULT_VERSION_PRIVACY_LEVEL,
default=settings.DEFAULT_VERSION_PRIVACY_LEVEL,
help_text=_('Level of privacy for this Version.'),
)
tags = TaggableManager(blank=True)
Expand Down
27 changes: 13 additions & 14 deletions readthedocs/builds/syncers.py
Expand Up @@ -63,13 +63,15 @@ def copy(cls, path, target, is_file=False, **kwargs):

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
app_servers = settings.MULTIPLE_APP_SERVERS
if app_servers:
log.info('Remote Copy %s to %s on %s', path, target, app_servers)
for server in app_servers:
if settings.MULTIPLE_APP_SERVERS:
log.info(
'Remote Copy %s to %s on %s',
path, target,
settings.MULTIPLE_APP_SERVERS
)
for server in settings.MULTIPLE_APP_SERVERS:
mkdir_cmd = (
'ssh {}@{} mkdir -p {}'.format(sync_user, server, target)
'ssh {}@{} mkdir -p {}'.format(settings.SYNC_USER, server, target)
)
ret = os.system(mkdir_cmd)
if ret != 0:
Expand All @@ -83,7 +85,7 @@ def copy(cls, path, target, is_file=False, **kwargs):
"rsync -e 'ssh -T' -av --delete {path}{slash} {user}@{server}:{target}".format(
path=path,
slash=slash,
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -102,15 +104,13 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
app_servers = settings.MULTIPLE_APP_SERVERS
if not is_file:
path += '/'
log.info('Remote Copy %s to %s', path, target)
for server in app_servers:
for server in settings.MULTIPLE_APP_SERVERS:
if not is_file:
mkdir_cmd = 'ssh {user}@{server} mkdir -p {target}'.format(
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -123,7 +123,7 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a
"--delete --exclude projects {user}@{host}:{path} {target}'".format(
host=host,
path=path,
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -142,7 +142,6 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
if not is_file:
path += '/'
log.info('Remote Pull %s to %s', path, target)
Expand All @@ -156,7 +155,7 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a
sync_cmd = "rsync -e 'ssh -T' -av --delete {user}@{host}:{path} {target}".format(
host=host,
path=path,
user=sync_user,
user=settings.SYNC_USER,
target=target,
)
ret = os.system(sync_cmd)
Expand Down
30 changes: 12 additions & 18 deletions readthedocs/config/config.py
Expand Up @@ -66,13 +66,6 @@
INVALID_KEYS_COMBINATION = 'invalid-keys-combination'
INVALID_KEY = 'invalid-key'

DOCKER_DEFAULT_IMAGE = settings.DOCKER_DEFAULT_IMAGE
DOCKER_DEFAULT_VERSION = settings.DOCKER_DEFAULT_VERSION
# These map to corresponding settings in the .org,
# so they haven't been renamed.
DOCKER_IMAGE = settings.DOCKER_IMAGE
DOCKER_IMAGE_SETTINGS = settings.DOCKER_IMAGE_SETTINGS

LATEST_CONFIGURATION_VERSION = 2


Expand Down Expand Up @@ -159,7 +152,8 @@ class BuildConfigBase:
'submodules',
]

default_build_image = DOCKER_DEFAULT_VERSION
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one can stay

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different configuration files can have a different default image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay

default_build_image = settings.DOCKER_DEFAULT_VERSION

version = None

def __init__(self, env_config, raw_config, source_file):
Expand Down Expand Up @@ -268,7 +262,7 @@ def valid_build_images(self):
``readthedocs/build`` part) plus ``stable`` and ``latest``.
"""
images = {'stable', 'latest'}
for k in DOCKER_IMAGE_SETTINGS:
for k in settings.DOCKER_IMAGE_SETTINGS:
_, version = k.split(':')
if re.fullmatch(r'^[\d\.]+$', version):
images.add(version)
Expand All @@ -284,12 +278,12 @@ def get_valid_python_versions_for_image(self, build_image):
Returns supported versions for the ``DOCKER_DEFAULT_VERSION`` if not
``build_image`` found.
"""
if build_image not in DOCKER_IMAGE_SETTINGS:
if build_image not in settings.DOCKER_IMAGE_SETTINGS:
build_image = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_IMAGE,
self.default_build_image,
)
return DOCKER_IMAGE_SETTINGS[build_image]['python']['supported_versions']
return settings.DOCKER_IMAGE_SETTINGS[build_image]['python']['supported_versions']

def as_dict(self):
config = {}
Expand Down Expand Up @@ -326,7 +320,7 @@ def get_valid_python_versions(self):
return self.env_config['python']['supported_versions']
except (KeyError, TypeError):
versions = set()
for _, options in DOCKER_IMAGE_SETTINGS.items():
for _, options in settings.DOCKER_IMAGE_SETTINGS.items():
versions = versions.union(
options['python']['supported_versions']
)
Expand Down Expand Up @@ -381,7 +375,7 @@ def validate_build(self):
if 'build' in self.env_config:
build = self.env_config['build'].copy()
else:
build = {'image': DOCKER_IMAGE}
build = {'image': settings.DOCKER_IMAGE}

# User specified
if 'build' in self.raw_config:
Expand All @@ -395,12 +389,12 @@ def validate_build(self):
if ':' not in build['image']:
# Prepend proper image name to user's image name
build['image'] = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_IMAGE,
build['image'],
)
# Update docker default settings from image name
if build['image'] in DOCKER_IMAGE_SETTINGS:
self.env_config.update(DOCKER_IMAGE_SETTINGS[build['image']])
if build['image'] in settings.DOCKER_IMAGE_SETTINGS:
self.env_config.update(settings.DOCKER_IMAGE_SETTINGS[build['image']])

# Allow to override specific project
config_image = self.defaults.get('build_image')
Expand Down Expand Up @@ -702,7 +696,7 @@ def validate_build(self):
with self.catch_validation_error('build.image'):
image = self.pop_config('build.image', self.default_build_image)
build['image'] = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_IMAGE,
validate_choice(
image,
self.valid_build_images,
Expand Down
19 changes: 9 additions & 10 deletions readthedocs/core/middleware.py
Expand Up @@ -15,8 +15,6 @@
log = logging.getLogger(__name__)

LOG_TEMPLATE = '(Middleware) %(msg)s [%(host)s%(path)s]'
SUBDOMAIN_URLCONF = settings.SUBDOMAIN_URLCONF
SINGLE_VERSION_URLCONF = settings.SINGLE_VERSION_URLCONF


class SubdomainMiddleware(MiddlewareMixin):
Expand All @@ -38,10 +36,9 @@ def process_request(self, request):
path = request.get_full_path()
log_kwargs = dict(host=host, path=path)
public_domain = settings.PUBLIC_DOMAIN
production_domain = settings.PRODUCTION_DOMAIN

if public_domain is None:
public_domain = production_domain
public_domain = settings.PRODUCTION_DOMAIN
if ':' in host:
host = host.split(':')[0]
domain_parts = host.split('.')
Expand All @@ -57,21 +54,23 @@ def process_request(self, request):
raise Http404(_('Project not found'))
request.subdomain = True
request.slug = subdomain
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
return None

# Serve CNAMEs
if (
public_domain not in host and production_domain not in host and
'localhost' not in host and 'testserver' not in host
public_domain not in host and
settings.PRODUCTION_DOMAIN not in host and
'localhost' not in host and
'testserver' not in host
):
request.cname = True
domains = Domain.objects.filter(domain=host)
if domains.count():
for domain in domains:
if domain.domain == host:
request.slug = domain.project.slug
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
request.domain_object = True
log.debug(
LOG_TEMPLATE,
Expand All @@ -86,7 +85,7 @@ def process_request(self, request):
'HTTP_X_RTD_SLUG' in request.META
):
request.slug = request.META['HTTP_X_RTD_SLUG'].lower()
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
request.rtdheader = True
log.debug(
LOG_TEMPLATE,
Expand Down Expand Up @@ -171,7 +170,7 @@ def process_request(self, request):
return None

if getattr(proj, 'single_version', False):
request.urlconf = SINGLE_VERSION_URLCONF
request.urlconf = settings.SINGLE_VERSION_URLCONF
# Logging
host = request.get_host()
path = request.get_full_path()
Expand Down
14 changes: 5 additions & 9 deletions readthedocs/core/resolver.py
Expand Up @@ -180,16 +180,15 @@ def resolve(
else:
domain = settings.PRODUCTION_DOMAIN

public_domain = settings.PUBLIC_DOMAIN
use_https = settings.PUBLIC_DOMAIN_USES_HTTPS

use_https_protocol = any([
# Rely on the ``Domain.https`` field
use_custom_domain and custom_domain.https,
# or force it if specified
require_https,
# or fallback to settings
use_https and public_domain and public_domain in domain,
settings.PUBLIC_DOMAIN_USES_HTTPS and
settings.PUBLIC_DOMAIN and
settings.PUBLIC_DOMAIN in domain,
])
protocol = 'https' if use_https_protocol else 'http'

Expand Down Expand Up @@ -229,11 +228,10 @@ def _get_canonical_project(self, project, projects=None):

def _get_project_subdomain(self, project):
"""Determine canonical project domain as subdomain."""
public_domain = settings.PUBLIC_DOMAIN
if self._use_subdomain():
project = self._get_canonical_project(project)
subdomain_slug = project.slug.replace('_', '-')
return '{}.{}'.format(subdomain_slug, public_domain)
return '{}.{}'.format(subdomain_slug, settings.PUBLIC_DOMAIN)

def _get_private(self, project, version_slug):
from readthedocs.builds.models import Version
Expand Down Expand Up @@ -266,9 +264,7 @@ def _use_custom_domain(self, custom_domain):

def _use_subdomain(self):
"""Make decision about whether to use a subdomain to serve docs."""
use_subdomain = settings.USE_SUBDOMAIN
public_domain = settings.PUBLIC_DOMAIN
return use_subdomain and public_domain is not None
return settings.USE_SUBDOMAIN and settings.PUBLIC_DOMAIN is not None


class Resolver(SettingsOverrideObject):
Expand Down
2 changes: 0 additions & 2 deletions readthedocs/core/utils/__init__.py
Expand Up @@ -20,8 +20,6 @@

log = logging.getLogger(__name__)

SYNC_USER = settings.SYNC_USER


def broadcast(type, task, args, kwargs=None, callback=None): # pylint: disable=redefined-builtin
"""
Expand Down
6 changes: 2 additions & 4 deletions readthedocs/core/views/serve.py
Expand Up @@ -242,17 +242,15 @@ def _serve_symlink_docs(request, project, privacy_level, filename=''):

files_tried = []

serve_docs = settings.SERVE_DOCS

if (settings.DEBUG or constants.PUBLIC in serve_docs) and privacy_level != constants.PRIVATE: # yapf: disable # noqa
if (settings.DEBUG or constants.PUBLIC in settings.SERVE_DOCS) and privacy_level != constants.PRIVATE: # yapf: disable # noqa
public_symlink = PublicSymlink(project)
basepath = public_symlink.project_root
if os.path.exists(os.path.join(basepath, filename)):
return _serve_file(request, filename, basepath)

files_tried.append(os.path.join(basepath, filename))

if (settings.DEBUG or constants.PRIVATE in serve_docs) and privacy_level == constants.PRIVATE: # yapf: disable # noqa
if (settings.DEBUG or constants.PRIVATE in settings.SERVE_DOCS) and privacy_level == constants.PRIVATE: # yapf: disable # noqa
# Handle private
private_symlink = PrivateSymlink(project)
basepath = private_symlink.project_root
Expand Down
3 changes: 1 addition & 2 deletions readthedocs/notifications/backends.py
Expand Up @@ -26,8 +26,7 @@ def send_notification(request, notification):
should be a list of class paths to be loaded, using the standard Django
string module loader.
"""
backends = settings.NOTIFICATION_BACKENDS
for cls_name in backends:
for cls_name in settings.NOTIFICATION_BACKENDS:
backend = import_string(cls_name)(request)
backend.send(notification)

Expand Down