Skip to content

Commit

Permalink
Data import cmd and data obj class abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
dmpetrov committed Mar 6, 2017
1 parent 02be93b commit a9305d5
Show file tree
Hide file tree
Showing 12 changed files with 485 additions and 47 deletions.
3 changes: 3 additions & 0 deletions bin/nlx-data-import
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

PYTHONPATH=$NEATLYNX_HOME python $NEATLYNX_HOME/neatlynx/cmd_data_import.py $@
2 changes: 1 addition & 1 deletion bin/nlx-init
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

python $NEATLYNX_HOME/lib/cmd_init.py $@
PYTHONPATH=$NEATLYNX_HOME python $NEATLYNX_HOME/neatlynx/cmd_init.py $@
Empty file added neatlynx/__init__.py
Empty file.
40 changes: 9 additions & 31 deletions neatlynx/base_cmd.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import configparser
import argparse
import os
import git
import subprocess

from neatlynx.exceptions import GitCmdError, ConfigError
from neatlynx.git_wrapper import GitWrapper
from neatlynx.config import Config, ConfigError


class Logger(object):
@staticmethod
Expand All @@ -21,16 +20,13 @@ def error(msg):


class BaseCmd(object):
CONFIG = 'neatlynx.conf'

def __init__(self, parse_config=True):
self._git_dir = None
self._git = GitWrapper()
self._args = None
self._lnx_home = None

if parse_config:
self._config = configparser.ConfigParser()
self._config.read(os.path.join(self.git_dir, self.CONFIG))
self._config = Config(os.path.join(self.git.git_dir, self.CONFIG))

parser = argparse.ArgumentParser()
self.define_args(parser)
Expand All @@ -53,31 +49,13 @@ def args(self):
return self._args

@property
def git_dir(self):
if self._git_dir:
return self._git_dir

try:
p = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = map(lambda s: s.decode().strip('\n\r'), p.communicate())

if p.returncode != 0:
raise GitCmdError('Git command error - {}'.format(err))

self._git_dir = out
return self._git_dir
except GitCmdError as e:
raise
except Exception as e:
raise GitCmdError('Unable to run git command: {}'.format(e))
pass
def git(self):
return self._git

def define_args(self):
pass

def add_string_arg(self, parser, name, default, message,
def add_string_arg(self, parser, name, message, default = None,
conf_section=None, conf_name=None):
if conf_section and conf_name:
section = self._config[conf_section]
Expand All @@ -93,4 +71,4 @@ def add_string_arg(self, parser, name, default, message,
help=message)

def run(self):
pass
pass
81 changes: 81 additions & 0 deletions neatlynx/cmd_data_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import sys
import os
from pathlib import Path
from shutil import copyfile

from neatlynx.base_cmd import BaseCmd, Logger
from neatlynx.data_file_obj import DataFileObj
from neatlynx.exceptions import NeatLynxException
from neatlynx.git_wrapper import GitWrapper


class DataImportError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, 'Import error: {}'.format(msg))


class DataImport(BaseCmd):
def __init__(self):
BaseCmd.__init__(self)
pass

def define_args(self, parser):
self.add_string_arg(parser, 'input', 'Input file')
self.add_string_arg(parser, 'output', 'Output file')
pass

def run(self):
input = Path(self.args.input)
if not input.exists():
raise DataImportError('Input file "{}" does not exist'.format(input))
if not input.is_file():
raise DataImportError('Input file "{}" has to be a regular file'.format(input))

dataFileObj = DataFileObj(self.args.output, self._config, GitWrapper.curr_commit())

#output = Path(self.args.output)
if dataFileObj.data_file_relative.exists():
raise DataImportError('Output file "{}" already exists'.format(dataFileObj.data_file_relative))
if os.path.isdir(dataFileObj.data_dir_relative):
raise DataImportError('Output file directory "{}" does not exists'.format(dataFileObj.data_dir_relative))

data_dir_path = Path(self.config.DataDir)
if output.parent < data_dir_path:
raise DataImportError('Output file has to be in data dir - {}'.format(data_dir_path))

# data_dir_path_str = str(data_dir_path)
# output_dir_str = str(output.parent)
# relative_dir = output_dir_str[len(data_dir_path_str):].strip(os.path.sep)
#
# cache_file_dir = os.path.join(self.config.CachDir, relative_dir)
# cache_file_dir_path = Path(cache_file_dir)
#
# state_file_dir = os.path.join(self.config.StateDir, relative_dir)
# state_file_dir_path = Path(state_file_dir)
#
# commit = GitWrapper.curr_commit()
# cache_file_name = output.name + '_' + commit
# cache_file = cache_file_dir_path / cache_file_name
# state_file = state_file_dir_path / output.name

# Perform actions
cache_file.parent.mkdir(parents=True, exist_ok=True)
state_file.parent.mkdir(parents=True, exist_ok=True)

copyfile(self.args.input, str(cache_file))
Logger.verbose('Input file "{}" was copied to cache "{}"'.format(self.args.input, cache_file))

output.symlink_to(cache_file)
Logger.verbose('Symlink from data file "{}" the cache file "{}" was created'.
format(output, cache_file))

StateFile.create(state_file, input, output.absolute(), cache_file.absolute())
pass


if __name__ == '__main__':
try:
sys.exit(DataImport().run())
except NeatLynxException as e:
Logger.error(e)
sys.exit(1)
11 changes: 6 additions & 5 deletions neatlynx/cmd_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path

from neatlynx.base_cmd import BaseCmd, Logger
from neatlynx.config import Config
from neatlynx.exceptions import NeatLynxException


Expand Down Expand Up @@ -46,19 +47,19 @@ def __init__(self):
pass

def define_args(self, parser):
self.add_string_arg(parser, '--data-dir', 'data', 'NeatLynx data directory')
self.add_string_arg(parser, '--cache-dir', 'cache', 'NeatLynx cache directory')
self.add_string_arg(parser, '--state-dir', 'state', 'NeatLynx state directory')
self.add_string_arg(parser, '--data-dir', 'NeatLynx data directory', 'data')
self.add_string_arg(parser, '--cache-dir', 'NeatLynx cache directory', 'cache')
self.add_string_arg(parser, '--state-dir', 'NeatLynx state directory', 'state')
pass

def get_not_existing_dir(self, dir):
path = Path(os.path.join(self.git_dir, dir))
path = Path(os.path.join(self.git.git_dir, dir))
if path.exists():
raise InitError('Directory "{}" already exist'.format(path.name))
return path

def get_not_existing_conf_file(self):
path = Path(os.path.join(self.git_dir, self.CONFIG))
path = Path(os.path.join(self.git.git_dir, Config.CONFIG))
if path.exists():
raise InitError('Configuration file "{}" already exist'.format(path.name))
return path
Expand Down
59 changes: 59 additions & 0 deletions neatlynx/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import os
import configparser

from neatlynx.exceptions import NeatLynxException


class ConfigError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, 'Config file error: {}'.format(msg))


class ConfigI(object):
def __init__(self, data_dir, cache_dir, state_dir):
self._data_dir = data_dir
self._cache_dir = cache_dir
self._state_dir = state_dir
pass

@property
def data_dir(self):
return self._data_dir

@property
def cache_dir(self):
return self._cache_dir

@property
def state_dir(self):
return self._state_dir


class Config(ConfigI):
CONFIG = 'neatlynx.conf'

def __init__(self, git_dir, file=None, data_dir=None, cache_dir=None, state_dir=None):
self._config = configparser.ConfigParser()
self._config.read(os.path.join(git_dir, self.CONFIG))

self._global = self._config['Global']

self._data_dir = self._global['DataDir']
self._cache_dir = self._global['CacheDir']
self._state_dir = self._global['StateDir']
pass

# def get_data_file_obj(self):
# return DataFileObj(self.config)

@property
def data_dir(self):
return self._data_dir

@property
def cache_dir(self):
return self._cache_dir

@property
def state_dir(self):
return self._state_dir
104 changes: 104 additions & 0 deletions neatlynx/data_file_obj.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import os

from neatlynx.exceptions import NeatLynxException


class DataFilePathError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, 'Data file error: {}'.format(msg))


class NotInDataDirError(NeatLynxException):
def __init__(self):
NeatLynxException.__init__(self, 'Data file location error: the file has to be in the data directory')


class DataFileObj(object):
STATE_FILE_SUFFIX = '.state'
CACHE_FILE_SEP = '_'

def __init__(self, data_file, git, config):
self._git = git
self._config = config

data_file = os.path.realpath(data_file)

self._data_file_name = os.path.basename(data_file)
data_file_dir = os.path.realpath(os.path.dirname(data_file))

data_dir = os.path.join(self._git.git_dir_abs, config.data_dir)
self._rel_path = os.path.relpath(data_file_dir, data_dir)

if not data_file_dir.startswith(data_dir):
raise NotInDataDirError()

if self._rel_path == '.':
self._rel_path = ''
pass

# Data file properties
@property
def data_file_name(self):
return self._data_file_name

@property
def data_file_nlx(self):
return os.path.join(self._config.data_dir, self._rel_path, self.data_file_name)

@property
def data_file_abs(self):
return os.path.join(self._git.git_dir_abs, self.data_file_nlx)

@property
def data_file_relative(self):
return os.path.relpath(self.data_file_abs, self._git.git_dir_abs())

@property
def data_dir_relative(self):
return os.path.basename(self.data_file_relative)

# Cache file properties
@property
def cache_file_name(self):
if not self._git.curr_commit:
return None
return self.data_file_name + self.CACHE_FILE_SEP + self._git.curr_commit

@property
def cache_file_nlx(self):
if not self._git.curr_commit:
return None
return os.path.join(self._config.cache_dir, self._rel_path, self.cache_file_name)

@property
def cache_file_abs(self):
return os.path.join(self._git.git_dir_abs, self.cache_file_nlx)

@property
def cache_file_relative(self):
return os.path.relpath(self.cache_file_abs, self._git.git_dir_abs)

@property
def cache_dir_relative(self):
return os.path.basename(self.cache_file_relative)

# State file properties
@property
def state_file_name(self):
return self.data_file_name + self.STATE_FILE_SUFFIX

@property
def state_file_nlx(self):
return os.path.join(self._config.state_dir, self._rel_path, self.state_file_name)

@property
def state_file_abs(self):
return os.path.join(self._git.git_dir_abs, self.state_file_nlx)

@property
def state_file_relative(self):
return os.path.relpath(self.state_file_abs, self._git.git_dir_abs)

@property
def state_dir_relative(self):
return os.path.basename(self.state_file_relative)
10 changes: 0 additions & 10 deletions neatlynx/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
class NeatLynxException(Exception):
def __init__(self, msg):
Exception.__init__(self, msg)


class GitCmdError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, msg)


class ConfigError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, 'Config file error: {}'.format(msg))
Loading

0 comments on commit a9305d5

Please sign in to comment.