Esempio n. 1
0
class ReportMeta(DocumentSchema):
    # `True` if this report was initially constructed by the report builder.
    created_by_builder = BooleanProperty(default=False)
    # `True` if this report was ever edited in the advanced JSON UIs (after June 7, 2016)
    edited_manually = BooleanProperty(default=False)
    last_modified = DateTimeProperty()
    builder_report_type = StringProperty(choices=['chart', 'list', 'table', 'worker', 'map'])
Esempio n. 2
0
class RepeatRecordAttempt(DocumentSchema):
    cancelled = BooleanProperty(default=False)
    datetime = DateTimeProperty()
    failure_reason = StringProperty()
    success_response = StringProperty()
    next_check = DateTimeProperty()
    succeeded = BooleanProperty(default=False)
    info = StringProperty()  # extra information about this attempt

    @property
    def message(self):
        return self.success_response if self.succeeded else self.failure_reason

    @property
    def state(self):
        state = RECORD_PENDING_STATE
        if self.succeeded:
            state = RECORD_SUCCESS_STATE
        elif self.cancelled:
            state = RECORD_CANCELLED_STATE
        elif self.failure_reason:
            state = RECORD_FAILURE_STATE
        return state

    @property
    def created_at(self):
        # Used by .../case/partials/repeat_records.html
        return self.datetime
Esempio n. 3
0
class CustomDataField(JsonObject):
    slug = StringProperty()
    is_required = BooleanProperty()
    label = StringProperty()
    choices = StringListProperty()
    regex = StringProperty()
    regex_msg = StringProperty()
    is_multiple_choice = BooleanProperty(default=False)
Esempio n. 4
0
class CustomDataField(JsonObject):
    slug = StringProperty()
    is_required = BooleanProperty()
    label = StringProperty()
    choices = StringListProperty()
    is_multiple_choice = BooleanProperty(default=False)
    # Currently only relevant for location fields
    index_in_fixture = BooleanProperty(default=False)
Esempio n. 5
0
class EWSGhanaConfig(Document):
    enabled = BooleanProperty(default=False)
    domain = StringProperty()
    url = StringProperty(default="http://ewsghana.com/api/v0_1")
    username = StringProperty()
    password = StringProperty()
    steady_sync = BooleanProperty(default=False)
    all_stock_data = BooleanProperty(default=False)

    @classmethod
    def for_domain(cls, name):
        try:
            mapping = DocDomainMapping.objects.get(domain_name=name,
                                                   doc_type='EWSGhanaConfig')
            return cls.get(docid=mapping.doc_id)
        except DocDomainMapping.DoesNotExist:
            return None

    @classmethod
    def get_all_configs(cls):
        mappings = DocDomainMapping.objects.filter(doc_type='EWSGhanaConfig')
        configs = [cls.get(docid=mapping.doc_id) for mapping in mappings]
        return configs

    @classmethod
    def get_all_steady_sync_configs(cls):
        return [
            config for config in cls.get_all_configs() if config.steady_sync
        ]

    @classmethod
    def get_all_enabled_domains(cls):
        configs = cls.get_all_configs()
        return [
            c.domain for c in [config for config in configs if config.enabled]
        ]

    @property
    def is_configured(self):
        return True if self.enabled and self.url and self.password and self.username else False

    def save(self, **params):
        super(EWSGhanaConfig, self).save(**params)

        try:
            DocDomainMapping.objects.get(doc_id=self._id,
                                         domain_name=self.domain,
                                         doc_type="EWSGhanaConfig")
        except DocDomainMapping.DoesNotExist:
            DocDomainMapping.objects.create(doc_id=self._id,
                                            domain_name=self.domain,
                                            doc_type='EWSGhanaConfig')

    class Meta(object):
        app_label = 'ewsghana'
Esempio n. 6
0
class MVPChildCasesByAgeIndicatorDefinition(MVPActiveCasesIndicatorDefinition):
    """
        Returns the number of child cases that were active within the datespan provided and have a date of birth
        that is less than the age provided by days in age.
    """
    max_age_in_days = IntegerProperty()
    min_age_in_days = IntegerProperty(default=0)
    show_active_only = BooleanProperty(default=True)
    is_dob_in_datespan = BooleanProperty(default=False)

    _admin_crud_class = MVPChildCasesByAgeCRUDManager

    def get_value_by_status(self, status, user_id, datespan):
        cases = self._get_cases_by_status(status, user_id, datespan)
        return self._filter_by_age(cases, datespan)

    def _filter_by_age(self, results, datespan):
        valid_case_ids = []
        datespan = self._apply_datespan_shifts(datespan)
        for item in results:
            if item.get('value'):
                try:
                    date_of_birth = dateutil.parser.parse(item['value'])
                    valid_id = False
                    if self.is_dob_in_datespan:
                        if datespan.startdate <= date_of_birth <= datespan.enddate:
                            valid_id = True
                    else:
                        td = datespan.enddate - date_of_birth
                        if self.min_age_in_days <= td.days < self.max_age_in_days:
                            valid_id = True
                    if valid_id:
                        valid_case_ids.append(item['id'])
                except Exception:
                    logging.error("date of birth could not be parsed")
        return valid_case_ids

    def get_value(self, user_ids, datespan=None, is_debug=False):
        if self.show_active_only:
            return super(MVPChildCasesByAgeIndicatorDefinition,
                         self).get_value(user_ids,
                                         datespan=datespan,
                                         is_debug=is_debug)
        else:
            results = self.get_raw_results(user_ids, datespan)
            all_cases = self._filter_by_age(results, datespan)

        value = len(all_cases)
        if is_debug:
            return value, list(all_cases)
        return value

    @classmethod
    def get_nice_name(cls):
        return "MVP Child Cases"
Esempio n. 7
0
class RepeatRecordAttempt(DocumentSchema):
    cancelled = BooleanProperty(default=False)
    datetime = DateTimeProperty()
    failure_reason = StringProperty()
    success_response = StringProperty()
    next_check = DateTimeProperty()
    succeeded = BooleanProperty(default=False)
    info = StringProperty()     # extra information about this attempt

    @property
    def message(self):
        return self.success_response if self.succeeded else self.failure_reason
Esempio n. 8
0
class ReportMeta(DocumentSchema):
    # `True` if this report was initially constructed by the report builder.
    created_by_builder = BooleanProperty(default=False)
    report_builder_version = StringProperty(default="")
    # `True` if this report was ever edited in the advanced JSON UIs (after June 7, 2016)
    edited_manually = BooleanProperty(default=False)
    last_modified = DateTimeProperty()
    builder_report_type = StringProperty(choices=['chart', 'list', 'table', 'worker', 'map'])
    builder_source_type = StringProperty(choices=REPORT_BUILDER_DATA_SOURCE_TYPE_VALUES)

    # If this is a linked report, this is the ID of the report this pulls from
    master_id = StringProperty()
Esempio n. 9
0
class ILSGatewayConfig(Document):
    enabled = BooleanProperty(default=False)
    domain = StringProperty()
    url = StringProperty(default="http://ilsgateway.com/api/v0_1")
    username = StringProperty()
    password = StringProperty()
    steady_sync = BooleanProperty(default=False)
    all_stock_data = BooleanProperty(default=False)

    @classmethod
    def for_domain(cls, name):
        try:
            mapping = DocDomainMapping.objects.get(domain_name=name,
                                                   doc_type='ILSGatewayConfig')
            return cls.get(docid=mapping.doc_id)
        except DocDomainMapping.DoesNotExist:
            return None

    @classmethod
    def get_all_configs(cls):
        mappings = DocDomainMapping.objects.filter(doc_type='ILSGatewayConfig')
        configs = [cls.get(docid=mapping.doc_id) for mapping in mappings]
        return configs

    @classmethod
    def get_all_enabled_domains(cls):
        configs = cls.get_all_configs()
        return [
            c.domain for c in filter(lambda config: config.enabled, configs)
        ]

    @classmethod
    def get_all_steady_sync_configs(cls):
        return [
            config for config in cls.get_all_configs() if config.steady_sync
        ]

    @property
    def is_configured(self):
        return True if self.enabled and self.url and self.password and self.username else False

    def save(self, **params):
        super(ILSGatewayConfig, self).save(**params)
        try:
            DocDomainMapping.objects.get(doc_id=self._id,
                                         domain_name=self.domain,
                                         doc_type="ILSGatewayConfig")
        except DocDomainMapping.DoesNotExist:
            DocDomainMapping.objects.create(doc_id=self._id,
                                            domain_name=self.domain,
                                            doc_type='ILSGatewayConfig')
            add_to_module_map(self.domain, 'custom.ilsgateway')
Esempio n. 10
0
class CallCenterProperties(DocumentSchema):
    enabled = BooleanProperty(default=False)
    use_fixtures = BooleanProperty(default=True)

    case_owner_id = StringProperty()
    use_user_location_as_owner = BooleanProperty(default=False)
    user_location_ancestor_level = IntegerProperty(default=0)

    case_type = StringProperty()

    def fixtures_are_active(self):
        return self.enabled and self.use_fixtures

    def config_is_valid(self):
        return (self.use_user_location_as_owner or self.case_owner_id) and self.case_type
Esempio n. 11
0
class Deployment(DocumentSchema, UpdatableSchema):
    city = StringProperty()
    countries = StringListProperty()
    region = StringProperty(
    )  # e.g. US, LAC, SA, Sub-saharn Africa, East Africa, West Africa, Southeast Asia)
    description = StringProperty()
    public = BooleanProperty(default=False)
Esempio n. 12
0
class CDotWeeklySchedule(OldDocument):
    """Weekly schedule where each day has a username"""
    schedule_id = StringProperty(default=make_uuid)

    sunday = StringProperty()
    monday = StringProperty()
    tuesday = StringProperty()
    wednesday = StringProperty()
    thursday = StringProperty()
    friday = StringProperty()
    saturday = StringProperty()

    comment = StringProperty()

    deprecated = BooleanProperty(default=False)

    started = OldDateTimeProperty(default=datetime.utcnow, required=True)
    ended = OldDateTimeProperty()

    created_by = StringProperty()  # user id
    edited_by = StringProperty()  # user id

    @property
    def is_current(self):
        now = datetime.utcnow()
        return self.started <= now and (self.ended is None or self.ended > now)

    class Meta:
        app_label = 'pact'
Esempio n. 13
0
class ApplicationAccess(QuickCachedDocumentMixin, Document):
    """
    This is used to control which users/groups can access which applications on cloudcare.
    """
    domain = StringProperty()
    app_groups = SchemaListProperty(AppGroup, default=[])
    restrict = BooleanProperty(default=False)
Esempio n. 14
0
class LicenseAgreement(DocumentSchema):
    signed = BooleanProperty(default=False)
    type = StringProperty()
    date = DateTimeProperty()
    user_id = StringProperty()
    user_ip = StringProperty()
    version = StringProperty()
Esempio n. 15
0
class StudySettings(DocumentSchema):
    is_ws_enabled = BooleanProperty()
    url = StringProperty()
    username = StringProperty()
    password = StringProperty()
    protocol_id = StringProperty()
    metadata = StringProperty()  # Required when web service is not enabled
Esempio n. 16
0
class Dhis2Connection(Document):
    domain = StringProperty()
    server_url = StringProperty()
    username = StringProperty()
    password = StringProperty()
    skip_cert_verify = BooleanProperty(default=False)

    @classmethod
    def wrap(cls, data):
        data.pop('log_level', None)
        return super(Dhis2Connection, cls).wrap(data)

    def save(self, *args, **kwargs):
        # Save to SQL
        model, created = SQLDhis2Connection.objects.update_or_create(
            domain=self.domain,
            defaults={
                'server_url': self.server_url,
                'username': self.username,
                'password': self.password,
                'skip_cert_verify': self.skip_cert_verify,
            }
        )

        # Save to couch
        super().save(*args, **kwargs)
Esempio n. 17
0
class ExportColumn(DocumentSchema):
    """
    A column configuration, for export
    """
    index = StringProperty()
    display = StringProperty()
    # signature: transform(val, doc) -> val
    transform = SerializableFunctionProperty(default=None)
    tag = StringProperty()
    is_sensitive = BooleanProperty(default=False)
    show = BooleanProperty(default=False)

    @classmethod
    def wrap(self, data):
        if 'is_sensitive' not in data and data.get('transform', None):
            data['is_sensitive'] = True

        if 'doc_type' in data and \
           self.__name__ == ExportColumn.__name__ and \
           self.__name__ != data['doc_type']:
            if data['doc_type'] in column_types:
                return column_types[data['doc_type']].wrap(data)
            else:
                raise ResourceNotFound('Unknown column type: %s', data)
        else:
            return super(ExportColumn, self).wrap(data)

    def get_display(self):
        return u'{primary}{extra}'.format(
            primary=self.display,
            extra=" [sensitive]" if self.is_sensitive else ''
        )

    def to_config_format(self, selected=True):
        return {
            "index": self.index,
            "display": self.display,
            "transform": self.transform.dumps() if self.transform else None,
            "is_sensitive": self.is_sensitive,
            "selected": selected,
            "tag": self.tag,
            "show": self.show,
            "doc_type": self.doc_type,
            "options": [],
            "allOptions": None,
        }
Esempio n. 18
0
class DataSourceBuildInformation(DocumentSchema):
    """
    A class to encapsulate meta information about the process through which
    its DataSourceConfiguration was configured and built.
    """
    # Either the case type or the form xmlns that this data source is based on.
    source_id = StringProperty()
    # The app that the form belongs to, or the app that was used to infer the case properties.
    app_id = StringProperty()
    # The version of the app at the time of the data source's configuration.
    app_version = IntegerProperty()
    # True if the data source has been built, that is, if the corresponding SQL table has been populated.
    finished = BooleanProperty(default=False)
    # Start time of the most recent build SQL table celery task.
    initiated = DateTimeProperty()
    # same as previous attributes but used for rebuilding tables in place
    finished_in_place = BooleanProperty(default=False)
    initiated_in_place = DateTimeProperty()
Esempio n. 19
0
class FormRepeater(Repeater):
    """
    Record that forms should be repeated to a new url

    """

    payload_generator_classes = (FormRepeaterXMLPayloadGenerator,
                                 FormRepeaterJsonPayloadGenerator)

    include_app_id_param = BooleanProperty(default=True)
    white_listed_form_xmlns = StringListProperty(
        default=[])  # empty value means all form xmlns are accepted
    friendly_name = _("Forward Forms")

    @memoized
    def payload_doc(self, repeat_record):
        return FormAccessors(repeat_record.domain).get_form(
            repeat_record.payload_id)

    @property
    def form_class_name(self):
        """
        FormRepeater and its subclasses use the same form for editing
        """
        return 'FormRepeater'

    def allowed_to_forward(self, payload):
        return (payload.xmlns != DEVICE_LOG_XMLNS
                and (not self.white_listed_form_xmlns
                     or payload.xmlns in self.white_listed_form_xmlns))

    def get_url(self, repeat_record):
        url = super(FormRepeater, self).get_url(repeat_record)
        if not self.include_app_id_param:
            return url
        else:
            # adapted from http://stackoverflow.com/a/2506477/10840
            url_parts = list(urlparse(url))
            query = parse_qsl(url_parts[4])
            try:
                query.append(
                    ("app_id", self.payload_doc(repeat_record).app_id))
            except (XFormNotFound, ResourceNotFound):
                return None
            url_parts[4] = urlencode(query)
            return urlunparse(url_parts)

    def get_headers(self, repeat_record):
        headers = super(FormRepeater, self).get_headers(repeat_record)
        headers.update({
            "received-on":
            self.payload_doc(repeat_record).received_on.isoformat() + "Z"
        })
        return headers

    def __str__(self):
        return "forwarding forms to: %s" % self.url
Esempio n. 20
0
class Dhis2Connection(Document):
    domain = StringProperty()
    server_url = StringProperty()
    username = StringProperty()
    password = StringProperty()
    skip_cert_verify = BooleanProperty(default=False)

    @classmethod
    def wrap(cls, data):
        data.pop('log_level', None)
        return super(Dhis2Connection, cls).wrap(data)
Esempio n. 21
0
class WisePillDeviceEvent(Document):
    """
    One DeviceEvent is created each time a device sends data that is
    forwarded to the CommCareHQ WisePill API (/wisepill/device/).
    """
    domain = StringProperty()
    data = StringProperty()
    received_on = DateTimeProperty()
    # Document _id of the case representing the device that sent this data in
    case_id = StringProperty()
    processed = BooleanProperty()

    @property
    @memoized
    def data_as_dict(self):
        """
        Convert 'a=b,c=d' to {'a': 'b', 'c': 'd'}
        """
        result = {}
        if isinstance(self.data, str):
            items = self.data.strip().split(',')
            for item in items:
                parts = item.partition('=')
                key = parts[0].strip().upper()
                value = parts[2].strip()
                if value:
                    result[key] = value
        return result

    @property
    def serial_number(self):
        return self.data_as_dict.get('SN', None)

    @property
    def timestamp(self):
        raw = self.data_as_dict.get('T', None)
        if isinstance(raw, str) and len(raw) == 12:
            return "20%s-%s-%s %s:%s:%s" % (
                raw[4:6],
                raw[2:4],
                raw[0:2],
                raw[6:8],
                raw[8:10],
                raw[10:12],
            )
        else:
            return None

    @classmethod
    def get_all_ids(cls):
        result = cls.view('wisepill/device_event', include_docs=False)
        return [row['id'] for row in result]
Esempio n. 22
0
class VerifiedNumber(Document):
    """
    There should only be one VerifiedNumber entry per (owner_doc_type, owner_id), and
    each VerifiedNumber.phone_number should be unique across all entries.
    """
    domain = StringProperty()
    owner_doc_type = StringProperty()
    owner_id = StringProperty()
    phone_number = StringProperty()
    backend_id = StringProperty(
    )  # the name of a MobileBackend (can be domain-level or system-level)
    ivr_backend_id = StringProperty()  # points to a MobileBackend
    verified = BooleanProperty()
    contact_last_modified = DateTimeProperty()
Esempio n. 23
0
class SavedBasicExport(BlobMixin, Document):
    """
    A cache of an export that lives in couch.
    Doesn't do anything smart, just works off an index
    """
    configuration = SchemaProperty(ExportConfiguration)
    last_updated = DateTimeProperty()
    last_accessed = DateTimeProperty()
    is_safe = BooleanProperty(default=False)
    _blobdb_type_code = CODES.basic_export

    @property
    def size(self):
        try:
            return self.blobs[self.get_attachment_name()].content_length
        except KeyError:
            return 0

    def has_file(self):
        return self.get_attachment_name() in self.blobs

    def get_attachment_name(self):
        # obfuscate this because couch doesn't like attachments that start with underscores
        return hashlib.md5(
            six.text_type(
                self.configuration.filename).encode('utf-8')).hexdigest()

    def set_payload(self, payload):
        # According to @esoergel this code is slated for removal in the near
        # future, so I didn't think it was worth it to try to pass the domain
        # in here.
        self.put_attachment(payload,
                            self.get_attachment_name(),
                            domain=UNKNOWN_DOMAIN)

    def get_payload(self, stream=False):
        return self.fetch_attachment(self.get_attachment_name(),
                                     stream=stream,
                                     return_bytes=True)

    @classmethod
    def by_index(cls, index):
        return SavedBasicExport.view(
            "couchexport/saved_exports",
            key=json.dumps(index),
            include_docs=True,
            reduce=False,
        ).all()
Esempio n. 24
0
class ApplicationAccess(QuickCachedDocumentMixin, Document):
    """
    This is used to control which users/groups can access which applications on cloudcare.
    """
    domain = StringProperty()
    app_groups = SchemaListProperty(AppGroup, default=[])
    restrict = BooleanProperty(default=False)

    @classmethod
    def get_by_domain(cls, domain):
        from corehq.apps.cloudcare.dbaccessors import get_application_access_for_domain
        self = get_application_access_for_domain(domain)
        return self or cls(domain=domain)

    def clear_caches(self):
        from corehq.apps.cloudcare.dbaccessors import get_application_access_for_domain
        get_application_access_for_domain.clear(self.domain)
        super(ApplicationAccess, self).clear_caches()

    def user_can_access_app(self, user, app):
        user_id = user['_id']
        app_id = app['_id']
        if not self.restrict or user['doc_type'] == 'WebUser':
            return True
        app_group = None
        for app_group in self.app_groups:
            if app_group.app_id in (app_id, app['copy_of'] or ()):
                break
        if app_group:
            return Group.user_in_group(user_id, app_group.group_id)
        else:
            return False

    @classmethod
    def get_template_json(cls, domain, apps):
        app_ids = dict([(app['_id'], app) for app in apps])
        self = ApplicationAccess.get_by_domain(domain)
        j = self.to_json()
        merged_access_list = []
        for a in j['app_groups']:
            app_id = a['app_id']
            if app_id in app_ids:
                merged_access_list.append(a)
                del app_ids[app_id]
        for app in app_ids.values():
            merged_access_list.append({'app_id': app['_id'], 'group_id': None})
        j['app_groups'] = merged_access_list
        return j
Esempio n. 25
0
class RegistrationRequest(Document):
    tos_confirmed = BooleanProperty(default=False)
    request_time = DateTimeProperty()
    request_ip = StringProperty()
    activation_guid = StringProperty()
    confirm_time = DateTimeProperty()
    confirm_ip = StringProperty()
    domain = StringProperty()
    new_user_username = StringProperty()
    requesting_user_username = StringProperty()

    @property
    @memoized
    def project(self):
        return Domain.get_by_name(self.domain)

    @classmethod
    def get_by_guid(cls, guid):
        result = cls.view("registration/requests_by_guid",
                          key=guid,
                          reduce=False,
                          include_docs=True).first()
        return result

    @classmethod
    def get_requests_today(cls):
        today = datetime.datetime.utcnow()
        yesterday = today - datetime.timedelta(1)
        result = cls.view("registration/requests_by_time",
                          startkey=yesterday.isoformat(),
                          endkey=today.isoformat(),
                          reduce=True).all()
        if not result:
            return 0
        return result[0]['value']

    @classmethod
    def get_request_for_username(cls, username):
        result = cls.view("registration/requests_by_username",
                          key=username,
                          reduce=False,
                          include_docs=True).first()
        return result
Esempio n. 26
0
class InternalProperties(DocumentSchema, UpdatableSchema):
    """
    Project properties that should only be visible/editable by superusers
    """
    sf_contract_id = StringProperty()
    sf_account_id = StringProperty()
    commcare_edition = StringProperty(
        choices=['', "plus", "community", "standard", "pro", "advanced", "enterprise"],
        default="community"
    )
    initiative = StringListProperty()
    workshop_region = StringProperty()
    project_state = StringProperty(choices=["", "POC", "transition", "at-scale"], default="")
    self_started = BooleanProperty(default=True)
    area = StringProperty()
    sub_area = StringProperty()
    using_adm = BooleanProperty()
    using_call_center = BooleanProperty()
    custom_eula = BooleanProperty()
    can_use_data = BooleanProperty(default=True)
    notes = StringProperty()
    organization_name = StringProperty()
    platform = StringListProperty()
    project_manager = StringProperty()
    phone_model = StringProperty()
    goal_time_period = IntegerProperty()
    goal_followup_rate = DecimalProperty()
    # intentionally different from and commtrack_enabled so that FMs can change
    commtrack_domain = BooleanProperty()
    performance_threshold = IntegerProperty()
    experienced_threshold = IntegerProperty()
    amplifies_workers = StringProperty(
        choices=[AMPLIFIES_YES, AMPLIFIES_NO, AMPLIFIES_NOT_SET],
        default=AMPLIFIES_NOT_SET
    )
    amplifies_project = StringProperty(
        choices=[AMPLIFIES_YES, AMPLIFIES_NO, AMPLIFIES_NOT_SET],
        default=AMPLIFIES_NOT_SET
    )
    business_unit = StringProperty(choices=BUSINESS_UNITS + [""], default="")
    data_access_threshold = IntegerProperty()
    partner_technical_competency = IntegerProperty()
    support_prioritization = IntegerProperty()
    gs_continued_involvement = StringProperty()
    technical_complexity = StringProperty()
    app_design_comments = StringProperty()
    training_materials = StringProperty()
    partner_comments = StringProperty()
    partner_contact = StringProperty()
    dimagi_contact = StringProperty()
Esempio n. 27
0
class ComputedDocumentMixin(DocumentSchema):
    """
        Use this mixin for things like CommCareCase or XFormInstance documents that take advantage
        of indicator definitions.

        computed_ is namespaced and may look like the following for indicators:
        computed_: {
            mvp_indicators: {
                indicator_slug: {
                    version: 1,
                    value: "foo"
                }
            }
        }
    """
    computed_ = DictProperty()
    computed_modified_on_ = DateTimeProperty()

    # a flag for the indicator pillows so that there aren't any Document Update Conflicts
    initial_processing_complete = BooleanProperty()
Esempio n. 28
0
class SavedBasicExport(BlobMixin, Document):
    """
    A cache of an export that lives in couch.
    Doesn't do anything smart, just works off an index
    """
    configuration = SchemaProperty(ExportConfiguration)
    last_updated = DateTimeProperty()
    last_accessed = DateTimeProperty()
    is_safe = BooleanProperty(default=False)

    @property
    def size(self):
        try:
            return self.blobs[self.get_attachment_name()].content_length
        except KeyError:
            return 0

    def has_file(self):
        return self.get_attachment_name() in self.blobs

    def get_attachment_name(self):
        # obfuscate this because couch doesn't like attachments that start with underscores
        return hashlib.md5(
            six.text_type(
                self.configuration.filename).encode('utf-8')).hexdigest()

    def set_payload(self, payload):
        self.put_attachment(payload, self.get_attachment_name())

    def get_payload(self, stream=False):
        return self.fetch_attachment(self.get_attachment_name(), stream=stream)

    @classmethod
    def by_index(cls, index):
        return SavedBasicExport.view(
            "couchexport/saved_exports",
            key=json.dumps(index),
            include_docs=True,
            reduce=False,
        ).all()
Esempio n. 29
0
class PatientFinder(DocumentSchema):
    """
    Subclasses of the PatientFinder class implement particular
    strategies for finding OpenMRS patients that suit a particular
    project. (WeightedPropertyPatientFinder was first subclass to be
    written. A future project with stronger emphasis on patient names
    might use Levenshtein distance, for example.)

    Subclasses must implement the `find_patients()` method.
    """

    # Whether to create a new patient if no patients are found
    create_missing = BooleanProperty(default=False)

    @classmethod
    def wrap(cls, data):

        if cls is PatientFinder:
            return {sub._doc_type: sub
                    for sub in recurse_subclasses(cls)
                    }[data['doc_type']].wrap(data)
        else:
            return super(PatientFinder, cls).wrap(data)

    def find_patients(self, requests, case, case_config):
        """
        Given a case, search OpenMRS for possible matches. Return the
        best results. Subclasses must define "best". If just one result
        is returned, it will be chosen.

        NOTE:: False positives can result in overwriting one patient
               with the data of another. It is definitely better to
               return no results or multiple results than to return a
               single invalid result. Returned results should be
               logged.
        """
        raise NotImplementedError
Esempio n. 30
0
class CallCenterProperties(DocumentSchema):
    enabled = BooleanProperty(default=False)
    use_fixtures = BooleanProperty(default=True)

    case_owner_id = StringProperty()
    use_user_location_as_owner = BooleanProperty(default=False)
    user_location_ancestor_level = IntegerProperty(default=0)

    case_type = StringProperty()

    form_datasource_enabled = BooleanProperty(default=True)
    case_datasource_enabled = BooleanProperty(default=True)
    case_actions_datasource_enabled = BooleanProperty(default=True)

    def fixtures_are_active(self):
        return self.enabled and self.use_fixtures

    def config_is_valid(self):
        return (self.use_user_location_as_owner
                or self.case_owner_id) and self.case_type

    def update_from_app_config(self, config):
        """Update datasources enabled based on app config.

        Follows similar logic to CallCenterIndicators
        :returns: True if changes were made
        """
        pre = (self.form_datasource_enabled, self.case_datasource_enabled,
               self.case_actions_datasource_enabled)
        self.form_datasource_enabled = config.forms_submitted.enabled or bool(
            config.custom_form)
        self.case_datasource_enabled = (config.cases_total.enabled
                                        or config.cases_opened.enabled
                                        or config.cases_closed.enabled)
        self.case_actions_datasource_enabled = config.cases_active.enabled
        post = (self.form_datasource_enabled, self.case_datasource_enabled,
                self.case_actions_datasource_enabled)
        return pre != post