Merge branch 'rmehta-backup-cleanup' into develop

This commit is contained in:
Anand Doshi 2015-09-28 19:38:06 +05:30
commit 6361ae3495
16 changed files with 49 additions and 1032 deletions

View File

@ -128,12 +128,6 @@ scheduler_events = {
"erpnext.support.doctype.issue.issue.auto_close_tickets",
"erpnext.accounts.doctype.fiscal_year.fiscal_year.auto_create_fiscal_year",
"erpnext.hr.doctype.employee.employee.send_birthday_reminders"
],
"daily_long": [
"erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily"
],
"weekly_long": [
"erpnext.setup.doctype.backup_manager.backup_manager.take_backups_weekly"
]
}

View File

@ -1,6 +1,10 @@
frappe.listview_settings['Task'] = {
add_fields: ["project", "status", "priority", "exp_end_date"],
onload: function(listview) {
frappe.route_options = {
"status": "Open"
};
var method = "erpnext.projects.doctype.task.task.set_multiple_status";
listview.page.add_menu_item(__("Set as Open"), function() {

View File

@ -37,3 +37,40 @@ $.extend(frappe.breadcrumbs.preferred, {
"Sales Partner": "Selling",
"Brand": "Selling"
});
frappe.desk_home_buttons.push({label:"<i class='icon-facetime-video'></i> "+ __("Learn"),
route:"Module/Learn"})
frappe.desk_home_flows.push({
title: __("Selling"),
sequence: [
{title: __("Opportunity"), route:"List/Opportunity"},
{title: __("Quotation"), route:"List/Quotation"},
{title: __("Sales Order"), route:"List/Sales Order"},
{title: __("Delivery Note"), route:"List/Delivery Note"},
{title: __("Sales Invoice"), route:"List/Sales Invoice"},
{title: __("Payment"), route:"List/Journal Entry"},
]
});
frappe.desk_home_flows.push({
title: __("Buying"),
sequence: [
{title: __("Material Request"), route:"List/Material Request"},
{title: __("Supplier Quotation"), route:"List/Supplier Quotation"},
{title: __("Purchase Order"), route:"List/Purchase Order"},
{title: __("Purchase Receipt"), route:"List/Purchase Receipt"},
{title: __("Purchase Invoice"), route:"List/Purchase Invoice"},
{title: __("Payment"), route:"List/Journal Entry"},
]
});
frappe.desk_home_flows.push({
title: __("Manufacturing"),
sequence: [
{title: __("BOM"), route:"List/BOM"},
{title: __("Production Planning Tool"), route:"Form/Production Planning Tool"},
{title: __("Production Order"), route:"List/Production Order"},
{title: __("Stock Entry"), route:"List/Stock Entry"},
]
});

View File

@ -1,7 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// start
$(document).on('startup', function() {
console.log(__('Starting up...'));
});

View File

@ -1 +0,0 @@
Settings to manage automated backups to third party tools like Dropbox and Google Drive.

View File

@ -1,155 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# SETUP:
# install pip install --upgrade dropbox
#
# Create new Dropbox App
#
# in conf.py, set oauth2 settings
# dropbox_access_key
# dropbox_access_secret
from __future__ import unicode_literals
import os
import frappe
from frappe.utils import get_request_site_address, cstr
from frappe import _
ignore_list = [".DS_Store"]
@frappe.whitelist()
def get_dropbox_authorize_url():
sess = get_dropbox_session()
request_token = sess.obtain_request_token()
return_address = get_request_site_address(True) \
+ "?cmd=erpnext.setup.doctype.backup_manager.backup_dropbox.dropbox_callback"
url = sess.build_authorize_url(request_token, return_address)
return {
"url": url,
"key": request_token.key,
"secret": request_token.secret,
}
@frappe.whitelist(allow_guest=True)
def dropbox_callback(oauth_token=None, not_approved=False):
from dropbox import client
if not not_approved:
if frappe.db.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
allowed = 1
message = "Dropbox access allowed."
sess = get_dropbox_session()
sess.set_request_token(frappe.db.get_value("Backup Manager", None, "dropbox_access_key"),
frappe.db.get_value("Backup Manager", None, "dropbox_access_secret"))
access_token = sess.obtain_access_token()
frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", access_token.key)
frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", access_token.secret)
frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", allowed)
frappe.db.set_value("Backup Manager", "Backup Manager", "send_backups_to_dropbox", 1)
dropbox_client = client.DropboxClient(sess)
try:
dropbox_client.file_create_folder("files")
except:
pass
else:
allowed = 0
message = "Illegal Access Token Please try again."
else:
allowed = 0
message = "Dropbox Access not approved."
frappe.local.message_title = "Dropbox Approval"
frappe.local.message = "<h3>%s</h3><p>Please close this window.</p>" % message
if allowed:
frappe.local.message_success = True
frappe.db.commit()
frappe.response['type'] = 'page'
frappe.response['page_name'] = 'message.html'
def backup_to_dropbox():
from dropbox import client, session
from frappe.utils.backups import new_backup
from frappe.utils import get_files_path, get_backups_path
if not frappe.db:
frappe.connect()
sess = session.DropboxSession(frappe.conf.dropbox_access_key, frappe.conf.dropbox_secret_key, "app_folder")
sess.set_token(frappe.db.get_value("Backup Manager", None, "dropbox_access_key"),
frappe.db.get_value("Backup Manager", None, "dropbox_access_secret"))
dropbox_client = client.DropboxClient(sess)
# upload database
backup = new_backup()
filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
upload_file_to_dropbox(filename, "/database", dropbox_client)
frappe.db.close()
response = dropbox_client.metadata("/files")
# upload files to files folder
did_not_upload = []
error_log = []
path = get_files_path()
for filename in os.listdir(path):
filename = cstr(filename)
if filename in ignore_list:
continue
found = False
filepath = os.path.join(path, filename)
for file_metadata in response["contents"]:
if os.path.basename(filepath) == os.path.basename(file_metadata["path"]) and os.stat(filepath).st_size == int(file_metadata["bytes"]):
found = True
break
if not found:
try:
upload_file_to_dropbox(filepath, "/files", dropbox_client)
except Exception:
did_not_upload.append(filename)
error_log.append(frappe.get_traceback())
frappe.connect()
return did_not_upload, list(set(error_log))
def get_dropbox_session():
try:
from dropbox import session
except:
frappe.msgprint(_("Please install dropbox python module"), raise_exception=1)
if not (frappe.conf.dropbox_access_key or frappe.conf.dropbox_secret_key):
frappe.throw(_("Please set Dropbox access keys in your site config"))
sess = session.DropboxSession(frappe.conf.dropbox_access_key, frappe.conf.dropbox_secret_key, "app_folder")
return sess
def upload_file_to_dropbox(filename, folder, dropbox_client):
from dropbox import rest
size = os.stat(filename).st_size
with open(filename, 'r') as f:
# if max packet size reached, use chunked uploader
max_packet_size = 4194304
if size > max_packet_size:
uploader = dropbox_client.get_chunked_uploader(f, size)
while uploader.offset < size:
try:
uploader.upload_chunked()
uploader.finish(folder + "/" + os.path.basename(filename), overwrite=True)
except rest.ErrorResponse:
pass
else:
dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True)
if __name__=="__main__":
backup_to_dropbox()

View File

@ -1,30 +0,0 @@
<table class="table table-striped" style="max-width: 600px;">
<thead>
<tr>
<th style="width: 30%;">
{{ __("Date") }}
</th>
<th style="width: 50%;">
{{ __("File") }}
</th>
<th>
{{ __("Size") }}
</th>
</tr>
</thead>
<tbody>
{% for (var i=0; i < files.length; i++) { %}
<tr>
<td>
{{ files[i][1] }}
</td>
<td>
<a href="{{ files[i][0] }}" target="_blank">{{ files[i][0] }}</a>
</td>
<td>
{{ files[i][2] }}
</td>
</tr>
{% } %}
</tbody>
</table>

View File

@ -1,172 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# SETUP:
# install pip install --upgrade google-api-python-client
#
# In Google API
# - create new API project
# - create new oauth2 client (create installed app type as google \
# does not support subdomains)
#
# in conf.py, set oauth2 settings
# gdrive_client_id
# gdrive_client_secret
from __future__ import unicode_literals
import httplib2
import os
import mimetypes
import frappe
import oauth2client.client
from frappe.utils import cstr
from frappe import _
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
# define log config for google drive api's log messages
# basicConfig redirects log to stderr
import logging
logging.basicConfig()
@frappe.whitelist()
def get_gdrive_authorize_url():
flow = get_gdrive_flow()
authorize_url = flow.step1_get_authorize_url()
return {
"authorize_url": authorize_url,
}
def upload_files(name, mimetype, service, folder_id):
if not frappe.db:
frappe.connect()
file_name = os.path.basename(name)
media_body = MediaFileUpload(name, mimetype=mimetype, resumable=True)
body = {
'title': file_name,
'description': 'Backup File',
'mimetype': mimetype,
'parents': [{
'kind': 'drive#filelink',
'id': folder_id
}]
}
request = service.files().insert(body=body, media_body=media_body)
response = None
while response is None:
status, response = request.next_chunk()
def backup_to_gdrive():
from frappe.utils.backups import new_backup
if not frappe.db:
frappe.connect()
get_gdrive_flow()
credentials_json = frappe.db.get_value("Backup Manager", None, "gdrive_credentials")
credentials = oauth2client.client.Credentials.new_from_json(credentials_json)
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
# upload database
backup = new_backup()
path = os.path.join(frappe.local.site_path, "public", "backups")
filename = os.path.join(path, os.path.basename(backup.backup_path_db))
# upload files to database folder
upload_files(filename, 'application/x-gzip', drive_service,
frappe.db.get_value("Backup Manager", None, "database_folder_id"))
# upload files to files folder
did_not_upload = []
error_log = []
files_folder_id = frappe.db.get_value("Backup Manager", None, "files_folder_id")
frappe.db.close()
path = os.path.join(frappe.local.site_path, "public", "files")
for filename in os.listdir(path):
filename = cstr(filename)
found = False
filepath = os.path.join(path, filename)
ext = filename.split('.')[-1]
size = os.path.getsize(filepath)
if ext == 'gz' or ext == 'gzip':
mimetype = 'application/x-gzip'
else:
mimetype = mimetypes.types_map.get("." + ext) or "application/octet-stream"
#Compare Local File with Server File
children = drive_service.children().list(folderId=files_folder_id).execute()
for child in children.get('items', []):
file = drive_service.files().get(fileId=child['id']).execute()
if filename == file['title'] and size == int(file['fileSize']):
found = True
break
if not found:
try:
upload_files(filepath, mimetype, drive_service, files_folder_id)
except Exception, e:
did_not_upload.append(filename)
error_log.append(cstr(e))
frappe.connect()
return did_not_upload, list(set(error_log))
def get_gdrive_flow():
from oauth2client.client import OAuth2WebServerFlow
from frappe import conf
if not "gdrive_client_id" in conf:
frappe.throw(_("Please set Google Drive access keys in {0}"),format("site_config.json"))
flow = OAuth2WebServerFlow(conf.gdrive_client_id, conf.gdrive_client_secret,
"https://www.googleapis.com/auth/drive", 'urn:ietf:wg:oauth:2.0:oob')
return flow
@frappe.whitelist()
def gdrive_callback(verification_code = None):
flow = get_gdrive_flow()
if verification_code:
credentials = flow.step2_exchange(verification_code)
allowed = 1
# make folders to save id
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
erpnext_folder_id = create_erpnext_folder(drive_service)
database_folder_id = create_folder('database', drive_service, erpnext_folder_id)
files_folder_id = create_folder('files', drive_service, erpnext_folder_id)
frappe.db.set_value("Backup Manager", "Backup Manager", "gdrive_access_allowed", allowed)
frappe.db.set_value("Backup Manager", "Backup Manager", "database_folder_id", database_folder_id)
frappe.db.set_value("Backup Manager", "Backup Manager", "files_folder_id", files_folder_id)
final_credentials = credentials.to_json()
frappe.db.set_value("Backup Manager", "Backup Manager", "gdrive_credentials", final_credentials)
frappe.msgprint(_("Updated"))
def create_erpnext_folder(service):
if not frappe.db:
frappe.connect()
erpnext = {
'title': 'erpnext',
'mimeType': 'application/vnd.google-apps.folder'
}
erpnext = service.files().insert(body=erpnext).execute()
return erpnext['id']
def create_folder(name, service, folder_id):
database = {
'title': name,
'mimeType': 'application/vnd.google-apps.folder',
'parents': [{
'kind': 'drive#fileLink',
'id': folder_id
}]
}
database = service.files().insert(body=database).execute()
return database['id']
if __name__=="__main__":
backup_to_gdrive()

View File

@ -1,73 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
$.extend(cur_frm.cscript, {
onload_post_render: function() {
cur_frm.fields_dict.allow_dropbox_access.$input.addClass("btn-primary");
if(cur_frm.doc.__onload && cur_frm.doc.__onload.files) {
$(frappe.render_template("backup_files_list", {files:cur_frm.doc.__onload.files}))
.appendTo(cur_frm.fields_dict.current_backups.$wrapper.empty());
}
},
refresh: function() {
cur_frm.disable_save();
},
validate_send_notifications_to: function() {
if(!cur_frm.doc.send_notifications_to) {
msgprint(__("Please specify") + ": " +
__(frappe.meta.get_label(cur_frm.doctype, "send_notifications_to")));
return false;
}
return true;
},
allow_dropbox_access: function() {
if(cur_frm.cscript.validate_send_notifications_to()) {
return frappe.call({
method: "erpnext.setup.doctype.backup_manager.backup_dropbox.get_dropbox_authorize_url",
callback: function(r) {
if(!r.exc) {
cur_frm.set_value("dropbox_access_secret", r.message.secret);
cur_frm.set_value("dropbox_access_key", r.message.key);
cur_frm.save(null, function() {
window.open(r.message.url);
});
}
}
});
}
},
allow_gdrive_access: function() {
if(cur_frm.cscript.validate_send_notifications_to()) {
return frappe.call({
method: "erpnext.setup.doctype.backup_manager.backup_googledrive.get_gdrive_authorize_url",
callback: function(r) {
if(!r.exc) {
window.open(r.message.authorize_url);
}
}
});
}
},
validate_gdrive: function() {
return frappe.call({
method: "erpnext.setup.doctype.backup_manager.backup_googledrive.gdrive_callback",
args: {
verification_code: cur_frm.doc.verification_code
},
});
},
upload_backups_to_dropbox: function() {
cur_frm.save();
},
// upload_backups_to_gdrive: function() {
// cur_frm.save();
// },
});

View File

@ -1,482 +0,0 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"creation": "2013-04-30 12:58:38",
"custom": 0,
"description": "System for managing Backups",
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "setup",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Download Backups",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "current_backups",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Current Backups",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "",
"fieldname": "sync_with_dropbox",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Sync with Dropbox",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "backup_right_now",
"fieldtype": "Button",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Backup Right Now",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "send_backups_to_dropbox",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Send Backups to Dropbox",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"depends_on": "send_backups_to_dropbox",
"description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.",
"fieldname": "upload_backups_to_dropbox",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Upload Backups to Dropbox",
"no_copy": 0,
"options": "Never\nWeekly\nDaily",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"depends_on": "send_backups_to_dropbox",
"description": "Email ids separated by commas.",
"fieldname": "send_notifications_to",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Send Notifications To",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "dropbox_access_key",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Dropbox Access Key",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "dropbox_access_secret",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Dropbox Access Secret",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "dropbox_access_allowed",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Dropbox Access Allowed",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"depends_on": "send_backups_to_dropbox",
"fieldname": "allow_dropbox_access",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Allow Dropbox Access",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "Note: Backups and files are not deleted from Google Drive, you will have to delete them manually.",
"fieldname": "sync_with_gdrive",
"fieldtype": "Section Break",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Sync with Google Drive",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "upload_backups_to_gdrive",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Upload Backups to Google Drive",
"no_copy": 0,
"options": "Never\nDaily\nWeekly",
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "allow_gdrive_access",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Allow Google Drive Access",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "verification_code",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Enter Verification Code",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "validate_gdrive",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Validate",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "gdrive_access_allowed",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Google Drive Access Allowed",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "gdrive_credentials",
"fieldtype": "Text",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Credentials",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "database_folder_id",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Database Folder ID",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "files_folder_id",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Files Folder ID",
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-cloud-upload",
"idx": 1,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2015-05-26 04:54:10.193573",
"modified_by": "Administrator",
"module": "Setup",
"name": "Backup Manager",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 0,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"read_only": 0,
"read_only_onload": 0
}

View File

@ -1,102 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.utils import get_site_path, cint, split_emails
from frappe.utils.data import convert_utc_to_user_timezone
import os
import datetime
import frappe
from frappe.model.document import Document
class BackupManager(Document):
def onload(self):
self.set_onload("files", get_files())
def get_files():
def get_time(path):
dt = os.path.getmtime(path)
return convert_utc_to_user_timezone(datetime.datetime.utcfromtimestamp(dt)).strftime('%Y-%m-%d %H:%M')
def get_size(path):
size = os.path.getsize(path)
if size > 1048576:
return "{0:.1f}M".format(float(size) / 1048576)
else:
return "{0:.1f}K".format(float(size) / 1024)
path = get_site_path('private', 'backups')
files = [x for x in os.listdir(path) if os.path.isfile(os.path.join(path, x))]
files = [('/backups/' + _file,
get_time(os.path.join(path, _file)),
get_size(os.path.join(path, _file))) for _file in files]
return files
def take_backups_daily():
take_backups_if("Daily")
def take_backups_weekly():
take_backups_if("Weekly")
def take_backups_if(freq):
if cint(frappe.db.get_value("Backup Manager", None, "send_backups_to_dropbox")):
if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq:
take_backups_dropbox()
# if frappe.db.get_value("Backup Manager", None, "upload_backups_to_gdrive")==freq:
# take_backups_gdrive()
@frappe.whitelist()
def take_backups_dropbox():
did_not_upload, error_log = [], []
try:
from erpnext.setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox
did_not_upload, error_log = backup_to_dropbox()
if did_not_upload: raise Exception
send_email(True, "Dropbox")
except Exception:
file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
frappe.errprint(error_message)
send_email(False, "Dropbox", error_message)
#backup to gdrive
@frappe.whitelist()
def take_backups_gdrive():
did_not_upload, error_log = [], []
try:
from erpnext.setup.doctype.backup_manager.backup_googledrive import backup_to_gdrive
did_not_upload, error_log = backup_to_gdrive()
if did_not_upload: raise Exception
send_email(True, "Google Drive")
except Exception:
file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
frappe.errprint(error_message)
send_email(False, "Google Drive", error_message)
def send_email(success, service_name, error_status=None):
if success:
subject = "Backup Upload Successful"
message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
that your backup was successfully uploaded to your %s account. So relax!</p>
""" % service_name
else:
subject = "[Warning] Backup Upload Failed"
message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s
failed.</p>
<p>Error message: %s</p>
<p>Please contact your system manager for more information.</p>
""" % (service_name, error_status)
if not frappe.db:
frappe.connect()
recipients = split_emails(frappe.db.get_value("Backup Manager", None, "send_notifications_to"))
frappe.sendmail(recipients=recipients, subject=subject, message=message)

View File

@ -11,7 +11,7 @@ default_mail_footer = """<div style="padding: 7px; text-align: right; color: #88
def after_install():
frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
set_single_defaults()
frappe.db.set_default('desktop:home_page', 'setup-wizard')
frappe.db.set_default('desktop:home_page', 'setup-wizard');
feature_setup()
from erpnext.setup.page.setup_wizard.setup_wizard import add_all_roles_to
add_all_roles_to("Administrator")

View File

@ -2,7 +2,7 @@ frappe.provide("erpnext.wiz");
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
if(sys_defaults.company) {
frappe.set_route("desktop");
frappe.set_route("desk-home");
return;
}
$(".navbar:first").toggle(false);

View File

@ -597,7 +597,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-09-07 15:51:26",
"modified": "2015-09-24 06:54:33.383186",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",
@ -605,7 +605,7 @@
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 1,
"delete": 0,

View File

@ -1,6 +1,10 @@
frappe.listview_settings['Issue'] = {
colwidths: {"subject": 6},
onload: function(listview) {
frappe.route_options = {
"status": "Open"
};
var method = "erpnext.support.doctype.issue.issue.set_multiple_status";
listview.page.add_menu_item(__("Set as Open"), function() {