Skip to content

Commit 326c014

Browse files
committed
2 parents 91a64cb + 4693f9e commit 326c014

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+333
-164
lines changed

docs/conda.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ You can enable it by creating a `readthedocs.yml` file in the root of your repos
2525
This Conda environment will also have Sphinx and other build time dependencies installed.
2626
It will use the same order of operations that we support currently:
2727

28-
* Environment Creation (``conda create``)
28+
* Environment Creation (``conda env create``)
2929
* Dependency Installation (Sphinx)
30-
* User Package Installation (``conda env update``)
3130

3231
Custom Installs
3332
---------------

prospector-more.yml

-12
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,13 @@ inherits: prospector
33
strictness: medium
44

55
ignore-paths:
6-
- api/
7-
- bookmarks/
8-
- builds/
9-
- cdn/
10-
- comments/
116
- core/
127
- doc_builder/
138
- donate/
14-
- gold/
15-
- notifications/
16-
- payments/
17-
- privacy/
18-
- profiles/
199
- projects/
2010
- redirects/
2111
- restapi/
22-
- rtd_tests/
2312
- search/
24-
- settings/
2513

2614
pylint:
2715
options:

readthedocs/api/base.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
"""API resources"""
12
import logging
23
import json
34
import redis
45

56
from django.contrib.auth.models import User
6-
from django.conf import settings
77
from django.conf.urls import url
88
from django.shortcuts import get_object_or_404
99
from django.core.cache import cache
@@ -16,7 +16,7 @@
1616
from tastypie.utils import dict_strip_unicode_keys, trailing_slash
1717

1818
from readthedocs.builds.constants import LATEST
19-
from readthedocs.builds.models import Build, Version
19+
from readthedocs.builds.models import Version
2020
from readthedocs.core.utils import trigger_build
2121
from readthedocs.projects.models import Project, ImportedFile
2222
from readthedocs.restapi.views.footer_views import get_version_compare_data
@@ -27,6 +27,9 @@
2727

2828

2929
class ProjectResource(ModelResource, SearchMixin):
30+
31+
"""API resource for Project model."""
32+
3033
users = fields.ToManyField('readthedocs.api.base.UserResource', 'users')
3134

3235
class Meta(object):
@@ -115,6 +118,9 @@ def override_urls(self):
115118

116119

117120
class VersionResource(ModelResource):
121+
122+
"""API resource for Version model."""
123+
118124
project = fields.ForeignKey(ProjectResource, 'project', full=True)
119125

120126
class Meta(object):
@@ -133,7 +139,7 @@ def get_object_list(self, request):
133139
self._meta.queryset = Version.objects.api(user=request.user)
134140
return super(VersionResource, self).get_object_list(request)
135141

136-
def version_compare(self, request, project_slug, base=None, **kwargs):
142+
def version_compare(self, request, project_slug, base=None, **__):
137143
project = get_object_or_404(Project, slug=project_slug)
138144
if base and base != LATEST:
139145
try:
@@ -180,6 +186,9 @@ def override_urls(self):
180186

181187

182188
class FileResource(ModelResource, SearchMixin):
189+
190+
"""API resource for ImportedFile model."""
191+
183192
project = fields.ForeignKey(ProjectResource, 'project', full=True)
184193

185194
class Meta(object):
@@ -207,7 +216,7 @@ def override_urls(self):
207216
name="api_get_anchor"),
208217
]
209218

210-
def get_anchor(self, request, **kwargs):
219+
def get_anchor(self, request, **__):
211220
self.method_check(request, allowed=['get'])
212221
self.is_authenticated(request)
213222
self.throttle_check(request)
@@ -229,6 +238,8 @@ def get_anchor(self, request, **kwargs):
229238

230239
class UserResource(ModelResource):
231240

241+
"""Read-only API resource for User model."""
242+
232243
class Meta(object):
233244
allowed_methods = ['get']
234245
queryset = User.objects.all()

readthedocs/api/client.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
"""Slumber API client"""
12
import logging
23

3-
from slumber import API, serialize
4+
from slumber import API
45
from requests import Session
56
from django.conf import settings
67

@@ -21,7 +22,7 @@ def setup_api():
2122
'session': session,
2223
}
2324
if USER and PASS:
24-
log.debug("Using slumber with user %s, pointed at %s" % (USER, API_HOST))
25+
log.debug("Using slumber with user %s, pointed at %s", USER, API_HOST)
2526
session.auth = (USER, PASS)
2627
else:
2728
log.warning("SLUMBER_USERNAME/PASSWORD settings are not set")

readthedocs/api/utils.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Utility classes for api module"""
12
import logging
23

34
from django.core.paginator import Paginator, InvalidPage
@@ -40,7 +41,7 @@ class Meta:
4041
search_highlight = True
4142
"""
4243

43-
def get_search(self, request, **kwargs):
44+
def get_search(self, request):
4445
self.method_check(request, allowed=['get'])
4546
self.is_authenticated(request)
4647
self.throttle_check(request)
@@ -72,12 +73,14 @@ def _url_template(self, query, selected_facets):
7273

7374
def _search(self, request, model, facets=None, page_size=20,
7475
highlight=True):
76+
# pylint: disable=too-many-locals
7577
"""
76-
`facets`
78+
Return a paginated list of objects for a request.
7779
80+
`model`
81+
Limit the search to a particular model
82+
`facets`
7883
A list of facets to include with the results
79-
`models`
80-
Limit the search to one or more models
8184
"""
8285
form = FacetedSearchForm(request.GET, facets=facets or [],
8386
models=(model,), load_all=True)
@@ -145,6 +148,9 @@ def error_response(self, errors, request):
145148

146149

147150
class PostAuthentication(BasicAuthentication):
151+
152+
"""Require HTTP Basic authentication for any method other than GET."""
153+
148154
def is_authenticated(self, request, **kwargs):
149155
val = super(PostAuthentication, self).is_authenticated(request,
150156
**kwargs)
@@ -154,7 +160,7 @@ def is_authenticated(self, request, **kwargs):
154160

155161

156162
class EnhancedModelResource(ModelResource):
157-
def obj_get_list(self, request=None, *args, **kwargs):
163+
def obj_get_list(self, request=None, *_, **kwargs):
158164
"""
159165
A ORM-specific implementation of ``obj_get_list``.
160166

readthedocs/bookmarks/models.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Models for the bookmarks app."""
2+
13
from django.db import models
24
from django.contrib.auth.models import User
35
from django.utils.translation import ugettext_lazy as _, ugettext
@@ -7,6 +9,9 @@
79

810

911
class Bookmark(models.Model):
12+
13+
"""A user's bookmark of a ``Project``, ``Version``, and page."""
14+
1015
user = models.ForeignKey(User, verbose_name=_('User'),
1116
related_name='bookmarks')
1217
project = models.ForeignKey(Project, verbose_name=_('Project'),

readthedocs/bookmarks/urls.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""URL config for the bookmarks app."""
2+
13
from django.conf.urls import url
24
from readthedocs.bookmarks.views import BookmarkListView
35
from readthedocs.bookmarks.views import BookmarkAddView, BookmarkRemoveView

readthedocs/bookmarks/views.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Views for the bookmarks app."""
2+
13
from django.contrib.auth.decorators import login_required
24
from django.http import HttpResponse, HttpResponseRedirect
35
from django.http import HttpResponseBadRequest

readthedocs/builds/constants.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Constants for the builds app."""
2+
13
from django.utils.translation import ugettext_lazy as _
24

35
BUILD_STATE_TRIGGERED = 'triggered'

readthedocs/builds/filters.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""FilterSets for the builds app."""
2+
13
from django.utils.translation import ugettext_lazy as _
24

35
import django_filters

readthedocs/builds/forms.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Django forms for the builds app."""
2+
13
from django import forms
24

35
from readthedocs.builds.models import VersionAlias, Version

readthedocs/builds/models.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Models for the builds app."""
2+
13
import logging
24
import re
35
import os.path
@@ -32,6 +34,9 @@
3234

3335

3436
class Version(models.Model):
37+
38+
"""Version of a ``Project``."""
39+
3540
project = models.ForeignKey(Project, verbose_name=_('Project'),
3641
related_name='versions')
3742
type = models.CharField(
@@ -154,7 +159,7 @@ def save(self, *args, **kwargs):
154159

155160
def delete(self, *args, **kwargs):
156161
from readthedocs.projects import tasks
157-
log.info('Removing files for version %s' % self.slug)
162+
log.info('Removing files for version %s', self.slug)
158163
tasks.clear_artifacts.delay(version_pk=self.pk)
159164
broadcast(type='app', task=tasks.symlink_project, args=[self.project.pk])
160165
super(Version, self).delete(*args, **kwargs)
@@ -220,6 +225,18 @@ def clean_build_path(self):
220225
log.error('Build path cleanup failed', exc_info=True)
221226

222227
def get_github_url(self, docroot, filename, source_suffix='.rst', action='view'):
228+
"""
229+
Return a GitHub URL for a given filename.
230+
231+
`docroot`
232+
Location of documentation in repository
233+
`filename`
234+
Name of file
235+
`source_suffix`
236+
File suffix of documentation format
237+
`action`
238+
`view` (default) or `edit`
239+
"""
223240
repo_url = self.project.repo
224241
if 'github' not in repo_url:
225242
return ''
@@ -283,6 +300,9 @@ def get_bitbucket_url(self, docroot, filename, source_suffix='.rst'):
283300

284301

285302
class VersionAlias(models.Model):
303+
304+
"""Alias for a ``Version``."""
305+
286306
project = models.ForeignKey(Project, verbose_name=_('Project'),
287307
related_name='aliases')
288308
from_slug = models.CharField(_('From slug'), max_length=255, default='')
@@ -299,6 +319,9 @@ def __unicode__(self):
299319

300320

301321
class Build(models.Model):
322+
323+
"""Build data."""
324+
302325
project = models.ForeignKey(Project, verbose_name=_('Project'),
303326
related_name='builds')
304327
version = models.ForeignKey(Version, verbose_name=_('Version'), null=True,
@@ -373,6 +396,9 @@ def failed(self):
373396

374397

375398
class BuildCommandResult(BuildCommandResultMixin, models.Model):
399+
400+
"""Build command for a ``Build``."""
401+
376402
build = models.ForeignKey(Build, verbose_name=_('Build'),
377403
related_name='commands')
378404

readthedocs/builds/urls.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
"""URL configuration for builds app."""
2+
13
from django.conf.urls import url
24

3-
from .views import (
4-
BuildList, BuildDetail, builds_redirect_detail, builds_redirect_list,
5-
)
5+
from .views import builds_redirect_detail, builds_redirect_list
66

77

88
urlpatterns = [

readthedocs/builds/utils.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Utilities for the builds app."""
2+
13
import re
24

35

readthedocs/builds/version_slug.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def __init__(self, *args, **kwargs):
5454
super(VersionSlugField, self).__init__(*args, **kwargs)
5555

5656
def get_queryset(self, model_cls, slug_field):
57+
# pylint: disable=protected-access
5758
for field, model in model_cls._meta.get_fields_with_model():
5859
if model and field == slug_field:
5960
return model._default_manager.all()
@@ -103,11 +104,14 @@ def uniquifying_suffix(self, iteration):
103104
return '_{suffix}'.format(suffix=suffix)
104105

105106
def create_slug(self, model_instance):
107+
"""Generate a unique slug for a model instance."""
108+
# pylint: disable=protected-access
109+
106110
# get fields to populate from and slug field to set
107111
slug_field = model_instance._meta.get_field(self.attname)
108112

109113
slug = self.slugify(getattr(model_instance, self._populate_from))
110-
next = 0
114+
count = 0
111115

112116
# strip slug depending on max_length attribute of the slug field
113117
# and clean-up
@@ -134,13 +138,13 @@ def create_slug(self, model_instance):
134138
# depending on the given slug, clean-up
135139
while not slug or queryset.filter(**kwargs):
136140
slug = original_slug
137-
end = self.uniquifying_suffix(next)
141+
end = self.uniquifying_suffix(count)
138142
end_len = len(end)
139143
if slug_len and len(slug) + end_len > slug_len:
140144
slug = slug[:slug_len - end_len]
141145
slug = slug + end
142146
kwargs[self.attname] = slug
143-
next += 1
147+
count += 1
144148

145149
assert self.test_pattern.match(slug), (
146150
'Invalid generated slug: {slug}'.format(slug=slug))

readthedocs/builds/views.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Views for builds app."""
2+
13
import logging
24

35
from django.shortcuts import get_object_or_404
@@ -35,14 +37,14 @@ class BuildList(BuildBase, ListView):
3537
def get_context_data(self, **kwargs):
3638
context = super(BuildList, self).get_context_data(**kwargs)
3739

38-
filter = BuildFilter(self.request.GET, queryset=self.get_queryset())
40+
filterset = BuildFilter(self.request.GET, queryset=self.get_queryset())
3941
active_builds = self.get_queryset().exclude(state="finished").values('id')
4042

4143
context['project'] = self.project
42-
context['filter'] = filter
44+
context['filter'] = filterset
4345
context['active_builds'] = active_builds
4446
context['versions'] = Version.objects.public(user=self.request.user, project=self.project)
45-
context['build_qs'] = filter.qs
47+
context['build_qs'] = filterset.qs
4648

4749
try:
4850
redis = Redis.from_url(settings.BROKER_URL)
@@ -64,9 +66,9 @@ def get_context_data(self, **kwargs):
6466

6567
# Old build view redirects
6668

67-
def builds_redirect_list(request, project_slug):
69+
def builds_redirect_list(request, project_slug): # pylint: disable=unused-argument
6870
return HttpResponsePermanentRedirect(reverse('builds_project_list', args=[project_slug]))
6971

7072

71-
def builds_redirect_detail(request, project_slug, pk):
73+
def builds_redirect_detail(request, project_slug, pk): # pylint: disable=unused-argument
7274
return HttpResponsePermanentRedirect(reverse('builds_detail', args=[project_slug, pk]))

0 commit comments

Comments
 (0)