pep257ifys core and api (#2245)

dont-set-build-state-on-exit
Fatema Boxwala 2016-06-02 18:40:45 -05:00 committed by Anthony
parent b5c8f87abe
commit d4762d9d0f
21 changed files with 76 additions and 63 deletions

View File

@ -34,6 +34,10 @@ mccabe:
pep257: pep257:
run: false run: false
disable:
- D105
- D211
- D104
pyflakes: pyflakes:
disable: disable:

View File

@ -19,13 +19,16 @@ log = logging.getLogger(__name__)
class SearchMixin(object): class SearchMixin(object):
'''
"""
Adds a search api to any ModelResource provided the model is indexed. Adds a search api to any ModelResource provided the model is indexed.
The search can be configured using the Meta class in each ModelResource. The search can be configured using the Meta class in each ModelResource.
The search is limited to the model defined by the meta queryset. If the The search is limited to the model defined by the meta queryset. If the
search is invalid, a 400 Bad Request will be raised. search is invalid, a 400 Bad Request will be raised.
e.g. e.g.
class Meta: class Meta:
# Return facet counts for each facetname # Return facet counts for each facetname
search_facets = ['facetname1', 'facetname1'] search_facets = ['facetname1', 'facetname1']
@ -35,7 +38,8 @@ class SearchMixin(object):
# Highlight search terms in the text # Highlight search terms in the text
search_highlight = True search_highlight = True
''' """
def get_search(self, request, **kwargs): def get_search(self, request, **kwargs):
self.method_check(request, allowed=['get']) self.method_check(request, allowed=['get'])
self.is_authenticated(request) self.is_authenticated(request)
@ -49,11 +53,12 @@ class SearchMixin(object):
return self.create_response(request, object_list) return self.create_response(request, object_list)
def _url_template(self, query, selected_facets): def _url_template(self, query, selected_facets):
''' """
Construct a url template to assist with navigating the resources. Construct a url template to assist with navigating the resources.
This looks a bit nasty but urllib.urlencode resulted in even This looks a bit nasty but urllib.urlencode resulted in even
nastier output... nastier output...
''' """
query_params = [] query_params = []
for facet in selected_facets: for facet in selected_facets:
query_params.append(('selected_facets', facet)) query_params.append(('selected_facets', facet))
@ -67,12 +72,13 @@ class SearchMixin(object):
def _search(self, request, model, facets=None, page_size=20, def _search(self, request, model, facets=None, page_size=20,
highlight=True): highlight=True):
''' """
`facets` `facets`
A list of facets to include with the results A list of facets to include with the results
`models` `models`
Limit the search to one or more models Limit the search to one or more models
''' """
form = FacetedSearchForm(request.GET, facets=facets or [], form = FacetedSearchForm(request.GET, facets=facets or [],
models=(model,), load_all=True) models=(model,), load_all=True)
if not form.is_valid(): if not form.is_valid():

View File

@ -42,17 +42,19 @@ class UserProfileForm(forms.ModelForm):
class FacetField(forms.MultipleChoiceField): class FacetField(forms.MultipleChoiceField):
''' """
For filtering searches on a facet, with validation for the format For filtering searches on a facet.
of facet values.
''' Has validation for the format of facet values.
"""
def valid_value(self, value): def valid_value(self, value):
''' """
Although this is a choice field, no choices need to be supplied. Although this is a choice field, no choices need to be supplied.
Instead, we just validate that the value is in the correct format Instead, we just validate that the value is in the correct format
for facet filtering (facet_name:value) for facet filtering (facet_name:value)
''' """
if ":" not in value: if ":" not in value:
return False return False
return True return True
@ -60,14 +62,14 @@ class FacetField(forms.MultipleChoiceField):
class FacetedSearchForm(SearchForm): class FacetedSearchForm(SearchForm):
''' """
Supports fetching faceted results with a corresponding query. Supports fetching faceted results with a corresponding query.
`facets` `facets`
A list of facet names for which to get facet counts A list of facet names for which to get facet counts
`models` `models`
Limit the search to one or more models Limit the search to one or more models
''' """
selected_facets = FacetField(required=False) selected_facets = FacetField(required=False)

View File

@ -10,8 +10,11 @@ log = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
"""Custom management command to rebuild documentation for all projects on
the site. Invoked via ``./manage.py update_repos``. """
Custom management command to rebuild documentation for all projects.
Invoked via ``./manage.py update_repos``.
""" """
def handle(self, *args, **options): def handle(self, *args, **options):

View File

@ -27,9 +27,7 @@ class Command(BaseCommand):
) )
def handle(self, *args, **options): def handle(self, *args, **options):
''' """Find stale builds and remove build paths"""
Find stale builds and remove build paths
'''
max_date = datetime.now() - timedelta(days=options['days']) max_date = datetime.now() - timedelta(days=options['days'])
queryset = (Build.objects queryset = (Build.objects
.values('project', 'version') .values('project', 'version')

View File

@ -22,9 +22,7 @@ class Command(BaseCommand):
) )
def handle(self, *args, **options): def handle(self, *args, **options):
''' """Build/index all versions or a single project's version"""
Build/index all versions or a single project's version
'''
project = options['project'] project = options['project']
queryset = Version.objects.public() queryset = Version.objects.public()

View File

@ -9,8 +9,11 @@ log = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
"""Custom management command to rebuild documentation for all projects on
the site. Invoked via ``./manage.py update_repos``. """
Custom management command to rebuild documentation for all projects.
Invoked via ``./manage.py update_repos``.
""" """
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (

View File

@ -9,6 +9,7 @@ log = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
""" """
Build documentation using the API and not hitting a database. Build documentation using the API and not hitting a database.

View File

@ -12,8 +12,10 @@ log = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
"""Custom management command to rebuild documentation for all projects on """
the site. Invoked via ``./manage.py update_repos``. Custom management command to rebuild documentation for all projects.
Invoked via ``./manage.py update_repos``.
""" """
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (

View File

@ -5,8 +5,11 @@ from readthedocs.projects.tasks import update_docs
class Command(BaseCommand): class Command(BaseCommand):
"""Custom management command to rebuild documentation for all projects on
the site. Invoked via ``./manage.py update_repos``. """
Custom management command to rebuild documentation for all projects.
Invoked via ``./manage.py update_repos``.
""" """
def handle(self, *args, **options): def handle(self, *args, **options):

View File

@ -178,6 +178,7 @@ class ProxyMiddleware(object):
""" """
Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the
latter is set. This is useful if you're sitting behind a reverse proxy that latter is set. This is useful if you're sitting behind a reverse proxy that
causes each request's REMOTE_ADDR to be set to 127.0.0.1. causes each request's REMOTE_ADDR to be set to 127.0.0.1.
Note that this does NOT validate HTTP_X_FORWARDED_FOR. If you're not behind Note that this does NOT validate HTTP_X_FORWARDED_FOR. If you're not behind
@ -207,6 +208,7 @@ class FooterNoSessionMiddleware(SessionMiddleware):
This will reduce the size of our session table drastically. This will reduce the size of our session table drastically.
""" """
IGNORE_URLS = ['/api/v2/footer_html', '/sustainability/view', '/sustainability/click'] IGNORE_URLS = ['/api/v2/footer_html', '/sustainability/view', '/sustainability/click']
def process_request(self, request): def process_request(self, request):

View File

@ -1,6 +1,4 @@
""" """Common mixin classes for views"""
Common mixin classes for views
"""
from vanilla import ListView from vanilla import ListView
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required

View File

@ -14,8 +14,8 @@ log = logging.getLogger(__name__)
class UserProfile (models.Model): class UserProfile (models.Model):
"""Additional information about a User. """Additional information about a User."""
"""
user = AutoOneToOneField('auth.User', verbose_name=_('User'), user = AutoOneToOneField('auth.User', verbose_name=_('User'),
related_name='profile') related_name='profile')
whitelisted = models.BooleanField(_('Whitelisted'), default=False) whitelisted = models.BooleanField(_('Whitelisted'), default=False)

View File

@ -69,6 +69,7 @@ log = logging.getLogger(__name__)
class Symlink(object): class Symlink(object):
"""Base class for symlinking of projects.""" """Base class for symlinking of projects."""
def __init__(self, project): def __init__(self, project):

View File

@ -14,10 +14,11 @@ register = template.Library()
@register.filter @register.filter
def gravatar(email, size=48): def gravatar(email, size=48):
"""hacked from djangosnippets.org, but basically given an email address """
hacked from djangosnippets.org, but basically given an email address
render an img tag with the hashed up bits needed for leetness render an img tag with the hashed up bits needed for leetness
omgwtfstillreading omgwtfstillreading
""" """
url = "http://www.gravatar.com/avatar.php?%s" % urllib.urlencode({ url = "http://www.gravatar.com/avatar.php?%s" % urllib.urlencode({
'gravatar_id': hashlib.md5(email).hexdigest(), 'gravatar_id': hashlib.md5(email).hexdigest(),

View File

@ -16,9 +16,7 @@ SYNC_USER = getattr(settings, 'SYNC_USER', getpass.getuser())
def run_on_app_servers(command): def run_on_app_servers(command):
""" """A helper to copy a single file across app servers"""
A helper to copy a single file across app servers
"""
log.info("Running %s on app servers" % command) log.info("Running %s on app servers" % command)
ret_val = 0 ret_val = 0
if getattr(settings, "MULTIPLE_APP_SERVERS", None): if getattr(settings, "MULTIPLE_APP_SERVERS", None):

View File

@ -14,25 +14,22 @@ STATUS_UPDATES_ENABLED = not getattr(settings, 'CELERY_ALWAYS_EAGER', False)
class PublicTask(Task): class PublicTask(Task):
""" """
See oauth.tasks for usage example. See oauth.tasks for usage example.
Subclasses need to define a ``run_public`` method. Subclasses need to define a ``run_public`` method.
""" """
public_name = 'unknown' public_name = 'unknown'
@classmethod @classmethod
def check_permission(cls, request, state, context): def check_permission(cls, request, state, context):
""" """Override this method to define who can monitor this task."""
Override this method to define who can monitor this task.
"""
return False return False
def get_task_data(self): def get_task_data(self):
""" """Return tuple with state to be set next and results task."""
Return a tuple with the state that should be set next and the results
task.
"""
state = 'STARTED' state = 'STARTED'
info = { info = {
'task_name': self.name, 'task_name': self.name,
@ -49,6 +46,7 @@ class PublicTask(Task):
def set_permission_context(self, context): def set_permission_context(self, context):
""" """
Set data that can be used by ``check_permission`` to authorize a Set data that can be used by ``check_permission`` to authorize a
request for the this task. By default it will be the ``kwargs`` passed request for the this task. By default it will be the ``kwargs`` passed
into the task. into the task.
""" """
@ -58,6 +56,7 @@ class PublicTask(Task):
def set_public_data(self, data): def set_public_data(self, data):
""" """
Set data that can be displayed in the frontend to authorized users. Set data that can be displayed in the frontend to authorized users.
This might include progress data about the task. This might include progress data about the task.
""" """
self.request.update(public_data=data) self.request.update(public_data=data)
@ -83,6 +82,7 @@ class PublicTask(Task):
def permission_check(check): def permission_check(check):
""" """
Class decorator for subclasses of PublicTask to sprinkle in re-usable Class decorator for subclasses of PublicTask to sprinkle in re-usable
permission checks:: permission checks::
@permission_check(user_id_matches) @permission_check(user_id_matches)
@ -90,7 +90,6 @@ def permission_check(check):
def run_public(self, user_id): def run_public(self, user_id):
pass pass
""" """
def decorator(cls): def decorator(cls):
cls.check_permission = staticmethod(check) cls.check_permission = staticmethod(check)
return cls return cls

View File

@ -14,9 +14,9 @@ class TaskNotFound(Exception):
def get_task_data(task_id): def get_task_data(task_id):
""" """
Will raise `TaskNotFound` if the task is in state ``PENDING`` or the task Will raise `TaskNotFound` if the task is in state ``PENDING`` or the task
meta data has no ``'task_name'`` key set. meta data has no ``'task_name'`` key set.
""" """
result = AsyncResult(task_id) result = AsyncResult(task_id)
state, info = result.state, result.info state, info = result.state, result.info
if state == 'PENDING': if state == 'PENDING':

View File

@ -1,5 +1,6 @@
""" """
Core views, including the main homepage, Core views, including the main homepage,
documentation and header rendering, and server errors. documentation and header rendering, and server errors.
""" """
@ -37,7 +38,7 @@ class HomepageView(DonateProgressMixin, TemplateView):
template_name = 'homepage.html' template_name = 'homepage.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
'''Add latest builds and featured projects''' """Add latest builds and featured projects"""
context = super(HomepageView, self).get_context_data(**kwargs) context = super(HomepageView, self).get_context_data(**kwargs)
latest = [] latest = []
latest_builds = ( latest_builds = (
@ -107,9 +108,7 @@ def divide_by_zero(request):
def server_error(request, template_name='500.html'): def server_error(request, template_name='500.html'):
""" """A simple 500 handler so we get media"""
A simple 500 handler so we get media
"""
r = render_to_response(template_name, r = render_to_response(template_name,
context_instance=RequestContext(request)) context_instance=RequestContext(request))
r.status_code = 500 r.status_code = 500
@ -117,9 +116,7 @@ def server_error(request, template_name='500.html'):
def server_error_404(request, template_name='404.html'): def server_error_404(request, template_name='404.html'):
""" """A simple 404 handler so we get media"""
A simple 404 handler so we get media
"""
response = get_redirect_response(request, path=request.get_full_path()) response = get_redirect_response(request, path=request.get_full_path())
if response: if response:
return response return response
@ -132,6 +129,7 @@ def server_error_404(request, template_name='404.html'):
class SendEmailView(FormView): class SendEmailView(FormView):
"""Form view for sending emails to users from admin pages """Form view for sending emails to users from admin pages
Accepts the following additional parameters: Accepts the following additional parameters:
queryset queryset
The queryset to use to determine the users to send emails to The queryset to use to determine the users to send emails to
@ -142,6 +140,7 @@ class SendEmailView(FormView):
def get_form_kwargs(self): def get_form_kwargs(self):
"""Override form kwargs based on input fields """Override form kwargs based on input fields
The admin posts to this view initially, so detect the send button on The admin posts to this view initially, so detect the send button on
form post variables. Drop additional fields if we see the send button. form post variables. Drop additional fields if we see the send button.
""" """
@ -189,6 +188,7 @@ class SendEmailView(FormView):
def message_user(self, message, level=messages.INFO, extra_tags='', def message_user(self, message, level=messages.INFO, extra_tags='',
fail_silently=False): fail_silently=False):
"""Implementation of :py:meth:`django.contrib.admin.options.ModelAdmin.message_user` """Implementation of :py:meth:`django.contrib.admin.options.ModelAdmin.message_user`
Send message through messages framework Send message through messages framework
""" """
# TODO generalize this or check if implementation in ModelAdmin is # TODO generalize this or check if implementation in ModelAdmin is

View File

@ -136,9 +136,7 @@ def _build_url(url, projects, branches):
@csrf_exempt @csrf_exempt
def github_build(request): def github_build(request):
""" """A post-commit hook for github."""
A post-commit hook for github.
"""
if request.method == 'POST': if request.method == 'POST':
try: try:
# GitHub RTD integration # GitHub RTD integration
@ -176,9 +174,7 @@ def github_build(request):
@csrf_exempt @csrf_exempt
def gitlab_build(request): def gitlab_build(request):
""" """A post-commit hook for GitLab."""
A post-commit hook for GitLab.
"""
if request.method == 'POST': if request.method == 'POST':
try: try:
# GitLab RTD integration # GitLab RTD integration

View File

@ -134,9 +134,7 @@ def _serve_file(request, filename, basepath):
@map_subproject_slug @map_subproject_slug
def serve_docs(request, project, subproject, def serve_docs(request, project, subproject,
lang_slug=None, version_slug=None, filename=''): lang_slug=None, version_slug=None, filename=''):
""" """Exists to map existing proj, lang, version, filename views to the file format."""
This exists mainly to map existing proj, lang, version, filename views to the file format.
"""
if not version_slug: if not version_slug:
version_slug = project.get_default_version() version_slug = project.get_default_version()
try: try: