This repository has been archived by the owner on Jan 31, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 46
/
manage_utils.py
238 lines (169 loc) · 6.79 KB
/
manage_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
"""This module holds all the functions that deal with starting up
Fjord for both the developer and server environments.
These functions shouldn't be used after startup is completed.
"""
import logging
import os
import sys
from functools import wraps
from itertools import chain
from fjord import path
log = logging.getLogger(__name__)
# Denotes that setup_environ has been run
_has_setup_environ = False
# Prevent from patching twice
_has_patched = False
# Taken from peep
class EmptyOptions(object):
"""Fake optparse options for compatibility with pip<1.2
pip<1.2 had a bug in parse_requirments() in which the ``options``
kwarg was required. We work around that by passing it a mock
object.
"""
default_vcs = None
skip_requirements_regex = None
isolated_mode = False
def check_dependencies():
"""Check installed requirements vs. specified requirements
This prints out a list of dependencies where the version installed
is not the same as the one specified in the requirements files.
It also exits immediately. At some point we might want to change
it from doing that, but not today.
If you want to skip this check, set SKIP_CHECK=1 in your
environment.
.. Note::
This only works for packaged requirements. It does not work for
requirements downloaded in a tarball from github. Those
requirements get put in the "unsatisfyable" requirements list
and this will tell you how many there are.
Generally we should minimize those requirements as much as
possible.
"""
# Import this here because not all environments have pip.
from pip.req import parse_requirements
from pip.download import PipSession
req_path = path('requirements')
req_files = [os.path.join(req_path, fn) for fn in os.listdir(req_path)]
reqs = list(chain(*(parse_requirements(path,
options=EmptyOptions(),
session=PipSession())
for path in req_files)))
unsatisfied_reqs = []
unsatisfyable_reqs = []
for req in reqs:
if req.link and req.url and 'github.com' in req.url:
unsatisfyable_reqs.append(req)
continue
req.check_if_exists()
if not req.satisfied_by:
unsatisfied_reqs.append(req)
if unsatisfyable_reqs:
print 'There are %d requirements that cannot be checked.' % (
len(unsatisfyable_reqs))
if unsatisfied_reqs:
print 'The following requirements are not satsifed:'
print ''
for req in unsatisfied_reqs:
print 'UNSATISFIED:', req.req
print ''
print 'Update your virtual environment by doing:'
print ''
print ' ./peep.sh install -r requirements/requirements.txt'
print ' ./peep.sh install -r requirements/compiled.txt'
print ' ./peep.sh install -r requirements/dev.txt'
print ''
print 'or run with SKIP_CHECK=1 .'
sys.exit(1)
def setup_environ():
"""Sets up the Django environment
1. validates settings
2. sets up django-celery
"""
global _has_setup_environ
if _has_setup_environ:
return
from django.conf import settings
validate_settings(settings)
_has_setup_environ = True
def validate_settings(settings):
"""Raise an error if we see insecure or missing settings"""
from django.core.exceptions import ImproperlyConfigured
if not settings.DATABASES['default']:
msg = 'DATABASES["default"] needs to be set.'
raise ImproperlyConfigured(msg)
if not getattr(settings, 'SECRET_KEY', None):
msg = 'settings.SECRET_KEY needs to be set.'
raise ImproperlyConfigured(msg)
if not settings.DEBUG:
if not getattr(settings, 'SECRET_KEY', 'notsecret'):
msg = 'settings.SECRET_KEY is set to "notsecret". please change.'
raise ImproperlyConfigured(msg)
if getattr(settings, 'SESSION_COOKIE_SECURE', None) is None:
msg = (
'settings.SESSION_COOKIE_SECURE should be set to True; '
'otherwise, your session ids can be intercepted over HTTP!'
)
raise ImproperlyConfigured(msg)
hmac = getattr(settings, 'HMAC_KEYS', {})
if not len(hmac.keys()):
msg = 'settings.HMAC_KEYS cannot be empty.'
raise ImproperlyConfigured(msg)
def monkeypatch():
"""All the monkeypatching we have to do to get things running"""
global _has_patched
if _has_patched:
return
# Import for side-effect: configures logging handlers
from fjord.settings.log_settings import noop
noop()
# Monkey-patch admin site
from django.contrib import admin
from django.contrib.auth.decorators import login_required
from session_csrf import anonymous_csrf
from adminplus.sites import AdminSitePlus
# Patch the admin
admin.site = AdminSitePlus()
admin.site.login = login_required(anonymous_csrf(admin.site.login))
# Monkey-patch Django's csrf_protect decorator to use
# session-based CSRF tokens
import session_csrf
session_csrf.monkeypatch()
logging.debug('Note: monkeypatches executed in %s' % __file__)
# Prevent it from being run again later
_has_patched = True
def monkeypatch_render():
"""Monkeypatches django.shortcuts.render for Jinja2 kung-fu action
.. Note::
Only call this in a testing context!
"""
import django.shortcuts
def more_info(fun):
"""Django's render shortcut, but captures information for testing
When using Django's render shortcut with Jinja2 templates, none of
the information is captured and thus you can't use it for testing.
This alleviates that somewhat by capturing some of the information
allowing you to test it.
Caveats:
* it does *not* capture all the Jinja2 templates used to render.
Only the topmost one requested by the render() function.
"""
@wraps(fun)
def _more_info(request, template_name, *args, **kwargs):
resp = fun(request, template_name, *args, **kwargs)
resp.jinja_templates = [template_name]
if args:
resp.jinja_context = args[0]
elif 'context' in kwargs:
resp.jinja_context = kwargs['context']
else:
resp.jinja_context = {}
return resp
return _more_info
django.shortcuts.render = more_info(django.shortcuts.render)
def main(argv=None):
if not _has_setup_environ:
raise EnvironmentError(
'setup_environ() has not been called for this process')
from django.core.management import execute_from_command_line
argv = argv or sys.argv
execute_from_command_line(argv)