From 08bd6776640a0659e8f7e49da47c6250396799a0 Mon Sep 17 00:00:00 2001 From: webnotes Date: Mon, 11 Mar 2013 10:43:33 +0530 Subject: [PATCH 01/18] Commit all these files. --- .../doctype/backup_manager/backup_dropbox.py | 65 +++++++++---------- .../doctype/backup_manager/backup_manager.py | 8 ++- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py index 3b0857fdd9..0cd82c9601 100644 --- a/setup/doctype/backup_manager/backup_dropbox.py +++ b/setup/doctype/backup_manager/backup_dropbox.py @@ -1,6 +1,9 @@ import os import webnotes -from webnotes.utils import get_request_site_address +from webnotes.utils import get_request_site_address, get_base_path +from webnotes import _ + +filename = '' @webnotes.whitelist() def get_dropbox_authorize_url(): @@ -9,8 +12,7 @@ def get_dropbox_authorize_url(): return_address = get_request_site_address(True) \ + "?cmd=setup.doctype.backup_manager.backup_dropbox.dropbox_callback" - url = sess.build_authorize_url(request_token, return_address) - + url = sess.build_authorize_url(request_token, return_address) return { "url": url, "key": request_token.key, @@ -49,7 +51,7 @@ def dropbox_callback(oauth_token=None, not_approved=False): webnotes.response['page_name'] = 'message.html' def backup_to_dropbox(): - from dropbox import client, session + from dropbox import client, session, rest from conf import dropbox_access_key, dropbox_secret_key from webnotes.utils.backups import new_backup if not webnotes.conn: @@ -67,22 +69,19 @@ def backup_to_dropbox(): backup = new_backup() filename = backup.backup_path_db upload_file_to_dropbox(filename, "database", dropbox_client) - # upload files - response = dropbox_client.metadata("files") - - - # add missing files - for filename in os.listdir(os.path.join("public", "files")): - found = False - for file_metadata in response["contents"]: - if filename==os.path.basename(file_metadata["path"]): - if os.stat(os.path.join("public", "files", filename)).st_size==file_metadata["bytes"]: - found=True - - if not found: - upload_file_to_dropbox(os.path.join("public", "files", filename), "files", dropbox_client) + response = dropbox_client.metadata("/database") + #add missing files + # for filename in os.listdir(filename): + # found = False + # for file_metadata in response["contents"]: + # if filename==os.path.basename(file_metadata["path"]): + # if os.stat(filename).st_size==file_metadata["bytes"]: + # found=True + + # if not found: + # upload_file_to_dropbox(filename, "database", dropbox_client) def get_dropbox_session(): from dropbox import session @@ -91,25 +90,25 @@ def get_dropbox_session(): except ImportError, e: webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py", raise_exception=True) - sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder") return sess def upload_file_to_dropbox(filename, folder, dropbox_client): - if __name__=="__main__": - print "Uploading " + filename - size = os.stat(filename).st_size - f = open(filename,'r') - - if size > 4194304: - uploader = dropbox_client.get_chunked_uploader(f, size) - while uploader.offset < size: - try: - uploader.upload_chunked() - except rest.ErrorResponse, e: - pass - else: - response = dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) + path = os.path.join(get_base_path(),"public", "backups") + for files in os.listdir(path): + file_name = path + "/" + files + size = os.stat(file_name).st_size + f = open(filename,'r') + + if size > 4194304: + uploader = dropbox_client.get_chunked_uploader(f, size) + while uploader.offset < size: + try: + uploader.upload_chunked() + except rest.ErrorResponse, e: + pass + else: + response = dropbox_client.put_file(folder + "/" + os.path.basename(file_name), f, overwrite=True) if __name__=="__main__": backup_to_dropbox() \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.py b/setup/doctype/backup_manager/backup_manager.py index 48d48e817c..ed2c64b0b9 100644 --- a/setup/doctype/backup_manager/backup_manager.py +++ b/setup/doctype/backup_manager/backup_manager.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import webnotes from webnotes import _ +from backup_dropbox import dropbox_callback, get_dropbox_session, get_dropbox_authorize_url class DocType: def __init__(self, d, dl): @@ -26,7 +27,6 @@ def take_backups(): send_email(True, "Dropbox") except Exception, e: send_email(False, "Dropbox", e) - def send_email(success, service_name, error_status=None): if success: subject = "Backup Upload Successful" @@ -44,5 +44,7 @@ def send_email(success, service_name, error_status=None): # email system managers from webnotes.utils.email_lib import sendmail - sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","), - subject=subject, msg=message) + sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","), + subject=subject, msg=message) + +get_dropbox_authorize_url() \ No newline at end of file From ebee1c70337e34bee964465f09766032e2143bf3 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 14:33:31 +0530 Subject: [PATCH 02/18] website module: minor updates --- stock/doctype/item/item.py | 3 +-- .../style_settings/custom_template.css | 11 ++++++---- .../doctype/style_settings/style_settings.txt | 6 ++--- .../website_settings/website_settings.js | 2 +- website/templates/html/product_page.html | 22 +++++++++---------- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index 74bf3f308c..931b7762d3 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -238,8 +238,7 @@ class DocType(DocListController): from website.helpers.product import get_parent_item_groups, url_for_website self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}] self.doc.website_image = url_for_website(self.doc.website_image) - self.doc.title = self.doc.item_name == self.doc.name and self.doc.item_name or \ - (self.doc.item_name + " [" + self.doc.name + "]") + self.doc.title = self.doc.item_name if self.doc.slideshow: from website.helpers.slideshow import get_slideshow diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css index f4038fbdcd..3e4aac76d2 100644 --- a/website/doctype/style_settings/custom_template.css +++ b/website/doctype/style_settings/custom_template.css @@ -47,10 +47,9 @@ div.outer { {% if doc.page_border %} /* Page Border*/ div.outer { - -moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.9); - -webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.9); - box-shadow: 0px 0px 3px rgba(0,0,0,0.9); - border-radius: 5px; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + -webkibox-shadow: 0 0 8px rgba(0, 0, 0, 0.2); } {% else %} {% if doc.background_color == doc.page_background %} @@ -61,6 +60,10 @@ div.web-footer { {% endif %} {% endif %} +div.web-footer, div.web-footer a { + color: #{{ get_hex_shade(doc.page_background or "ffffff", 70) }}; +} + /* Bootstrap Navbar */ .navbar-inverse .navbar-inner { background-color: #{{ doc.top_bar_background or "444444"}}; diff --git a/website/doctype/style_settings/style_settings.txt b/website/doctype/style_settings/style_settings.txt index 3f898e72f2..df266a5992 100644 --- a/website/doctype/style_settings/style_settings.txt +++ b/website/doctype/style_settings/style_settings.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-08 11:36:53", "docstatus": 0, - "modified": "2013-03-12 13:35:14", + "modified": "2013-03-14 11:57:20", "modified_by": "Administrator", "owner": "Administrator" }, @@ -150,14 +150,14 @@ "fieldtype": "Column Break" }, { - "description": "Add the name of Google Web Font e.g. \"Open Sans\"", + "description": "Add the name of Google Web Font e.g. \"Open Sans\"", "doctype": "DocField", "fieldname": "google_web_font_for_heading", "fieldtype": "Data", "label": "Google Web Font (Heading)" }, { - "description": "Add the name of Google Web Font e.g. \"Open Sans\"", + "description": "Add the name of Google Web Font e.g. \"Open Sans\"", "doctype": "DocField", "fieldname": "google_web_font_for_text", "fieldtype": "Data", diff --git a/website/doctype/website_settings/website_settings.js b/website/doctype/website_settings/website_settings.js index a02c3b2fcc..67e494154f 100644 --- a/website/doctype/website_settings/website_settings.js +++ b/website/doctype/website_settings/website_settings.js @@ -50,5 +50,5 @@ cur_frm.cscript.set_banner_from_image = function(doc) { var src = doc.banner_image; if(src.indexOf("/")==-1) src = "files/" + src; cur_frm.set_value("banner_html", ""); + +"' style='max-width: 200px;'>"); } \ No newline at end of file diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html index 5bffe9133d..1680c7dec5 100644 --- a/website/templates/html/product_page.html +++ b/website/templates/html/product_page.html @@ -36,18 +36,18 @@ {{ web_long_description or web_short_description or "[No description given]" }} -
{% if obj.doclist.get({"doctype":"Item Website Specification"}) %} -

Specifications

- - {% for d in obj.doclist.get( - {"doctype":"Item Website Specification"}) %} - - - - - {% endfor %} -
{{ d.label }}{{ d.description }}
+
+

Specifications

+ + {% for d in obj.doclist.get( + {"doctype":"Item Website Specification"}) %} + + + + + {% endfor %} +
{{ d.label }}{{ d.description }}
{% endif %}
From 1aab4eaf8d8c1a4c641acfbe1b4a00d2fa6938d2 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 15:06:44 +0530 Subject: [PATCH 03/18] website module: minor updates --- website/utils.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/website/utils.py b/website/utils.py index c7fe2f697f..39e30bad07 100644 --- a/website/utils.py +++ b/website/utils.py @@ -309,10 +309,6 @@ def url_for_website(url): return url def get_hex_shade(color, percent): - # switch dark and light shades - if int(color, 16) > int("808080", 16): - percent = -percent - # stronger diff for darker shades if int(color, 16) < int("333333", 16): percent = percent * 2 @@ -329,4 +325,11 @@ def get_hex_shade(color, percent): return h r, g, b = color[0:2], color[2:4], color[4:6] - return p(r) + p(g) + p(b) \ No newline at end of file + + # switch dark and light shades + if float(int(r, 16) + int(g, 16) + int(b, 16)) / 3 < 8: + percent = -percent + + return p(r) + p(g) + p(b) + + \ No newline at end of file From 93da8a1b0e3fa71c1de443e84a1f5248b2e93faa Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 15:32:49 +0530 Subject: [PATCH 04/18] website module: minor updates --- website/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/utils.py b/website/utils.py index 39e30bad07..94d648bf5f 100644 --- a/website/utils.py +++ b/website/utils.py @@ -327,7 +327,7 @@ def get_hex_shade(color, percent): r, g, b = color[0:2], color[2:4], color[4:6] # switch dark and light shades - if float(int(r, 16) + int(g, 16) + int(b, 16)) / 3 < 8: + if (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3) > 128: percent = -percent return p(r) + p(g) + p(b) From 1ffaaf411018eb6dbd20ef9f690cadf5ede45803 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 15:36:43 +0530 Subject: [PATCH 05/18] website module: minor updates --- website/utils.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/website/utils.py b/website/utils.py index 94d648bf5f..443bde0b66 100644 --- a/website/utils.py +++ b/website/utils.py @@ -309,9 +309,6 @@ def url_for_website(url): return url def get_hex_shade(color, percent): - # stronger diff for darker shades - if int(color, 16) < int("333333", 16): - percent = percent * 2 def p(c): v = int(c, 16) + int(int('ff', 16) * (float(percent)/100)) @@ -326,9 +323,14 @@ def get_hex_shade(color, percent): r, g, b = color[0:2], color[2:4], color[4:6] - # switch dark and light shades - if (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3) > 128: + avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3) + # switch dark and light shades + if avg > 128: percent = -percent + + # stronger diff for darker shades + if percent < 25 and avg < 64: + percent = percent * 2 return p(r) + p(g) + p(b) From e9bef3cbf0ff8aec6492a400fe2f6a20402dfa2d Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 15:39:43 +0530 Subject: [PATCH 06/18] website module: minor updates --- website/doctype/style_settings/custom_template.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css index 3e4aac76d2..b7e381bb80 100644 --- a/website/doctype/style_settings/custom_template.css +++ b/website/doctype/style_settings/custom_template.css @@ -61,7 +61,7 @@ div.web-footer { {% endif %} div.web-footer, div.web-footer a { - color: #{{ get_hex_shade(doc.page_background or "ffffff", 70) }}; + color: #{{ get_hex_shade(doc.background_color or "ffffff", 70) }}; } /* Bootstrap Navbar */ From cb6cf710bb38c47447f22792867a1c06593ac402 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 16:45:28 +0530 Subject: [PATCH 07/18] website module: product page update --- website/templates/html/product_page.html | 41 +++++++++++------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html index 1680c7dec5..0a19efe506 100644 --- a/website/templates/html/product_page.html +++ b/website/templates/html/product_page.html @@ -11,34 +11,31 @@ {% block content %} {% include 'html/product_search_box.html' %} {% include 'html/product_breadcrumbs.html' %} -
-

{{ item_name }}

-

Item Code: {{ name }}

-
- {% if slideshow %} - {% include "html/slideshow.html" %} - {% else %} - {% if website_image %} - - {% else %} -
- {% include 'html/product_missing_image.html' %} -
- {% endif %} - {% endif %} -

-
-

Product Description

+
+ {% if slideshow %} + {% include "html/slideshow.html" %} + {% else %} + {% if website_image %} + + {% else %} +
+ {% include 'html/product_missing_image.html' %} +
+ {% endif %} + {% endif %} +
+
+

{{ item_name }}

+

Item Code: {{ name }}

+

Product Description

{{ web_long_description or web_short_description or "[No description given]" }}
{% if obj.doclist.get({"doctype":"Item Website Specification"}) %} -
-

Specifications

+

Specifications

{% for d in obj.doclist.get( {"doctype":"Item Website Specification"}) %} @@ -49,8 +46,6 @@ {% endfor %}
{% endif %} -
-

Price:

From 37db2233298bded11a0f95e45d56f0518cb00dfe Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 15 Mar 2013 11:29:25 +0530 Subject: [PATCH 08/18] make blog as raw content --- website/doctype/style_settings/custom_template.css | 1 + website/helpers/blog_feed.py | 3 +-- website/templates/css/login.css | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css index b7e381bb80..712c748cb8 100644 --- a/website/doctype/style_settings/custom_template.css +++ b/website/doctype/style_settings/custom_template.css @@ -61,6 +61,7 @@ div.web-footer { {% endif %} div.web-footer, div.web-footer a { + font-size: 90%; color: #{{ get_hex_shade(doc.background_color or "ffffff", 70) }}; } diff --git a/website/helpers/blog_feed.py b/website/helpers/blog_feed.py index c59a419fc6..ce1555649b 100644 --- a/website/helpers/blog_feed.py +++ b/website/helpers/blog_feed.py @@ -57,13 +57,12 @@ def generate(): items = '' blog_list = webnotes.conn.sql("""\ - select page_name as name, modified, creation, title from `tabBlog Post` + select page_name as name, modified, creation, title, content from `tabBlog Post` where ifnull(published,0)=1 order by creation desc, modified desc, name asc limit 20""", as_dict=1) for blog in blog_list: blog.link = host + '/' + blog.name + '.html' - blog.content = get_blog_content(blog.name) items += rss_item % blog diff --git a/website/templates/css/login.css b/website/templates/css/login.css index 710f88944b..c2a7af2521 100644 --- a/website/templates/css/login.css +++ b/website/templates/css/login.css @@ -6,6 +6,7 @@ .layout-wrapper { background-color: #fff; + color: #333; padding: 10px; box-shadow: 1px 1px 3px 3px #ccc; font-size: 12px; From c08e1037d60ee30c03ed07c4a19f83aa84bfdf6d Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 15 Mar 2013 11:36:43 +0530 Subject: [PATCH 09/18] blog_feed --- website/helpers/blog_feed.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/helpers/blog_feed.py b/website/helpers/blog_feed.py index ce1555649b..41c203e0ad 100644 --- a/website/helpers/blog_feed.py +++ b/website/helpers/blog_feed.py @@ -44,7 +44,7 @@ rss_item = u""" %(content)s %(link)s %(name)s - %(creation)s + %(published_on)s """ def generate(): @@ -57,9 +57,9 @@ def generate(): items = '' blog_list = webnotes.conn.sql("""\ - select page_name as name, modified, creation, title, content from `tabBlog Post` + select page_name as name, published_on, modified, title, content from `tabBlog Post` where ifnull(published,0)=1 - order by creation desc, modified desc, name asc limit 20""", as_dict=1) + order by published_on desc limit 20""", as_dict=1) for blog in blog_list: blog.link = host + '/' + blog.name + '.html' From 1cf73915620a73196b5481139dc04be8f18a365f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 15 Mar 2013 13:42:31 +0530 Subject: [PATCH 10/18] patch to fix incorrect gl entries due to payment reconciliation between 2013-03-11 and 2013-03-15 --- controllers/accounts_controller.py | 5 +++- .../march_2013/p05_payment_reconciliation.py | 30 +++++++++++++++++++ patches/patch_list.py | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 patches/march_2013/p05_payment_reconciliation.py diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index 73d7608240..576921a530 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -23,6 +23,9 @@ from utilities.transaction_base import TransactionBase class AccountsController(TransactionBase): def get_gl_dict(self, args, cancel=None): """this method populates the common properties of a gl entry record""" + if cancel is None: + cancel = (self.doc.docstatus == 2) + gl_dict = { 'company': self.doc.company, 'posting_date': self.doc.posting_date, @@ -30,7 +33,7 @@ class AccountsController(TransactionBase): 'voucher_no': self.doc.name, 'aging_date': self.doc.fields.get("aging_date") or self.doc.posting_date, 'remarks': self.doc.remarks, - 'is_cancelled': self.doc.docstatus == 2 and "Yes" or "No", + 'is_cancelled': cancel and "Yes" or "No", 'fiscal_year': self.doc.fiscal_year, 'debit': 0, 'credit': 0, diff --git a/patches/march_2013/p05_payment_reconciliation.py b/patches/march_2013/p05_payment_reconciliation.py new file mode 100644 index 0000000000..f2f03064d6 --- /dev/null +++ b/patches/march_2013/p05_payment_reconciliation.py @@ -0,0 +1,30 @@ +import webnotes + +def execute(): + # delete wrong gle entries created due to a bug in make_gl_entries of Account Controller + # when using payment reconciliation + res = webnotes.conn.sql_list("""select distinct gl1.voucher_no + from `tabGL Entry` gl1, `tabGL Entry` gl2 + where + (date(gl1.modified) between "2013-03-11" and "2013-03-15") + and date(gl1.modified) = date(gl2.modified) + and gl1.voucher_no = gl2.voucher_no + and gl1.voucher_type = "Journal Voucher" + and gl1.voucher_type = gl2.voucher_type + and gl1.posting_date = gl2.posting_date + and gl1.account = gl2.account + and ifnull(gl1.cost_center, "") = ifnull(gl2.cost_center, "") + and ifnull(gl1.is_cancelled, 'No') = 'No' and ifnull(gl2.is_cancelled, 'No') = 'No' + and ifnull(gl1.against_voucher, '') = ifnull(gl2.against_voucher, '') + and ifnull(gl1.against_voucher_type, '') = ifnull(gl2.against_voucher_type, '') + and gl1.remarks = gl2.remarks + and ifnull(gl1.debit, 0) = ifnull(gl2.credit, 0) + and ifnull(gl1.credit, 0) = ifnull(gl2.debit, 0) + and gl1.name > gl2.name""") + + for r in res: + webnotes.conn.sql("""update `tabGL Entry` set `is_cancelled`='Yes' + where voucher_type='Journal Voucher' and voucher_no=%s""", r) + jv = webnotes.bean("Journal Voucher", r) + jv.run_method("make_gl_entries") + \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index bc68ea15c2..f5e3f40916 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -211,4 +211,5 @@ patch_list = [ "patches.march_2013.p02_get_global_default", "patches.march_2013.p03_rename_blog_to_blog_post", "execute:webnotes.reload_doc('hr', 'search_criteria', 'monthly_attendance_details')", + "patches.march_2013.p05_payment_reconciliation", ] \ No newline at end of file From 479af526b023dbf07e45ebe7595503a97d09ef3d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 15 Mar 2013 16:17:31 +0530 Subject: [PATCH 11/18] Backup commited. --- .../doctype/backup_manager/backup_dropbox.py | 77 +++++++++---------- .../doctype/backup_manager/backup_manager.js | 68 ++++++++++++---- .../doctype/backup_manager/backup_manager.py | 23 ++++-- .../doctype/backup_manager/backup_manager.txt | 72 ++++++++++++++++- 4 files changed, 178 insertions(+), 62 deletions(-) diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py index 0cd82c9601..6cdae7aa1b 100644 --- a/setup/doctype/backup_manager/backup_dropbox.py +++ b/setup/doctype/backup_manager/backup_dropbox.py @@ -3,8 +3,6 @@ import webnotes from webnotes.utils import get_request_site_address, get_base_path from webnotes import _ -filename = '' - @webnotes.whitelist() def get_dropbox_authorize_url(): sess = get_dropbox_session() @@ -12,7 +10,8 @@ def get_dropbox_authorize_url(): return_address = get_request_site_address(True) \ + "?cmd=setup.doctype.backup_manager.backup_dropbox.dropbox_callback" - url = sess.build_authorize_url(request_token, return_address) + url = sess.build_authorize_url(request_token, return_address) + return { "url": url, "key": request_token.key, @@ -21,31 +20,32 @@ def get_dropbox_authorize_url(): @webnotes.whitelist(allow_guest=True) def dropbox_callback(oauth_token=None, not_approved=False): + from dropbox import client if not not_approved: if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1) + allowed = 1 message = "Dropbox access allowed." sess = get_dropbox_session() sess.set_request_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"), webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret")) access_token = sess.obtain_access_token() + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", access_token.key) + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", access_token.secret) + webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", allowed) + dropbox_client = client.DropboxClient(sess) + dropbox_client.file_create_folder("files") - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", - access_token.key) - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", - access_token.secret) - else: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) + allowed = 0 message = "Illegal Access Token Please try again." else: - webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0) + allowed = 0 message = "Dropbox Access not approved." - + webnotes.message_title = "Dropbox Approval" webnotes.message = "

%s

Please close this window.

" % message - + webnotes.conn.commit() webnotes.response['type'] = 'page' webnotes.response['page_name'] = 'message.html' @@ -57,7 +57,6 @@ def backup_to_dropbox(): if not webnotes.conn: webnotes.connect() - sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder") sess.set_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"), @@ -69,19 +68,20 @@ def backup_to_dropbox(): backup = new_backup() filename = backup.backup_path_db upload_file_to_dropbox(filename, "database", dropbox_client) - # upload files - response = dropbox_client.metadata("/database") - #add missing files - # for filename in os.listdir(filename): - # found = False - # for file_metadata in response["contents"]: - # if filename==os.path.basename(file_metadata["path"]): - # if os.stat(filename).st_size==file_metadata["bytes"]: - # found=True + response = dropbox_client.metadata("/files") + + # upload files to files folder + filename = os.path.join(get_base_path(),"public", "files") + for filename in os.listdir(filename): + found = False + for file_metadata in response["contents"]: + if filename==os.path.basename(file_metadata["path"]): + if os.stat(filename).st_size==file_metadata["bytes"]: + found=True - # if not found: - # upload_file_to_dropbox(filename, "database", dropbox_client) + if not found: + upload_file_to_dropbox(os.path.join(get_base_path(),"public", "files", filename), "files", dropbox_client) def get_dropbox_session(): from dropbox import session @@ -94,21 +94,18 @@ def get_dropbox_session(): return sess def upload_file_to_dropbox(filename, folder, dropbox_client): - path = os.path.join(get_base_path(),"public", "backups") - for files in os.listdir(path): - file_name = path + "/" + files - size = os.stat(file_name).st_size - f = open(filename,'r') - - if size > 4194304: - uploader = dropbox_client.get_chunked_uploader(f, size) - while uploader.offset < size: - try: - uploader.upload_chunked() - except rest.ErrorResponse, e: - pass - else: - response = dropbox_client.put_file(folder + "/" + os.path.basename(file_name), f, overwrite=True) + size = os.stat(filename).st_size + f = open(filename,'r') + if size > 4194304: + uploader = dropbox_client.get_chunked_uploader(f, size) + while uploader.offset < size: + try: + uploader.upload_chunked() + finish(folder + '/' + os.path.basename(filename), overwrite='True') + except rest.ErrorResponse, e: + pass + else: + response = dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) if __name__=="__main__": backup_to_dropbox() \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.js b/setup/doctype/backup_manager/backup_manager.js index 154c72ec0e..073e0a0906 100644 --- a/setup/doctype/backup_manager/backup_manager.js +++ b/setup/doctype/backup_manager/backup_manager.js @@ -1,24 +1,66 @@ +cur_frm.cscript.refresh = function(doc) { + cur_frm.disable_save(); +} + +//dropbox cur_frm.cscript.allow_dropbox_access = function(doc) { - wn.call({ - method: "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); - }); + if (doc.send_notifications_to == '') { + msgprint("Please enter email address.") + } + else { + wn.call({ + method: "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); + }); + } } - } - }) + }) + } } cur_frm.cscript.backup_right_now = function(doc) { msgprint("Backing up and uploading. This may take a few minutes.") wn.call({ - method: "setup.doctype.backup_manager.backup_manager.take_backups", + method: "setup.doctype.backup_manager.backup_manager.take_backups_dropbox", callback: function(r) { msgprint("Backups taken. Please check your email for the response.") } }) -} \ No newline at end of file +} +//gdrive +cur_frm.cscript.allow_gdrive_access = function(doc) { + if (doc.send_notifications_to == '') { + msgprint("Please enter email address.") + } + else { + wn.call({ + method: "setup.doctype.backup_manager.backup_googledrive.get_gdrive_authorize_url", + callback: function(r) { + window.open(r.message.authorize_url); + } + }) + } +} + +cur_frm.cscript.validate_gdrive_code = function(doc) { + wn.call({ + method: "setup.doctype.backup_manager.backup_manager.gdrive_callback", + args: { + verification_code: doc.verification_code + }, + }); +} +// cur_frm.cscript.backup_to_gdrive = function(doc) { +// msgprint("Backing up and uploading. This may take a few minutes.") +// wn.call({ +// method: "setup.doctype.backup_manager.backup_manager.take_backups_gdrive", +// callback: function(r) { +// msgprint("Backups taken. Please check your email for the response.") +// } +// }) +// } \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.py b/setup/doctype/backup_manager/backup_manager.py index ed2c64b0b9..71d8ad7625 100644 --- a/setup/doctype/backup_manager/backup_manager.py +++ b/setup/doctype/backup_manager/backup_manager.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import webnotes from webnotes import _ from backup_dropbox import dropbox_callback, get_dropbox_session, get_dropbox_authorize_url +from backup_googledrive import gdrive_callback, get_gdrive_flow, get_gdrive_authorize_url class DocType: def __init__(self, d, dl): @@ -17,16 +18,28 @@ def take_backups_weekly(): def take_backups_if(freq): if webnotes.conn.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq: - take_backups() - + take_backups_dropbox() + take_backups_gdrive() +#backup to dropbox @webnotes.whitelist() -def take_backups(): +def take_backups_dropbox(): try: from setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox backup_to_dropbox() send_email(True, "Dropbox") except Exception, e: send_email(False, "Dropbox", e) + +#backup to gdrive +@webnotes.whitelist() +def take_backups_gdrive(): + try: + from setup.doctype.backup_manager.backup_googledrive import backup_to_gdrive + backup_to_gdrive() + send_email(True, "Google Drive") + except Exception, e: + send_email(False, "Google Drive", e) + def send_email(success, service_name, error_status=None): if success: subject = "Backup Upload Successful" @@ -45,6 +58,4 @@ def send_email(success, service_name, error_status=None): # email system managers from webnotes.utils.email_lib import sendmail sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","), - subject=subject, msg=message) - -get_dropbox_authorize_url() \ No newline at end of file + subject=subject, msg=message) \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_manager.txt b/setup/doctype/backup_manager/backup_manager.txt index a994e7da53..bdb9c50605 100644 --- a/setup/doctype/backup_manager/backup_manager.txt +++ b/setup/doctype/backup_manager/backup_manager.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-05 16:35:50", + "creation": "2013-03-15 11:06:59", "docstatus": 0, - "modified": "2013-03-07 12:18:07", + "modified": "2013-03-15 16:10:05", "modified_by": "Administrator", "owner": "Administrator" }, @@ -56,7 +56,9 @@ "doctype": "DocField", "fieldname": "backup_right_now", "fieldtype": "Button", - "label": "Backup Right Now" + "hidden": 1, + "label": "Backup Right Now", + "read_only": 1 }, { "description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.", @@ -102,6 +104,70 @@ "fieldtype": "Button", "label": "Allow Dropbox Access" }, + { + "description": "Note: Backups and files are not deleted from Google Drive, you will have to delete them manually.", + "doctype": "DocField", + "fieldname": "sync_with_gdrive", + "fieldtype": "Section Break", + "label": "Sync with Google Drive" + }, + { + "doctype": "DocField", + "fieldname": "upload_backups_to_gdrive", + "fieldtype": "Select", + "label": "Upload Backups to Google Drive", + "options": "Never\nDaily\nWeekly" + }, + { + "doctype": "DocField", + "fieldname": "allow_gdrive_access", + "fieldtype": "Button", + "label": "Allow Google Drive Access" + }, + { + "doctype": "DocField", + "fieldname": "verification_code", + "fieldtype": "Data", + "label": "Enter Verification Code" + }, + { + "doctype": "DocField", + "fieldname": "validate_gdrive", + "fieldtype": "Button", + "label": "Validate" + }, + { + "doctype": "DocField", + "fieldname": "gdrive_access_allowed", + "fieldtype": "Check", + "hidden": 1, + "label": "Google Drive Access Allowed", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "gdrive_credentials", + "fieldtype": "Text", + "hidden": 1, + "label": "Credentials", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "database_folder_id", + "fieldtype": "Data", + "hidden": 1, + "label": "Database Folder ID", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "files_folder_id", + "fieldtype": "Data", + "hidden": 1, + "label": "Files Folder ID", + "read_only": 1 + }, { "doctype": "DocPerm" } From 0db94077125f7748cbfc446501e145d912dfe6c4 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 15 Mar 2013 17:50:21 +0530 Subject: [PATCH 12/18] fix in payment reconciliation patch --- patches/march_2013/p05_payment_reconciliation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/patches/march_2013/p05_payment_reconciliation.py b/patches/march_2013/p05_payment_reconciliation.py index f2f03064d6..9208aa798f 100644 --- a/patches/march_2013/p05_payment_reconciliation.py +++ b/patches/march_2013/p05_payment_reconciliation.py @@ -13,7 +13,6 @@ def execute(): and gl1.voucher_type = gl2.voucher_type and gl1.posting_date = gl2.posting_date and gl1.account = gl2.account - and ifnull(gl1.cost_center, "") = ifnull(gl2.cost_center, "") and ifnull(gl1.is_cancelled, 'No') = 'No' and ifnull(gl2.is_cancelled, 'No') = 'No' and ifnull(gl1.against_voucher, '') = ifnull(gl2.against_voucher, '') and ifnull(gl1.against_voucher_type, '') = ifnull(gl2.against_voucher_type, '') From 36a3461e55fb4df442d082e57b5936bdd4f80cf6 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Sat, 16 Mar 2013 19:09:26 +0530 Subject: [PATCH 13/18] fix in payment reconciliation patch - run for all modified dates >= 2013-03-11 --- patches/march_2013/p05_payment_reconciliation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/march_2013/p05_payment_reconciliation.py b/patches/march_2013/p05_payment_reconciliation.py index 9208aa798f..7b6306b385 100644 --- a/patches/march_2013/p05_payment_reconciliation.py +++ b/patches/march_2013/p05_payment_reconciliation.py @@ -6,7 +6,7 @@ def execute(): res = webnotes.conn.sql_list("""select distinct gl1.voucher_no from `tabGL Entry` gl1, `tabGL Entry` gl2 where - (date(gl1.modified) between "2013-03-11" and "2013-03-15") + date(gl1.modified) >= "2013-03-11" and date(gl1.modified) = date(gl2.modified) and gl1.voucher_no = gl2.voucher_no and gl1.voucher_type = "Journal Voucher" From 5265f79e031bab256483a30c2a5f7f21ce19d792 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 18 Mar 2013 10:31:18 +0530 Subject: [PATCH 14/18] [website] product_page.html - fixed width --- website/templates/css/product_page.css | 2 +- website/templates/html/product_page.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/website/templates/css/product_page.css b/website/templates/css/product_page.css index 5780ee4fd3..566b6b57aa 100644 --- a/website/templates/css/product_page.css +++ b/website/templates/css/product_page.css @@ -1,6 +1,6 @@