Commit 692706d3 authored by Hilko Bengen's avatar Hilko Bengen

New upstream version 20171109

parent d59018af
This diff is collapsed.
include ACKNOWLEDGEMENTS AUTHORS LICENSE README
include dependencies.ini run_tests.py utils/dependencies.py
include dependencies.ini run_tests.py utils/__init__.py utils/dependencies.py
include utils/check_dependencies.py
exclude .gitignore
exclude *.pyc
......
environment:
matrix:
- PYTHON: "C:\\Python27"
- TARGET: python27
PYTHON: "C:\\Python27"
- TARGET: python36
PYTHON: "C:\\Python36"
install:
- cmd: '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86 /release'
- ps: (new-object net.webclient).DownloadFile('https://bootstrap.pypa.io/get-pip.py', 'C:\Projects\get-pip.py')
- ps: (new-object net.webclient).DownloadFile('https://github.com/log2timeline/l2tbinaries/raw/master/win32/pywin32-220.win32-py2.7.exe', 'C:\Projects\pywin32-220.win32-py2.7.exe')
- ps: (new-object net.webclient).DownloadFile('https://github.com/log2timeline/l2tbinaries/raw/master/win32/WMI-1.4.9.win32.exe', 'C:\Projects\WMI-1.4.9.win32.exe')
- cmd: "%PYTHON%\\python.exe C:\\Projects\\get-pip.py"
- cmd: "%PYTHON%\\Scripts\\easy_install.exe C:\\Projects\\pywin32-220.win32-py2.7.exe"
- cmd: "%PYTHON%\\Scripts\\easy_install.exe C:\\Projects\\WMI-1.4.9.win32.exe"
- cmd: git clone https://github.com/log2timeline/l2tdevtools.git && move l2tdevtools ..\
- cmd: mkdir dependencies && set PYTHONPATH=..\l2tdevtools && "%PYTHON%\\python.exe" ..\l2tdevtools\tools\update.py --download-directory dependencies --machine-type x86 --msi-targetdir "%PYTHON%" funcsigs mock pbr six
- cmd: '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86 /release'
- cmd: "%PYTHON%\\Scripts\\pip.exe install --upgrade pip"
- cmd: "%PYTHON%\\Scripts\\pip.exe install pypiwin32 WMI"
- cmd: git clone https://github.com/log2timeline/l2tdevtools.git ..\l2tdevtools
- cmd: mkdir dependencies && set PYTHONPATH=..\l2tdevtools && "%PYTHON%\\python.exe" ..\l2tdevtools\tools\update.py --download-directory dependencies --machine-type x86 --msi-targetdir "%PYTHON%" --track dev funcsigs mock pbr six
build: off
test_script:
- "%PYTHON%\\python.exe run_tests.py"
- "%PYTHON%\\python.exe run_tests.py"
dfdatetime (20170719-1) unstable; urgency=low
dfdatetime (20171109-1) unstable; urgency=low
* Auto-generated
-- Log2Timeline <log2timeline-dev@googlegroups.com> Wed, 19 Jul 2017 17:43:12 +0200
\ No newline at end of file
-- Log2Timeline <log2timeline-dev@googlegroups.com> Thu, 09 Nov 2017 19:25:09 +0100
\ No newline at end of file
......@@ -22,7 +22,7 @@ then
mv l2tdevtools ../;
mkdir dependencies;
PYTHONPATH=../l2tdevtools ../l2tdevtools/tools/update.py --download-directory=dependencies ${L2TBINARIES_DEPENDENCIES} ${L2TBINARIES_TEST_DEPENDENCIES};
PYTHONPATH=../l2tdevtools ../l2tdevtools/tools/update.py --download-directory dependencies --track dev ${L2TBINARIES_DEPENDENCIES} ${L2TBINARIES_TEST_DEPENDENCIES};
elif test ${TRAVIS_OS_NAME} = "linux";
then
......
......@@ -5,4 +5,4 @@ dfDateTime, or Digital Forensics date and time, provides date and time
objects to preserve accuracy and precision.
"""
__version__ = '20170719'
__version__ = '20171109'
......@@ -9,6 +9,7 @@ Also see:
from __future__ import unicode_literals
PRECISION_1_DAY = '1d'
PRECISION_1_HOUR = '1h'
PRECISION_1_NANOSECOND = '1ns'
......
......@@ -203,10 +203,10 @@ class DateTimeValues(object):
"""
time_string_length = len(time_string)
# The time string should at least contain 'hh:mm:ss'.
if time_string_length < 8:
raise ValueError('Time string too short.')
# The time string should at least contain 'hh:mm:ss'.
if time_string[2] != ':' or time_string[5] != ':':
raise ValueError('Invalid time string.')
......@@ -216,7 +216,7 @@ class DateTimeValues(object):
raise ValueError('Unable to parse hours.')
if hours not in range(0, 24):
raise ValueError('Hours value out of bounds.')
raise ValueError('Hours value: {0:d} out of bounds.'.format(hours))
try:
minutes = int(time_string[3:5], 10)
......@@ -224,7 +224,7 @@ class DateTimeValues(object):
raise ValueError('Unable to parse minutes.')
if minutes not in range(0, 60):
raise ValueError('Minutes value out of bounds.')
raise ValueError('Minutes value: {0:d} out of bounds.'.format(minutes))
try:
seconds = int(time_string[6:8], 10)
......@@ -233,66 +233,69 @@ class DateTimeValues(object):
# TODO: support a leap second?
if seconds not in range(0, 60):
raise ValueError('Seconds value out of bounds.')
raise ValueError('Seconds value: {0:d} out of bounds.'.format(seconds))
microseconds = None
time_zone_offset = None
if time_string_length > 8:
if time_string[8] != '.':
time_zone_string_index = 8
else:
for time_zone_string_index in range(8, time_string_length):
if time_string[time_zone_string_index] in ('+', '-'):
break
# The calculations that follow rely on the time zone string index
# to point beyond the string in case no time zone offset was defined.
if time_zone_string_index == time_string_length - 1:
time_zone_string_index += 1
if time_zone_string_index > 8:
fraction_of_seconds_length = time_zone_string_index - 9
if fraction_of_seconds_length not in (3, 6):
raise ValueError('Invalid time string.')
try:
microseconds = int(time_string[9:time_zone_string_index], 10)
except ValueError:
raise ValueError('Unable to parse fraction of seconds.')
if fraction_of_seconds_length == 3:
microseconds *= 1000
if time_zone_string_index < time_string_length:
if (time_string_length - time_zone_string_index != 6 or
time_string[time_zone_string_index + 3] != ':'):
raise ValueError('Invalid time string.')
try:
hours_from_utc = int(time_string[
time_zone_string_index + 1:time_zone_string_index + 3])
except ValueError:
raise ValueError('Unable to parse time zone hours offset.')
if hours_from_utc not in range(0, 15):
raise ValueError('Time zone hours offset value out of bounds.')
try:
minutes_from_utc = int(time_string[
time_zone_string_index + 4:time_zone_string_index + 6])
except ValueError:
raise ValueError('Unable to parse time zone minutes offset.')
if minutes_from_utc not in range(0, 60):
raise ValueError('Time zone minutes offset value out of bounds.')
time_zone_offset = (hours_from_utc * 60) + minutes_from_utc
# Note that when the sign of the time zone offset is negative
# the difference needs to be added. We do so by flipping the sign.
if time_string[time_zone_string_index] != '-':
time_zone_offset = -time_zone_offset
time_zone_string_index = 8
while time_zone_string_index < time_string_length:
if time_string[time_zone_string_index] in ('+', '-'):
break
time_zone_string_index += 1
# The calculations that follow rely on the time zone string index
# to point beyond the string in case no time zone offset was defined.
if time_zone_string_index == time_string_length - 1:
time_zone_string_index += 1
if time_string_length > 8 and time_string[8] == '.':
time_fraction_length = time_zone_string_index - 9
if time_fraction_length not in (3, 6):
raise ValueError('Invalid time string.')
try:
time_fraction = time_string[9:time_zone_string_index]
time_fraction = int(time_fraction, 10)
except ValueError:
raise ValueError('Unable to parse time fraction.')
if time_fraction_length == 3:
time_fraction *= 1000
microseconds = time_fraction
if time_zone_string_index < time_string_length:
if (time_string_length - time_zone_string_index != 6 or
time_string[time_zone_string_index + 3] != ':'):
raise ValueError('Invalid time string.')
try:
hours_from_utc = int(time_string[
time_zone_string_index + 1:time_zone_string_index + 3])
except ValueError:
raise ValueError('Unable to parse time zone hours offset.')
if hours_from_utc not in range(0, 15):
raise ValueError('Time zone hours offset value out of bounds.')
try:
minutes_from_utc = int(time_string[
time_zone_string_index + 4:time_zone_string_index + 6])
except ValueError:
raise ValueError('Unable to parse time zone minutes offset.')
if minutes_from_utc not in range(0, 60):
raise ValueError('Time zone minutes offset value out of bounds.')
# pylint: disable=invalid-unary-operand-type
time_zone_offset = (hours_from_utc * 60) + minutes_from_utc
# Note that when the sign of the time zone offset is negative
# the difference needs to be added. We do so by flipping the sign.
if time_string[time_zone_string_index] != '-':
time_zone_offset = -time_zone_offset
return hours, minutes, seconds, microseconds, time_zone_offset
......@@ -413,6 +416,7 @@ class DateTimeValues(object):
Returns:
bool: True if the year is a leap year.
"""
# pylint: disable=consider-using-ternary
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
@abc.abstractmethod
......
This diff is collapsed.
......@@ -6,7 +6,7 @@ import sys
import unittest
# Change PYTHONPATH to include dependencies.
sys.path.insert(0, u'.')
sys.path.insert(0, '.')
import utils.dependencies # pylint: disable=wrong-import-position
......
......@@ -89,8 +89,20 @@ else:
in_description = True
elif line.startswith('%files'):
line = '%files -f INSTALLED_FILES -n {0:s}-%{{name}}'.format(
python_package)
# Cannot use %{_libdir} here since it can expand to "lib64".
lines = [
'%files',
'%defattr(644,root,root,755)',
'%doc ACKNOWLEDGEMENTS AUTHORS LICENSE README',
'%{_prefix}/lib/python*/site-packages/dfdatetime/*.py',
'%{_prefix}/lib/python*/site-packages/dfdatetime*.egg-info/*',
'%exclude %{_prefix}/lib/python*/site-packages/dfdatetime/*.pyc',
'%exclude %{_prefix}/lib/python*/site-packages/dfdatetime/*.pyo',
('%exclude %{_prefix}/lib/python*/site-packages/dfdatetime/'
'__pycache__/*')]
python_spec_file.extend(lines)
break
elif line.startswith('%prep'):
in_description = False
......
This diff is collapsed.
......@@ -5,12 +5,12 @@
import sys
# Change PYTHONPATH to include dependencies.
sys.path.insert(0, u'.')
sys.path.insert(0, '.')
import utils.dependencies # pylint: disable=wrong-import-position
if __name__ == u'__main__':
if __name__ == '__main__':
dependency_helper = utils.dependencies.DependencyHelper()
dependency_helper.CheckDependencies()
......@@ -88,6 +88,8 @@ class DependencyDefinitionReader(object):
DependencyDefinition: dependency definition.
"""
config_parser = configparser.RawConfigParser()
# pylint: disable=deprecated-method
# TODO: replace readfp by read_file, check if Python 2 compatible
config_parser.readfp(file_object)
for section_name in config_parser.sections():
......@@ -102,17 +104,23 @@ class DependencyDefinitionReader(object):
class DependencyHelper(object):
"""Dependency helper."""
_VERSION_NUMBERS_REGEX = re.compile(r'[0-9.]+')
_VERSION_SPLIT_REGEX = re.compile(r'\.|\-')
def __init__(self):
"""Initializes a dependency helper."""
def __init__(self, configuration_file='dependencies.ini'):
"""Initializes a dependency helper.
Args:
configuration_file (Optional[str]): path to the dependencies
configuration file.
"""
super(DependencyHelper, self).__init__()
self._dependencies = {}
self._test_dependencies = {}
dependency_reader = DependencyDefinitionReader()
with open('dependencies.ini', 'r') as file_object:
with open(configuration_file, 'r') as file_object:
for dependency in dependency_reader.Read(file_object):
self._dependencies[dependency.name] = dependency
......@@ -185,10 +193,28 @@ class DependencyHelper(object):
# Split the version string and convert every digit into an integer.
# A string compare of both version strings will yield an incorrect result.
module_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(module_version)))
minimum_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(minimum_version)))
# Strip any semantic suffixes such as a1, b1, pre, post, rc, dev.
module_version = self._VERSION_NUMBERS_REGEX.findall(module_version)[0]
if module_version[-1] == '.':
module_version = module_version[:-1]
try:
module_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(module_version)))
except ValueError:
status_message = 'unable to parse module version: {0:s} {1:s}'.format(
module_name, module_version)
return False, status_message
try:
minimum_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(minimum_version)))
except ValueError:
status_message = 'unable to parse minimum version: {0:s} {1:s}'.format(
module_name, minimum_version)
return False, status_message
if module_version_map < minimum_version_map:
status_message = (
......@@ -197,8 +223,14 @@ class DependencyHelper(object):
return False, status_message
if maximum_version:
maximum_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(maximum_version)))
try:
maximum_version_map = list(
map(int, self._VERSION_SPLIT_REGEX.split(maximum_version)))
except ValueError:
status_message = 'unable to parse maximum version: {0:s} {1:s}'.format(
module_name, maximum_version)
return False, status_message
if module_version_map > maximum_version_map:
status_message = (
'{0:s} version: {1!s} is too recent, {2!s} or earlier '
......
# Original file copied from:
# http://src.chromium.org/chrome/trunk/tools/depot_tools/pylintrc
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
# CHANGED:
#
# C0103: Invalid name ""
# C0302: Too many lines in module (N)
#
# I0010: Unable to consider inline option ''
# I0011: Locally disabling WNNNN
#
# R0201: Method could be a function
# R0801: Similar lines in N files
# R0901: Too many ancestors (N/7)
# R0902: Too many instance attributes (N/7)
# R0903: Too few public methods (N/2)
# R0904: Too many public methods (N/20)
# R0911: Too many return statements (N/6)
# R0912: Too many branches (N/12)
# R0913: Too many arguments (N/5)
# R0914: Too many local variables (N/15)
# R0915: Too many statements (N/50)
# R0921: Abstract class not referenced
# R0922: Abstract class is only referenced 1 times
#
# W0141: Used builtin function ''
# W0142: Used * or ** magic
# W0402: Uses of a deprecated module 'string'
# W0404: 41: Reimport 'XX' (imported line NN)
# W0511: TODO
# W1201: Specify string format arguments as logging function parameters
#
# Disabled:
# locally-enabled
# logging-format-interpolation
# redefined-variable-type
# simplifiable-if-statement
# too-many-boolean-expressions (N/5)
# too-many-nested-blocks (N/5)
# ungrouped-imports
disable=C0103,C0302,I0010,I0011,R0201,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,W0141,W0142,W0402,W0404,W0511,W1201,locally-enabled,logging-format-interpolation,redefined-variable-type,simplifiable-if-statement,too-many-boolean-expressions,too-many-nested-blocks,ungrouped-imports
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells whether to display a full report or only the messages
# CHANGED:
reports=no
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the beginning of the name of unused variables.
# By default this is _ and dummy but we prefer _ and unused.
dummy-variables-rgx=_|unused
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject,twisted.internet.reactor,hashlib,google.appengine.api.memcache
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent,multiprocessing.managers.SyncManager
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=80
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
# CHANGED:
indent-string=' '
[BASIC]
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,input
# Regular expression which should only match correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression which should only match correct module level names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression which should only match correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Regular expression which should only match correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct instance attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct list comprehension /
# generator expression variable names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Regular expression which should only match functions or classes name which do
# not require a docstring
no-docstring-rgx=__.*__
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branchs=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment