Skip to content

Commit

Permalink
Complete initial ECNQueue.py Python 3 rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Campbell committed Jul 26, 2020
1 parent a63c80c commit 8d6c5fe
Showing 1 changed file with 198 additions and 0 deletions.
198 changes: 198 additions & 0 deletions api/ECNQueue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# TODO: Add ECNQueue module documentation

#------------------------------------------------------------------------------#
# Imports
#------------------------------------------------------------------------------#
import os, time, email, re
from typing import Union



#------------------------------------------------------------------------------#
# Configuration
#------------------------------------------------------------------------------#

# The directory where queue items are
queueDirectory = "/Users/justincampbell/GitHub/ecn-queue/webqueue/q-snapshot"



#------------------------------------------------------------------------------#
# Classes
#------------------------------------------------------------------------------#
class Item:
# TODO: Add Item class documentation

def __init__(self, queue: str, number: int) -> None:
self.queue = queue
self.number = number

self.__path = "/".join([queueDirectory, self.queue, str(self.number)])
self.lastUpdated = self.__getLastUpdated()
self.__rawItem = self.__getRawItem()
self.headers = self.__parseHeaders()
self.content = self.__getContent()
self.isLocked = self.__isLocked()

def __getLastUpdated(self) -> float:
"""Returns last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format.
Example:
07-23-20 10:34 AM
Returns:
float: last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format.
"""
unixTime = os.path.getmtime(self.__path)
formattedTime = time.strftime('%m-%d-%y %I:%M %p', time.localtime(unixTime))
return formattedTime

def __getRawItem(self) -> list:
"""Returns a list of all lines in the item file
Returns:
list: List of all the lines in the item file
"""
with open(self.__path) as file:
return file.readlines()

def __getHeaderBoundary(self) -> int:
"""Returns the 0 based line number where the Item headers stop.
Example: The header end would be on line 13
12: X-ECN-Queue-Original-URL:
13:
14: I need help.
Returns:
int: line number where the Item headers end
"""
for lineNumber, line in enumerate(self.__rawItem):
if line == "\n":
return lineNumber

def __parseHeaders(self) -> list:
"""Returns a list containing dictionaries of header type and data.
Removes queue prefixes and whitespace.
Examples:
"[ce] QStatus: Dont Delete\\nFrom: Justin Campbell <campb303@purdue.edu>\\n"
becomes
[
{"QStatus": "Don't Delete"},
{"From": "Justin Campbell <campb303@purdue.edu>"}
]
Returns:
list: Header dicts
"""
headerString = ""

# Remove '[queue] ' prefixes:
# Example:
# [ce] QTime-Updated-By: campb303 becomes
# QTime-Updated-By: campb303
queuePrefixPattern = re.compile("\[.*\] {1}")
for lineNumber in range(self.__getHeaderBoundary() - 1):
line = self.__rawItem[lineNumber]
lineHasQueuePrefix = queuePrefixPattern.match(line)

if lineHasQueuePrefix:
queuePrefix = line[ lineHasQueuePrefix.regs[0][0] : lineHasQueuePrefix.regs[0][1]]
line = line.replace(queuePrefix, "")

headerString += line

message = email.message_from_string(headerString + "".join(self.__getContent()))

headers = []
for key in message.keys():
headers.append( { "type": key, "content": message[key] } )

return headers

# TODO: Implement attachment parsing

def __getContent(self) -> list:
"""Returns a dictionary lines of the item body.
Example:
"Hello. I need help.\\n\\n*** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\\nDont Delete" becomes
[
"Hello. I need help.\\n",
"\\n",
"*** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\\n",
"Don't Delete",
]
Returns:
list: Lines of the body item.
"""
contentStart = self.__getHeaderBoundary() + 1
contentEnd = len(self.__rawItem) - 1
return self.__rawItem[ contentStart : contentEnd ]

# TODO: Implement section parsing.

def __isLocked(self) -> Union[str, bool]:
"""Returns a string info about the lock if true and a bool False if false
Example: A file is locked
"CE 100 is locked by campb303 using qvi"
Example: a file is not locked
False
Returns:
Union[str, bool]: String with info about lock if true, bool False if false
"""
lockFile = self.__path + ".lck"
if os.path.exists(lockFile):
with open(lockFile) as file:
lockInfo = file.readline().split(" ")
lockedBy = lockInfo[4]
lockedUsing = lockInfo[1]
return "{queue} {number} is locked by {lockedBy} using {lockedUsing}".format(queue=self.queue, number=self.number, lockedBy=lockedBy, lockedUsing=lockedUsing)
else:
return False

def __repr__(self) -> str:
return self.queue + str(self.number)

class Queue:
# TODO: Add Queue class documentation

def __init__(self, name: str) -> None:
self.name = name
self.__directory = queueDirectory + "/" + self.name + "/"
self.items = self.__getItems()
self.length = len(self)

def __getItems(self) -> list:
"""Returns a list of items for this Queue
Returns:
list: a list of items for this Queue
"""
items = []

for item in os.listdir(self.__directory):
itemPath = self.__directory + "/" + item

isFile = True if os.path.isfile(itemPath) else False

itemPattern = re.compile("^[0123456789]{1,3}$")
isItem = True if itemPattern.match(item) else False

if isFile and isItem:
items.append( Item(self.name, item) )

return items

def __len__(self) -> int:
return len(self.items)

if __name__ == "__main__":
# queue = Queue("ce")
item = Item("ce", 9)
print("s")

0 comments on commit 8d6c5fe

Please sign in to comment.