Skip to content

Commit 5525c03

Browse files
author
Daniela Butano
authored
Merge pull request #90 from intermine/bitfount
Bitfount
2 parents a121beb + 6d69ce0 commit 5525c03

4 files changed

Lines changed: 149 additions & 2 deletions

File tree

intermine/lists/listmanager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ def create_list(
256256
This only makes sense with text uploads
257257
- it is not required (or used) when
258258
the content is a list or a query.
259+
@param organism: organism name
259260
260261
@rtype: intermine.lists.List
261262
"""

intermine/query.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,8 +1835,31 @@ def __init__(self, *args, **kwargs):
18351835
super(Template, self).__init__(*args, **kwargs)
18361836
self.constraint_factory = constraints.TemplateConstraintFactory()
18371837
self.title = ''
1838+
self.user_name = ''
18381839
self.view_types = []
18391840

1841+
def clone(self):
1842+
"""
1843+
Performs a deep clone
1844+
=====================
1845+
1846+
This method will produce a clone that is independent,
1847+
and can be altered without affecting the original,
1848+
but starts off with the exact same state as it.
1849+
1850+
The only shared elements should be the model
1851+
and the service, which are shared by all queries
1852+
that refer to the same webservice.
1853+
1854+
@return: same class as caller
1855+
"""
1856+
newobj = super(Template, self).clone()
1857+
setattr(newobj, "user_name", getattr(self, "user_name"))
1858+
return newobj
1859+
1860+
def add_user_name(self, user_name):
1861+
self.user_name = user_name
1862+
18401863
@classmethod
18411864
def from_xml(cls, xml, *args, **kwargs):
18421865
"""
@@ -1914,7 +1937,7 @@ def to_query_params(self):
19141937
19151938
@rtype: dict
19161939
"""
1917-
p = {'name': self.name}
1940+
p = {'name': self.name, 'userName': self.user_name}
19181941
i = 1
19191942
for c in self.editable_constraints:
19201943
if not c.switched_on:
@@ -1964,6 +1987,7 @@ def get_adjusted_template(self, con_values):
19641987
@rtype: L{Template}
19651988
"""
19661989
clone = self.clone()
1990+
19671991
for code, options in list(con_values.items()):
19681992
con = clone.get_constraint(code)
19691993
if not con.editable:
@@ -2031,7 +2055,6 @@ def get_row_list(self, start=0, size=None, **con_values):
20312055
return super(Template, clone).get_row_list(start, size)
20322056

20332057
def rows(self, start=0, size=None, **con_values):
2034-
print("basil2")
20352058
"""Get an iterator over the rows returned by this query"""
20362059
clone = self.get_adjusted_template(con_values)
20372060
return super(Template, clone).rows(start, size)

intermine/webservice.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class Service(object):
211211
MODEL_PATH = '/model'
212212
TEMPLATES_PATH = '/templates'
213213
TEMPLATEQUERY_PATH = '/template/results'
214+
ALL_TEMPLATES_PATH = '/alltemplates'
214215
LIST_PATH = '/lists'
215216
LIST_CREATION_PATH = '/lists'
216217
LIST_RENAME_PATH = '/lists/rename'
@@ -270,6 +271,8 @@ def __init__(self, root,
270271
self.prefetch_id_only = prefetch_id_only
271272
# Initialize empty cached data.
272273
self._templates = None
274+
self._all_templates = None
275+
self._all_templates_names = None
273276
self._model = None
274277
self._version = None
275278
self._release = None
@@ -488,6 +491,44 @@ def get_template(self, name):
488491
self.templates[name] = t
489492
return t
490493

494+
def get_template_by_user(self, name, username):
495+
"""
496+
Returns a template of the given name belonging to username
497+
==========================================================
498+
499+
Tries to retrieve a template of the given name belonging
500+
to the username from the webservice. You need to authenticate
501+
as admin
502+
503+
@see: L{intermine.webservice.Service.__init__}
504+
505+
@param name: the template's name
506+
@type name: string
507+
508+
@param username: the username
509+
@type name: string
510+
511+
@raise ServiceError: if the template or user does not exist
512+
@raise QueryParseError: if the template cannot be parsed
513+
514+
@return: L{intermine.query.Template}
515+
"""
516+
try:
517+
templates = self.all_templates[username]
518+
except KeyError:
519+
raise ServiceError("There is no user called '" + username + "'")
520+
try:
521+
t = templates[name]
522+
except KeyError:
523+
raise ServiceError("There is no template called '"
524+
+ name + "' at this service belonging to '"
525+
+ username + "'")
526+
if not isinstance(t, Template):
527+
t = Template.from_xml(t, self.model, self)
528+
t.user_name = username
529+
self.all_templates[name] = t
530+
return t
531+
491532
def _get_json(self, path, payload=None):
492533
headers = {'Accept': 'application/json'}
493534
with closing(self.opener.open(self.root + path, payload,
@@ -605,6 +646,8 @@ def flush(self):
605646
self._list_manager.delete_temporary_lists()
606647
self._list_manager = ListManager(self)
607648
self._templates = None
649+
self._all_templates = None
650+
self._all_templates_names = None
608651
self._model = None
609652
self._version = None
610653
self._release = None
@@ -644,6 +687,80 @@ def templates(self):
644687
self._templates = templates
645688
return self._templates
646689

690+
@property
691+
def all_templates(self):
692+
"""
693+
The dictionary of templates by users from the webservice
694+
========================================================
695+
696+
Service.all_templates S{->} dict(string|string)
697+
698+
You need to be authenticated as admin.
699+
700+
For efficiency's sake, Templates are not parsed until
701+
they are required, and until then they are stored as XML
702+
strings. It is recommended that in most cases you would want
703+
to use L{Service.get_template}.
704+
705+
You can use this property however to test for template existence::
706+
707+
if name in service.templates:
708+
template = service.get_template(name)
709+
710+
@rtype: dict
711+
712+
"""
713+
if self._all_templates is None:
714+
all_templates = {}
715+
dom = self._get_xml(self.ALL_TEMPLATES_PATH)
716+
for e in dom.getElementsByTagName('template'):
717+
user = e.getAttribute('userName')
718+
name = e.getAttribute('name')
719+
if user in all_templates:
720+
templates = all_templates[user]
721+
templates[name] = e.toxml()
722+
else:
723+
templates = {}
724+
templates[name] = e.toxml()
725+
all_templates[user] = templates
726+
self._all_templates = all_templates
727+
return self._all_templates
728+
729+
@property
730+
def all_templates_names(self):
731+
"""
732+
The dictionary of templates names by users from the webservice
733+
=============================================================
734+
735+
Service.all_templates_names S{->} dict(string|array)
736+
737+
You need to be authenticated as admin.
738+
739+
Example::
740+
allTemplatesNames = service.all_templates_names
741+
for user in allTemplatesNames:
742+
userTemplatesNames = allTemplatesNames[user]
743+
for templateName in userTemplatesNames:
744+
template = service.get_template_by_user(templateName, user)
745+
746+
@rtype: dict
747+
748+
"""
749+
if self._all_templates_names is None:
750+
all_templates_names = {}
751+
dom = self._get_xml(self.ALL_TEMPLATES_PATH)
752+
for e in dom.getElementsByTagName('template'):
753+
user = e.getAttribute('userName')
754+
name = e.getAttribute('name')
755+
if user in all_templates_names:
756+
all_templates_names[user].append(name)
757+
else:
758+
templates_names = []
759+
templates_names.append(name)
760+
all_templates_names[user] = templates_names
761+
self._all_templates_names = all_templates_names
762+
return self._all_templates_names
763+
647764
@property
648765
def model(self):
649766
"""

tests/test_core.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ def testURLs(self):
10251025

10261026
expected1 = ('/TEMPLATE-PATH', {
10271027
'name': 'TEST-TEMPLATE',
1028+
'userName': '',
10281029
'code1': 'A',
10291030
'code2': 'B',
10301031
'constraint1': 'Employee.name',
@@ -1041,6 +1042,7 @@ def testURLs(self):
10411042

10421043
expected1 = ('/TEMPLATE-PATH', {
10431044
'name': 'TEST-TEMPLATE',
1045+
'userName': '',
10441046
'code1': 'A',
10451047
'code2': 'B',
10461048
'constraint1': 'Employee.name',
@@ -1057,6 +1059,7 @@ def testURLs(self):
10571059

10581060
expected2 = ('/TEMPLATE-PATH', {
10591061
'name': 'TEST-TEMPLATE',
1062+
'userName': '',
10601063
'code1': 'A',
10611064
'code2': 'B',
10621065
'constraint1': 'Employee.name',
@@ -1076,6 +1079,7 @@ def testURLs(self):
10761079

10771080
expected2 = ('/TEMPLATE-PATH', {
10781081
'name': 'TEST-TEMPLATE',
1082+
'userName': '',
10791083
'code1': 'A',
10801084
'code2': 'B',
10811085
'constraint1': 'Employee.name',
@@ -1108,6 +1112,7 @@ def testURLs(self):
11081112
# Check that we can just use strings for simple value replacement.
11091113
expected3 = ('/TEMPLATE-PATH', {
11101114
'name': 'TEST-TEMPLATE',
1115+
'userName': '',
11111116
'code1': 'A',
11121117
'code2': 'B',
11131118
'constraint1': 'Employee.name',
@@ -1128,6 +1133,7 @@ def testURLs(self):
11281133
self.assertEqual(expected1, t.rows())
11291134
expected1 = ('/TEMPLATE-PATH', {
11301135
'name': 'TEST-TEMPLATE',
1136+
'userName': '',
11311137
'code1': 'A',
11321138
'code2': 'B',
11331139
'constraint1': 'Employee.name',

0 commit comments

Comments
 (0)