forked from log2timeline/plaso
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Code review: 255980043: Added xlsx output module log2timeline#263
- Loading branch information
1 parent
5e2294e
commit 7f03df3
Showing
11 changed files
with
460 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
Copyright (c) 2013, John McNamara <[email protected]> | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
The views and conclusions contained in the software and documentation are those | ||
of the authors and should not be interpreted as representing official policies, | ||
either expressed or implied, of the FreeBSD Project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# -*- coding: utf-8 -*- | ||
"""The arguments helper for the xlsx output module.""" | ||
|
||
from plaso.lib import errors | ||
from plaso.cli.helpers import interface | ||
from plaso.cli.helpers import manager | ||
from plaso.output import xlsx | ||
|
||
|
||
class XlsxOutputHelper(interface.ArgumentsHelper): | ||
"""CLI arguments helper class for the XLSX output module.""" | ||
|
||
NAME = u'xlsx' | ||
CATEGORY = u'output' | ||
DESCRIPTION = u'Argument helper for the XLSX output module.' | ||
|
||
_DEFAULT_TIMESTAMP_FORMAT = u'YYYY-MM-DD HH:MM:SS.000' | ||
|
||
@classmethod | ||
def AddArguments(cls, argument_group): | ||
"""Add command line arguments the helper supports to an argument group. | ||
This function takes an argument parser or an argument group object and adds | ||
to it all the command line arguments this helper supports. | ||
Args: | ||
argument_group: the argparse group (instance of argparse._ArgumentGroup or | ||
or argparse.ArgumentParser). | ||
""" | ||
argument_group.add_argument( | ||
u'--timestamp_format', dest=u'timestamp_format', type=unicode, | ||
action=u'store', default=u'', help=( | ||
u'Set the timestamp format that will be used in the datetime' | ||
u'column of the XLSX spreadsheet.')) | ||
|
||
@classmethod | ||
def ParseOptions(cls, options, output_module): | ||
"""Parses and validates options. | ||
Args: | ||
options: the parser option object (instance of argparse.Namespace). | ||
output_module: an output module (instance of OutputModule). | ||
Raises: | ||
BadConfigObject: when the output module object is of the wrong type. | ||
BadConfigOption: when a configuration parameter fails validation. | ||
""" | ||
if not isinstance(output_module, xlsx.XlsxOutputModule): | ||
raise errors.BadConfigObject( | ||
u'Output module is not an instance of XlsxOutputModule') | ||
|
||
timestamp_format = getattr( | ||
options, u'timestamp_format', cls._DEFAULT_TIMESTAMP_FORMAT) | ||
output_module.SetTimestampFormat(timestamp_format) | ||
|
||
filename = getattr(options, u'write', None) | ||
if filename: | ||
output_module.SetFilename(filename) | ||
|
||
|
||
manager.ArgumentHelperManager.RegisterHelper(XlsxOutputHelper) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Output module for the Excel Spreadsheet (XLSX) output format.""" | ||
|
||
import datetime | ||
import logging | ||
import os | ||
|
||
try: | ||
import xlsxwriter | ||
except ImportError: | ||
xlsxwriter = None | ||
|
||
from plaso.lib import timelib | ||
from plaso.lib import utils | ||
from plaso.output import dynamic | ||
from plaso.output import manager | ||
|
||
|
||
class XlsxOutputModule(dynamic.DynamicOutputModule): | ||
"""Output module for the Excel Spreadsheet (XLSX) output format.""" | ||
|
||
NAME = u'xlsx' | ||
DESCRIPTION = u'Excel Spreadsheet (XLSX) output' | ||
|
||
_MAX_COLUMN_WIDTH = 50 | ||
_MIN_COLUMN_WIDTH = 6 | ||
|
||
def __init__(self, output_mediator): | ||
"""Initializes the output module object. | ||
Args: | ||
output_mediator: The output mediator object (instance of OutputMediator). | ||
""" | ||
super(XlsxOutputModule, self).__init__(output_mediator) | ||
self._column_widths = {} | ||
self._current_row = 0 | ||
self._filename = None | ||
self._sheet = None | ||
self._timestamp_format = None | ||
self._workbook = None | ||
|
||
def _FormatDateTime(self, event_object): | ||
"""Formats the date to a datetime object without timezone information. | ||
Note: Timezone information must be removed due to lack of support | ||
by xlsxwriter and Excel. | ||
Args: | ||
event_object: the event object (instance of EventObject). | ||
Returns: | ||
A datetime object (instance of datetime.datetime) of the event object's | ||
timestamp or the Excel epoch (the null time according to Excel) | ||
on an OverflowError. | ||
""" | ||
try: | ||
timestamp = timelib.Timestamp.CopyToDatetime( | ||
event_object.timestamp, timezone=self._output_mediator.timezone, | ||
raise_error=True) | ||
|
||
return timestamp.replace(tzinfo=None) | ||
|
||
except OverflowError as exception: | ||
logging.error(( | ||
u'Unable to copy {0:d} into a human readable timestamp with error: ' | ||
u'{1:s}. Event {2:d}:{3:d} triggered the exception.').format( | ||
event_object.timestamp, exception, | ||
getattr(event_object, u'store_number', u''), | ||
getattr(event_object, u'store_index', u''))) | ||
|
||
return datetime.datetime(1899, 12, 31) | ||
|
||
def Close(self): | ||
"""Closes the output.""" | ||
self._workbook.close() | ||
|
||
def Open(self): | ||
"""Creates a new workbook.""" | ||
if not self._filename: | ||
raise ValueError(( | ||
u'Unable to create XlSX workbook. Output filename was not provided.')) | ||
|
||
if os.path.isfile(self._filename): | ||
raise IOError(( | ||
u'Unable to use an already existing file for output ' | ||
u'[{0:s}]').format(self._filename)) | ||
|
||
self._workbook = xlsxwriter.Workbook( | ||
self._filename, | ||
{u'constant_memory': True, u'strings_to_urls': False, | ||
u'default_date_format': self._timestamp_format}) | ||
self._sheet = self._workbook.add_worksheet(u'Sheet') | ||
self._current_row = 0 | ||
|
||
def SetFilename(self, filename): | ||
"""Sets the filename. | ||
Args: | ||
filename: the filename. | ||
""" | ||
self._filename = filename | ||
|
||
def SetTimestampFormat(self, timestamp_format): | ||
"""Set the timestamp format to use for the datetime column. | ||
Args: | ||
timestamp_format: A string that describes the way to format the datetime. | ||
""" | ||
self._timestamp_format = timestamp_format | ||
|
||
def WriteEventBody(self, event_object): | ||
"""Writes the body of an event object to the spreadsheet. | ||
Args: | ||
event_object: the event object (instance of EventObject). | ||
""" | ||
for field in self._fields: | ||
callback_name = self.FIELD_FORMAT_CALLBACKS.get(field, None) | ||
callback_function = None | ||
if callback_name: | ||
callback_function = getattr(self, callback_name, None) | ||
|
||
if callback_function: | ||
value = callback_function(event_object) | ||
else: | ||
value = getattr(event_object, field, u'-') | ||
|
||
if not isinstance(value, (bool, int, long, float, datetime.datetime)): | ||
value = utils.GetUnicodeString(value) | ||
value = utils.RemoveIllegalXMLCharacters(value) | ||
|
||
# Auto adjust column width based on length of value. | ||
column_index = self._fields.index(field) | ||
self._column_widths.setdefault(column_index, 0) | ||
self._column_widths[column_index] = max( | ||
self._MIN_COLUMN_WIDTH, | ||
self._column_widths[column_index], | ||
min(self._MAX_COLUMN_WIDTH, len(utils.GetUnicodeString(value)) + 2)) | ||
self._sheet.set_column( | ||
column_index, column_index, self._column_widths[column_index]) | ||
|
||
if field in [u'datetime', u'timestamp']: | ||
self._sheet.write_datetime( | ||
self._current_row, column_index, value) | ||
else: | ||
self._sheet.write(self._current_row, column_index, value) | ||
|
||
self._current_row += 1 | ||
|
||
def WriteHeader(self): | ||
"""Writes the header to the spreadsheet.""" | ||
self._column_widths = {} | ||
bold = self._workbook.add_format({u'bold': True}) | ||
bold.set_align(u'center') | ||
for index, field in enumerate(self._fields): | ||
self._sheet.write(self._current_row, index, field, bold) | ||
self._column_widths[index] = len(field) + 2 | ||
self._current_row += 1 | ||
self._sheet.autofilter(0, len(self._fields)-1, 0, 0) | ||
self._sheet.freeze_panes(1, 0) | ||
|
||
|
||
manager.OutputManager.RegisterOutput( | ||
XlsxOutputModule, disabled=xlsxwriter is None) | ||
|
Oops, something went wrong.