Browse Source

Open FTP session on the last moment possible

Used to open  fp = open(file_path,'wb') a few lines before it was needed. This shouldn't be too much of a problem but opening and closing it right after eachother keeps the session open for less time and there are less chances on failure.
pull/1384/head
Alessio Gerace 9 years ago
committed by Aitor Bouzas
parent
commit
7ca4c9ff9e
  1. 100
      auto_backup/README.rst
  2. 24
      auto_backup/__init__.py
  3. 43
      auto_backup/__openerp__.py
  4. 267
      auto_backup/backup_scheduler.py
  5. 18
      auto_backup/data/backup_data.xml
  6. 335
      auto_backup/i18n/it.po
  7. 23
      auto_backup/model/__init__.py
  8. 376
      auto_backup/model/backup_scheduler.py
  9. 2
      auto_backup/security/ir.model.access.csv
  10. 100
      auto_backup/static/description/no_index.html
  11. 22
      auto_backup/tests/__init__.py
  12. 56
      auto_backup/tests/test_auto_backup.py
  13. 100
      auto_backup/view/bkp_conf_view.xml

100
auto_backup/README.rst

@ -0,0 +1,100 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
=================
Automated backups
=================
A tool for all your back-ups, internal and external!
Installation
============
Before to install this module, you need to:
instal pysftp via pip.
Configuration
=============
Go to Settings -> Configuration -> Configure Backup
create your configurations for each database that you needed
to backups.
Usage
=====
Keep your Odoo data safe with this module. Take automated back-ups,
remove them automatically and even write them to an external server
through an encrypted tunnel. You can even specify how long local backups
and external backups should be kept, automatically!
Connect with an FTP Server
--------------------------
#### Keep your data safe, through an SSH tunnel!
Want to go even further and write your backups to an external server?
You can with this module! Specify the credentials to the server, specify
a path and everything will be backed up automatically. This is done
through an SSH (encrypted) tunnel, thanks to pysftp, so your data is
safe!
Test connection
---------------
#### Checks your credentials in one click
Want to make sure if the connection details are correct and if Odoo can
automatically write them to the remote server? Simply click on the ‘Test
SFTP Connection’ button and you will get message telling you if
everything is OK, or what is wrong!
E-mail on backup failure
------------------------
#### Stay informed of problems, automatically!
Do you want to know if the database backup failed? Check the checkbox 'Auto. E-mail on backup fail' and fill in your e-mail.
Every time a backup fails you will get an e-mail in your mailbox with technical details.
Known issues / Roadmap
======================
* ...
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/server-tools/issues/new?body=module:%20auto_backup%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Yenthe Van Ginneken <yenthe.vanginneken@vanroey.be>
* Alessio Gerace <alessio.gerace@agilebg.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.

24
auto_backup/__init__.py

@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
# Copyright (C) 2015 Agile Business Group <http://www.agilebg.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import model
from . import tests

43
auto_backup/__openerp__.py

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
# Copyright (C) 2015 Agile Business Group <http://www.agilebg.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Database Auto-Backup",
"version": "8.0.1.0.0",
"author": (
"VanRoey.be - Yenthe Van Ginneken, Agile Business Group,"
" Odoo Community Association (OCA)"
),
'license': "AGPL-3",
"website": "http://www.vanroey.be/applications/bedrijfsbeheer/odoo",
"category": "Tools",
"summary": "Backups data base",
"depends": ['email_template'],
"demo": [],
"data": [
"view/bkp_conf_view.xml",
"data/backup_data.xml",
"security/ir.model.access.csv"
],
"application": True,
"installable": True
}

267
auto_backup/backup_scheduler.py

@ -1,267 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import xmlrpclib
import socket
import os
import time
import datetime
import base64
import re
try:
import pysftp
except ImportError:
raise ImportError('This module needs pysftp to automaticly write backups to the FTP through SFTP.Please install pysftp on your system.(sudo pip install pysftp)')
from openerp.osv import fields,osv,orm
from openerp import tools
from openerp import netsvc
from openerp import tools, _
import logging
_logger = logging.getLogger(__name__)
def execute(connector, method, *args):
res = False
try:
res = getattr(connector,method)(*args)
except socket.error,e:
raise e
return res
addons_path = tools.config['addons_path'] + '/auto_backup/DBbackups'
class db_backup(osv.Model):
_name = 'db.backup'
def get_db_list(self, cr, user, ids, host, port, context={}):
print("Host: " + host)
print("Port: " + port)
uri = 'http://' + host + ':' + port
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/db')
db_list = execute(conn, 'list')
return db_list
def _get_db_name(self,cr,uid, vals,context=None):
attach_pool = self.pool.get("ir.logging")
dbName = cr.dbname
return dbName
_columns = {
#Columns local server
'host' : fields.char('Host', size=100, required='True'),
'port' : fields.char('Port', size=10, required='True'),
'name' : fields.char('Database', size=100, required='True',help='Database you want to schedule backups for'),
'bkp_dir' : fields.char('Backup Directory', size=100, help='Absolute path for storing the backups', required='True'),
'autoremove': fields.boolean('Auto. Remove Backups', help="If you check this option you can choose to automaticly remove the backup after xx days"),
'daystokeep': fields.integer('Remove after x days',
help="Choose after how many days the backup should be deleted. For example:\nIf you fill in 5 the backups will be removed after 5 days.",required=True),
#Columns for external server (SFTP)
'sftpwrite': fields.boolean('Write to external server with sftp', help="If you check this option you can specify the details needed to write to a remote server with SFTP."),
'sftppath': fields.char('Path external server', help="The location to the folder where the dumps should be written to. For example /odoo/backups/.\nFiles will then be written to /odoo/backups/ on your remote server."),
'sftpip': fields.char('IP Address SFTP Server', help="The IP address from your remote server. For example 192.168.0.1"),
'sftpport': fields.integer("SFTP Port", help="The port on the FTP server that accepts SSH/SFTP calls."),
'sftpusername': fields.char('Username SFTP Server', help="The username where the SFTP connection should be made with. This is the user on the external server."),
'sftppassword': fields.char('Password User SFTP Server', help="The password from the user where the SFTP connection should be made with. This is the password from the user on the external server."),
'daystokeepsftp': fields.integer('Remove SFTP after x days', help="Choose after how many days the backup should be deleted from the FTP server. For example:\nIf you fill in 5 the backups will be removed after 5 days from the FTP server."),
'sendmailsftpfail': fields.boolean('Auto. E-mail on backup fail', help="If you check this option you can choose to automaticly get e-mailed when the backup to the external server failed."),
'emailtonotify': fields.char('E-mail to notify', help="Fill in the e-mail where you want to be notified that the backup failed on the FTP."),
}
_defaults = {
#'bkp_dir' : lambda *a : addons_path,
'bkp_dir' : '/odoo/backups',
'host' : lambda *a : 'localhost',
'port' : lambda *a : '8069',
'name': _get_db_name,
'daystokeepsftp': 30,
'sftpport': 22,
}
def _check_db_exist(self, cr, user, ids):
for rec in self.browse(cr,user,ids):
db_list = self.get_db_list(cr, user, ids, rec.host, rec.port)
if rec.name in db_list:
return True
return False
_constraints = [
(_check_db_exist, _('Error ! No such database exists!'), [])
]
def test_sftp_connection(self, cr, uid, ids, context=None):
conf_ids= self.search(cr, uid, [])
confs = self.browse(cr,uid,conf_ids)
#Check if there is a success or fail and write messages
messageTitle = ""
messageContent = ""
for rec in confs:
db_list = self.get_db_list(cr, uid, [], rec.host, rec.port)
try:
pathToWriteTo = rec.sftppath
ipHost = rec.sftpip
portHost = rec.sftpport
usernameLogin = rec.sftpusername
passwordLogin = rec.sftppassword
#Connect with external server over SFTP, so we know sure that everything works.
srv = pysftp.Connection(host=ipHost, username=usernameLogin,
password=passwordLogin,port=portHost)
srv.close()
#We have a success.
messageTitle = "Connection Test Succeeded!"
messageContent = "Everything seems properly set up for FTP back-ups!"
except Exception, e:
messageTitle = "Connection Test Failed!"
if len(rec.sftpip) < 8:
messageContent += "\nYour IP address seems to be too short.\n"
messageContent += "Here is what we got instead:\n"
if "Failed" in messageTitle:
raise osv.except_osv(_(messageTitle), _(messageContent + "%s") % tools.ustr(e))
else:
raise osv.except_osv(_(messageTitle), _(messageContent))
def schedule_backup(self, cr, user, context={}):
conf_ids= self.search(cr, user, [])
confs = self.browse(cr,user,conf_ids)
for rec in confs:
db_list = self.get_db_list(cr, user, [], rec.host, rec.port)
if rec.name in db_list:
try:
if not os.path.isdir(rec.bkp_dir):
os.makedirs(rec.bkp_dir)
except:
raise
#Create name for dumpfile.
bkp_file='%s_%s.dump' % (time.strftime('%d_%m_%Y_%H_%M_%S'),rec.name)
file_path = os.path.join(rec.bkp_dir,bkp_file)
fp = open(file_path,'wb')
uri = 'http://' + rec.host + ':' + rec.port
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/db')
bkp=''
try:
bkp = execute(conn, 'dump', tools.config['admin_passwd'], rec.name)
except:
logger.notifyChannel('backup', netsvc.LOG_INFO, "Could'nt backup database %s. Bad database administrator password for server running at http://%s:%s" %(rec.name, rec.host, rec.port))
continue
bkp = base64.decodestring(bkp)
fp.write(bkp)
fp.close()
else:
logger.notifyChannel('backup', netsvc.LOG_INFO, "database %s doesn't exist on http://%s:%s" %(rec.name, rec.host, rec.port))
#Check if user wants to write to SFTP or not.
if rec.sftpwrite is True:
try:
#Store all values in variables
dir = rec.bkp_dir
pathToWriteTo = rec.sftppath
ipHost = rec.sftpip
portHost = rec.sftpport
usernameLogin = rec.sftpusername
passwordLogin = rec.sftppassword
#Connect with external server over SFTP
srv = pysftp.Connection(host=ipHost, username=usernameLogin,
password=passwordLogin, port=portHost)
#Move to the correct directory on external server. If the user made a typo in his path with multiple slashes (/odoo//backups/) it will be fixed by this regex.
pathToWriteTo = re.sub('([/]{2,5})+','/',pathToWriteTo)
print(pathToWriteTo)
try:
srv.chdir(pathToWriteTo)
except IOError:
#Create directory and subdirs if they do not exist.
currentDir = ''
for dirElement in pathToWriteTo.split('/'):
currentDir += dirElement + '/'
try:
srv.chdir(currentDir)
except:
print('(Part of the) path didn\'t exist. Creating it now at ' + currentDir)
#Make directory and then navigate into it
srv.mkdir(currentDir, mode=777)
srv.chdir(currentDir)
pass
srv.chdir(pathToWriteTo)
#Loop over all files in the directory.
for f in os.listdir(dir):
fullpath = os.path.join(dir, f)
if os.path.isfile(fullpath):
print(fullpath)
srv.put(fullpath)
#Navigate in to the correct folder.
srv.chdir(pathToWriteTo)
#Loop over all files in the directory from the back-ups.
#We will check the creation date of every back-up.
for file in srv.listdir(pathToWriteTo):
#Get the full path
fullpath = os.path.join(pathToWriteTo,file)
#Get the timestamp from the file on the external server
timestamp = srv.stat(fullpath).st_atime
createtime = datetime.datetime.fromtimestamp(timestamp)
now = datetime.datetime.now()
delta = now - createtime
#If the file is older than the daystokeepsftp (the days to keep that the user filled in on the Odoo form it will be removed.
if delta.days >= rec.daystokeepsftp:
#Only delete files, no directories!
if srv.isfile(fullpath) and ".dump" in file:
print("Delete: " + file)
srv.unlink(file)
#Close the SFTP session.
srv.close()
except Exception, e:
_logger.debug('Exception! We couldn\'t back up to the FTP server..')
#At this point the SFTP backup failed. We will now check if the user wants
#an e-mail notification about this.
if rec.sendmailsftpfail:
try:
ir_mail_server = self.pool.get('ir.mail_server')
message = "Dear,\n\nThe backup for the server " + rec.host + " (IP: " + rec.sftpip + ") failed.Please check the following details:\n\nIP address SFTP server: " + rec.sftpip + "\nUsername: " + rec.sftpusername + "\nPassword: " + rec.sftppassword + "\n\nError details: " + tools.ustr(e) + "\n\nWith kind regards"
msg = ir_mail_server.build_email("auto_backup@" + rec.name + ".com", [rec.emailtonotify], "Backup from " + rec.host + "(" + rec.sftpip + ") failed", message)
ir_mail_server.send_email(cr, user, msg)
except Exception:
pass
"""Remove all old files (on local server) in case this is configured..
This is done after the SFTP writing to prevent unusual behaviour:
If the user would set local back-ups to be kept 0 days and the SFTP
to keep backups xx days there wouldn't be any new back-ups added to the
SFTP.
If we'd remove the dump files before they're writen to the SFTP there willbe nothing to write. Meaning that if an user doesn't want to keep back-ups locally and only wants them on the SFTP (NAS for example) there wouldn't be any writing to the remote server if this if statement was before the SFTP write method right above this comment.
"""
if rec.autoremove is True:
dir = rec.bkp_dir
#Loop over all files in the directory.
for f in os.listdir(dir):
fullpath = os.path.join(dir, f)
timestamp = os.stat(fullpath).st_ctime
createtime = datetime.datetime.fromtimestamp(timestamp)
now = datetime.datetime.now()
delta = now - createtime
if delta.days >= rec.daystokeep:
#Only delete files (which are .dump), no directories.
if os.path.isfile(fullpath) and ".dump" in f:
print("Delete: " + fullpath)
os.remove(fullpath)
db_backup()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

18
auto_backup/data/backup_data.xml

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<record id="ir_cron_backupscheduler0" model="ir.cron">
<field eval="&quot;&quot;&quot;schedule_backup&quot;&quot;&quot;" name="function"/>
<field eval="&quot;&quot;&quot;work_days&quot;&quot;&quot;" name="interval_type"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;&quot;&quot;Backup scheduler&quot;&quot;&quot;" name="name"/>
<field eval="-1" name="numbercall"/>
<field eval="&quot;&quot;&quot;2015-07-07 11:35:28&quot;&quot;&quot;" name="nextcall"/>
<field eval="5" name="priority"/>
<field eval="0" name="doall"/>
<field eval="False" name="active"/>
<field eval="1" name="interval_number"/>
<field eval="&quot;&quot;&quot;db.backup&quot;&quot;&quot;" name="model"/>
</record>
</data>
</openerp>

335
auto_backup/i18n/it.po

@ -0,0 +1,335 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-07-21 13:00+0000\n"
"PO-Revision-Date: 2015-07-21 13:00+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:204
#, python-format
msgid "\n"
"Your IP address seems to be too short.\n"
""
msgstr "\n"
"L' indirizzo IP sembra essere troppo corto.\n"
""
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:209
#, python-format
msgid "%s"
msgstr "%s"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:288
#, python-format
msgid "(Part of the) path didn't exist. Creating it now at %s"
msgstr "(Una parte del) path non esiste. Verra' creato in %s"
#. module: auto_backup
#: help:db.backup,bkp_dir:0
msgid "Absolute path for storing the backups"
msgstr "Percorso assoluto per il salvataggio del DB"
#. module: auto_backup
#: field:db.backup,sendmailsftpfail:0
msgid "Auto. E-mail on backup fail"
msgstr "Auto. E-mail nel caso di errori durante il backup "
#. module: auto_backup
#: field:db.backup,autoremove:0
msgid "Auto. Remove Backups"
msgstr "Rimuovi Backups"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr "Il backup automatico del DB e' pianificato come segue:"
#. module: auto_backup
#: field:db.backup,bkp_dir:0
msgid "Backup Directory"
msgstr "Backup Directory"
#. module: auto_backup
#: model:email.template,subject:auto_backup.email_template_autobackup_error_noificaiton
msgid "Backup from ${object.host} - (${object.sftpip}) failed"
msgstr "Backup da ${object.host} - (${object.sftpip}) fallito"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_tree
msgid "Backups"
msgstr "Backups"
#. module: auto_backup
#: help:db.backup,daystokeepsftp:0
msgid "Choose after how many days the backup should be deleted from the FTP server. For example:\n"
"If you fill in 5 the backups will be removed after 5 days from the FTP server."
msgstr "Scegliere dopo quanti giorni si possa condsiderare da eliminare, un Backup nel server FTP. Per esempio:\n"
"se si imposta 5 i files di backups piu' vecchi di 5 giorni saranno eliminati dal server FTP"
#. module: auto_backup
#: help:db.backup,daystokeep:0
msgid "Scegliere dopo quanti giorni si possa condsiderare da eliminare un Backup. For example:\n"
"If you fill in 5 the backups will be removed after 5 days."
msgstr "Choose after how many days the backup should be deleted. For example:\n"
"se si imposta 5 i files di backups piu' vecchi di 5 giorni saranno eliminati."
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Configure Backup"
msgstr "Configura Backup"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:202
#, python-format
msgid "Connection Test Failed!"
msgstr "Test connessione Fallito!"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:198
#, python-format
msgid "Connection Test Succeeded!"
msgstr "Test connessione avvenuto con successo!"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:241
#, python-format
msgid "Couldn't backup database %s. Bad database administratorpassword for server running at http://%s:%s"
msgstr "Impossibile eseguire il backup di %s. DB password erraata per il server http://%s:%s"
#. module: auto_backup
#: field:db.backup,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: auto_backup
#: field:db.backup,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: auto_backup
#: field:db.backup,name:0
msgid "Database"
msgstr "Database"
#. module: auto_backup
#: help:db.backup,name:0
msgid "Database you want to schedule backups for"
msgstr "Database you want to schedule backups for"
#. module: auto_backup
#: field:db.backup,emailtonotify:0
#: field:db.backup,lasterrorlog:0
msgid "E-mail to notify"
msgstr "E-mail di notifica"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:176
#, python-format
msgid "Error"
msgstr "Errore"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:176
#, python-format
msgid "Error ! No such database exists!"
msgstr "Errore ! Il DB non esiste!"
#. module: auto_backup
#: code:addons/auto_backup/model/backup_scheduler.py:199
#, python-format
msgid "Everything seems properly set up for FTP back-ups!"
msgstr "Tutto sembra impostato correttamente per il back-up FTP!"
#. module: auto_backup
#: help:db.backup,emailtonotify:0
#: help:db.backup,lasterrorlog:0
msgid "Fill in the e-mail where you want to be notified that the backup failed on the FTP."
msgstr "Compilare l'e -mail in cui si desidera essere avvisati,se il backup FTP fallisce."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "For example: /odoo/backups/"
msgstr "Es.: /odoo/backups/"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr "Anadare in Settings / Technical / Automation / Scheduled Actions."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Help"
msgstr "Aiuto"
#. module: auto_backup
#: field:db.backup,host:0
msgid "Host"
msgstr "Host"
#. module: auto_backup
#: field:db.backup,id:0
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: field:db.backup,sftpip:0
msgid "IP Address SFTP Server"
msgstr "IP Address SFTP Server"
#. module: auto_backup
#: help:db.backup,sendmailsftpfail:0
msgid "If you check this option you can choose to automaticly get e-mailed when the backup to the external server failed."
msgstr "Se si seleziona questa opzione è possibile scegliere di essere notificati automaticamente via e-mail quando il backup al server esterno fallisce ."
#. module: auto_backup
#: help:db.backup,autoremove:0
msgid "If you check this option you can choose to automaticly remove the backup after xx days"
msgstr "Se si seleziona questa opzione è possibile scegliere di rimuovere automaticamente il backup dopo xx giorni"
#. module: auto_backup
#: help:db.backup,sftpwrite:0
msgid "If you check this option you can specify the details needed to write to a remote server with SFTP."
msgstr "Se si seleziona questa opzione è possibile specificare i dettagli necessari per scrivere a un server remoto con SFTP ."
#. module: auto_backup
#: field:db.backup,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: auto_backup
#: field:db.backup,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Local backup configuration"
msgstr "Configurazione backup locale"
#. module: auto_backup
#: field:db.backup,sftppassword:0
msgid "Password User SFTP Server"
msgstr "Password utene SFTP Server"
#. module: auto_backup
#: field:db.backup,sftppath:0
msgid "Path external server"
msgstr "Path server esterno"
#. module: auto_backup
#: field:db.backup,port:0
msgid "Port"
msgstr "Porta"
#. module: auto_backup
#: field:db.backup,daystokeepsftp:0
msgid "Remove SFTP after x days"
msgstr "Rimuovi backup da SFTP dopo x giorni"
#. module: auto_backup
#: field:db.backup,daystokeep:0
msgid "Remove after x days"
msgstr "Rimuovi dopo x giorni"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "SFTP"
msgstr "SFTP"
#. module: auto_backup
#: field:db.backup,sftpport:0
msgid "SFTP Port"
msgstr "Porta SFTP"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_search
msgid "Search options"
msgstr "Search options"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr "Cerca l'azione denominata ' di pianificazione del backup ' ."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Set the scheduler to active and fill in how often you want backups generated."
msgstr "Impostare lo scheduler per attivare e compilare la frequenza con cui si desidera generare il backup."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Test"
msgstr "Test"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr "Test SFTP Connection"
#. module: auto_backup
#: help:db.backup,sftpip:0
msgid "The IP address from your remote server. For example 192.168.0.1"
msgstr "Indirizzo IP server remoto. Es. 192.168.0.1"
#. module: auto_backup
#: help:db.backup,sftppath:0
msgid "The location to the folder where the dumps should be written to. For example /odoo/backups/.\n"
"Files will then be written to /odoo/backups/ on your remote server."
msgstr "La posizione della cartella in cui i dumps devono essere scritti. Es. /odoo/backups/.\n"
"i files verranno scritti su /odoo/backups/ nel server remoto."
#. module: auto_backup
#: help:db.backup,sftppassword:0
msgid "The password from the user where the SFTP connection should be made with. This is the password from the user on the external server."
msgstr "La password dell'utente con cui la connessione SFTP deve essere fatta. Questa è la password dall'utente sul server esterno ."
#. module: auto_backup
#: help:db.backup,sftpport:0
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr "La porta sul server FTP che accetta chiamate SSH / SFTP."
#. module: auto_backup
#: help:db.backup,sftpusername:0
msgid "The username where the SFTP connection should be made with. This is the user on the external server."
msgstr "Il nome utente in cui la connessione SFTP dovrebbe essere fatto con . Questo è l'utente sul server esterno."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "This configures the scheduler for automatic backup of the given database running on given host at given port on regular intervals."
msgstr "pianificazione per il backup automatico del database in esecuzione su dato host /porta ad intervalli regolari."
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Use SFTP with caution! This writes files to external servers under the path you specify."
msgstr "Usare SFTP con cautela ! Questo scrive file su server esterni nel percorso specificato "
#. module: auto_backup
#: field:db.backup,sftpusername:0
msgid "Username SFTP Server"
msgstr "Username SFTP Server"
#. module: auto_backup
#: view:db.backup:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr "Warning:"
#. module: auto_backup
#: field:db.backup,sftpwrite:0
msgid "Write to external server with sftp"
msgstr "Salva il backup anche su server FTP esterno"

23
auto_backup/model/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import backup_scheduler

376
auto_backup/model/backup_scheduler.py

@ -0,0 +1,376 @@
# -*- coding: utf-8 -*-
##############################################################################
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# Copyright 2015 Agile Business Group <http://www.agilebg.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import socket
import os
import time
import datetime
import re
from openerp import models, fields, api, _
from openerp.exceptions import except_orm, Warning as UserError
from openerp import tools
from openerp.service import db
import logging
_logger = logging.getLogger(__name__)
try:
import pysftp
except ImportError:
_logger.debug('Can not import pysftp')
def execute(connector, method, *args):
res = False
try:
res = getattr(connector, method)(*args)
except socket.error as e:
raise e
return res
class DbBackup(models.Model):
_name = 'db.backup'
@api.model
def _get_db_name(self):
return self.env.cr.dbname
name = fields.Char(
string='Database', size=100, required=True,
default=_get_db_name,
help='Database you want to schedule backups for'
)
bkp_dir = fields.Char(
string='Backup Directory', size=100,
default='/odoo/backups',
help='Absolute path for storing the backups',
required=True
)
autoremove = fields.Boolean(
string='Auto. Remove Backups',
help=(
"If you check this option you can choose to "
"automaticly remove the backup after xx days"
)
)
daystokeep = fields.Integer(
string='Remove after x days',
default=30,
help=(
"Choose after how many days the backup should be "
"deleted. For example:\nIf you fill in 5 the backups "
"will be removed after 5 days."
), required=True
)
sftpwrite = fields.Boolean(
string='Write to external server with sftp',
help=(
"If you check this option you can specify the details "
"needed to write to a remote server with SFTP."
)
)
sftppath = fields.Char(
string='Path external server',
help=(
"The location to the folder where the dumps should be "
"written to. For example /odoo/backups/.\nFiles will then"
" be written to /odoo/backups/ on your remote server."
)
)
sftpip = fields.Char(
string='IP Address SFTP Server',
help=(
"The IP address from your remote"
" server. For example 192.168.0.1"
)
)
sftpport = fields.Integer(
string="SFTP Port",
default=22,
help="The port on the FTP server that accepts SSH/SFTP calls."
)
sftpusername = fields.Char(
string='Username SFTP Server',
help=(
"The username where the SFTP connection "
"should be made with. This is the user on the external server."
)
)
sftppassword = fields.Char(
string='Password User SFTP Server',
help=(
"The password from the user where the SFTP connection "
"should be made with. This is the password from the user"
" on the external server."
)
)
daystokeepsftp = fields.Integer(
string='Remove SFTP after x days',
default=30,
help=(
"Choose after how many days the backup should be deleted "
"from the FTP server. For example:\nIf you fill in 5 the "
"backups will be removed after 5 days from the FTP server."
)
)
sendmailsftpfail = fields.Boolean(
string='Auto. E-mail on backup fail',
help=(
"If you check this option you can choose to automaticly"
" get e-mailed when the backup to the external server failed."
)
)
emailtonotify = fields.Char(
string='E-mail to notify',
help=(
"Fill in the e-mail where you want to be"
" notified that the backup failed on the FTP."
)
)
lasterrorlog = fields.Text(
string='E-mail to notify',
help=(
"Fill in the e-mail where you want to be"
" notified that the backup failed on the FTP."
)
)
@api.multi
def _check_db_exist(self):
for rec in self:
db_list = db.exp_list(True)
if rec.name in db_list:
return True
return False
_constraints = [
(
_check_db_exist,
_('Error ,No such database exists'), ['name']
)
]
@api.multi
def test_sftp_connection(self):
confs = self.search([])
# Check if there is a success or fail and write messages
messageTitle = ""
messageContent = ""
conn_success = False
for rec in confs:
try:
conn_success = True
ipHost = rec.sftpip
portHost = rec.sftpport
usernameLogin = rec.sftpusername
passwordLogin = rec.sftppassword
# Connect with external server over SFTP, so we know sure that
# everything works.
srv = pysftp.Connection(host=ipHost, username=usernameLogin,
password=passwordLogin, port=portHost)
srv.close()
# We have a success.
messageTitle = _("Connection Test Succeeded!")
messageContent = _(
"Everything seems properly set up for FTP back-ups!")
except Exception as e:
conn_success = False
messageTitle = _("Connection Test Failed!")
if len(rec.sftpip) < 8:
messageContent += _(
"\nYour IP address seems to be too short.\n")
messageContent += _("Here is what we got instead:\n")
if not conn_success:
raise except_orm(
_(messageTitle), _(
messageContent + "%s") %
tools.ustr(e))
else:
raise UserError(_(messageTitle), _(messageContent))
@api.model
def schedule_backup(self):
for rec in self.search([]):
if not os.path.isdir(rec.bkp_dir):
os.makedirs(rec.bkp_dir)
# Create name for dumpfile.
bkp_file = '%s_%s.dump.zip' % (
time.strftime('%d_%m_%Y_%H_%M_%S'),
rec.name)
file_path = os.path.join(rec.bkp_dir, bkp_file)
fbk = open(file_path, 'wb')
db.dump_db(rec.name, fbk)
fbk.close()
# Check if user wants to write to SFTP or not.
if rec.sftpwrite is True:
try:
# Store all values in variables
dir = rec.bkp_dir
pathToWriteTo = rec.sftppath
ipHost = rec.sftpip
portHost = rec.sftpport
usernameLogin = rec.sftpusername
passwordLogin = rec.sftppassword
# Connect with external server over SFTP
srv = pysftp.Connection(
host=ipHost,
username=usernameLogin,
password=passwordLogin,
port=portHost)
# Move to the correct directory on external server. If the
# user made a typo in his path with multiple slashes
# (/odoo//backups/) it will be fixed by this regex.
pathToWriteTo = re.sub('/+', '/', pathToWriteTo)
_logger.debug(
'Start to copy files..'
)
try:
srv.chdir(pathToWriteTo)
except IOError:
# Create directory and subdirs if they do not exist.
currentDir = ''
for dirElement in pathToWriteTo.split('/'):
currentDir += dirElement + '/'
try:
srv.chdir(currentDir)
except:
_logger.info(
_(
'(Part of the) path didn\'t exist. '
'Creating it now at %s'
) % currentDir
)
# Make directory and then navigate into it
srv.mkdir(currentDir, mode=777)
srv.chdir(currentDir)
pass
srv.chdir(pathToWriteTo)
# Loop over all files in the directory.
for f in os.listdir(dir):
fullpath = os.path.join(dir, f)
if os.path.isfile(fullpath):
srv.put(fullpath)
# Navigate in to the correct folder.
srv.chdir(pathToWriteTo)
# Loop over all files in the directory from the back-ups.
# We will check the creation date of every back-up.
for file in srv.listdir(pathToWriteTo):
# Get the full path
fullpath = os.path.join(pathToWriteTo, file)
if srv.isfile(fullpath) and ".dump.zip" in file:
# Get the timestamp from the file on the external
# server
timestamp = srv.stat(fullpath).st_atime
createtime = (
datetime.datetime.fromtimestamp(timestamp)
)
now = datetime.datetime.now()
delta = now - createtime
# If the file is older than the daystokeepsftp (the
# days to keep that the user filled in on the Odoo
# form it will be removed.
if (
rec.daystokeepsftp > 0 and
delta.days >= rec.daystokeepsftp
):
# Only delete files, no directories!
srv.unlink(file)
# Close the SFTP session.
srv.close()
except Exception as e:
_logger.debug(
'Exception We couldn\'t back '
'up to the FTP server..'
)
# At this point the SFTP backup failed.
# We will now check if the user wants
# an e-mail notification about this.
if rec.sendmailsftpfail:
self.send_notification(rec, e)
# Remove all old files (on local server)
# in case this is configured..
if rec.autoremove is True:
try:
self.remove_folder(rec)
except Exception as e:
_logger.debug(
'Exception when try to remove file'
)
return True
def send_notification(self, rec, e):
try:
ir_mail_server = self.env['ir.mail_server']
message = (
"Dear,\n\nThe backup for the server %s"
" (IP: %s) failed.Please check"
" the following details:\n\n"
"IP address SFTP server: %s \nUsername: %s"
"\nPassword: %s"
"\n\nError details: %s \n\nWith kind regards"
) % (
rec.host, rec.sftpip, rec.sftpip,
rec.sftpusername, rec.sftppassword,
tools.ustr(e)
)
msg = ir_mail_server.build_email(
"auto_backup@%s.com" % rec.name,
[rec.emailtonotify],
"Backup from %s ( %s ) failed" % (
rec.host, rec.sftpip),
message)
ir_mail_server.send_email(msg)
except Exception as e:
_logger.debug(
'Exception %s' % tools.ustr(e)
)
# This is done after the SFTP writing to prevent unusual behaviour:
# If the user would set local back-ups to be kept 0 days and the SFTP
# to keep backups xx days there wouldn't be any new back-ups added
# to the SFTP.
# If we'd remove the dump files before they're writen to the SFTP
# there willbe nothing to write. Meaning that if an user doesn't want
# to keep back-ups locally and only wants them on the SFTP
# (NAS for example) there wouldn't be any writing to the
# remote server if this if statement was before the SFTP write method
# right above this comment.
def remove_folder(self, rec):
dir = rec.bkp_dir
# Loop over all files in the directory.
for f in os.listdir(dir):
fullpath = os.path.join(dir, f)
if os.path.isfile(fullpath) and ".dump.zip" in f:
timestamp = os.stat(fullpath).st_ctime
createtime = (
datetime.datetime.fromtimestamp(timestamp)
)
now = datetime.datetime.now()
delta = now - createtime
if delta.days >= rec.daystokeep:
_logger.debug(
'Remove local file...'
)
os.remove(fullpath)

2
auto_backup/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_db_backup,access_db_backup,model_db_backup,,1,0,0,0

100
auto_backup/static/description/no_index.html

@ -0,0 +1,100 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Automated backups</h2>
<h3 class="oe_slogan">A tool for all your back-ups, internal and external!</h3>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img src="overview.png">
</div>
</div>
<div class="oe_span6">
<p class="oe_mt32">
Keep your Odoo data safe with this module. Take automated back-ups, remove them automatically
and even write them to an external server through an encrypted tunnel.
You can even specify how long local backups and external backups should be kept, automatically!
</p>
<div class="oe_centeralign oe_websiteonly">
<a href="http://www.openerp.com/start?app=mail" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
</div>
</div>
</div>
</section>
<!-- Second block -->
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Connect with an FTP Server</h2>
<h3 class="oe_slogan">Keep your data safe, through an SSH tunnel!</h3>
<div class="oe_span6">
<p class="oe_mt32">
Want to go even further and write your backups to an external server?
You can with this module! Specify the credentials to the server, specify a path and everything will be backed up automatically. This is done through an SSH (encrypted) tunnel, thanks to pysftp, so your data is safe!
</p>
</div>
<div class="oe_span6">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="terminalssh.png">
</div>
</div>
</div>
</section>
<!--Third block -->
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Test connection</h2>
<h3 class="oe_slogan">Checks your credentials in one click</h3>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img src="testconnection.png">
<img src="testconnectionfailed.png">
</div>
</div>
<div class="oe_span6">
<p class="oe_mt32">
Want to make sure if the connection details are correct and if Odoo can automatically write them to the remote server? Simply click on the 'Test SFTP Connection' button and you will get message telling you if everything is OK, or what is wrong!
</p>
</div>
</div>
</section>
<!-- Fourth block -->
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">E-mail on backup failure</h2>
<h3 class="oe_slogan">Stay informed of problems, automatically!</h3>
<div class="oe_span6">
<p class="oe_mt32">
Do you want to know if the database backup failed? Check the checkbox 'Auto. E-mail on backup fail' and fill in your e-mail.
Every time a backup fails you will get an e-mail in your mailbox with technical details.
</p>
</div>
<div class="oe_span6">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="emailnotification.png">
</div>
</div>
</div>
</section>
<!--Fifth block -->
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Contact / Support</h2>
<h3 class="oe_slogan">Need help or want extra features?</h3>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<a href="http://www.vanroey.be/appplications/bedrijfsbeheer/odoo"><img src="logo.png"></a>
</div>
</div>
<div class="oe_span6">
<p class="oe_mt32">
Need help with the configuration or want this module to have more functionalities?
Contact us through e-mail at <a href="mailto:"yenthe.vanginneken@vanroey.be">yenthe.vanginneken@vanroey.be</a> or <a href="mailto:"tony.crols@vanroey.be">tony.crols@vanroey.be</a>
</p>
</div>
</div>
</section>

22
auto_backup/tests/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Agile Business Group <http://www.agilebg.com>
# Copyright (C) 2015 Alessio Gerace <alesiso.gerace@agilebg.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 . import test_auto_backup

56
auto_backup/tests/test_auto_backup.py

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Agile Business Group <http://www.agilebg.com>
# Copyright (C) 2015 Alessio Gerace <alesiso.gerace@agilebg.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.tests import common
from openerp.exceptions import except_orm
import os
import time
class TestsAutoBackup(common.TransactionCase):
def setUp(self):
super(TestsAutoBackup, self).setUp()
self.abk_model = self.env["db.backup"]
self.cron_model = self.env["ir.cron"]
def test_0(self):
with self.assertRaises(except_orm):
self.abk_model.create(
{
'name': 'abcd',
'adminpassword': 'admin'
}
)
def test_1(self):
this = self.abk_model.create(
{
'bkp_dir': '/tmp'
}
)
self.assertEqual(this.bkp_dir, '/tmp')
bkp_file = '%s_%s.dump.zip' % (
time.strftime('%d_%m_%Y_%H_%M_%S'),
this.name)
file_path = os.path.join(this.bkp_dir, bkp_file)
this.schedule_backup()
self.assertTrue(os.path.isfile(file_path))

100
auto_backup/view/bkp_conf_view.xml

@ -0,0 +1,100 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_backup_conf_form">
<field name="name">Configure Backup</field>
<field name="model">db.backup</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Test">
<group col="4" colspan="4">
<separator col="2" string="Local backup configuration"/>
</group>
<group>
<field name="name"/>
<field name="bkp_dir"/>
<field name="autoremove"/>
<field name="daystokeep" attrs="{'invisible': [('autoremove','=',False)]}"/>
</group>
<group col="4" colspan="4">
<separator col="2" string="SFTP"/>
</group>
<div
style="width:50%;border-radius:10px;
margin: 10px 0px;
padding:15px 10px 15px 10px;
background-repeat:
no-repeat;background-position: 10px center;
color: #9F6000;background-color: #FEEFB3;"
attrs="{'invisible': [('sftpwrite','=',False)]}">
<b>Warning:</b>
Use SFTP with caution! This writes files to external servers under the path you specify.
</div>
<group>
<field name="sftpwrite"/>
<field name="sftpip" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}"/>
<field name="sftpport" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}"/>
<field name="sftpusername" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}"/>
<field name="sftppassword" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}" password="True"/>
<field name="sftppath" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}" placeholder="For example: /odoo/backups/"/>
<field name="daystokeepsftp" attrs="{'invisible':[('sftpwrite', '==', False)],'required':[('sftpwrite', '==', True)]}"/>
<field name="sendmailsftpfail" attrs="{'invisible': [('sftpwrite','=',False)]}"/>
<field name="emailtonotify" attrs="{'invisible':['|',('sendmailsftpfail', '==', False),
('sftpwrite', '==', False)],'required':[('sendmailsftpfail', '==', True)]}"/>
<button name="test_sftp_connection" type="object" attrs="{'invisible': [('sftpwrite','=',False)]}" string="Test SFTP Connection" icon="gtk-network"/>
</group>
<separator string="Help" colspan="2"/>
<div>
This configures the scheduler for automatic backup of the given database running on given host at given port on regular intervals.
<br/>
Automatic backups of the database can be scheduled as follows:
<ol>
<li>Go to Settings / Technical / Automation / Scheduled Actions.</li>
<li>Search the action named 'Backup scheduler'.</li>
<li>Set the scheduler to active and fill in how often you want backups generated.</li>
</ol>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_backup_conf_tree">
<field name="name">Configure Backup</field>
<field name="model">db.backup</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Backups">
<field name='name'/>
<field name='bkp_dir'/>
<field name="autoremove"/>
<field name="sftpip"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_backup_conf_search">
<field name="name">Configure Backup</field>
<field name="model">db.backup</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search options">
<field name='name'/>
<field name='bkp_dir'/>
<field name="autoremove"/>
<field name="sftpip"/>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_backup_conf_form">
<field name="name">Configure Backup</field>
<field name="res_model">db.backup</field>
<field name="view_type">form</field>
<field name='view_mode'>tree,form</field>
<field name='view_id' ref='view_backup_conf_tree'/>
</record>
<menuitem parent="base.menu_config" action="action_backup_conf_form" id="backup_conf_menu"/>
</data>
</openerp>
Loading…
Cancel
Save