First commit Work in Progress

This commit is contained in:
Valentin Chemiere 2015-02-18 15:00:42 +01:00
parent 01316a47c2
commit 2fa7baf1b2
21 changed files with 658 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
import attachment

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
{'name': 'ir_attachment_metadata',
'version': '0.0.1',
'author': 'Akretion',
'website': 'www.akretion.com',
'license': 'AGPL-3',
'category': 'Generic Modules',
'description': """
""",
'depends': [
'base',
],
'data': [
'attachment_view.xml',
],
'installable': True,
'application': True,
}

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
from openerp import models, fields, api, _
from openerp.exceptions import Warning
import hashlib
class AttachmentMetadata(models.Model):
_inherit = 'ir.attachment'
internal_hash = fields.Char(store=True, compute='_compute_hash')
external_hash = fields.Char()
@api.depends('datas')
def _compute_hash(self):
if self.datas:
print hashlib.md5(self.datas).hexdigest()
self.internal_hash = hashlib.md5(self.datas).hexdigest()
if self.external_hash and self.internal_hash != self.external_hash:
raise Warning(_('File corrupted'), _("Something was wrong with the retreived file, please relaunch the task."))

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_attachment_improved_form" model="ir.ui.view">
<field name="model">ir.attachment</field>
<field name="inherit_id" ref="base.view_attachment_form" />
<field name="arch" type="xml">
<field name="url" position="after">
<field name="internal_hash"/>
<field name="external_hash"/>
</field>
</field>
</record>
</data>
</openerp>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
import attachment
import location
import task

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
{'name': 'ir_exchange_file',
'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,
}

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
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')

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_attachment_improved_form" model="ir.ui.view">
<field name="model">ir.attachment</field>
<field name="inherit_id" ref="base.view_attachment_form" />
<field name="arch" type="xml">
<field name="url" position="after">
<field name="sync_date"/>
<field name="parse_state"/>
</field>
</field>
</record>
</data>
</openerp>

34
ir_exchange_file/backend.py Executable file
View File

@ -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

Binary file not shown.

View File

@ -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():

View File

@ -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

View File

@ -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))

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
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')]

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_location_form" model="ir.ui.view">
<field name="model">ir.location</field>
<field name="arch" type="xml">
<form string="Location" version="7.0">
<sheet>
<group col="4">
<field name="name" select="1" colspan="4"/>
<field name="protocol" colspan="2"/>
<newline/>
<field name="address" colspan="2"/>
<field name="port" colspan="2"/>
<field name="login" colspan="4"/>
<field name="password" colspan="4"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_location_tree" model="ir.ui.view">
<field name="model">ir.location</field>
<field name="arch" type="xml">
<tree string="Location">
<field name="name" select="1"/>
<field name="protocol"/>
<field name="address"/>
<field name="port"/>
<field name="login"/>
<field name="password"/>
</tree>
</field>
</record>
<record id="action_location" model="ir.actions.act_window">
<field name="name">Locations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.location</field>
<field name="view_type">form</field>
<field name="view_id" eval="False"/>
</record>
<menuitem id="menu_ir_location"
parent="base.next_id_9"
sequence="20"
action="action_location"/>
</data>
</openerp>

48
ir_exchange_file/task.py Normal file
View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
###############################################################################
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()

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_task_form" model="ir.ui.view">
<field name="model">ir.location.task</field>
<field name="arch" type="xml">
<form string="Tasks" version="7.0">
<sheet>
<group col="4">
<field name="name" select="1" colspan="4"/>
<field name="method" colspan="4"/>
<field name="filename" colspan="4"/>
<field name="filepath" colspan="4"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_task_tree" model="ir.ui.view">
<field name="model">ir.location.task</field>
<field name="arch" type="xml">
<tree string="Tasks" >
<field name="name" select="1"/>
<field name="method"/>
<field name="filename"/>
<field name="filepath"/>
</tree>
</field>
</record>
<record id="action_task" model="ir.actions.act_window">
<field name="name">Tasks</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.location.task</field>
<field name="view_type">form</field>
<field name="view_id" eval="False"/>
</record>
<menuitem id="menu_ir_location_task"
parent="base.next_id_9"
sequence="20"
action="action_task"/>
</data>
</openerp>