Skip to content

0.9.1 Merge #200

Merged
merged 155 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
155 commits
Select commit Hold shift + click to select a range
1dd473c
Implementation of headers only by passing a boolean to the Item class…
Nov 2, 2020
afaaf81
update documentation for header-only and more efficient jsondata defi…
Nov 3, 2020
6e6492b
Added background state varible and created lastUpdatedCell component …
Nov 23, 2020
a6d8132
Removed uncesscary function and variables. Changed name of the state …
Nov 25, 2020
0123593
Remove debugging comments
Nov 29, 2020
db08a0f
Change wholeItem to headersOnly and add to Item, Queue and loadAllQueues
Nov 29, 2020
5dc0aa7
Update docs
Nov 29, 2020
21f347c
Update docs
Nov 29, 2020
d8225d8
Add headersOnly flags to API
Nov 30, 2020
ab75000
Implemented logic for changing cell color based on last updated time.
Dec 2, 2020
6b67902
implemented logic that sets color of lastUpdated cell based on time o…
Dec 3, 2020
c418a5a
Forammting fixes, removed uneccessary overrides, fixed date received…
Dec 3, 2020
ad4935b
Error parsing for empty headers in Additional info from user section
Dec 3, 2020
c895ef1
readabilty update
Dec 3, 2020
d842e2c
disabled autoResetSortBy to allow for sorting to persist when data ch…
Dec 9, 2020
140c71e
Removed Paper render to remove extraneous shadows
Dec 11, 2020
3a95107
Changed the table render to the small variant in order to reduce unee…
Dec 11, 2020
561d435
Styling fixes for sort by buttons to add visual weight and make them …
Dec 11, 2020
2cccad2
Set autoResetFilters to false in order to stop filters from resetting…
Dec 11, 2020
c20b9b8
Minor formatting
campb303 Dec 16, 2020
38445fe
Merge pull request #154 from ECN/enhancement-persistent-filters-and-s…
campb303 Dec 16, 2020
4c57b61
Created ItemTableCell and LastUpdated cell components for refactoring…
wrigh393 Dec 16, 2020
566efca
Add spacing for table
campb303 Dec 16, 2020
56d6f28
Remove unused classes
campb303 Dec 16, 2020
ae03e13
Fixed background color not displaying in LastUpdatedCell component
wrigh393 Dec 17, 2020
3effeb7
Refactored sorting to its own component
wrigh393 Dec 17, 2020
6019e2b
Fixed merge conflict
wrigh393 Dec 17, 2020
9aa5321
Fixed column border gap
wrigh393 Dec 18, 2020
2bd362c
Update Python requirements to fix Flask_JWT_Extended and PyJWT conflict
campb303 Dec 30, 2020
db5f1a1
Refactored ItemTableFilter to allow the label to hide label overlfow …
wrigh393 Dec 30, 2020
d0dc7fe
Implementation of alphabetical sorting for the getQueueCounts function
benne238 Jan 5, 2021
2a50f12
removal of debugging tools
benne238 Jan 5, 2021
bb68f11
Implement logic for default sorting order of ItemTable
wrigh393 Jan 8, 2021
7373d88
Removed uncessary desc key from intialState.sortBy in the table optio…
wrigh393 Jan 8, 2021
30d9cfe
implementation of blank content handling
benne238 Jan 11, 2021
ea9dec3
Removed unecesssary classes/props
wrigh393 Jan 12, 2021
02b9990
Removed unecessary class
wrigh393 Jan 12, 2021
0df01d7
Implemented code for hover styling in ItemTable
wrigh393 Jan 12, 2021
610bc86
removal of queueDirectory testing code
benne238 Jan 12, 2021
1e819d8
Fix for greedy regular expressions causing improper header parsing
campb303 Jan 19, 2021
8ac1d92
Update Python requirements to fix Flask_JWT_Extended and PyJWT
campb303 Dec 30, 2020
7110cda
Update venv-manager to allow 60 second for requirement installation
campb303 Dec 30, 2020
f36ac8e
Moved ternary statements to swtich statement for readability
campb303 Jan 20, 2021
375b679
Formatting
campb303 Jan 20, 2021
55de973
Rename reactTableProps to TableCellProps
campb303 Jan 20, 2021
fc608a6
Renamed folder and update exports
campb303 Jan 20, 2021
0c3f1bb
Formatting
campb303 Jan 20, 2021
813438a
Remove unused backgroundColor prop
campb303 Jan 21, 2021
672b0f9
Refactir timeToBackgroundColor and inject background color into props
campb303 Jan 21, 2021
86b75a1
Rename reactTableProps to ItemTableCellProps
campb303 Jan 21, 2021
e3724de
Make time prop required
campb303 Jan 21, 2021
9df197e
Add docs
campb303 Jan 21, 2021
246e4d9
Add docs
campb303 Jan 21, 2021
1ed9daa
Update docs to show what values the time prop can be
campb303 Jan 21, 2021
1084d86
Merge branch 'staging' into enhancement-lastupdated-styling
campb303 Jan 22, 2021
f3aa06f
Merge pull request #135 from ECN/enhancement-lastupdated-styling
campb303 Jan 22, 2021
3eabe11
Fix for dark mode background toggle
campb303 Jan 22, 2021
34b73ca
Merge branch 'enhancement-lastupdated-styling' of github.itap.purdue.…
campb303 Jan 22, 2021
ebcda1d
Merge pull request #167 from ECN/enhancement-lastupdated-styling
campb303 Jan 22, 2021
4936578
Update Python requirements to fix Flask_JWT_Extended and PyJWT conflict
campb303 Dec 30, 2020
4910621
Update venv-manager to allow 60 second for requirement installation
campb303 Dec 30, 2020
a647639
Add EasyAD to project requirements
campb303 Jan 22, 2021
75e8cd4
Replace shared username/password with AD auth
campb303 Jan 22, 2021
e068623
Update comments
campb303 Jan 22, 2021
7ec22d6
Update venv-manager to allow 60 second for requirement installation
campb303 Jan 27, 2021
8201b54
Remove egg-info files for Python module installation and add to gitig…
campb303 Jan 27, 2021
3b5399d
Fix ignore for egg-info
campb303 Jan 27, 2021
f5b4b1e
Update comments
campb303 Jan 27, 2021
7925d9a
Merge pull request #160 from ECN/Feature-Sort-queue-counts-by-queue-n…
benne238 Jan 27, 2021
02ab227
fix for accounting for empty content in messages
benne238 Jan 28, 2021
d9942b9
removal of debugging lines
benne238 Jan 28, 2021
25b33a6
Update comments, change minor formatting
campb303 Jan 28, 2021
7535510
Squashed commit of the following:
benne238 Jan 31, 2021
64f0f0d
Merge pull request #173 from ECN/Bugfix-Queues-That-Won't-Load
campb303 Jan 31, 2021
72579af
Revert "Squashed commit of the following:"
benne238 Jan 31, 2021
fc90e73
Merge branch 'Bugfix-Webmaster-Queue' of github.itap.purdue.edu:ECN/w…
benne238 Jan 31, 2021
73a930c
bugfix for item.__getUserAlias() function
benne238 Feb 1, 2021
cb7a5fd
removal of debugging lines from previous commit
benne238 Feb 1, 2021
e33eec0
Add pyldap build process to venv-manager
campb303 Feb 1, 2021
469d4bd
Update requirements.txt to include pyldap and update comments
campb303 Feb 1, 2021
86b3395
Minor formatting changes
wrigh393 Feb 1, 2021
55df82b
Added queue as one of the default sort props
wrigh393 Feb 1, 2021
98843ef
explicit error handling for spliting and invalid email address
benne238 Feb 1, 2021
acaf76c
Merge pull request #140 from ECN/Bugfix-Webmaster-Queue
campb303 Feb 1, 2021
9b8c010
Implemented InvertedSort prop for LastUpdated and DateRecieved columns
wrigh393 Feb 1, 2021
75b2ff3
Update venv-manager to allow 60 second for requirement installation
campb303 Feb 1, 2021
e6c4877
Formatting, reorder imports, remove unused styles, simplify hover rule
campb303 Feb 1, 2021
c5f48d4
Merge remote-tracking branch 'origin/enhancement-hover-styling' into …
campb303 Feb 2, 2021
7af8823
Merge branch 'staging' into enhancement-default-sort-order
campb303 Feb 2, 2021
7be45ff
Merge pull request #161 from ECN/enhancement-default-sort-order
campb303 Feb 2, 2021
3edc67a
Minor formatting
campb303 Feb 2, 2021
9cb49bf
update api according to git issue 170: consolidate API endpoints unde…
benne238 Feb 2, 2021
c02fae3
updated /api/get_queues endpoint to /api/data/get_queues
benne238 Feb 2, 2021
b91f0d9
Add global exit codes with docs
campb303 Feb 3, 2021
2595643
Refactored code to reduce number of props for ItemTableSortButtons co…
wrigh393 Feb 3, 2021
10de4bd
Fixed merge conflicts
wrigh393 Feb 3, 2021
db580ee
Update refresh token path
campb303 Feb 3, 2021
1b0fafb
Update hompage entry
wrigh393 Feb 3, 2021
311ad72
Updated auth utilities paths
wrigh393 Feb 3, 2021
7cac01a
Updated API routes
wrigh393 Feb 3, 2021
ec5680c
Remove breaking character
campb303 Feb 4, 2021
1a84209
Prepend API calls with subdirectory path
campb303 Feb 4, 2021
1a91015
Prepend API calls with subdirectory path
campb303 Feb 4, 2021
c3792a0
Update QueueSelector.js
campb303 Feb 4, 2021
e2c00d1
Add comment explaining overflow fix
campb303 Feb 8, 2021
1145f3b
Merge remote-tracking branch 'origin/bugfix-filter-label-overflow' in…
campb303 Feb 8, 2021
ca62502
Merge pull request #158 from ECN/bugfix-filter-label-overflow
campb303 Feb 8, 2021
0799a8f
Updated ItemTableSortButtons docs with examples of usage
wrigh393 Feb 8, 2021
c7e264f
removal of wekzeug.security import from api
benne238 Feb 11, 2021
b56e225
update requirements.txt
benne238 Feb 11, 2021
3139fb6
Removed duplicate columns in ItemTable
benne238 Feb 11, 2021
f48de17
update gitignore for .egg files
benne238 Feb 11, 2021
5b2d5c0
Merge remote-tracking branch 'origin/implement-active-directory-auth'…
campb303 Feb 12, 2021
8eb152d
Add from field to ItemTable
campb303 Feb 12, 2021
0460c0c
Merge pull request #193 from ECN/enhancement-add-from-to-ItemTable
wrigh393 Feb 15, 2021
fd49dd7
Add headersOnly to docstrings
campb303 Feb 21, 2021
f960cd3
Make Queue objects iterable
campb303 Feb 21, 2021
c435fe1
Update iterable interface to avoid parse error
campb303 Feb 21, 2021
6a1b660
Add example to Queue endpoint docs
campb303 Feb 21, 2021
f52daa5
Merge branch 'staging' into Feature-Load-Item-Headers-Only
campb303 Feb 22, 2021
748a49c
Fix Queue endpoint error from merge
campb303 Feb 22, 2021
666135f
Create ItemProvider w/ Docs
campb303 Feb 22, 2021
27f9fba
Replace activeItem state variable with context provider values
campb303 Feb 22, 2021
abb9a79
Implement code for testing skeleton view UI in ItemBodyView
wrigh393 Feb 22, 2021
c73fb0e
WIP Skeleton view for ItemTable
wrigh393 Feb 23, 2021
4b12f9e
Merge branch 'Feature-Load-Item-Headers-Only' of github.itap.purdue.e…
wrigh393 Feb 23, 2021
c343963
Refactored queue loading
campb303 Feb 23, 2021
b0173b9
Merge branch 'Feature-Load-Item-Headers-Only' of github.itap.purdue.e…
campb303 Feb 23, 2021
5fcb7d7
Implement loading UI
campb303 Feb 23, 2021
ffeb3fe
Remove feature placeholder
campb303 Feb 23, 2021
25f0635
Replace prop with context
campb303 Feb 23, 2021
75de4ad
Remove debug logging
campb303 Feb 23, 2021
d4961b5
Remove hardcoded ID for uniqueness
campb303 Feb 23, 2021
0470bbe
Create timeline skeleton loader
campb303 Feb 23, 2021
abf98df
Add support for static files to react-styleguidist
campb303 Feb 23, 2021
f144667
Add loading state and refactor props
campb303 Mar 1, 2021
2a7b674
Fix validateDOM warning
campb303 Mar 2, 2021
e534ef6
Fix proptype specifications
campb303 Mar 2, 2021
6e7acf1
Fix validateDOM warning
campb303 Mar 2, 2021
d0e5649
Implement async item loading in ItemView
campb303 Mar 12, 2021
322a075
Update ItemView docs
campb303 Mar 12, 2021
6afaf23
Add error page to ItemView
campb303 Mar 12, 2021
ebbafcb
Remove unused icon
campb303 Mar 12, 2021
bfbb895
Merge pull request #113 from ECN/Feature-Load-Item-Headers-Only
campb303 Mar 12, 2021
8faa519
FIx hard coded item values
campb303 Mar 12, 2021
21858cd
Merge branch 'enhancement-itemtable-visual-improvements' into staging
campb303 Mar 13, 2021
9e9e48a
Reformat
campb303 Mar 13, 2021
17a2847
Merge remote-tracking branch 'origin/enhancement-consolidate-api-endp…
campb303 Mar 14, 2021
dfbc048
Correct API paths
campb303 Mar 14, 2021
5e8f703
Fix incorrect item count when getting queue counts
campb303 Mar 15, 2021
66b4234
Merge pull request #199 from ECN/bugfix-queue-selector-displays-wrong…
campb303 Mar 15, 2021
3d553f6
Set version
campb303 Mar 16, 2021
d30db88
Add htaccess and maintenance page
campb303 Mar 16, 2021
f033e3e
Replace pypi python-ldap with self hosted version
campb303 Mar 16, 2021
60e754e
Merge branch 'master' into staging
campb303 Mar 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ yarn-error.log*
/api/venv
__pycache__/
venv-manager.log
/api/.env
/api/.env
*.egg*
136 changes: 90 additions & 46 deletions api/ECNQueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
Attributes:
queueDirectory: The directory to load queues from.
queuesToIgnore: Queues that will not be loaded when running getQueues()
Raises:
# TODO: Add description(s) of when a ValueError is raised.
ValueError: [description]
"""

#------------------------------------------------------------------------------#
Expand Down Expand Up @@ -62,7 +58,10 @@
#------------------------------------------------------------------------------#

def isValidItemName(name: str) -> bool:
"""Returns true if file name is a valid item name
"""Returns true if file name is a valid item name.
A file name is true if it contains between 1 and 3 integer numbers allowing for
any integer between 0 and 999.
Example:
isValidItemName("21") -> true
Expand All @@ -83,16 +82,23 @@ def isValidItemName(name: str) -> bool:
# Classes
#------------------------------------------------------------------------------#
class Item:
"""A single issue.
"""A chronological representation of an interaction with a user.
Example:
# Create an Item (ce100)
>>> item = Item("ce", 100)
>>> item = Item("ce", 100, headersOnly=false)
# Create an Item without parsing its contents (ce100)
>>> item = Item("ce", 100, headersOnly=True)
Args:
queue (str): The name of the Item's queue.
number (int): The number of the Item.
headersOnly (bool, optional): Whether or not to parse headers only. Defaults to True.
Attributes:
lastUpdated: An ISO 8601 formatted time string showing the last time the file was updated according to the filesystem.
headers: A list of dictionaries containing header keys and values.
content: A list of section dictionaries.
content: A list of section dictionaries (only included if headersOnly is False).
isLocked: A boolean showing whether or not a lockfile for the item is present.
userEmail: The email address of the person who this item is from.
userName: The real name of the person who this item is from.
Expand All @@ -104,21 +110,22 @@ class Item:
department: The most recent department for this item.
dateReceived: The date this item was created.
jsonData: A JSON serializable representation of the Item.
Raises:
ValueError: When the number passed to the constructor cannot be parsed.
"""

def __init__(self, queue: str, number: int) -> None:
def __init__(self, queue: str, number: int, headersOnly: bool = False) -> None:
self.queue = queue
try:
self.number = int(number)
except ValueError:
raise ValueError(" Could not convert \"" +
number + "\" to an integer")

raise ValueError(f'Could not convert "{number}" to an integer')
self.__path = "/".join([queueDirectory, self.queue, str(self.number)])
self.lastUpdated = self.__getLastUpdated()
self.__rawItem = self.__getRawItem()
self.headers = self.__parseHeaders()
self.content = self.__parseSections()
if not headersOnly: self.content = self.__parseSections()
self.isLocked = self.__isLocked()
self.userEmail = self.__parseFromData(data="userEmail")
self.userName = self.__parseFromData(data="userName")
Expand All @@ -129,28 +136,12 @@ def __init__(self, queue: str, number: int) -> None:
self.priority = self.__getMostRecentHeaderByType("Priority")
self.department = self.__getMostRecentHeaderByType("Department")
self.building = self.__getMostRecentHeaderByType("Building")
self.dateReceived = self.__getFormattedDate(
self.__getMostRecentHeaderByType("Date"))
self.dateReceived = self.__getFormattedDate(self.__getMostRecentHeaderByType("Date"))
self.jsonData = {}

# TODO: Autopopulate jsonData w/ __dir__() command. Exclude `^_` and `jsonData`.
self.jsonData = {
"queue": self.queue,
"number": self.number,
"lastUpdated": self.lastUpdated,
"headers": self.headers,
"content": self.content,
"isLocked": self.isLocked,
"userEmail": self.userEmail,
"userName": self.userName,
"userAlias": self.userAlias,
"assignedTo": self.assignedTo,
"subject": self.subject,
"status": self.status,
"priority": self.priority,
"department": self.department,
"building": self.building,
"dateReceived": self.dateReceived
}
for attribute in self.__dir__():
if "_" not in attribute and attribute != "toJson" and attribute != "jsonData":
self.jsonData[attribute] = self.__getattribute__(attribute)

def __getLastUpdated(self) -> str:
"""Returns last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format.
Expand Down Expand Up @@ -212,7 +203,7 @@ def __parseHeaders(self) -> list:
# Example:
# [ce] QTime-Updated-By: campb303 becomes
# QTime-Updated-By: campb303
queuePrefixPattern = re.compile("\[.*\] {1}")
queuePrefixPattern = re.compile(r"\[.*?\] {1}")
for lineNumber in range(self.__getHeaderBoundary()):
line = self.__rawItem[lineNumber]
lineHasQueuePrefix = queuePrefixPattern.match(line)
Expand Down Expand Up @@ -263,6 +254,12 @@ def __parseSections(self) -> list:
for assignment in assignementLsit:
sections.append(assignment)

# Checks for empty content within an item and returns and
if contentEnd <= contentStart:
blankInitialMessage = self.__initialMessageParsing([""])
sections.append(blankInitialMessage)
return sections

# Checks for Directory Identifiers
if self.__rawItem[contentStart] == "\n" and self.__rawItem[contentStart + 1].startswith("\t"):

Expand Down Expand Up @@ -915,6 +912,10 @@ def __userReplyParsing(self, replyContent: list, lineNumber: int) -> dict:
if line == "\n":
newLineCounter = newLineCounter + 1

if newLineCounter == 2 and "datetime" not in replyFromInfo.keys():
errorMessage = "Expected \"Date: [datetime]\" in the header info"
return self.__errorParsing(line, lineNumber + lineNum + 1, errorMessage)

elif line == "===============================================\n":
endingDelimiterCount = endingDelimiterCount + 1

Expand Down Expand Up @@ -1190,7 +1191,19 @@ def __getUserAlias(self) -> str:
Returns:
str: User's Career Account alias if present or empty string
"""
emailUser, emailDomain = self.userEmail.split("@")


try:
emailUser, emailDomain = self.userEmail.split("@")

# Returns an error parse if the self.useremail doesn't contain exactally one "@" symbol
except ValueError:
# Parses through the self.headers list to find the "From" header and its line number
for lineNum, header in enumerate(self.headers):
if header["type"] == "From":
headerString = header["type"] + ": " + header["content"]
return self.__errorParsing(headerString, lineNum + 1, "Expected valid email Address")

return emailUser if emailDomain.endswith("purdue.edu") else ""

def __getFormattedDate(self, date: str) -> str:
Expand Down Expand Up @@ -1223,24 +1236,31 @@ def toJson(self) -> dict:
def __repr__(self) -> str:
return self.queue + str(self.number)

# TODO: Make Queue iterable using __iter__. See: https://thispointer.com/python-how-to-make-a-class-iterable-create-iterator-class-for-it/
class Queue:
"""A collection of items.
"""A collection of Items.
Example:
# Create a queue (ce)
>>> queue = Queue("ce")
# Create a queue without parsing item contents (ce)
>>> queue = Queue("ce", headersOnly=False)
Args:
queue (str): The name of the queue.
headersOnly (bool, optional): Whether or not to parse headers only. Defaults to True.
Attributes:
name: The name of the queue.
items: A list of Items in the queue.
jsonData: A JSON serializable representation of the Queue.
"""

def __init__(self, name: str) -> None:
def __init__(self, name: str, headersOnly: bool = True) -> None:
self.name = name
self.headersOnly = headersOnly
self.__directory = queueDirectory + "/" + self.name + "/"
self.items = self.__getItems()
self._index = 0

self.jsonData = {
"name": self.name,
Expand All @@ -1261,7 +1281,7 @@ def __getItems(self) -> list:
isFile = True if os.path.isfile(itemPath) else False

if isFile and isValidItemName(item):
items.append(Item(self.name, item))
items.append(Item(self.name, item, headersOnly=self.headersOnly))

return items

Expand All @@ -1287,6 +1307,13 @@ def __len__(self) -> int:
def __repr__(self) -> str:
return f'{self.name}_queue'

# Implements the interable interface requirements by passing direct references
# to the item list's interable values.
def __iter__(self) -> list:
return iter(self.items)
def __next__(self) -> int:
return iter(self.items).__next__()

def getValidQueues() -> list:
"""Returns a list of queues on the filesystem excluding ignored queues.
Expand Down Expand Up @@ -1329,20 +1356,37 @@ def getQueueCounts() -> list:
queueInfo = []
for queue in getValidQueues():
possibleItems = os.listdir(queueDirectory + "/" + queue)
validItems = [isValidItemName for file in possibleItems]
validItems = [file for file in possibleItems if isValidItemName(file)]
queueInfo.append( {"name": queue, "number_of_items": len(validItems)} )
return queueInfo


# Sorts list of queue info alphabetically
sortedQueueInfo = sorted(queueInfo, key = lambda queueInfoList: queueInfoList['name'])

def loadQueues() -> list:
return sortedQueueInfo

def loadAllQueues(headersOnly: bool = True) -> list:
"""Return a list of Queues for each queue.
Example:
# Load all Queues without parsing Item content
>>> loadAllQueues();
Load all Queues and parsing Item content
>>> loadAllQueues(headersOnly=False)
Args:
headersOnly (bool, optional): Whether or not to parse headers only. Defaults to True.
Returns:
list: list of Queues for each queue.
list: List of Queues for each queue.
"""
queues = []

for queue in getValidQueues():
queues.append(Queue(queue))
queues.append(Queue(queue, headersOnly=headersOnly))

return queues

if __name__ == "__main__":
abe = Queue("abe")
abeCount = getQueueCounts()
print()
Loading