def highlight_text(query, text, open_tag='<span foreground="white">', close_tag='</span>'): """ Highlights words from query in a given text string :returns: string with Pango markup """ positions = get_matching_indexes(query, text) query = force_unicode(query) text = force_unicode(text) # use positions to highlight text with tags hl_started = False hlted = [] for i, char in enumerate(text): if i in positions and not hl_started: hl_started = True hlted.append(open_tag) elif i not in positions and hl_started: hl_started = False hlted.append(close_tag) hlted.append(char) if hl_started: # don't forget to close tag if it is opened hlted.append(close_tag) # replace & characters with & return ''.join(hlted).replace('&', '&')
def highlight_text(query, text, open_tag='<span foreground="white">', close_tag='</span>'): """ Highlights words from query in a given text string :returns: string with Pango markup """ positions = get_matching_indexes(query, text) query = force_unicode(query) text = force_unicode(text) # use positions to highlight text with tags hl_started = False hlted = [] for i, char in enumerate(text): if i in positions and not hl_started: hl_started = True hlted.append(open_tag) elif i not in positions and hl_started: hl_started = False hlted.append(close_tag) hlted.append(char) if hl_started: # don't forget to close tag if it is opened hlted.append(close_tag) # replace & characters with & return ''.join(hlted).replace('&', '&')
def prefs_shortcut_update(self, url_params): req_data = url_params['query'] logger.info('Add/Update shortcut: %s' % json.dumps(req_data)) shortcuts = ShortcutsDb.get_instance() id = shortcuts.put_shortcut(force_unicode(req_data['name']), force_unicode(req_data['keyword']), force_unicode(req_data['cmd']), req_data.get('icon') or None, str_to_bool(req_data['is_default_search']), req_data.get('id')) shortcuts.commit() return {'id': id}
def prefs_shortcut_update(self, url_params): req_data = url_params['query'] logger.info('Add/Update shortcut: %s' % json.dumps(req_data)) shortcuts = ShortcutsDb.get_instance() id = shortcuts.put_shortcut(force_unicode(req_data['name']), force_unicode(req_data['keyword']), force_unicode(req_data['cmd']), req_data.get('icon') or None, str_to_bool(req_data['is_default_search']), req_data.get('id')) shortcuts.commit() return {'id': id}
def find_desktop_files(dirs=DESKTOP_DIRS): """ :param list dirs: :rtype: list """ all_files = chain.from_iterable( map(lambda f: os.path.join(f_path, f), find_files(f_path, '*.desktop')) for f_path in dirs) # dedup desktop file according to folow XDG data dir order # specifically the first file name (i.e. firefox.desktop) take precedence # and other files with the same name shoudl be ignored deduped_file_dict = OrderedDict() for file_path in all_files: file_name = os.path.basename(file_path) if file_name not in deduped_file_dict: deduped_file_dict[file_name] = file_path deduped_files = deduped_file_dict.itervalues() blacklisted_dirs_srt = Settings.get_instance().get_property('blacklisted-desktop-dirs') blacklisted_dirs = blacklisted_dirs_srt.split(':') if blacklisted_dirs_srt else [] for file in deduped_files: try: if any([force_unicode(file).startswith(dir) for dir in blacklisted_dirs]): continue except UnicodeDecodeError: continue yield file
def find_desktop_files(dirs=DESKTOP_DIRS): """ :param list dirs: :rtype: list """ all_files = chain.from_iterable( map(lambda f: os.path.join(f_path, f), find_files(f_path, '*.desktop')) for f_path in dirs) # dedup desktop file according to folow XDG data dir order # specifically the first file name (i.e. firefox.desktop) take precedence # and other files with the same name shoudl be ignored deduped_file_dict = OrderedDict() for file_path in all_files: file_name = os.path.basename(file_path) if file_name not in deduped_file_dict: deduped_file_dict[file_name] = file_path deduped_files = deduped_file_dict.itervalues() blacklisted_dirs_srt = Settings.get_instance().get_property( 'blacklisted-desktop-dirs') blacklisted_dirs = blacklisted_dirs_srt.split( ':') if blacklisted_dirs_srt else [] for file in deduped_files: try: if any([ force_unicode(file).startswith(dir) for dir in blacklisted_dirs ]): continue except UnicodeDecodeError: continue yield file
def _remove_file(self, pathname): """ Remove .desktop file from DB :param str pathname: """ pathname = force_unicode(pathname) self.__db.remove_by_path(pathname) logger.info('App was removed (%s)' % pathname)
def _remove_file(self, pathname): """ Remove .desktop file from DB :param str pathname: """ pathname = force_unicode(pathname) self.__db.remove_by_path(pathname) logger.info('App was removed (%s)' % pathname)
def get_by_name(self, name): query = 'SELECT * FROM app_db where name = ? COLLATE NOCASE' try: collection = self._conn.execute(query, (force_unicode(name),)) except Exception as e: logger.exception('Exception %s for query: %s. Name: %s' % (e, query, name)) raise row = collection.fetchone() if row: return self._row_to_rec(row)
def get_by_path(self, desktop_file): query = 'SELECT * FROM app_db where desktop_file = ?' try: collection = self._conn.execute(query, (force_unicode(desktop_file),)) except Exception as e: logger.exception('Exception %s for query: %s. Path: %s' % (e, query, desktop_file)) raise row = collection.fetchone() if row: return self._row_to_rec(row)
def put_app(self, app): """ :param Gio.DesktopAppInfo app: """ name = force_unicode(app.get_string('X-GNOME-FullName') or app.get_name()) exec_name = force_unicode(app.get_string('Exec') or '') record = { "desktop_file": force_unicode(app.get_filename()), "description": force_unicode(app.get_description() or ''), "name": name, "search_name": search_name(name, exec_name) } self._icons[record['desktop_file']] = get_app_icon_pixbuf(app, AppResultItem.ICON_SIZE) query = '''INSERT OR REPLACE INTO app_db (name, desktop_file, description, search_name) VALUES (:name, :desktop_file, :description, :search_name)''' try: self._conn.execute(query, record) self.commit() except Exception as e: logger.exception('Exception %s for query: %s. Record: %s' % (e, query, record))
def put_app(self, app): """ :param Gio.DesktopAppInfo app: """ name = force_unicode(app.get_string('X-GNOME-FullName') or app.get_name()) exec_name = force_unicode(app.get_string('Exec') or '') record = { "desktop_file": force_unicode(app.get_filename()), "desktop_file_short": force_unicode(os.path.basename(app.get_filename())), "description": force_unicode(app.get_description() or ''), "name": name, "search_name": search_name(name, exec_name) } self._icons[record['desktop_file']] = get_app_icon_pixbuf(app, AppResultItem.ICON_SIZE) query = '''INSERT OR REPLACE INTO app_db (name, desktop_file, desktop_file_short, description, search_name) VALUES (:name, :desktop_file, :desktop_file_short, :description, :search_name)''' try: self._conn.execute(query, record) self.commit() except Exception as e: logger.exception('Exception %s for query: %s. Record: %s' % (e, query, record))
def remove_by_path(self, desktop_file): """ :param str desktop_file: path to a desktop file """ query = 'DELETE FROM app_db WHERE desktop_file = ?' try: self._conn.execute(query, (force_unicode(desktop_file), )) self.commit() except Exception as e: logger.exception('Exception %s for query: %s. Path: %s' % (e, query, desktop_file)) raise del self._icons[desktop_file]
def get_score(query, text): """ Uses Levenshtein's algorithm + some improvements to the score :returns: number between 0 and 100 """ if not query or not text: return 0 query = query.lower() text = text.lower() score = ratio(force_unicode(query), force_unicode(text)) * 100 # increase score if a word from text starts with a query for text_part in text.split(' '): if text_part.startswith(query): score += 30 break # increase score if each separate group in indexes is a beginning of a word in text # example for query 'fiwebr' groups 'fi', 'we', and 'br' are matching word beginnings # of text 'Firefox Web Browser' # increase score for each such group increment = 10 i = 0 # query iterator lq = len(query) for j, char in enumerate(text): # run until query ends and check if a query char. equals to current text char if i < lq and query[i] == char: # if char from query matches beginning of text or beginning of a word inside the text, increase the score if j == 0 or text[j - 1] in ' .(-_+)': score += increment i += 1 elif i == lq: break return min(100, score)
def remove_by_path(self, desktop_file): """ :param str desktop_file: path to a desktop file """ query = 'DELETE FROM app_db WHERE desktop_file = ?' try: self._conn.execute(query, (force_unicode(desktop_file),)) self.commit() except Exception as e: logger.exception('Exception %s for query: %s. Path: %s' % (e, query, desktop_file)) raise try: del self._icons[desktop_file] except KeyError: pass
def find_desktop_files(dirs=DESKTOP_DIRS): """ :param list dirs: :rtype: list """ files = chain.from_iterable( map(lambda f: os.path.join(f_path, f), find_files(f_path, '*.desktop')) for f_path in dirs) blacklisted_dirs_srt = Settings.get_instance().get_property( 'blacklisted-desktop-dirs') blacklisted_dirs = blacklisted_dirs_srt.split( ':') if blacklisted_dirs_srt else [] for file in files: if any( [force_unicode(file).startswith(dir) for dir in blacklisted_dirs]): continue yield file
def add_file_deffered(self, pathname): """ Add .desktop file to DB a little bit later """ pathname = force_unicode(pathname) self._deferred_files[pathname] = time()
def run(self): app = read_desktop_file(self.filename) logger.info('Run application %s (%s)' % (force_unicode(app.get_name()), self.filename)) app.launch()
def add_file_deffered(self, pathname): """ Add .desktop file to DB a little bit later """ pathname = force_unicode(pathname) self._deferred_files[pathname] = time()
def _get_user_query(self): # get_text() returns str, so we need to convert it to unicode return Query(force_unicode(self.input.get_text()))
def run(self): app = read_desktop_file(self.filename) logger.info('Run application %s (%s)' % (force_unicode(app.get_name()), self.filename)) app.launch()