예제 #1
0
class Product(DynamicDocument, BizBase):
    """Base of all specific Product-classes for each industry and company.
    A Product actually describes a product-class, NOT a product-instance. E.g. consider the following:
    Product
    |-Car
      |-ElectricCar
    then a list of Product-instances may look like:
    (1) brand: Toyota  model: Prius Plugin type: Executive
    (2) brand: Toyota  model: Prius Plugin type: Executive
    (3) brand: Toyota  model: Prius Plugin type: Comfort
    (4) brand: Toyota  model: Prius Plugin type: Business
    A specific instance is created using ProductInstance, with additional data like color, 
    mileage etc."""
    name = StringField()
    type_of = GenericReferenceField()
    part_of = ListField(GenericReferenceField())  # Originaly it was a ReferenceField('self'), but this can break if a class
    parts = ListField(GenericReferenceField())    # inherits from Product and 
    variety = StringField()
    meta = {'allow_inheritance': True,
            'indexes': ['name', ('name', 'variety')]}
    def factory(self, **kwargs):
        """abstract factory for instances. Tbd: how instances are created and connected to their product.
        Work out a complete example for Odin to clear things up."""
        kwargs['product'] = self
        return ProductInstance(**kwargs)
예제 #2
0
class Qualifier(Document, BizBase):
    """Qualifies the relationship of the referenced objects.
    Links two objects together (attributes 'first' and 'second'). A simple qualification
    can be given in the string 'qualification', an elaborate one can be given in the
    dynamic embedded document 'doc'.
    When a qualification of three or more connected objects is needed, a new qualifier must 
    be designed."""
    first = GenericReferenceField()
    second = GenericReferenceField()
    qualification = StringField()
    doc = EmbeddedDocumentField(Qualification)

    @classmethod
    def link(cls, first, second, qualification=None):
        q = cls(first=first, second=second, qualification=qualification)
        q.save()
        return q

    @classmethod
    def get(cls, first, second, ignore_order=True):
        """Retrieve the qualifier for the specified objects. Try it both ways of ignore_order 
        is set (try first, second and then second, first). Return the simple qualification if 
        present; the doc overrules the qualification string if present."""
        q = cls.objects(first=first, second=second).first()
        if not q:
            q = cls.objects(first=second, second=first).first()
        if not q:
            return None
        return q.doc if q.doc else q.qualification
예제 #3
0
class UserRatings(DynamicDocument):
    """
    This is for storing feedback given to client or seller
    """
    count = IntField()
    feedback = StringField()
    client = GenericReferenceField()
    gig = GenericReferenceField()
    date = DateTimeField(default=datetime.now())
예제 #4
0
파일: audit.py 프로젝트: qinxiaoapp/vinz
class ActivityLog(Document):
    """
    Keep track of user activities
    Example: Matthew added a user "max" to server "host1"
    Example: User "max" uploaded a new public key
    """
    actor = ReferenceField('User')
    timestamp = DateTimeField(default=datetime.datetime.now)
    obj = GenericReferenceField()
    secondary_obj = GenericReferenceField(required=False)

    # Possible values defined in constants.AUDIT_ACTIONS
    action = StringField()
예제 #5
0
class CORD19Document(VespaDocument):
    meta = {"collection": "CORD_parsed_vespa",
            "indexes": indexes
            }

    latest_version = latest_version
    unparsed_document = GenericReferenceField(required=True)
예제 #6
0
class Volume(Document):
    name = StringField(required=True)
    comic = GenericReferenceField()
    issues = ListField(ReferenceField(Issue))

    def __str__(self):
        s = "Volume(%s, %s, %s)" % (self.id, self.name, self.comic.title)
        return s
예제 #7
0
class Issue(Document):
    number = StringField()
    comic = GenericReferenceField()
    is_read = BooleanField(default=False)
    is_stock = BooleanField(default=False)

    def __str__(self):
        s = "Issue(%s # %s, %s)" % (self.comic.title, self.number, self.is_read)
        return s
예제 #8
0
class SupplementaryConceptRecord(MeshTerm):
    frequency = IntField()
    note = StringField()
    mapped_to_headings = ListField(GenericReferenceField())
    sources = ListField()

    def __init__(self, record: OrderedDict = None, *args, **kwargs):
        super(SupplementaryConceptRecord,
              self).__init__(record, *args, **kwargs)

        if record is not None:
            self.frequency = record[
                "Frequency"] if "Frequency" in record else None
            self.note = record["Note"] if "Note" in record else None

            if "HeadingMappedToList" in record:
                descriptors = []
                qualifiers = []
                refs = []
                heading_mapped_to_list = record["HeadingMappedToList"][
                    "HeadingMappedTo"]
                if isinstance(heading_mapped_to_list, list):
                    for ref in heading_mapped_to_list:
                        if "DescriptorReferredTo" in ref:
                            descriptors.append(ref["DescriptorReferredTo"]
                                               ["DescriptorUI"].replace(
                                                   "*", ""))
                        elif "QualifierReferredTo" in ref:
                            qualifiers.append(ref["QualifierReferredTo"]
                                              ["QualifierUI"].replace("*", ""))
                else:
                    if "DescriptorReferredTo" in heading_mapped_to_list:
                        descriptors.append(
                            heading_mapped_to_list["DescriptorReferredTo"]
                            ["DescriptorUI"])
                    if "QualifierReferredTo" in heading_mapped_to_list:
                        qualifiers.append(
                            heading_mapped_to_list["QualifierReferredTo"]
                            ["QualifierUI"])
                if len(descriptors) > 0:
                    for d in Descriptor.objects(uid__in=descriptors):
                        refs.append(d)
                    (refs.append(d)
                     for d in Descriptor.objects(uid__in=descriptors))
                if len(qualifiers) > 0:
                    (refs.append(q)
                     for q in Qualifier.objects(uid__in=qualifiers))
                if len(refs) > 0:
                    self.mapped_to_headings = refs

            if "SourceList" in record:
                if isinstance(record["SourceList"]["Source"], list):
                    self.sources = record["SourceList"]["Source"]
                else:
                    self.sources = [record["SourceList"]["Source"]]
예제 #9
0
class Customer(Document, BizBase):
    meta = {'allow_inheritance': True}
    name = StringField()
    address = ListField(ReferenceField(Address))
    email = ListField(ReferenceField(Email))
    others = ListField(GenericReferenceField())
    products = ListField(ReferenceField(ProductInstance))

    def link(self, other, qualification=None):
        self.others.append(other)
        other.others.append(self)
        self.save()
        other.save()
        if qualification:
            return Qualifier.link(self, other, qualification)
예제 #10
0
class VariantCall(Call):

    meta = {'indexes': [
        {
            'fields': ['call_set']
        },
        {
            'fields': ['variant']
        }
    ]
    }
    variant = ReferenceField('Variant', required=True)  # Not in ga4gh
    # If this field is not null, this variant call's genotype ordering implies
    # the phase of the bases and is consistent with any other variant calls on
    # the same contig which have the same phaseset string.
    phaseset = GenericReferenceField(default=None)

    @classmethod
    def create(cls, variant, genotype, call_set=None, genotype_likelihoods=[],
               phaseset=None, info={}):
        if isinstance(genotype, str):
            genotype = convert_string_gt_to_list_int_gt(variant, genotype)
        if variant:
            cls._check_genotype_likelihood_length(
                genotype_likelihoods,
                variant)
        return cls(
            variant=variant,
            genotype=genotype,
            call_set=call_set,
            genotype_likelihoods=genotype_likelihoods,
            phaseset=phaseset,
            info=info)

    @classmethod
    def _check_genotype_likelihood_length(cls, genotype_likelihood, variant):
        if len(variant.alternate_bases) == 1:
            if not len(genotype_likelihood) == 3:
                raise ValueError(
                    "Biallelic sites should have 3 genotype likelihoods. AA,AB,BB")
        elif len(variant.alternate_bases) == 2:
            if not len(genotype_likelihood) == 6:
                raise ValueError(
                    "Biallelic sites should have 6 genotype likelihoods. AA,AB,BB,AC,BC,CC, etc")
        else:
            raise NotImplementedError(
                "Haven't implemented check for > triallelic sites")
예제 #11
0
class Sample(db.Document, CommentsMixin):
    delivery_date = DateTimeField(default=TimeFunctions.get_timestamp, required=True)
    first_seen = DateTimeField(default=TimeFunctions.get_timestamp, required=True)
    tags = ListField(StringField(regex=r'^[\w:\-\_\/\+\.]+$'))
    dispatched_to = ListField(ReferenceField(AnalysisSystem))
    created_by = GenericReferenceField()
    tlp_level = TLPLevelField(verbose_name='TLP Level', help_text='Privacy level of this sample', required=True)

    meta = {
        'allow_inheritance': True,
        'ordering': ['-delivery_date'],
        'indexes': ['delivery_date'],
        'queryset_class': SampleQuerySet
    }

    def __repr__(self):
        return '[{}] {}'.format(str(self.__class__.__name__), str(self.id))

    def __str__(self):
        return self.__repr__()

    @property
    def title(self):
        return self.id

    def add_tags(self, tags):
        self.tags = ListFunctions.merge_lists_without_duplicates(self.tags, tags)
        self.save()

    def _update(self, **kwargs):
        if 'first_seen' in kwargs and kwargs['first_seen'] < self.first_seen:
            self.first_seen = kwargs['first_seen']
        if 'tlp_level' in kwargs and not self.tlp_level:
            self.tlp_level = kwargs['tlp_level']
        if current_authenticated_entity.is_authenticated and not self.created_by:
            self.created_by = current_authenticated_entity._get_current_object()
        if 'tags' in kwargs:
            tags = kwargs['tags']
        else:
            tags = []
        self.tags = ListFunctions.merge_lists_without_duplicates(self.tags, tags)

    @classmethod
    def create_or_update(cls, **kwargs):
        raise ValidationError('Samples of the base type Sample should not be instantiated directly.')
예제 #12
0
class CartItem(EmbeddedDocument):
    item = GenericReferenceField()
    name = StringField()
    local_name = StringField()
    amount = FloatField()
    price = FloatField()
    total_price = FloatField()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def get_safe(self) -> dict:
        res = document_to_dict(self)
        if self.item:
            res['item'] = self.item.get_safe()
        return res

    def create_xml(self, amount=None) -> list:
        amount = amount if amount is not None else self.amount
        item = self.item
        res = ET.Element('Товар')
        ET.SubElement(res, 'Ид').text = str(item.id)
        ET.SubElement(res, 'Наименование').text = item.NomenclatureType
        measure = ET.Element('БазоваяЕдиница')
        measure.text = item.MeasureName
        measure.attrib['Код'] = item.MeasureCode
        measure.attrib['НаименованиеПолное'] = item.MeasureName
        measure.attrib['МеждународноеСокращение'] = item.MeasureInt
        res.append(measure)
        ET.SubElement(res, 'ЦенаЗаЕдиницу').text = str(self.price)
        ET.SubElement(res, 'Количество').text = str(amount)
        ET.SubElement(res, 'Сумма').text = str(round(self.price * amount, 2))
        recs = ET.Element('ЗначенияРеквизитов')
        rec1 = ET.Element('ЗначениеРеквизита')
        ET.SubElement(rec1, 'Наименование').text = 'ВидНоменклатуры'
        ET.SubElement(rec1, 'Значение').text = item.NomenclatureType
        rec2 = ET.Element('ЗначениеРеквизита')
        ET.SubElement(rec2, 'Наименование').text = 'ТипНоменклатуры'
        ET.SubElement(rec2, 'Значение').text = 'Товар'
        recs.append(rec1)
        recs.append(rec2)
        res.append(recs)

        return [res]
예제 #13
0
class Comment(db.Document):
    post = GenericReferenceField()
    user = ReferenceField(User, reverse_delete_rule=CASCADE)
    content = StringField(default='')
    liked = ListField(ReferenceField(User,
                                     deref=True,
                                     reverse_delete_rule=PULL),
                      default=lambda: [])
    created = DateTimeField(default=datetime.datetime.now)
    meta = {'ordering': ['created'], 'strict': False}

    def __unicode__(self):
        return self.content

    def to_dict(self):
        return {
            'user': self.user.to_dict_public(),
            'created': str(self.created),
            'content': self.content,
            'id': str(self.id)
        }
예제 #14
0
class User(DynamicDocument):
    email = StringField(unique=True)
    password = StringField()
    profile_pic = StringField()
    pinned_board = ListField(GenericReferenceField())

    def encrypt_set_password(self, password):
        self.password = pwd_context.encrypt(password)

    @staticmethod
    def authenticate(email, password):
        user = User.objects(email=email).first()
        if user:
            user.id = str(user.id)
            if pwd_context.verify(password, user.password):
                return user
        return None

    @staticmethod
    def identity(payload):
        user = User.objects(id=payload['identity']).first()
        g.user = user
        user.id = str(user.id)
        return user
예제 #15
0
class Author(Agent):
    meta = {"collection": "Authors"}
    type = StringField(required=False)
    followers_ids = ListField(IntField(), required=True, default=list)
    friends_ids = ListField(IntField(), required=True, default=list)

    tweets = ListField(GenericReferenceField(Tweet),
                       required=True,
                       default=list)
    retweets = IntField(required=True, default=0)
    retweeted_tweets = IntField(required=True, default=0)
    links = IntField(required=True, default=0)
    replies_to_others = IntField(required=True, default=0)
    mentions_by_others = IntField(required=True, default=0)
    feature_vector = ListField(FloatField(), required=True, default=list)

    followers_history = ListField(EmbeddedDocumentField(History),
                                  required=True,
                                  default=list)
    friends_history = ListField(EmbeddedDocumentField(History),
                                required=True,
                                default=list)

    def get_feature_vector(self):
        '''
        If a feature vector exists it returns it otherwise it creates it.
        '''
        if len(self.feature_vector) == 0:
            self.calculate_author_stats()
            total_tweets = len(self.tweets)
            vector = numpy.zeros(6, dtype=float)
            vector[0] = self.retweets / float(total_tweets)  #retweet ratio
            vector[1] = self.links / float(total_tweets)  #links ratio
            vector[2] = float(
                total_tweets
            ) / self.retweeted_tweets  #how often this author gets retweeted
            vector[3] = self.replies_to_others / float(
                total_tweets)  #how many of them are replies
            vector[4] = self.mentions_by_others
            if self.friends_count != 0:
                vector[5] = self.followers_count / float(self.friends_count)
            else:
                #Add 1 to friends count to avoid division by zero
                vector[5] = self.followers_count / (self.friends_count + 1.0)

            self.feature_vector = vector
        return self.feature_vector

    def calculate_author_stats(self):
        '''
        Parses the entire list of this author's tweets and calculates stats
        '''
        for tweet in self.tweets:
            self.update_retweeted(tweet)
            self.update_links(tweet)
            is_a_retweet = self.update_retweets(tweet)
            if not is_a_retweet:
                self.update_mentions_and_replies(tweet)
            self.save(safe=True)

    def update_retweeted(self, tweet):
        '''
        Parses the tweet and if it belongs to this author and has been retweeted 
        then it updates the retweeted (another author retweeted this) count
        '''
        #If the url belongs to that user then this is their tweet so theri retweets as well
        if self.screen_name == urlparse(tweet.url).path.split('/')[1]:
            self.retweeted_tweets += tweet.retweet_count

    def update_links(self, tweet):
        '''
        Parses the tweet and if it contains a url it updates the links count
        '''
        urls = tools.utils.extract_urls(tweet.content.raw)
        if len(
                urls
        ) > 0:  #We just want to find out if this tweet has aurl not how many
            self.links += 1

    def update_retweets(self, tweet):
        '''
        Parses the tweet and if it is a retweet it updates the retweet count
        '''
        #if this is a retweet increase counter
        is_a_retweet = tools.utils.is_a_retweet(tweet.content.raw)
        if is_a_retweet:
            self.retweets += 1
        return is_a_retweet

    def update_mentions_and_replies(self, tweet):
        '''
        If this is a mention to another user then increase replies
        counter and also update the mentioned user's mentions
        '''
        mentions = tools.utils.get_mentions(tweet.content.raw)
        if len(mentions) > 0:
            self.replies_to_others += 1  #No matter how many people are mentioned in the tweet we just increase by one cz we just want to know if this tweet is a reply
            for mention in mentions:
                mentioned_author = Author.objects(screen_name=mention)
                if len(mentioned_author) > 0:
                    mentioned_author.update(inc__mentions_by_others=1)
예제 #16
0
class EntriesDocument(VespaDocument):

    indexes = [
        'journal',
        'journal_short',
        'publication_date',
        'has_full_text',
        'origin',
        'last_updated',
        'has_year',
        'has_month',
        'has_day',
        'is_preprint',
        'is_covid19',
        'cord_uid',
        'who_covidence',
        'version',
        'copyright',
        'document_type',
        {
            "fields": [
                "doi",
            ],
            "unique": True,
            "partialFilterExpression": {
                "doi": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "#title",
            ]
        },
        {
            "fields": [
                "pmcid",
            ],
            "unique": True,
            "partialFilterExpression": {
                "pmcid": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "pubmed_id",
            ],
            "unique": True,
            "partialFilterExpression": {
                "pubmed_id": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "scopus_eid",
            ],
            "unique": True,
            "partialFilterExpression": {
                "scopus_eid": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "hashed_title",
            ],
            "unique": True,
            "partialFilterExpression": {
                "hashed_title": {
                    "$type": "string"
                }
            }
        },
    ]
    meta = {
        "collection": "entries_vespa2",
        "indexes": indexes,
        "allow_inheritance": False
    }

    source_documents = ListField(GenericReferenceField(), required=True)
    embeddings = DictField(default={})
    is_covid19_ML = FloatField()
    keywords_ML = ListField(StringField(required=True), default=lambda: [])
    synced = BooleanField(default=False)
    #Titles are be default too long for a unique index, so we have to hash them
    hashed_title = StringField(default=None)
    last_twitter_search = DateTimeField()
    tweets = ListField(ReferenceField(TweetDocument))
    altmetric = DynamicField()
예제 #17
0
 class Drinker(Document):
     drink = GenericReferenceField()
예제 #18
0
class EntriesDocument(VespaDocument):

    indexes = [
        'journal',
        'journal_short',
        'publication_date',
        'has_full_text',
        'origin',
        'last_updated',
        'has_year',
        'has_month',
        'has_day',
        'is_preprint',
        'is_covid19',
        'cord_uid',
        'who_covidence',
        'version',
        'copyright',
        'document_type',
        {
            "fields": [
                "doi",
            ],
            "unique": True,
            "partialFilterExpression": {
                "doi": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "pmcid",
            ],
            "unique": True,
            "partialFilterExpression": {
                "pmcid": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "pubmed_id",
            ],
            "unique": True,
            "partialFilterExpression": {
                "pubmed_id": {
                    "$type": "string"
                }
            }
        },
        {
            "fields": [
                "scopus_eid",
            ],
            "unique": True,
            "partialFilterExpression": {
                "scopus_eid": {
                    "$type": "string"
                }
            }
        },
    ]
    meta = {
        "collection": "entries_vespa",
        "indexes": indexes,
        "allow_inheritance": False
    }

    source_documents = ListField(GenericReferenceField(), required=True)
    embeddings = DictField(default={})
    is_covid19_ML = FloatField()
    integer_id = IntField()
예제 #19
0
class HotFocus(ApiDocument):
    focus = GenericReferenceField()
    create_time = DateTimeField(default=datetime.datetime.now)
    _ttl_day = IntField(db_field='ttl_day', default=5)
예제 #20
0
class Favorites(Document):
    items = ListField(GenericReferenceField())
    last_modified = DateTimeField(required=True, default=datetime.datetime.now)
예제 #21
0
class UserSlotProcess(UserProcess, MongoEngineGetOrCreateMixin):
    """
    The process of interaction between user and system about some slot filling via ActiveQuestioning Process

    TODO link ActiveQuestioningProcess in doc

    For slots that requre asking the user and then handling the answer

    TODO Strategy of requestioning must be attachable composite behaviour
    """
    # ###################################################################################################
    # ######## ORM Attrs ################################################################################
    # we define slots as dynamic classes, so we put class name and then route it into dynamic object:
    slot_codename = StringField(required=False)

    # slot instance:
    slot = GenericReferenceField(required=False)

    # calculates how many times reception attempt failed during ActiveQuestioningProcess:
    recept_fails_counter = IntField(default=0, required=False)
    # (may be used by ReQuestioning Strategy):

    # it is a memory URI where the value of the slot after evaluation will be placed:
    target_uri = StringField(required=False)

    # field for results of evaluation of slot process:
    raw_result = DynamicField(required=False)

    # ######## END ORM Attrs ################################################################################
    # ###################################################################################################

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # get or create NewUserMessage signal

        # self.slot_filled_signal = django.dispatch.dispatcher.Signal(
        #     providing_args=["user_slot_process", "results"])

        # from components.signal_reflex_routes.models.signals import SlotFilledSignal
        # if not self.target_uri:
        #     print(self)
        #     import ipdb; ipdb.set_trace()

        from components.signal_pattern_reflex.signal import Signal
        self.slot_filled_signal = Signal(signal_type="SlotFilledSignal",
                                         user_domain=self.user_domain)
        from components.signal_pattern_reflex.signal_pattern import SignalPattern
        self.slot_filled_signal_pattern, _ = SignalPattern.get_or_create_strict(
            signal_type="SlotFilledSignal",
            user_domain=self.user_domain,
            slot=self.slot)
        # self.slot_filled_signal.save()

    @classmethod
    def initialize(cls, user_domain, slot_obj, target_uri=None):
        """
        1. Create UserSlotProcess if it is not exist
        2. Declare Signal of the process for announcing completion (slot_filled_signal)

        :param user_domain:
        :param slot_obj:
        :param target_uri: URI in memory ontology where the value must be written to
        :return:
        """
        # slot_codename = slotClass2SlotNameRouter[slot_obj.__class__]
        slot_codename = slot_obj.get_name()

        usp, _ = cls.get_or_create(user_domain=user_domain,
                                   slot_codename=slot_codename,
                                   slot=slot_obj,
                                   target_uri=target_uri)
        # signal emitted when slot is filled

        # # TODO how to restore signal connections? (So listeners will be notified)
        # if user_domain_controller:
        #     usp.ic = user_domain_controller
        return usp

    def connect_to_dataflow(self, user_domain_controller):
        self.ic = user_domain_controller

    def save(self, *args, **kwargs):
        if not hasattr(self, 'slot_codename'):
            # self.slot_codename = slotClass2SlotNameRouter[self.slot.__class__]
            print("Auto creation of attribute slot_codename from classname")
            self.slot_codename = self.slot.get_name()

        return super().save(*args, **kwargs)

    def start(self, ic):
        """

        Start of ActiveQuestioning retrieval process:
        1. Ask Question to user (if it is not asked already on current step)
        2. (GoC)Connect AnswerReceptor to UserMessageSignal
        3. Set state as Active
        :param ic:
        :return:
        """
        # TODO implement pre-search that avoids questioning if user provided Answer in Dialog Prehistory

        # send question to active dialog
        ic.reload()
        self.ic = ic
        # #################################################################################
        # ########## START ACTIVE QUESTIONING PHASE #######################################
        self.ic.DialogPlanner.sendText(self.slot.asker_fn())
        # self.ic.userdialog.send_message_to_user(self.slot.asker_fn())

        # tiny check that we don't ask two questions in one step
        if self.user_domain.agenda.current_step_active_question:
            # second slot at current step
            # Exceptional case adding the second slot. Is it context switch?
            # print(self.ic.DialogPlanner.questions_under_discussion)
            print(self.user_domain.agenda.questions_under_discussion)
            import ipdb
            ipdb.set_trace()
            raise Exception("Why 2questions per step?")

        # now we should put the question under questions on discussion
        if self.slot in self.user_domain.agenda.questions_under_discussion:
            print(f"duplicated call to user_slot_process: {self}")
            #self.reload()
            #import ipdb; ipdb.set_trace()
            #print("WTF?")
        else:
            self.user_domain.agenda.questions_under_discussion.insert(
                0, self.slot)
            self.user_domain.agenda.current_step_active_question = self.slot
            self.user_domain.agenda.save()
            self.user_domain.user_message_signal_pattern.connect(
                self.on_user_response, weak=False)
        # connect particular Receptor to ActiveReceptors Pool
        # self.user_domain.user_message_signal.connect(self.on_user_response, weak=False)
        self.state = self.ACTIVE
        self.save()
        # #################################################################################

    def reasking_process(self):
        """
        function called when ReAsking approved by dialog planner
        :return:
        """
        # self.user_domain.ic.userdialog.send_message_to_user(self.slot.asker_fn())
        self.user_domain.udm.DialogPlanner.sendText(self.slot.asker_fn())
        self.user_domain.agenda.current_step_active_question = self.slot
        self.user_domain.agenda.save()
        # assert that usermessage connector is still connected

    def on_user_response(self, *args, **kwargs):
        """
        When user message comes after questioning
        :param text:
        :return:
        """
        print("UserSlotProcess.on_user_response")
        text = kwargs['text']
        # import ipdb; ipdb.set_trace()
        if not hasattr(self, 'ic'):
            self.user_domain.reload()

            #from components.user_domains.user_domain_controller import UserDomainController
            self.ic = self.user_domain.udm

        if self.slot.can_recept(text):

            result = self.slot.recept(text)
            # #################################################################################
            # ########## FINALIZATION and MEMORIZATION of the SLOT  ###########################
            # self.user_domain.user_message_signal.disconnect(self.on_user_response)
            self.user_domain.user_message_signal_pattern.disconnect(
                self.on_user_response)
            self.complete_self(result)
            # END FINALIZATION and MEMORIZATION of the SLOT
            # #################################################################################
        else:
            # wrong response (
            self.recept_fails_counter += 1
            self.state = self.IGNORED
            self.save()
            print("IGNORED")
            #import ipdb; ipdb.set_trace()
            # TODO refactor
            # #################################################################################
            # ########## Requestioning Strategy Exploitation ##################################
            if self.slot.requestioning_strategy == "Greed":

                # Greed reAsk Strategy:
                print("Slot Unhandled (Greed reAsk Strategy). ReAsking...")
                self.user_domain.udm.DialogPlanner.sendText(
                    self.slot.asker_fn() + " (Greed ReAsk Strategy)")

                # print("Slot Unhandled (Passive waiting Strategy)")
            elif self.slot.requestioning_strategy == "ResumeOnIdle":
                # self.ic.reaskers_queue.append(self)
                # if self.recept_fails_counter >= 3:
                #     print("Slot Unhandled (ResumeOnIdle). ReAsking...")
                #     self.ic.userdialog.send_message_to_user(self.slot.asker_fn() + " (ResumeOnIdle ReAsk Strategy)")
                # import ipdb; ipdb.set_trace()

                pass
            elif self.slot.requestioning_strategy == "Passive":
                # default behaviour?
                print("Slot Unhandled (Passive Strategy)...")
            else:
                raise Exception("Unspecified ReQuestioning Strategy!")
            # TODO implement attachement of Exception Strategy:
            # 1. Forced Slot: ReAsk Urgently
            # 2. Passive Waiting, but we need to attach handler
            # here

    def _clean_queue_of_tasks(self):
        # TODO move to dialog planner/ agenda?
        self.user_domain.agenda.reload()
        for each_slot_task in self.user_domain.agenda.queue_of_tasks:
            if self.slot == each_slot_task.item:
                #import ipdb;
                #ipdb.set_trace()

                self.user_domain.agenda.queue_of_tasks.remove(each_slot_task)
                self.user_domain.agenda.save()
                break
        else:
            # no tasks with that shit
            return

        self._clean_queue_of_tasks()

    def complete_self(self, result):
        """
        Implements finalization of slot process with provided result
        :param result:
        :return:
        """
        # self.result = UserSlot(self.user, self.slot, result)
        # self.result.save()
        self.reload()
        self.raw_result = result
        if self.state == self.COMPLETED:
            # already completed!
            print(self)
            import ipdb
            ipdb.set_trace()
            print(self)

        self.state = self.COMPLETED

        if self.target_uri:
            # write the memory
            self.user_domain.udm.MemoryManager.put_slot_value(
                self.target_uri, result)

        # now we should remove question under discussion (if we are in active questioning process)
        # if self.slot in self.ic.DialogPlanner.questions_under_discussion:

        if self.slot in self.user_domain.agenda.questions_under_discussion:
            self.user_domain.agenda.questions_under_discussion.remove(
                self.slot)
            print("self.slot")
            print(self.slot)
            print("self.user_domain.agenda.questions_under_discussion=")
            print(self.user_domain.agenda.questions_under_discussion)
            self.user_domain.agenda.save()
            #import ipdb; ipdb.set_trace()
        if self.user_domain.agenda.urgent_slot_tasks:
            # find slot in tasks
            for each_urgent_slot_task in self.user_domain.agenda.urgent_slot_tasks:
                if self.slot == each_urgent_slot_task.item:
                    self.user_domain.agenda.urgent_slot_tasks.remove(
                        each_urgent_slot_task)
                    self.user_domain.agenda.save()
                    break
        if self.user_domain.agenda.queue_of_tasks:
            self._clean_queue_of_tasks()

            # self.ic.DialogPlanner.questions_under_discussion.remove(self.slot)
        self.save()
        print("User response filled slot %s: %s!" % (self.slot, result))
        #if 'MUSIC' in result:
        ##
        ##     import traceback
        ##     for line in traceback.format_stack():
        ##         print(line.strip())
        #    print(result)
        #    # UserSlotProcess.objects(user_domain=self.user_domain, slot=self.slot)
        #    import ipdb;
        #    ipdb.set_trace()
        #    print(result)
        #import ipdb; ipdb.set_trace()

        self.slot_filled_signal.send(signal_type="SlotFilledSignal",
                                     sender=self,
                                     slot=self.slot,
                                     user_slot_process=self,
                                     results=result)

    def fast_evaluation_process_attempt(self):
        """
        Attempt to evaluate slot without Interacting with User via ActiveQuestioning process
        :return:
        """
        # import ipdb; ipdb.set_trace()
        is_recepted, result = self._fast_evaluation_process_attempt_raw_output(
        )
        if is_recepted and self.state != self.COMPLETED:
            # finlize userslot process (if it is not finalized yet)
            self.complete_self(result)

        return is_recepted, result

    def _fast_evaluation_process_attempt_raw_output(self):
        """
        Process of value evaluation when we check
            1. Memory
            2. Prehistory
            3. DefaultValue

        if some of them succed then annoubnce completion
        else return exception

        No callback polling

        No slot process finalization

        :return: (is_slot_value_retrieved:bool, result:any)
        """
        slot_spec_obj = self.slot

        if not self.target_uri:
            # means uri is slot name for singleton slots
            self.target_uri = slot_spec_obj.get_name()

        try:
            # #######################################################################################
            # ########## MemorySlotValueRetrievalOperation ##########################################
            slot_value = self.ic.MemoryManager.get_slot_value(self.target_uri)

            return True, slot_value

        except Exception as e:
            # #########################################################################
            # ###### PreHistory Filling Process #####################################
            if hasattr(slot_spec_obj, 'prehistory_recept'):
                print("Retrieving slot %s value from PreHistory" %
                      slot_spec_obj)
                # asserting it is callable method!

                is_recepted, results = slot_spec_obj.prehistory_recept(
                    self.user_domain.udm.userdialog)
                if is_recepted:
                    print("Recepted Slot from Prehistory!")
                    print(results)
                    # if self.target_uri:
                    # write the memory
                    self.user_domain.udm.MemoryManager.put_slot_value(
                        self.target_uri, results)

                    return True, results

                else:
                    print("Can NOT RECEPT Slot from Prehistory!")
            # no prehistory value, so we need to check default value:
            # #########################################################################
            # ###### Default Value Filling Process #####################################
            if hasattr(slot_spec_obj,
                       'silent_value') and slot_spec_obj.silent_value:
                # we have default value then we don't need to specify it in ActiveQuestioning
                print("Retrieving slot value from DefaultValue")
                # if self.target_uri:
                # write the memory
                self.ic.MemoryManager.put_slot_value(
                    self.target_uri, slot_spec_obj.silent_value)

                return True, slot_spec_obj.silent_value

            return False, None

    def __str__(self):
        return "UserDomain: %s, slot: %s, state: %s" % (
            self.user_domain, self.slot_codename, self.state)
예제 #22
0
class UserWishList(DynamicDocument):
    user = GenericReferenceField()
    gig = GenericReferenceField()