def upload_file_to_dropbox(filename, folder, dropbox_client): """upload files with chunk of 15 mb to reduce session append calls""" if not os.path.exists(filename): return create_folder_if_not_exists(folder, dropbox_client) chunk_size = 15 * 1024 * 1024 file_size = os.path.getsize(encode(filename)) mode = (dropbox.files.WriteMode.overwrite) f = open(encode(filename), 'rb') path = "{0}/{1}".format(folder, os.path.basename(filename)) try: if file_size <= chunk_size: dropbox_client.files_upload(f.read(), path, mode) else: upload_session_start_result = dropbox_client.files_upload_session_start(f.read(chunk_size)) cursor = dropbox.files.UploadSessionCursor(session_id=upload_session_start_result.session_id, offset=f.tell()) commit = dropbox.files.CommitInfo(path=path, mode=mode) while f.tell() < file_size: if ((file_size - f.tell()) <= chunk_size): dropbox_client.files_upload_session_finish(f.read(chunk_size), cursor, commit) else: dropbox_client.files_upload_session_append(f.read(chunk_size), cursor.session_id,cursor.offset) cursor.offset = f.tell() except dropbox.exceptions.ApiError as e: if isinstance(e.error, dropbox.files.UploadError): error = "File Path: {path}\n".format(path=path) error += frappe.get_traceback() frappe.log_error(error) else: raise
def make_error_snapshot(exception): if frappe.conf.disable_error_snapshot: return logger = frappe.get_logger() try: error_id = '{timestamp:s}-{ip:s}-{hash:s}'.format( timestamp=cstr(datetime.datetime.now()), ip=frappe.local.request_ip or '127.0.0.1', hash=frappe.generate_hash(length=3) ) snapshot_folder = get_error_snapshot_path() frappe.create_folder(snapshot_folder) snapshot_file_path = os.path.join(snapshot_folder, "{0}.json".format(error_id)) snapshot = get_snapshot(exception) with open(encode(snapshot_file_path), 'wb') as error_file: error_file.write(encode(frappe.as_json(snapshot))) logger.error('New Exception collected with id: {}'.format(error_id)) except Exception, e: logger.error('Could not take error snapshot: {0}'.format(e))
def execute(): """Fix the File records created via item.py even if the website_image file didn't exist""" for item in frappe.db.sql_list("""select name from `tabItem` where website_image is not null and website_image != '' and website_image like '/files/%' and exists ( select name from `tabFile` where attached_to_doctype='Item' and attached_to_name=`tabItem`.name and file_url=`tabItem`.website_image and (file_name is null or file_name = '') )"""): item = frappe.get_doc("Item", item) file = frappe.get_doc("File", { "attached_to_doctype": "Item", "attached_to_name": item.name, "file_url": item.website_image }) try: file.validate_file() except IOError: print encode(item.website_image), "does not exist" file.delete() item.db_set("website_image", None, update_modified=False)
def set_header(self, key, value): key = encode(key) value = encode(value) if self.msg_root.has_key(key): del self.msg_root[key] self.msg_root[key] = value
def decrypt(pwd): try: cipher_suite = Fernet(encode(get_encryption_key())) plain_text = cstr(cipher_suite.decrypt(encode(pwd))) return plain_text except InvalidToken: # encryption_key in site_config is changed and not valid frappe.throw(_('Encryption key is invalid, Please check site_config.json'))
def encrypt(pwd): if len(pwd) > 100: # encrypting > 100 chars will lead to truncation frappe.throw(_('Password cannot be more than 100 characters long')) cipher_suite = Fernet(encode(get_encryption_key())) cipher_text = cstr(cipher_suite.encrypt(encode(pwd))) return cipher_text
def _raise_exception(): if raise_exception: if flags.rollback_on_exception: db.rollback() import inspect if inspect.isclass(raise_exception) and issubclass(raise_exception, Exception): raise raise_exception(encode(msg)) else: raise ValidationError(encode(msg))
def __hash__(self): event_hash = hashlib.sha256() for key, value in sorted(self.items()): if 'time.observation' == key: continue event_hash.update(utils.encode(key)) event_hash.update(b'\xc0') event_hash.update(utils.encode(repr(value))) event_hash.update(b'\xc0') return int(event_hash.hexdigest(), 16)
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False: msgprint(_("Emails are muted")) from_test = True for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def send_one(email, smtpserver=None, auto_commit=True, now=False): '''Send Email Queue with given smtpserver''' email = frappe.db.sql('''select name, status, communication, message, sender, recipient, reference_doctype from `tabEmail Queue` where name=%s for update''', email, as_dict=True)[0] if email.status != 'Not Sent': # rollback to release lock and return frappe.db.rollback() return frappe.db.sql("""update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) try: if auto_commit: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email.sender, email.recipient, encode(email.message)) frappe.db.sql("""update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.rollback() frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s where name=%s""", (unicode(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) if now: raise e else: # log to scheduler log log('frappe.email.queue.flush', unicode(e))
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return try: response = dropbox_client.files_list_folder(dropbox_folder) except dropbox.exceptions.ApiError as e: # folder not found if isinstance(e.error, dropbox.files.ListFolderError): response = frappe._dict({"entries": []}) else: raise 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.entries: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int(file_metadata.size)): found = True break if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filename) error_log.append(frappe.get_traceback())
def upload_file_to_dropbox(filename, folder, dropbox_client): from dropbox import rest size = os.stat(encode(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, e: # if "[401] u'Access token not found.'", # it means that the user needs to again allow dropbox backup from the UI # so re-raise exc_message = cstr(e) if (exc_message.startswith("[401]") and dropbox_client.connection_reset_count < 10 and exc_message != "[401] u'Access token not found.'"): # session expired, so get a new connection! # [401] u"The given OAuth 2 access token doesn't exist or has expired." dropbox_client = get_dropbox_client(dropbox_client) else: raise else:
def get_website_settings(): hooks = frappe.get_hooks() all_top_items = frappe.db.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='top_bar_items' order by idx asc""", as_dict=1) top_items = [d for d in all_top_items if not d['parent_label']] # attach child items to top bar for d in all_top_items: if d['parent_label']: for t in top_items: if t['label']==d['parent_label']: if not 'child_items' in t: t['child_items'] = [] t['child_items'].append(d) break context = frappe._dict({ 'top_bar_items': top_items, 'footer_items': frappe.db.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='footer_items' order by idx asc""", as_dict=1), "post_login": [ {"label": "Reset Password", "url": "update-password", "icon": "icon-key"}, {"label": "Logout", "url": "?cmd=web_logout", "icon": "icon-signout"} ] }) settings = frappe.get_doc("Website Settings", "Website Settings") for k in ["banner_html", "brand_html", "copyright", "twitter_share_via", "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup"]: if hasattr(settings, k): context[k] = settings.get(k) if not context.get("favicon"): context["favicon"] = "/assets/frappe/images/favicon.ico" if settings.address: context["footer_address"] = settings.address for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup"]: context[k] = int(context.get(k) or 0) context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") context.encoded_title = quote(encode(context.title or ""), str("")) for update_website_context in hooks.update_website_context or []: frappe.get_attr(update_website_context)(context) context.web_include_js = hooks.web_include_js or [] context.web_include_css = hooks.web_include_css or [] return context
def zip_attachments(document): zip_count = 1 zip_size = 0 document = json.loads(document) document2 = frappe._dict(document) fname = get_file_name(document2.name + " (zip 1).zip", random_string(7)) import zipfile docZip = zipfile.ZipFile(fname,"w", zipfile.ZIP_DEFLATED) for file_url in frappe.db.sql("""select file_url, is_private from `tabFile` where attached_to_doctype = %(doctype)s and attached_to_name = %(docname)s""", {'doctype': document2.doctype, 'docname': document2.name}, as_dict=True ): frappe.msgprint("Adding " + file_url.file_url) if file_url.file_url.startswith("/private/files/"): path = get_files_path(*file_url.file_url.split("/private/files/", 1)[1].split("/"), is_private=1) elif file_url.file_url.startswith("/files/"): path = get_files_path(*file_url.file_url.split("/files/", 1)[1].split("/")) path = encode(path) if zip_size + os.path.getsize(path) > 10000000: zip_count = zip_count + 1 zip_size = 0 docZip.close() with open(encode(fname), 'r') as f: content = f.read() content = base64.b64encode(content) save_file(fname, content, document2.doctype, document2.name, "Home/Attachments", 1) fname = get_file_name(document2.name + " (zip " + str(zip_count) + ").zip", random_string(7)) docZip = zipfile.ZipFile(fname,"w", zipfile.ZIP_DEFLATED) docZip.write(path, os.path.basename(path)) zip_size = zip_size + docZip.getinfo(os.path.basename(path)).compress_size docZip.close() with open(encode(fname), 'r') as f: content = f.read() content = base64.b64encode(content) save_file(fname, content, document2.doctype, document2.name, "Home/Attachments", 1)
def send(self, message): message = utils.encode(message) for destination_queue in self.destination_queues: try: self.pipe.lpush(destination_queue, message) except Exception as exc: raise exceptions.PipelineError(exc)
def get_file(fname): """Returns [`file_name`, `content`] for given file name `fname`""" file_path = get_file_path(fname) # read the file with open(encode(file_path), 'r') as f: content = f.read() return [file_path.rsplit("/", 1)[-1], content]
def get_file(fname): """Returns [`file_name`, `content`] for given file name `fname`""" file_path = get_file_path(fname) # read the file if PY2: with open(encode(file_path)) as f: content = f.read() else: with io.open(encode(file_path), mode='rb') as f: content = f.read() try: # for plain text files content = content.decode() except UnicodeDecodeError: # for .png, .jpg, etc pass return [file_path.rsplit("/", 1)[-1], content]
def get_website_settings(): hooks = frappe.get_hooks() context = frappe._dict({ 'top_bar_items': get_items('top_bar_items'), 'footer_items': get_items('footer_items'), "post_login": [ {"label": _("My Account"), "url": "/me"}, # {"class": "divider"}, {"label": _("Logout"), "url": "/?cmd=web_logout"} ] }) settings = frappe.get_single("Website Settings") for k in ["banner_html", "brand_html", "copyright", "twitter_share_via", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup", "hide_footer_signup", "head_html", "title_prefix", "navbar_search"]: if hasattr(settings, k): context[k] = settings.get(k) if settings.address: context["footer_address"] = settings.address for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup"]: context[k] = int(context.get(k) or 0) if frappe.request: context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") context.encoded_title = quote(encode(context.title or ""), str("")) for update_website_context in hooks.update_website_context or []: frappe.get_attr(update_website_context)(context) context.web_include_js = hooks.web_include_js or [] context.web_include_css = hooks.web_include_css or [] via_hooks = frappe.get_hooks("website_context") for key in via_hooks: context[key] = via_hooks[key] if key not in ("top_bar_items", "footer_items", "post_login") \ and isinstance(context[key], (list, tuple)): context[key] = context[key][-1] add_website_theme(context) if not context.get("favicon"): context["favicon"] = "/assets/frappe/images/favicon.png" if settings.favicon and settings.favicon != "attach_files:": context["favicon"] = settings.favicon return context
def delete_file(path): """Delete file from `public folder`""" if path and path.startswith("/files/"): parts = os.path.split(path) path = frappe.utils.get_site_path("public", "files", parts[-1]) if "/../" in path: frappe.msgprint(_("It is risky to delete this file: {0}. Please contact your System Manager.").format(path)) path = encode(path) if os.path.exists(path): os.remove(path)
def delete_file_from_filesystem(doc): path = doc.file_name if path.startswith("files/"): path = frappe.utils.get_site_path("public", doc.file_name) else: path = frappe.utils.get_site_path("public", "files", doc.file_name) path = encode(path) if os.path.exists(path): os.remove(path)
def get_content(self): """Returns [`file_name`, `content`] for given file name `fname`""" if self.get('content'): return self.content file_path = self.get_full_path() # read the file if PY2: with open(encode(file_path)) as f: content = f.read() else: with io.open(encode(file_path), mode='rb') as f: content = f.read() try: # for plain text files content = content.decode() except UnicodeDecodeError: # for .png, .jpg, etc pass return content
def upload_file_to_dropbox(filename, folder, dropbox_client): """upload files with chunk of 15 mb to reduce session append calls""" if not os.path.exists(filename): return create_folder_if_not_exists(folder, dropbox_client) file_size = os.path.getsize(encode(filename)) chunk_size = get_chunk_site(file_size) mode = (dropbox.files.WriteMode.overwrite) f = open(encode(filename), 'rb') path = "{0}/{1}".format(folder, os.path.basename(filename)) try: if file_size <= chunk_size: dropbox_client.files_upload(f.read(), path, mode) else: upload_session_start_result = dropbox_client.files_upload_session_start( f.read(chunk_size)) cursor = dropbox.files.UploadSessionCursor( session_id=upload_session_start_result.session_id, offset=f.tell()) commit = dropbox.files.CommitInfo(path=path, mode=mode) while f.tell() < file_size: if ((file_size - f.tell()) <= chunk_size): dropbox_client.files_upload_session_finish( f.read(chunk_size), cursor, commit) else: dropbox_client.files_upload_session_append( f.read(chunk_size), cursor.session_id, cursor.offset) cursor.offset = f.tell() except dropbox.exceptions.ApiError as e: if isinstance(e.error, dropbox.files.UploadError): error = "File Path: {path}\n".format(path=path) error += frappe.get_traceback() frappe.log_error(error) else: raise
def save_file(self, content=None, decode=False, ignore_existing_file_check=False): file_exists = False self.content = content if decode: if isinstance(content, text_type): self.content = content.encode("utf-8") if b"," in self.content: self.content = self.content.split(b",")[1] self.content = base64.b64decode(self.content) if not self.is_private: self.is_private = 0 self.content_type = mimetypes.guess_type(self.file_name)[0] self.file_size = self.check_max_file_size() if ( self.content_type and "image" in self.content_type and frappe.get_system_settings("strip_exif_metadata_from_uploaded_images") ): self.content = strip_exif_data(self.content, self.content_type) self.content_hash = get_content_hash(self.content) duplicate_file = None # check if a file exists with the same content hash and is also in the same folder (public or private) if not ignore_existing_file_check: duplicate_file = frappe.get_value("File", { "content_hash": self.content_hash, "is_private": self.is_private }, ["file_url", "name"], as_dict=True) if duplicate_file: file_doc = frappe.get_cached_doc('File', duplicate_file.name) if file_doc.exists_on_disk(): self.file_url = duplicate_file.file_url file_exists = True if os.path.exists(encode(get_files_path(self.file_name, is_private=self.is_private))): self.file_name = get_file_name(self.file_name, self.content_hash[-6:]) if not file_exists: call_hook_method("before_write_file", file_size=self.file_size) write_file_method = get_hook_method('write_file') if write_file_method: return write_file_method(self) return self.save_file_on_filesystem()
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test # additional check check_bulk_limit([]) if frappe.are_emails_muted(): msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3""", auto_commit=auto_commit) for i in xrange(100): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by priority desc, creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql("""update `tabBulk Email` set status='Not Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit) finally:
def get_file_name(fname, optional_suffix): # convert to unicode fname = cstr(fname) n_records = frappe.db.sql("select name from `tabFile` where file_name=%s", fname) if len(n_records) > 0 or os.path.exists(encode(get_files_path(fname))): f = fname.rsplit('.', 1) if len(f) == 1: partial, extn = f[0], "" else: partial, extn = f[0], "." + f[1] return '{partial}{suffix}{extn}'.format(partial=partial, extn=extn, suffix=optional_suffix) return fname
def generate_calling_code(doc, method): country = frappe.defaults.get_defaults().get("country") docs = phone_format_docs() if doc.doctype in docs: if country: country_code = (frappe.db.get_value("Country", country, "code")).upper() field = docs[doc.doctype] if field and type(field) == list: for f in field: if doc.get(f): x = phonenumbers.parse(encode(doc.get(f)), (encode(country_code))) no_format = phonenumbers.format_number( x, phonenumbers.PhoneNumberFormat.INTERNATIONAL) doc.update({f: no_format}) elif field and doc.get(field): x = phonenumbers.parse(encode(doc.get(field)), (encode(country_code))) no_format = phonenumbers.format_number( x, phonenumbers.PhoneNumberFormat.INTERNATIONAL) doc.update({field: no_format})
def upload_file_to_dropbox(filename, folder, dropbox_client): create_folder_if_not_exists(folder, dropbox_client) chunk_size = 4 * 1024 * 1024 file_size = os.path.getsize(encode(filename)) mode = (dropbox.files.WriteMode.overwrite) f = open(encode(filename), 'rb') path = "{0}/{1}".format(folder, os.path.basename(filename)) if file_size <= chunk_size: dropbox_client.files_upload(f.read(), path, mode) else: upload_session_start_result = dropbox_client.files_upload_session_start(f.read(chunk_size)) cursor = dropbox.files.UploadSessionCursor(session_id=upload_session_start_result.session_id, offset=f.tell()) commit = dropbox.files.CommitInfo(path=path, mode=mode) while f.tell() < file_size: if ((file_size - f.tell()) <= chunk_size): dropbox_client.files_upload_session_finish(f.read(chunk_size), cursor, commit) else: dropbox_client.files_upload_session_append(f.read(chunk_size), cursor.session_id,cursor.offset) cursor.offset = f.tell()
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test # additional check check_bulk_limit([]) if frappe.are_emails_muted(): msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3 and status='Not Sent'""", auto_commit=auto_commit) for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by priority desc, creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql("""update `tabBulk Email` set status='Sending' where name=%s""", (email["name"],), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.replace_sender_in_email(email) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql("""update `tabBulk Email` set status='Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql("""update `tabBulk Email` set status='Not Sent' where name=%s""", (email["name"],), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def upload_from_folder(path, is_private, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return if is_fresh_upload(): response = get_uploaded_files_meta(dropbox_folder, dropbox_client) else: response = frappe._dict({"entries": []}) path = str(path) for f in frappe.get_all( "File", filters={ "is_folder": 0, "is_private": is_private, "uploaded_to_dropbox": 0 }, fields=["file_url", "name", "file_name"], ): if not f.file_url: continue filename = f.file_url.rsplit("/", 1)[-1] filepath = os.path.join(path, filename) if filename in ignore_list: continue found = False for file_metadata in response.entries: try: if os.path.basename( filepath) == file_metadata.name and os.stat( encode(filepath)).st_size == int( file_metadata.size): found = True update_file_dropbox_status(f.name) break except Exception: error_log.append(frappe.get_traceback()) if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) update_file_dropbox_status(f.name) except Exception: did_not_upload.append(filepath) error_log.append(frappe.get_traceback())
def delete_file(path): """Delete file from `public folder`""" if path and path.startswith("/files/"): parts = os.path.split(path) path = frappe.utils.get_site_path("public", "files", parts[-1]) if ".." in path.split("/"): frappe.msgprint( _("It is risky to delete this file: {0}. Please contact your System Manager." ).format(path)) path = encode(path) if os.path.exists(path): os.remove(path)
def upload_file_to_dropbox(filename, folder, dropbox_client): from dropbox import rest size = os.stat(encode(filename)).st_size with open(encode(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 as e: # if "[401] u'Access token not found.'", # it means that the user needs to again allow dropbox backup from the UI # so re-raise exc_message = cstr(e) if (exc_message.startswith("[401]") and dropbox_client.connection_reset_count < 10 and exc_message != "[401] u'Access token not found.'"): # session expired, so get a new connection! # [401] u"The given OAuth 2 access token doesn't exist or has expired." dropbox_client = get_dropbox_client(dropbox_client) else: raise else: dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) return dropbox_client
def upload_from_folder(path, is_private, ftp_folder, ftp_client, did_not_upload, error_log): if not os.path.exists(path): return if is_fresh_upload(): response = get_uploaded_files_meta(ftp_folder, ftp_client) else: response = frappe._dict({"entries": []}) path = text_type(path) for f in frappe.get_all("File", filters={ "is_folder": 0, "is_private": is_private, "uploaded_to_ftp": 0 }, fields=['file_url', 'name', 'file_name']): if is_private: filename = f.file_url.replace('/private/files/', '') else: if not f.file_url: f.file_url = '/files/' + f.file_name filename = f.file_url.replace('/files/', '') filepath = os.path.join(path, filename) if filename in ignore_list: continue found = False for file_metadata in response.entries: try: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int( file_metadata.size)): found = True update_file_ftp_status(f.name) break except Exception: error_log.append(frappe.get_traceback()) if not found: try: upload_file_to_ftp(filepath, ftp_folder, ftp_client) update_file_ftp_status(f.name) except Exception: did_not_upload.append(filepath) error_log.append(frappe.get_traceback())
def get_file(fname): """Returns [`file_name`, `content`] for given file name `fname`""" file_path = get_file_path(fname) # read the file with io.open(encode(file_path), mode='rb') as f: content = f.read() try: # for plain text files content = content.decode() except UnicodeDecodeError: # for .png, .jpg, etc pass return [file_path.rsplit("/", 1)[-1], content]
def delete_file(path): """Delete file from `public folder`""" if path: if ".." in path.split("/"): frappe.msgprint(_("It is risky to delete this file: {0}. Please contact your System Manager.").format(path)) parts = os.path.split(path.strip("/")) if parts[0]=="files": path = frappe.utils.get_site_path("public", "files", parts[-1]) else: path = frappe.utils.get_site_path("private", "files", parts[-1]) path = encode(path) if os.path.exists(path): os.remove(path)
def flush(from_test=False): """flush email queue, every time: called from scheduler""" smtpserver = SMTPServer() auto_commit = not from_test if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False: msgprint(_("Emails are muted")) from_test = True frappe.db.sql("""update `tabBulk Email` set status='Expired' where datediff(curdate(), creation) > 3""", auto_commit=auto_commit) for i in xrange(500): email = frappe.db.sql("""select * from `tabBulk Email` where status='Not Sent' and ifnull(send_after, "2000-01-01 00:00:00") < %s order by creation asc limit 1 for update""", now_datetime(), as_dict=1) if email: email = email[0] else: break frappe.db.sql( """update `tabBulk Email` set status='Sending' where name=%s""", (email["name"], ), auto_commit=auto_commit) try: if not from_test: smtpserver.setup_email_account(email.reference_doctype) smtpserver.sess.sendmail(email["sender"], email["recipient"], encode(email["message"])) frappe.db.sql( """update `tabBulk Email` set status='Sent' where name=%s""", (email["name"], ), auto_commit=auto_commit) except Exception, e: frappe.db.sql( """update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email["name"]), auto_commit=auto_commit)
def cash_out_process(): date = today() cash_out_invoices = frappe.db.sql("""select description from `tabCash Out` where date = '%s' and docstatus=1""" % (date)) inv_list = [(e).split(",") for ele in cash_out_invoices for e in ele] inv_list = [encode(e) for ele in inv_list for e in ele] if len(inv_list) > 1: inv_list = tuple(inv_list) elif len(inv_list) == 1: inv_list = "(" + "'" + inv_list[0] + "'" + ")" frappe.errprint(inv_list) query = """select m.mode_of_payment, sum(m.amount) as amount, GROUP_CONCAT(s.name SEPARATOR ',') as invoices from `tabSales Invoice` s left join `tabMode of Pay` m on s.name = m.parent where s.docstatus = 1 and m.mode_of_payment = "Cash" and s.posting_date = '%s' """ % (date) query += "and s.name not in {0} group by s.posting_date".format( inv_list) if inv_list else "group by s.posting_date" invoices_data = frappe.db.sql(query, as_dict=1) if invoices_data: cash_acc = frappe.db.get_value("Mode of Payment Account", {"parent": "Cash"}, "default_account") cash_out_acc = frappe.db.get_value("Account", {"account_name": "Cash Out"}, "name") if not cash_out_acc: cash_out_acc = create_cash_out_acc() jv_name = make_cash_out_jv(cash_acc, cash_out_acc, invoices_data[0]) make_cash_out_form(invoices_data[0], jv_name) else: frappe.msgprint("Nothing to Cash Out")
def save_file(self, content=None, decode=False, ignore_existing_file_check=False): file_exists = False self.content = content if decode: if isinstance(content, text_type): self.content = content.encode("utf-8") if b"," in self.content: self.content = self.content.split(b",")[1] self.content = base64.b64decode(self.content) if not self.is_private: self.is_private = 0 self.file_size = self.check_max_file_size() self.content_hash = get_content_hash(self.content) self.content_type = mimetypes.guess_type(self.file_name)[0] _file = False # check if a file exists with the same content hash and is also in the same folder (public or private) if not ignore_existing_file_check: _file = frappe.get_value("File", { "content_hash": self.content_hash, "is_private": self.is_private }, ["file_url"]) if _file: self.file_url = _file file_exists = True if not file_exists: if os.path.exists(encode(get_files_path(self.file_name))): self.file_name = get_file_name(self.file_name, self.content_hash[-6:]) call_hook_method("before_write_file", file_size=self.file_size) write_file_method = get_hook_method('write_file') if write_file_method: return write_file_method(self) return self.save_file_on_filesystem()
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): import dropbox.rest if not os.path.exists(path): return try: response = dropbox_client.metadata(dropbox_folder) except dropbox.rest.ErrorResponse as e: # folder not found if e.status == 404: response = {"contents": []} else: raise 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(encode(filepath)).st_size == int( file_metadata["bytes"])): found = True break if not found: try: dropbox_client = upload_file_to_dropbox( filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filename) error_log.append(frappe.get_traceback()) return dropbox_client
def upload_file_to_ftp(filename, folder, ftp_client): """upload files with chunk of 15 mb to reduce session append calls""" if not os.path.exists(filename): return with open(encode(filename), 'rb') as f: path = "{0}/{1}".format(folder, os.path.basename(filename)) try: create_folder_if_not_exists(ftp_client, folder) pwd = ftp_client.pwd() ftp_client.cwd(folder) ftp_client.storbinary('STOR %s' % os.path.basename(filename), f) ftp_client.cwd(pwd) except Exception: error = "File Path: {path}\n".format(path=path) error += frappe.get_traceback() frappe.log_error(error) print (error)
def send_one(email, smtpserver=None, auto_commit=True, now=False): '''Send bulk email with given smtpserver''' if not smtpserver: smtpserver = SMTPServer() frappe.db.sql( """update `tabBulk Email` set status='Sending' where name=%s""", (email.name, ), auto_commit=auto_commit) try: if auto_commit: smtpserver.setup_email_account(email.reference_doctype) smtpserver.replace_sender_in_email(email) smtpserver.sess.sendmail(email.sender, email.recipient, encode(email.message)) frappe.db.sql( """update `tabBulk Email` set status='Sent' where name=%s""", (email.name, ), auto_commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError): # bad connection, retry later frappe.db.sql( """update `tabBulk Email` set status='Not Sent' where name=%s""", (email.name, ), auto_commit=auto_commit) # no need to attempt further return except Exception, e: frappe.db.sql("""update `tabBulk Email` set status='Error', error=%s where name=%s""", (unicode(e), email.name), auto_commit=auto_commit) if now: raise e
def upload_from_folder(path, is_private, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return if is_fresh_upload(): response = get_uploaded_files_meta(dropbox_folder, dropbox_client) else: response = frappe._dict({"entries": []}) path = text_type(path) for f in frappe.get_all("File", filters={"is_folder": 0, "is_private": is_private, "uploaded_to_dropbox": 0}, fields=['file_url', 'name', 'file_name']): if is_private: filename = f.file_url.replace('/private/files/', '') else: if not f.file_url: f.file_url = '/files/' + f.file_name; filename = f.file_url.replace('/files/', '') filepath = os.path.join(path, filename) if filename in ignore_list: continue found = False for file_metadata in response.entries: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int(file_metadata.size)): found = True update_file_dropbox_status(f.name) break if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) update_file_dropbox_status(f.name) except Exception: did_not_upload.append(filepath) error_log.append(frappe.get_traceback())
def get_content(self): """Returns [`file_name`, `content`] for given file name `fname`""" if self.is_folder: frappe.throw(_("Cannot get file contents of a Folder")) if self.get('content'): return self.content self.validate_url() file_path = self.get_full_path() # read the file with io.open(encode(file_path), mode='rb') as f: content = f.read() try: # for plain text files content = content.decode() except UnicodeDecodeError: # for .png, .jpg, etc pass return content
def cash_out_process(): date = today() cash_out_invoices = frappe.db.sql("""select description from `tabCash Out` where date = '%s' and docstatus=1"""%(date)) inv_list = [(e).split(",") for ele in cash_out_invoices for e in ele] inv_list = [encode(e) for ele in inv_list for e in ele] if len(inv_list) > 1: inv_list = tuple(inv_list) elif len(inv_list) == 1: inv_list = "("+"'"+inv_list[0]+"'"+")" frappe.errprint(inv_list) query = """select m.mode_of_payment, sum(m.amount) as amount, GROUP_CONCAT(s.name SEPARATOR ',') as invoices from `tabSales Invoice` s left join `tabMode of Pay` m on s.name = m.parent where s.docstatus = 1 and m.mode_of_payment = "Cash" and s.posting_date = '%s' """%(date) query += "and s.name not in {0} group by s.posting_date".format(inv_list) if inv_list else "group by s.posting_date" invoices_data = frappe.db.sql(query,as_dict=1) if invoices_data: cash_acc = frappe.db.get_value("Mode of Payment Account", {"parent": "Cash"}, "default_account") cash_out_acc = frappe.db.get_value("Account", {"account_name": "Cash Out"}, "name") if not cash_out_acc: cash_out_acc = create_cash_out_acc(); jv_name = make_cash_out_jv(cash_acc, cash_out_acc, invoices_data[0]); make_cash_out_form(invoices_data[0], jv_name) else: frappe.msgprint("Nothing to Cash Out")
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return try: response = dropbox_client.files_list_folder(dropbox_folder) except dropbox.exceptions.ApiError as e: # folder not found if isinstance(e.error, dropbox.files.ListFolderError): response = frappe._dict({"entries": []}) else: raise path = text_type(path) for root, directory, files in os.walk(path): for filename in files: filename = cstr(filename) filepath = os.path.join(root, filename) if filename in ignore_list: continue found = False for file_metadata in response.entries: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int( file_metadata.size)): found = True break if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filepath) error_log.append(frappe.get_traceback())
def get_website_settings(): hooks = frappe.get_hooks() context = frappe._dict({ 'top_bar_items': get_items('top_bar_items'), 'footer_items': get_items('footer_items'), "post_login": [ { "label": _("My Account"), "url": "/me" }, # {"class": "divider"}, { "label": _("Logout"), "url": "/?cmd=web_logout" } ] }) settings = frappe.get_single("Website Settings") for k in [ "banner_html", "brand_html", "copyright", "twitter_share_via", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup", "hide_footer_signup", "head_html", "title_prefix", "navbar_search" ]: if hasattr(settings, k): context[k] = settings.get(k) if settings.address: context["footer_address"] = settings.address for k in [ "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup" ]: context[k] = int(context.get(k) or 0) if frappe.request: context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") context.encoded_title = quote(encode(context.title or ""), str("")) for update_website_context in hooks.update_website_context or []: frappe.get_attr(update_website_context)(context) context.web_include_js = hooks.web_include_js or [] context.web_include_css = hooks.web_include_css or [] via_hooks = frappe.get_hooks("website_context") for key in via_hooks: context[key] = via_hooks[key] if key not in ("top_bar_items", "footer_items", "post_login") \ and isinstance(context[key], (list, tuple)): context[key] = context[key][-1] add_website_theme(context) if not context.get("favicon"): context["favicon"] = "/assets/frappe/images/favicon.png" if settings.favicon and settings.favicon != "attach_files:": context["favicon"] = settings.favicon return context
def post(self, action, data, raise_on_empty=False): if not isinstance(data, dict): raise BioTrackClientError("data must be instance of dict") log = {} data["action"] = action action_data = data.copy() data.update({ "license_number": self.license_number, "username": self.username, "password": self.password, "training": self.is_training, "API": self.__API__, }) if action != 'login': data["nosession"] = 1 log["request"] = action_data print_log(data, " - Request Data") service = get_integration_controller("BioTrack") integration_req = service.create_request(log) integration_req.action = action integration_req.integration_type = "Remote" request = get_request_session() # catch network errors try: response = request.post(self.__API_URL__, data=json.dumps(data), headers={'Content-Type': 'application/json'}) except Exception as e: raise BioTrackClientError(e.message) response.raise_for_status() result = response.json() if not action.startswith("sync_"): log["response"] = result print_log(result, " - Response") else: log["response"] = {"success": result.get('success')} integration_req.data = json.dumps(log) if not result.get('success'): integration_req.status = 'Failed' integration_req.save() raise BioTrackClientError(encode(result.get('error'))) if raise_on_empty and len(result) == 1: integration_req.status = 'Failed' integration_req.save() raise BioTrackEmptyDataError( 'BioTrackTHC request was response with empty data: {}'.format(json.dumps(action_data)) ) integration_req.status = 'Completed' integration_req.save() return result
def encrypt(pwd): cipher_suite = Fernet(encode(get_encryption_key())) cipher_text = cstr(cipher_suite.encrypt(encode(pwd))) return cipher_text
response = {"contents": []} else: raise 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(encode(filepath)).st_size == int( file_metadata["bytes"])): found = True break if not found: try: dropbox_client = upload_file_to_dropbox( filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filename) error_log.append(frappe.get_traceback()) return dropbox_client
def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=False): '''Send Email Queue with given smtpserver''' email = frappe.db.sql('''select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, show_as_cc, add_unsubscribe_link, attachments from `tabEmail Queue` where name=%s for update''', email, as_dict=True)[0] recipients_list = frappe.db.sql('''select name, recipient, status from `tabEmail Queue Recipient` where parent=%s''', email.name, as_dict=1) if frappe.are_emails_muted(): frappe.msgprint(_("Emails are muted")) return if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1: return if email.status not in ('Not Sent', 'Partially Sent'): # rollback to release lock and return frappe.db.rollback() return frappe.db.sql( """update `tabEmail Queue` set status='Sending', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) try: if not frappe.flags.in_test: if not smtpserver: smtpserver = SMTPServer() smtpserver.setup_email_account(email.reference_doctype, sender=email.sender) for recipient in recipients_list: if recipient.status != "Not Sent": continue message = prepare_message(email, recipient.recipient, recipients_list) if not frappe.flags.in_test: smtpserver.sess.sendmail(email.sender, recipient.recipient, encode(message)) recipient.status = "Sent" frappe.db.sql( """update `tabEmail Queue Recipient` set status='Sent', modified=%s where name=%s""", (now_datetime(), recipient.name), auto_commit=auto_commit) #if all are sent set status if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", ("No recipients to send to", email.name), auto_commit=auto_commit) if frappe.flags.in_test: frappe.flags.sent_mail = message return if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) except (smtplib.SMTPServerDisconnected, smtplib.SMTPConnectError, smtplib.SMTPHeloError, smtplib.SMTPAuthenticationError, JobTimeoutException): # bad connection/timeout, retry later if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Partially Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Not Sent', modified=%s where name=%s""", (now_datetime(), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) # no need to attempt further return except Exception as e: frappe.db.rollback() if any("Sent" == s.status for s in recipients_list): frappe.db.sql( """update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) else: frappe.db.sql( """update `tabEmail Queue` set status='Error', error=%s where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc( 'Communication', email.communication).set_delivery_status(commit=auto_commit) if now: print(frappe.get_traceback()) raise e else: # log to Error Log log('frappe.email.queue.flush', text_type(e))
def writerow(self, row): row = encode(row, self.encoding) self.writer.writerow(row)
def writerow(self, row): if six.PY2: row = encode(row, self.encoding) self.writer.writerow(row)
def post(self, action, data, raise_on_empty=False): if not isinstance(data, dict): raise BioTrackClientError("data must be instance of dict") log = {} data["action"] = action action_data = data.copy() data.update({ "license_number": self.license_number, "username": self.username, "password": self.password, "training": self.is_training, "API": self.__API__, }) if action != 'login': data["nosession"] = 1 log["request"] = action_data print_log(data, " - Request Data") service = get_integration_controller("BioTrack") integration_req = service.create_request(log) integration_req.action = action integration_req.integration_type = "Remote" request = get_request_session() # catch network errors try: response = request.post( self.__API_URL__, data=json.dumps(data), headers={'Content-Type': 'application/json'}) except Exception as e: raise BioTrackClientError(e.message) response.raise_for_status() result = response.json() if not action.startswith("sync_"): log["response"] = result print_log(result, " - Response") else: log["response"] = {"success": result.get('success')} integration_req.data = json.dumps(log) if not result.get('success'): integration_req.status = 'Failed' integration_req.save() raise BioTrackClientError(encode(result.get('error'))) if raise_on_empty and len(result) == 1: integration_req.status = 'Failed' integration_req.save() raise BioTrackEmptyDataError( 'BioTrackTHC request was response with empty data: {}'.format( json.dumps(action_data))) integration_req.status = 'Completed' integration_req.save() return result
def get_website_settings(): hooks = frappe.get_hooks() all_top_items = frappe.db.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='top_bar_items' order by idx asc""", as_dict=1) top_items = [d for d in all_top_items if not d['parent_label']] # attach child items to top bar for d in all_top_items: if d['parent_label']: for t in top_items: if t['label'] == d['parent_label']: if not 'child_items' in t: t['child_items'] = [] t['child_items'].append(d) break context = frappe._dict({ 'top_bar_items': top_items, 'footer_items': frappe.db.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='footer_items' order by idx asc""", as_dict=1), "post_login": [{ "label": "Reset Password", "url": "update-password", "icon": "icon-key" }, { "label": "Logout", "url": "?cmd=web_logout", "icon": "icon-signout" }] }) settings = frappe.get_doc("Website Settings", "Website Settings") for k in [ "banner_html", "brand_html", "copyright", "twitter_share_via", "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup", "no_sidebar" ]: if hasattr(settings, k): context[k] = settings.get(k) if not context.get("favicon"): context["favicon"] = "/assets/frappe/images/favicon.ico" if settings.address: context["footer_address"] = settings.address for k in [ "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "disable_signup" ]: context[k] = int(context.get(k) or 0) context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") context.encoded_title = quote(encode(context.title or ""), str("")) for update_website_context in hooks.update_website_context or []: frappe.get_attr(update_website_context)(context) context.web_include_js = hooks.web_include_js or [] context.web_include_css = hooks.web_include_css or [] return context
def get_snapshot(exception, context=10): """ Return a dict describing a given traceback (based on cgitb.text) """ etype, evalue, etb = sys.exc_info() if isinstance(etype, types.ClassType): etype = etype.__name__ # creates a snapshot dict with some basic information s = { 'pyver': 'Python {version:s}: {executable:s} (prefix: {prefix:s})'.format( version = sys.version.split()[0], executable = sys.executable, prefix = sys.prefix ), 'timestamp': cstr(datetime.datetime.now()), 'traceback': traceback.format_exc(), 'frames': [], 'etype': cstr(etype), 'evalue': cstr(evalue), 'exception': {}, 'locals': {} } # start to process frames records = inspect.getinnerframes(etb, 5) for frame, file, lnum, func, lines, index in records: file = file and os.path.abspath(file) or '?' args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': call = inspect.formatargvalues(args, varargs, varkw, locals, formatvalue=lambda value: '={}'.format(pydoc.text.repr(value))) # basic frame information f = {'file': file, 'func': func, 'call': call, 'lines': {}, 'lnum': lnum} def reader(lnum=[lnum]): try: return linecache.getline(file, lnum[0]) finally: lnum[0] += 1 vars = cgitb.scanvars(reader, frame, locals) # if it is a view, replace with generated code # if file.endswith('html'): # lmin = lnum > context and (lnum - context) or 0 # lmax = lnum + context # lines = code.split("\n")[lmin:lmax] # index = min(context, lnum) - 1 if index is not None: i = lnum - index for line in lines: f['lines'][i] = line.rstrip() i += 1 # dump local variable (referenced in current line only) f['dump'] = {} for name, where, value in vars: if name in f['dump']: continue if value is not cgitb.__UNDEF__: if where == 'global': name = 'global {name:s}'.format(name=name) elif where != 'local': name = where + ' ' + name.split('.')[-1] f['dump'][name] = pydoc.text.repr(value) else: f['dump'][name] = 'undefined' s['frames'].append(f) # add exception type, value and attributes if isinstance(evalue, BaseException): for name in dir(evalue): # prevent py26 DeprecationWarning if (name != 'messages' or sys.version_info < (2.6)) and not name.startswith('__'): value = pydoc.text.repr(getattr(evalue, name)) # render multilingual string properly if type(value)==str and value.startswith(b"u'"): value = eval(value) s['exception'][name] = encode(value) # add all local values (of last frame) to the snapshot for name, value in locals.items(): if type(value)==str and value.startswith(b"u'"): value = eval(value) s['locals'][name] = pydoc.text.repr(value) return s
def get_snapshot(exception, context=10): """ Return a dict describing a given traceback (based on cgitb.text) """ etype, evalue, etb = sys.exc_info() if isinstance(etype, types.ClassType): etype = etype.__name__ # creates a snapshot dict with some basic information s = { 'pyver': 'Python {version:s}: {executable:s} (prefix: {prefix:s})'.format( version=sys.version.split()[0], executable=sys.executable, prefix=sys.prefix), 'timestamp': cstr(datetime.datetime.now()), 'traceback': traceback.format_exc(), 'frames': [], 'etype': cstr(etype), 'evalue': cstr( ` evalue `), 'exception': {}, 'locals': {} } # start to process frames records = inspect.getinnerframes(etb, 5) for frame, file, lnum, func, lines, index in records: file = file and os.path.abspath(file) or '?' args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': call = inspect.formatargvalues( args, varargs, varkw, locals, formatvalue=lambda value: '={}'.format(pydoc.text.repr(value))) # basic frame information f = { 'file': file, 'func': func, 'call': call, 'lines': {}, 'lnum': lnum } def reader(lnum=[lnum]): try: return linecache.getline(file, lnum[0]) finally: lnum[0] += 1 vars = cgitb.scanvars(reader, frame, locals) # if it is a view, replace with generated code # if file.endswith('html'): # lmin = lnum > context and (lnum - context) or 0 # lmax = lnum + context # lines = code.split("\n")[lmin:lmax] # index = min(context, lnum) - 1 if index is not None: i = lnum - index for line in lines: f['lines'][i] = line.rstrip() i += 1 # dump local variable (referenced in current line only) f['dump'] = {} for name, where, value in vars: if name in f['dump']: continue if value is not cgitb.__UNDEF__: if where == 'global': name = 'global {name:s}'.format(name=name) elif where != 'local': name = where + ' ' + name.split('.')[-1] f['dump'][name] = pydoc.text.repr(value) else: f['dump'][name] = 'undefined' s['frames'].append(f) # add exception type, value and attributes if isinstance(evalue, BaseException): for name in dir(evalue): # prevent py26 DeprecationWarning if (name != 'messages' or sys.version_info < (2.6)) and not name.startswith('__'): value = pydoc.text.repr(getattr(evalue, name)) # render multilingual string properly if type(value) == str and value.startswith(b"u'"): value = eval(value) s['exception'][name] = encode(value) # add all local values (of last frame) to the snapshot for name, value in locals.items(): if type(value) == str and value.startswith(b"u'"): value = eval(value) s['locals'][name] = pydoc.text.repr(value) return s
def make_boilerplate(dest, app_name): if not os.path.exists(dest): print("Destination directory does not exist") return # app_name should be in snake_case app_name = frappe.scrub(app_name) hooks = frappe._dict() hooks.app_name = app_name app_title = hooks.app_name.replace("_", " ").title() for key in ("App Title (default: {0})".format(app_title), "App Description", "App Publisher", "App Email", "App Icon (default 'octicon octicon-file-directory')", "App Color (default 'grey')", "App License (default 'MIT')"): hook_key = key.split(" (")[0].lower().replace(" ", "_") hook_val = None while not hook_val: hook_val = cstr(raw_input(key + ": ")) if not hook_val: defaults = { "app_title": app_title, "app_icon": "octicon octicon-file-directory", "app_color": "grey", "app_license": "MIT" } if hook_key in defaults: hook_val = defaults[hook_key] if hook_key == "app_name" and hook_val.lower().replace( " ", "_") != hook_val: print("App Name must be all lowercase and without spaces") hook_val = "" elif hook_key == "app_title" and not re.match( "^(?![\W])[^\d_\s][\w -]+$", hook_val, re.UNICODE): print( "App Title should start with a letter and it can only consist of letters, numbers, spaces and underscores" ) hook_val = "" hooks[hook_key] = hook_val frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), with_init=True) frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True) frappe.create_folder( os.path.join(dest, hooks.app_name, hooks.app_name, "www")) frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates", "pages"), with_init=True) frappe.create_folder( os.path.join(dest, hooks.app_name, hooks.app_name, "templates", "includes")) frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "config"), with_init=True) frappe.create_folder( os.path.join(dest, hooks.app_name, hooks.app_name, "public", "css")) frappe.create_folder( os.path.join(dest, hooks.app_name, hooks.app_name, "public", "js")) with open( os.path.join(dest, hooks.app_name, hooks.app_name, "__init__.py"), "w") as f: f.write(encode(init_template)) with open(os.path.join(dest, hooks.app_name, "MANIFEST.in"), "w") as f: f.write(encode(manifest_template.format(**hooks))) with open(os.path.join(dest, hooks.app_name, ".gitignore"), "w") as f: f.write(encode(gitignore_template.format(app_name=hooks.app_name))) with open(os.path.join(dest, hooks.app_name, "setup.py"), "w") as f: f.write(encode(setup_template.format(**hooks))) with open(os.path.join(dest, hooks.app_name, "requirements.txt"), "w") as f: f.write("frappe") with open(os.path.join(dest, hooks.app_name, "README.md"), "w") as f: f.write( encode("## {0}\n\n{1}\n\n#### License\n\n{2}".format( hooks.app_title, hooks.app_description, hooks.app_license))) with open(os.path.join(dest, hooks.app_name, "license.txt"), "w") as f: f.write(encode("License: " + hooks.app_license)) with open( os.path.join(dest, hooks.app_name, hooks.app_name, "modules.txt"), "w") as f: f.write(encode(hooks.app_title)) with open(os.path.join(dest, hooks.app_name, hooks.app_name, "hooks.py"), "w") as f: f.write(encode(hooks_template.format(**hooks))) touch_file( os.path.join(dest, hooks.app_name, hooks.app_name, "patches.txt")) with open( os.path.join(dest, hooks.app_name, hooks.app_name, "config", "desktop.py"), "w") as f: f.write(encode(desktop_template.format(**hooks))) with open( os.path.join(dest, hooks.app_name, hooks.app_name, "config", "docs.py"), "w") as f: f.write(encode(docs_template.format(**hooks))) print("'{app}' created at {path}".format(app=app_name, path=os.path.join(dest, app_name)))