def save_feed(self, feed_object, feed_link, feed_title): touch(self.feed_file_path) article_ids = list(map(lambda post: post.id if hasattr(post, 'id') else post.link, feed_object.entries)) try: with open(self.feed_file_path, "r") as feed_file: feed_dict = json.loads(feed_file.read()) if feed_link not in feed_dict: feed_dict[feed_link] = { "title": feed_title, "unread_articles": article_ids } self.save_feed_dict(feed_dict) self.buffer.message_to_emacs.emit("Add feed: " + feed_link) except Exception: import traceback traceback.print_exc() self.save_feed_dict({feed_link : { "title": feed_title, "unread_articles": article_ids }}) self.buffer.message_to_emacs.emit("Add feed: " + feed_link)
def handle_download_request(self, download_item): 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"))) self.message_to_emacs.emit("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) self.message_to_emacs.emit("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 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_file(self, notify=True): file_path = self.get_save_path("emm") touch(file_path) with open(file_path, "w") as f: f.write(self.buffer_widget.execute_js("save_file();")) if notify: self.message_to_emacs.emit("Save file: " + file_path)
def record_close_page(self, url): ''' Record closing pages.''' self.page_closed = True if self.emacs_var_dict[ "eaf-browser-remember-history"] == "true" and self.arguments != "temp_html_file" and url != "about:blank": touch(self.history_close_file_path) with open(self.history_close_file_path, "r") as f: close_urls = f.readlines() close_urls.append("{0}\n".format(url)) open(self.history_close_file_path, "w").writelines(close_urls)
def record_history(self, new_title): if self.arguments != "temp_html_file" and new_title != "about:blank" and self.emacs_var_dict["eaf-browser-remember-history"] == "true": touch(self.history_log_file_path) with open(self.history_log_file_path, "r") as f: lines = f.readlines() new_url = self.buffer_widget.filter_url(self.buffer_widget.url().toString()) exists = False with open(self.history_log_file_path, "w") as f: for line in lines: title = re.match(self.history_url_pattern, line).group(1) url = re.match(self.history_url_pattern, line).group(2) if url == new_url: exists = True if new_title != title: f.write(new_title + " " + new_url + "\n") else: f.write(line) if not exists: f.write(new_title + " " + new_url + "\n")
def handle_download_request(self, download_item): 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"))) self.message_to_emacs.emit("Save image: " + image_path) else: self.try_start_aria2_daemon() download_data = download_item.url().toString() with open(os.devnull, "w") as null_file: subprocess.Popen(["aria2p", "add", download_data], stdout=null_file) self.message_to_emacs.emit("Start download: " + download_data)
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path): BrowserBuffer.__init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path, False) self.config_dir = config_dir # When arguments is "temp_html_file", browser will load content of html file, then delete temp file. # Usually use for render html mail. if arguments == "temp_html_file": with open(url, "r") as html_file: self.buffer_widget.setHtml(html_file.read()) if os.path.exists(url): os.remove(url) else: self.buffer_widget.setUrl(QUrl(url)) self.history_list = [] if self.emacs_var_dict["eaf-browser-remember-history"] == "true": self.history_log_file_path = os.path.join(self.config_dir, "browser", "history", "log.txt") self.history_pattern = re.compile("^(.+)ᛝ(.+)ᛡ(.+)$") self.noprefix_url_pattern = re.compile("^(https?|file)://(.+)") self.nopostfix_url_pattern = re.compile("^[^#\?]*") self.history_close_file_path = os.path.join( self.config_dir, "browser", "history", "close.txt") touch(self.history_log_file_path) with open(self.history_log_file_path, "r", encoding="utf-8") as f: raw_list = f.readlines() for raw_his in raw_list: his_line = re.match(self.history_pattern, raw_his) if his_line is None: # Obsolete Old history format old_his = re.match("(.*)\s((https?|file):[^\s]+)$", raw_his) if old_his is not None: self.history_list.append( HistoryPage(old_his.group(1), old_his.group(2), 1)) else: self.history_list.append( HistoryPage(his_line.group(1), his_line.group(2), his_line.group(3))) self.autofill = PasswordDb( os.path.join(os.path.dirname(config_dir), "browser", "password.db")) self.pw_autofill_id = 0 self.pw_autofill_raw = self.buffer_widget.read_js_content( "pw_autofill.js") self.close_page.connect(self.record_close_page) self.buffer_widget.titleChanged.connect(self.record_history) self.buffer_widget.titleChanged.connect(self.change_title) self.buffer_widget.translate_selected_text.connect(self.translate_text) self.buffer_widget.open_url_in_new_tab.connect( self.open_url_in_new_tab) self.buffer_widget.duplicate_page_in_new_tab.connect( self.duplicate_page_in_new_tab) self.buffer_widget.open_url_in_background_tab.connect( self.open_url_in_background_tab) self.buffer_widget.urlChanged.connect(self.set_adblocker) self.buffer_widget.urlChanged.connect(self.caret_exit) # Record url when url changed. self.buffer_widget.urlChanged.connect(self.update_url)
def __init__(self, config_dir): self.cookie_file = os.path.join(config_dir, "browser", "cookie", "cookie") touch(self.cookie_file)
def save_org_file(self): file_path = self.get_save_path("org") touch(file_path) self.export_org_json.emit( self.buffer_widget.execute_js("save_file();"), file_path) self.message_to_emacs.emit("Save org file: " + file_path)
def __init__(self): self.cookie_file = os.path.expanduser( "~/.emacs.d/eaf/browser/cookie/cookie") touch(self.cookie_file)
def record_close_page(self, url): if self.emacs_var_dict["eaf-browser-remember-history"] == "true": touch(self.history_close_file_path) with open(self.history_close_file_path, "a") as f: f.write("{0}\n".format(url))
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path): BrowserBuffer.__init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path, False) self.config_dir = config_dir # When arguments is "temp_html_file", browser will load content of html file, then delete temp file. # Usually use for render html mail. if arguments == "temp_html_file": with open(url, "r") as html_file: self.buffer_widget.setHtml(html_file.read()) if os.path.exists(url): os.remove(url) else: self.buffer_widget.setUrl(QUrl(url)) self.history_list = [] if self.emacs_var_dict["eaf-browser-remember-history"] == "true": self.history_log_file_path = os.path.join(self.config_dir, "browser", "history", "log.txt") self.history_pattern = re.compile("^(.+)ᛝ(.+)ᛡ(.+)$") self.noprefix_url_pattern = re.compile("^(https?|file)://(.+)") self.nopostfix_url_pattern = re.compile("^[^#\?]*") self.history_close_file_path = os.path.join( self.config_dir, "browser", "history", "close.txt") touch(self.history_log_file_path) with open(self.history_log_file_path, "r", encoding="utf-8") as f: raw_list = f.readlines() for raw_his in raw_list: his_line = re.match(self.history_pattern, raw_his) if his_line is None: # Obsolete Old history format old_his = re.match("(.*)\s((https?|file):[^\s]+)$", raw_his) if old_his is not None: self.history_list.append( HistoryPage(old_his.group(1), old_his.group(2), 1)) else: self.history_list.append( HistoryPage(his_line.group(1), his_line.group(2), his_line.group(3))) self.autofill = PasswordDb( os.path.join(os.path.dirname(config_dir), "browser", "password.db")) self.pw_autofill_id = 0 self.pw_autofill_raw = self.buffer_widget.read_js_content( "pw_autofill.js") self.readability_js = open(os.path.join( os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "node_modules", "@mozilla", "readability", "Readability.js"), encoding="utf-8").read() self.close_page.connect(self.record_close_page) self.buffer_widget.titleChanged.connect(self.record_history) self.buffer_widget.titleChanged.connect(self.change_title) self.buffer_widget.translate_selected_text.connect(translate_text) self.buffer_widget.urlChanged.connect(self.set_adblocker) self.buffer_widget.urlChanged.connect(self.caret_exit) # Record url when url changed. self.buffer_widget.urlChanged.connect(self.update_url) # Draw progressbar. self.progressbar_progress = 0 self.buffer_widget.loadStarted.connect(self.start_progress) self.buffer_widget.loadProgress.connect(self.update_progress) # Reset zoom after page loading finish. # Otherwise page won't zoom if we call setUrl api in current page. self.buffer_widget.loadFinished.connect( lambda: self.buffer_widget.zoom_reset())
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path, fit_to_view): Buffer.__init__(self, buffer_id, url, arguments, emacs_var_dict, module_path, fit_to_view) self.add_widget(BrowserView(config_dir)) self.config_dir = config_dir self.history_list = [] if self.emacs_var_dict["eaf-browser-remember-history"] == "true": self.history_log_file_path = os.path.join(self.config_dir, "browser", "history", "log.txt") self.history_pattern = re.compile("^(.+)ᛝ(.+)ᛡ(.+)$") self.noprefix_url_pattern = re.compile("^(https?|file)://(.+)") self.nopostfix_url_pattern = re.compile("^[^#\?]*") self.history_close_file_path = os.path.join( self.config_dir, "browser", "history", "close.txt") touch(self.history_log_file_path) with open(self.history_log_file_path, "r") as f: raw_list = f.readlines() for raw_his in raw_list: his_line = re.match(self.history_pattern, raw_his) if his_line is None: # Obsolete Old history format old_his = re.match("(.*)\s((https?|file):[^\s]+)$", raw_his) if old_his is not None: self.history_list.append( HistoryPage(old_his.group(1), old_his.group(2), 1)) else: self.history_list.append( HistoryPage(his_line.group(1), his_line.group(2), his_line.group(3))) # Set User Agent with Firefox's one to make EAF browser can login in Google account. self.pc_user_agent = "Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/72.0" self.phone_user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A5370a Safari/604.1" self.profile = QWebEngineProfile(self.buffer_widget) self.profile.defaultProfile().setHttpUserAgent(self.pc_user_agent) self.draw_progressbar = False self.eval_dark_js = False self.progressbar_progress = 0 self.progressbar_color = QColor(233, 129, 35, 255) self.progressbar_height = 2 self.light_mode_mask_color = QColor("#FFFFFF") self.dark_mode_mask_color = QColor("#242525") self.current_url = "" self.request_url = "" self.no_need_draw_background = False self.init_background_color() self.buffer_widget.loadStarted.connect(self.start_progress) self.buffer_widget.loadProgress.connect(self.update_progress) self.buffer_widget.urlChanged.connect(self.record_url) self.buffer_widget.web_page.windowCloseRequested.connect( self.close_buffer) self.buffer_widget.web_page.fullScreenRequested.connect( self.handle_fullscreen_request) self.buffer_widget.web_page.pdfPrintingFinished.connect( self.notify_print_message) self.profile.defaultProfile().downloadRequested.connect( self.handle_download_request) settings = QWebEngineSettings.globalSettings() try: settings.setAttribute( QWebEngineSettings.PluginsEnabled, self.emacs_var_dict["eaf-browser-enable-plugin"] == "true") settings.setAttribute( QWebEngineSettings.JavascriptEnabled, self.emacs_var_dict["eaf-browser-enable-javascript"] == "true") settings.setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True) settings.setAttribute( QWebEngineSettings.PlaybackRequiresUserGesture, False) settings.setAttribute(QWebEngineSettings.DnsPrefetchEnabled, True) except Exception: pass for method_name in [ "search_text_forward", "search_text_backward", "zoom_out", "zoom_in", "zoom_reset", "scroll_left", "scroll_right", "scroll_up", "scroll_down", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom", "refresh_page", "undo_action", "redo_action", "get_url", "exit_fullscreen", "set_focus_text", "clear_focus", "dark_mode", "view_source" ]: self.build_widget_method(method_name) self.build_widget_method("history_backward", "back") self.build_widget_method("history_forward", "forward") self.build_widget_method("action_quit", "search_quit") self.build_widget_method("yank_text", "yank_text", "Yank text.") self.build_widget_method("kill_text", "kill_text", "Kill text.") for method_name in [ "recover_prev_close_page", "scroll_up", "scroll_down", "scroll_left", "scroll_right", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom", "open_link", "open_link_new_buffer", "open_link_background_buffer", "copy_link", "history_backward", "history_forward", "new_blank_page", "open_download_manage_page", "refresh_page", "zoom_in", "zoom_out", "zoom_reset", "save_as_bookmark", "edit_url", "download_youtube_video", "download_youtube_audio", "toggle_device", "close_buffer", "save_as_pdf", "view_source", "save_as_single_file", "select_left_tab", "select_right_tab", "copy_code" ]: self.build_insert_or_do(method_name)
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, fit_to_view, background_color): Buffer.__init__(self, buffer_id, url, arguments, emacs_var_dict, fit_to_view, background_color) self.add_widget(BrowserView(config_dir)) self.config_dir = config_dir self.history_list = [] if self.emacs_var_dict["eaf-browser-remember-history"] == "true": self.history_log_file_path = os.path.join(self.config_dir, "browser", "history", "log.txt") self.history_pattern = re.compile("^(.+)ᛝ(.+)ᛡ(.+)$") self.noprefix_url_pattern = re.compile("^(https?|file)://(.+)") self.nopostfix_url_pattern = re.compile("^[^#\?]*") self.history_close_file_path = os.path.join( self.config_dir, "browser", "history", "close.txt") touch(self.history_log_file_path) with open(self.history_log_file_path, "r") as f: raw_list = f.readlines() for raw_his in raw_list: his_line = re.match(self.history_pattern, raw_his) if his_line is None: # Obsolete Old history format old_his = re.match("(.*)\s((https?|file):[^\s]+)$", raw_his) if old_his is not None: self.history_list.append( HistoryPage(old_his.group(1), old_his.group(2), 1)) else: self.history_list.append( HistoryPage(his_line.group(1), his_line.group(2), his_line.group(3))) # Set User Agent with Firefox's one to make EAF browser can login in Google account. self.profile = QWebEngineProfile(self.buffer_widget) self.profile.defaultProfile().setHttpUserAgent( "Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/72.0" ) self.buffer_widget.loadStarted.connect(self.start_progress) self.buffer_widget.loadProgress.connect(self.update_progress) self.buffer_widget.loadFinished.connect(self.stop_progress) self.buffer_widget.web_page.windowCloseRequested.connect( self.request_close_buffer) self.buffer_widget.web_page.fullScreenRequested.connect( self.handle_fullscreen_request) self.profile.defaultProfile().downloadRequested.connect( self.handle_download_request) settings = QWebEngineSettings.globalSettings() try: settings.setAttribute( QWebEngineSettings.PluginsEnabled, self.emacs_var_dict["eaf-browser-enable-plugin"] == "true") settings.setAttribute( QWebEngineSettings.JavascriptEnabled, self.emacs_var_dict["eaf-browser-enable-javascript"] == "true") settings.setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True) except Exception: pass for method_name in [ "search_text_forward", "search_text_backward", "zoom_out", "zoom_in", "zoom_reset", "scroll_left", "scroll_right", "scroll_up", "scroll_down", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom", "refresh_page", "undo_action", "redo_action", "get_url", "exit_fullscreen", "set_focus_text", "clear_focus", "dark_mode" ]: self.build_widget_method(method_name) self.build_widget_method("history_backward", "back") self.build_widget_method("history_forward", "forward") self.build_widget_method("action_quit", "search_quit") self.build_widget_method("yank_text", "yank_text", "Yank text.") self.build_widget_method("kill_text", "kill_text", "Kill text.") for method_name in [ "recover_prev_close_page", "scroll_up", "scroll_down", "scroll_left", "scroll_right", "scroll_up_page", "scroll_down_page", "scroll_to_begin", "scroll_to_bottom", "open_link", "open_link_new_buffer", "open_link_background_buffer", "history_backward", "history_forward", "new_blank_page", "open_download_manage_page", "refresh_page", "zoom_in", "zoom_out", "zoom_reset", "save_as_bookmark" ]: self.build_insert_or_do(method_name)
def __init__(self, url, config_dir, background_color, buffer_id): super(PdfViewerWidget, self).__init__() self.url = url self.config_dir = config_dir self.background_color = background_color self.buffer_id = buffer_id self.installEventFilter(self) self.setMouseTracking(True) # Load document first. self.document = fitz.open(url) # Get document's page information. self.first_pixmap = self.document.getPagePixmap(0) self.page_width = self.first_pixmap.width self.page_height = self.first_pixmap.height self.page_total_number = self.document.pageCount # Init scale and scale mode. self.scale = 1.0 self.read_mode = "fit_to_width" # Inverted mode. self.inverted_mode = False # mark link self.is_mark_link = False self.mark_link_annot_cache_dict = {} #jump link self.is_jump_link = False self.jump_link_key_cache_dict = {} self.jump_link_annot_cache_dict = {} #global search text self.is_mark_search = False self.search_text_offset_list = [] self.search_text_annot_cache_dict = {} # select text self.is_select_mode = False self.start_char_rect_index = None self.start_char_page_index = None self.last_char_rect_index = None self.last_char_page_index = None self.select_area_annot_cache_dict = {} self.select_area_annot_quad_cache_dict = {} self.char_dict = {k: None for k in range(self.page_total_number)} # annot self.is_hover_annot = False # Init scroll attributes. self.scroll_step = 20 self.scroll_offset = 0 self.mouse_scroll_offset = 20 # Padding between pages. self.page_padding = 10 # Init font. self.page_annotate_height = 22 self.page_annotate_padding_right = 10 self.page_annotate_padding_bottom = 10 self.page_annotate_light_color = QColor("#333333") self.page_annotate_dark_color = QColor("#999999") self.font = QFont() self.font.setPointSize(12) # Page cache. self.page_cache_pixmap_dict = {} self.page_cache_scale = self.scale self.page_cache_trans = None self.page_cache_context_delay = 1000 self.last_action_time = 0 self.is_page_just_changed = False self.remember_offset = None # Save table in file for search framework, such as snails, search table to navigate. table_info = "" for info in self.document.getToC(): indentation_num = info[0] title = info[1] page = info[2] table_info += str(page) + self.repeat_to_length( " ", indentation_num * 4) + title + "\n" table_file_hash = hashlib.md5(self.url.encode()).hexdigest() self.table_file_path = os.path.join(config_dir, "pdf-viewer", "table", table_file_hash) touch(self.table_file_path) with open(self.table_file_path, "w") as f: f.write(table_info)