mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-03 22:01:39 +00:00
Update redirect csv <FileName>
This commit is contained in:
@@ -1351,9 +1351,12 @@ verify
|
|||||||
## File Redirection
|
## File Redirection
|
||||||
|
|
||||||
If the pattern {{Section}} appears in <FileName>, it will be replaced with the name of the current section.
|
If the pattern {{Section}} appears in <FileName>, it will be replaced with the name of the current section.
|
||||||
For redirect csv, the optional arguments must appear in the order shown.
|
|
||||||
|
For redirect csv, the optional arguments can be specfified in any order but `todrive <ToDriveAttribute>*`
|
||||||
|
must be last.
|
||||||
|
|
||||||
<Redirect> ::=
|
<Redirect> ::=
|
||||||
redirect csv <FileName> [multiprocess] [append] [noheader] [charset <Charset>]
|
redirect csv <FileName> [delayopen] multiprocess] [append] [noheader] [charset <Charset>]
|
||||||
[columndelimiter <Character>] [quotechar <Character>] [noescapechar [<Boolean>]]
|
[columndelimiter <Character>] [quotechar <Character>] [noescapechar [<Boolean>]]
|
||||||
[sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Bopolean>]]
|
[sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Bopolean>]]
|
||||||
[todrive <ToDriveAttribute>*] |
|
[todrive <ToDriveAttribute>*] |
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
7.42.00
|
||||||
|
|
||||||
|
In versions prior to 7.42.00, when `redirect csv <FileName>` was used, GAM did not open and write `<FileName>`
|
||||||
|
until all processing was complete; if `<FileName>` was not accessible, an error was generated
|
||||||
|
and no results were saved. Now, `<FileName>` is opened initially to verify accessiblity
|
||||||
|
and then written when processing is complete.
|
||||||
|
|
||||||
|
In the unlikely event that this causes issues, you can do `redirect csv <FileName> delayopen`
|
||||||
|
to get the previous behavior.
|
||||||
|
|
||||||
7.41.03
|
7.41.03
|
||||||
|
|
||||||
Fixed bug in the following:
|
Fixed bug in the following:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.41.03'
|
__version__ = '7.42.00'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
# pylint: disable=wrong-import-position
|
||||||
@@ -3953,7 +3953,7 @@ def SetGlobalVariables():
|
|||||||
'\n'))
|
'\n'))
|
||||||
status['errors'] = True
|
status['errors'] = True
|
||||||
|
|
||||||
def _setCSVFile(fileName, mode, encoding, writeHeader, multi):
|
def _setCSVFile(fileName, mode, encoding, writeHeader, multi, delayOpen):
|
||||||
if fileName != '-':
|
if fileName != '-':
|
||||||
fileName = setFilePath(fileName, GC.DRIVE_DIR)
|
fileName = setFilePath(fileName, GC.DRIVE_DIR)
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME] = fileName
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME] = fileName
|
||||||
@@ -3962,6 +3962,9 @@ def SetGlobalVariables():
|
|||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_WRITE_HEADER] = writeHeader
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_WRITE_HEADER] = writeHeader
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_MULTIPROCESS] = multi
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_MULTIPROCESS] = multi
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE] = None
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE] = None
|
||||||
|
if not delayOpen and fileName != '-':
|
||||||
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_FD] = openFile(fileName, mode, newline='',
|
||||||
|
encoding=encoding, errors='backslashreplace')
|
||||||
|
|
||||||
def _setSTDFile(stdtype, fileName, mode, multi):
|
def _setSTDFile(stdtype, fileName, mode, multi):
|
||||||
if stdtype == GM.STDOUT:
|
if stdtype == GM.STDOUT:
|
||||||
@@ -4243,7 +4246,7 @@ def SetGlobalVariables():
|
|||||||
# multiprocessexit (rc<Operator><Number>)|(rcrange=<Number>/<Number>)|(rcrange!=<Number>/<Number>)
|
# multiprocessexit (rc<Operator><Number>)|(rcrange=<Number>/<Number>)|(rcrange!=<Number>/<Number>)
|
||||||
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
||||||
_setMultiprocessExit()
|
_setMultiprocessExit()
|
||||||
# redirect csv <FileName> [multiprocess] [append] [noheader] [charset <CharSet>]
|
# redirect csv <FileName> [delayopen] [multiprocess] [append] [noheader] [charset <CharSet>]
|
||||||
# [columndelimiter <Character>] [quotechar <Character>]] [noescapechar [<Boolean>]]
|
# [columndelimiter <Character>] [quotechar <Character>]] [noescapechar [<Boolean>]]
|
||||||
# [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Boolean>]]
|
# [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Boolean>]]
|
||||||
# [todrive <ToDriveAttribute>*]
|
# [todrive <ToDriveAttribute>*]
|
||||||
@@ -4256,23 +4259,39 @@ def SetGlobalVariables():
|
|||||||
myarg = getChoice(['csv', 'stdout', 'stderr'])
|
myarg = getChoice(['csv', 'stdout', 'stderr'])
|
||||||
filename = re.sub(r'{{Section}}', sectionName, getString(Cmd.OB_FILE_NAME, checkBlank=True))
|
filename = re.sub(r'{{Section}}', sectionName, getString(Cmd.OB_FILE_NAME, checkBlank=True))
|
||||||
if myarg == 'csv':
|
if myarg == 'csv':
|
||||||
multi = checkArgumentPresent('multiprocess')
|
multi = False
|
||||||
mode = DEFAULT_FILE_APPEND_MODE if checkArgumentPresent('append') else DEFAULT_FILE_WRITE_MODE
|
mode = DEFAULT_FILE_WRITE_MODE
|
||||||
writeHeader = not checkArgumentPresent('noheader')
|
writeHeader = True
|
||||||
encoding = getCharSet()
|
encoding = GC.Values[GC.CHARSET]
|
||||||
if checkArgumentPresent('columndelimiter'):
|
delayOpen = False
|
||||||
GM.Globals[GM.CSV_OUTPUT_COLUMN_DELIMITER] = GC.Values[GC.CSV_OUTPUT_COLUMN_DELIMITER] = getCharacter()
|
while Cmd.ArgumentsRemaining():
|
||||||
if checkArgumentPresent('quotechar'):
|
myarg = getArgument()
|
||||||
GM.Globals[GM.CSV_OUTPUT_QUOTE_CHAR] = GC.Values[GC.CSV_OUTPUT_QUOTE_CHAR] = getCharacter()
|
if myarg == 'multiprocess':
|
||||||
if checkArgumentPresent('noescapechar'):
|
multi = True
|
||||||
GM.Globals[GM.CSV_OUTPUT_NO_ESCAPE_CHAR] = GC.Values[GC.CSV_OUTPUT_NO_ESCAPE_CHAR] = getBoolean()
|
elif myarg == 'append':
|
||||||
if checkArgumentPresent('sortheaders'):
|
mode = DEFAULT_FILE_APPEND_MODE
|
||||||
GM.Globals[GM.CSV_OUTPUT_SORT_HEADERS] = GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
elif myarg == 'noheader':
|
||||||
if checkArgumentPresent('timestampcolumn'):
|
writeHeader = False
|
||||||
GM.Globals[GM.CSV_OUTPUT_TIMESTAMP_COLUMN] = GC.Values[GC.CSV_OUTPUT_TIMESTAMP_COLUMN] = getString(Cmd.OB_STRING, minLen=0)
|
elif myarg == 'charset':
|
||||||
if checkArgumentPresent('transpose'):
|
encoding = getString(Cmd.OB_CHAR_SET)
|
||||||
GM.Globals[GM.CSV_OUTPUT_TRANSPOSE] = getBoolean()
|
elif myarg == 'delayopen':
|
||||||
_setCSVFile(filename, mode, encoding, writeHeader, multi)
|
delayOpen = True
|
||||||
|
elif myarg == 'columndelimiter':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_COLUMN_DELIMITER] = GC.Values[GC.CSV_OUTPUT_COLUMN_DELIMITER] = getCharacter()
|
||||||
|
elif myarg == 'quotechar':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_QUOTE_CHAR] = GC.Values[GC.CSV_OUTPUT_QUOTE_CHAR] = getCharacter()
|
||||||
|
elif myarg == 'noescapechar':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_NO_ESCAPE_CHAR] = GC.Values[GC.CSV_OUTPUT_NO_ESCAPE_CHAR] = getBoolean()
|
||||||
|
elif myarg == 'sortheaders':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_SORT_HEADERS] = GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
||||||
|
elif myarg == 'timestampcolumn':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_TIMESTAMP_COLUMN] = GC.Values[GC.CSV_OUTPUT_TIMESTAMP_COLUMN] = getString(Cmd.OB_STRING, minLen=0)
|
||||||
|
elif myarg == 'transpose':
|
||||||
|
GM.Globals[GM.CSV_OUTPUT_TRANSPOSE] = getBoolean()
|
||||||
|
else:
|
||||||
|
Cmd.Backup()
|
||||||
|
break
|
||||||
|
_setCSVFile(filename, mode, encoding, writeHeader, multi, delayOpen)
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF] = CSVPrintFile()
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF] = CSVPrintFile()
|
||||||
if checkArgumentPresent('todrive'):
|
if checkArgumentPresent('todrive'):
|
||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].GetTodriveParameters()
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].GetTodriveParameters()
|
||||||
@@ -4309,9 +4328,9 @@ def SetGlobalVariables():
|
|||||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_MULTIPROCESS] == GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS] and
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_MULTIPROCESS] == GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS] and
|
||||||
GM.Globals[GM.CSVFILE].get(GM.REDIRECT_QUEUE_CSVPF) and not GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].todrive):
|
GM.Globals[GM.CSVFILE].get(GM.REDIRECT_QUEUE_CSVPF) and not GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].todrive):
|
||||||
_setCSVFile('-', GM.Globals[GM.STDOUT].get(GM.REDIRECT_MODE, DEFAULT_FILE_WRITE_MODE), GC.Values[GC.CHARSET],
|
_setCSVFile('-', GM.Globals[GM.STDOUT].get(GM.REDIRECT_MODE, DEFAULT_FILE_WRITE_MODE), GC.Values[GC.CHARSET],
|
||||||
GM.Globals[GM.CSVFILE].get(GM.REDIRECT_WRITE_HEADER, True), GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS])
|
GM.Globals[GM.CSVFILE].get(GM.REDIRECT_WRITE_HEADER, True), GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS], False)
|
||||||
elif not GM.Globals[GM.CSVFILE]:
|
elif not GM.Globals[GM.CSVFILE]:
|
||||||
_setCSVFile('-', GM.Globals[GM.STDOUT].get(GM.REDIRECT_MODE, DEFAULT_FILE_WRITE_MODE), GC.Values[GC.CHARSET], True, False)
|
_setCSVFile('-', GM.Globals[GM.STDOUT].get(GM.REDIRECT_MODE, DEFAULT_FILE_WRITE_MODE), GC.Values[GC.CHARSET], True, False, False)
|
||||||
initAPICallsRateCheck()
|
initAPICallsRateCheck()
|
||||||
# Main process
|
# Main process
|
||||||
# Clear input row filters/limit from parser, children can define but shouldn't inherit global value
|
# Clear input row filters/limit from parser, children can define but shouldn't inherit global value
|
||||||
@@ -8782,9 +8801,11 @@ class CSVPrintFile():
|
|||||||
closeFile(csvFile)
|
closeFile(csvFile)
|
||||||
|
|
||||||
def writeCSVToFile():
|
def writeCSVToFile():
|
||||||
csvFile = openFile(GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME], GM.Globals[GM.CSVFILE][GM.REDIRECT_MODE], newline='',
|
csvFile = GM.Globals[GM.CSVFILE].get(GM.REDIRECT_FD, None)
|
||||||
encoding=GM.Globals[GM.CSVFILE][GM.REDIRECT_ENCODING], errors='backslashreplace',
|
if not csvFile:
|
||||||
continueOnError=True)
|
csvFile = openFile(GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME], GM.Globals[GM.CSVFILE][GM.REDIRECT_MODE], newline='',
|
||||||
|
encoding=GM.Globals[GM.CSVFILE][GM.REDIRECT_ENCODING], errors='backslashreplace',
|
||||||
|
continueOnError=True)
|
||||||
if csvFile:
|
if csvFile:
|
||||||
writerDialect = setDialect(str(GC.Values[GC.CSV_OUTPUT_LINE_TERMINATOR]), self.noEscapeChar)
|
writerDialect = setDialect(str(GC.Values[GC.CSV_OUTPUT_LINE_TERMINATOR]), self.noEscapeChar)
|
||||||
writer = csv.DictWriter(csvFile, titlesList, extrasaction=extrasaction, **writerDialect)
|
writer = csv.DictWriter(csvFile, titlesList, extrasaction=extrasaction, **writerDialect)
|
||||||
@@ -9741,18 +9762,15 @@ def initializeLogging():
|
|||||||
logging.getLogger().addHandler(nh)
|
logging.getLogger().addHandler(nh)
|
||||||
|
|
||||||
def saveNonPickleableValues():
|
def saveNonPickleableValues():
|
||||||
savedValues = {GM.STDOUT: {}, GM.STDERR: {}, GM.SAVED_STDOUT: None,
|
savedValues = {GM.CSVFILE: {}, GM.STDOUT: {}, GM.STDERR: {},
|
||||||
GM.CMDLOG_HANDLER: None, GM.CMDLOG_LOGGER: None}
|
GM.SAVED_STDOUT: None, GM.CMDLOG_HANDLER: None, GM.CMDLOG_LOGGER: None}
|
||||||
|
savedValues[GM.CSVFILE][GM.REDIRECT_FD] = GM.Globals[GM.CSVFILE].pop(GM.REDIRECT_FD, None)
|
||||||
|
savedValues[GM.STDOUT][GM.REDIRECT_FD] = GM.Globals[GM.STDOUT].pop(GM.REDIRECT_FD, None)
|
||||||
|
savedValues[GM.STDOUT][GM.REDIRECT_MULTI_FD] = GM.Globals[GM.STDOUT].pop(GM.REDIRECT_MULTI_FD, None)
|
||||||
|
savedValues[GM.STDERR][GM.REDIRECT_FD] = GM.Globals[GM.STDERR].pop(GM.REDIRECT_FD, None)
|
||||||
|
savedValues[GM.STDERR][GM.REDIRECT_MULTI_FD] = GM.Globals[GM.STDERR].pop(GM.REDIRECT_MULTI_FD, None)
|
||||||
savedValues[GM.SAVED_STDOUT] = GM.Globals[GM.SAVED_STDOUT]
|
savedValues[GM.SAVED_STDOUT] = GM.Globals[GM.SAVED_STDOUT]
|
||||||
GM.Globals[GM.SAVED_STDOUT] = None
|
GM.Globals[GM.SAVED_STDOUT] = None
|
||||||
savedValues[GM.STDOUT][GM.REDIRECT_FD] = GM.Globals[GM.STDOUT].get(GM.REDIRECT_FD, None)
|
|
||||||
GM.Globals[GM.STDOUT].pop(GM.REDIRECT_FD, None)
|
|
||||||
savedValues[GM.STDERR][GM.REDIRECT_FD] = GM.Globals[GM.STDERR].get(GM.REDIRECT_FD, None)
|
|
||||||
GM.Globals[GM.STDERR].pop(GM.REDIRECT_FD, None)
|
|
||||||
savedValues[GM.STDOUT][GM.REDIRECT_MULTI_FD] = GM.Globals[GM.STDOUT].get(GM.REDIRECT_MULTI_FD, None)
|
|
||||||
GM.Globals[GM.STDOUT].pop(GM.REDIRECT_MULTI_FD, None)
|
|
||||||
savedValues[GM.STDERR][GM.REDIRECT_MULTI_FD] = GM.Globals[GM.STDERR].get(GM.REDIRECT_MULTI_FD, None)
|
|
||||||
GM.Globals[GM.STDERR].pop(GM.REDIRECT_MULTI_FD, None)
|
|
||||||
savedValues[GM.CMDLOG_HANDLER] = GM.Globals[GM.CMDLOG_HANDLER]
|
savedValues[GM.CMDLOG_HANDLER] = GM.Globals[GM.CMDLOG_HANDLER]
|
||||||
GM.Globals[GM.CMDLOG_HANDLER] = None
|
GM.Globals[GM.CMDLOG_HANDLER] = None
|
||||||
savedValues[GM.CMDLOG_LOGGER] = GM.Globals[GM.CMDLOG_LOGGER]
|
savedValues[GM.CMDLOG_LOGGER] = GM.Globals[GM.CMDLOG_LOGGER]
|
||||||
@@ -9760,11 +9778,12 @@ def saveNonPickleableValues():
|
|||||||
return savedValues
|
return savedValues
|
||||||
|
|
||||||
def restoreNonPickleableValues(savedValues):
|
def restoreNonPickleableValues(savedValues):
|
||||||
GM.Globals[GM.SAVED_STDOUT] = savedValues[GM.SAVED_STDOUT]
|
GM.Globals[GM.CSVFILE][GM.REDIRECT_FD] = savedValues[GM.CSVFILE][GM.REDIRECT_FD]
|
||||||
GM.Globals[GM.STDOUT][GM.REDIRECT_FD] = savedValues[GM.STDOUT][GM.REDIRECT_FD]
|
GM.Globals[GM.STDOUT][GM.REDIRECT_FD] = savedValues[GM.STDOUT][GM.REDIRECT_FD]
|
||||||
GM.Globals[GM.STDERR][GM.REDIRECT_FD] = savedValues[GM.STDERR][GM.REDIRECT_FD]
|
|
||||||
GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD] = savedValues[GM.STDOUT][GM.REDIRECT_MULTI_FD]
|
GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD] = savedValues[GM.STDOUT][GM.REDIRECT_MULTI_FD]
|
||||||
|
GM.Globals[GM.STDERR][GM.REDIRECT_FD] = savedValues[GM.STDERR][GM.REDIRECT_FD]
|
||||||
GM.Globals[GM.STDERR][GM.REDIRECT_MULTI_FD] = savedValues[GM.STDERR][GM.REDIRECT_MULTI_FD]
|
GM.Globals[GM.STDERR][GM.REDIRECT_MULTI_FD] = savedValues[GM.STDERR][GM.REDIRECT_MULTI_FD]
|
||||||
|
GM.Globals[GM.SAVED_STDOUT] = savedValues[GM.SAVED_STDOUT]
|
||||||
GM.Globals[GM.CMDLOG_HANDLER] = savedValues[GM.CMDLOG_HANDLER]
|
GM.Globals[GM.CMDLOG_HANDLER] = savedValues[GM.CMDLOG_HANDLER]
|
||||||
GM.Globals[GM.CMDLOG_LOGGER] = savedValues[GM.CMDLOG_LOGGER]
|
GM.Globals[GM.CMDLOG_LOGGER] = savedValues[GM.CMDLOG_LOGGER]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user