def is_answer(line):

    return re.search(ansregex, line) is not None def is_bpart(line):
    
    return re.search(bpart_regex, line) is not None def is_vhsl_bpart(line):
    
    return re.search(vhsl_bpart_regex, line) is not None def is_category(line):
    
    return re.search(category_regex, line) is not None def parse_packet_data(data, question_set):

    data = [line for line in data if line.strip() != '']

    tossups = []
    bonuses = []

    tossup_errors = []
    bonus_errors = []

    tossup_flag = False
    bonus_flag = False
    vhsl_bonus_flag = False
    
    question_stack = []

    for i in range(len(data)):

        this_line = data[i].strip()
        
        # push current line onto the stack
        question_stack.append(this_line)

        if not tossup_flag and not bonus_flag and not vhsl_bonus_flag:
            if is_answer(this_line):
                # if no flags have been set, and we encounter an ANSWER: then we
                # know that this is a tossup
                tossup_flag = True
            elif is_bpart(this_line):
                # if no flags have been set and we encounter a [10] then we
                # know that this is a bonus
                bonus_flag = True
            elif is_vhsl_bpart(this_line):
                # if not flags have been set and we encounter a [V10] then we
                # know that this is a VHSL bonus
                vhsl_bonus_flag = True

        # print this_line
        # print tossup_flag, bonus_flag, vhsl_bonus_flag

        # if there are two items on the stack and the second one is an ANSWER:
        # pop the stack and create a tossup
        if (len(question_stack) == 2 or i == len(data) - 1) and tossup_flag:
            if (len(question_stack) < 2):
                # print "Tossups required both a question and answer, but only one item found on stack."
                tossup = Tossup('', question_stack.pop(), i, '')
                tossup_errors.append(tossup)
            else:
                tossup_answer = question_stack.pop()
                tossup_category = get_category(tossup_answer)
                tossup_answer = remove_category(tossup_answer)

                tossup_text = question_stack.pop()
                tossup = None        
                try:
                    tossup = create_tossup(tossup_text, tossup_answer, tossup_category, question_set=question_set)
                    validate_tossup_category(tossup, tossup_category)                    
                    tossup.is_valid()
                    tossups.append(tossup)
                except InvalidTossup as ex:
                    # print ex
                    tossup_errors.append(ex)
                tossup_flag = False
            
        # if we are in bonus mode and the line is not an answer or a bonus part
        # then pop the stack until it's empty and form a bonus
        elif bonus_flag and ((not is_answer(this_line) and not is_bpart(this_line)) or i == len(data) - 1):
            
            # If there are still lines to read, the top of the stack represents the first line
            # in the next question.  Otherwise, it's the last part of the bonus and we don't
            # want to pop it
            next_question_line = ''
            if (i < len(data) - 1):
                next_question_line = question_stack.pop()
                
            parts = []
            values = []
            answers = []
            leadin = ''
            category = ''
            while question_stack != []:
                bonus_line = question_stack.pop()
                # print "Bonus Line from question stack: " + bonus_line
                if is_bpart(bonus_line):
                    # print "Is BPart"
                    val = get_bonus_part_value(bonus_line)
                    question = string.strip(re.sub(bpart_regex, '', bonus_line))
                    values.append(val)
                    parts.append(question)
                elif is_answer(bonus_line):
                    # print "Is Answer"
                    answer = bonus_line
                    tempCategory = get_category(answer)
                    # print "Answer Line: " + answer
                    # print "TempCategory: " + tempCategory
                    if (tempCategory != ''):
                        category = tempCategory
                        answer = remove_category(answer)
                    
                    answers.append(answer)
                else:
                    # print "Is Leadin"
                    leadin = bonus_line
            parts.reverse()
            values.reverse()
            answers.reverse()
            
            # print leadin
            # print parts
            # print answers
            
            if (i < len(data) - 1):
                question_stack.append(next_question_line)
            
            bonus = None
            try:
                bonus = create_bonus(leadin, parts, answers, values, question_type_text=ACF_STYLE_BONUS, category_text=category, question_set=question_set)
                validate_bonus_category(bonus, category)                
                bonus.is_valid()
                bonuses.append(bonus)
            except InvalidBonus as ex:
                # print ex
                bonus_errors.append(ex)
            bonus_flag = False

        # special case for vhsl bonuses
        # There isn't a great way to tell VHSL bonuses from other bonuses, so need to require a special
        # bonus part flag of [V10] rahter than just [10]
        elif vhsl_bonus_flag and (is_answer(this_line) or i == len(data) - 1):
            answer = question_stack.pop()
            question = question_stack.pop()
            question = string.strip(re.sub(vhsl_bpart_regex, '', question))
            answer = string.strip(re.sub(ansregex, '', answer))
            category = get_category(answer)
            answer = remove_category(answer)
            
            bonus = None
            try:
                bonus = create_bonus('', [question], [answer], [], question_type_text=VHSL_BONUS, category_text=category, question_set=question_set)
                validate_bonus_category(bonus, category)
                bonus.is_valid()
                bonuses.append(bonus)
            except InvalidBonus as ex:
                # print ex
                bonus_errors.append(ex)
            vhsl_bonus_flag = False
 
    return tossups, bonuses, tossup_errors, bonus_errors def get_bonus_part_value(line):
    
    match = re.search(bpart_regex, line)
    return re.sub(bonus_value_regex, '', match.group(0))      def remove_category(line):
    
    return re.sub(category_regex, '', line) def remove_answer_label(line):
    
    return re.sub(ansregex, '', line) def get_character_count(line, ignore_pronunciation):
    if not ignore_pronunciation:
        return len(line)

    count = 0
    parensFlag = False # Parentheses indicate pronunciation guide
    previousChar = ""
    for c in line:
        if (parensFlag):
            if (c == ")" and previousChar != "\\"):
                parensFlag = False
        else:
            if (c == "(" and previousChar != "\\"):
                parensFlag = True                    
            elif (c != "~" and not (previousChar == "\\" and (c == ")" or c == "("))):
                count = count + 1 # Only count non-special chars not in pronunciation guide
        previousChar = c

    return count def get_formatted_question_html(line, allowUnderlines, allowParens, allowNewLines, allowPowers):
    italicsFlag = False
    parensFlag = False
    underlineFlag = False
    needToRestoreItalicsFlag = False
    subScriptFlag = False
    superScriptFlag = False
    powerFlag = False
    powerIndex = -1
    promptFlag = False
    index = 0
    
    previousChar = u""
    secondPreviousChar = u""
    output = u""
    nextChar = u""
    
    # If powers are allowed, see if there's a power in this question
    # If so, then start the question in power
    if (allowPowers):        
        powerIndex = line.find(u"(*)")
        if (powerIndex > -1):
            powerFlag = True
            output += u"<strong>"
                
    while (index < len(line)):
        c = line[index]        
        if (index < len(line) - 1):
            nextChar = line[index + 1]
        else:
            nextChar = ""
        
        if (index >= powerIndex and powerFlag):
            powerFlag = False
            output += u"(*)</strong>"
            index += 3 # Skip over the rest of what's in the power mark
            continue
        
        if (c == u"~"):
            if (not italicsFlag):
                output += u"<i>"
                italicsFlag = True
            else:
                output += u"</i>"
                italicsFlag = False
        elif (c == u"(" and allowParens and previousChar != u"\\"):
            if (italicsFlag):
                needToRestoreItalicsFlag = True
                itatlicsFlag = False
                output += u"</i>"
            
            if (not powerFlag):
                output += u"<strong>("
                parensFlag = True
            else:
                output += u"("
        elif (c == u"(" and allowParens and previousChar == u"\\" and secondPreviousChar != u"\\"):
            output = output[:-1] # Get rid of the escape character
            output += c
        elif (c == u")" and allowParens and previousChar != u"\\" and secondPreviousChar != u"\\"):
            if (not powerFlag):
                output += u")</strong>"
                parensFlag = False
            else:
                output += u")"

            if (needToRestoreItalicsFlag):
                output += u"<i>"
                italticsFlag = True
                needToRestoreItalicsFlag = False

        elif (c == u")" and allowParens and previousChar == u"\\"):
            output = output[:-1] # Get rid of the escape character
            output += c
        elif (c == u"s" and previousChar == u"\\" and secondPreviousChar != u"\\" and not superScriptFlag):
            output = output[:-1] # Get rid of the escape character
            if (subScriptFlag):
                subScriptFlag = False
                output += u"</sub>"
            else:
                subScriptFlag = True
                output += u"<sub>"
        elif (c == u"S" and previousChar == u"\\" and secondPreviousChar != u"\\" and not subScriptFlag):
            output = output[:-1] # Get rid of the escape character
            if (superScriptFlag):
                superScriptFlag = False
                output += u"</sup>"
            else:
                superScriptFlag = True
                output += u"<sup>"
        else:
            if (c == u"_" and allowUnderlines):
                if (nextChar == u"_"):
                    # This is a prompt
                    if (not promptFlag):
                        output += u"<u>"
                        promptFlag = True
                    else:
                        output += u"</u>"
                        promptFlag = False
                    
                    index += 1 # Skip ahead so we don't re-process this character
                else:
                    # This is a regular answer line
                    if (not underlineFlag):
                        output += u"<u><b>"
                        underlineFlag = True
                    else:
                        output += u"</b></u>"
                        underlineFlag = False
            else:
                output += c
        secondPreviousChar = previousChar
        previousChar = c
        index += 1

    if (italicsFlag):
        output += u"</i>"

    if (underlineFlag):
        output += u"</b></u>"

    if (parensFlag):
        output += u"</strong>"
        
    if (powerFlag):
        output += u"</strong>"
        
    if (promptFlag):
        output += u"</u>"

    if (allowNewLines):
        output = output.replace(u"&lt;br&gt;", u"<br />")

    return output def are_special_characters_balanced(line):
    underlineFlag = False
    italicsFlag = False
    parensFlag = False
    previousChar = ""
    for c in line:
        if (c == '_'):
            if (underlineFlag):
                underlineFlag = False
            else:
                underlineFlag = True
        elif (c == '~'):
            if (italicsFlag):
                italicsFlag = False
            else:
                italicsFlag = True
        elif (c == '(' and previousChar != "\\"):
            if (parensFlag):
                # There are too many open parens
                return False
            else:
                parensFlag = True
        elif (c == ')' and previousChar != "\\"):
            if (parensFlag):
                parensFlag = False
            else:
                # There are too many close parens
                return False
        previousChar = c

    if (underlineFlag or italicsFlag or parensFlag):
        return False
    else:
        return True
from django.test import SimpleTestCase
from django.contrib.auth.models import AnonymousUser, User
from datetime import datetime
from django.utils import timezone
from django.contrib.auth.models import User
from django.test import TestCase
from datetime import datetime
from qems2.qsub.packet_parser import is_answer, is_bpart, is_vhsl_bpart, is_category
from qems2.qsub.packet_parser import parse_packet_data, get_bonus_part_value, remove_category
from qems2.qsub.packet_parser import remove_answer_label
from qems2.qsub.utils import get_character_count, get_formatted_question_html, are_special_characters_balanced
from qems2.qsub.models import *
from qems2.qsub.model_utils import *
from qems2.qsub.packetizer import *
import django
<<<<<<< HEAD
=======
>>>>>>> dc5f333216071c2f7e80ec9a556251516d74364a


class PacketParserTests(TestCase):

    # TODO: Determine if we really need this block of code anymore
    #if django.VERSION[:2] == (1, 7):
    #    # Django 1.7 requires an explicit setup() when running tests in PTVS
    #    @classmethod
    #    def setUpClass(cls):
    #        django.setup()
    #elif django.VERSION[:2] >= (1, 8):
    #    # Django 1.8 requires a different setup. See https://github.com/Microsoft/PTVS-Samples/issues/1
    #    @classmethod
    #    def setUpClass(cls):
    #        super(DjangoTestCase, cls).setUpClass()
    #        django.setup()

    user = None
    writer = None
    dist = None
    qset = None
    pwe = None
    packet = None
    period = None
    ce = None
    cefd = None
    pwce = None
    opce = None
    acf_tossup = None
    acf_bonus = None
    vhsl_bonus = None
    
    acf_reg_dist = None
    acf_tb_dist = None
    acf_qset = None
    
    acf_reg_pwe = None
    acf_tb_pwe = None
    
    acf_packets = []
    acf_reg_periods = []
    acf_tb_periods = []
    
    acf_ces = []
    acf_reg_cefds = []
    acf_tb_cefds = []
    
    #########################################################################
    # Setup and helper methods
    #########################################################################
    
    def setUp(self):
<<<<<<< HEAD
        acfTossup = QuestionType.objects.get_or_create(question_type=ACF_STYLE_TOSSUP)
        acfBonus = QuestionType.objects.get_or_create(question_type=ACF_STYLE_BONUS)
        vhslBonus = QuestionType.objects.get_or_create(question_type=VHSL_BONUS)
    
    # If the object exists, re-query it from the DB to get updated properties
    def reload_standard_objects(self):         
        if (self.user is not None):
            self.user = User.objects.get(id=self.user.id)
=======
        self.user = User.objects.create_user(username="testuser", password="top_secret", email="qems2test@gmail.com")
        self.user.save()
                        
        self.writer = Writer.objects.get(user=self.user.id)
        self.writer.save()

        acfTossup = QuestionType.objects.get_or_create(question_type=ACF_STYLE_TOSSUP)
        acfBonus = QuestionType.objects.get_or_create(question_type=ACF_STYLE_BONUS)
        vhslBonus = QuestionType.objects.get_or_create(question_type=VHSL_BONUS)
            
    def test_is_answer(self):
        answers = ["answer:", "Answer:", "ANSWER:", "ANSWER: _underlined_", "ANSWER: no underline", "ANSWER: <u>underline2</u>"]
        for answer in answers:
            self.assertTrue(is_answer(answer), msg=answer)
        non_answers = ["question:", "answer", "ansER"]
        for non_answer in non_answers:

            self.assertFalse(is_answer(non_answer), msg=non_answer)