Add pylint config and selectively fix some pylint errors
Some pylint errors are worth fixing; many are not.
This commit is contained in:
parent
2ed544bd30
commit
2f2faeeab7
250
.pylintrc
250
.pylintrc
|
@ -1,250 +0,0 @@
|
||||||
# -*- conf -*-
|
|
||||||
[MASTER]
|
|
||||||
|
|
||||||
# Specify a configuration file.
|
|
||||||
#rcfile=
|
|
||||||
|
|
||||||
# Python code to execute, usually for sys.path manipulation such as
|
|
||||||
# pygtk.require().
|
|
||||||
#init-hook=
|
|
||||||
|
|
||||||
# Profiled execution.
|
|
||||||
profile=no
|
|
||||||
|
|
||||||
# Add files or directories to the blacklist. They should be base names, not
|
|
||||||
# paths.
|
|
||||||
ignore=datetime_tz
|
|
||||||
|
|
||||||
# Pickle collected data for later comparisons.
|
|
||||||
persistent=no
|
|
||||||
|
|
||||||
# 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).
|
|
||||||
disable=C0111,R0903,R0201,R0914,R0912,W0142,W0703,W0702
|
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
|
||||||
|
|
||||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
|
||||||
# (visual studio) and html
|
|
||||||
output-format=parseable
|
|
||||||
|
|
||||||
# Include message's id in output
|
|
||||||
include-ids=yes
|
|
||||||
|
|
||||||
# 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
|
|
||||||
reports=yes
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# Add a comment according to your evaluation note. This is used by the global
|
|
||||||
# evaluation report (RP0004).
|
|
||||||
comment=no
|
|
||||||
|
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
# When zope mode is activated, add a predefined set of Zope acquired attributes
|
|
||||||
# to generated-members.
|
|
||||||
zope=no
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
||||||
[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).
|
|
||||||
indent-string=' '
|
|
||||||
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
|
||||||
|
|
||||||
# List of note tags to take in consideration, separated by a comma.
|
|
||||||
notes=FIXME,XXX,TODO
|
|
||||||
|
|
||||||
|
|
||||||
[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 dummy variables
|
|
||||||
# (i.e. not used).
|
|
||||||
dummy-variables-rgx=_|dummy
|
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
|
||||||
# you should avoid to define new builtins when possible.
|
|
||||||
additional-builtins=
|
|
||||||
|
|
||||||
|
|
||||||
[BASIC]
|
|
||||||
|
|
||||||
# Required attributes for module, separated by a comma
|
|
||||||
required-attributes=
|
|
||||||
|
|
||||||
# List of builtins function names that should not be used, separated by a comma
|
|
||||||
bad-functions=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_]*)|(__.*__)|version)$
|
|
||||||
|
|
||||||
# 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_]{0,30}$
|
|
||||||
|
|
||||||
# Regular expression which should only match correct method names
|
|
||||||
method-rgx=[a-z_][a-z0-9_]{0,30}$
|
|
||||||
|
|
||||||
# Regular expression which should only match correct instance attribute names
|
|
||||||
attr-rgx=[a-z_][a-z0-9_]{0,30}$
|
|
||||||
|
|
||||||
# Regular expression which should only match correct argument names
|
|
||||||
argument-rgx=[a-z_][a-z0-9_]{0,30}$
|
|
||||||
|
|
||||||
# Regular expression which should only match correct variable names
|
|
||||||
variable-rgx=[a-z_][a-z0-9_]{0,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=__.*__
|
|
||||||
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
|
|
||||||
# List of interface methods to ignore, separated by a comma. This is used for
|
|
||||||
# instance to not check methods defines in Zope's Interface base class.
|
|
||||||
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
|
|
||||||
[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
|
|
9
Makefile
9
Makefile
|
@ -20,9 +20,11 @@ develop:
|
||||||
docs:
|
docs:
|
||||||
make -C docs
|
make -C docs
|
||||||
|
|
||||||
|
ctrl: flake
|
||||||
|
flake:
|
||||||
|
flake8 nilmdb
|
||||||
lint:
|
lint:
|
||||||
flake8 nilmdb --exclude=fsck.py,nilmdb_fsck.py
|
pylint3 --rcfile=setup.cfg nilmdb
|
||||||
ctrl: lint
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
ifneq ($(INSIDE_EMACS),)
|
ifneq ($(INSIDE_EMACS),)
|
||||||
|
@ -44,4 +46,5 @@ clean::
|
||||||
gitclean::
|
gitclean::
|
||||||
git clean -dXf
|
git clean -dXf
|
||||||
|
|
||||||
.PHONY: all version build dist sdist install docs lint test clean gitclean
|
.PHONY: all version build dist sdist install docs test
|
||||||
|
.PHONY: ctrl lint flake clean gitclean
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
"""Class for performing HTTP client requests via libcurl"""
|
"""Class for performing HTTP client requests via libcurl"""
|
||||||
|
|
||||||
import nilmdb.utils
|
|
||||||
import nilmdb.client.httpclient
|
|
||||||
from nilmdb.client.errors import ClientError
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
|
import nilmdb.utils
|
||||||
|
import nilmdb.client.httpclient
|
||||||
|
from nilmdb.client.errors import ClientError
|
||||||
from nilmdb.utils.time import timestamp_to_string, string_to_timestamp
|
from nilmdb.utils.time import timestamp_to_string, string_to_timestamp
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ def extract_timestamp(line):
|
||||||
return string_to_timestamp(line.split()[0])
|
return string_to_timestamp(line.split()[0])
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
class Client():
|
||||||
"""Main client interface to the Nilm database."""
|
"""Main client interface to the Nilm database."""
|
||||||
|
|
||||||
def __init__(self, url, post_json=False):
|
def __init__(self, url, post_json=False):
|
||||||
|
@ -250,7 +249,7 @@ class Client(object):
|
||||||
return int(counts[0])
|
return int(counts[0])
|
||||||
|
|
||||||
|
|
||||||
class StreamInserter(object):
|
class StreamInserter():
|
||||||
"""Object returned by stream_insert_context() that manages
|
"""Object returned by stream_insert_context() that manages
|
||||||
the insertion of rows of data into a particular path.
|
the insertion of rows of data into a particular path.
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
"""HTTP client library"""
|
"""HTTP client library"""
|
||||||
|
|
||||||
from nilmdb.client.errors import ClientError, ServerError, Error
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from nilmdb.client.errors import ClientError, ServerError, Error
|
||||||
|
|
||||||
class HTTPClient(object):
|
|
||||||
|
class HTTPClient():
|
||||||
"""Class to manage and perform HTTP requests from the client"""
|
"""Class to manage and perform HTTP requests from the client"""
|
||||||
def __init__(self, baseurl="", post_json=False, verify_ssl=True):
|
def __init__(self, baseurl="", post_json=False, verify_ssl=True):
|
||||||
"""If baseurl is supplied, all other functions that take
|
"""If baseurl is supplied, all other functions that take
|
||||||
|
@ -46,10 +46,10 @@ class HTTPClient(object):
|
||||||
args["traceback"] = jsonerror["traceback"]
|
args["traceback"] = jsonerror["traceback"]
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if code >= 400 and code <= 499:
|
if 400 <= code <= 499:
|
||||||
raise ClientError(**args)
|
raise ClientError(**args)
|
||||||
else:
|
else:
|
||||||
if code >= 500 and code <= 599:
|
if 500 <= code <= 599:
|
||||||
if args["message"] is None:
|
if args["message"] is None:
|
||||||
args["message"] = ("(no message; try disabling "
|
args["message"] = ("(no message; try disabling "
|
||||||
"response.stream option in "
|
"response.stream option in "
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
"""Provide a NumpyClient class that is based on normal Client, but has
|
"""Provide a NumpyClient class that is based on normal Client, but has
|
||||||
additional methods for extracting and inserting data via Numpy arrays."""
|
additional methods for extracting and inserting data via Numpy arrays."""
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
import numpy
|
||||||
|
|
||||||
import nilmdb.utils
|
import nilmdb.utils
|
||||||
import nilmdb.client.client
|
import nilmdb.client.client
|
||||||
import nilmdb.client.httpclient
|
import nilmdb.client.httpclient
|
||||||
from nilmdb.client.errors import ClientError
|
from nilmdb.client.errors import ClientError
|
||||||
|
|
||||||
import contextlib
|
|
||||||
|
|
||||||
import numpy
|
|
||||||
|
|
||||||
|
|
||||||
def layout_to_dtype(layout):
|
def layout_to_dtype(layout):
|
||||||
ltype = layout.split('_')[0]
|
ltype = layout.split('_')[0]
|
||||||
|
@ -151,7 +151,7 @@ class StreamInserterNumpy(nilmdb.client.client.StreamInserter):
|
||||||
|
|
||||||
def insert(self, array):
|
def insert(self, array):
|
||||||
"""Insert Numpy data, which must match the layout type."""
|
"""Insert Numpy data, which must match the layout type."""
|
||||||
if type(array) != numpy.ndarray:
|
if not isinstance(array, numpy.ndarray):
|
||||||
array = numpy.array(array)
|
array = numpy.array(array)
|
||||||
if array.ndim == 1:
|
if array.ndim == 1:
|
||||||
# Already a structured array; just verify the type
|
# Already a structured array; just verify the type
|
||||||
|
@ -251,7 +251,7 @@ class StreamInserterNumpy(nilmdb.client.client.StreamInserter):
|
||||||
# If we have no endpoints, or equal endpoints, it's OK as long
|
# If we have no endpoints, or equal endpoints, it's OK as long
|
||||||
# as there's no data to send
|
# as there's no data to send
|
||||||
if (start_ts is None or end_ts is None) or (start_ts == end_ts):
|
if (start_ts is None or end_ts is None) or (start_ts == end_ts):
|
||||||
if len(array) == 0:
|
if not array:
|
||||||
return
|
return
|
||||||
raise ClientError("have data to send, but invalid start/end times")
|
raise ClientError("have data to send, but invalid start/end times")
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
"""Command line client functionality"""
|
"""Command line client functionality"""
|
||||||
|
|
||||||
import nilmdb.client
|
|
||||||
|
|
||||||
from nilmdb.utils.printf import fprintf, sprintf
|
|
||||||
import datetime_tz
|
|
||||||
import nilmdb.utils.time
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
import argparse
|
import argparse
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
import signal
|
|
||||||
|
import nilmdb.client
|
||||||
|
from nilmdb.utils.printf import fprintf, sprintf
|
||||||
|
import nilmdb.utils.time
|
||||||
|
|
||||||
import argcomplete
|
import argcomplete
|
||||||
|
import datetime_tz
|
||||||
|
|
||||||
# Valid subcommands. Defined in separate files just to break
|
# Valid subcommands. Defined in separate files just to break
|
||||||
# things up -- they're still called with Cmdline as self.
|
# things up -- they're still called with Cmdline as self.
|
||||||
|
@ -39,7 +38,7 @@ class JimArgumentParser(argparse.ArgumentParser):
|
||||||
self.exit(2, sprintf("error: %s\n", message))
|
self.exit(2, sprintf("error: %s\n", message))
|
||||||
|
|
||||||
|
|
||||||
class Complete(object):
|
class Complete():
|
||||||
# Completion helpers, for using argcomplete (see
|
# Completion helpers, for using argcomplete (see
|
||||||
# extras/nilmtool-bash-completion.sh)
|
# extras/nilmtool-bash-completion.sh)
|
||||||
def escape(self, s):
|
def escape(self, s):
|
||||||
|
@ -86,7 +85,7 @@ class Complete(object):
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
class Cmdline(object):
|
class Cmdline():
|
||||||
|
|
||||||
def __init__(self, argv=None):
|
def __init__(self, argv=None):
|
||||||
self.argv = argv or sys.argv[1:]
|
self.argv = argv or sys.argv[1:]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import nilmdb.client
|
|
||||||
|
|
||||||
from argparse import RawDescriptionHelpFormatter as raw_form
|
from argparse import RawDescriptionHelpFormatter as raw_form
|
||||||
|
|
||||||
|
import nilmdb.client
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("create", help="Create a new stream",
|
cmd = sub.add_parser("create", help="Create a new stream",
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from nilmdb.utils.printf import printf
|
|
||||||
import nilmdb.client
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
|
from nilmdb.utils.printf import printf
|
||||||
|
import nilmdb.client
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("destroy", help="Delete a stream and all data",
|
cmd = sub.add_parser("destroy", help="Delete a stream and all data",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
import nilmdb.client
|
import nilmdb.client
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
import nilmdb.client
|
import nilmdb.client
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
from nilmdb.utils import human_size
|
from nilmdb.utils import human_size
|
||||||
|
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("info", help="Server information",
|
cmd = sub.add_parser("info", help="Server information",
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
import nilmdb.client
|
import nilmdb.client
|
||||||
import nilmdb.utils.timestamper as timestamper
|
import nilmdb.utils.timestamper as timestamper
|
||||||
import nilmdb.utils.time
|
import nilmdb.utils.time
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("insert", help="Insert data",
|
cmd = sub.add_parser("insert", help="Insert data",
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
import nilmdb.utils.time
|
import nilmdb.utils.time
|
||||||
from nilmdb.utils.interval import Interval
|
from nilmdb.utils.interval import Interval
|
||||||
|
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("intervals", help="List intervals",
|
cmd = sub.add_parser("intervals", help="List intervals",
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from nilmdb.utils.printf import printf
|
|
||||||
import nilmdb.utils.time
|
|
||||||
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
|
from nilmdb.utils.printf import printf
|
||||||
|
import nilmdb.utils.time
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("list", help="List streams",
|
cmd = sub.add_parser("list", help="List streams",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import fnmatch
|
||||||
|
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
import nilmdb.client
|
import nilmdb.client
|
||||||
import fnmatch
|
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import nilmdb.client
|
|
||||||
|
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
|
import nilmdb.client
|
||||||
|
|
||||||
|
|
||||||
def setup(self, sub):
|
def setup(self, sub):
|
||||||
cmd = sub.add_parser("rename", help="Rename a stream",
|
cmd = sub.add_parser("rename", help="Rename a stream",
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import nilmdb.server
|
|
||||||
import argparse
|
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
import cherrypy
|
|
||||||
import sys
|
import sys
|
||||||
|
import socket
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
|
import nilmdb.server
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
# Fixed record size bulk data storage
|
# Fixed record size bulk data storage
|
||||||
|
|
||||||
# Need absolute_import so that "import nilmdb" won't pull in
|
import os
|
||||||
# nilmdb.py, but will pull the parent nilmdb module instead.
|
import re
|
||||||
|
import sys
|
||||||
|
import pickle
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from nilmdb.utils.printf import sprintf
|
from nilmdb.utils.printf import sprintf
|
||||||
from nilmdb.utils.time import timestamp_to_string
|
from nilmdb.utils.time import timestamp_to_string
|
||||||
import nilmdb.utils
|
import nilmdb.utils
|
||||||
|
|
||||||
import os
|
|
||||||
import pickle
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
import nilmdb.utils.lock
|
import nilmdb.utils.lock
|
||||||
from . import rocket
|
from . import rocket
|
||||||
|
|
||||||
|
@ -24,7 +20,7 @@ fd_cache_size = 8
|
||||||
|
|
||||||
|
|
||||||
@nilmdb.utils.must_close(wrap_verify=False)
|
@nilmdb.utils.must_close(wrap_verify=False)
|
||||||
class BulkData(object):
|
class BulkData():
|
||||||
def __init__(self, basepath, **kwargs):
|
def __init__(self, basepath, **kwargs):
|
||||||
if isinstance(basepath, str):
|
if isinstance(basepath, str):
|
||||||
self.basepath = self._encode_filename(basepath)
|
self.basepath = self._encode_filename(basepath)
|
||||||
|
@ -93,7 +89,7 @@ class BulkData(object):
|
||||||
# Look for any files in subdirectories. Fully empty subdirectories
|
# Look for any files in subdirectories. Fully empty subdirectories
|
||||||
# are OK; they might be there during a rename
|
# are OK; they might be there during a rename
|
||||||
for (root, dirs, files) in os.walk(ospath):
|
for (root, dirs, files) in os.walk(ospath):
|
||||||
if len(files):
|
if files:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"non-empty subdirs of this path already exist")
|
"non-empty subdirs of this path already exist")
|
||||||
|
|
||||||
|
@ -265,7 +261,7 @@ class BulkData(object):
|
||||||
|
|
||||||
|
|
||||||
@nilmdb.utils.must_close(wrap_verify=False)
|
@nilmdb.utils.must_close(wrap_verify=False)
|
||||||
class Table(object):
|
class Table():
|
||||||
"""Tools to help access a single table (data at a specific OS path)."""
|
"""Tools to help access a single table (data at a specific OS path)."""
|
||||||
# See design.md for design details
|
# See design.md for design details
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,9 @@ Object that represents a NILM database file.
|
||||||
Manages both the SQL database and the table storage backend.
|
Manages both the SQL database and the table storage backend.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Need absolute_import so that "import nilmdb" won't pull in
|
import os
|
||||||
# nilmdb.py, but will pull the parent nilmdb module instead.
|
import errno
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
import nilmdb.utils
|
import nilmdb.utils
|
||||||
from nilmdb.utils.printf import printf
|
from nilmdb.utils.printf import printf
|
||||||
|
@ -20,10 +21,6 @@ from nilmdb.server.interval import Interval, DBInterval, IntervalSet
|
||||||
from nilmdb.server import bulkdata
|
from nilmdb.server import bulkdata
|
||||||
from nilmdb.server.errors import NilmDBError, StreamError, OverlapError
|
from nilmdb.server.errors import NilmDBError, StreamError, OverlapError
|
||||||
|
|
||||||
import sqlite3
|
|
||||||
import os
|
|
||||||
import errno
|
|
||||||
|
|
||||||
# Note about performance and transactions:
|
# Note about performance and transactions:
|
||||||
#
|
#
|
||||||
# Committing a transaction in the default sync mode (PRAGMA synchronous=FULL)
|
# Committing a transaction in the default sync mode (PRAGMA synchronous=FULL)
|
||||||
|
@ -80,7 +77,7 @@ _sql_schema_updates = {
|
||||||
|
|
||||||
|
|
||||||
@nilmdb.utils.must_close()
|
@nilmdb.utils.must_close()
|
||||||
class NilmDB(object):
|
class NilmDB():
|
||||||
verbose = 0
|
verbose = 0
|
||||||
|
|
||||||
def __init__(self, basepath,
|
def __init__(self, basepath,
|
||||||
|
@ -462,7 +459,7 @@ class NilmDB(object):
|
||||||
|
|
||||||
# Verify that no intervals are present, and clear the cache
|
# Verify that no intervals are present, and clear the cache
|
||||||
iset = self._get_intervals(stream_id)
|
iset = self._get_intervals(stream_id)
|
||||||
if len(iset):
|
if iset:
|
||||||
raise NilmDBError("all intervals must be removed before "
|
raise NilmDBError("all intervals must be removed before "
|
||||||
"destroying a stream")
|
"destroying a stream")
|
||||||
self._get_intervals.cache_remove(self, stream_id)
|
self._get_intervals.cache_remove(self, stream_id)
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
"""CherryPy-based server for accessing NILM database via HTTP"""
|
"""CherryPy-based server for accessing NILM database via HTTP"""
|
||||||
|
|
||||||
# Need absolute_import so that "import nilmdb" won't pull in
|
import os
|
||||||
# nilmdb.py, but will pull the nilmdb module instead.
|
import json
|
||||||
|
import socket
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
import nilmdb.server
|
import nilmdb.server
|
||||||
from nilmdb.utils.printf import sprintf
|
from nilmdb.utils.printf import sprintf
|
||||||
from nilmdb.server.errors import NilmDBError
|
from nilmdb.server.errors import NilmDBError
|
||||||
from nilmdb.utils.time import string_to_timestamp
|
from nilmdb.utils.time import string_to_timestamp
|
||||||
|
|
||||||
import cherrypy
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import json
|
|
||||||
import psutil
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
from nilmdb.server.serverutil import (
|
from nilmdb.server.serverutil import (
|
||||||
chunked_response,
|
chunked_response,
|
||||||
response_type,
|
response_type,
|
||||||
|
@ -31,7 +29,7 @@ from nilmdb.server.serverutil import (
|
||||||
cherrypy.tools.CORS_allow = cherrypy.Tool('on_start_resource', CORS_allow)
|
cherrypy.tools.CORS_allow = cherrypy.Tool('on_start_resource', CORS_allow)
|
||||||
|
|
||||||
|
|
||||||
class NilmApp(object):
|
class NilmApp():
|
||||||
def __init__(self, db):
|
def __init__(self, db):
|
||||||
self.db = db
|
self.db = db
|
||||||
|
|
||||||
|
@ -39,10 +37,6 @@ class NilmApp(object):
|
||||||
# CherryPy apps
|
# CherryPy apps
|
||||||
class Root(NilmApp):
|
class Root(NilmApp):
|
||||||
"""Root application for NILM database"""
|
"""Root application for NILM database"""
|
||||||
|
|
||||||
def __init__(self, db):
|
|
||||||
super(Root, self).__init__(db)
|
|
||||||
|
|
||||||
# /
|
# /
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
|
@ -190,9 +184,7 @@ class Stream(NilmApp):
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
raise NilmDBError("can't parse 'data' parameter: " + str(e))
|
raise NilmDBError("can't parse 'data' parameter: " + str(e))
|
||||||
for key in data:
|
for key in data:
|
||||||
if not (isinstance(data[key], str) or
|
if not isinstance(data[key], (str, float, int)):
|
||||||
isinstance(data[key], float) or
|
|
||||||
isinstance(data[key], int)):
|
|
||||||
raise NilmDBError("metadata values must be a string or number")
|
raise NilmDBError("metadata values must be a string or number")
|
||||||
function(path, data)
|
function(path, data)
|
||||||
|
|
||||||
|
@ -400,7 +392,7 @@ class Stream(NilmApp):
|
||||||
return content(start, end)
|
return content(start, end)
|
||||||
|
|
||||||
|
|
||||||
class Exiter(object):
|
class Exiter():
|
||||||
"""App that exits the server, for testing"""
|
"""App that exits the server, for testing"""
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
|
@ -414,7 +406,7 @@ class Exiter(object):
|
||||||
index._cp_config = {'response.stream': True}
|
index._cp_config = {'response.stream': True}
|
||||||
|
|
||||||
|
|
||||||
class Server(object):
|
class Server():
|
||||||
def __init__(self, db, host='127.0.0.1', port=8080,
|
def __init__(self, db, host='127.0.0.1', port=8080,
|
||||||
stoppable=False, # whether /exit URL exists
|
stoppable=False, # whether /exit URL exists
|
||||||
fast_shutdown=False, # don't wait for clients to disconn.
|
fast_shutdown=False, # don't wait for clients to disconn.
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
"""Miscellaneous decorators and other helpers for running a CherryPy
|
"""Miscellaneous decorators and other helpers for running a CherryPy
|
||||||
server"""
|
server"""
|
||||||
|
|
||||||
import cherrypy
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import decorator
|
import sys
|
||||||
import json
|
import json
|
||||||
|
import decorator
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
|
|
||||||
# Helper to parse parameters into booleans
|
# Helper to parse parameters into booleans
|
||||||
def bool_param(s):
|
def bool_param(s):
|
||||||
|
@ -130,11 +131,12 @@ def json_error_page(status, message, traceback, version,
|
||||||
"""Return a custom error page in JSON so the client can parse it"""
|
"""Return a custom error page in JSON so the client can parse it"""
|
||||||
errordata = {"status": status,
|
errordata = {"status": status,
|
||||||
"message": message,
|
"message": message,
|
||||||
|
"version": version,
|
||||||
"traceback": traceback}
|
"traceback": traceback}
|
||||||
# Don't send a traceback if the error was 400-499 (client's fault)
|
# Don't send a traceback if the error was 400-499 (client's fault)
|
||||||
code = int(status.split()[0])
|
code = int(status.split()[0])
|
||||||
if not force_traceback:
|
if not force_traceback:
|
||||||
if code >= 400 and code <= 499:
|
if 400 <= code <= 499:
|
||||||
errordata["traceback"] = ""
|
errordata["traceback"] = ""
|
||||||
# Override the response type, which was previously set to text/html
|
# Override the response type, which was previously set to text/html
|
||||||
cherrypy.serving.response.headers['Content-Type'] = (
|
cherrypy.serving.response.headers['Content-Type'] = (
|
||||||
|
|
|
@ -7,15 +7,15 @@ def human_size(num):
|
||||||
"""Human friendly file size"""
|
"""Human friendly file size"""
|
||||||
unit_list = list(zip(['bytes', 'kiB', 'MiB', 'GiB', 'TiB'],
|
unit_list = list(zip(['bytes', 'kiB', 'MiB', 'GiB', 'TiB'],
|
||||||
[0, 0, 1, 2, 2]))
|
[0, 0, 1, 2, 2]))
|
||||||
if num > 1:
|
if num == 0:
|
||||||
exponent = min(int(log(num, 1024)), len(unit_list) - 1)
|
return '0 bytes'
|
||||||
quotient = float(num) / 1024**exponent
|
if num == 1:
|
||||||
unit, num_decimals = unit_list[exponent]
|
|
||||||
format_string = '{:.%sf} {}' % (num_decimals)
|
|
||||||
return format_string.format(quotient, unit)
|
|
||||||
elif num == 1:
|
|
||||||
return '1 byte'
|
return '1 byte'
|
||||||
return '0 bytes'
|
exponent = min(int(log(num, 1024)), len(unit_list) - 1)
|
||||||
|
quotient = float(num) / 1024**exponent
|
||||||
|
unit, num_decimals = unit_list[exponent]
|
||||||
|
format_string = '{:.%sf} {}' % (num_decimals)
|
||||||
|
return format_string.format(quotient, unit)
|
||||||
|
|
||||||
|
|
||||||
def du(path):
|
def du(path):
|
||||||
|
|
|
@ -19,8 +19,8 @@ def imerge(*iterables):
|
||||||
h_append = h.append
|
h_append = h.append
|
||||||
for it in map(iter, iterables):
|
for it in map(iter, iterables):
|
||||||
try:
|
try:
|
||||||
next = it.__next__
|
nexter = it.__next__
|
||||||
h_append([next(), next])
|
h_append([nexter(), nexter])
|
||||||
except _Stop:
|
except _Stop:
|
||||||
pass
|
pass
|
||||||
heapq.heapify(h)
|
heapq.heapify(h)
|
||||||
|
@ -28,9 +28,9 @@ def imerge(*iterables):
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
while 1:
|
while 1:
|
||||||
v, next = s = h[0] # raises IndexError when h is empty
|
v, nexter = s = h[0] # raises IndexError when h is empty
|
||||||
yield v
|
yield v
|
||||||
s[0] = next() # raises StopIteration when exhausted
|
s[0] = nexter() # raises StopIteration when exhausted
|
||||||
siftup(h, 0) # restore heap condition
|
siftup(h, 0) # restore heap condition
|
||||||
except _Stop:
|
except _Stop:
|
||||||
heappop(h) # remove empty iterator
|
heappop(h) # remove empty iterator
|
||||||
|
|
|
@ -54,7 +54,7 @@ def lru_cache(size=10, onremove=None, keys=slice(None)):
|
||||||
if key in cache:
|
if key in cache:
|
||||||
evict(cache.pop(key))
|
evict(cache.pop(key))
|
||||||
else:
|
else:
|
||||||
if len(cache) > 0:
|
if cache:
|
||||||
if len(args) != len(next(iter(cache.keys()))):
|
if len(args) != len(next(iter(cache.keys()))):
|
||||||
raise KeyError("trying to remove from LRU cache, but "
|
raise KeyError("trying to remove from LRU cache, but "
|
||||||
"number of arguments doesn't match the "
|
"number of arguments doesn't match the "
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from nilmdb.utils.printf import fprintf
|
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
import decorator
|
import decorator
|
||||||
|
from nilmdb.utils.printf import fprintf
|
||||||
|
|
||||||
|
|
||||||
def must_close(errorfile=sys.stderr, wrap_verify=False):
|
def must_close(errorfile=sys.stderr, wrap_verify=False):
|
||||||
|
|
|
@ -47,7 +47,7 @@ def serializer_proxy(obj_or_type):
|
||||||
The proxied requests, including instantiation, are performed in a
|
The proxied requests, including instantiation, are performed in a
|
||||||
single thread and serialized between caller threads.
|
single thread and serialized between caller threads.
|
||||||
"""
|
"""
|
||||||
class SerializerCallProxy(object):
|
class SerializerCallProxy():
|
||||||
def __init__(self, call_queue, func, objectproxy):
|
def __init__(self, call_queue, func, objectproxy):
|
||||||
self.call_queue = call_queue
|
self.call_queue = call_queue
|
||||||
self.func = func
|
self.func = func
|
||||||
|
@ -64,10 +64,10 @@ def serializer_proxy(obj_or_type):
|
||||||
else:
|
else:
|
||||||
raise exc_info[1].with_traceback(exc_info[2])
|
raise exc_info[1].with_traceback(exc_info[2])
|
||||||
|
|
||||||
class SerializerObjectProxy(object):
|
class SerializerObjectProxy():
|
||||||
def __init__(self, obj_or_type, *args, **kwargs):
|
def __init__(self, obj_or_type, *args, **kwargs):
|
||||||
self.__object = obj_or_type
|
self.__object = obj_or_type
|
||||||
if type(obj_or_type) == type:
|
if isinstance(obj_or_type, type):
|
||||||
classname = obj_or_type.__name__
|
classname = obj_or_type.__name__
|
||||||
else:
|
else:
|
||||||
classname = obj_or_type.__class__.__name__
|
classname = obj_or_type.__class__.__name__
|
||||||
|
@ -118,7 +118,7 @@ def serializer_proxy(obj_or_type):
|
||||||
to serializer_proxy. Otherwise, pass the call through."""
|
to serializer_proxy. Otherwise, pass the call through."""
|
||||||
ret = SerializerCallProxy(self.__call_queue,
|
ret = SerializerCallProxy(self.__call_queue,
|
||||||
self.__object, self)(*args, **kwargs)
|
self.__object, self)(*args, **kwargs)
|
||||||
if type(self.__object) == type:
|
if isinstance(self.__object, type):
|
||||||
# Instantiation
|
# Instantiation
|
||||||
self.__object = ret
|
self.__object = ret
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from nilmdb.utils.printf import sprintf
|
|
||||||
import threading
|
import threading
|
||||||
|
from nilmdb.utils.printf import sprintf
|
||||||
|
|
||||||
|
|
||||||
def verify_proxy(obj_or_type, check_thread=True,
|
def verify_proxy(obj_or_type, check_thread=True,
|
||||||
|
@ -16,10 +16,10 @@ def verify_proxy(obj_or_type, check_thread=True,
|
||||||
check_concurrent = True # Fail if two functions are concurrently
|
check_concurrent = True # Fail if two functions are concurrently
|
||||||
# run through this proxy
|
# run through this proxy
|
||||||
"""
|
"""
|
||||||
class Namespace(object):
|
class Namespace():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class VerifyCallProxy(object):
|
class VerifyCallProxy():
|
||||||
def __init__(self, func, parent_namespace):
|
def __init__(self, func, parent_namespace):
|
||||||
self.func = func
|
self.func = func
|
||||||
self.parent_namespace = parent_namespace
|
self.parent_namespace = parent_namespace
|
||||||
|
@ -63,7 +63,7 @@ def verify_proxy(obj_or_type, check_thread=True,
|
||||||
p.concur_lock.release()
|
p.concur_lock.release()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
class VerifyObjectProxy(object):
|
class VerifyObjectProxy():
|
||||||
def __init__(self, obj_or_type, *args, **kwargs):
|
def __init__(self, obj_or_type, *args, **kwargs):
|
||||||
p = Namespace()
|
p = Namespace()
|
||||||
self.__ns = p
|
self.__ns = p
|
||||||
|
@ -73,7 +73,7 @@ def verify_proxy(obj_or_type, check_thread=True,
|
||||||
p.concur_tname = None
|
p.concur_tname = None
|
||||||
p.concur_callee = None
|
p.concur_callee = None
|
||||||
self.__obj = obj_or_type
|
self.__obj = obj_or_type
|
||||||
if type(obj_or_type) in (type, type):
|
if isinstance(obj_or_type, type):
|
||||||
p.classname = self.__obj.__name__
|
p.classname = self.__obj.__name__
|
||||||
else:
|
else:
|
||||||
p.classname = self.__obj.__class__.__name__
|
p.classname = self.__obj.__class__.__name__
|
||||||
|
@ -88,7 +88,7 @@ def verify_proxy(obj_or_type, check_thread=True,
|
||||||
"""Call this to instantiate the type, if a type was passed
|
"""Call this to instantiate the type, if a type was passed
|
||||||
to verify_proxy. Otherwise, pass the call through."""
|
to verify_proxy. Otherwise, pass the call through."""
|
||||||
ret = VerifyCallProxy(self.__obj, self.__ns)(*args, **kwargs)
|
ret = VerifyCallProxy(self.__obj, self.__ns)(*args, **kwargs)
|
||||||
if type(self.__obj) in (type, type):
|
if isinstance(self.__obj, type):
|
||||||
# Instantiation
|
# Instantiation
|
||||||
self.__obj = ret
|
self.__obj = ret
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import datetime_tz
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
import datetime_tz
|
||||||
|
|
||||||
# Range
|
# Range
|
||||||
min_timestamp = (-2**63)
|
min_timestamp = (-2**63)
|
||||||
|
@ -10,15 +10,15 @@ max_timestamp = (2**63 - 1)
|
||||||
epsilon = 1
|
epsilon = 1
|
||||||
|
|
||||||
|
|
||||||
def string_to_timestamp(str):
|
def string_to_timestamp(string):
|
||||||
"""Convert a string that represents an integer number of microseconds
|
"""Convert a string that represents an integer number of microseconds
|
||||||
since epoch."""
|
since epoch."""
|
||||||
try:
|
try:
|
||||||
# Parse a string like "1234567890123456" and return an integer
|
# Parse a string like "1234567890123456" and return an integer
|
||||||
return int(str)
|
return int(string)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# Try parsing as a float, in case it's "1234567890123456.0"
|
# Try parsing as a float, in case it's "1234567890123456.0"
|
||||||
return int(round(float(str)))
|
return int(round(float(string)))
|
||||||
|
|
||||||
|
|
||||||
def timestamp_to_string(timestamp):
|
def timestamp_to_string(timestamp):
|
||||||
|
@ -108,9 +108,9 @@ def parse_time(toparse):
|
||||||
try:
|
try:
|
||||||
val = float(toparse)
|
val = float(toparse)
|
||||||
# range is from about year 2001 - 2128
|
# range is from about year 2001 - 2128
|
||||||
if val > 1e9 and val < 5e9:
|
if 1e9 < val < 5e9:
|
||||||
return unix_to_timestamp(val)
|
return unix_to_timestamp(val)
|
||||||
if val > 1e15 and val < 5e15:
|
if 1e15 < val < 5e15:
|
||||||
return val
|
return val
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -4,7 +4,7 @@ from nilmdb.utils.printf import sprintf
|
||||||
import nilmdb.utils.time
|
import nilmdb.utils.time
|
||||||
|
|
||||||
|
|
||||||
class Timestamper(object):
|
class Timestamper():
|
||||||
"""A file-like object that adds timestamps to lines of an input file."""
|
"""A file-like object that adds timestamps to lines of an input file."""
|
||||||
def __init__(self, infile, ts_iter):
|
def __init__(self, infile, ts_iter):
|
||||||
"""file: filename, or another file-like object
|
"""file: filename, or another file-like object
|
||||||
|
|
|
@ -47,5 +47,10 @@ tag_prefix=nilmdb-
|
||||||
parentdir_prefix=nilmdb-
|
parentdir_prefix=nilmdb-
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
|
exclude=_version.py,fsck.py,nilmdb_fsck.py
|
||||||
extend-ignore=E731
|
extend-ignore=E731
|
||||||
per-file-ignores=__init__.py:F401,E402 serializer.py:E722 mustclose.py:E722
|
per-file-ignores=__init__.py:F401,E402 serializer.py:E722 mustclose.py:E722
|
||||||
|
|
||||||
|
[pylint]
|
||||||
|
ignore=_version.py,fsck.py,nilmdb_fsck.py
|
||||||
|
disable=C0103,C0111,R0913,R0914
|
||||||
|
|
Loading…
Reference in New Issue
Block a user