Skip to content

Commit

Permalink
More generalized error statements, refactored error parsing dictionar…
Browse files Browse the repository at this point in the history
…y to include got, expected, file_path, and line_num keys
  • Loading branch information
Jacob Daniel Bennett committed Oct 14, 2020
1 parent ef86c7a commit dd8399f
Showing 1 changed file with 76 additions and 120 deletions.
196 changes: 76 additions & 120 deletions api/ECNQueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,28 +508,20 @@ def __editParsing(self, line: str, lineNum: int) -> dict:
formattedDateTime = ""
editedBy = ""

if not line.endswith(" ***\n"):

columnNum = len(line) - 1
errorMessage = "Expected the delimiter to end with \" ***\n\""

return self.__errorParsing(line, lineNum, columnNum, errorMessage)

# Parses for the author of the edit, which is located between the "*** Edited by: " and " at:" substrings
editedBy = (re.search("(?<=\*{3} Edited by: )(.*)(?= at:)", line)).group()

# ece23
try:
editedBy = (re.search("(?<=\*{3} Edited by: )(.*)(?= at:)", line)).group()
except:
errorMessage = "*** Edited by: [username] at: [date and time] ***\n"
return self.__errorParsing(line, lineNum, errorMessage)

try:
# Parses for the date and time of the edit, which is located between the " at: " and "***\n" substrings
dateTimeString = (re.search("(?<= at: )(.*)(?= \*\*\*\n)", line)).group()

except:
# Returns an error message if there is no space after "at:"

columnNum = line.find("at:") + 3
errorMessage = "Expected a space after \"at:\" followed by the date which is followed by \" ***\n\""

return self.__errorParsing(line, lineNum, columnNum, errorMessage)
errorMessage = "*** Edited by: [username] at: [date and time] ***\n"
return self.__errorParsing(line, lineNum, errorMessage)

# Attempts to format the date and time into utc format
formattedDateTime = self.__getFormattedDate(dateTimeString)
Expand All @@ -554,19 +546,20 @@ def __replyToParsing(self, line: str, lineNum: int) -> dict:
repliedBy = ""

#tech112
# Checks for malformed delimiter
if not line.endswith(" ***\n"):

columnNum = len(line) - 1
errorMessage = "Expected the delimiter to end with \" ***\n\""

return self.__errorParsing(line, lineNum, columnNum, errorMessage)

# Parses for the author of the reply, which is located between the "*** Replied by: " and " at:" substrings
repliedBy = (re.search("(?<=\*{3} Replied by: )(.*)(?= at:)", line)).group()
try:
# Parses for the author of the reply, which is located between the "*** Replied by: " and " at:" substrings
repliedBy = (re.search("(?<=\*{3} Replied by: )(.*)(?= at:)", line)).group()
except:
errorMessage = "*** Replied by: [username] at: [date and time] ***\n"
return self.__errorParsing(line, lineNum, errorMessage)

# Parses for the date and time of the reply, which is located between the " at: " and "***\n" substrings
dateTimeString = (re.search("(?<= at: )(.*)(?= \*\*\*\n)", line)).group()
try:
dateTimeString = (re.search("(?<= at: )(.*)(?= \*\*\*\n)", line)).group()
except:
errorMessage = "*** Replied by: [username] at: [date and time] ***\n"
return self.__errorParsing(line, lineNum, errorMessage)

# Formats date to UTC
formattedDateTime = self.__getFormattedDate(dateTimeString)
Expand All @@ -591,18 +584,20 @@ def __statusParsing(self, line: str, lineNum: int) -> dict:
updatedBy = ""

# Parses for the author of the status change, which is located between the "*** Status updated by: " and " at:" substrings
updatedBy = (re.search("(?<=\*{3} Status updated by: )(.*)(?= at:)", line)).group()

# tech 56
if not line.endswith(" ***\n"):

columnNum = len(line) - 1
errorMessage = "Expected the delimiter to end with \" ***\n\""
try:
updatedBy = (re.search("(?<=\*{3} Status updated by: )(.*)(?= at:)", line)).group()
except:
errorMessage = "*** Status updated by: [username] at: [date and time] ***\n"

return self.__errorParsing(line, lineNum, columnNum, errorMessage)
return self.__errorParsing(line, lineNum, errorMessage)

# Parses for the date and time of the status change, which is located between the " at: " and "***\n" substrings
dateTimeString = re.search("(?<= at: )(.*)(?= \*\*\*\n)", line).group()
try:
dateTimeString = re.search("(?<= at: )(.*)(?= \*\*\*\n)", line).group()
except:
errorMessage = "*** Status updated by: [username] at: [date and time] ***\n"

return self.__errorParsing(line, lineNum, errorMessage)

# Formats the date to UTC
formattedDateTime = self.__getFormattedDate(dateTimeString)
Expand All @@ -622,85 +617,64 @@ def __userReplyParsing(self, replyContent: list, lineNumber: int) -> dict:
Returns:
dictionary: "type": "replyFromUser", datetime, subject, userName, userEmail, content, ccRecipients
"""
formattedDateTime = ""
repliedByName = ""
repliedByEmail = ""
subject = ""
ccRecipientsList = []
replyFromInfo = {
"type": "reply_from_user",
"datetime": "",
"from_name": "",
"from_email": "",
"cc": [],
"content": []
}

newLineCounter = 0
endingDelimiterCount = 0

# Delimiter information line numbers to remove from reply from user
linesToRemove =[]


# Parses the section content looking for any line that starts with a metadata, also tracks the line
# number with the enumerate function
for lineNum, line in enumerate(replyContent):

#Checks for a newline and breaks for loop on second occurance of a newline
if line == "\n":

newLineCounter = newLineCounter + 1

if line.startswith("===="):

endingDelimiterCount = endingDelimiterCount + 1

if endingDelimiterCount > 1:

errorMessage = "Encountered two reply-from-user ending delimiters and expected only one"

return self.__errorParsing(line, lineNumber + lineNum + 1, 0, errorMessage)
if newLineCounter == 2:
break

elif endingDelimiterCount == 0 and lineNum == len(replyContent) - 1:

errorMessage = "Did not encounter a reply-from-user ending delimiter"
return self.__errorParsing(line, lineNumber + lineNum + 1, errorMessage)

return self.__errorParsing(line, lineNumber + lineNum + 1, 0, errorMessage)

# Checks for lines starting with Subject, From, Date and CC
elif line.startswith("Subject: ") and newLineCounter < 2:

# Matches everything after "Subject: " in the line
subject = (re.search("(?<=Subject: )(.*)", line)).group()

linesToRemove.append(lineNum)

elif line.startswith("From: ") and newLineCounter < 2:

# Returns a list of tuples with name and email information
elif line.startswith("From: "):
# Returns a list of one tuples with a name stored in the first index of the tuple and an email stored in the second index of the tuple
emailList = email.utils.getaddresses([line])

# The name in stored in the first index of the tuple
repliedByName = emailList[0][0]

# The email is stored in the second index of the tuple
repliedByEmail = emailList[0][1]
replyFromInfo["from_name"] = emailList[0][0]
replyFromInfo["from_email"] = emailList[0][1]

linesToRemove.append(lineNum)

elif line.startswith("Date: ") and newLineCounter < 2:

elif line.startswith("Date: "):
# Matches everything after "Date: "
try:
dateStr = (re.search("(?<=Date: )(.*)", line)).group()
except:
errorMessage = "\"Date: [datetime]\""
return self.__errorParsing(line, lineNumber + lineNum + 1, errorMessage)

dateStr = (re.search("(?<=Date: )(.*)", line)).group()

dateStr = ""
# Formatts the date to UTC
formattedDateTime = self.__getFormattedDate(dateStr)
replyFromInfo["datetime"] = self.__getFormattedDate(dateStr)

linesToRemove.append(lineNum)

elif line.startswith("Cc: ") and newLineCounter < 2:

elif line.startswith("Cc: "):
# Returns a list of tuples with email information
recipientsList = email.utils.getaddresses([line])

# Parses through the cc tuple list
for cc in recipientsList:

# Stores the cc information in a dictionary and appends it to the ccRecipientsList
ccRecipientsList.append(
replyFromInfo["cc"].append(
{"name":cc[0],
"email":cc[1]}
)
Expand All @@ -712,16 +686,7 @@ def __userReplyParsing(self, replyContent: list, lineNumber: int) -> dict:
replyContent.pop(lineNum)

# Strips any unnecessary newlines or any delimiters frm the message content
replyContent = self.__getFormattedMessageContent(replyContent)

replyFromInfo = {
"type": "reply_from_user",
"datetime": formattedDateTime,
"from_name": repliedByName,
"from_email": repliedByEmail,
"cc": ccRecipientsList,
"content": replyContent
}
replyFromInfo["content"] = self.__getFormattedMessageContent(replyContent)

return replyFromInfo

Expand All @@ -731,38 +696,29 @@ def __getFormattedMessageContent(self, messageContent: list) -> list:
Returns:
list: formattedMessageContent
"""
# Parses looking for the reply-from-user ending delimiter adn removes the first line that contains the ending delimiter.


# Continually loops while looking at the first line of messageContent, removing it from messageContent
# if its a newline. Doesn't run if there is only one line in message content.

# Continually removes the first line of messageContent if it is a newline or delimiter in each iteration
while len(messageContent) > 1:
if messageContent[0] == "\n" or messageContent[0].startswith("***") or messageContent[0].startswith("===") :
messageContent.pop(0)

else:
# Breaks the loop if the first line isn't a newline
# Breaks the loop if the first line isn't a newline or delimiter
break


# Continually removes the last line of messageContent if it is a newline or delimiter in each iteration
while len(messageContent) > 1:

# Initializes the Length of messageContent each iteration of the loop
messagecontentLength = len(messageContent)

# Checks if the last line is a newline
if messageContent[messagecontentLength -1] == "\n" or messageContent[messagecontentLength -1].startswith("===="):

# Deletes the last line if it is a newline
messageContent.pop(messagecontentLength - 1)

else:
# Breaks the loop if the last line isn't a newline
# Breaks the loop if the last line isn't a newline or delimiter
break

return messageContent

def __errorParsing(self, line: str, lineNum: int, lineColumn: int, errorMessage: str) -> dict:
def __errorParsing(self, line: str, lineNum: int, expectedSyntax: str) -> dict:
"""Returns a dictionary with error parse information
Returns:
Expand All @@ -779,17 +735,23 @@ def __errorParsing(self, line: str, lineNum: int, lineColumn: int, errorMessage:
errorDictionary = {
"type": "parse_error",
"datetime": self.__getFormattedDate(str(datetime.datetime.now())),
"content": []
"file_path": "",
"expected": "",
"got": "",
"line_num": 0
}

# Error message with itemm line and column numbers
errorMessage = errorMessage + " at " + str(lineNum) + ":" + str(lineColumn)
# Filepath
errorDictionary["file_path"] = self.__path

# Appends the error message to the content list in the error dictionary
errorDictionary["content"].append(errorMessage)
# Error message with itemm line and column numbers
errorDictionary["expected"] = expectedSyntax

# Appends the item line to the content list in the error dictionary
errorDictionary["content"].append(line)
errorDictionary["got"] = line

# Apeends error num to the dictonary
errorDictionary["line_num"] = lineNum

# returns the error dictionary
return errorDictionary
Expand Down Expand Up @@ -983,9 +945,3 @@ def getQueues() -> list:
queues.append(Queue(file))

return queues
if __name__ == "__main__":
item = Item("aae", 2)
print()
# for queue in getQueues():
# for item in queue.items:
# print(f"${item.queue} ${item.number}")

0 comments on commit dd8399f

Please sign in to comment.