-
Notifications
You must be signed in to change notification settings - Fork 14
/
setup.py
144 lines (106 loc) · 4.43 KB
/
setup.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
"""Setting up projects for Dillo.
This is intended to be used by the CLI and unittests only, not tested
for live/production situations.
"""
import copy
import logging
from bson import ObjectId
from eve.methods.put import put_internal
from flask import current_app
from pillarsdk import Project
from pillar.api.utils import node_type_utils
from pillar.api.projects.utils import abort_with_error
from . import EXTENSION_NAME
log = logging.getLogger(__name__)
def _get_project(project_url):
"""Find a project in the database, or SystemExit()s.
:param project_url: UUID of the project
:type: str
:return: the project
:rtype: dict
"""
projects_collection = current_app.data.driver.db['projects']
# Find the project in the database.
project = projects_collection.find_one({'url': project_url})
if not project:
raise RuntimeError('Project %s does not exist.' % project_url)
return project
def _update_project(project):
"""Updates a project in the database, or SystemExit()s.
:param project: the project data, should be the entire project document
:type: dict
:return: the project
:rtype: dict
"""
from pillar.api.utils import remove_private_keys
project_id = ObjectId(project['_id'])
project = remove_private_keys(project)
result, _, _, status_code = put_internal('projects', project, _id=project_id)
if status_code != 200:
raise RuntimeError("Can't update project %s, issues: %s", project_id, result)
def _ensure_user_main_group() -> ObjectId:
"""Retrieve the dillo_user_main group.
If the group does not exist, create it.
Returns the group ObjectId.
"""
grp_collection = current_app.data.driver.db['groups']
dillo_user_main_group = grp_collection.find_one({'name': 'dillo_user_main'})
if not dillo_user_main_group:
dillo_user_main_group, _, _, status = current_app.post_internal(
'groups', {'name': 'dillo_user_main'})
if status != 201:
log.error('Unable to create dillo_user_main group')
return abort_with_error(status)
return dillo_user_main_group['_id']
def setup_for_dillo(project_url, replace=False):
"""Adds Dillo node types to the project.
Use --replace to replace pre-existing Dillo node types
(by default already existing Dillo node types are skipped).
Returns the updated project.
"""
from .node_types import NODE_TYPES
# Copy permissions from the project, then give everyone with PUT
# access also DELETE access.
project = _get_project(project_url)
def permission_callback(node_type, ugw, ident, proj_methods):
if 'PUT' not in set(proj_methods):
return None
# TODO: we allow PATCH on shot node types, but that's not explicit in
# the permission system. Maybe we want to revisit that at some point.
# if node_type is shot.node_type_shot:
# return ['DELETE', 'PATCH']
return ['DELETE']
# Add/replace our node types.
node_types = node_type_utils.assign_permissions(project, NODE_TYPES, permission_callback)
node_type_utils.add_to_project(project, node_types, replace_existing=replace)
# Add the dillo_user_main group to the dillo_post node type in order to
# allow every member to create posts in the project. Editing of posts (PUT)
# is allowed on a per-user basis when creating the actual post.
dillo_user_main_group = _ensure_user_main_group()
for nt in project['node_types']:
if nt['name'] in {'comment', 'dillo_post'}:
groups = nt['permissions']['groups']
groups.append({
'group': dillo_user_main_group,
'methods': ['GET', 'POST']
})
# Set default extension properties. Be careful not to overwrite any properties that
# are already there.
eprops = project.setdefault('extension_props', {})
eprops.setdefault(EXTENSION_NAME, {
'last_used_shortcodes': {},
'community_theme_css': '',
# The accent color (can be 'blue' or '#FFBBAA' or 'rgba(1, 1, 1, 1)
'community_theme_color': '',
# Social media handles for the community
'social': {
'twitter': '',
'youtube': '',
'facebook': '',
},
# A 16:9 image to be used with OpenGraph or others
'picture_16_9': None,
})
_update_project(project)
log.info('Project %s was updated for Dillo.', project_url)
return project