def update_note(id, title, text, source, tags, reminder, queue_schedule): text = utility.text.clean_user_note_text(text) tags = " %s " % tags.strip() conn = _get_connection() sql = """ update notes set title=?, text=?, source=?, tags=?, modified=datetime('now', 'localtime') where id=? """ pos = None orig_prio_list = _get_priority_list() note_had_position = False list = [] for li in orig_prio_list: if li[0] == id: note_had_position = True else: list.append(li) if queue_schedule != 1: if QueueSchedule(queue_schedule) == QueueSchedule.HEAD: pos = 0 elif QueueSchedule(queue_schedule) == QueueSchedule.FIRST_THIRD: pos = int(len(list) / 3.0) elif QueueSchedule(queue_schedule) == QueueSchedule.SECOND_THIRD: pos = int(2 * len(list) / 3.0) elif QueueSchedule(queue_schedule) == QueueSchedule.END: pos = len(list) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM: pos = random.randint(0, len(list)) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM_FIRST_THIRD: pos = random.randint(0, int(len(list) / 3.0)) elif QueueSchedule( queue_schedule) == QueueSchedule.RANDOM_SECOND_THIRD: pos = random.randint(int(len(list) / 3.0), int(len(list) * 2 / 3.0)) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM_THIRD_THIRD: pos = random.randint(int(len(list) * 2 / 3.0), int(len(list) * 3 / 3.0)) sql = """ update notes set title=?, text=?, source=?, tags=?, position=%s, modified=datetime('now', 'localtime') where id=? """ % pos else: if note_had_position: sql = "update notes set title=?, text=?, source=?, tags=?, modified=datetime('now', 'localtime') where id=?" else: sql = "update notes set title=?, text=?, source=?, tags=?, position=null, modified=datetime('now', 'localtime') where id=?" conn.execute(sql, (title, text, source, tags, id)) if pos is not None: list.insert(pos, (id, )) pos_list = [(ix, r[0]) for ix, r in enumerate(list)] conn.executemany("update notes set position = ? where id = ?", pos_list) conn.commit() conn.close() index = get_index() if index is not None: index.update_user_note((id, title, text, source, tags, -1, ""))
def create_note(title, text, source, tags, nid, reminder, queue_schedule): #clean the text text = utility.text.clean_user_note_text(text) if source is not None: source = source.strip() if (len(text) + len(title)) == 0: return if tags is not None and len(tags.strip()) > 0: tags = " %s " % tags.strip() else: tags = "" pos = None if queue_schedule != 1: list = _get_priority_list() if QueueSchedule(queue_schedule) == QueueSchedule.HEAD: pos = 0 elif QueueSchedule(queue_schedule) == QueueSchedule.FIRST_THIRD: pos = int(len(list) / 3.0) elif QueueSchedule(queue_schedule) == QueueSchedule.SECOND_THIRD: pos = int(2 * len(list) / 3.0) elif QueueSchedule(queue_schedule) == QueueSchedule.END: pos = len(list) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM: pos = random.randint(0, len(list)) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM_FIRST_THIRD: pos = random.randint(0, int(len(list) / 3.0)) elif QueueSchedule( queue_schedule) == QueueSchedule.RANDOM_SECOND_THIRD: pos = random.randint(int(len(list) / 3.0), int(len(list) * 2 / 3.0)) elif QueueSchedule(queue_schedule) == QueueSchedule.RANDOM_THIRD_THIRD: pos = random.randint(int(len(list) * 2 / 3.0), int(len(list) * 3 / 3.0)) conn = _get_connection() if pos is not None: pos_list = [(ix if ix < pos else ix + 1, r[0]) for ix, r in enumerate(list)] conn.executemany("update notes set position = ? where id = ?", pos_list) id = conn.execute( """insert into notes (title, text, source, tags, nid, created, modified, reminder, lastscheduled, position) values (?,?,?,?,?,datetime('now', 'localtime'),""," ","", ?)""", (title, text, source, tags, nid, pos)).lastrowid conn.commit() conn.close() index = get_index() if index is not None: index.add_user_note((id, title, text, source, tags, nid, ""))
def update_note_text(id, text): conn = _get_connection() sql = """ update notes set text=?, modified=datetime('now', 'localtime') where id=? """ text = utility.text.clean_user_note_text(text) conn.execute(sql, (text, id)) conn.commit() note = conn.execute(f"select title, source, tags from notes where id={id}").fetchone() conn.close() index = get_index() if index is not None: index.update_user_note((id, note[0], text, note[1], note[2], -1, ""))
def update_note_tags(id, tags): if not tags.endswith(" "): tags += " " if not tags.startswith(" "): tags = f" {tags}" conn = _get_connection() sql = """ update notes set tags=?, modified=datetime('now', 'localtime') where id=? """ conn.execute(sql, (tags, id)) conn.commit() note = conn.execute(f"select title, source, tags, text from notes where id={id}").fetchone() conn.close() index = get_index() if index is not None: index.update_user_note((id, note[0], note[3], note[1], tags, -1, ""))
def update_note(id, title, text, source, tags, reminder, queue_schedule): text = utility.text.clean_user_note_text(text) tags = " %s " % tags.strip() mod = _date_now_str() sql = f"update notes set title=?, text=?, source=?, tags=?, modified='{mod}' where id=?" conn = _get_connection() conn.execute(sql, (title, text, source, tags, id)) conn.commit() conn.close() # if schedule is NOT_ADD/keep priority, don't recalc queue if queue_schedule != QueueSchedule.NOT_ADD.value: update_priority_list(id, queue_schedule) index = get_index() if index is not None: index.update_user_note((id, title, text, source, tags, -1, ""))
def display(self, note_id): index = get_index() note = get_note(note_id) self.note_id = note_id self.note = note html = get_reading_modal_html(note) index.ui.show_in_large_modal(html) # if source is a pdf file path, try to display it if note.is_pdf(): if utility.misc.file_exists(note.source): self._display_pdf(note.source.strip(), note_id) else: message = "Could not load the given PDF.<br>Are you sure the path is correct?" self.notification(message)
def find_by_tag(tag_str): index = get_index() pinned = [] if index is not None: pinned = index.pinned query = "where " for t in tag_str.split(" "): if len(t) > 0: t = t.replace("'", "''") if len(query) > 6: query += " or " query += "lower(tags) like '% " + t + " %' or lower(tags) like '% " + t + "::%' or lower(tags) like '%::" + t + " %' or lower(tags) like '% " + t + "::%' or lower(tags) like '" + t + " %' or lower(tags) like '%::" + t + "::%'" conn = _get_connection() res = conn.execute("select * from notes %s order by id desc" % (query)).fetchall() output_list = _to_output_list(res, pinned) return output_list
def find_by_tag(tag_str, to_output_list=True): if len(tag_str.strip()) == 0: return [] index = get_index() pinned = [] if index is not None: pinned = index.pinned query = "where " for t in tag_str.split(" "): if len(t) > 0: t = t.replace("'", "''") if len(query) > 6: query += " or " query = f"{query}lower(tags) like '% {t} %' or lower(tags) like '% {t}::%' or lower(tags) like '%::{t} %' or lower(tags) like '{t} %' or lower(tags) like '%::{t}::%'" conn = _get_connection() res = conn.execute("select * from notes %s order by id desc" %(query)).fetchall() if not to_output_list: return res return _to_notes(res, pinned)
def create_note(title, text, source, tags, nid, reminder, queue_schedule): #clean the text text = utility.text.clean_user_note_text(text) if source is not None: source = source.strip() if (len(text) + len(title)) == 0: return if tags is not None and len(tags.strip()) > 0: tags = " %s " % tags.strip() else: tags = "" conn = _get_connection() id = conn.execute("""insert into notes (title, text, source, tags, nid, created, modified, reminder, lastscheduled, position) values (?,?,?,?,?,datetime('now', 'localtime'),""," ","", NULL)""", (title, text, source, tags, nid)).lastrowid conn.commit() conn.close() if queue_schedule != QueueSchedule.NOT_ADD: update_priority_list(id, queue_schedule) index = get_index() if index is not None: index.add_user_note((id, title, text, source, tags, nid, ""))
def print_search_results(self, notes, stamp, editor=None, logging=False, printTimingInfo=False, page=1, query_set=None, is_queue=False, is_cached=False): """ This is the html that gets rendered in the search results div. This will always print the first page. """ if logging: log("Entering print_search_results") log("Length (searchResults): " + str(len(notes))) if stamp is not None: if stamp != self.latest: return if not is_cached and len(notes) > 0: self.previous_calls.append([ notes, None, editor, logging, printTimingInfo, page, query_set, is_queue ]) if len(self.previous_calls) > 11: self.previous_calls.pop(0) html = "" allText = "" tags = [] epochTime = int(time.time() * 1000) timeDiffString = "" newNote = "" lastNote = "" ret = 0 self.last_had_timing_info = printTimingInfo if notes is not None and len(notes) > 0: self.lastResults = notes self.last_query_set = query_set searchResults = notes[(page - 1) * 50:page * 50] nids = [r.id for r in searchResults] if self.showRetentionScores: retsByNid = getRetentions(nids) # various time stamps to collect information about rendering performance start = time.time() highlight_start = None build_user_note_start = None highlight_total = 0.0 build_user_note_total = 0.0 remaining_to_highlight = {} highlight_boundary = 15 if self.gridView else 10 # for better performance, collect all notes that are .pdfs, and # query their reading progress after they have been rendered pdfs = [] check_for_suspended = [] for counter, res in enumerate(searchResults): nid = res.id counter += (page - 1) * 50 try: timeDiffString = self._getTimeDifferenceString(nid, epochTime) except: if logging: log("Failed to determine creation date: " + str(nid)) timeDiffString = "Could not determine creation date" ret = retsByNid[int(nid)] if self.showRetentionScores and int( nid) in retsByNid else None if ret is not None: retMark = "background: %s; color: black;" % ( utility.misc._retToColor(ret)) if str(nid) in self.edited: retMark = ''.join((retMark, "max-width: 20px;")) retInfo = """<div class='retMark' style='%s'>%s</div>""" % ( retMark, int(ret)) else: retInfo = "" lastNote = newNote #non-anki notes should be displayed differently, we distinguish between title, text and source here #confusing: 'source' on notes from the index means the original note content (without stopwords removed etc.), #on SiacNotes, it means the source field. build_user_note_start = time.time() text = res.get_content() progress = "" pdf_class = "" if res.note_type == "user" and res.is_pdf(): pdfs.append(nid) p_html = "<div class='siac-prog-sq'></div>" * 10 progress = f"<div id='ptmp-{nid}' class='siac-prog-tmp'>{p_html} <span> 0 / ?</span></div>" pdf_class = "pdf" elif res.note_type == "index" and res.did > 0: check_for_suspended.append(res.id) build_user_note_total += time.time() - build_user_note_start # hide fields that should not be shown if str(res.mid) in self.fields_to_hide_in_results: text = "\u001f".join([ spl for i, spl in enumerate(text.split("\u001f")) if i not in self.fields_to_hide_in_results[str(res.mid)] ]) #remove double fields separators text = utility.text.cleanFieldSeparators(text).replace( "\\", "\\\\") #try to remove image occlusion fields text = utility.text.try_hide_image_occlusion(text) #try to put fields that consist of a single image in their own line text = utility.text.newline_before_images(text) #remove <div> tags if set in config if self.remove_divs and res.note_type != "user": text = utility.text.remove_divs(text, " ") #highlight highlight_start = time.time() if query_set is not None: if counter - (page - 1) * 50 < highlight_boundary: text = utility.text.mark_highlights(text, query_set) else: remaining_to_highlight[nid] = "" highlight_total += time.time() - highlight_start if query_set is not None and counter - ( page - 1) * 50 >= highlight_boundary: remaining_to_highlight[nid] = text gridclass = "grid" if self.gridView else "" if self.gridView and len(text) < 200: if self.scale < 0.8: gridclass = ' '.join((gridclass, "grid-smaller")) else: gridclass = ' '.join((gridclass, "grid-small")) elif self.gridView and self.scale < 0.8: gridclass = ' '.join((gridclass, "grid-small")) elif self.gridView and len(text) > 700 and self.scale > 0.8: gridclass = ' '.join((gridclass, "grid-large")) if self.scale != 1.0: gridclass = ' '.join([ gridclass, "siac-sc-%s" % str(self.scale).replace(".", "-") ]) # use either the template for addon's notes or the normal if res.note_type == "user": newNote = noteTemplateUserNote.format( grid_class=gridclass, counter=counter + 1, nid=nid, creation=" 🕐 " + timeDiffString, edited="" if str(nid) not in self.edited else " 🕐 " + self._buildEditedInfo(self.edited[str(nid)]), mouseup="getSelectionText()" if not is_queue else "", text=text, tags=utility.tags.build_tag_string(res.tags, self.gridView), queue=": Q-%s " % (res.position + 1) if res.is_in_queue() else "", progress=progress, pdf_class=pdf_class, ret=retInfo) else: newNote = noteTemplate.format( grid_class=gridclass, counter=counter + 1, nid=nid, creation=" 🕐 " + timeDiffString, edited="" if str(nid) not in self.edited else " 🕐 " + self._buildEditedInfo(self.edited[str(nid)]), mouseup="getSelectionText()" if not is_queue else "", text=text, tags=utility.tags.build_tag_string(res.tags, self.gridView), ret=retInfo) html = f"{html}{newNote}" tags = self._addToTags(tags, res.tags) if counter - (page - 1) * 50 < 20: # todo: title for user notes allText = f"{allText} {res.text[:5000]}" tags.sort() html = html.replace("`", "`").replace("$", "$") pageMax = math.ceil(len(notes) / 50.0) if get_index() is not None and get_index().lastResDict is not None: get_index().lastResDict["time-html"] = int( (time.time() - start) * 1000) get_index().lastResDict["time-html-highlighting"] = int( highlight_total * 1000) get_index().lastResDict["time-html-build-user-note"] = int( build_user_note_total * 1000) if stamp is None and self.last_took is not None: took = self.last_took stamp = -1 elif stamp is not None: took = utility.misc.get_milisec_stamp() - stamp self.last_took = took else: took = "?" timing = "true" if printTimingInfo else "false" if not self.hideSidebar: infoMap = { "Took": "<b>%s</b> ms %s" % (took, " <b style='cursor: pointer' onclick='pycmd(`siac-last-timing`)'>ⓘ</b>" if printTimingInfo else ""), "Found": "<b>%s</b> notes" % (len(notes) if len(notes) > 0 else "<span style='color: red;'>0</span>") } info = self.build_info_table(infoMap, tags, allText) cmd = "setSearchResults(`%s`, `%s`, %s, page=%s, pageMax=%s, total=%s, cacheSize=%s, stamp=%s, printTiming=%s);" % ( html, info[0].replace("`", "`"), json.dumps(info[1]), page, pageMax, len(notes), len(self.previous_calls), stamp, timing) else: cmd = "setSearchResults(`%s`, ``, null, page=%s , pageMax=%s, total=%s, cacheSize=%s, stamp=%s, printTiming=%s);" % ( html, page, pageMax, len(notes), len( self.previous_calls), stamp, timing) cmd = f"{cmd}updateSwitchBtn({len(notes)});" self._js(cmd, editor) if len(remaining_to_highlight) > 0: cmd = "" for nid, text in remaining_to_highlight.items(): cmd = ''.join( (cmd, "document.getElementById('%s').innerHTML = `%s`;" % (nid, utility.text.mark_highlights(text, query_set)))) self._js(cmd, editor) if len(check_for_suspended) > 0: susp = get_suspended(check_for_suspended) if len(susp) > 0: cmd = "" for nid in susp: cmd = f"{cmd}$('#cW-{nid}').after(`<span id='siac-susp-lbl-{nid}' onclick='pycmd(\"siac-unsuspend-modal {nid}\")' class='siac-susp-lbl'>SUSPENDED</span>`);" if str(nid) in self.edited: cmd = f"{cmd} $('#siac-susp-lbl-{nid}').css('left', '140px');" self._js(cmd, editor) if len(pdfs) > 0: pdf_info_list = get_pdf_info(pdfs) if pdf_info_list is not None and len(pdf_info_list) > 0: cmd = "" for i in pdf_info_list: perc = int(i[1] * 10.0 / i[2]) prog_bar = "" for x in range(0, 10): if x < perc: prog_bar = ''.join( (prog_bar, "<div class='siac-prog-sq-filled'></div>")) else: prog_bar = ''.join( (prog_bar, "<div class='siac-prog-sq'></div>")) cmd = ''.join(( cmd, "document.querySelector('#ptmp-%s').innerHTML = `%s <span>%s / %s</span>`;" % (i[0], prog_bar, i[1], i[2]))) self._js(cmd, editor) return (highlight_total * 1000, build_user_note_total)
def find_by_text(text): index = get_index() index.search(text, [])