Skip to content

Commit a07cf1d

Browse files
committed
Merge pull request #1344 from gregmuellegger/issue/1154
Adding option to disable pdf/epub builds for sphinx based projects.
2 parents 69d7284 + d530903 commit a07cf1d

File tree

10 files changed

+329
-70
lines changed

10 files changed

+329
-70
lines changed

readthedocs/builds/constants.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
('html', _('HTML')),
1313
('pdf', _('PDF')),
1414
('epub', _('Epub')),
15+
# There is currently no support for building man/dash formats, but we keep
16+
# it there since the DB might still contain those values for legacy
17+
# projects.
1518
('man', _('Manpage')),
1619
('dash', _('Dash')),
1720
)

readthedocs/core/management/commands/update_repos.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ class Command(BaseCommand):
1717
"""
1818

1919
option_list = BaseCommand.option_list + (
20-
make_option('-p',
21-
action='store_true',
22-
dest='pdf',
23-
default=False,
24-
help='Make a pdf'),
2520
make_option('-r',
2621
action='store_true',
2722
dest='record',
@@ -39,7 +34,6 @@ class Command(BaseCommand):
3934
)
4035

4136
def handle(self, *args, **options):
42-
make_pdf = options['pdf']
4337
record = options['record']
4438
force = options['force']
4539
version = options['version']
@@ -55,7 +49,6 @@ def handle(self, *args, **options):
5549
active=True,
5650
uploaded=False):
5751
tasks.update_docs(pk=version.project_id,
58-
pdf=make_pdf,
5952
record=False,
6053
version_pk=version.pk)
6154
else:
@@ -68,14 +61,12 @@ def handle(self, *args, **options):
6861
for version in Version.objects.filter(active=True,
6962
uploaded=False):
7063
tasks.update_docs(pk=version.project_id,
71-
pdf=make_pdf,
7264
record=record,
7365
force=force,
7466
version_pk=version.pk)
7567
else:
7668
log.info("Updating all docs")
77-
tasks.update_docs_pull(pdf=make_pdf,
78-
record=record,
69+
tasks.update_docs_pull(record=record,
7970
force=force)
8071

8172
@property
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
from builds.models import Version
22
from django.core.management.base import BaseCommand
3-
from optparse import make_option
43
from projects.tasks import update_docs
54

65

76
class Command(BaseCommand):
87
"""Custom management command to rebuild documentation for all projects on
98
the site. Invoked via ``./manage.py update_repos``.
109
"""
11-
option_list = BaseCommand.option_list + (
12-
make_option('-p',
13-
action='store_true',
14-
dest='pdf',
15-
default=False,
16-
help='Make a pdf'),
17-
)
1810

1911
def handle(self, *args, **options):
20-
make_pdf = options['pdf']
2112
for version in Version.objects.filter(active=True, built=False):
22-
update_docs(version.project_id, pdf=make_pdf, record=False,
13+
update_docs(version.project_id, record=False,
2314
version_pk=version.pk)

readthedocs/doc_builder/loader.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
mkdocs = import_module(getattr(settings, 'MKDOCS_BACKEND', 'doc_builder.backends.mkdocs'))
66
sphinx = import_module(getattr(settings, 'SPHINX_BACKEND', 'doc_builder.backends.sphinx'))
77

8-
loading = {
8+
BUILDER_BY_NAME = {
99
# Possible HTML Builders
1010
'sphinx': sphinx.HtmlBuilder,
1111
'sphinx_htmldir': sphinx.HtmlDirBuilder,
@@ -19,3 +19,7 @@
1919
'mkdocs': mkdocs.MkdocsHTML,
2020
'mkdocs_json': mkdocs.MkdocsJSON,
2121
}
22+
23+
24+
def get_builder_class(name):
25+
return BUILDER_BY_NAME[name]

readthedocs/projects/constants.py

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
('sphinx_htmldir', _('Sphinx HtmlDir')),
2222
('sphinx_singlehtml', _('Sphinx Single Page HTML')),
2323
#('sphinx_websupport2', _('Sphinx Websupport')),
24-
#('sphinx_man', 'Sphinx Man'),
2524
#('rdoc', 'Rdoc'),
2625
)
2726

readthedocs/projects/forms.py

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ class Meta:
141141
'conf_py_file',
142142
'default_branch',
143143
'default_version',
144+
'enable_pdf_build',
145+
'enable_epub_build',
144146
# Privacy
145147
'privacy_level',
146148
# 'version_privacy_level',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# -*- coding: utf-8 -*-
2+
from south.utils import datetime_utils as datetime
3+
from south.db import db
4+
from south.v2 import SchemaMigration
5+
from django.db import models
6+
7+
8+
class Migration(SchemaMigration):
9+
10+
def forwards(self, orm):
11+
# Adding field 'Project.enable_epub_build'
12+
db.add_column(u'projects_project', 'enable_epub_build',
13+
self.gf('django.db.models.fields.BooleanField')(default=True),
14+
keep_default=False)
15+
16+
# Adding field 'Project.enable_pdf_build'
17+
db.add_column(u'projects_project', 'enable_pdf_build',
18+
self.gf('django.db.models.fields.BooleanField')(default=True),
19+
keep_default=False)
20+
21+
22+
def backwards(self, orm):
23+
# Deleting field 'Project.enable_epub_build'
24+
db.delete_column(u'projects_project', 'enable_epub_build')
25+
26+
# Deleting field 'Project.enable_pdf_build'
27+
db.delete_column(u'projects_project', 'enable_pdf_build')
28+
29+
30+
models = {
31+
u'auth.group': {
32+
'Meta': {'object_name': 'Group'},
33+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
34+
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
35+
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
36+
},
37+
u'auth.permission': {
38+
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
39+
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
40+
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
41+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42+
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
43+
},
44+
u'auth.user': {
45+
'Meta': {'object_name': 'User'},
46+
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
47+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
48+
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
49+
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
50+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
51+
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
52+
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
53+
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
54+
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
55+
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
56+
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
57+
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
58+
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
59+
},
60+
u'builds.version': {
61+
'Meta': {'ordering': "['-verbose_name']", 'unique_together': "[('project', 'slug')]", 'object_name': 'Version'},
62+
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
63+
'built': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
64+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
65+
'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
66+
'machine': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
67+
'privacy_level': ('django.db.models.fields.CharField', [], {'default': "'public'", 'max_length': '20'}),
68+
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'versions'", 'to': u"orm['projects.Project']"}),
69+
'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
70+
'supported': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
71+
'type': ('django.db.models.fields.CharField', [], {'default': "'unknown'", 'max_length': '20'}),
72+
'uploaded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
73+
'verbose_name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
74+
},
75+
u'contenttypes.contenttype': {
76+
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
77+
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
78+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
79+
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
80+
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
81+
},
82+
u'projects.emailhook': {
83+
'Meta': {'object_name': 'EmailHook'},
84+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
85+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
86+
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailhook_notifications'", 'to': u"orm['projects.Project']"})
87+
},
88+
u'projects.importedfile': {
89+
'Meta': {'object_name': 'ImportedFile'},
90+
'commit': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
91+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
92+
'md5': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
93+
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
94+
'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
95+
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imported_files'", 'to': u"orm['projects.Project']"}),
96+
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
97+
'version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imported_files'", 'null': 'True', 'to': u"orm['builds.Version']"})
98+
},
99+
u'projects.project': {
100+
'Meta': {'ordering': "('slug',)", 'object_name': 'Project'},
101+
'allow_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
102+
'analytics_code': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
103+
'canonical_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
104+
'comment_moderation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
105+
'conf_py_file': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}),
106+
'copyright': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
107+
'default_branch': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
108+
'default_version': ('django.db.models.fields.CharField', [], {'default': "'latest'", 'max_length': '255'}),
109+
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
110+
'django_packages_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
111+
'documentation_type': ('django.db.models.fields.CharField', [], {'default': "'auto'", 'max_length': '20'}),
112+
'featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
113+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
114+
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '20'}),
115+
'main_language_project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': u"orm['projects.Project']"}),
116+
'mirror': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
117+
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
118+
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
119+
'num_major': ('django.db.models.fields.IntegerField', [], {'default': '2', 'max_length': '3', 'null': 'True', 'blank': 'True'}),
120+
'num_minor': ('django.db.models.fields.IntegerField', [], {'default': '2', 'max_length': '3', 'null': 'True', 'blank': 'True'}),
121+
'num_point': ('django.db.models.fields.IntegerField', [], {'default': '2', 'max_length': '3', 'null': 'True', 'blank': 'True'}),
122+
'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
123+
'privacy_level': ('django.db.models.fields.CharField', [], {'default': "'public'", 'max_length': '20'}),
124+
'programming_language': ('django.db.models.fields.CharField', [], {'default': "'words'", 'max_length': '20', 'blank': 'True'}),
125+
'project_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
126+
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
127+
'python_interpreter': ('django.db.models.fields.CharField', [], {'default': "'python'", 'max_length': '20'}),
128+
'related_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['projects.Project']", 'null': 'True', 'through': u"orm['projects.ProjectRelationship']", 'blank': 'True'}),
129+
'repo': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
130+
'repo_type': ('django.db.models.fields.CharField', [], {'default': "'git'", 'max_length': '10'}),
131+
'requirements_file': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
132+
'single_version': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
133+
'skip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
134+
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
135+
'enable_epub_build': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
136+
'enable_pdf_build': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
137+
'suffix': ('django.db.models.fields.CharField', [], {'default': "'.rst'", 'max_length': '10'}),
138+
'theme': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '20'}),
139+
'use_system_packages': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
140+
'use_virtualenv': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
141+
'users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'projects'", 'symmetrical': 'False', 'to': u"orm['auth.User']"}),
142+
'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
143+
'version_privacy_level': ('django.db.models.fields.CharField', [], {'default': "'public'", 'max_length': '20'})
144+
},
145+
u'projects.projectrelationship': {
146+
'Meta': {'object_name': 'ProjectRelationship'},
147+
'child': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'superprojects'", 'to': u"orm['projects.Project']"}),
148+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
149+
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subprojects'", 'to': u"orm['projects.Project']"})
150+
},
151+
u'projects.webhook': {
152+
'Meta': {'object_name': 'WebHook'},
153+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
154+
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'webhook_notifications'", 'to': u"orm['projects.Project']"}),
155+
'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
156+
}
157+
}
158+
159+
complete_apps = ['projects']

readthedocs/projects/models.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
from vcs_support.base import VCSProject
2828
from vcs_support.backends import backend_cls
2929
from vcs_support.utils import Lock, NonBlockingLock
30-
from doc_builder.loader import loading
3130

3231

3332
log = logging.getLogger(__name__)
@@ -115,6 +114,16 @@ class Project(models.Model):
115114
"(ex. <code>UA-22345342-1</code>). "
116115
"This may slow down your page loads."))
117116

117+
# Sphinx specific build options.
118+
enable_epub_build = models.BooleanField(
119+
_('Enable EPUB build'), default=True,
120+
help_text=_(
121+
'Create a EPUB version of your documentation with each build.'))
122+
enable_pdf_build = models.BooleanField(
123+
_('Enable PDF build'), default=True,
124+
help_text=_(
125+
'Create a PDF version of your documentation with each build.'))
126+
118127
# Other model data.
119128
path = models.CharField(_('Path'), max_length=255, editable=False,
120129
help_text=_("The directory where "
@@ -426,9 +435,6 @@ def clean_repo(self):
426435
# Doc PATH:
427436
# MEDIA_ROOT/slug/checkouts/version/<repo>
428437

429-
def doc_builder(self):
430-
return loading.get(self.documentation_type)
431-
432438
@property
433439
def doc_path(self):
434440
return os.path.join(settings.DOCROOT, self.slug.replace('_', '-'))
@@ -506,18 +512,22 @@ def full_latex_path(self, version='latest'):
506512
"""
507513
return os.path.join(self.conf_dir(version), "_build", "latex")
508514

509-
def full_man_path(self, version='latest'):
510-
"""
511-
The path to the build man docs in the project.
512-
"""
513-
return os.path.join(self.conf_dir(version), "_build", "man")
514-
515515
def full_epub_path(self, version='latest'):
516516
"""
517517
The path to the build epub docs in the project.
518518
"""
519519
return os.path.join(self.conf_dir(version), "_build", "epub")
520520

521+
# There is currently no support for building man/dash formats, but we keep
522+
# the support there for existing projects. They might have already existing
523+
# legacy builds.
524+
525+
def full_man_path(self, version='latest'):
526+
"""
527+
The path to the build man docs in the project.
528+
"""
529+
return os.path.join(self.conf_dir(version), "_build", "man")
530+
521531
def full_dash_path(self, version='latest'):
522532
"""
523533
The path to the build dash docs in the project.

0 commit comments

Comments
 (0)