1010from repocache .models import CachedModelVersion , CachedProtocolVersion
1111
1212
13- class Experiment (UserCreatedModelMixin , models .Model ):
13+ class ExperimentMixin (models .Model ):
14+ """
15+ Model mixin for different types of experiment
16+
17+ Models must have model, model_version, protocol and protocol_version fields
18+ and be the parent of a Runnable-derived model.
19+ """
20+ def __str__ (self ):
21+ return self .name
22+
23+ @property
24+ def latest_version (self ):
25+ return self .versions .latest ('created_at' )
26+
27+ @property
28+ def nice_model_version (self ):
29+ """Use tags to give a nicer representation of the commit id"""
30+ return self .model_version .nice_version ()
31+
32+ @property
33+ def nice_protocol_version (self ):
34+ """Use tags to give a nicer representation of the commit id"""
35+ return self .protocol_version .nice_version ()
36+
37+ @property
38+ def latest_result (self ):
39+ try :
40+ return self .latest_version .status
41+ except Runnable .DoesNotExist :
42+ return ''
43+
44+ def is_visible_to_user (self , user ):
45+ """
46+ Can the user view the experiment?
47+
48+ :param user: user to test against
49+
50+ :returns: True if the user is allowed to view the experiment, False otherwise
51+ """
52+ return visibility_check (self .visibility , self .viewers , user )
53+
54+
55+ class Experiment (UserCreatedModelMixin , ExperimentMixin , models .Model ):
1456 """A specific version of a protocol run on a specific version of a model
1557
1658 This class essentially just stores the model & protocol links. The results are
@@ -34,9 +76,6 @@ class Meta:
3476 ('create_experiment' , 'Can create experiments' ),
3577 )
3678
37- def __str__ (self ):
38- return self .name
39-
4079 @property
4180 def name (self ):
4281 return self .get_name ()
@@ -60,54 +99,28 @@ def get_name(self, model_version=False, proto_version=False):
6099 def visibility (self ):
61100 return get_joint_visibility (self .model_version .visibility , self .protocol_version .visibility )
62101
102+ @property
103+ def entities (self ):
104+ """Entity objects related to this experiment"""
105+ return (self .model , self .protocol )
106+
63107 @property
64108 def viewers (self ):
65109 """
66- Get users which have special permissions to view this experiment
110+ Get users which have special permissions to view this experiment.
67111
68- We do not handle the case where both model and protocol are public,
69- since this would make the experiment also public and therefore
70- visible to every user - so calling this method makes very little sense .
112+ We take the intersection of users with special permissions to view each object
113+ (model, fitting spec, etc) involved, if that object is private. If it's public,
114+ we can ignore it because everyone can see it .
71115
72116 :return: `set` of `User` objects
73117 """
74- if self .protocol .visibility != Visibility .PRIVATE :
75- return self .model .viewers
76- elif self .model .visibility != Visibility .PRIVATE :
77- return self .protocol .viewers
78- else :
79- return self .model .viewers & self .protocol .viewers
80-
81- def is_visible_to_user (self , user ):
82- """
83- Can the user view the experiment?
84-
85- :param user: user to test against
86-
87- :returns: True if the user is allowed to view the experiment, False otherwise
88- """
89- return visibility_check (self .visibility , self .viewers , user )
90-
91- @property
92- def latest_version (self ):
93- return self .versions .latest ('created_at' )
94-
95- @property
96- def nice_model_version (self ):
97- """Use tags to give a nicer representation of the commit id"""
98- return self .model_version .nice_version ()
99-
100- @property
101- def nice_protocol_version (self ):
102- """Use tags to give a nicer representation of the commit id"""
103- return self .protocol_version .nice_version ()
104-
105- @property
106- def latest_result (self ):
107- try :
108- return self .latest_version .status
109- except Runnable .DoesNotExist :
110- return ''
118+ viewers = [
119+ obj .viewers
120+ for obj in self .entities
121+ if obj .visibility == Visibility .PRIVATE
122+ ]
123+ return set .intersection (* viewers ) if viewers else {}
111124
112125
113126class Runnable (UserCreatedModelMixin , FileCollectionMixin , models .Model ):
0 commit comments