<commit_before>from __future__ import absolute_import

import datetime
from django.conf import settings
from couchdbkit.ext.django.schema import *
import couchforms.const as const
from dimagi.utils.indicators import ComputedDocumentMixin
from dimagi.utils.parsing import string_to_datetime
from couchdbkit.schema.properties_proxy import SchemaListProperty
from couchforms.safe_index import safe_index
from xml.etree import ElementTree
from django.utils.datastructures import SortedDict
from couchdbkit.resource import ResourceNotFound
import logging
import hashlib
from copy import copy
from couchforms.signals import submission_error_received, xform_archived
from dimagi.utils.mixins import UnicodeMixIn
from couchforms.const import ATTACHMENT_NAME

class Metadata(DocumentSchema):
    """
    Metadata of an xform, from a meta block structured like:
        
        <Meta>
            <timeStart />
            <timeEnd />
            <instanceID />
            <userID />
            <deviceID />
            <deprecatedID /> 
            <username />
        </Meta>
    
    See spec: https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaMetaDataSchema
    
    username is not part of the spec but included for convenience
    """
    timeStart = DateTimeProperty()
    timeEnd = DateTimeProperty()
    instanceID = StringProperty()
    userID = StringProperty()
    deviceID = StringProperty()
    deprecatedID = StringProperty()
    username = StringProperty()
    
class XFormInstance(Document, UnicodeMixIn, ComputedDocumentMixin):
    """An XForms instance."""
    xmlns = StringProperty()
    received_on = DateTimeProperty()
    partial_submission = BooleanProperty(default=False) # Used to tag forms that were forcefully submitted without a touchforms session completing normally
    <commit_msg>Add get_appropriate_subclass to XFormInstance, dispatched on doc_type<commit_after>from __future__ import absolute_import

import datetime
from django.conf import settings
from couchdbkit.ext.django.schema import *
import couchforms.const as const
from dimagi.utils.indicators import ComputedDocumentMixin
from dimagi.utils.parsing import string_to_datetime
from couchdbkit.schema.properties_proxy import SchemaListProperty
from couchforms.safe_index import safe_index
from xml.etree import ElementTree
from django.utils.datastructures import SortedDict
from couchdbkit.resource import ResourceNotFound
import logging
import hashlib
from copy import copy
from couchforms.signals import submission_error_received, xform_archived
from dimagi.utils.mixins import UnicodeMixIn
from couchforms.const import ATTACHMENT_NAME

class Metadata(DocumentSchema):
    """
    Metadata of an xform, from a meta block structured like:
        
        <Meta>
            <timeStart />
            <timeEnd />
            <instanceID />
            <userID />
            <deviceID />
            <deprecatedID /> 
            <username />
        </Meta>
    
    See spec: https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaMetaDataSchema
    
    username is not part of the spec but included for convenience
    """
    timeStart = DateTimeProperty()
    timeEnd = DateTimeProperty()
    instanceID = StringProperty()
    userID = StringProperty()
    deviceID = StringProperty()
    deprecatedID = StringProperty()
    username = StringProperty()

class XFormInstance(Document, UnicodeMixIn, ComputedDocumentMixin):
    """An XForms instance."""
    xmlns = StringProperty()
    received_on = DateTimeProperty()
    partial_submission = BooleanProperty(default=False) # Used to tag forms that were forcefully submitted without a touchforms session completing normally

    @classmethod
    def get_appropriate_subclass(cls, doc_id):
        """
        Will return an instance of XFormArchived, XFormInstance, XFormDeleted, etc, according to doc_type.
        This could/should be made more generic by not caring about subclassing, and more explicit by
        using a registry instead of globals()
        """
        doc = cls.get_db().get(doc_id)
        doc_type = doc['doc_type']
        if doc_type in globals():
            subclass = globals()[doc_type]
            if issubclass(subclass, cls):
                return subclass.wrap(doc)
        raise ResourceNotFound(doc_id)
    
{'fraction_non_alphanumeric': 0.06525285481239804, 'fraction_numerical': 0.0, 'mean_word_length': 3.3975409836065573, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3785722', 'n_tokens_mistral': 1115, 'n_tokens_neox': 1099, 'n_words': 344}