class TegField(me.EmbeddedDocument): teg = me.ReferenceField(Teg) teg_name = me.StringField(min_length=2, max_length=255, required=True)
class Rate(BaseDocument): user = mongoengine.ReferenceField(User) paste = mongoengine.ReferenceField(Paste) score = mongoengine.IntField(default=0)
class Processor(me.Document): meta = { 'collection': 'processors', # 'strict': False, } camera = me.ReferenceField('Camera', dbref=True) storage_period = me.IntField(required=True, default=30) # in day # image_processors = me.ListField(me.DictField()) status = me.StringField(required=True, default='active') created_date = me.DateTimeField(required=True, default=datetime.datetime.now) updated_date = me.DateTimeField(required=True, auto_now=True, auto_now_add=False, default=datetime.datetime.now) project = me.ReferenceField('Project', required=True, dbref=True) # owner = me.ReferenceField('User', required=True, dbref=True) user_command = me.EmbeddedDocumentField(UserProcessorCommand, default=UserProcessorCommand()) # last_command = me.ReferenceField('ProcessorCommand', dbref=True) # reference_command = me.ReferenceField('ProcessorCommand', dbref=True) state = me.StringField(required=True, default='stop', choices=PROCESSOR_OPERATING_STATE) compute_node = me.ReferenceField('ComputeNode', dbref=True) reports = me.ListField(me.EmbeddedDocumentField('ProcessorReport')) def push_processor_report(self, report): if len(self.reports) > MAX_RECORE: self.reports.pop(0) self.reports.append(report) def update_user_command(self, processor_command): if processor_command.type != 'user': return if 'streamer' in processor_command.action: self.user_command.streamer = processor_command elif 'recorder' in processor_command.action: self.user_command.recorder = processor_command def count_system_start_recorder(self, seconds=10): after_time = datetime.datetime.now() - datetime.timedelta(seconds) count = ProcessorCommand.objects( processor=self, action__in=['start-recorder', 'start-motion_recorder'], type='system', commanded_date__gt=after_time, ).count() return count @classmethod def pre_save(cls, sender, document, **kwargs): document.updated_date = datetime.datetime.now()
class PermissionGrant(mongoengine.Document): action = mongoengine.StringField(required=True) resource = mongoengine.ReferenceField(ResourceRegistration, required=True) role = mongoengine.ReferenceField(RoleRegistration, required=True)
class Line_Order(me.EmbeddedDocument): product = me.ReferenceField(Product) count = me.IntField(min_value=1, required=True) sum = me.DecimalField(min_value=1, force_string=True)
class Cloud(OwnershipMixin, me.Document): """Abstract base class for every cloud/provider mongoengine model This class defines the fields common to all clouds of all types. For each different cloud type, a subclass should be created adding any cloud specific fields and methods. Documents of all Cloud subclasses will be stored on the same mongo collection. One can perform a query directly on Cloud to fetch all cloud types, like this: Cloud.objects(owner=owner).count() This will return an iterable of clouds for that owner. Each cloud will be an instance of its respective Cloud subclass, like AmazonCloud and LinodeCloud instances. Clouds of a specific type can be queried like this: AmazonCloud.objects(owner=owner).count() This will return an iterable of AmazonCloud instances. To create a new cloud, one should initialize a Cloud subclass like AmazonCloud. Intializing directly a Cloud instance won't have any credential fields or associated handler to work with. Each Cloud subclass should define a `_controller_cls` class attribute. Its value should be a subclass of `mist.api.clouds.controllers.main.base.BaseMainController`. These subclasses are stored in `mist.api.clouds.controllers`. When a cloud is instanciated, it is given a `ctl` attribute which gives access to the clouds controller. This way it is possible to do things like: cloud = Cloud.objects.get(id=cloud_id) print cloud.ctl.compute.list_machines() """ id = me.StringField(primary_key=True, default=lambda: uuid.uuid4().hex) owner = me.ReferenceField(Organization, required=True, reverse_delete_rule=me.CASCADE) title = me.StringField(required=True) enabled = me.BooleanField(default=True) machine_count = me.IntField(default=0) starred = me.ListField() unstarred = me.ListField() polling_interval = me.IntField(default=0) # in seconds dns_enabled = me.BooleanField(default=False) observation_logs_enabled = me.BooleanField(default=False) default_monitoring_method = me.StringField( choices=config.MONITORING_METHODS) deleted = me.DateTimeField() meta = { 'strict': False, 'allow_inheritance': True, 'collection': 'clouds', # collection 'cloud' is used by core's model 'indexes': [ 'owner', # Following index ensures owner with title combos are unique { 'fields': ['owner', 'title', 'deleted'], 'sparse': False, 'unique': True, 'cls': False, } ], } _private_fields = () _controller_cls = None def __init__(self, *args, **kwargs): super(Cloud, self).__init__(*args, **kwargs) # Set attribute `ctl` to an instance of the appropriate controller. if self._controller_cls is None: raise NotImplementedError( "Can't initialize %s. Cloud is an abstract base class and " "shouldn't be used to create cloud instances. All Cloud " "subclasses should define a `_controller_cls` class attribute " "pointing to a `BaseMainController` subclass." % self) elif not issubclass(self._controller_cls, controllers.BaseMainController): raise TypeError( "Can't initialize %s. All Cloud subclasses should define a " "`_controller_cls` class attribute pointing to a " "`BaseMainController` subclass." % self) self.ctl = self._controller_cls(self) # Calculate and store cloud type specific fields. self._cloud_specific_fields = [ field for field in type(self)._fields if field not in Cloud._fields ] @classmethod def add(cls, owner, title, id='', **kwargs): """Add cloud This is a class method, meaning that it is meant to be called on the class itself and not on an instance of the class. You're not meant to be calling this directly, but on a cloud subclass instead like this: cloud = AmazonCloud.add(owner=org, title='EC2', apikey=apikey, apisecret=apisecret) Params: - owner and title are common and required params - only provide a custom cloud id if you're migrating something - kwargs will be passed to appropriate controller, in most cases these should match the extra fields of the particular cloud type. """ if not title: raise RequiredParameterMissingError('title') if not owner or not isinstance(owner, Organization): raise BadRequestError('owner') if Cloud.objects(owner=owner, title=title, deleted=None): raise CloudExistsError() cloud = cls(owner=owner, title=title) if id: cloud.id = id cloud.ctl.add(**kwargs) return cloud def delete(self): super(Cloud, self).delete() Tag.objects(resource_id=self.id, resource_type='cloud').delete() try: self.owner.mapper.remove(self) except Exception as exc: log.error("Got error %r while removing cloud %s", exc, self.id) try: if self.owned_by: self.owned_by.get_ownership_mapper(self.owner).remove(self) except Exception as exc: log.error("Got error %r while removing cloud %s", exc, self.id) def clean(self): if self.dns_enabled and not hasattr(self.ctl, 'dns'): self.dns_enabled = False def as_dict(self): cdict = { 'id': self.id, 'title': self.title, 'provider': self.ctl.provider, 'enabled': self.enabled, 'dns_enabled': self.dns_enabled, 'observation_logs_enabled': self.observation_logs_enabled, 'state': 'online' if self.enabled else 'offline', 'polling_interval': self.polling_interval, 'tags': { tag.key: tag.value for tag in Tag.objects(owner=self.owner, resource_id=self.id, resource_type='cloud').only( 'key', 'value') }, 'owned_by': self.owned_by.id if self.owned_by else '', 'created_by': self.created_by.id if self.created_by else '', } cdict.update({ key: getattr(self, key) for key in self._cloud_specific_fields if key not in self._private_fields }) return cdict def __str__(self): return '%s cloud %s (%s) of %s' % (type(self), self.title, self.id, self.owner)
class MUserStory(mongo.Document): """ Stories read by the user. These are deleted as the mark_read_date for the UserSubscription passes the UserStory date. """ user_id = mongo.IntField() feed_id = mongo.IntField() read_date = mongo.DateTimeField() story_id = mongo.StringField() story_date = mongo.DateTimeField() story = mongo.ReferenceField(MStory, dbref=True) found_story = mongo.GenericReferenceField() meta = { 'collection': 'userstories', 'indexes': [ { 'fields': ('user_id', 'feed_id', 'story_id'), 'unique': True }, ('feed_id', 'story_id'), # Updating stories with new guids ('feed_id', 'story_date'), # Trimming feeds ], 'allow_inheritance': False, 'index_drop_dups': True, 'cascade': False, } def save(self, *args, **kwargs): self.sync_redis() super(MUserStory, self).save(*args, **kwargs) def delete(self, *args, **kwargs): self.remove_from_redis() super(MUserStory, self).delete(*args, **kwargs) @property def guid_hash(self): return hashlib.sha1(self.story_id).hexdigest() @classmethod def delete_old_stories(cls, feed_id): UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta( days=settings.DAYS_OF_UNREAD) cls.objects(feed_id=feed_id, story_date__lte=UNREAD_CUTOFF).delete() @classmethod def delete_marked_as_read_stories(cls, user_id, feed_id, mark_read_date=None): if not mark_read_date: usersub = UserSubscription.objects.get(user__pk=user_id, feed__pk=feed_id) mark_read_date = usersub.mark_read_date # Next line forces only old read stories to be removed, just in case newer stories # come in as unread because they're being shared. mark_read_date = datetime.datetime.utcnow() - datetime.timedelta( days=settings.DAYS_OF_UNREAD) cls.objects(user_id=user_id, feed_id=feed_id, read_date__lte=mark_read_date).delete() @property def story_db_id(self): if self.story: return self.story.id elif self.found_story: if '_ref' in self.found_story: return self.found_story['_ref'].id elif hasattr(self.found_story, 'id'): return self.found_story.id story, found_original = MStory.find_story(self.feed_id, self.story_id) if story: if found_original: self.story = story else: self.found_story = story self.save() return story.id def sync_redis(self, r=None): if not r: r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) if self.story_db_id: all_read_stories_key = 'RS:%s' % (self.user_id) r.sadd(all_read_stories_key, self.story_db_id) read_story_key = 'RS:%s:%s' % (self.user_id, self.feed_id) r.sadd(read_story_key, self.story_db_id) r.expire(read_story_key, settings.DAYS_OF_UNREAD * 24 * 60 * 60) def remove_from_redis(self): r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) if self.story_db_id: r.srem('RS:%s' % self.user_id, self.story_db_id) r.srem('RS:%s:%s' % (self.user_id, self.feed_id), self.story_db_id) @classmethod def sync_all_redis(cls): read_stories = cls.objects.all() for read_story in read_stories: read_story.sync_redis()
class User(BaseDocument): username = mongoengine.StringField(required=True) email = mongoengine.StringField(required=True) password = mongoengine.StringField() salt = mongoengine.StringField() is_email_confirmed = mongoengine.BooleanField(default=False) email_confirmed_on = mongoengine.DateTimeField(default=None) oauths = mongoengine.ListField(mongoengine.ReferenceField('UserOauth')) paste_likes_count = mongoengine.IntField(default=0) pastes_count = mongoengine.IntField(default=0) @property def private_pastes_count(self): return len(self.pastes(is_private=True)) @property def public_pastes_count(self): return self.pastes_count - len(self.pastes(is_private=True)) @property def likes(self): return Like.objects(user=self) @property def pastes(self): return Paste.objects(user=self) def save(self, *args, **kwargs): if not self.salt: self.salt = hashlib.sha1(str(time.time())).hexdigest() self.password = self.generate_password(self.password) super(User, self).save(*args, **kwargs) def owns_record(self, record): return record.user == self def generate_password(self, string): return hashlib.sha1('%s%s' % (string, self.salt)).hexdigest() def check_login(self, password): return self.generate_password(password) == self.password def gravatar_url(self, width=80): return "https://cn.gravatar.com/avatar/%s?s=%d" % (hashlib.md5( self.email).hexdigest(), width) @classmethod def find_by_oauth(cls, provider, openid): """Find user that has oauth info with given provider and openid""" oauth = UserOauth.objects(provider=provider, openid=openid).first() if oauth and oauth.user: return oauth.user def is_in_favourites(self, paste): return paste in self.favourites def to_json(self): return { 'username': self.username, 'gravatar_url': self.gravatar_url(width=38) } def liked(self, paste): like = Like.objects(likeable=paste, user=self).first() return like is not None
class Approver(me.EmbeddedDocument): user = me.ReferenceField("User", required=True) approved_date = me.DateTimeField(required=True, default=datetime.datetime.now) ip_address = me.StringField(max_length=100, required=True, default='0.0.0.0')
class Key(OwnershipMixin, me.Document): """Abstract base class for every key/machine attr mongoengine model. This class defines the fields common to all keys of all types. For each different key type, a subclass should be created adding any key specific fields and methods. Documents of all Key subclasses will be stored on the same mongo collection. One can perform a query directly on Key to fetch all key types, like this: Key.objects(owner=owner).count() This will return an iterable of keys for that owner. Each key will be an instance of its respective Key subclass, like SSHKey and SignedSSHKey instances. Keys of a specific type can be queried like this: SSKey.objects(owner=owner).count() This will return an iterable of SSHKey instances. To create a new key, one should initialize a Key subclass like SSHKey. Initializing directly a Key instance won't have any fields or associated handler to work with. Each Key subclass should define a `_controller_cls` class attribute. Its value should be a subclass of `mist.api.keys.controllers.BaseKeyController'. These subclasses are stored in `mist.api.keys.BaseKeyController`. When a key is instanciated, it is given a `ctl` attribute which gives access to the keys controller. This way it is possible to do things like: key = SSKey.objects.get(id=key_id) key.ctl.generate() """ meta = { 'allow_inheritance': True, 'collection': 'keys', 'indexes': [ { 'fields': ['owner', 'name', 'deleted'], 'sparse': False, 'unique': True, 'cls': False, }, ], } id = me.StringField(primary_key=True, default=lambda: uuid4().hex) name = me.StringField(required=True) owner = me.ReferenceField(Owner) default = me.BooleanField(default=False) deleted = me.DateTimeField() _private_fields = () _controller_cls = None def __init__(self, *args, **kwargs): super(Key, self).__init__(*args, **kwargs) # Set attribute `ctl` to an instance of the appropriate controller. if self._controller_cls is None: raise NotImplementedError( "Can't initialize %s. Key is an abstract base class and " "shouldn't be used to create cloud instances. All Key " "subclasses should define a `_controller_cls` class attribute " "pointing to a `BaseController` subclass." % self) elif not issubclass(self._controller_cls, BaseKeyController): raise TypeError( "Can't initialize %s. All Key subclasses should define a" " `_controller_cls` class attribute pointing to a " "`BaseController` subclass." % self) self.ctl = self._controller_cls(self) # Calculate and store key type specific fields. self._key_specific_fields = [ field for field in type(self)._fields if field not in Key._fields ] @classmethod def add(cls, owner, name, id='', **kwargs): """Add key This is a class method, meaning that it is meant to be called on the class itself and not on an instance of the class. You 're not meant to be calling this directly, but on a key subclass instead like this: key = SSHKey.add(owner=org, name='unicorn', **kwargs) """ if not name: raise RequiredParameterMissingError('title') if not owner or not isinstance(owner, Owner): raise BadRequestError('owner') key = cls(owner=owner, name=name) if id: key.id = id key.ctl.add(**kwargs) return key def delete(self): super(Key, self).delete() mist.api.tag.models.Tag.objects(resource=self).delete() self.owner.mapper.remove(self) if self.owned_by: self.owned_by.get_ownership_mapper(self.owner).remove(self) def as_dict(self): # Return a dict as it will be returned to the API mdict = { 'id': self.id, 'name': self.name, 'owner': self.owner.id, 'default': self.default, 'owned_by': self.owned_by.id if self.owned_by else '', 'created_by': self.created_by.id if self.created_by else '', } mdict.update({ key: getattr(self, key) for key in self._key_specific_fields if key not in self._private_fields }) return mdict def __str__(self): return '%s key %s (%s) of %s' % (type(self), self.name, self.id, self.owner)
class Paste(BaseDocument): user = mongoengine.ReferenceField(User) title = mongoengine.StringField() hash_id = mongoengine.StringField(unique=True) is_private = mongoengine.BooleanField(default=False) codes = mongoengine.ListField(mongoengine.ReferenceField(Code)) tags = mongoengine.ListField(mongoengine.StringField()) rate = mongoengine.IntField(default=0) views = mongoengine.IntField(default=0) likes_count = mongoengine.IntField(default=0) def save(self, *args, **kwargs): self.create_hash_id(self.user.salt, 'paste') if not self.title: self.title = u'代码集合: %s' % self.hash_id super(Paste, self).save(*args, **kwargs) def increase_views(self): self.views = self.views + 1 self.save() def to_json(self): return { 'hash_id': self.hash_id, 'title': self.title, 'short_title': self.title[:30], 'tags': self.tags, 'num_codes': len(self.codes), 'time_passed': time_passed(self.updated_at), 'disqus_identifier': self.disqus_identifier, 'is_private': self.is_private, 'user': self.user.to_json() } def is_user_favourited(self): if request.user: return request.user.is_in_favourites(self) return False @property def disqus_identifier(self): return 'paste-%s' % self.hash_id def toggle_like_by(self, user, flag): filters = dict(likeable=self, user=user) if flag: Like.find_or_create_by(**filters) else: Like.find_and_delete_by(**filters) return { 'paste_id': self.hash_id, 'user_like': user.reload().paste_likes_count, 'paste_likes': self.reload().likes_count, 'liked': flag } def is_user_owned(self, user): return self.user == user @classmethod def post_save(cls, sender, document, **kwargs): if kwargs.get('created'): document.user.increase_counter('pastes') @classmethod def post_delete(cls, sender, document, **kwargs): document.user.increase_counter('pastes', -1)
class Post(mongo.Document): author = mongo.ReferenceField(Author) title = mongo.StringField(required=True, max_length=300) text = mongo.StringField(required=True)
class FollowerConnections(me.EmbeddedDocument): follower = me.ReferenceField('Account') distance = me.IntField()
class RoleAssignment(TrackedAssignment): role = me.StringField(required=True) user = me.ReferenceField('User', required=True)
class Message(mongoengine.Document): author: User = mongoengine.ReferenceField(User, required=True) room: Chatroom = mongoengine.ReferenceField(Chatroom, required=True) message: dict = mongoengine.DictField(required=True, default=dict) timeSent: datetime.datetime = mongoengine.DateTimeField( required=True, default=datetime.datetime.utcnow)
class User(me.Document): """ status : 'wait for approval' -> wait member approve this profile : 'activate' -> this profile are approve """ meta = {'collection' : 'users'} username = me.StringField(required=True, unique=True) password = me.StringField() email = me.EmailField(required=True, unique=True) first_name = me.StringField(max_length=100, required=True) last_name = me.StringField(max_length=100, required=True) display_name = me.StringField(max_length=250, required=True) default_profile = me.StringField(default='pumbaa.coe.psu.ac.th') online_profiles = me.ListField(me.EmbeddedDocumentField(Profile)) status = me.StringField(max_length=100, required=True, default='wait for approval') registration_date = me.DateTimeField(required=True, default=datetime.datetime.now) updated_date = me.DateTimeField(required=True, default=datetime.datetime.now) approvers = me.ListField(me.EmbeddedDocumentField(Approver)) ip_address = me.StringField(max_length=100, required=True, default='0.0.0.0') roles = me.ListField(me.ReferenceField('Role', dbref=True)) def get_display_name(self): if self.display_name is not None: return self.display_name else: return self.username def set_password(self, password): from pyramid.threadlocal import get_current_request request = get_current_request() self.password = request.secret_manager.get_hash_password(password) def get_profile(self, domain): for profile in self.online_profiles: if profile.domain == domain: return profile def get_role(self, name): for role in self.roles: if role.name == name: return role def get_profile_picture(self, width=50): if self.default_profile == 'pumbaa.coe.psu.ac.th': return None profile = self.get_profile(self.default_profile) if profile.domain == 'facebook.com': if '=' in profile.username: username = profile.username.split('=')[-1] else: username = profile.username return '<img src="https://graph.facebook.com/%s/picture" width="%d"/>'%(username, width) if profile.domain == 'twitter.com': return '<img src="%s" width="%d"/>'%(profile.profile_source['photos'][0]['value'], width) if profile.domain == 'accounts.google.com': return '<img src="%s" width="%d"/>'%(profile.profile_source['photos'][0]['value'], width) return None def get_profile_url(self): if self.default_profile == 'pumbaa.coe.psu.ac.th': return '#' profile = self.get_profile(self.default_profile) if profile.domain == 'facebook.com': return 'https://www.facebook.com/%s'%profile.username if profile.domain == 'twitter.com': return 'https://twitter.com/%s'%profile.username if profile.domain == 'accounts.google.com': return 'https://plus.google.com/%s'%profile.user_id return '#'
class Exit(mongoengine.Document): name = mongoengine.StringField(required=True) destination = mongoengine.ReferenceField('Room', required=True) description = mongoengine.StringField() visible = mongoengine.StringField(choices=['listed', 'hidden', 'obvious'], default='listed') is_open = mongoengine.BooleanField(default=True) key_names = mongoengine.ListField(mongoengine.StringField()) room = mongoengine.ReferenceField('Room', default=None) def __init__(self, *args, save_on_creation=True, **kwargs): super().__init__(*args, **kwargs) if self.id is None and save_on_creation: self.save() def save(self): self.ensure_i_am_valid() super().save() def ensure_i_am_valid(self): name_conditions = self._get_name_validation_conditions( self.name, self.room, self) for condition in name_conditions.values(): if not condition['condition']: raise condition['exception'] @classmethod def _get_name_validation_conditions(cls, exit_name, local_room, ignore_item=None): return item_module.Item._get_name_validation_conditions( exit_name, local_room, ignore_item) @classmethod def name_is_valid(cls, exit_name, local_room, ignore_item=None): return item_module.Item.name_is_valid(exit_name, local_room, ignore_item) def add_key(self, item_name): self.key_names.append(item_name) self.save() def remove_key(self, item_name): self.key_names.remove(item_name) self.save() def open(self): self.is_open = True self.save() def close(self): self.is_open = False self.save() def is_obvious(self): return self.visible == 'obvious' def is_listed(self): return self.visible == 'listed' def is_hidden(self): return self.visible == 'hidden' def clone(self, new_destination, new_room=None): new_exit = Exit(name=self.name, destination=new_destination, room=new_room, visible=self.visible, is_open=self.is_open, key_names=self.key_names.copy()) return new_exit @classmethod def get_exits_in_world_state(cls, world_state): exits_in_world_state = [] for room in room_module.Room.objects(world_state=world_state): exits_in_world_state += room.exits return exits_in_world_state
class ChildRegisteredAfter(mongoengine.Document): meta = {"collection": "test_child_after_reference"} parent = mongoengine.ReferenceField(ParentWithRelationship) name = mongoengine.StringField()
class Project(mongoengine.Document): """ A project is the highest controlling structure of an analysis and houses all the experiments, their associated FileGroups and the populations contained in each FileGroup and the populations clusters. Project can be used to create new experiments and to load existing experiments to interact with. Attributes ---------- project_id: str, required unique identifier for project subjects: list List of references for associated subjects; see Subject start_date: DateTime date of creation owner: str, required user name of owner experiments: list List of references for associated fcs files """ project_id = mongoengine.StringField(required=True, unique=True) subjects = mongoengine.ListField( mongoengine.ReferenceField(Subject, reverse_delete_rule=4)) start_date = mongoengine.DateTimeField(default=datetime.datetime.now) owner = mongoengine.StringField(requred=True) experiments = mongoengine.ListField( mongoengine.ReferenceField(Experiment, reverse_delete_rule=4)) meta = {'db_alias': 'core', 'collection': 'projects'} def list_experiments(self) -> Generator: """ Generate a list of associated flow cytometry experiments Returns ------- Generator list of experiment IDs """ for e in self.experiments: yield e.experiment_id def load_experiment(self, experiment_id: str) -> Experiment: """ Load the experiment object for a given experiment ID Parameters ---------- experiment_id: str experiment to load Returns -------- Experiment """ assert experiment_id in list(self.list_experiments( )), f'Error: no experiment {experiment_id} found' return Experiment.objects(experiment_id=experiment_id).get() def add_experiment(self, experiment_id: str, data_directory: str, panel_name: str or None = None, panel_definition: str or None = None) -> Experiment: """ Add new experiment to project. Note you must provide either a path to an excel template for the panel definition (panel_definition) or the name of an existing panel (panel_name). If panel_definition is provided, then the panel_name will be used to name the new Panel document associated to this experiment. If no panel_name is provided, then the panel name will default to "{experiment_id}_panel". Parameters ----------- experiment_id: str experiment name data_directory: str Path where experiment events data files will be stored panel_name: str (optional) Name of panel to associate to experiment panel_definition: str (optional) Path to excel template for generating the panel Returns -------- Experiment Newly created FCSExperiment """ err = f'Error: Experiment with id {experiment_id} already exists!' assert experiment_id not in list(self.list_experiments()), err exp = Experiment(experiment_id=experiment_id, panel_definition=panel_definition, panel_name=panel_name, data_directory=data_directory) exp.save() self.experiments.append(exp) self.save() return exp def add_subject(self, subject_id: str, drug_data: list or None = None, infection_data: list or None = None, patient_biology: list or None = None, **kwargs) -> Subject: """ Create a new subject and associated to project; a subject is an individual element of a study e.g. a patient or a mouse Parameters ----------- subject_id: str subject ID for the new subject drug_data: list, optional list of Drug documents to associated to subject (see cytopy.data.subject.Drug) infection_data: list, optional list of Bug documents to associated to subject (see cytopy.data.subject.Bug) patient_biology: list, optional list of Biology documents to associated to subject (see cytopy.data.subject.Biology) kwargs: Additional keyword arguments to pass to Subject initialisation (see cytopy.data.subject.Subject) Returns -------- None """ new_subject = Subject(subject_id=subject_id, **kwargs) if drug_data is not None: new_subject.drug_data = drug_data if infection_data is not None: new_subject.infection_data = infection_data if patient_biology is not None: new_subject.patient_biology = patient_biology new_subject.save() self.subjects.append(new_subject) self.save() return new_subject def list_subjects(self) -> Generator: """ Generate a list of subject ID for subjects associated to this project Returns -------- Generator List of subject IDs """ for s in self.subjects: yield s.subject_id def get_subject(self, subject_id: str) -> Subject: """ Given a subject ID associated to Project, return the Subject document Parameters ----------- subject_id: str subject ID to pull Returns -------- Subject """ assert subject_id in list(self.list_subjects()), f'Invalid subject ID, valid subjects: ' \ f'{list(self.list_subjects())}' return Subject.objects(subject_id=subject_id).get() def delete(self, *args, **kwargs) -> None: """ Delete project (wrapper function of mongoengine.Document.delete) Parameters ----------- args: positional arguments to pass to parent call (see mongoengine.Document.delete) kwargs: keyword arguments to pass to parent call (see mongoengine.Document.delete) Returns -------- None """ experiments = [ self.load_experiment(e) for e in list(self.list_experiments()) ] for e in experiments: samples = e.list_samples() for s in samples: e.remove_sample(s) if e.panel: e.panel.delete() e.delete() for p in self.subjects: p.delete() super().delete(*args, **kwargs)
class User(mongo.Document): Id = mongo.ObjectIdField() FirstName = mongo.StringField(required=True) LastName = mongo.StringField(required=True) Email = mongo.StringField(required=True) CareerTimelines = mongo.ReferenceField(CareerTimeline)
class ResourceRegistration(mongoengine.Document): name = mongoengine.StringField() actions = mongoengine.ListField(default=list(["access"])) service = mongoengine.ReferenceField(ServiceRegistration, required=False)
class Customer(mongoengine.Document): person = mongoengine.ReferenceField(Person) employed = mongoengine.BooleanField(default=False)
class RoleUserStore(mongoengine.Document): user = mongoengine.ReferenceField(registrationModels.UserRegistration) role = mongoengine.ReferenceField(RoleRegistration)
class Tesoro(me.Document): id = me.IntField(primary_key=True, default=1) name = me.StringField() score = me.StringField() juego_id = me.ListField(me.ReferenceField('Juego')) zona_id = me.ListField(me.ReferenceField('Zona'))
class Order(me.Document): ORDER_ACTIVE = 'active' ORDER_PROCESSED = 'processed' ORDER_COMPLETED = 'completed' ORDER_CANCELED = 'canceled' STATUS_CONSTANT = ((ORDER_CANCELED, 'order canceled'), (ORDER_COMPLETED, 'order completed'), (ORDER_ACTIVE, 'order active'), (ORDER_PROCESSED, 'order processed')) REQUEST_TELEPHONE = 'request_telephone' REQUEST_NAME = 'request_name' LAST_REQUEST = ((REQUEST_TELEPHONE, 'request_telephone'), (REQUEST_NAME, 'request_name')) nom = me.IntField(min_value=1) date = me.DateTimeField(default=datetime.now()) user = me.ReferenceField(User, reverse_delete_rule=me.DENY) sum = me.DecimalField(min_value=0, force_string=True, default=0) status = me.StringField(min_length=5, choices=STATUS_CONSTANT, default=ORDER_ACTIVE, required=True) products = me.EmbeddedDocumentListField(Line_Order) name_recipients = me.StringField(min_length=3, max_length=255) telephone_recipients = me.StringField(min_length=10, max_length=12, regex='^[0-9]*$') last_request = me.StringField(min_length=5, choices=LAST_REQUEST) id_message_cart = me.ListField() def get_text_status_order(self): if self.status == Order.ORDER_CANCELED: return Text.get_body(Text.TEXT_ORDER_CANCELED) elif self.status == Order.ORDER_ACTIVE: return Text.get_body(Text.TEXT_ORDER_ACTIVE) elif self.status == Order.ORDER_COMPLETED: return Text.get_body(Text.TEXT_ORDER_COMPLETED) else: return Text.get_body(Text.TEXT_ORDER_PROCESSED) def add_count_in_line(self, num: int): line_product = self.products[num] line_product.count += 1 line_product.sum = line_product.count * line_product.product.actual_price self.sum = self.get_sum_order() self.save() def sub_count_in_line(self, num: int): line_product = self.products[num] if line_product.count == 1: return line_product.count -= 1 line_product.sum = line_product.count * line_product.product.actual_price self.sum = self.get_sum_order() self.save() def add_product_to_order(self, product: Product, count: int): try: line_product = self.products.get(product=product) line_product.count += count line_product.sum = line_product.count * product.actual_price except me.DoesNotExist: self.products.create(product=product, count=count, sum=count * product.actual_price) self.sum = self.get_sum_order() self.save() def get_sum_order(self): # Не працює функція сум для такого поля. Мінімум - працює, по полю кількості - працює, а по сумі ні. # Тулитиму костиль # sums = Order.objects(id=self.id).aggregate([ # {'$unwind': '$products'}, # {'$group': {'_id': '$_id', 'sum_products': {'$sum': '$products.sum'}}} # ]) # if sums.alive: # elem = sums.next() # print(elem['sum_products']) # return elem['sum_products'] # else: # return 0 total_sum = 0 for product in self.products: total_sum += product.sum return total_sum @classmethod def find_active_order(cls, user: User): try: order = cls.objects().get( Q(user=user) & Q(status=Order.ORDER_ACTIVE)) except me.DoesNotExist: order = None return order @classmethod def get_max_num_orders(cls, user: User): max_num = cls.objects(user=user).aggregate([{ '$group': { '_id': '$user', 'max_num': { '$max': '$nom' } } }]) if max_num.alive: elem = max_num.next() return elem['max_num'] else: return 0 @classmethod def get_count_orders(cls, user: User): return cls.objects(user=user).count() @classmethod def create_order(cls, user: User): return cls.objects.create(user=user, nom=cls.get_max_num_orders(user) + 1) @classmethod def get_active_order(cls, user: User) -> 'Order': active_orders = cls.find_active_order(user) if not active_orders: active_orders = cls.create_order(user) return active_orders @classmethod def get_count_products_in_active_order(cls, user): sums = cls.objects(Q(user=user) & Q(status=Order.ORDER_ACTIVE)).aggregate([{ '$unwind': '$products' }, { '$group': { '_id': '$_id', 'count_products': { '$sum': '$products.count' } } }]) if sums.alive: elem = sums.next() return elem['count_products'] else: return 0
class Project(me.Document): organization = me.ReferenceField('Organization', required=False, reverse_delete_rule=me.CASCADE, default=None) # these four will come in request data for put title = me.StringField(max_length=64, required=True) permalink = me.StringField(required=True, unique=True) start_date = me.DateTimeField(default=datetime.utcnow()) end_date = me.DateTimeField(default=datetime.utcnow()) duration = me.IntField() # sprint duration updates = me.ListField() hashtags = me.ListField() # following has to be updated at time of saving object sequence = me.IntField() sprints = me.ListField() members = me.ListField() admin = me.ListField(me.ReferenceField('User')) is_active = me.BooleanField(default=True) description = me.StringField(max_length=500) roles = me.ListField(default=PROJECT_ROLES) is_todo = me.BooleanField(default=False) # these have to be moved to base model created_by = me.ReferenceField('User', required=True, dbref=True) updated_by = me.ReferenceField('User', required=True, dbref=True) created_at = me.DateTimeField(default=datetime.utcnow()) updated_at = me.DateTimeField(default=datetime.utcnow()) deleted_at = me.DateTimeField() deleted_by = me.ReferenceField('User', dbref=True) meta = {'indexes': ['title', 'permalink']} def __init__(self, *args, **values): super(Project, self).__init__(*args, **values) def __str__(self): return self.title def to_json(self, fields=None, exclude=None): return json_dumper(self, fields, exclude) def clean(self): permalink = self.get_permalink() if Project.objects.filter(permalink=permalink).count() > 0: raise ValidationError('Duplicate project') if self.start_date > self.end_date: raise ValidationError( 'start date should be greater than end date.') def get_permalink(self): owner = self.organization.name if self.organization else\ self.created_by.username permalink = slugify(owner) + '/' + slugify(self.title) return permalink @classmethod def last_project_id(cls, organization=None): sequence = None if not organization: if Project.objects: sequence = list( Project.objects.order_by('sequence'))[-1].sequence elif organization: projects = Project.objects.filter( organization=organization).order_by('sequence') if projects: sequence = list(projects)[-1].sequence return sequence @classmethod def pre_save(cls, sender, document, **kwargs): ''' 1. check if project already exists, 2. create id for project ''' if document.organization and \ document.organization not in document.created_by.belongs_to: raise ValidationError('You do not belong to this organization.') last_sequence = cls.last_project_id(document.organization) if last_sequence: document.sequence = last_sequence + 1 else: document.sequence = 1 if len(document.title) > 64: raise ValidationError('Title exceeds 64 characters') if len(document.description) > 500: raise ValidationError('Description exceeds 500 characters') @classmethod def post_save(cls, sender, document, **kwargs): ''' 1. update sequence value ''' if document.sequence: document.update(set__sequence=document.sequence, set__members=[document.created_by], set__admin=[document.created_by]) def create_sprints(self): # for todo try: Sprint.objects.get(sequence=-1, project=self) except Sprint.DoesNotExist: Sprint.objects.create(project=self, created_by=self.created_by, updated_by=self.updated_by, sequence=-1, start_date=self.start_date, end_date=self.end_date) for (idx, sprint) in enumerate(self.sprints): if idx != 0: proj_start_date = self.start_date sprint_duration = int(self.duration) sprint_start_date = proj_start_date + timedelta(days=( (idx - 1) * sprint_duration)) sprint_end_date = sprint_start_date + timedelta( days=sprint_duration) try: Sprint.objects.get(sequence=idx, project=self) except Sprint.DoesNotExist: Sprint.objects.create(sequence=idx, project=self, start_date=sprint_start_date, end_date=sprint_end_date, created_by=self.created_by, updated_by=self.updated_by) elif idx == 0: # for backlog try: Sprint.objects.get(sequence=idx, project=self) except Sprint.DoesNotExist: Sprint.objects.create(project=self, created_by=self.created_by, updated_by=self.updated_by) def calculate_sprints(self): project_duration = (self.end_date - self.start_date).days if not self.duration: self.duration = project_duration self.update(set__duration=self.duration) sprints = project_duration / self.duration # in case duration is of form 7K + 1, one sprint has to be added self.update(set__sprints=['Sprint -1']) self.create_sprints() else: self.update(set__duration=self.duration) sprints = project_duration / self.duration # in case duration is of form 7K + 1, one sprint has to be added difference = project_duration - (self.duration * sprints) if difference > 0 and difference < self.duration: sprints += 1 sprint_list = ['Backlog'] sprint_list.extend( ['Sprint ' + str(idx) for idx in range(1, sprints + 1)]) self.update(set__sprints=sprint_list) self.create_sprints() def get_current_sprint(self): now = datetime.utcnow() sprints = Sprint.objects.filter(project=self, sequence__nin=[0, -1], start_date__lte=now, end_date__gte=now) if len(sprints) == 1: curr_sprint = sprints[0] elif self.start_date > now: curr_sprint = Sprint.objects.get(project=self, sequence=0) else: curr_sprint = Sprint.objects.get(project=self, sequence=(len(self.sprints) - 2)) return curr_sprint @classmethod def get_project_object(cls, sequence=None, organization=None): if not organization: try: project = Project.objects.get(sequence=sequence, is_active=True) except Project.DoesNotExist, error: raise ValidationError(error.message) elif organization: try: project = Project.objects.get(sequence=sequence, organization=organization, is_active=True) except Project.DoesNotExist, error: raise ValidationError(error.message)
class UserProcessorCommand(me.EmbeddedDocument): streamer = me.ReferenceField('ProcessorCommand', dbref=True) recorder = me.ReferenceField('ProcessorCommand', dbref=True)
class Doc(me.Document): id = me.StringField(primary_key=True, default='main') ref = me.ReferenceField(ReferenceDoc)
class Post(mongoengine.Document): owner = mongoengine.ReferenceField(User, reverse_delete_rule=mongoengine.CASCADE) a = mongoengine.StringField()
class ProfileTransaction(mongoengine.Document): chat_user_profile = mongoengine.ReferenceField(ChatUserProfile) score_delta = mongoengine.IntField(required=True) issuer = mongoengine.ReferenceField(ChatUserProfile, required=True) message = mongoengine.DictField()