summaryrefslogtreecommitdiff
path: root/src/tablib/packages/dbfpy3/utils.py
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2019-10-18 15:57:13 +0200
committerGitHub <noreply@github.com>2019-10-18 15:57:13 +0200
commitf6bf14afd22d8e5b706670590cc95f29d4483434 (patch)
treea65fbc8b6fd1112222beb6f66c31082ffe231460 /src/tablib/packages/dbfpy3/utils.py
parentf3d02aa3b088e2f9044fe5e4869e8c8cb91d2cdc (diff)
downloadtablib-f6bf14afd22d8e5b706670590cc95f29d4483434.tar.gz
Add project release config and cleanup project setup. (#398)
* Add project release config and use Travis build stages. Refs #378. * Restructure project to use src/ and tests/ directories. * Fix testing. * Remove eggs. * More fixes. - isort and flake8 config - manifest template update - tox ini extension - docs build fixes - docs content fixes * Docs and license cleanup.
Diffstat (limited to 'src/tablib/packages/dbfpy3/utils.py')
-rw-r--r--src/tablib/packages/dbfpy3/utils.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/tablib/packages/dbfpy3/utils.py b/src/tablib/packages/dbfpy3/utils.py
new file mode 100644
index 0000000..856ade8
--- /dev/null
+++ b/src/tablib/packages/dbfpy3/utils.py
@@ -0,0 +1,170 @@
+"""String utilities.
+
+TODO:
+ - allow strings in getDateTime routine;
+"""
+"""History (most recent first):
+11-feb-2007 [als] added INVALID_VALUE
+10-feb-2007 [als] allow date strings padded with spaces instead of zeroes
+20-dec-2005 [yc] handle long objects in getDate/getDateTime
+16-dec-2005 [yc] created from ``strutil`` module.
+"""
+
+__version__ = "$Revision: 1.4 $"[11:-2]
+__date__ = "$Date: 2007/02/11 08:57:17 $"[7:-2]
+
+import datetime
+import time
+
+
+def unzfill(str):
+ """Return a string without ASCII NULs.
+
+ This function searchers for the first NUL (ASCII 0) occurance
+ and truncates string till that position.
+
+ """
+ try:
+ return str[:str.index(b'\0')]
+ except ValueError:
+ return str
+
+
+def getDate(date=None):
+ """Return `datetime.date` instance.
+
+ Type of the ``date`` argument could be one of the following:
+ None:
+ use current date value;
+ datetime.date:
+ this value will be returned;
+ datetime.datetime:
+ the result of the date.date() will be returned;
+ string:
+ assuming "%Y%m%d" or "%y%m%dd" format;
+ number:
+ assuming it's a timestamp (returned for example
+ by the time.time() call;
+ sequence:
+ assuming (year, month, day, ...) sequence;
+
+ Additionaly, if ``date`` has callable ``ticks`` attribute,
+ it will be used and result of the called would be treated
+ as a timestamp value.
+
+ """
+ if date is None:
+ # use current value
+ return datetime.date.today()
+ if isinstance(date, datetime.date):
+ return date
+ if isinstance(date, datetime.datetime):
+ return date.date()
+ if isinstance(date, (int, float)):
+ # date is a timestamp
+ return datetime.date.fromtimestamp(date)
+ if isinstance(date, str):
+ date = date.replace(" ", "0")
+ if len(date) == 6:
+ # yymmdd
+ return datetime.date(*time.strptime(date, "%y%m%d")[:3])
+ # yyyymmdd
+ return datetime.date(*time.strptime(date, "%Y%m%d")[:3])
+ if hasattr(date, "__getitem__"):
+ # a sequence (assuming date/time tuple)
+ return datetime.date(*date[:3])
+ return datetime.date.fromtimestamp(date.ticks())
+
+
+def getDateTime(value=None):
+ """Return `datetime.datetime` instance.
+
+ Type of the ``value`` argument could be one of the following:
+ None:
+ use current date value;
+ datetime.date:
+ result will be converted to the `datetime.datetime` instance
+ using midnight;
+ datetime.datetime:
+ ``value`` will be returned as is;
+ string:
+ *** CURRENTLY NOT SUPPORTED ***;
+ number:
+ assuming it's a timestamp (returned for example
+ by the time.time() call;
+ sequence:
+ assuming (year, month, day, ...) sequence;
+
+ Additionaly, if ``value`` has callable ``ticks`` attribute,
+ it will be used and result of the called would be treated
+ as a timestamp value.
+
+ """
+ if value is None:
+ # use current value
+ return datetime.datetime.today()
+ if isinstance(value, datetime.datetime):
+ return value
+ if isinstance(value, datetime.date):
+ return datetime.datetime.fromordinal(value.toordinal())
+ if isinstance(value, (int, float)):
+ # value is a timestamp
+ return datetime.datetime.fromtimestamp(value)
+ if isinstance(value, str):
+ raise NotImplementedError("Strings aren't currently implemented")
+ if hasattr(value, "__getitem__"):
+ # a sequence (assuming date/time tuple)
+ return datetime.datetime(*tuple(value)[:6])
+ return datetime.datetime.fromtimestamp(value.ticks())
+
+
+class classproperty(property):
+ """Works in the same way as a ``property``, but for the classes."""
+
+ def __get__(self, obj, cls):
+ return self.fget(cls)
+
+
+class _InvalidValue(object):
+
+ """Value returned from DBF records when field validation fails
+
+ The value is not equal to anything except for itself
+ and equal to all empty values: None, 0, empty string etc.
+ In other words, invalid value is equal to None and not equal
+ to None at the same time.
+
+ This value yields zero upon explicit conversion to a number type,
+ empty string for string types, and False for boolean.
+
+ """
+
+ def __eq__(self, other):
+ return not other
+
+ def __ne__(self, other):
+ return not (other is self)
+
+ def __bool__(self):
+ return False
+
+ def __int__(self):
+ return 0
+ __long__ = __int__
+
+ def __float__(self):
+ return 0.0
+
+ def __str__(self):
+ return ""
+
+ def __unicode__(self):
+ return ""
+
+ def __repr__(self):
+ return "<INVALID>"
+
+# invalid value is a constant singleton
+INVALID_VALUE = _InvalidValue()
+
+# vim: set et sts=4 sw=4 :