def test_validate_chaining(self): frappe.get_doc({ "doctype": "Transaction Log", "reference_doctype": "Test Doctype", "document_name": "Test Document 1", "data": "first_data" }).insert(ignore_permissions=True) second_log = frappe.get_doc({ "doctype": "Transaction Log", "reference_doctype": "Test Doctype", "document_name": "Test Document 2", "data": "second_data" }).insert(ignore_permissions=True) third_log = frappe.get_doc({ "doctype": "Transaction Log", "reference_doctype": "Test Doctype", "document_name": "Test Document 3", "data": "third_data" }).insert(ignore_permissions=True) sha = hashlib.sha256() sha.update( frappe.safe_encode(str(third_log.transaction_hash)) + frappe.safe_encode(str(second_log.chaining_hash)) ) self.assertEqual(sha.hexdigest(), third_log.chaining_hash)
def hash_chain(self): sha = hashlib.sha256() sha.update( frappe.safe_encode(str(self.transaction_hash)) + \ frappe.safe_encode(str(self.previous_hash)) ) return sha.hexdigest()
def hash_line(self): sha = hashlib.sha256() sha.update( frappe.safe_encode(str(self.row_index)) + \ frappe.safe_encode(str(self.timestamp)) + \ frappe.safe_encode(str(self.data)) ) return sha.hexdigest()
def setup_suppliers(): system_doc = frappe.get_doc("System Setup") company = frappe.db.get_single_value('Global Defaults', 'default_company') abbr = frappe.get_value("Company", filters={'name': company}, fieldname='abbr') if system_doc.no_suppliers: delete_nongroup_supplier_groups() insert_suppliers_group(company, "General Group") if not frappe.db.exists("Supplier", "General Supplier"): doc = frappe.new_doc("Supplier") doc.supplier_name = "General Supplier" doc.supplier_group = "General Group" doc.supplier_type = "Individual" doc.insert() elif system_doc.suppliers_attachment: file = frappe.get_doc("File", {"file_url": system_doc.suppliers_attachment}) filename = file.get_full_path() with open(filename, "r", encoding="utf8") as infile: if frappe.safe_encode(filename).lower().endswith( "csv".encode('utf-8')): rows = read_csv_content(infile.read()) elif frappe.safe_encode(filename).lower().endswith( "xls".encode('utf-8')): content = file.get_content() rows = read_xls_file_from_attached_file(fcontent=content) elif frappe.safe_encode(filename).lower().endswith( "xlsx".encode('utf-8')): content = file.get_content() rows = read_xlsx_file_from_attached_file(fcontent=content) else: frappe.throw( _("Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload" )) delete_nongroup_supplier_groups() for index, row in enumerate(rows): if index != 0: insert_suppliers_group(company, row[1]) if not frappe.db.exists("Supplier", row[0]): doc = frappe.new_doc("Supplier") doc.supplier_name = row[0] doc.supplier_group = row[1] if row[2].lower() == "individual": doc.supplier_type = "Individual" elif row[20].lower() == "company": doc.supplier_type = "Company" else: frappe.throw( _("Supplier Type column values must be Company or Individual" )) doc.insert()
def setup_customers(self): company = frappe.db.get_single_value('Global Defaults', 'default_company') abbr = frappe.get_value("Company", filters = {'name': company}, fieldname = 'abbr') if self.no_customers: self.delete_nongroup_customer_groups() self.delete_nongroup_territories() self.insert_customers_group(company, "General Group") self.insert_territories("General Territory") if not frappe.db.exists("Customer", "General Customer"): doc = frappe.new_doc("Customer") doc.customer_name = "General Customer" doc.customer_group = "General Group" doc.territory = "General Territory" doc.insert() elif self.customers_attachment: file = frappe.get_doc("File", {"file_url": self.customers_attachment}) filename = file.get_full_path() with open(filename, "r", encoding = "utf8") as infile: if frappe.safe_encode(filename).lower().endswith("csv".encode('utf-8')): rows = read_csv_content(infile.read()) elif frappe.safe_encode(filename).lower().endswith("xls".encode('utf-8')): content = file.get_content() rows = read_xls_file_from_attached_file(fcontent=content) elif frappe.safe_encode(filename).lower().endswith("xlsx".encode('utf-8')): content = file.get_content() rows = read_xlsx_file_from_attached_file(fcontent=content) else: frappe.throw(_("Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload")) self.delete_nongroup_customer_groups() self.delete_nongroup_territories() for index, row in enumerate(rows): if index != 0: self.insert_customers_group(company, row[1]) self.insert_territories(row[2]) if not frappe.db.exists("Customer", row[0]): doc = frappe.new_doc("Customer") doc.customer_name = row[0] doc.customer_group = row[1] doc.territory = row[2] doc.insert() else: frappe.throw(_("Please attach a file"))
def pre_process(user): name = frappe.safe_decode(user.name) if "," in name: firstname = name.split(',')[-1] lastname = name.split(',')[0] else: firstname = name.split()[0] lastname = name.split()[-1] phone = frappe.safe_decode( user.phone) if user.phone is not None else user.phone condition = None if user.email is not None and phone is not None: condition = "(email_id = '{0}' OR phone = '{1}') AND (zendesk_sync_id != '{2}' OR zendesk_sync_id IS NULL)".format( user.email, frappe.safe_encode(phone), user.id) elif user.email is not None: condition = "email_id = '{0}' AND (zendesk_sync_id != '{1}' OR zendesk_sync_id IS NULL)".format( user.email, user.id) elif phone is not None: condition = "phone = '{0}' AND (zendesk_sync_id != '{1}' OR zendesk_sync_id IS NULL)".format( frappe.safe_encode(phone), user.id) if condition: contacts = frappe.db.sql(""" SELECT name FROM tabContact WHERE %s """ % condition, as_dict=True) for contact in contacts: try: frappe.db.set_value("Contact", frappe.safe_decode(contact.name), "zendesk_sync_id", user.id) except Exception as e: frappe.log_error(e, user.name) return { 'id': user.id, 'firstname': firstname, 'lastname': lastname, 'email': user.email, 'phone': phone }
def test_auth_via_api_key_secret(self): # generate API key and API secret for administrator keys = generate_keys("Administrator") frappe.db.commit() generated_secret = frappe.utils.password.get_decrypted_password( "User", "Administrator", fieldname='api_secret' ) api_key = frappe.db.get_value("User", "Administrator", "api_key") header = {"Authorization": "token {}:{}".format(api_key, generated_secret)} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 200) self.assertEqual("Administrator", res.json()["message"]) self.assertEqual(keys['api_secret'], generated_secret) header = {"Authorization": "Basic {}".format(base64.b64encode(frappe.safe_encode("{}:{}".format(api_key, generated_secret))).decode())} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 200) self.assertEqual("Administrator", res.json()["message"]) # Valid api key, invalid api secret api_secret = "ksk&93nxoe3os" header = {"Authorization": "token {}:{}".format(api_key, api_secret)} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 403) # random api key and api secret api_key = "@3djdk3kld" api_secret = "ksk&93nxoe3os" header = {"Authorization": "token {}:{}".format(api_key, api_secret)} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 401)
def get_additional_conditions(from_date, ignore_closing_entries, filters): additional_conditions = [] if ignore_closing_entries: additional_conditions.append( "ifnull(voucher_type, '')!='Period Closing Voucher'") if from_date: additional_conditions.append("posting_date >= %(from_date)s") if filters: if filters.get("project"): if not isinstance(filters.get("project"), list): projects = frappe.safe_encode(filters.get("project")) filters.project = [ d.strip() for d in projects.strip().split(',') if d ] additional_conditions.append("project in %(project)s") if filters.get("cost_center"): filters.cost_center = get_cost_centers_with_children( filters.cost_center) additional_conditions.append("cost_center in %(cost_center)s") if filters.get("finance_book"): if filters.get("include_default_book_entries"): additional_conditions.append( "finance_book in (%(finance_book)s, %(company_fb)s)") else: additional_conditions.append( "finance_book in (%(finance_book)s)") return " and {}".format( " and ".join(additional_conditions)) if additional_conditions else ""
def get_additional_conditions(from_date, ignore_closing_entries, filters): additional_conditions = [] if ignore_closing_entries: additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'") if from_date: additional_conditions.append("posting_date >= %(from_date)s") if filters: if filters.get("project"): if not isinstance(filters.get("project"), list): projects = frappe.safe_encode(filters.get("project")) filters.project = [d.strip() for d in projects.strip().split(',') if d] additional_conditions.append("project in %(project)s") if filters.get("cost_center"): filters.cost_center = get_cost_centers_with_children(filters.cost_center) additional_conditions.append("cost_center in %(cost_center)s") company_finance_book = erpnext.get_default_finance_book(filters.get("company")) if not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book): additional_conditions.append("ifnull(finance_book, '') in ('%s', '')" % frappe.db.escape(company_finance_book)) elif filters.get("finance_book"): additional_conditions.append("ifnull(finance_book, '') = '%s' " % frappe.db.escape(filters.get("finance_book"))) return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
def get_payment_url(self): if self.reference_doctype != "Fees": data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["company", "customer_name"], as_dict=1) else: data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["student_name"], as_dict=1) data.update({"company": frappe.defaults.get_defaults().company}) controller = get_payment_gateway_controller(self.payment_gateway) controller.validate_transaction_currency(self.currency) if hasattr(controller, 'validate_minimum_transaction_amount'): controller.validate_minimum_transaction_amount( self.currency, self.grand_total) return controller.get_payment_url( **{ "amount": flt(self.grand_total, self.precision("grand_total")), "title": data.company.encode("utf-8"), "description": self.subject.encode("utf-8"), "reference_doctype": "Payment Request", "reference_docname": self.name, "payer_email": self.email_to or frappe.session.user, "payer_name": frappe.safe_encode(data.customer_name), "order_id": self.name, "currency": self.currency })
def __init__(self, content): """Parses headers, content, attachments from given raw message. :param content: Raw message.""" if six.PY2: self.mail = email.message_from_string(safe_encode(content)) else: if isinstance(content, bytes): self.mail = email.message_from_bytes(content) else: self.mail = email.message_from_string(content) self.text_content = '' self.html_content = '' self.attachments = [] self.cid_map = {} self.parse() self.set_content_and_type() self.set_subject() self.set_from() self.message_id = (self.mail.get('Message-ID') or "").strip(" <>") if self.mail["Date"]: try: utc = email.utils.mktime_tz(email.utils.parsedate_tz(self.mail["Date"])) utc_dt = datetime.datetime.utcfromtimestamp(utc) self.date = convert_utc_to_user_timezone(utc_dt).strftime('%Y-%m-%d %H:%M:%S') except: self.date = now() else: self.date = now() if self.date > now(): self.date = now()
def get_charset(self, part): """Detect chartset.""" charset = part.get_content_charset() if not charset: charset = chardet.detect(safe_encode(cstr(part)))['encoding'] return charset
def __init__(self, content): """Parses headers, content, attachments from given raw message. :param content: Raw message.""" if six.PY2: self.mail = email.message_from_string(safe_encode(content)) else: if isinstance(content, bytes): self.mail = email.message_from_bytes(content) else: self.mail = email.message_from_string(content) self.text_content = '' self.html_content = '' self.attachments = [] self.cid_map = {} self.parse() self.set_content_and_type() self.set_subject() self.set_from() self.message_id = (self.mail.get('Message-ID') or "").strip(" <>") if self.mail["Date"]: try: utc = email.utils.mktime_tz( email.utils.parsedate_tz(self.mail["Date"])) utc_dt = datetime.datetime.utcfromtimestamp(utc) self.date = convert_utc_to_user_timezone(utc_dt).strftime( '%Y-%m-%d %H:%M:%S') except: self.date = now() else: self.date = now() if self.date > now(): self.date = now()
def create_csv_file(columns, data, dt, dn): csv_filename = '{0}.csv'.format( frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M")) rows = [] if data: columns_without_meta = remove_header_meta(columns) row = data[0] if type(row) == list: rows = [tuple(columns_without_meta)] + data else: for row in data: new_row = [] for col in columns: key = col.get('fieldname') or col.get('label') new_row.append(row.get(key, '')) rows.append(new_row) rows = [tuple(columns_without_meta)] + rows encoded = base64.b64encode(frappe.safe_encode(to_csv(rows))) # Call save() file function to upload and attach the file _file = frappe.get_doc({ "doctype": "File", "file_name": csv_filename, "attached_to_doctype": dt, "attached_to_name": dn, "content": encoded, "decode": True }) _file.save()
def reset_password(self, user, password, logout_sessions=False): from ldap3 import HASHED_SALTED_SHA, MODIFY_REPLACE from ldap3.utils.hashed import hashed search_filter = "({0}={1})".format(self.ldap_email_field, user) conn = self.connect_to_ldap(self.base_dn, self.get_password(raise_exception=False), read_only=False) if conn.search(search_base=self.organizational_unit, search_filter=search_filter, attributes=self.get_ldap_attributes()): if conn.entries and conn.entries[0]: entry_dn = conn.entries[0].entry_dn hashed_password = hashed(HASHED_SALTED_SHA, safe_encode(password)) changes = { 'userPassword': [(MODIFY_REPLACE, [hashed_password])] } if conn.modify(entry_dn, changes=changes): if logout_sessions: from frappe.sessions import clear_sessions clear_sessions(user=user, force=True) frappe.msgprint(_("Password changed successfully.")) else: frappe.throw(_("Failed to change password.")) else: frappe.throw( _("No Entry for the User {0} found within LDAP!").format( user)) else: frappe.throw(_("No LDAP User found for email: {0}").format(user))
def include_attachments(self, message): message_obj = self.get_message_object(message) attachments = self.queue_doc.attachments_list for attachment in attachments: if attachment.get('fcontent'): continue fid = attachment.get("fid") if fid: _file = frappe.get_doc("File", fid) fcontent = _file.get_content() attachment.update({ 'fname': _file.file_name, 'fcontent': fcontent, 'parent': message_obj }) attachment.pop("fid", None) add_attachment(**attachment) elif attachment.get("print_format_attachment") == 1: attachment.pop("print_format_attachment", None) print_format_file = frappe.attach_print(**attachment) print_format_file.update({"parent": message_obj}) add_attachment(**print_format_file) return safe_encode(message_obj.as_string())
def setup_email_account(self, append_to=None, sender=None): self.email_account = get_outgoing_email_account( raise_exception_not_set=False, append_to=append_to, sender=sender) if self.email_account: self.server = self.email_account.smtp_server self.login = (getattr(self.email_account, "login_id", None) or self.email_account.email_id) if not self.email_account.no_smtp_authentication: if self.email_account.ascii_encode_password: self.password = frappe.safe_encode( self.email_account.password, 'ascii') else: self.password = self.email_account.password else: self.password = None self.port = self.email_account.smtp_port self.use_tls = self.email_account.use_tls self.use_ssl = cint(self.email_account.use_ssl_for_outgoing) self.sender = self.email_account.email_id self.always_use_account_email_id_as_sender = cint( self.email_account.get( "always_use_account_email_id_as_sender")) self.always_use_account_name_as_sender_name = cint( self.email_account.get( "always_use_account_name_as_sender_name"))
def generate_bootstrap_theme(self): from subprocess import Popen, PIPE from os.path import join as join_path file_name = frappe.scrub(self.name) + '_' + frappe.generate_hash( 'Website Theme', 8) + '.css' output_path = join_path(frappe.utils.get_bench_path(), 'sites', 'assets', 'css', file_name) content = self.theme_scss content = content.replace('\n', '\\n') command = ['node', 'generate_bootstrap_theme.js', output_path, content] process = Popen(command, cwd=frappe.get_app_path('frappe', '..'), stdout=PIPE, stderr=PIPE) stderr = process.communicate()[1] if stderr: frappe.throw('<pre>{stderr}</pre>'.format( stderr=frappe.safe_encode(stderr))) else: self.theme_url = '/assets/css/' + file_name frappe.msgprint(_('Compiled Successfully'), alert=True)
def test_pdf_encryption(self): password = "******" pdf = pdfgen.get_pdf(self.html, options={"password": password}) reader = PdfFileReader(io.BytesIO(pdf)) self.assertTrue(reader.isEncrypted) if six.PY2: password = frappe.safe_encode(password) self.assertTrue(reader.decrypt(password))
def after_insert(self): if not self.is_folder: self.add_comment_in_reference_doc('Attachment', _('Added {0}').format("<a href='{file_url}' target='_blank'>{file_name}</a>{icon}".format(**{ "icon": ' <i class="fa fa-lock text-warning"></i>' if self.is_private else "", "file_url": quote(frappe.safe_encode(self.file_url)) if self.file_url else self.file_name, "file_name": self.file_name or self.file_url })))
def setup_warehouses(self): company = frappe.db.get_single_value('Global Defaults', 'default_company') abbr = frappe.get_value("Company", filters = {'name': company}, fieldname = 'abbr') if self.no_warehouses: self.delete_nongroup_warehouse_groups() if not frappe.db.exists("Warehouse", 'General Warehouse - '+abbr): doc = frappe.new_doc("Warehouse") doc.warehouse_name = 'General Warehouse' doc.parent_warehouse = frappe.db.sql("select name from `tabWarehouse` where is_group = 1 order by creation asc limit 1")[0][0] doc.insert() elif self.warehouses_attachment: file = frappe.get_doc("File", {"file_url": self.warehouses_attachment}) filename = file.get_full_path() company = frappe.db.get_single_value('Global Defaults', 'default_company') abbr = frappe.get_value("Company", filters = {'name': company}, fieldname = 'abbr') with open(filename, "r", encoding = "utf8") as infile: if frappe.safe_encode(filename).lower().endswith("csv".encode('utf-8')): rows = read_csv_content(infile.read()) elif frappe.safe_encode(filename).lower().endswith("xls".encode('utf-8')): content = file.get_content() rows = read_xls_file_from_attached_file(fcontent=content) elif frappe.safe_encode(filename).lower().endswith("xlsx".encode('utf-8')): content = file.get_content() rows = read_xlsx_file_from_attached_file(fcontent=content) else: frappe.throw(_("Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload")) self.delete_nongroup_warehouse_groups() for index, row in enumerate(rows): if index != 0: if not frappe.db.exists("Warehouse", row[0]+' - '+abbr): doc = frappe.new_doc("Warehouse") doc.warehouse_name = row[0] doc.parent_warehouse = frappe.db.sql("select name from `tabWarehouse` where is_group = 1 order by creation asc limit 1")[0][0] doc.insert() else: frappe.throw(_("Please attach a file"))
def get_pdf(html, options=None, output=None): html = scrub_urls(html) html, options = prepare_options(html, options) options.update({ "disable-javascript": "", "disable-local-file-access": "", "disable-smart-shrinking": "" }) filedata = '' try: # Set filename property to false, so no file is actually created filedata = pdfkit.from_string(html, False, options=options or {}) # https://pythonhosted.org/PyPDF2/PdfFileReader.html # create in-memory binary streams from filedata and create a PdfFileReader object reader = PdfFileReader(io.BytesIO(filedata)) except IOError as e: if ("ContentNotFoundError" in e.message or "ContentOperationNotPermittedError" in e.message or "UnknownContentError" in e.message or "RemoteHostClosedError" in e.message): # allow pdfs with missing images if file got created if filedata: if output: # output is a PdfFileWriter object output.appendPagesFromReader(reader) else: frappe.throw( _("PDF generation failed because of broken image links")) else: raise if "password" in options: password = options["password"] if six.PY2: password = frappe.safe_encode(password) if output: output.appendPagesFromReader(reader) return output writer = PdfFileWriter() writer.appendPagesFromReader(reader) if "password" in options: writer.encrypt(password) filedata = get_file_data_from_writer(writer) return filedata
def upload_bank_statement(): if getattr(frappe, "uploaded_file", None): with open(frappe.uploaded_file, "rb") as upfile: fcontent = upfile.read() else: from frappe.utils.file_manager import get_uploaded_content fname, fcontent = get_uploaded_content() if frappe.safe_encode(fname).lower().endswith("csv"): from frappe.utils.csvutils import read_csv_content rows = read_csv_content(fcontent, False) elif frappe.safe_encode(fname).lower().endswith("xlsx"): from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file rows = read_xlsx_file_from_attached_file(fcontent=fcontent) columns = rows[0] rows.pop(0) data = rows return {"columns": columns, "data": data}
def upload_bank_statement(): if getattr(frappe, "uploaded_file", None): with open(frappe.uploaded_file, "rb") as upfile: fcontent = upfile.read() else: from frappe.utils.file_manager import get_uploaded_content fname, fcontent = get_uploaded_content() if frappe.safe_encode(fname).lower().endswith("csv".encode('utf-8')): from frappe.utils.csvutils import read_csv_content rows = read_csv_content(fcontent, False) elif frappe.safe_encode(fname).lower().endswith("xlsx".encode('utf-8')): from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file rows = read_xlsx_file_from_attached_file(fcontent=fcontent) columns = rows[0] rows.pop(0) data = rows return {"columns": columns, "data": data}
def get_pdf(html, options=None, output=None): html = scrub_urls(html) html, options = prepare_options(html, options) options.update({"disable-javascript": "", "disable-local-file-access": ""}) filedata = '' if LooseVersion(get_wkhtmltopdf_version()) > LooseVersion('0.12.3'): options.update({"disable-smart-shrinking": ""}) try: # Set filename property to false, so no file is actually created filedata = pdfkit.from_string(html, False, options=options or {}) # https://pythonhosted.org/PyPDF2/PdfFileReader.html # create in-memory binary streams from filedata and create a PdfFileReader object reader = PdfFileReader(io.BytesIO(filedata)) except OSError as e: if any([error in str(e) for error in PDF_CONTENT_ERRORS]): if not filedata: frappe.throw( _("PDF generation failed because of broken image links")) # allow pdfs with missing images if file got created if output: # output is a PdfFileWriter object output.appendPagesFromReader(reader) else: frappe.throw( _("PDF generation failed because of broken image links")) else: raise if "password" in options: password = options["password"] if six.PY2: password = frappe.safe_encode(password) if output: output.appendPagesFromReader(reader) return output writer = PdfFileWriter() writer.appendPagesFromReader(reader) if "password" in options: writer.encrypt(password) filedata = get_file_data_from_writer(writer) return filedata
def parseXLS(self): file_url = self.get_full_path( ) # file attachment only the first one attached fname = os.path.basename(file_url) fxlsx = re.search("^{}.*\.xlsx".format(self.doctype), fname) if (fxlsx): # match with open(file_url, "rb") as upfile: fcontent = upfile.read() if frappe.safe_encode(fname).lower().endswith( "xlsx".encode('utf-8')): from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file rows = read_xlsx_file_from_attached_file(fcontent=fcontent) columns = rows[0] rows.pop(0) data = rows try: for row in rows: name = row[0] full_name = row[1] isid = row[2] dm_id = row[3] if frappe.db.exists('MR', name): doc = frappe.get_doc('MR', name) doc.full_name = full_name doc.berno_id = isid doc.dm_id = dm_id doc.save() else: doc = frappe.get_doc({ "doctype": "MR", "name": name, "full_name": full_name, "email": name.lower() + "@ksp.ksp", "berno_id": isid, "dm_id": dm_id }).insert() frappe.db.commit() frappe.msgprint("Done") except: frappe.db.rollback() frappe.msgprint("Error has occurred") return {"columns": columns, "data": data} else: return { "status": "Error", "filename": fname, "doctype": self.doctype }
def create_csv_file(columns, data, dt, dn): csv_filename = '{0}.csv'.format( frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M")) rows = [tuple(columns)] + data encoded = base64.b64encode(frappe.safe_encode(to_csv(rows))) # Call save() file function to upload and attach the file _file = frappe.get_doc({ "doctype": "File", "file_name": csv_filename, "attached_to_doctype": dt, "attached_to_name": dn, "content": encoded, "decode": True }) _file.save()
def create_json_gz_file(data, dt, dn): # Storing data in CSV file causes information loss # Reports like P&L Statement were completely unsuable because of this json_filename = '{0}.json.gz'.format(frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M")) encoded_content = frappe.safe_encode(frappe.as_json(data)) # GZip compression seems to reduce storage requirements by 80-90% compressed_content = gzip_compress(encoded_content) save_file( fname=json_filename, content=compressed_content, dt=dt, dn=dn, folder=None, is_private=True)
def create_json_gz_file(data, dt, dn): # Storing data in CSV file causes information loss # Reports like P&L Statement were completely unsuable because of this json_filename = '{0}.json.gz'.format(frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M")) encoded_content = frappe.safe_encode(frappe.as_json(data)) # GZip compression seems to reduce storage requirements by 80-90% compressed_content = gzip_compress(encoded_content) save_file( fname=json_filename, content=compressed_content, dt=dt, dn=dn, folder=None, is_private=False)
def create_json_gz_file(data, dt, dn): # Storing data in CSV file causes information loss # Reports like P&L Statement were completely unsuable because of this json_filename = '{0}.json.gz'.format(frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M")) encoded_content = frappe.safe_encode(frappe.as_json(data)) compressed_content = gzip_compress(encoded_content) # Call save() file function to upload and attach the file _file = frappe.get_doc({ "doctype": "File", "file_name": json_filename, "attached_to_doctype": dt, "attached_to_name": dn, "content": compressed_content }) _file.save()
def setup_email_account(self, append_to=None, sender=None): self.email_account = get_outgoing_email_account(raise_exception_not_set=False, append_to=append_to, sender=sender) if self.email_account: self.server = self.email_account.smtp_server self.login = (getattr(self.email_account, "login_id", None) or self.email_account.email_id) if not self.email_account.no_smtp_authentication: if self.email_account.ascii_encode_password: self.password = frappe.safe_encode(self.email_account.password, 'ascii') else: self.password = self.email_account.password else: self.password = None self.port = self.email_account.smtp_port self.use_tls = self.email_account.use_tls self.sender = self.email_account.email_id self.always_use_account_email_id_as_sender = cint(self.email_account.get("always_use_account_email_id_as_sender"))
def get_untranslated(lang, untranslated_file, get_all=False): """Returns all untranslated strings for a language and writes in a file :param lang: Language code. :param untranslated_file: Output file path. :param get_all: Return all strings, translated or not.""" clear_cache() apps = frappe.get_all_apps(True) messages = [] untranslated = [] for app in apps: messages.extend(get_messages_for_app(app)) messages = deduplicate_messages(messages) def escape_newlines(s): return (s.replace("\\\n", "|||||").replace("\\n", "||||").replace("\n", "|||")) if get_all: print(str(len(messages)) + " messages") with open(untranslated_file, "w") as f: for m in messages: # replace \n with ||| so that internal linebreaks don't get split f.write((escape_newlines(m[1]) + os.linesep).encode("utf-8")) else: full_dict = get_full_dict(lang) for m in messages: if not full_dict.get(m[1]): untranslated.append(m[1]) if untranslated: print( str(len(untranslated)) + " missing translations of " + str(len(messages))) with open(untranslated_file, "w") as f: for m in untranslated: # replace \n with ||| so that internal linebreaks don't get split f.write( cstr( frappe.safe_encode( escape_newlines(m) + os.linesep))) else: print("all translated!")
def parseXLS(self): file_url = self.get_full_path( ) # file attachment only the first one attached fname = os.path.basename(file_url) fxlsx = re.search("^{}.*\.xlsx".format(self.doctype), fname) if (fxlsx): # match with open(file_url, "rb") as upfile: fcontent = upfile.read() if frappe.safe_encode(fname).lower().endswith( "xlsx".encode('utf-8')): from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file rows = read_xlsx_file_from_attached_file(fcontent=fcontent) columns = rows[0] rows.pop(0) data = rows return {"columns": columns, "data": data} else: return {"status": "Error", "filename": fname}
def parseXLS(self): file_url = self.get_full_path() # file attachment only the first one attached fname = os.path.basename(file_url) fxlsx = re.search("^{}.*\.xlsx".format("Dx"), fname) if(fxlsx): # match with open( file_url , "rb") as upfile: fcontent = upfile.read() if frappe.safe_encode(fname).lower().endswith("xlsx".encode('utf-8')): from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file rows = read_xlsx_file_from_attached_file(fcontent=fcontent) columns = rows[0] rows.pop(0) data = rows res = check_dx_list(self.name, rows) if res: columns[0] = '<span style="color:red">Error ID Not Found</span>' return {"columns": columns, "data": res, "filename": self.filename} frappe.enqueue(import_loan, name=self.name, rows=rows, now=True if len(rows) < 200 else False) return {"columns": columns, "data": data, "filename": self.filename} else: return {"status" : "Error", "filename": fname}
def append_email_to_sent_folder(self, message): email_server = None try: email_server = self.get_incoming_server(in_receive=True) except Exception: frappe.log_error( title=_("Error while connecting to email account {0}").format( self.name)) if not email_server: return email_server.connect() if email_server.imap: try: message = safe_encode(message) email_server.imap.append( "Sent", "\\Seen", imaplib.Time2Internaldate(time.time()), message) except Exception: frappe.log_error()
def get_payment_url(self): if self.reference_doctype != "Fees": data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["company", "customer_name"], as_dict=1) else: data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["student_name"], as_dict=1) data.update({"company": frappe.defaults.get_defaults().company}) controller = get_payment_gateway_controller(self.payment_gateway) controller.validate_transaction_currency(self.currency) if hasattr(controller, 'validate_minimum_transaction_amount'): controller.validate_minimum_transaction_amount(self.currency, self.grand_total) return controller.get_payment_url(**{ "amount": flt(self.grand_total, self.precision("grand_total")), "title": data.company.encode("utf-8"), "description": self.subject.encode("utf-8"), "reference_doctype": "Payment Request", "reference_docname": self.name, "payer_email": self.email_to or frappe.session.user, "payer_name": frappe.safe_encode(data.customer_name), "order_id": self.name, "currency": self.currency })
def prepare_message(email, recipient, recipients_list): message = email.message if not message: return "" # Parse "Email Account" from "Email Sender" email_account = get_outgoing_email_account(raise_exception_not_set=False, sender=email.sender) if frappe.conf.use_ssl and email_account.track_email_status: # Using SSL => Publically available domain => Email Read Reciept Possible message = message.replace( "<!--email open check-->", quopri.encodestring( '<img src="https://{}/api/method/frappe.core.doctype.communication.email.mark_email_as_seen?name={}"/>' .format(frappe.local.site, email.communication).encode()).decode()) else: # No SSL => No Email Read Reciept message = message.replace("<!--email open check-->", quopri.encodestring("".encode()).decode()) if email.add_unsubscribe_link and email.reference_doctype: # is missing the check for unsubscribe message but will not add as there will be no unsubscribe url unsubscribe_url = get_unsubcribed_url(email.reference_doctype, email.reference_name, recipient, email.unsubscribe_method, email.unsubscribe_params) message = message.replace( "<!--unsubscribe url-->", quopri.encodestring(unsubscribe_url.encode()).decode()) if email.expose_recipients == "header": pass else: if email.expose_recipients == "footer": if isinstance(email.show_as_cc, string_types): email.show_as_cc = email.show_as_cc.split(",") email_sent_to = [r.recipient for r in recipients_list] email_sent_cc = ", ".join( [e for e in email_sent_to if e in email.show_as_cc]) email_sent_to = ", ".join( [e for e in email_sent_to if e not in email.show_as_cc]) if email_sent_cc: email_sent_message = _( "This email was sent to {0} and copied to {1}").format( email_sent_to, email_sent_cc) else: email_sent_message = _("This email was sent to {0}").format( email_sent_to) message = message.replace( "<!--cc message-->", quopri.encodestring(email_sent_message.encode()).decode()) message = message.replace("<!--recipient-->", recipient) message = (message and message.encode('utf8')) or '' message = safe_decode(message) if PY3: from email.policy import SMTPUTF8 message = Parser(policy=SMTPUTF8).parsestr(message) else: message = Parser().parsestr(message) if email.attachments: # On-demand attachments attachments = json.loads(email.attachments) for attachment in attachments: if attachment.get('fcontent'): continue fid = attachment.get("fid") if fid: _file = frappe.get_doc("File", fid) fcontent = _file.get_content() attachment.update({ 'fname': _file.file_name, 'fcontent': fcontent, 'parent': message }) attachment.pop("fid", None) add_attachment(**attachment) elif attachment.get("print_format_attachment") == 1: attachment.pop("print_format_attachment", None) print_format_file = frappe.attach_print(**attachment) print_format_file.update({"parent": message}) add_attachment(**print_format_file) return safe_encode(message.as_string())