diff --git a/external_file_location/.__openerp__.py.swp b/external_file_location/.__openerp__.py.swp new file mode 100644 index 00000000..8d9e9bd5 Binary files /dev/null and b/external_file_location/.__openerp__.py.swp differ diff --git a/external_file_location/.attachment.py.swp b/external_file_location/.attachment.py.swp new file mode 100644 index 00000000..dc65a5c0 Binary files /dev/null and b/external_file_location/.attachment.py.swp differ diff --git a/external_file_location/.backend.py.swp b/external_file_location/.backend.py.swp new file mode 100644 index 00000000..5afb768f Binary files /dev/null and b/external_file_location/.backend.py.swp differ diff --git a/external_file_location/__init__.py b/external_file_location/__init__.py new file mode 100644 index 00000000..046125d4 --- /dev/null +++ b/external_file_location/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +import attachment +import location +import task + diff --git a/external_file_location/__openerp__.py b/external_file_location/__openerp__.py new file mode 100644 index 00000000..e2b4624f --- /dev/null +++ b/external_file_location/__openerp__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +{'name': 'external_file_location', + 'version': '0.0.1', + 'author': 'Akretion', + 'website': 'www.akretion.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'description': """ + + """, + 'depends': [ + 'base', + ], + 'data': [ + 'attachment_view.xml', + 'location_view.xml', + 'task_view.xml', + ], + 'installable': True, + 'application': True, +} + + + + diff --git a/external_file_location/attachment.py b/external_file_location/attachment.py new file mode 100644 index 00000000..fc1d479e --- /dev/null +++ b/external_file_location/attachment.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +from openerp import models, fields, api, _ +from openerp.exceptions import Warning +import hashlib + + +class AttachmentMetadata(models.Model): + _inherit = 'ir.attachment' + + sync_date = fields.Datetime() + parse_state = fields.Selection([ + ('pending', 'Pending'), + ('failed', 'Failed'), + ('done', 'Done'), + ], readonly=True, required=True, default='pending') + diff --git a/external_file_location/attachment_view.xml b/external_file_location/attachment_view.xml new file mode 100644 index 00000000..69cd719e --- /dev/null +++ b/external_file_location/attachment_view.xml @@ -0,0 +1,18 @@ + + + + + + ir.attachment + + + + + + + + + + + + diff --git a/external_file_location/backend.py b/external_file_location/backend.py new file mode 100755 index 00000000..7555f125 --- /dev/null +++ b/external_file_location/backend.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +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 diff --git a/external_file_location/backends/.filestore.py.swp b/external_file_location/backends/.filestore.py.swp new file mode 100644 index 00000000..09405007 Binary files /dev/null and b/external_file_location/backends/.filestore.py.swp differ diff --git a/external_file_location/backends/filestore.py b/external_file_location/backends/filestore.py new file mode 100755 index 00000000..febd353b --- /dev/null +++ b/external_file_location/backends/filestore.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from ..backend import AbstractConnection +import sys +import os +from tempfile import TemporaryFile + +class AbtractTask() + + def __init__(self, cr, uid): + + + +class FileStoreConnection(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 connect(self): + return NotImplemented + + def close(self): + return NotImplemented + + def get(self, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = filename + return open(filepath, 'r+b') + + def put(self, fileobject, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = filename + output = open(filepath, 'w+b') + return True + + def search(self, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = 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): + _synchronize_type = "import" + + + def run(): + diff --git a/external_file_location/backends/ftp.py b/external_file_location/backends/ftp.py new file mode 100755 index 00000000..7316b81f --- /dev/null +++ b/external_file_location/backends/ftp.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +import sys +import os +from tempfile import TemporaryFile +from ftplib import FTP + +class FTPConnection(object): + + def __init__(self, host, user, pwd, port=None, allow_dir_creation=False): + super(FTPConnection, self).__init__(host, user, pwd, port, allow_dir_creation) + if not port: + self.port = 21 + self.protocol = "FTP" + + def connect(self): + self.connection = FTP(self.location, self.port) + self.connection.login(self.user, self.pwd) + + def close(self): + self.connection.close() + + def get(self, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = filename + outfile = TemporaryFile('w+b') + self.connection.retrbinary('RETR ' + filepath, outfile.write) + return outfile + + def put(self, fileobject, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = filename + self.connection.storbinary('STOR ' + filepath, fileobject) + return True + + def search(self, filename, path=None): + if path: + filepath = "{}/{}".format(path, filename) + else: + filepath = filename + connection_list_result = self.connection.nlst() + return [x for x in connection_list_result if filename in x] + + + def move(self, filename, oldpath, newpath): + self.connection.rename( + os.path.join(oldpath, filename), + os.path.join(newpath, filename) + ) + + def rename(self, oldfilename, newfilename, path=None): + return NotImplemented diff --git a/external_file_location/backends/sftp.py b/external_file_location/backends/sftp.py new file mode 100755 index 00000000..4d40b896 --- /dev/null +++ b/external_file_location/backends/sftp.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import paramiko +import os +from tempfile import TemporaryFile + + +class SFTPConnection(AbstractConnection): + + def __init__(self, host, user, pwd, port=None, allow_dir_creation=False): + super(SFTPConnection, self).__init__(host, user, pwd, port, allow_dir_creation) + if not port: + self.port = 22 + self.protocol = "STFP" + + def connect(self): + self.ssh = paramiko.SSHClient() + self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.ssh.connect(self.host, self.port, self.user, self.pwd, compress=True) + self.connection = self.ssh.open_sftp() + + def close(self): + self.connection.close() + + def get(self, filename, path=None): + if path: + remotefile = "{}/{}".format(path, filename) + else: + remotefile = filename + localfile = filename + newfile = open(filename, 'w') + self.connection.getfo(remotefile, newfile) + return newfile + + def put(self, fileobject, filename, path=None): + if path: + remotefile = "{}/{}".format(path, filename) + else: + remotefile = filename + if self.allow_dir_creation: + self.connection.mkdirs(path) + oldfile = open(fileobj, 'r') + self.connection.putfo(oldfile, remotefile) + + def search(self, filename, path=None): + if path: + self.connection.chdir(path) + file_list = self.connection.listdir() + return [x for x in file_list if filename in x] + + def move(self, filename, oldpath, newpath): + self.connection.rename(os.path.join(oldpath, filename), os.path.join(newpath, filename)) + + def rename(self, oldfilename, newfilename, path=None): + if not path: + path = '' + self.connection.rename(os.path.join(path, oldfilename), os.path.join(path, newfilename)) diff --git a/external_file_location/location.py b/external_file_location/location.py new file mode 100644 index 00000000..d82ef52b --- /dev/null +++ b/external_file_location/location.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +from openerp import models, fields + +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') + port = fields.Integer() + login = fields.Char() + password = fields.Char() + + + def _get_protocol(self): + return [('ftp', 'FTP'), ('sftp', 'SFTP'), ('filestore', 'Filestore')] + diff --git a/external_file_location/location_view.xml b/external_file_location/location_view.xml new file mode 100644 index 00000000..c4d4ffcf --- /dev/null +++ b/external_file_location/location_view.xml @@ -0,0 +1,52 @@ + + + + + + ir.location + +
+ + + + + + + + + + + +
+
+
+ + + ir.location + + + + + + + + + + + + + + Locations + ir.actions.act_window + ir.location + form + + + + + +
+
diff --git a/external_file_location/task.py b/external_file_location/task.py new file mode 100644 index 00000000..c632ec6c --- /dev/null +++ b/external_file_location/task.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +import sys +from openerp import models, fields + +class Task(models.Model): + _name = 'ir.location.task' + _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'), + ]) + filename = fields.Char() + filepath = fields.Char() + location_id = fields.Many2one('ir.location', string='Location') + + def run(self): + connection_class = ... + + method_class = getattr(sys.modules[__name__], self.method) + conn = method_class(config) + conn.run() diff --git a/external_file_location/task_view.xml b/external_file_location/task_view.xml new file mode 100644 index 00000000..b8e928b1 --- /dev/null +++ b/external_file_location/task_view.xml @@ -0,0 +1,47 @@ + + + + + + ir.location.task + +
+ + + + + + + + +
+
+
+ + + ir.location.task + + + + + + + + + + + + Tasks + ir.actions.act_window + ir.location.task + form + + + + + +
+