def handle_download_request(self, download_item): ''' Handle download request.''' if self.should_skip_download_item(download_item): return download_data = download_item.url().toString() if download_data.startswith("data:image/"): image_path = os.path.join( os.path.expanduser( self.emacs_var_dict["eaf-browser-download-path"]), "image.png") touch(image_path) with open(image_path, "wb") as f: f.write( base64.decodestring( download_data.split(",")[1].encode("utf-8"))) message_to_emacs("Save image: " + image_path) else: self.try_start_aria2_daemon() from core.pyaria2 import Jsonrpc download_url = download_item.url().toString() jsonrpc = Jsonrpc('localhost', 6800) resp = jsonrpc.addUris(download_url) message_to_emacs("Downloading: " + download_url)
def save_org_file(self): file_path = self.get_save_path("org") touch(file_path) eval_in_emacs( 'eaf--export-org-json', [self.buffer_widget.execute_js("save_file();"), file_path]) message_to_emacs("Save org file: " + file_path)
def atomic_edit(self): ''' Edit the focus text.''' text = self.buffer_widget.get_focus_text() if text != None: atomic_edit(self.buffer_id, text) else: message_to_emacs("No active input element.")
def copy_text(self): text = self.buffer_widget.execute_js("get_selection();") if text == "": message_to_emacs("Nothing selected") else: self.set_clipboard_text(text) message_to_emacs("Copy text")
def destroy_buffer(self): global local_file_path message_to_emacs("Stop file sender server: http://{0}:{1}/{2}".format(self.local_ip, self.port, local_file_path)) self.sender_thread.stop() super().destroy_buffer()
def cut_node_tree(self): self.cut_node_id = self.buffer_widget.execute_js("get_selected_nodeid();") if self.cut_node_id: if self.cut_node_id != "root": message_to_emacs("Root node not allowed cut.") else: message_to_emacs("Cut node tree: {}".format(self.cut_node_id))
def save_screenshot_data(self, download_data): image_path = self.get_save_path("png") touch(image_path) with open(image_path, "wb") as f: f.write(base64.decodestring(download_data.split("data:image/png;base64,")[1].encode("utf-8"))) message_to_emacs("Save image: " + image_path)
def save_freemind_file(self, notify=True): file_path = self.get_save_path("mm") with open(file_path, "w") as f: f.write(self.buffer_widget.execute_js("save_freemind_file();")) if notify: message_to_emacs("Save freemind file: " + file_path)
def save_as_single_file(self): ''' Request to save current webpage as single html file.''' import shutil if shutil.which("monolith") is None: message_to_emacs("Executable monolith not in PATH") else: self.send_input_message("Save current webpage as single html file?", "save_as_single_file", "yes-or-no")
def run(self): while self.running_flag: ## In some cases, the markers may not be ready when fetch_marker_callback is first called, ## so we need to call fetch_marker_callback multiple times. if self.markers is None or len(self.markers) == 0: self.markers = self.fetch_marker_callback() minibuffer_input = get_emacs_func_result( "minibuffer-contents-no-properties", []) marker_input_quit = len(minibuffer_input) > 0 and minibuffer_input[ -1] in self.marker_quit_keys marker_input_finish = minibuffer_input in self.markers if marker_input_quit: self.running_flag = False eval_in_emacs('exit-minibuffer', []) message_to_emacs("Quit marker selection.") self.match_marker.emit(self.callback_tag, minibuffer_input) elif marker_input_finish: self.running_flag = False eval_in_emacs('exit-minibuffer', []) message_to_emacs("Marker selected.") self.match_marker.emit(self.callback_tag, minibuffer_input) time.sleep(0.1)
def save_page_password(self): ''' Record form data.''' if self.emacs_var_dict["eaf-browser-enable-autofill"] == "true": self.add_password_entry() else: message_to_emacs( "Password autofill is not enabled! Enable with `C-t` (default binding)" )
def take_photo(self): if os.path.exists(os.path.expanduser(get_emacs_var("eaf-camera-save-path"))): location = get_emacs_var("eaf-camera-save-path") else: location = "~/Downloads" result = self.buffer_widget.take_photo(location) if result: message_to_emacs("Captured Photo at " + location)
def add_multiple_middle_nodes(self): node_id = self.buffer_widget.execute_js("_jm.get_selected_node();") if node_id == None: message_to_emacs("No selected node.") elif not self.buffer_widget.execute_js("_jm.get_selected_node().parent;"): message_to_emacs("No parent node for selected node.") else: eval_in_emacs('eaf--add-multiple-middle-nodes', [self.buffer_id])
def _save_as_single_file(self): parsed = urlparse(self.url) qd = parse_qs(parsed.query, keep_blank_values=True) file_path = os.path.join(os.path.expanduser(self.emacs_var_dict["eaf-browser-download-path"]), "{}.html".format(parsed.netloc)) message_to_emacs("Saving as single file...") args = ["monolith", self.url, "-o", file_path] handler = partial(self.notify_monolith_message, self.emacs_var_dict["eaf-browser-download-path"], file_path, self.title) call_and_check_code(args, handler)
def _save_as_pdf(self): parsed = urlparse(self.url) qd = parse_qs(parsed.query, keep_blank_values=True) pdf_path = os.path.join( os.path.expanduser( self.emacs_var_dict["eaf-browser-download-path"]), "{}.pdf".format(parsed.netloc)) message_to_emacs("Saving as pdf...") self.buffer_widget.web_page.printToPdf(pdf_path)
def _caret_search_text(self, text, is_backward = False): if self.caret_browsing_search_text != text: self.caret_browsing_search_text = text if is_backward: if not self.buffer_widget.execute_js("window.find('"+text+"',false,true)"): message_to_emacs("Unable to find more, please try forward search.") else: if not self.buffer_widget.execute_js("window.find('"+text+"')"): message_to_emacs("Unable to find more, please try backward search.")
def paste_node_topic(self): text = self.get_clipboard_text() if text.strip() != "": self.buffer_widget.eval_js("update_node_topic('{}');".format(text)) message_to_emacs("Paste: {}".format(text)) self.save_file(False) else: message_to_emacs("Nothing in clipboard, can't paste.")
def _do(*args): buffer_id = args[0] if type(buffer_id) == str and buffer_id in self.buffer_dict: try: getattr(self.buffer_dict[buffer_id], name)(*args[1:]) except AttributeError: import traceback traceback.print_exc() message_to_emacs("Got error with : " + name + " (" + buffer_id + ")")
def toggle_adblocker(self): ''' Change adblocker status.''' if get_emacs_var("eaf-browser-enable-adblocker"): set_emacs_var("eaf-browser-enable-adblocker", False) self.buffer_widget.remove_css('adblocker', True) message_to_emacs("Successfully disabled adblocker!") elif not get_emacs_var("eaf-browser-enable-adblocker"): set_emacs_var("eaf-browser-enable-adblocker", True) self.load_adblocker() message_to_emacs("Successfully enabled adblocker!")
def caret_toggle_mark(self): ''' Toggle mark in caret browsing.''' if self.caret_browsing_mode: self.buffer_widget.eval_js("CaretBrowsing.toggleMark();") if self.buffer_widget.execute_js("CaretBrowsing.markEnabled"): self.caret_browsing_mark_activated = True message_to_emacs("Caret Mark set") else: self.caret_browsing_mark_activated = False message_to_emacs("Caret Mark deactivated")
def toggle_adblocker(self): ''' Change adblocker status.''' if self.emacs_var_dict["eaf-browser-enable-adblocker"] == "true": set_emacs_var("eaf-browser-enable-adblocker", "false", "true") self.buffer_widget.remove_css('adblocker', True) message_to_emacs("Successfully disabled adblocker!") elif self.emacs_var_dict["eaf-browser-enable-adblocker"] == "false": set_emacs_var("eaf-browser-enable-adblocker", "true", "true") self.load_adblocker() message_to_emacs("Successfully enabled adblocker!")
def call_function(self, buffer_id, function_name): ''' Call function and return the result. ''' if buffer_id in self.buffer_dict: try: return str( self.buffer_dict[buffer_id].call_function(function_name)) except AttributeError: import traceback traceback.print_exc() message_to_emacs("Cannot call function: " + function_name) return ""
def eval_function(self, buffer_id, function_name, event_string): ''' Execute function and do not return anything. ''' if type(buffer_id) == str and buffer_id in self.buffer_dict: try: buffer = self.buffer_dict[buffer_id] buffer.current_event_string = event_string getattr(buffer, function_name)() except AttributeError: import traceback traceback.print_exc() message_to_emacs("Cannot execute function: " + function_name + " (" + buffer_id + ")")
def caret_toggle_browsing(self): ''' Init caret browsing.''' if self.caret_js_ready: if self.caret_browsing_mode: self.buffer_widget.eval_js("CaretBrowsing.shutdown();") message_to_emacs("Caret browsing deactivated.") self.caret_browsing_mode = False else: self.buffer_widget.eval_js("CaretBrowsing.setInitialCursor();") message_to_emacs("Caret browsing activated.") self.caret_browsing_mode = True eval_in_emacs('eaf--toggle-caret-browsing', ["'t" if self.caret_browsing_mode else "'nil"])
def translate_page(self): import locale system_language = locale.getdefaultlocale()[0].replace("_", "-") translate_language = get_emacs_var("eaf-browser-translate-language") language = system_language if translate_language == "" else translate_language url = urllib.parse.quote(self.buffer_widget.url().toString(), safe='') open_url_in_new_tab( "https://translate.google.com/translate?hl=en&sl=auto&tl={}&u={}". format(language, url)) message_to_emacs("Translating page...")
def add_password_entry(self): self.buffer_widget.eval_js(self.pw_autofill_raw.replace("%1", "''")) password, form_data = self.buffer_widget.execute_js( "retrievePasswordFromPage();") if password != "": self.autofill.add_entry( urlparse(self.current_url).hostname, password, form_data) message_to_emacs("Successfully recorded this page's password!") return True else: message_to_emacs("There is no password present in this page!") return False
def switch_to_reader_mode(self): self.buffer_widget.eval_js(self.readability_js) html = self.buffer_widget.execute_js( "new Readability(document).parse().content;") if html == None: self.refresh_page() message_to_emacs( "Cannot parse text content of current page, failed to switch reader mode." ) else: self.buffer_widget.setHtml( "<style> #readability-page-1 { width: 60%; margin: auto; } </style>" + html)
def render(self): params = { "input_file": self.url, "output_file": self.preview_file, "dark_mode": self.dark_mode } url = 'http://localhost:{}?{}'.format(self.server_port, urlencode(params)) with urlopen(url) as f: resp = f.read().decode("utf-8") if resp == "ok": self.buffer_widget.load(QUrl.fromLocalFile(self.preview_file)) if platform.system() == "Windows": eval_in_emacs('eaf-activate-emacs-window', []) else: message_to_emacs("preview failed: {}".format(resp))
def download_youtube_file(self, only_audio=False): ''' Download Youtube File.''' url = self.buffer_widget.get_url() if url.startswith("https://www.youtube.com"): import shutil if shutil.which("youtube-dl"): download_path = "{}/%(title)s-%(id)s.%(ext)s".format( os.path.expanduser( str(self.emacs_var_dict["eaf-browser-download-path"]))) youtube_dl_args = ["youtube-dl"] youtube_dl_args.append("--proxy") youtube_dl_args.append(self.proxy_string) youtube_dl_args.append(url) youtube_dl_args.append("-o") youtube_dl_args.append(download_path) file_type = "video" if only_audio: youtube_dl_args.append("-x") file_type = "audio" with open(os.devnull, "w") as null_file: popen_and_call( youtube_dl_args, lambda: message_to_emacs( "Downloaded: {0}".format(url)), null_file) message_to_emacs("Downloading {0}: {1}".format(file_type, url)) else: message_to_emacs( "Please install youtube-dl to use this feature.") else: message_to_emacs( "Only videos from YouTube can be downloaded for now.")
def _record_history(self, new_title, new_url): # Throw traceback info if algorithm has bug and protection of historical record is not erased. try: noprefix_new_url_match = re.match(self.noprefix_url_pattern, new_url) if noprefix_new_url_match is not None: found = False for history in self.history_list: noprefix_url_match = re.match(self.noprefix_url_pattern, history.url) if noprefix_url_match is not None: noprefix_url = noprefix_url_match.group(2) noprefix_new_url = noprefix_new_url_match.group(2) nopostfix_new_url_match = re.match( self.nopostfix_url_pattern, noprefix_new_url) if noprefix_url == noprefix_new_url: # found unique url history.title = new_title history.url = new_url history.hit += 0.5 found = True elif nopostfix_new_url_match is not None and noprefix_url == nopostfix_new_url_match.group( ): # also increment parent history.hit += 0.25 if not found: self.history_list.append(HistoryPage( new_title, new_url, 1)) self.history_list.sort(key=lambda x: x.hit, reverse=True) with open(self.history_log_file_path, "w", encoding="utf-8") as f: f.writelines( map( lambda history: history.title + "ᛝ" + history.url + "ᛡ" + str(history.hit) + "\n", self.history_list)) except Exception: import traceback message_to_emacs("Error in record_history: " + str(traceback.print_exc()))