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+ @property
45+ def entities (self ):
46+ """Entity objects related to this experiment"""
47+ return (self .model , self .protocol )
48+
49+ def is_visible_to_user (self , user ):
50+ """
51+ Can the user view the experiment?
52+
53+ :param user: user to test against
54+
55+ :returns: True if the user is allowed to view the experiment, False otherwise
56+ """
57+ return visibility_check (self .visibility , self .viewers , user )
58+
59+ @property
60+ def viewers (self ):
61+ """
62+ Get users which have special permissions to view this experiment.
63+
64+ We take the intersection of users with special permissions to view each object
65+ (model, fitting spec, etc) involved, if that object is private. If it's public,
66+ we can ignore it because everyone can see it.
67+
68+ :return: `set` of `User` objects
69+ """
70+ viewers = [
71+ obj .viewers
72+ for obj in self .entities
73+ if obj .visibility == Visibility .PRIVATE
74+ ]
75+ return set .intersection (* viewers ) if viewers else {}
76+
77+ class Meta :
78+ abstract = True
79+
80+
81+ class Experiment (ExperimentMixin , UserCreatedModelMixin , models .Model ):
1482 """A specific version of a protocol run on a specific version of a model
1583
1684 This class essentially just stores the model & protocol links. The results are
@@ -34,9 +102,6 @@ class Meta:
34102 ('create_experiment' , 'Can create experiments' ),
35103 )
36104
37- def __str__ (self ):
38- return self .name
39-
40105 @property
41106 def name (self ):
42107 return self .get_name ()
@@ -60,55 +125,6 @@ def get_name(self, model_version=False, proto_version=False):
60125 def visibility (self ):
61126 return get_joint_visibility (self .model_version .visibility , self .protocol_version .visibility )
62127
63- @property
64- def viewers (self ):
65- """
66- Get users which have special permissions to view this experiment
67-
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.
71-
72- :return: `set` of `User` objects
73- """
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 ''
111-
112128
113129class Runnable (UserCreatedModelMixin , FileCollectionMixin , models .Model ):
114130 """ Runnable base class
0 commit comments