diff --git a/external_file_location/.location.py.swp b/external_file_location/.location.py.swp new file mode 100644 index 00000000..5edb09b8 Binary files /dev/null and b/external_file_location/.location.py.swp differ diff --git a/external_file_location/.task.py.swp b/external_file_location/.task.py.swp new file mode 100644 index 00000000..5b9a1957 Binary files /dev/null and b/external_file_location/.task.py.swp differ diff --git a/external_file_location/backend.py b/external_file_location/backend.py index 7555f125..d01c4793 100755 --- a/external_file_location/backend.py +++ b/external_file_location/backend.py @@ -2,33 +2,37 @@ # -*- coding: utf-8 -*- -class AbstractConnection(object): +#class AbstractConnection(object): +# +# def __init__(self, host, user, pwd, port=None, allow_dir_creation=False): +# self.host = host +# self.user = user +# self.pwd = pwd +# self.port = port +# self.allow_dir_creation = allow_dir_creation +# self.connection = None +# +# def connect(self): +# return NotImplemented +# +# def close(self): +# return NotImplemented +# +# def get(self, filename, path=None): +# return NotImplemented +# +# def put(self, fileobject, filename, path=None): +# return NotImplemented +# +# def search(self, filename, path=None): +# return NotImplemented +# +# def move(self, filename, oldpath, newpath): +# return NotImplemented +# +# def rename(self, oldfilename, newfilename, path=None): +# return NotImplemented - def __init__(self, host, user, pwd, port=None, allow_dir_creation=False): - self.host = host - self.user = user - self.pwd = pwd - self.port = port - self.allow_dir_creation = allow_dir_creation - self.connection = None +class AbstractTask(): - def connect(self): - return NotImplemented - - def close(self): - return NotImplemented - - def get(self, filename, path=None): - return NotImplemented - - def put(self, fileobject, filename, path=None): - return NotImplemented - - def search(self, filename, path=None): - return NotImplemented - - def move(self, filename, oldpath, newpath): - return NotImplemented - - def rename(self, oldfilename, newfilename, path=None): - return NotImplemented + diff --git a/external_file_location/backends/.filestore.py.swo b/external_file_location/backends/.filestore.py.swo new file mode 100644 index 00000000..65c54ea1 Binary files /dev/null and b/external_file_location/backends/.filestore.py.swo differ diff --git a/external_file_location/backends/filestore.py b/external_file_location/backends/filestore.py index febd353b..302fc733 100755 --- a/external_file_location/backends/filestore.py +++ b/external_file_location/backends/filestore.py @@ -1,24 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from ..backend import AbstractConnection +from ..backend import AbstractTask import sys import os from tempfile import TemporaryFile -class AbtractTask() - def __init__(self, cr, uid): - - - -class FileStoreConnection(AbstractTask): +class FileStore(AbstractTask): _key = "filestore" _name = "Filestore" _synchronize_type = None - def __init__(self, host, user, pwd, port=None, allow_dir_creation=False): - super(FilestoreConnection, self).__init__(host, user, pwd, port, allow_dir_creation) + def __init__(self, config): + # super(FilestoreConnection, self).__init__(host, user, pwd, port, allow_dir_creation) + self.host = config.get('host', '') + self.user = config.get('user', '') + self.pwd = config.get('pwd', '') + self.port = config.get('port', '') + self.allow_dir_creation = config.get('allow_dir_creation', '') + self.filename = config.get('filename', '') + self.path = config.get('path', '') def connect(self): return NotImplemented @@ -26,41 +28,46 @@ class FileStoreConnection(AbstractTask): def close(self): return NotImplemented - def get(self, filename, path=None): - if path: - filepath = "{}/{}".format(path, filename) + def get(self): + if self.path: + filepath = "{}/{}".format(self.path, self.filename) else: - filepath = filename + filepath = self.filename return open(filepath, 'r+b') - def put(self, fileobject, filename, path=None): - if path: - filepath = "{}/{}".format(path, filename) + def put(self): + if self.path: + filepath = "{}/{}".format(self.path, self.filename) else: - filepath = filename + filepath = self.filename output = open(filepath, 'w+b') return True - def search(self, filename, path=None): - if path: - filepath = "{}/{}".format(path, filename) + def search(self): + if self.path: + filepath = "{}/{}".format(self.path, self.filename) else: - filepath = filename + filepath = self.filename connection_list_result = os.listdir(filepath) return [x for x in connection_list_result if filename in x] - def move(self, filename, oldpath, newpath): - os.rename( - os.path.join(oldpath, filename), - os.path.join(newpath, filename) - ) - def rename(self, oldfilename, newfilename, path=None): - return NotImplemented - -class ImportFileStore(FileStoreConnection): +class ImportFileStore(FileStore): _synchronize_type = "import" def run(): + self.connect() + file = self.get(self.filename) + self.close() + return file + +class ExportFileStore(FileStore): + _synchronize_type = "export" + + + def run(): + self.connect() + self.put(self.filename) + self.close() diff --git a/external_file_location/location.py b/external_file_location/location.py index d82ef52b..ea0a6499 100644 --- a/external_file_location/location.py +++ b/external_file_location/location.py @@ -21,11 +21,12 @@ ############################################################################### from openerp import models, fields +from backend import AbstractTask class Location(models.Model): _name = 'ir.location' _description = 'Description' - + name = fields.Char(string='Name') protocol = fields.Selection(selection='_get_protocol') address = fields.Char(string='Address') @@ -35,5 +36,49 @@ class Location(models.Model): def _get_protocol(self): - return [('ftp', 'FTP'), ('sftp', 'SFTP'), ('filestore', 'Filestore')] - + res = [] + for cls in itersubclasses(AbstractTask): + if not cls._synchronize_type: + cls_info = (cls._key, cls._name) + res.append(cls_info) + return res + + +def itersubclasses(cls, _seen=None): + """ + itersubclasses(cls) + Generator over all subclasses of a given class, in depth first order. + >>> list(itersubclasses(int)) == [bool] + True + >>> class A(object): pass + >>> class B(A): pass + >>> class C(A): pass + >>> class D(B,C): pass + >>> class E(D): pass + >>> + >>> for cls in itersubclasses(A): + ... print(cls.__name__) + B + D + E + C + >>> # get ALL (new-style) classes currently defined + >>> [cls.__name__ for cls in itersubclasses(object)] #doctest: +ELLIPSIS + ['type', ...'tuple', ...] + """ + if not isinstance(cls, type): + raise TypeError('itersubclasses must be called with ' + 'new-style classes, not %.100r' % cls + ) + if _seen is None: + _seen = set() + try: + subs = cls.__subclasses__() + except TypeError: # fails only when cls is type + subs = cls.__subclasses__(cls) + for sub in subs: + if sub not in _seen: + _seen.add(sub) + yield sub + for sub in itersubclasses(sub, _seen): + yield sub diff --git a/external_file_location/task.py b/external_file_location/task.py index c632ec6c..51500cda 100644 --- a/external_file_location/task.py +++ b/external_file_location/task.py @@ -28,21 +28,79 @@ class Task(models.Model): _description = 'Description' name = fields.Char() - method = fields.Selection([ - ('ftp_import', 'FTP import'), - ('ftp_export', 'FTP export'), - ('sftp_import', 'SFTP import'), - ('sftp_export', 'SFTP export'), - ('filestore_import', 'Filestore import'), - ('filestore_export', 'Filestore export'), - ]) + # method = fields.Selection([ + # ('ftp_import', 'FTP import'), + # ('ftp_export', 'FTP export'), + # ('sftp_import', 'SFTP import'), + # ('sftp_export', 'SFTP export'), + # ('filestore_import', 'Filestore import'), + # ('filestore_export', 'Filestore export'), + # ]) + method = fields.Selection(selection='_get_method') filename = fields.Char() filepath = fields.Char() location_id = fields.Many2one('ir.location', string='Location') + def _get_method(self): + res = [] + for cls in itersubclasses(AbstractTask): + if cls._synchronize_type: + cls_info = (cls._key + cls._synchronize_type, cls._name + cls._synchronize_type) + res.append(cls_info) + return res + def run(self): connection_class = ... method_class = getattr(sys.modules[__name__], self.method) + config = { + 'host': self.location_id.address, + 'user': self.location_id.login, + 'pwd': self.location_id.password, + 'port': self.location_id.port, + 'allow_dir_creation': False, + 'filename': self.filename, + 'path': self.filepath + } conn = method_class(config) conn.run() + + +def itersubclasses(cls, _seen=None): + """ + itersubclasses(cls) + Generator over all subclasses of a given class, in depth first order. + >>> list(itersubclasses(int)) == [bool] + True + >>> class A(object): pass + >>> class B(A): pass + >>> class C(A): pass + >>> class D(B,C): pass + >>> class E(D): pass + >>> + >>> for cls in itersubclasses(A): + ... print(cls.__name__) + B + D + E + C + >>> # get ALL (new-style) classes currently defined + >>> [cls.__name__ for cls in itersubclasses(object)] #doctest: +ELLIPSIS + ['type', ...'tuple', ...] + """ + if not isinstance(cls, type): + raise TypeError('itersubclasses must be called with ' + 'new-style classes, not %.100r' % cls + ) + if _seen is None: + _seen = set() + try: + subs = cls.__subclasses__() + except TypeError: # fails only when cls is type + subs = cls.__subclasses__(cls) + for sub in subs: + if sub not in _seen: + _seen.add(sub) + yield sub + for sub in itersubclasses(sub, _seen): + yield sub