-
Notifications
You must be signed in to change notification settings - Fork 2k
/
admin.py
190 lines (163 loc) · 8.69 KB
/
admin.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
# encoding: utf-8
from pylons import config
import ckan.lib.base as base
import ckan.lib.helpers as h
import ckan.lib.app_globals as app_globals
import ckan.lib.navl.dictization_functions as dict_fns
import ckan.model as model
import ckan.logic as logic
import ckan.plugins as plugins
from home import CACHE_PARAMETERS
c = base.c
request = base.request
_ = base._
def get_sysadmins():
q = model.Session.query(model.User).filter(model.User.sysadmin == True,
model.User.state == 'active')
return q.all()
class AdminController(base.BaseController):
def __before__(self, action, **params):
super(AdminController, self).__before__(action, **params)
context = {'model': model,
'user': c.user, 'auth_user_obj': c.userobj}
try:
logic.check_access('sysadmin', context, {})
except logic.NotAuthorized:
base.abort(403, _('Need to be system administrator to administer'))
c.revision_change_state_allowed = True
def _get_config_form_items(self):
# Styles for use in the form.select() macro.
styles = [{'text': 'Default', 'value': '/base/css/main.css'},
{'text': 'Red', 'value': '/base/css/red.css'},
{'text': 'Green', 'value': '/base/css/green.css'},
{'text': 'Maroon', 'value': '/base/css/maroon.css'},
{'text': 'Fuchsia', 'value': '/base/css/fuchsia.css'}]
homepages = [{'value': '1', 'text': 'Introductory area, search, featured group and featured organization'},
{'value': '2', 'text': 'Search, stats, introductory area, featured organization and featured group'},
{'value': '3', 'text': 'Search, introductory area and stats'}]
items = [
{'name': 'ckan.site_title', 'control': 'input', 'label': _('Site Title'), 'placeholder': ''},
{'name': 'ckan.main_css', 'control': 'select', 'options': styles, 'label': _('Style'), 'placeholder': ''},
{'name': 'ckan.site_description', 'control': 'input', 'label': _('Site Tag Line'), 'placeholder': ''},
{'name': 'ckan.site_logo', 'control': 'input', 'label': _('Site Tag Logo'), 'placeholder': ''},
{'name': 'ckan.site_about', 'control': 'markdown', 'label': _('About'), 'placeholder': _('About page text')},
{'name': 'ckan.site_intro_text', 'control': 'markdown', 'label': _('Intro Text'), 'placeholder': _('Text on home page')},
{'name': 'ckan.site_custom_css', 'control': 'textarea', 'label': _('Custom CSS'), 'placeholder': _('Customisable css inserted into the page header')},
{'name': 'ckan.homepage_style', 'control': 'select', 'options': homepages, 'label': _('Homepage'), 'placeholder': ''},
]
return items
def reset_config(self):
'''FIXME: This method is probably not doing what people would expect.
It will reset the configuration to values cached when CKAN started.
If these were coming from the database during startup, that's the
ones that will get applied on reset, not the ones in the ini file.
Only after restarting the server and having CKAN reset the values
from the ini file (as the db ones are not there anymore) will these
be used.
'''
if 'cancel' in request.params:
h.redirect_to(controller='admin', action='config')
if request.method == 'POST':
# remove sys info items
for item in self._get_config_form_items():
name = item['name']
model.delete_system_info(name)
# reset to values in config
app_globals.reset()
h.redirect_to(controller='admin', action='config')
return base.render('admin/confirm_reset.html')
def config(self):
items = self._get_config_form_items()
data = request.POST
if 'save' in data:
try:
# really?
data_dict = logic.clean_dict(
dict_fns.unflatten(
logic.tuplize_dict(
logic.parse_params(
request.POST, ignore_keys=CACHE_PARAMETERS))))
del data_dict['save']
data = logic.get_action('config_option_update')(
{'user': c.user}, data_dict)
except logic.ValidationError, e:
errors = e.error_dict
error_summary = e.error_summary
vars = {'data': data, 'errors': errors,
'error_summary': error_summary, 'form_items': items}
return base.render('admin/config.html', extra_vars=vars)
h.redirect_to(controller='admin', action='config')
schema = logic.schema.update_configuration_schema()
data = {}
for key in schema:
data[key] = config.get(key)
vars = {'data': data, 'errors': {}, 'form_items': items}
return base.render('admin/config.html',
extra_vars=vars)
def index(self):
#now pass the list of sysadmins
c.sysadmins = [a.name for a in get_sysadmins()]
return base.render('admin/index.html')
def trash(self):
c.deleted_revisions = model.Session.query(
model.Revision).filter_by(state=model.State.DELETED)
c.deleted_packages = model.Session.query(
model.Package).filter_by(state=model.State.DELETED)
if not request.params or (len(request.params) == 1 and '__no_cache__'
in request.params):
return base.render('admin/trash.html')
else:
# NB: we repeat retrieval of of revisions
# this is obviously inefficient (but probably not *that* bad)
# but has to be done to avoid (odd) sqlalchemy errors (when doing
# purge packages) of form: "this object already exists in the
# session"
msgs = []
if ('purge-packages' in request.params) or ('purge-revisions' in
request.params):
if 'purge-packages' in request.params:
revs_to_purge = []
for pkg in c.deleted_packages:
revisions = [x[0] for x in pkg.all_related_revisions]
# ensure no accidental purging of other(non-deleted)
# packages initially just avoided purging revisions
# where non-deleted packages were affected
# however this lead to confusing outcomes e.g.
# we succesfully deleted revision in which package
# was deleted (so package now active again) but no
# other revisions
problem = False
for r in revisions:
affected_pkgs = set(r.packages).\
difference(set(c.deleted_packages))
if affected_pkgs:
msg = _('Cannot purge package %s as '
'associated revision %s includes '
'non-deleted packages %s')
msg = msg % (pkg.id, r.id, [pkg.id for r
in affected_pkgs])
msgs.append(msg)
problem = True
break
if not problem:
revs_to_purge += [r.id for r in revisions]
model.Session.remove()
else:
revs_to_purge = [rev.id for rev in c.deleted_revisions]
revs_to_purge = list(set(revs_to_purge))
for id in revs_to_purge:
revision = model.Session.query(model.Revision).get(id)
try:
# TODO deleting the head revision corrupts the edit
# page Ensure that whatever 'head' pointer is used
# gets moved down to the next revision
model.repo.purge_revision(revision, leave_record=False)
except Exception, inst:
msg = _('Problem purging revision %s: %s') % (id, inst)
msgs.append(msg)
h.flash_success(_('Purge complete'))
else:
msgs.append(_('Action not implemented.'))
for msg in msgs:
h.flash_error(msg)
h.redirect_to(controller='admin', action='trash')