From b7e738c5b930d9c56902941a20dcfeef613a6037 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 23 Apr 2018 17:02:21 +0100 Subject: [PATCH 01/42] Add files to gitignore used for development --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7bbc71c..3b30928 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,6 @@ ENV/ # mypy .mypy_cache/ +Results.tsv +Callouts.xls +OnCall Spreadsheet Notes.txt From 243206514edc305c02c0119bfc40c5618f9df42d Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 23 Apr 2018 17:02:57 +0100 Subject: [PATCH 02/42] Add basic structure to readme --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab5443c..13574a8 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# oncall \ No newline at end of file +# Automating OnCall Spreadsheet +A Python script to aid filling in the OnCall spreadsheet in preparation for the OnCall meeting in RIG using data from a TSV file downloaded from RT using a specific search. + +# Required Packages +Package | Version +------- | ------- +xlrd | 1.1.0 +xlutils | 2.0.0 + From 0d87a5234b09c54ba7bcd17a563399bcc9bd21d4 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 24 Apr 2018 16:37:15 +0100 Subject: [PATCH 03/42] Add more files to gitignore Files introduced by IDE --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3b30928..9ccff5d 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,5 @@ ENV/ Results.tsv Callouts.xls OnCall Spreadsheet Notes.txt +*.xml +*.iml From d43ff7b2b0ac985a237f5c15225983d71a3652b5 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 26 Apr 2018 14:20:49 +0100 Subject: [PATCH 04/42] Add section 'Using Script' --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13574a8..e6d9530 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,19 @@ # Automating OnCall Spreadsheet -A Python script to aid filling in the OnCall spreadsheet in preparation for the OnCall meeting in RIG using data from a TSV file downloaded from RT using a specific search. +A Python script to aid filling in the OnCall spreadsheet in preparation for the OnCall meeting in RIG using data from a TSV file downloaded from RT using a specific search (see 'Using Script'). -# Required Packages +## Required Packages Package | Version ------- | ------- xlrd | 1.1.0 xlutils | 2.0.0 +## Using Script +- Create a custom ticket search in RT + - Normal OnCall queue (new or open tickets) + - Ignore 'NoCall' tickets + - Ignore 'Tier1_service_Test_Nagios_and_paging_on_host_nagger' tickets (test pager tickets) + - Ignore 'Downtime Expiry Report' tickets +- Download spreadsheet (.TSV file) from search results +- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script then Python script +- Perform usual OnCall meeting protocol regarding the tickets - resolve those that have been cleared up + From c6f098230c1b7401581cd1a8dc1b0d6c721bf118 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 26 Apr 2018 14:28:18 +0100 Subject: [PATCH 05/42] Add AppendSpreadsheet.py First commit of this file: - Works out which row to append from - Few inital lines to extract data from TSV file --- AppendSpreadsheet.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 AppendSpreadsheet.py diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py new file mode 100644 index 0000000..61b1efd --- /dev/null +++ b/AppendSpreadsheet.py @@ -0,0 +1,48 @@ +import csv +from xlrd import open_workbook +from xlutils.copy import copy + +with open("Results.tsv") as tsv, open("Callouts.xls"): + print('Both files found') + + # Skips first row with column headers + iterResults = iter(csv.reader(tsv, dialect="excel-tab")) + next(iterResults) + + wb = open_workbook("Callouts.xls", formatting_info=True) + # Make a writeable copy - not needed at this point + calloutsBook = copy(wb) + currentSheet = calloutsBook.get_sheet('Callouts 2018') + + # Find which row to start appending + firstRow = currentSheet.row(0) + readSheet = wb.sheet_by_name('Callouts 2018') + alarmColumn = readSheet.col_values(0) + + print('Working out where to start appending spreadsheet') + startAppending = False + i = 1 # Start at 1 as first result will always be 'Alarm name' + while not startAppending: + if readSheet.col(0)[i].value == '': + startAppending = True + startingRowNumber = i + 1 + i = i + 1 + + print('Will append spreadsheet from row #' + startingRowNumber - 1) + + for row in iterResults: + # Getting data from the TSV file + ticketID = row[0] + ticketCreated = row[15] + if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 + alarm = row[2] + else: + alarm = row[20] + + calloutsBook.save("Callouts.xls") + print(currentSheet.name) + + + + + From be5ab9468b4cca7c3a77cb2559360d4a3cd3d579 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 26 Apr 2018 14:46:15 +0100 Subject: [PATCH 06/42] Cleanup existing code Cleanup of code from previous commit: - Sections of code moved around to suit where they're needed (not used until a certain point) - General code improvement, little things --- AppendSpreadsheet.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 61b1efd..e06afec 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -5,16 +5,12 @@ with open("Results.tsv") as tsv, open("Callouts.xls"): print('Both files found') - # Skips first row with column headers - iterResults = iter(csv.reader(tsv, dialect="excel-tab")) - next(iterResults) - wb = open_workbook("Callouts.xls", formatting_info=True) - # Make a writeable copy - not needed at this point + # Make a writeable copy calloutsBook = copy(wb) currentSheet = calloutsBook.get_sheet('Callouts 2018') - # Find which row to start appending + # Find which row to start appending spreadsheet firstRow = currentSheet.row(0) readSheet = wb.sheet_by_name('Callouts 2018') alarmColumn = readSheet.col_values(0) @@ -26,21 +22,28 @@ if readSheet.col(0)[i].value == '': startAppending = True startingRowNumber = i + 1 - i = i + 1 + i += 1 - print('Will append spreadsheet from row #' + startingRowNumber - 1) + print('Will append spreadsheet from row #' + str(startingRowNumber - 1)) + # Skips first row of TSV file due to column headers + iterResults = iter(csv.reader(tsv, dialect="excel-tab")) + next(iterResults) + + # Extracting data from TSV file for row in iterResults: # Getting data from the TSV file ticketID = row[0] ticketCreated = row[15] - if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 + if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 callout alarm = row[2] else: alarm = row[20] + # Putting data into spreadsheet + calloutsBook.save("Callouts.xls") - print(currentSheet.name) + print('Spreadsheet changes saved') From 906b472fc6e4243fe8971211f2795671ad5f5a74 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Thu, 26 Apr 2018 17:02:25 +0100 Subject: [PATCH 07/42] Add functionality to put data into spreadsheet - Basic functionality now works, data is taken from TSV file and appended to the spreadsheet - Needs lots of cleanup regarding formatting, loss of excel formulas etc. --- AppendSpreadsheet.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index e06afec..61e00f2 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -21,7 +21,8 @@ while not startAppending: if readSheet.col(0)[i].value == '': startAppending = True - startingRowNumber = i + 1 + startingRowNumber = i + print(startingRowNumber) i += 1 print('Will append spreadsheet from row #' + str(startingRowNumber - 1)) @@ -31,8 +32,8 @@ next(iterResults) # Extracting data from TSV file + i = 0 for row in iterResults: - # Getting data from the TSV file ticketID = row[0] ticketCreated = row[15] if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 callout @@ -40,12 +41,13 @@ else: alarm = row[20] - # Putting data into spreadsheet + # Putting data into spreadsheet + currentRow = startingRowNumber + i + currentSheet.write(currentRow, 0, alarm) # Alarm name + currentSheet.write(currentRow, 2, ticketCreated) # Date issued + currentSheet.write(currentRow, 3, ticketCreated) # Time issued + currentSheet.write(currentRow, 4, ticketID) # RT query + i += 1 calloutsBook.save("Callouts.xls") - print('Spreadsheet changes saved') - - - - - + print('Spreadsheet changes saved') \ No newline at end of file From 2e8e34a8c5d3114c630490a92dae7bc5d51d03dc Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 27 Apr 2018 12:51:55 +0100 Subject: [PATCH 08/42] Remove Callouts.xls being opened No reason for this to occur, xlrd takes this role --- AppendSpreadsheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 61e00f2..0ae9087 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -2,7 +2,7 @@ from xlrd import open_workbook from xlutils.copy import copy -with open("Results.tsv") as tsv, open("Callouts.xls"): +with open("Results.tsv") as tsv: print('Both files found') wb = open_workbook("Callouts.xls", formatting_info=True) From c4cbc07492e196db61d4f83f108d1713f007b021 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 27 Apr 2018 13:33:23 +0100 Subject: [PATCH 09/42] Convert script to use openpyxl - Script now using openpyxl module instead of xlrd because xlrd erased formulas upon saving spreadsheet - This now means OnCall spreadsheet must be .xlsx file to work with the script - State of script in this commit: working, formulas don't erase - Working hours conditional formatting doesn't work as the ticket creation time hasn't been split (one variable containing date, another containing the time) --- AppendSpreadsheet.py | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 0ae9087..31d2a0e 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,31 +1,25 @@ import csv -from xlrd import open_workbook -from xlutils.copy import copy +from openpyxl import load_workbook with open("Results.tsv") as tsv: print('Both files found') - wb = open_workbook("Callouts.xls", formatting_info=True) - # Make a writeable copy - calloutsBook = copy(wb) - currentSheet = calloutsBook.get_sheet('Callouts 2018') + wb = load_workbook("Callouts.xlsx") + currentSheet = wb['Callouts 2018'] # Find which row to start appending spreadsheet - firstRow = currentSheet.row(0) - readSheet = wb.sheet_by_name('Callouts 2018') - alarmColumn = readSheet.col_values(0) + alarmColumn = currentSheet['A'] print('Working out where to start appending spreadsheet') startAppending = False - i = 1 # Start at 1 as first result will always be 'Alarm name' + i = 2 # Start at 2 as first result will always be 'column header' while not startAppending: - if readSheet.col(0)[i].value == '': + if alarmColumn[i].value is None: startAppending = True - startingRowNumber = i - print(startingRowNumber) + startingRowNumber = i + 1 i += 1 - print('Will append spreadsheet from row #' + str(startingRowNumber - 1)) + print('Will append spreadsheet from row #' + str(startingRowNumber)) # Skips first row of TSV file due to column headers iterResults = iter(csv.reader(tsv, dialect="excel-tab")) @@ -43,11 +37,11 @@ # Putting data into spreadsheet currentRow = startingRowNumber + i - currentSheet.write(currentRow, 0, alarm) # Alarm name - currentSheet.write(currentRow, 2, ticketCreated) # Date issued - currentSheet.write(currentRow, 3, ticketCreated) # Time issued - currentSheet.write(currentRow, 4, ticketID) # RT query + currentSheet.cell(row=currentRow, column=1).value = alarm # Alarm name + currentSheet.cell(row=currentRow, column=3).value = ticketCreated # Date issued + currentSheet.cell(row=currentRow, column=4).value = ticketCreated # Time issued + currentSheet.cell(row=currentRow, column=5).value = ticketID # RT query i += 1 - calloutsBook.save("Callouts.xls") + wb.save("Callouts.xlsx") print('Spreadsheet changes saved') \ No newline at end of file From 73adc1f3b0d4e6efeaf4f214fff351361517c229 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 27 Apr 2018 13:34:03 +0100 Subject: [PATCH 10/42] Add .xlsx files to gitignore - Script now manipulates .xlsx files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9ccff5d..aa7d3a0 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,4 @@ Callouts.xls OnCall Spreadsheet Notes.txt *.xml *.iml +*.xlsx From bbfee5326c1ba4428a7e27809cbde6318c2d5858 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 27 Apr 2018 15:41:04 +0100 Subject: [PATCH 11/42] Separate time and date ticket got created - Separates them for the two cells in the spreadsheet - The 'outside work hours?' formatting still not working - if time created is doubled clicked in Excel then it works but that's manual --- AppendSpreadsheet.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 31d2a0e..6448ea4 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,5 +1,6 @@ import csv from openpyxl import load_workbook +from datetime import datetime with open("Results.tsv") as tsv: print('Both files found') @@ -29,7 +30,11 @@ i = 0 for row in iterResults: ticketID = row[0] - ticketCreated = row[15] + + ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') + dateCreated = ticketCreated.strftime('%d/%m/%Y') + timeCreated = ticketCreated.strftime('%H:%M:%S') + if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 callout alarm = row[2] else: @@ -37,10 +42,10 @@ # Putting data into spreadsheet currentRow = startingRowNumber + i - currentSheet.cell(row=currentRow, column=1).value = alarm # Alarm name - currentSheet.cell(row=currentRow, column=3).value = ticketCreated # Date issued - currentSheet.cell(row=currentRow, column=4).value = ticketCreated # Time issued - currentSheet.cell(row=currentRow, column=5).value = ticketID # RT query + currentSheet.cell(row=currentRow, column=1, value=alarm) # Alarm name + currentSheet.cell(row=currentRow, column=3, value=dateCreated) # Date issued + currentSheet.cell(row=currentRow, column=4, value=timeCreated) # Time issued + currentSheet.cell(row=currentRow, column=5, value=ticketID) # RT query i += 1 wb.save("Callouts.xlsx") From 3eb7aca1c88c207167d20e3d35d14ab599ce6d37 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 27 Apr 2018 15:53:14 +0100 Subject: [PATCH 12/42] Change ticket ID to int and centre cell - Once running script, the added 'RT query' cells had an error saying they should be numbers but are text - fixed in this commit - The same cells were being aligned to the right once I made the above change so are now aligned to centre as per previous spreadsheet use --- AppendSpreadsheet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 6448ea4..d5560a1 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,5 +1,6 @@ import csv from openpyxl import load_workbook +from openpyxl.styles import Alignment from datetime import datetime with open("Results.tsv") as tsv: @@ -29,7 +30,7 @@ # Extracting data from TSV file i = 0 for row in iterResults: - ticketID = row[0] + ticketID = int(row[0]) ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') dateCreated = ticketCreated.strftime('%d/%m/%Y') @@ -45,7 +46,7 @@ currentSheet.cell(row=currentRow, column=1, value=alarm) # Alarm name currentSheet.cell(row=currentRow, column=3, value=dateCreated) # Date issued currentSheet.cell(row=currentRow, column=4, value=timeCreated) # Time issued - currentSheet.cell(row=currentRow, column=5, value=ticketID) # RT query + currentSheet.cell(row=currentRow, column=5, value=ticketID).alignment = Alignment(horizontal='center') # RT query i += 1 wb.save("Callouts.xlsx") From 8791dc2f863a327245a863e038a239a05c4d0389 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 30 Apr 2018 09:38:11 +0100 Subject: [PATCH 13/42] Add hyperlinks to ticket IDs - Hyperlink is added to each ticket ID to point at ticket on RT --- AppendSpreadsheet.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index d5560a1..ea87ed8 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,6 +1,6 @@ import csv from openpyxl import load_workbook -from openpyxl.styles import Alignment +from openpyxl.styles import Alignment, Font from datetime import datetime with open("Results.tsv") as tsv: @@ -46,7 +46,10 @@ currentSheet.cell(row=currentRow, column=1, value=alarm) # Alarm name currentSheet.cell(row=currentRow, column=3, value=dateCreated) # Date issued currentSheet.cell(row=currentRow, column=4, value=timeCreated) # Time issued - currentSheet.cell(row=currentRow, column=5, value=ticketID).alignment = Alignment(horizontal='center') # RT query + # RT query + currentSheet.cell(row=currentRow, column=5, value=ticketID).alignment = Alignment(horizontal='center') + currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ + '.html?id=' + str(ticketID) i += 1 wb.save("Callouts.xlsx") From b7e6fabfa7bf800a847750ac7a006b93793bffac Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 30 Apr 2018 10:25:01 +0100 Subject: [PATCH 14/42] Merge cells and input meeting date --- AppendSpreadsheet.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index ea87ed8..d64b536 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -52,5 +52,10 @@ '.html?id=' + str(ticketID) i += 1 + # Merge cells + currentDate = datetime.now().strftime('%d-%b') + currentSheet.cell(row=startingRowNumber, column=12, value=currentDate).alignment = Alignment(horizontal='center', vertical='center') + currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) + wb.save("Callouts.xlsx") print('Spreadsheet changes saved') \ No newline at end of file From 8f0b3b697dd236a677f8e854b739b13a6a4f92bf Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 30 Apr 2018 16:51:54 +0100 Subject: [PATCH 15/42] Add border creation to spreadsheet - Thin border for all cells created - Thick outer border for the cells added also created --- AppendSpreadsheet.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index d64b536..aaa2562 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,6 +1,6 @@ import csv from openpyxl import load_workbook -from openpyxl.styles import Alignment, Font +from openpyxl.styles import Alignment, Side, Border from datetime import datetime with open("Results.tsv") as tsv: @@ -57,5 +57,46 @@ currentSheet.cell(row=startingRowNumber, column=12, value=currentDate).alignment = Alignment(horizontal='center', vertical='center') currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) + # Apply inner and outer borders (inner then outer) + rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) + + # Setting inner borders + innerBorderStyle = Side(border_style='thin', color='FF000000') + innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, bottom=innerBorderStyle) + for row in rows: + for cell in row: + cell.border = innerBorderFormat + + # Setting outer border + # Code found at: https://stackoverflow.com/questions/34520764/apply-border-to-range-of-cells-using-openpyxl + # Written by Yaroslav Admin, edited by Adam Stewart + + outerRows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) + outerBorderStyle = Side(border_style='medium', color='FF000000') + outerRows = list(outerRows) + max_y = len(outerRows) - 1 + for pos_y, cells in enumerate(outerRows): + max_x = len(cells) - 1 # index of the last cell + for pos_x, cell in enumerate(cells): + border = Border( + left=cell.border.left, + right=cell.border.right, + top=cell.border.top, + bottom=cell.border.bottom + ) + # Checking if an edge cell + if pos_x == 0: + border.left = outerBorderStyle + if pos_x == max_x: + border.right = outerBorderStyle + if pos_y == 0: + border.top = outerBorderStyle + if pos_y == max_y: + border.bottom = outerBorderStyle + + # Set new border only if it's one of the edge cells + if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y: + cell.border = border + wb.save("Callouts.xlsx") print('Spreadsheet changes saved') \ No newline at end of file From 619ac994f7c4bca9b3dda177ecb451c3a8922b6e Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 30 Apr 2018 16:57:01 +0100 Subject: [PATCH 16/42] Cleanup border changes - Layout of code slightly changed --- AppendSpreadsheet.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index aaa2562..c57c991 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -57,10 +57,8 @@ currentSheet.cell(row=startingRowNumber, column=12, value=currentDate).alignment = Alignment(horizontal='center', vertical='center') currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) - # Apply inner and outer borders (inner then outer) - rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) - # Setting inner borders + rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) innerBorderStyle = Side(border_style='thin', color='FF000000') innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, bottom=innerBorderStyle) for row in rows: @@ -70,7 +68,6 @@ # Setting outer border # Code found at: https://stackoverflow.com/questions/34520764/apply-border-to-range-of-cells-using-openpyxl # Written by Yaroslav Admin, edited by Adam Stewart - outerRows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) outerBorderStyle = Side(border_style='medium', color='FF000000') outerRows = list(outerRows) @@ -82,8 +79,8 @@ left=cell.border.left, right=cell.border.right, top=cell.border.top, - bottom=cell.border.bottom - ) + bottom=cell.border.bottom) + # Checking if an edge cell if pos_x == 0: border.left = outerBorderStyle From 51feba20937e8f7a55db3e2359457b26646cfaa5 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 10:07:38 +0100 Subject: [PATCH 17/42] Update method of grabbing alarm name - This will mean the spreadsheet won't need to be corrected due to merged tickets and subjects updated (e.g. ceph-mon1-5 tickets) --- AppendSpreadsheet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index c57c991..d2cc5f6 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -29,6 +29,7 @@ # Extracting data from TSV file i = 0 + nagiosFiller = "Nagios issued and cleared service alarm" for row in iterResults: ticketID = int(row[0]) @@ -36,10 +37,9 @@ dateCreated = ticketCreated.strftime('%d/%m/%Y') timeCreated = ticketCreated.strftime('%H:%M:%S') - if row[20] == '': # If no Nagios alarm, use ticket's subject - problem when ceph-mon1-5 callout - alarm = row[2] - else: - alarm = row[20] + alarm = row[2] + if nagiosFiller in alarm: + alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm # Putting data into spreadsheet currentRow = startingRowNumber + i From 6b505f614fc8ffd5d5ad7879df22fa80d12d981c Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 10:14:07 +0100 Subject: [PATCH 18/42] Remove unneeded print statement - Due to the change to the 'with' statement above, you can no longer say both files can be found at this stage in the code --- AppendSpreadsheet.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index d2cc5f6..bf213bd 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -4,8 +4,6 @@ from datetime import datetime with open("Results.tsv") as tsv: - print('Both files found') - wb = load_workbook("Callouts.xlsx") currentSheet = wb['Callouts 2018'] From 0a98ab12b4c2f5424d02f3cd9822f63173e1b2b6 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 10:45:02 +0100 Subject: [PATCH 19/42] Add service cell editing - Will add to 'Service' column when you can tell what service the alarm refers to - Currently implemented for: CEPH, CE and DISK Server services - Uses alarm to search for keywords --- AppendSpreadsheet.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index bf213bd..9992af9 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -29,6 +29,7 @@ i = 0 nagiosFiller = "Nagios issued and cleared service alarm" for row in iterResults: + service = None ticketID = int(row[0]) ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') @@ -39,11 +40,20 @@ if nagiosFiller in alarm: alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm + if 'ceph' in alarm.lower(): + service = 'CEPH' + elif 'arc-ce' in alarm.lower(): + service = 'CE' + elif 'gdss' in alarm.lower(): + service = 'DISK Server' + # Putting data into spreadsheet currentRow = startingRowNumber + i - currentSheet.cell(row=currentRow, column=1, value=alarm) # Alarm name - currentSheet.cell(row=currentRow, column=3, value=dateCreated) # Date issued - currentSheet.cell(row=currentRow, column=4, value=timeCreated) # Time issued + currentSheet.cell(row=currentRow, column=1, value=alarm) + currentSheet.cell(row=currentRow, column=3, value=dateCreated) + currentSheet.cell(row=currentRow, column=4, value=timeCreated) + if service is not None: + currentSheet.cell(row=currentRow, column=6, value=service) # RT query currentSheet.cell(row=currentRow, column=5, value=ticketID).alignment = Alignment(horizontal='center') currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ From d5a22fa25ae4ea9ee97c832eb53f4ede58cf7f23 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 11:12:28 +0100 Subject: [PATCH 20/42] Align all cells on rows relevant to this week's callouts --- AppendSpreadsheet.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 9992af9..bcb2e54 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -55,22 +55,27 @@ if service is not None: currentSheet.cell(row=currentRow, column=6, value=service) # RT query - currentSheet.cell(row=currentRow, column=5, value=ticketID).alignment = Alignment(horizontal='center') + currentSheet.cell(row=currentRow, column=5, value=ticketID) currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ '.html?id=' + str(ticketID) i += 1 # Merge cells currentDate = datetime.now().strftime('%d-%b') - currentSheet.cell(row=startingRowNumber, column=12, value=currentDate).alignment = Alignment(horizontal='center', vertical='center') + currentSheet.cell(row=startingRowNumber, column=12, value=currentDate) currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) - # Setting inner borders + # Setting inner borders and cell alignment rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) innerBorderStyle = Side(border_style='thin', color='FF000000') innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, bottom=innerBorderStyle) for row in rows: for cell in row: + if cell.column == 'A' or cell.column == 'K': + cell.alignment = Alignment(vertical='center') + else: + cell.alignment = Alignment(horizontal='center', vertical='center') + cell.border = innerBorderFormat # Setting outer border From 1cfc2f2ed4b74303a734686ea8c622fed5160828 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 11:19:25 +0100 Subject: [PATCH 21/42] Wrap text on cells - Text will be wrapped on all cells for rows being written to during execution of the script --- AppendSpreadsheet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index bcb2e54..9f87171 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -72,9 +72,9 @@ for row in rows: for cell in row: if cell.column == 'A' or cell.column == 'K': - cell.alignment = Alignment(vertical='center') + cell.alignment = Alignment(vertical='center', wrap_text=True) else: - cell.alignment = Alignment(horizontal='center', vertical='center') + cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) cell.border = innerBorderFormat From 5039dd241700cc1634008e3d70173b17ebc357d1 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 12:09:33 +0100 Subject: [PATCH 22/42] Add data about host - Name of host added under the host column (to the relevant row) if it can be identified from the alarm name --- AppendSpreadsheet.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 9f87171..a50a730 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -28,8 +28,11 @@ # Extracting data from TSV file i = 0 nagiosFiller = "Nagios issued and cleared service alarm" + hostFiller = "on_host_" for row in iterResults: + hostStart = None service = None + hostCheck = True ticketID = int(row[0]) ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') @@ -40,6 +43,7 @@ if nagiosFiller in alarm: alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm + # Service if 'ceph' in alarm.lower(): service = 'CEPH' elif 'arc-ce' in alarm.lower(): @@ -47,9 +51,21 @@ elif 'gdss' in alarm.lower(): service = 'DISK Server' + # Get hostname + if hostFiller in alarm: + j = len(alarm) - 1 + while hostCheck: + if alarm[j] == '_': + hostStart = j + hostCheck = False + j -= 1 + hostname = alarm[hostStart + 1:] + # Putting data into spreadsheet currentRow = startingRowNumber + i currentSheet.cell(row=currentRow, column=1, value=alarm) + if hostStart is not None: + currentSheet.cell(row=currentRow, column=2, value=hostname) currentSheet.cell(row=currentRow, column=3, value=dateCreated) currentSheet.cell(row=currentRow, column=4, value=timeCreated) if service is not None: From 7722f350ffbad303e6dc9834dcf3065ccb9580ab Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 14:00:40 +0100 Subject: [PATCH 23/42] Add functionality to add data dependent on working hours --- AppendSpreadsheet.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index a50a730..bc7ece8 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -9,8 +9,8 @@ # Find which row to start appending spreadsheet alarmColumn = currentSheet['A'] - print('Working out where to start appending spreadsheet') + startAppending = False i = 2 # Start at 2 as first result will always be 'column header' while not startAppending: @@ -33,12 +33,18 @@ hostStart = None service = None hostCheck = True + workingHours = False ticketID = int(row[0]) ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') dateCreated = ticketCreated.strftime('%d/%m/%Y') timeCreated = ticketCreated.strftime('%H:%M:%S') + # In working hours or not + weekday = ticketCreated.isoweekday() + if '08:30:00' < timeCreated < '17:00:00' and weekday < 6: + workingHours = True + alarm = row[2] if nagiosFiller in alarm: alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm @@ -74,6 +80,9 @@ currentSheet.cell(row=currentRow, column=5, value=ticketID) currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ '.html?id=' + str(ticketID) + if workingHours: + currentSheet.cell(row=currentRow, column=8, value='N/A') + currentSheet.cell(row=currentRow, column=10, value='Work hours') i += 1 # Merge cells From 8e807de6032137ec20723210b26c9d47d711c811 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 14:41:45 +0100 Subject: [PATCH 24/42] General code cleanup - Better comments - Constants added for filenames and sheet name for things that will definitely end up changing over time --- AppendSpreadsheet.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index bc7ece8..1b40bd5 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -3,13 +3,17 @@ from openpyxl.styles import Alignment, Side, Border from datetime import datetime -with open("Results.tsv") as tsv: - wb = load_workbook("Callouts.xlsx") - currentSheet = wb['Callouts 2018'] +NEW_TICKETS_FILE_NAME = "Results.tsv" +SPREADSHEET_NAME = "Callouts.xlsx" +SHEET_NAME = "Callouts 2018" + +with open(NEW_TICKETS_FILE_NAME) as tsv: + wb = load_workbook(SPREADSHEET_NAME) + currentSheet = wb[SHEET_NAME] # Find which row to start appending spreadsheet alarmColumn = currentSheet['A'] - print('Working out where to start appending spreadsheet') + print('Calculating where to append spreadsheet') startAppending = False i = 2 # Start at 2 as first result will always be 'column header' @@ -40,11 +44,12 @@ dateCreated = ticketCreated.strftime('%d/%m/%Y') timeCreated = ticketCreated.strftime('%H:%M:%S') - # In working hours or not + # Is callout in work hours? weekday = ticketCreated.isoweekday() if '08:30:00' < timeCreated < '17:00:00' and weekday < 6: workingHours = True + # Get Nagios alarm (or subject if not from Nagios) alarm = row[2] if nagiosFiller in alarm: alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm @@ -57,7 +62,7 @@ elif 'gdss' in alarm.lower(): service = 'DISK Server' - # Get hostname + # Get hostname from Nagios alarm if hostFiller in alarm: j = len(alarm) - 1 while hostCheck: @@ -97,6 +102,7 @@ for row in rows: for cell in row: if cell.column == 'A' or cell.column == 'K': + # These columns need to be horizontally left aligned (alarm and comment columns) cell.alignment = Alignment(vertical='center', wrap_text=True) else: cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) @@ -133,5 +139,5 @@ if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y: cell.border = border - wb.save("Callouts.xlsx") + wb.save(SPREADSHEET_NAME) print('Spreadsheet changes saved') \ No newline at end of file From 43a27fd9f1f5a9609b34edd6b3a6040ed6757956 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 15:21:59 +0100 Subject: [PATCH 25/42] Add error handling - Try and except blocks setup for missing Callouts.xlsx and missing sheet in that file - Few bits of code cleanup to improve readability --- AppendSpreadsheet.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 1b40bd5..c7aaa29 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -1,4 +1,4 @@ -import csv +import csv, sys, time, os from openpyxl import load_workbook from openpyxl.styles import Alignment, Side, Border from datetime import datetime @@ -8,8 +8,23 @@ SHEET_NAME = "Callouts 2018" with open(NEW_TICKETS_FILE_NAME) as tsv: - wb = load_workbook(SPREADSHEET_NAME) - currentSheet = wb[SHEET_NAME] + try: + wb = load_workbook(SPREADSHEET_NAME) + except FileNotFoundError: + print(SPREADSHEET_NAME, 'doesn\'t exist (weekly spreadsheet), please add this file to the directory ' + 'of this script') + print('Directory of script:', os.path.dirname(os.path.realpath(__file__))) + time.sleep(4) + sys.exit() + + try: + currentSheet = wb[SHEET_NAME] + except KeyError: + print('Sheet named \'' + SHEET_NAME + '\' doesn\'t exist') + print('Either create a sheet with this name in', SPREADSHEET_NAME, 'or edit script code so it finds a sheet ' + 'that does exist') + time.sleep(4) + sys.exit() # Find which row to start appending spreadsheet alarmColumn = currentSheet['A'] @@ -98,7 +113,8 @@ # Setting inner borders and cell alignment rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) innerBorderStyle = Side(border_style='thin', color='FF000000') - innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, bottom=innerBorderStyle) + innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, + bottom=innerBorderStyle) for row in rows: for cell in row: if cell.column == 'A' or cell.column == 'K': From a37ee45fe60d313933ca5d7ee030db64c619eed5 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 15:46:57 +0100 Subject: [PATCH 26/42] Add error handling for missing Results.tsv - Added try except block on with open statement --- AppendSpreadsheet.py | 306 ++++++++++++++++++++++--------------------- 1 file changed, 156 insertions(+), 150 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index c7aaa29..9f7ffd7 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -7,153 +7,159 @@ SPREADSHEET_NAME = "Callouts.xlsx" SHEET_NAME = "Callouts 2018" -with open(NEW_TICKETS_FILE_NAME) as tsv: - try: - wb = load_workbook(SPREADSHEET_NAME) - except FileNotFoundError: - print(SPREADSHEET_NAME, 'doesn\'t exist (weekly spreadsheet), please add this file to the directory ' - 'of this script') - print('Directory of script:', os.path.dirname(os.path.realpath(__file__))) - time.sleep(4) - sys.exit() - - try: - currentSheet = wb[SHEET_NAME] - except KeyError: - print('Sheet named \'' + SHEET_NAME + '\' doesn\'t exist') - print('Either create a sheet with this name in', SPREADSHEET_NAME, 'or edit script code so it finds a sheet ' - 'that does exist') - time.sleep(4) - sys.exit() - - # Find which row to start appending spreadsheet - alarmColumn = currentSheet['A'] - print('Calculating where to append spreadsheet') - - startAppending = False - i = 2 # Start at 2 as first result will always be 'column header' - while not startAppending: - if alarmColumn[i].value is None: - startAppending = True - startingRowNumber = i + 1 - i += 1 - - print('Will append spreadsheet from row #' + str(startingRowNumber)) - - # Skips first row of TSV file due to column headers - iterResults = iter(csv.reader(tsv, dialect="excel-tab")) - next(iterResults) - - # Extracting data from TSV file - i = 0 - nagiosFiller = "Nagios issued and cleared service alarm" - hostFiller = "on_host_" - for row in iterResults: - hostStart = None - service = None - hostCheck = True - workingHours = False - ticketID = int(row[0]) - - ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') - dateCreated = ticketCreated.strftime('%d/%m/%Y') - timeCreated = ticketCreated.strftime('%H:%M:%S') - - # Is callout in work hours? - weekday = ticketCreated.isoweekday() - if '08:30:00' < timeCreated < '17:00:00' and weekday < 6: - workingHours = True - - # Get Nagios alarm (or subject if not from Nagios) - alarm = row[2] - if nagiosFiller in alarm: - alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm - - # Service - if 'ceph' in alarm.lower(): - service = 'CEPH' - elif 'arc-ce' in alarm.lower(): - service = 'CE' - elif 'gdss' in alarm.lower(): - service = 'DISK Server' - - # Get hostname from Nagios alarm - if hostFiller in alarm: - j = len(alarm) - 1 - while hostCheck: - if alarm[j] == '_': - hostStart = j - hostCheck = False - j -= 1 - hostname = alarm[hostStart + 1:] - - # Putting data into spreadsheet - currentRow = startingRowNumber + i - currentSheet.cell(row=currentRow, column=1, value=alarm) - if hostStart is not None: - currentSheet.cell(row=currentRow, column=2, value=hostname) - currentSheet.cell(row=currentRow, column=3, value=dateCreated) - currentSheet.cell(row=currentRow, column=4, value=timeCreated) - if service is not None: - currentSheet.cell(row=currentRow, column=6, value=service) - # RT query - currentSheet.cell(row=currentRow, column=5, value=ticketID) - currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ - '.html?id=' + str(ticketID) - if workingHours: - currentSheet.cell(row=currentRow, column=8, value='N/A') - currentSheet.cell(row=currentRow, column=10, value='Work hours') - i += 1 - - # Merge cells - currentDate = datetime.now().strftime('%d-%b') - currentSheet.cell(row=startingRowNumber, column=12, value=currentDate) - currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) - - # Setting inner borders and cell alignment - rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) - innerBorderStyle = Side(border_style='thin', color='FF000000') - innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, - bottom=innerBorderStyle) - for row in rows: - for cell in row: - if cell.column == 'A' or cell.column == 'K': - # These columns need to be horizontally left aligned (alarm and comment columns) - cell.alignment = Alignment(vertical='center', wrap_text=True) - else: - cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) - - cell.border = innerBorderFormat - - # Setting outer border - # Code found at: https://stackoverflow.com/questions/34520764/apply-border-to-range-of-cells-using-openpyxl - # Written by Yaroslav Admin, edited by Adam Stewart - outerRows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) - outerBorderStyle = Side(border_style='medium', color='FF000000') - outerRows = list(outerRows) - max_y = len(outerRows) - 1 - for pos_y, cells in enumerate(outerRows): - max_x = len(cells) - 1 # index of the last cell - for pos_x, cell in enumerate(cells): - border = Border( - left=cell.border.left, - right=cell.border.right, - top=cell.border.top, - bottom=cell.border.bottom) - - # Checking if an edge cell - if pos_x == 0: - border.left = outerBorderStyle - if pos_x == max_x: - border.right = outerBorderStyle - if pos_y == 0: - border.top = outerBorderStyle - if pos_y == max_y: - border.bottom = outerBorderStyle - - # Set new border only if it's one of the edge cells - if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y: - cell.border = border - - wb.save(SPREADSHEET_NAME) - print('Spreadsheet changes saved') \ No newline at end of file +try: + with open(NEW_TICKETS_FILE_NAME) as tsv: + try: + wb = load_workbook(SPREADSHEET_NAME) + except FileNotFoundError: + print(SPREADSHEET_NAME, 'doesn\'t exist (weekly spreadsheet), please add this file to the directory ' + 'of this script') + print('Directory of script:', os.path.dirname(os.path.realpath(__file__))) + time.sleep(4) + sys.exit() + + try: + currentSheet = wb[SHEET_NAME] + except KeyError: + print('Sheet named \'' + SHEET_NAME + '\' doesn\'t exist') + print('Either create a sheet with this name in', SPREADSHEET_NAME, 'or edit script code so it finds a sheet ' + 'that does exist') + time.sleep(4) + sys.exit() + + # Find which row to start appending spreadsheet + alarmColumn = currentSheet['A'] + print('Calculating where to append spreadsheet') + + startAppending = False + i = 2 # Start at 2 as first result will always be 'column header' + while not startAppending: + if alarmColumn[i].value is None: + startAppending = True + startingRowNumber = i + 1 + i += 1 + + print('Will append spreadsheet from row #' + str(startingRowNumber)) + + # Skips first row of TSV file due to column headers + iterResults = iter(csv.reader(tsv, dialect="excel-tab")) + next(iterResults) + + # Extracting data from TSV file + i = 0 + nagiosFiller = "Nagios issued and cleared service alarm" + hostFiller = "on_host_" + for row in iterResults: + hostStart = None + service = None + hostCheck = True + workingHours = False + ticketID = int(row[0]) + + ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') + dateCreated = ticketCreated.strftime('%d/%m/%Y') + timeCreated = ticketCreated.strftime('%H:%M:%S') + + # Is callout in work hours? + weekday = ticketCreated.isoweekday() + if '08:30:00' < timeCreated < '17:00:00' and weekday < 6: + workingHours = True + + # Get Nagios alarm (or subject if not from Nagios) + alarm = row[2] + if nagiosFiller in alarm: + alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm + + # Service + if 'ceph' in alarm.lower(): + service = 'CEPH' + elif 'arc-ce' in alarm.lower(): + service = 'CE' + elif 'gdss' in alarm.lower(): + service = 'DISK Server' + + # Get hostname from Nagios alarm + if hostFiller in alarm: + j = len(alarm) - 1 + while hostCheck: + if alarm[j] == '_': + hostStart = j + hostCheck = False + j -= 1 + hostname = alarm[hostStart + 1:] + + # Putting data into spreadsheet + currentRow = startingRowNumber + i + currentSheet.cell(row=currentRow, column=1, value=alarm) + if hostStart is not None: + currentSheet.cell(row=currentRow, column=2, value=hostname) + currentSheet.cell(row=currentRow, column=3, value=dateCreated) + currentSheet.cell(row=currentRow, column=4, value=timeCreated) + if service is not None: + currentSheet.cell(row=currentRow, column=6, value=service) + # RT query + currentSheet.cell(row=currentRow, column=5, value=ticketID) + currentSheet.cell(row=currentRow, column=5).hyperlink = 'https://helpdesk.gridpp.rl.ac.uk/Ticket/Display' \ + '.html?id=' + str(ticketID) + if workingHours: + currentSheet.cell(row=currentRow, column=8, value='N/A') + currentSheet.cell(row=currentRow, column=10, value='Work hours') + i += 1 + + # Merge cells + currentDate = datetime.now().strftime('%d-%b') + currentSheet.cell(row=startingRowNumber, column=12, value=currentDate) + currentSheet.merge_cells(start_row=startingRowNumber, start_column=12, end_row=currentRow, end_column=12) + + # Setting inner borders and cell alignment + rows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) + innerBorderStyle = Side(border_style='thin', color='FF000000') + innerBorderFormat = Border(left=innerBorderStyle, right=innerBorderStyle, top=innerBorderStyle, + bottom=innerBorderStyle) + for row in rows: + for cell in row: + if cell.column == 'A' or cell.column == 'K': + # These columns need to be horizontally left aligned (alarm and comment columns) + cell.alignment = Alignment(vertical='center', wrap_text=True) + else: + cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) + + cell.border = innerBorderFormat + + # Setting outer border + # Code found at: https://stackoverflow.com/questions/34520764/apply-border-to-range-of-cells-using-openpyxl + # Written by Yaroslav Admin, edited by Adam Stewart + outerRows = currentSheet.iter_rows(min_row=startingRowNumber, min_col=1, max_row=currentRow, max_col=17) + outerBorderStyle = Side(border_style='medium', color='FF000000') + outerRows = list(outerRows) + max_y = len(outerRows) - 1 + for pos_y, cells in enumerate(outerRows): + max_x = len(cells) - 1 # index of the last cell + for pos_x, cell in enumerate(cells): + border = Border( + left=cell.border.left, + right=cell.border.right, + top=cell.border.top, + bottom=cell.border.bottom) + + # Checking if an edge cell + if pos_x == 0: + border.left = outerBorderStyle + if pos_x == max_x: + border.right = outerBorderStyle + if pos_y == 0: + border.top = outerBorderStyle + if pos_y == max_y: + border.bottom = outerBorderStyle + + # Set new border only if it's one of the edge cells + if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y: + cell.border = border + + wb.save(SPREADSHEET_NAME) + print('Spreadsheet changes saved') +except FileNotFoundError: + print(NEW_TICKETS_FILE_NAME, '(this week\'s tickets) not found, please add to the same directory of the script') + print('Directory of script:', os.path.dirname(os.path.realpath(__file__))) + time.sleep(4) + sys.exit() From a6cfaa1aa0281ed357fb6884cb739c5c4e14a463 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 8 May 2018 16:21:31 +0100 Subject: [PATCH 27/42] Add to README - Instructions to use the script added as well as a couple of changes --- README.md | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e6d9530..001e736 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,31 @@ # Automating OnCall Spreadsheet -A Python script to aid filling in the OnCall spreadsheet in preparation for the OnCall meeting in RIG using data from a TSV file downloaded from RT using a specific search (see 'Using Script'). +This is a Python script to aid filling in the OnCall spreadsheet. The spreadsheet is used during the 3pm meeting on a Monday to discuss callouts from the past week. +The script takes data from a TSV file downloaded from RT using a specific search (see 'Using Script') and appends it to the ongoing OnCall spreadsheet (found within Tier 1's section on the TWiki). ## Required Packages -Package | Version -------- | ------- -xlrd | 1.1.0 -xlutils | 2.0.0 +Only openpyxl is needed for this script. The script was written using version 2.5.3 of this module. ## Using Script -- Create a custom ticket search in RT +There are a couple of steps to using this script as there will be some cleanup to do once the script has run however this makes the process significantly quicker. + +### Pre-Script Execution +- Create a custom ticket search in RT: - Normal OnCall queue (new or open tickets) - Ignore 'NoCall' tickets - Ignore 'Tier1_service_Test_Nagios_and_paging_on_host_nagger' tickets (test pager tickets) - Ignore 'Downtime Expiry Report' tickets + - Sort ID by ascending - Download spreadsheet (.TSV file) from search results -- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script then Python script -- Perform usual OnCall meeting protocol regarding the tickets - resolve those that have been cleared up +- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run it + +### Post-Script Execution +- For each row added because of the script, double click and press ENTER on the cell in 'Time issued' column. This will execute the formula that deals with the conditional formatting for working hours as this doesn't occur during the script. +- Fill in any blank cells which the script didn't fill: + - Host + - Service + - People involved + - Handled by + - Any helpful comments +- Upload to TWiki +- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet From 3a7bfce8d569d64ac0d6fcad20d0e59214c23fef Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 14 May 2018 09:50:13 +0100 Subject: [PATCH 28/42] Change method of grabbing alarm - If subject didn't include 'and cleared', the Nagios filler would still remain in the alarm name - This generalises nagiosFiller and searches for the first 'T' (for Tier 1) to remove Nagios filler --- AppendSpreadsheet.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 9f7ffd7..f224875 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -47,7 +47,7 @@ # Extracting data from TSV file i = 0 - nagiosFiller = "Nagios issued and cleared service alarm" + nagiosFiller = "Nagios issued" hostFiller = "on_host_" for row in iterResults: hostStart = None @@ -68,7 +68,11 @@ # Get Nagios alarm (or subject if not from Nagios) alarm = row[2] if nagiosFiller in alarm: - alarm = alarm[len(nagiosFiller) + 1:] # Just leaves Nagios alarm + for k in range(len(nagiosFiller), len(alarm)): + print(alarm[k]) + if 'T' in alarm[k]: + alarm = alarm[k:] + break # Service if 'ceph' in alarm.lower(): From 80cbd3b7efd5daeb4ddbbde250a090385d6c72d5 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 14 May 2018 14:33:44 +0100 Subject: [PATCH 29/42] Clean README - README made clearer to understand - RT custom search easier to put into RT (more like RT language used) --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 001e736..63315e7 100644 --- a/README.md +++ b/README.md @@ -6,26 +6,26 @@ The script takes data from a TSV file downloaded from RT using a specific search Only openpyxl is needed for this script. The script was written using version 2.5.3 of this module. ## Using Script -There are a couple of steps to using this script as there will be some cleanup to do once the script has run however this makes the process significantly quicker. +There are a couple of steps to using this script as there will be some cleanup to do once the script has executed. ### Pre-Script Execution - Create a custom ticket search in RT: - - Normal OnCall queue (new or open tickets) - - Ignore 'NoCall' tickets - - Ignore 'Tier1_service_Test_Nagios_and_paging_on_host_nagger' tickets (test pager tickets) - - Ignore 'Downtime Expiry Report' tickets + - Queue is OnCall + - Status is new or open + - Subject not like 'NoCall' + - Subject not like 'Tier1_service_Test_Nagios_and_paging_on_host_nagger' (test pager tickets) + - Subject not like 'Downtime Expiry Report' - Sort ID by ascending -- Download spreadsheet (.TSV file) from search results -- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run it +- Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) +- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script ### Post-Script Execution -- For each row added because of the script, double click and press ENTER on the cell in 'Time issued' column. This will execute the formula that deals with the conditional formatting for working hours as this doesn't occur during the script. -- Fill in any blank cells which the script didn't fill: +- For each row added by the script, double click and press ENTER on the cell in 'Time issued' column. This will execute the formula that deals with the conditional formatting for working hours as this doesn't occur during the script. You will know which rows should be black as these will have the 'Normal Service Restored?' and the 'Handled by' columns filled in. +- Fill in any blank cells the script didn't fill from the following columns: - Host - Service - People involved - Handled by - Any helpful comments - Upload to TWiki -- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet - +- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet \ No newline at end of file From 78a6b638d2d3366230da54625e1411c54b7cf9b0 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 21 May 2018 08:47:54 +0100 Subject: [PATCH 30/42] Remove unneeded print statement --- AppendSpreadsheet.py | 1 - 1 file changed, 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index f224875..3942e74 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -69,7 +69,6 @@ alarm = row[2] if nagiosFiller in alarm: for k in range(len(nagiosFiller), len(alarm)): - print(alarm[k]) if 'T' in alarm[k]: alarm = alarm[k:] break From 80745cc753e2e5280b9639aaea6d1b3558355de9 Mon Sep 17 00:00:00 2001 From: Benjamin Edwards <32669118+BenCEdwards@users.noreply.github.com> Date: Mon, 8 Oct 2018 17:11:13 +0100 Subject: [PATCH 31/42] Update AppendSpreadsheet.py Formatted date time to allow excel to automatically apply conditional formatting to the cells --- AppendSpreadsheet.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 3942e74..8682afc 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -32,7 +32,7 @@ print('Calculating where to append spreadsheet') startAppending = False - i = 2 # Start at 2 as first result will always be 'column header' + i = 1 # Start at 1 as first result will always be 'column header' while not startAppending: if alarmColumn[i].value is None: startAppending = True @@ -55,14 +55,16 @@ hostCheck = True workingHours = False ticketID = int(row[0]) - + ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') - dateCreated = ticketCreated.strftime('%d/%m/%Y') - timeCreated = ticketCreated.strftime('%H:%M:%S') + #Excel date time counts days and seconds since 1900-01-00 but mistakenly treats 1900 as a leap year + excelTicketCreated = ticketCreated - datetime(1899, 12, 30) + dateCreated = float(excelTicketCreated.days) + timeCreated = float(excelTicketCreated.seconds) / 86400 - # Is callout in work hours? + # Is callout in work hours (8:30-5:00 converted into percent of day)? weekday = ticketCreated.isoweekday() - if '08:30:00' < timeCreated < '17:00:00' and weekday < 6: + if (60*8+30)/(24*60) < timeCreated < 17/24 and weekday < 6: workingHours = True # Get Nagios alarm (or subject if not from Nagios) From 0cf4e718b433c27f32e0eb43feed5cfead88ca28 Mon Sep 17 00:00:00 2001 From: Benjamin Edwards <32669118+BenCEdwards@users.noreply.github.com> Date: Mon, 8 Oct 2018 17:11:48 +0100 Subject: [PATCH 32/42] Update README.md Removed instructions to format date and time entries --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 63315e7..b18784f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ There are a couple of steps to using this script as there will be some cleanup t - Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script ### Post-Script Execution -- For each row added by the script, double click and press ENTER on the cell in 'Time issued' column. This will execute the formula that deals with the conditional formatting for working hours as this doesn't occur during the script. You will know which rows should be black as these will have the 'Normal Service Restored?' and the 'Handled by' columns filled in. - Fill in any blank cells the script didn't fill from the following columns: - Host - Service @@ -28,4 +27,4 @@ There are a couple of steps to using this script as there will be some cleanup t - Handled by - Any helpful comments - Upload to TWiki -- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet \ No newline at end of file +- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet From 7299985f7abec119d9f72f894961779183d568f7 Mon Sep 17 00:00:00 2001 From: Benjamin Edwards <32669118+BenCEdwards@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:18:48 +0100 Subject: [PATCH 33/42] Added 'fts' to services --- AppendSpreadsheet.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 8682afc..0db7ec7 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -82,6 +82,8 @@ service = 'CE' elif 'gdss' in alarm.lower(): service = 'DISK Server' + elif 'fts' in alarm.lower(): + service = 'FTS' # Get hostname from Nagios alarm if hostFiller in alarm: From 9720ab7e2d876099d9d550011cfb20bf91111120 Mon Sep 17 00:00:00 2001 From: Benjamin Edwards <32669118+BenCEdwards@users.noreply.github.com> Date: Fri, 29 Mar 2019 14:17:28 +0000 Subject: [PATCH 34/42] Update AppendSpreadsheet.py Updated year to 2019, made alterations to fit new sheet formatting, updated list of services --- AppendSpreadsheet.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 0db7ec7..a593586 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -5,7 +5,7 @@ NEW_TICKETS_FILE_NAME = "Results.tsv" SPREADSHEET_NAME = "Callouts.xlsx" -SHEET_NAME = "Callouts 2018" +SHEET_NAME = "Callouts 2019" try: with open(NEW_TICKETS_FILE_NAME) as tsv: @@ -57,9 +57,9 @@ ticketID = int(row[0]) ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') + dateCreated = ticketCreated.strftime('%d/%m/%Y') #Excel date time counts days and seconds since 1900-01-00 but mistakenly treats 1900 as a leap year excelTicketCreated = ticketCreated - datetime(1899, 12, 30) - dateCreated = float(excelTicketCreated.days) timeCreated = float(excelTicketCreated.seconds) / 86400 # Is callout in work hours (8:30-5:00 converted into percent of day)? @@ -78,12 +78,26 @@ # Service if 'ceph' in alarm.lower(): service = 'CEPH' + elif 'lcgdb' in alarm.lower() or 'database' in alarm.lower(): + service = 'DATABASE' + elif 'castor' in alarm.lower(): + service = 'CASTOR' elif 'arc-ce' in alarm.lower(): service = 'CE' - elif 'gdss' in alarm.lower(): + elif 'bdii' in alarm.lower(): + service = 'BDII' + elif 'dss' in alarm.lower(): service = 'DISK Server' elif 'fts' in alarm.lower(): service = 'FTS' + elif 'ipv6' in alarm.lower() or 'network' in alarm.lower(): + service = 'NETWORK' + elif 'eql-varray' in alarm.lower(): + service = 'Hypervisor' + elif 'condor' in alarm.lower(): + service = 'BATCH' + elif 'argus' in alarm.lower(): + service = 'Argus' # Get hostname from Nagios alarm if hostFiller in alarm: From bc8bd014a2bdbba8b0d759e8df12998a1b0a4e90 Mon Sep 17 00:00:00 2001 From: Benjamin Edwards <32669118+BenCEdwards@users.noreply.github.com> Date: Fri, 29 Mar 2019 14:21:39 +0000 Subject: [PATCH 35/42] Update README.md Updated to fit with formatting on new 2019 sheet --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b18784f..c474519 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,14 @@ There are a couple of steps to using this script as there will be some cleanup t - Queue is OnCall - Status is new or open - Subject not like 'NoCall' - - Subject not like 'Tier1_service_Test_Nagios_and_paging_on_host_nagger' (test pager tickets) + - Subject not like 'Test_Nagios' (test tickets) - Subject not like 'Downtime Expiry Report' - Sort ID by ascending - Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) - Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script ### Post-Script Execution +- Format column D as Time - Fill in any blank cells the script didn't fill from the following columns: - Host - Service @@ -27,4 +28,4 @@ There are a couple of steps to using this script as there will be some cleanup t - Handled by - Any helpful comments - Upload to TWiki -- After the meeting, resolve all tickets from the OnCall queue, except the ones where the situation is still ongoing or haven't been put in the spreadsheet +- After the meeting, resolve all tickets from the OnCall queue search, except the ones where the situation is still ongoing From 74de33ae73b085a2145c9a40e994f6ffbeb21d7b Mon Sep 17 00:00:00 2001 From: JHaydock Date: Mon, 1 Apr 2019 13:49:45 +0100 Subject: [PATCH 36/42] Future Proofing --- AppendSpreadsheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index a593586..0b34de6 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -5,7 +5,7 @@ NEW_TICKETS_FILE_NAME = "Results.tsv" SPREADSHEET_NAME = "Callouts.xlsx" -SHEET_NAME = "Callouts 2019" +SHEET_NAME = "Callouts %s" % datetime.now().year try: with open(NEW_TICKETS_FILE_NAME) as tsv: From 2e37c62d74eda29ea63b6cb8cadc541920631b03 Mon Sep 17 00:00:00 2001 From: JHaydock Date: Tue, 2 Apr 2019 11:38:02 +0100 Subject: [PATCH 37/42] Corrected Text alignment --- AppendSpreadsheet.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 0b34de6..54e1cff 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -55,7 +55,7 @@ hostCheck = True workingHours = False ticketID = int(row[0]) - + ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') dateCreated = ticketCreated.strftime('%d/%m/%Y') #Excel date time counts days and seconds since 1900-01-00 but mistakenly treats 1900 as a leap year @@ -139,11 +139,12 @@ bottom=innerBorderStyle) for row in rows: for cell in row: - if cell.column == 'A' or cell.column == 'K': + if cell.column == 1 or cell.column == 11: # These columns need to be horizontally left aligned (alarm and comment columns) - cell.alignment = Alignment(vertical='center', wrap_text=True) + cell.alignment = Alignment(horizontal='left', vertical='center', wrap_text=True) else: cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) + # print(cell.column) cell.border = innerBorderFormat From eb589de6a7adb3424ecce3ff791c3c14bba6afb1 Mon Sep 17 00:00:00 2001 From: JHaydock-Pro Date: Mon, 10 Jun 2019 11:24:37 +0100 Subject: [PATCH 38/42] Updated expected datetime format --- AppendSpreadsheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 54e1cff..2e471a7 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -56,7 +56,7 @@ workingHours = False ticketID = int(row[0]) - ticketCreated = datetime.strptime(row[15], '%Y-%m-%d %H:%M:%S') + ticketCreated = datetime.strptime(row[15], '%a %b %d %H:%M:%S %Y') dateCreated = ticketCreated.strftime('%d/%m/%Y') #Excel date time counts days and seconds since 1900-01-00 but mistakenly treats 1900 as a leap year excelTicketCreated = ticketCreated - datetime(1899, 12, 30) From 9a5c06a96f2635c7edbc55e76f57472c6f0d002b Mon Sep 17 00:00:00 2001 From: JHaydock-Pro Date: Mon, 10 Jun 2019 11:37:58 +0100 Subject: [PATCH 39/42] Simplfied Spreadsheet --- AppendSpreadsheet.py | 4 ++-- README.md | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AppendSpreadsheet.py b/AppendSpreadsheet.py index 2e471a7..a40c008 100644 --- a/AppendSpreadsheet.py +++ b/AppendSpreadsheet.py @@ -56,7 +56,7 @@ workingHours = False ticketID = int(row[0]) - ticketCreated = datetime.strptime(row[15], '%a %b %d %H:%M:%S %Y') + ticketCreated = datetime.strptime(row[3], '%a %b %d %H:%M:%S %Y') dateCreated = ticketCreated.strftime('%d/%m/%Y') #Excel date time counts days and seconds since 1900-01-00 but mistakenly treats 1900 as a leap year excelTicketCreated = ticketCreated - datetime(1899, 12, 30) @@ -68,7 +68,7 @@ workingHours = True # Get Nagios alarm (or subject if not from Nagios) - alarm = row[2] + alarm = row[1] if nagiosFiller in alarm: for k in range(len(nagiosFiller), len(alarm)): if 'T' in alarm[k]: diff --git a/README.md b/README.md index c474519..487765d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Automating OnCall Spreadsheet -This is a Python script to aid filling in the OnCall spreadsheet. The spreadsheet is used during the 3pm meeting on a Monday to discuss callouts from the past week. +This is a Python script to aid filling in the OnCall spreadsheet. The spreadsheet is used during the 3pm meeting on a Monday to discuss callouts from the past week. The script takes data from a TSV file downloaded from RT using a specific search (see 'Using Script') and appends it to the ongoing OnCall spreadsheet (found within Tier 1's section on the TWiki). ## Required Packages @@ -16,6 +16,11 @@ There are a couple of steps to using this script as there will be some cleanup t - Subject not like 'Test_Nagios' (test tickets) - Subject not like 'Downtime Expiry Report' - Sort ID by ascending +- Set the first four display columns to the following order: + - id + - Subject + - Status + - Created - Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) - Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script From 2e69e586c148ba4c77e901a5561c2f91a5a93d33 Mon Sep 17 00:00:00 2001 From: JHaydock-Pro Date: Mon, 10 Jun 2019 11:43:34 +0100 Subject: [PATCH 40/42] Shared RT search --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 487765d..61c9a6f 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,20 @@ Only openpyxl is needed for this script. The script was written using version 2. There are a couple of steps to using this script as there will be some cleanup to do once the script has executed. ### Pre-Script Execution -- Create a custom ticket search in RT: +- Load the saved search 'OnCall Spreadsheet' under 'Tier1a-support's saved searches. +Or create a custom search with the following criteria: - Queue is OnCall - Status is new or open - Subject not like 'NoCall' - Subject not like 'Test_Nagios' (test tickets) - Subject not like 'Downtime Expiry Report' - Sort ID by ascending -- Set the first four display columns to the following order: - - id - - Subject - - Status - - Created + - Set the first four display columns to the following order: + - id + - Subject + - Status + - Created + - Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) - Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script From 29abe7429859b59327b4c20269532525fe82d4c0 Mon Sep 17 00:00:00 2001 From: Jack Haydock <33467680+JHaydock-Pro@users.noreply.github.com> Date: Mon, 10 Jun 2019 11:48:38 +0100 Subject: [PATCH 41/42] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 61c9a6f..bfa8468 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,7 @@ Only openpyxl is needed for this script. The script was written using version 2. There are a couple of steps to using this script as there will be some cleanup to do once the script has executed. ### Pre-Script Execution -- Load the saved search 'OnCall Spreadsheet' under 'Tier1a-support's saved searches. -Or create a custom search with the following criteria: +- Load the saved search `OnCall Spreadsheet` under `Tier1a-support's saved searches` or create a custom search with the following criteria: - Queue is OnCall - Status is new or open - Subject not like 'NoCall' From 5c6b49b7d46eb6879b5f7b26e92b8dc7f7a8be5f Mon Sep 17 00:00:00 2001 From: Jack Haydock <33467680+JHaydock-Pro@users.noreply.github.com> Date: Mon, 10 Jun 2019 11:49:39 +0100 Subject: [PATCH 42/42] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bfa8468..b88bf38 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Only openpyxl is needed for this script. The script was written using version 2. There are a couple of steps to using this script as there will be some cleanup to do once the script has executed. ### Pre-Script Execution -- Load the saved search `OnCall Spreadsheet` under `Tier1a-support's saved searches` or create a custom search with the following criteria: +1. Load the saved search `OnCall Spreadsheet` under `Tier1a-support's saved searches` or create a custom search with the following criteria: - Queue is OnCall - Status is new or open - Subject not like 'NoCall' @@ -22,16 +22,16 @@ There are a couple of steps to using this script as there will be some cleanup t - Status - Created -- Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) -- Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script +2. Download spreadsheet (.TSV file) from search results (press 'Spreadsheet' hyperlink towards top right of the page) +3. Put OnCall spreadsheet (found in TWiki within Tier 1 section) and TSV file in same folder as script and then run script ### Post-Script Execution -- Format column D as Time -- Fill in any blank cells the script didn't fill from the following columns: +1. Format column D as Time +2. Fill in any blank cells the script didn't fill from the following columns: - Host - Service - People involved - Handled by - Any helpful comments -- Upload to TWiki -- After the meeting, resolve all tickets from the OnCall queue search, except the ones where the situation is still ongoing +3. Upload to TWiki +4. After the meeting, resolve all tickets from the OnCall queue search, except the ones where the situation is still ongoing