Пример #1
0
def generate(request):
    """Reset system."""

    oErr = ErrHandle()
    oData = dict(status="fail")

    try:
        # Only allow POST command of the Su
        if request.is_ajax() and request.method == "POST" and \
            user_is_authenticated(request) and \
            user_is_superuser(request):

            # Get the parameters passed on
            qd = request.POST
            action = qd.get("action", "")

            if action == "random":
                # Remove previous data
                Result.objects.all().delete()
                # Make sure each woorduser is assigned to a qset
                for wusr in WoordUser.objects.all():
                    qset = wusr.woorduserqsets.first()
                    if qset == None:
                        qset = Qset.objects.filter(woorduser__isnull=True).first()
                        qset.woorduser = wusr
                        qset.save()
                # Generate random data
                choices = [1, 5]
                for choice in choices:
                    # Iterate over all questions for this particular choice
                    with transaction.atomic():
                        for idx, oQuestion in enumerate(Question.objects.filter(choice=choice).values('id')):
                            que_id = oQuestion['id']
                            oErr.Status("choice = {}, q = {}".format(choice, idx+1))
                            # Iterate over all users
                            for wusr in WoordUser.objects.all():
                                qset = wusr.woorduserqsets.first()
                                judgment = random.randint(1,10)
                                # 90% of the time dontknown is false
                                dontknow = (random.randint(1,10) == 10)
                                # Add the random result
                                obj = Result.objects.create(question_id=que_id, user=wusr, judgment=judgment, dontknown=dontknow)
                                # Signal that this result has been accomplished
                                obj = QuestionSet.objects.filter(qset=qset, question_id=que_id).first()
                                obj.set_status("done")

            # REturn positively
            oData['status'] = "ok"
        else:
            oData['msg'] = "Not authenticated"
    except:
        msg = oErr.get_error_message()
        oErr.DoError("question")
        oData['status'] = "error"
        oData['msg'] = msg

    mimetype = "application/json"
    data = json.dumps(oData)
    return HttpResponse(data, mimetype)
Пример #2
0
def initialize_woord(additional=None, randomize=None):
    """Fill the application if this is needed
    
    Initial: only use stimuli.txt
    Issue #147: read stimuli2021.txt, omitting first line with column headers
    """

    def get_stimulus(row):
        woord = ""
        cat = ""
        note = ""
        oBack = {}
        try:
            if len(row) == 3:
                woord = row[0]
                cat = row[1]
                note = row[2]
                oBack = dict(woord=woord, cat=cat, note=note)
            elif row != "":
                # parts = re.split(r'\s+', row)
                parts = re.split(r'\t', row)
                if len(parts) > 1:
                    woord = parts[0]
                    cat = parts[1] # parts[1].replace("(", "").replace(")", "")
                    note = parts[2]
                    oBack = dict(woord=woord, cat=cat, note=note)
            else:
                # Empty row
                iStop = 1
        except:
            msg = oErr.get_error_message()
            oErr.DoError("get_stimulus")
        return oBack

    oErr = ErrHandle()
    bNeedRandomization = False
    msg = "no changes"
    bOrderStimuli = True                # See issue #151: (valid) choices must be treated one by one for the user
    STIMULI_NAME = "stimuli2021.txt"    # Was: stimuli.txt
    lhtml = []

    try:
        # Figure out directory and file names
        woord_dir = os.path.abspath(os.path.join(WRITABLE_DIR, "../woord"))
        choices_file = os.path.abspath(os.path.join(woord_dir, "choices.txt"))
        stimuli_file = os.path.abspath(os.path.join(woord_dir, STIMULI_NAME))
        if randomize != None and randomize == "reset":
            bNeedRandomization = True

        # Check on number of users
        if WoordUser.objects.count() <= 1:
            # Create 20 random users
            with transaction.atomic():
                for number in range(NUMBER_OF_PARTICIPANTS):
                    username = WoordUser.generate_new()
                    WoordUser.objects.create(name=username)

            # Reset done  status for QuestionSet objects
            with transaction.atomic():
                for obj in QuestionSet.objects.filter(status="done"):
                    obj.status = "created"
                    obj.save()
            # Message
            lhtml.append("Created {} users".format(NUMBER_OF_PARTICIPANTS))

        # Check on choices
        if Choice.objects.count() == 0:
            # Load choices
            with open(choices_file) as f:
                reader = csv.reader(f, dialect='excel', delimiter='\t')
                left, right = zip(*reader)
            # Make lists
            left_lst = list(left)
            right_lst = list(right)
            # Copy and create from these lists
            break_points = ['heel', 'niet']
            with transaction.atomic():
                for idx, left in enumerate(left_lst):
                    right = right_lst[idx]
                    name = left
                    for bp in break_points:
                        if bp in left:
                            name = left.split(bp)[1].strip()
                            break
                    # Create object
                    Choice.objects.create(name=name, left=left, right=right)
            lhtml.append("Created {} choices".format(len(left_lst)))

        # Check on stimuli
        oErr.Status("initialize_woord #1")
        if additional != None and additional == "stimuli":
            # THis is a POST method, continue
            count = Stimulus.objects.count()
            # Delete
            Stimulus.objects.all().delete()
            # Prepare message
            lhtml.append("Stimuli deleted: {}".format(count))

        if Stimulus.objects.count() == 0:
            bNeedRandomization = True
            oErr.Status("initialize_woord #2")
            # Load the stimuli
            with open(stimuli_file) as f:
                reader = csv.reader(f, dialect='excel-tab')
                lst_stimuli = [get_stimulus(row) for row in reader]
            oErr.Status("initialize_woord #3")
            # Add the stimuli into the objects
            with transaction.atomic():
                # Note: skip the first line containing column headers
                for oStimulus in lst_stimuli[1:]:
                    woord = oStimulus['woord']
                    cat = oStimulus['cat']
                    note = oStimulus['note']
                    Stimulus.objects.create(woord=woord, category=cat, note=note)
            oErr.Status("initialize_woord #4")
            lhtml.append("Read from file {} stimuli".format(len(lst_stimuli)))

        # Otherwise in need of randomization?
        if Question.objects.count() == 0:
            bNeedRandomization = True

        # Do we need to randomize?
        if bNeedRandomization:
            # Remove previous questions
            Question.objects.all().delete()
            # Remove previous questions
            Qset.objects.all().delete()
            lhtml.append("Removed previous questions and qsets")

            # Combine stimuli and choices so that we have the full set
            if bOrderStimuli:
                # See issue #151
                result_sets = []
                with transaction.atomic():
                    # Iterate over the choices in the correct order
                    for choice in Choice.objects.filter(valid=True).order_by("id"):
                        # Stimuli for this result set
                        result = []
                        for stimulus in Stimulus.objects.all():
                            obj = Question.objects.create(stimulus=stimulus, choice=choice)
                            result.append(obj.id)
                        # Add this set to the result_sets
                        result_sets.append(result)
                lhtml.append("Created {} questions".format(Question.objects.count()))

                # Divide the shuffled questions over sets 
                num_sets = NUMBER_OF_PARTICIPANTS + 10
                for i in range(num_sets):
                    # Show where we are
                    oErr.Status("initialize_woord random set #{}".format(i))
                    # Create a Qset
                    qset = Qset.objects.create()
                    # Walk all the result sets
                    order = 0
                    for result in result_sets:
                        # Shuffle the question object id's
                        random.shuffle(result)
                        # Make the links for this shuffle
                        with transaction.atomic():
                            for idx, question_id in enumerate(result):
                                order = order + 1
                                QuestionSet.objects.create(qset=qset, question_id=question_id, order=order)
                lhtml.append("Created {} question sets".format(num_sets))

            else:
                result = []
                # Full randomization
                with transaction.atomic():
                    # Iterate over all stimuli (will be 5000)
                    # 2021: these are now 1823
                    for stimulus in Stimulus.objects.all():
                        # And then over all choices (should be just 1)
                        # 2021: this is now 2
                        for choice in Choice.objects.filter(valid=True):
                            # This yields 10,000 objects
                            obj = Question.objects.create(stimulus=stimulus, choice=choice)
                            result.append(obj.id)
                lhtml.append("Created {} questions".format(Question.objects.count()))

                # Divide the shuffled questions over sets 
                num_sets = NUMBER_OF_PARTICIPANTS + 10
                for i in range(num_sets):
                    # Show where we are
                    oErr.Status("initialize_woord random set #{}".format(i))
                    # Shuffle the question object id's
                    random.shuffle(result)
                    # Create a Qset
                    qset = Qset.objects.create()
                    # Make the links for this shuffle
                    with transaction.atomic():
                        for idx, question_id in enumerate(result):
                            order = idx + 1
                            QuestionSet.objects.create(qset=qset, question_id=question_id, order=order)
                lhtml.append("Created {} question sets".format(num_sets))

        # COmbine the message
        msg = "<br />".join(lhtml)
            
    except:
        msg = oErr.get_error_message()
        oErr.DoError("initialize_woord")

    return msg
Пример #3
0
def get_crpp_texts(sLng, sPart, sFormat, status):
    """Read the list of texts from the /crpp service (if available)"""

    oErr = ErrHandle()
    try:
        # Construct the object we pass along
        oTxtList = {'userid': "erwin",
                    'lng': sLng,
                    'ext': sFormat}
        # Possibly add 'dir'
        if sPart != None and sPart != "":
            oTxtList['dir'] = sPart
        # Set the correct URL
        url = CRPP_HOME + '/txtlist?' + json.dumps(oTxtList)
        # Default reply
        oBack = {}
        # Get the data from the CRPP api
        try:
            r = requests.get(url)
        except:
            # Getting an exception here probably means that the back-end is not reachable (down)
            oBack['status'] = 'error'
            oBack['code'] = "get_crpp_texts(): The back-end server (crpp) cannot be reached. Is it running? \n{} \nURL={}".format(
                get_exc_message(), url)
            return oBack
        # Action depends on what we receive
        if r.status_code == 200:
            # Convert to JSON
            reply = json.loads(r.text.replace("\t", " "))
            # Get the [content] part (note: no final 's')
            oContent = reply['content']
            # If all is well, then we receive just a jobid
            if "jobid" in oContent:
                sJobId = oContent['jobid']
                # Now continue to ask for the status
                oTxtListStatus = {'userid': "erwin", 'jobid': sJobId}
                url = CRPP_HOME + '/statusxl?' + json.dumps(oTxtListStatus)
                bDone = False
                while not bDone:
                    # Get the data from the CRPP api
                    try:
                        r = requests.get(url)
                    except:
                        error_info = sys.exc_info()
                        iStop = True
                    # Action depends on what we receive
                    if r.status_code == 200:
                        # Convert the reply to JSON
                        reply = json.loads(r.text.replace("\t", " "))
                        # Get the [content] part (note: no final 's')
                        oContent = reply['content']
                        # Get the status part
                        oStatus = reply['status']
                        if oStatus['code'] == "error":
                            # There is an error
                            oBack['status'] = 'error'
                            oBack['code'] = oContent['code'] + oContent['msg']
                            bDone = True
                            # Need to store this status!!!
                            status.set("crpp", oBack)
                        elif oStatus['code'] == "finished":
                            # The process is ready
                            bDone = True
                            # Get the textlist
                            oTextList = oContent['textlist']
                            # Define the lists
                            oBack['count'] = oTextList['texts']
                            oBack['subtype'] = oTextList['subtype']
                            oBack['genre'] = oTextList['genre']
                            oBack['paths'] = oTextList['paths']
                            oBack['txtlist'] = oTextList['list']
                            oBack['status'] = 'ok'

                            # What we show in the end is not what needs to be returned
                            oShow = dict(count=oTextList['texts'],
                                         subtype=oTextList['subtype'],
                                         paths=oTextList['paths'])
                            oShow['status'] = 'ok'
                            oShow['status.code'] = oStatus['code']
                            # Need to store this status!!!
                            status.set("crpp", oShow)
                        else:
                            # Update the synchronisation object that contains all relevant information
                            oBack['lng'] = sLng
                            oBack['part'] = sPart
                            oBack['format'] = sFormat
                            oBack['count'] = oContent['total']
                            oBack['status.code'] = oStatus['code']
                            oBack['last.url'] = url
                            status.set("crpp", oBack)

                            # DEBUGGING
                            sMsg = oStatus['code'] 
                            if 'msg' in oContent:
                                sMsg += " " + oContent['msg']
                            if 'msg' in oStatus:
                                sMsg += " " + oStatus['msg']
                            oErr.Status(sMsg)

                            # Make sure we wait some time before making the next request
                            period = 0.400
                            nexttime = time.time() + period
                            bReady = False
                            while not bReady:
                                now = time.time()
                                bReady = (now > nexttime)
                            
                    else:
                        # There is an error
                        oBack['status'] = 'error'
                        oBack['code'] = r.status_code
                        bDone = True
            else:
                oBack['status'] = 'error'
                oBack['code'] = ""

        else:
            oBack['status'] = 'error'
            oBack['code'] = r.status_code
    except:
        oBack['status'] = 'error'
        oBack['code'] = sys.exc_info()[1]

    # REturn what we have
    return oBack