Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import logging 

2 

3from django.core.exceptions import PermissionDenied 

4from guardian.core import ObjectPermissionChecker 

5from elasticsearch_dsl import Q 

6from discuss_data.core.documents import DataSetDocument, UserDocument 

7from discuss_data.pages.models import ManualPage 

8 

9 

10logger = logging.getLogger(__name__) 

11 

12 

13SEARCH_FIELDS_USER = [ 

14 "first_name", 

15 "last_name^3", 

16 "countries.name", 

17 "interests.name", 

18 "affiliation_user.place_of_institution", 

19 "affiliation_user.country_of_institution", 

20 "affiliation_user.name_of_institution", 

21 "affiliation_user.position", 

22] 

23SEARCH_FIELDS_DATASET = [ 

24 "title^3", 

25 "subtitle^2", 

26 "dataset_creator.name", 

27 "countries.name", 

28 "keywords.name", 

29 "published_categories.name", 

30 "published_main_category.name", 

31 "owner.first_name", 

32 "owner.last_name^2", 

33 "description", 

34 "related_dataset_text", 

35 "sources_of_data", 

36 "funding", 

37 "institutional_affiliation", 

38 "languages_of_data.name", 

39 "methods_of_data_collection.name", 

40 "analysis_of_data_collection.name", 

41 "disciplines.name", 

42] 

43 

44# SEARCH_FILTERS = { 

45# "countries": list(), 

46# "categories": list(), 

47# "keywords": list(), 

48# "languages": list(), 

49# "methods_of_data_collection": list(), 

50# "methods_of_data_analysis": list(), 

51# "disciplines": list(), 

52# } 

53 

54 

55# Commented out, as filters are not applied using this code. 

56# Switching back to older version below. 

57# def add_tag_filter(search, filter_name, filter_list, filter_field): 

58# """ 

59# Add specific filters dynamically to search object using the alternative elasticsearch-dsl syntax 

60# see: https://elasticsearch-dsl.readthedocs.io/en/latest/search_dsl.html#dotted-fields 

61# """ 

62# if filter_list: 

63# query_list = list() 

64# # construct list of Q match clauses for filtering elements 

65# for elem in filter_list: 

66# if elem != "": 

67# query_list.append(Q("match", **{"{}.name".format(filter_name): elem})) 

68# # add the list to the search object 

69# return search.filter("terms", **{filter_name + "." + filter_field: query_list}) 

70# else: 

71# # return original search object if filter_list is None 

72# return search 

73 

74 

75def add_tag_filter(search, filter_name, filter_list): 

76 """ 

77 Add specific filters dynamically using the alternative elasticsearch-dsl syntax 

78 see: https://elasticsearch-dsl.readthedocs.io/en/latest/search_dsl.html#dotted-fields 

79 """ 

80 if filter_list: 

81 for elem in filter_list: 

82 if elem != "": 

83 search = search.query("match", **{"{}.name".format(filter_name): elem}) 

84 return search 

85 

86 

87def index_search(index, term, **kwargs): 

88 """ 

89 Using elastic simple_query_string with default wildcard attached, default AND 

90 operator and a limited set of weighted fields. Parallel use of wildcards and 

91 fuzziness is not possible. See fields and options: 

92 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html 

93 """ 

94 

95 if term: 

96 # add fuzziness to each word in query for catching misspellings 

97 # term_list = term.split(" ") 

98 # wc_term = "~1 ".join(term_list) 

99 # wc_term = wc_term + "~1" 

100 # add wildcard to each word 

101 term_list = term.split(" ") 

102 wc_term = "* ".join(term_list) 

103 wc_term = wc_term + "*" 

104 else: 

105 # use wildcard search for returning all objects in index if no term is provided (default on list pages) 

106 wc_term = "*" 

107 

108 countries = kwargs.get("countries", None) 

109 categories = kwargs.get("categories", None) 

110 keywords = kwargs.get("keywords", None) 

111 languages = kwargs.get("languages", None) 

112 methods_of_data_collection = kwargs.get("methods_of_data_collection", None) 

113 methods_of_data_analysis = kwargs.get("methods_of_data_analysis", None) 

114 disciplines = kwargs.get("disciplines", None) 

115 

116 if index == "user_index": 

117 document = UserDocument 

118 search_fields = SEARCH_FIELDS_USER 

119 

120 # do only index published datasets!! 

121 if index == "dataset_index": 

122 document = DataSetDocument 

123 search_fields = SEARCH_FIELDS_DATASET 

124 

125 # create an elastic simple query clause 

126 q = Q( 

127 "simple_query_string", 

128 query=wc_term, 

129 fields=search_fields, 

130 default_operator="AND", 

131 ) 

132 

133 # "filter" does not work with categories as they come from 2 different fields. 

134 # Using "query" clause instead, but only AND concatenation with q produces reasonable results 

135 if categories: 

136 for elem in categories: 

137 if elem != "": 

138 q_cat = Q("match", published_main_category__name=elem) | Q( 

139 "match", published_categories__name=elem 

140 ) 

141 # using & instead of | to add to query 

142 q = q & q_cat 

143 

144 # create elastic bool query and include q query 

145 filter_query = Q("bool", must=q) 

146 

147 # create search object from document 

148 search = document.search().query(filter_query) 

149 

150 # add filters for both dataset_index and user_index to search 

151 search = add_tag_filter(search, "countries", countries) 

152 

153 # add filters for dataset_index 

154 if index == "dataset_index": 

155 search = add_tag_filter(search, "keywords", keywords) 

156 search = add_tag_filter(search, "languages_of_data", languages) 

157 search = add_tag_filter(search, "disciplines", disciplines) 

158 search = add_tag_filter( 

159 search, "methods_of_data_collection", methods_of_data_collection 

160 ) 

161 search = add_tag_filter( 

162 search, "methods_of_data_analysis", methods_of_data_analysis 

163 ) 

164 

165 # add filters for user_index 

166 if index == "user_index": 

167 search = add_tag_filter(search, "interests", keywords) 

168 

169 # return all results, not just 10 (elastic default) 

170 total = search.count() 

171 search = search[0:total] 

172 return search.to_queryset() 

173 

174 

175def split_items_2(items): 

176 output = list() 

177 items_len = len(items) 

178 for i in range(0, items_len, 2): 

179 try: 

180 output.append((items[i], items[i + 1])) 

181 except IndexError: 

182 output.append((items[i], None)) 

183 return output 

184 

185 

186def split_items_3(items): 

187 output = list() 

188 items_len = len(items) 

189 for i in range(0, items_len, 3): 

190 try: 

191 output.append((items[i], items[i + 1], items[i + 2])) 

192 except IndexError: 

193 try: 

194 output.append((items[i], items[i + 1], None)) 

195 except IndexError: 

196 output.append((items[i], None)) 

197 return output 

198 

199 

200def check_perms_403(permission, user, dd_obj): 

201 if not check_perms(permission, user, dd_obj): 

202 raise PermissionDenied 

203 

204 

205def is_curator_or_check_perms_for_ds(permission, user, ds): 

206 if user in ds.get_curators(): 

207 return True 

208 else: 

209 check = check_perms(permission, user, ds) 

210 return check 

211 

212 

213def get_oep_parameters(dtype, outer_panel, add_text): 

214 return { 

215 "type": dtype, 

216 "title": "{}s".format(dtype.capitalize()), 

217 "edit_url": "{}_add".format(dtype), 

218 "list_url": "get_user_{}s".format(dtype), 

219 "outer_panel": outer_panel, 

220 "add_text": add_text, 

221 } 

222 

223 

224def check_perms(permission, user, dd_obj): 

225 try: 

226 if dd_obj.owner == user: 

227 logger.debug("is owner") 

228 return True 

229 except Exception: 

230 logger.debug("is not owner") 

231 

232 checker = ObjectPermissionChecker(user) 

233 

234 if checker.has_perm(permission, dd_obj): 

235 logger.debug("%s has perm %s on %s" % (user, permission, dd_obj)) 

236 return True 

237 else: 

238 logger.debug("%s lacks perm %s on %s" % (user, permission, dd_obj)) 

239 return False 

240 return False 

241 

242 

243# this is not a view function 

244def get_help_texts(slug): 

245 try: # try block because this code part gets somehow called before migrations are executed. 

246 # Querying for a ManualPage thus triggers a db error in an empty db 

247 # ("django.db.utils.ProgrammingError: relation "pages_manualpage" does not exist") 

248 # as the db schema is not defined yet 

249 manpage = ManualPage.objects.get(slug=slug) 

250 help_text_dict = dict() 

251 help_text_dict["manpage"] = manpage 

252 for block in manpage.body: 

253 help_text_dict[block.value["field_slug"]] = block.value["paragraph"] 

254 return help_text_dict 

255 except Exception: 

256 return None