コード例 #1
0
ファイル: notes_db.py プロジェクト: Kensai2000/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                sspat = re.compile(search_string)
            except re.error:
                sspat = None
            
        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if not n.get('deleted') and (not sspat or sspat.search(c)):
                # we have to store our local key also
                filtered_notes.append(utils.KeyValueObject(key=k, note=n))
            
        if self.config.sort_mode == 0:
            # sort alphabetically on title
            filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            
        else:
            # last modified on top
            filtered_notes.sort(key=lambda o: -float(o.note.get('modifydate', 0)))
            
        return filtered_notes
コード例 #2
0
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                sspat = re.compile(search_string)
            except re.error:
                sspat = None

        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if not n.get('deleted') and (not sspat or sspat.search(c)):
                # we have to store our local key also
                filtered_notes.append(utils.KeyValueObject(key=k, note=n))

        if self.config.sort_mode == 0:
            # sort alphabetically on title
            filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))

        else:
            # last modified on top
            filtered_notes.sort(
                key=lambda o: -float(o.note.get('modifydate', 0)))

        return filtered_notes
コード例 #3
0
ファイル: view.py プロジェクト: DivineDominion/nvpy
    def append(self, note, config):
        """
        @param note: The complete note dictionary.
        """


        title = utils.get_note_title(note)
        tags = note.get('tags')
        modifydate = float(note.get('modifydate'))
        pinned = utils.note_pinned(note)
        self.note_headers.append((title, tags, modifydate, pinned))

        self.enable_text()


        self.text.insert(tk.END, title, ("title,"))

        if pinned:
            self.text.insert(tk.END, ' *', ("pinned",))

        self.text.insert(tk.END, ' ' + utils.human_date(modifydate), ("modifydate",))

        # tags can be None (newly created note) or [] or ['tag1', 'tag2']
        if tags > 0:
            if config.tagfound:
                self.text.insert(tk.END, ' ' + ','.join(tags), ("found",))
            else:
                self.text.insert(tk.END, ' ' + ','.join(tags), ("tags",))


        self.text.insert(tk.END, '\n')

        self.disable_text()
コード例 #4
0
    def cli_note_dump(self, key):

        note = self.ndb.get_note(key)
        if not note:
            self.log(u'ERROR: Key does not exist')
            return

        w = 60
        sep = u'+' + u'-' * (w + 2) + u'+'
        t = time.localtime(float(note['modifydate']))
        mod_time = time.strftime('%a, %d %b %Y %H:%M:%S', t)
        title = utils.get_note_title(note)
        flags = utils.get_note_flags(note)
        tags = utils.get_note_tags(note)

        print sep
        print(u'| {:<' + str(w) + u'} |').format((u'    Title: ' + title)[:w])
        print(u'| {:<' + str(w) + u'} |').format(
            (u'      Key: ' + note['key'])[:w])
        print(u'| {:<' + str(w) + u'} |').format(
            (u'     Date: ' + mod_time)[:w])
        print(u'| {:<' + str(w) + u'} |').format((u'     Tags: ' + tags)[:w])
        print(u'| {:<' + str(w) + u'} |').format(
            (u'  Version: v' + str(note['version']))[:w])
        print(u'| {:<' + str(w) + u'} |').format(
            (u'    Flags: [' + flags + u']')[:w])
        if utils.note_published(note) and 'publishkey' in note:
            print(u'| {:<' + str(w) + u'} |').format(
                (u'Published: http://simp.ly/publish/' +
                 note['publishkey'])[:w])
        else:
            print(u'| {:<' + str(w) + u'} |').format((u'Published: n/a')[:w])
        print sep
        print note['content']
コード例 #5
0
ファイル: notes_db.py プロジェクト: DivineDominion/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search string.

        Based on the search mode that has been selected in self.config,
        this method will call the appropriate helper method to do the
        actual work of filtering the notes.

        @param search_string: String that will be used for searching.
         Different meaning depending on the search mode.
        @return: notes filtered with selected search mode and sorted according
        to configuration.
        """

        if self.config.search_mode == 'regexp':
            filtered_notes, match_regexp = self.filter_notes_regexp(search_string)
        else:
            filtered_notes, match_regexp = self.filter_notes_gstyle(search_string)

        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(utils.sort_by_title_pinned)

        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(utils.sort_by_modify_date_pinned, reverse=True)

        return filtered_notes, match_regexp
コード例 #6
0
ファイル: view.py プロジェクト: johnwin/nvpy
    def append(self, note, config):
        """
        @param note: The complete note dictionary.
        """

        title = utils.get_note_title(note)
        tags = note.get('tags')
        modifydate = float(note.get('modifydate'))
        pinned = utils.note_pinned(note)
        self.note_headers.append((title, tags, modifydate, pinned))

        self.enable_text()

        self.text.insert(tk.END, title, ("title,"))

        if pinned:
            self.text.insert(tk.END, ' *', ("pinned", ))

        self.text.insert(tk.END, ' ' + utils.human_date(modifydate),
                         ("modifydate", ))

        # tags can be None (newly created note) or [] or ['tag1', 'tag2']
        if tags > 0:
            if config.tagfound:
                self.text.insert(tk.END, ' ' + ','.join(tags), ("found", ))
            else:
                self.text.insert(tk.END, ' ' + ','.join(tags), ("tags", ))

        self.text.insert(tk.END, '\n')

        self.disable_text()
コード例 #7
0
ファイル: sncli.py プロジェクト: Qu4tro/sncli
    def cli_note_dump(self, key):

        note = self.ndb.get_note(key)
        if not note:
            self.log(u'ERROR: Key does not exist')
            return

        w = 60
        sep = u'+' + u'-'*(w+2) + u'+'
        t = time.localtime(float(note['modifydate']))
        mod_time = time.strftime('%a, %d %b %Y %H:%M:%S', t)
        title = utils.get_note_title(note)
        flags = utils.get_note_flags(note)
        tags  = utils.get_note_tags(note)

        print sep
        print (u'| {:<' + str(w) + u'} |').format((u'    Title: ' + title)[:w])
        print (u'| {:<' + str(w) + u'} |').format((u'      Key: ' + note['key'])[:w])
        print (u'| {:<' + str(w) + u'} |').format((u'     Date: ' + mod_time)[:w])
        print (u'| {:<' + str(w) + u'} |').format((u'     Tags: ' + tags)[:w])
        print (u'| {:<' + str(w) + u'} |').format((u'  Version: v' + str(note['version']))[:w])
        print (u'| {:<' + str(w) + u'} |').format((u'    Flags: [' + flags + u']')[:w])
        if utils.note_published(note) and 'publishkey' in note:
            print (u'| {:<' + str(w) + u'} |').format((u'Published: http://simp.ly/publish/' + note['publishkey'])[:w])
        else:
            print (u'| {:<' + str(w) + u'} |').format((u'Published: n/a')[:w])
        print sep
        print note['content']
コード例 #8
0
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                if self.config.case_sensitive == 0:
                    sspat = re.compile(search_string, re.I)
                else:
                    sspat = re.compile(search_string)
            except re.error:
                sspat = None

        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if self.config.search_tags == 1:
                t = n.get('tags')
                if not n.get('deleted') and sspat:
                    if filter(sspat.search, t):
                        # we have to store our local key also
                        filtered_notes.append(
                            utils.KeyValueObject(key=k, note=n, tagfound=1))
                    elif sspat.search(c):
                        # we have to store our local key also
                        filtered_notes.append(
                            utils.KeyValueObject(key=k, note=n, tagfound=0))
                elif not n.get('deleted') and not sspat:
                    # we have to store our local key also
                    filtered_notes.append(
                        utils.KeyValueObject(key=k, note=n, tagfound=0))
            else:
                if not n.get('deleted') and (not sspat or sspat.search(c)):
                    # we have to store our local key also
                    filtered_notes.append(
                        utils.KeyValueObject(key=k, note=n, tagfound=0))

        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(utils.sort_by_title_pinned)

        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(
                    key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(utils.sort_by_modify_date_pinned,
                                    reverse=True)

        return filtered_notes
コード例 #9
0
    def cli_list_notes(self, regex, search_string):

        note_list, match_regex, all_notes_cnt = \
            self.ndb.filter_notes(
                    search_string,
                    search_mode='regex' if regex else 'gstyle')
        for n in note_list:
            flags = utils.get_note_flags(n.note)
            print n.key + \
                  u' [' + flags + u'] ' + \
                  utils.get_note_title(n.note)
コード例 #10
0
ファイル: sncli.py プロジェクト: Qu4tro/sncli
    def cli_list_notes(self, regex, search_string):

        note_list, match_regex, all_notes_cnt = \
            self.ndb.filter_notes(
                    search_string,
                    search_mode='regex' if regex else 'gstyle')
        for n in note_list:
            flags = utils.get_note_flags(n.note)
            print n.key + \
                  u' [' + flags + u'] ' + \
                  utils.get_note_title(n.note)
コード例 #11
0
ファイル: notes_db.py プロジェクト: johnwin/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                if self.config.case_sensitive == 0:
                    sspat = re.compile(search_string, re.I)
                else:
                    sspat = re.compile(search_string)
            except re.error:
                sspat = None
            
        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if self.config.search_tags == 1:
                t = n.get('tags')
                if not n.get('deleted') and sspat:
                   if filter(sspat.search, t):
                       # we have to store our local key also
                       filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=1))
                   elif sspat.search(c):
                       # we have to store our local key also
                       filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))
                elif not n.get('deleted') and not sspat:
                    # we have to store our local key also
                    filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))
            else:
                if not n.get('deleted') and (not sspat or sspat.search(c)):
                    # we have to store our local key also
                    filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))
            
        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(utils.sort_by_title_pinned)
            
        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(utils.sort_by_modify_date_pinned, reverse=True)
            
        return filtered_notes
コード例 #12
0
ファイル: notes_db.py プロジェクト: lfini/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search string.

        Based on the search mode that has been selected in self.config,
        this method will call the appropriate helper method to do the
        actual work of filtering the notes.

        @param search_string: String that will be used for searching.
         Different meaning depending on the search mode.
        @return: notes filtered with selected search mode and sorted according
        to configuration. Two more elements in tuple: a regular expression
        that can be used for highlighting strings in the text widget; the
        total number of notes in memory.
        """

        if self.config.search_mode == 'regexp':
            filtered_notes, match_regexp, active_notes = self.filter_notes_regexp(
                search_string)
        else:
            filtered_notes, match_regexp, active_notes = self.filter_notes_gstyle(
                search_string)

        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(key=utils.sort_key_by_title_pinned)
        elif self.config.sort_mode == 2:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(
                    key=lambda o: -float(o.note.get('createdate', 0)))
            else:
                filtered_notes.sort(key=utils.sort_key_by_create_date_pinned,
                                    reverse=True)

        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(
                    key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(key=utils.sort_key_by_modify_date_pinned,
                                    reverse=True)

        return filtered_notes, match_regexp, active_notes
コード例 #13
0
 def handler_housekeeper(self):
     # nvPY will do saving and syncing!
     self.notify_observers('keep:house', None)
     
     # check if titles need refreshing
     refresh_notes_list = False
     prev_title = None
     prev_modifydate = None
     for i,o in enumerate(self.notes_list_model.list):
         # order should be the same as our listbox
         nt = utils.get_note_title(o.note)
         ot = self.lb_notes.get(i)
         # if we strike a note with an out-of-date title, redo.
         if nt != ot:
             logging.debug('title "%s" resync' % (nt,))
             refresh_notes_list = True
             continue
         
         if self.config.sort_mode == 0:
             # alpha
             if prev_title is not None and prev_title > nt:
                 logging.debug("alpha resort triggered")
                 refresh_notes_list = True
                 continue
             
             prev_title = nt
             
         else:
             md = float(o.note.get('modifydate', 0))
             if prev_modifydate is not None and prev_modifydate < md:
                 logging.debug("modifydate resort triggered")
                 refresh_notes_list = True
                 continue
             
             prev_modifydate = md 
         
     if refresh_notes_list:
         self.refresh_notes_list()
     
     self.root.after(self.config.housekeeping_interval_ms, self.handler_housekeeper)
コード例 #14
0
ファイル: view.py プロジェクト: mt3/nvpy
 def handler_housekeeper(self):
     # nvPY will do saving and syncing!
     self.notify_observers('keep:house', None)
     
     # check if titles need refreshing
     refresh_notes_list = False
     prev_title = None
     prev_modifydate = None
     for i,o in enumerate(self.notes_list_model.list):
         # order should be the same as our listbox
         nt = utils.get_note_title(o.note)
         ot = self.lb_notes.get(i)
         # if we strike a note with an out-of-date title, redo.
         if nt != ot:
             print "title out of date"
             refresh_notes_list = True
             continue
         
         if self.config.sort_mode == 0:
             # alpha
             if prev_title is not None and prev_title > nt:
                 print "alpha resort"
                 refresh_notes_list = True
                 continue
             
             prev_title = nt
             
         else:
             md = float(o.note.get('modifydate', 0))
             if prev_modifydate is not None and prev_modifydate < md:
                 print "modifydate resort"
                 refresh_notes_list = True
                 continue
             
             prev_modifydate = md 
         
     if refresh_notes_list:
         self.refresh_notes_list()
     
     self.root.after(self.config.housekeeping_interval_ms, self.handler_housekeeper)
コード例 #15
0
ファイル: notes_db.py プロジェクト: ewalstad/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                if self.config.case_sensitive == 0:
                    sspat = re.compile(search_string, re.I)
                else:
                    sspat = re.compile(search_string)
            except re.error:
                sspat = None
            
        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if self.config.search_tags == 1:
                t = n.get('tags')
                if not n.get('deleted') and sspat:
                    # this used to use a filter(), but that would by definition
                    # test all elements, whereas we can stop when the first
                    # matching element is found
                    # now I'm using this awesome trick by Alex Martelli on
                    # http://stackoverflow.com/a/2748753/532513
                    # first parameter of next is a generator
                    # next() executes one step, but due to the if, this will
                    # either be first matching element or None (second param)
                    if next((ti for ti in t if sspat.search(ti)), None) is not None:
                        # we have to store our local key also
                        filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=1))

                    elif sspat.search(c):
                        # we have to store our local key also
                        filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))

                elif not n.get('deleted') and not sspat:
                    # we have to store our local key also
                    filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))
            else:
                if not n.get('deleted') and (not sspat or sspat.search(c)):
                    # we have to store our local key also
                    filtered_notes.append(utils.KeyValueObject(key=k, note=n, tagfound=0))
            
        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(utils.sort_by_title_pinned)
            
        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(utils.sort_by_modify_date_pinned, reverse=True)
            
        return filtered_notes
コード例 #16
0
ファイル: view.py プロジェクト: johnwin/nvpy
    def handler_housekeeper(self):
        # nvPY will do saving and syncing!
        self.notify_observers('keep:house', None)

        # check if titles need refreshing
        refresh_notes_list = False
        prev_title = None
        prev_modifydate = None
        prev_pinned = 0
        for i, o in enumerate(self.notes_list_model.list):
            # order should be the same as our listbox
            nt = utils.get_note_title(o.note)
            ot = self.notes_list.get_title(i)
            # if we strike a note with an out-of-date title, redo.
            if nt != ot:
                logging.debug('title "%s" resync' % (nt, ))
                refresh_notes_list = True
                break

            # compare modifydate timestamp in our notes_list_model to what's displayed
            # if these are more than 60 seconds apart, we want to update our
            # mod-date display.
            md = float(o.note.get('modifydate', 0))
            omd = self.notes_list.get_modifydate(i)
            if abs(md - omd) > 60:
                # we log the title
                logging.debug('modifydate "%s" resync' % (nt, ))
                refresh_notes_list = True
                break

            pinned = utils.note_pinned(o.note)
            old_pinned = self.notes_list.get_pinned(i)
            if pinned != old_pinned:
                # we log the title
                logging.debug('pinned "%s" resync' % (nt, ))
                refresh_notes_list = True
                break

            tags = o.note.get('tags', 0)
            old_tags = self.notes_list.get_tags(i)
            if tags != old_tags:
                # we log the title
                logging.debug('tags "%s" resync' % (nt, ))
                refresh_notes_list = True
                break

            if self.config.sort_mode == 0:
                # alpha
                if prev_title is not None and prev_title > nt:
                    logging.debug("alpha resort triggered")
                    refresh_notes_list = True
                    break

                prev_title = nt

            else:

                # we go from top to bottom, newest to oldest
                # this means that prev_modifydate (above) needs to be larger
                # than md (below). if it's not, re-sort.
                if prev_modifydate is not None and prev_modifydate < md and \
                   not prev_pinned:
                    logging.debug("modifydate resort triggered")
                    refresh_notes_list = True
                    break

                prev_modifydate = md
                if self.config.pinned_ontop:
                    prev_pinned = utils.note_pinned(o.note)

        if refresh_notes_list:
            self.refresh_notes_list()

        self.root.after(self.config.housekeeping_interval_ms,
                        self.handler_housekeeper)
コード例 #17
0
ファイル: view_note.py プロジェクト: Qu4tro/sncli
    def get_status_bar(self):
        if not self.key:
            return \
                urwid.AttrMap(urwid.Text(u'No note...'),
                              'status_bar')

        cur   = -1
        total = 0
        if len(self.body.positions()) > 0:
            cur   = self.focus_position
            total = len(self.body.positions())

        if self.old_note:
            t = time.localtime(float(self.old_note['versiondate']))
            title    = utils.get_note_title(self.old_note)
            version  = self.old_note['version']
        else:
            t = time.localtime(float(self.note['modifydate']))
            title    = utils.get_note_title(self.note)
            flags    = utils.get_note_flags(self.note)
            tags     = utils.get_note_tags(self.note)
            version  = self.note['version']

        mod_time = time.strftime(u'Date: %a, %d %b %Y %H:%M:%S', t)

        status_title = \
            urwid.AttrMap(urwid.Text(u'Title: ' +
                                     title,
                                     wrap='clip'),
                          'status_bar')

        status_key_index = \
            ('pack', urwid.AttrMap(urwid.Text(u' [' + 
                                              self.key + 
                                              u'] ' +
                                              str(cur + 1) +
                                              u'/' +
                                              str(total)),
                                   'status_bar'))

        status_date = \
            urwid.AttrMap(urwid.Text(mod_time,
                                     wrap='clip'),
                          'status_bar')

        if self.old_note:
            status_tags_flags = \
                ('pack', urwid.AttrMap(urwid.Text(u'[OLD:v' + 
                                                  str(version) + 
                                                  u']'),
                                       'status_bar'))
        else:
            status_tags_flags = \
                ('pack', urwid.AttrMap(urwid.Text(u'[' + 
                                                  tags + 
                                                  u'] [v' + 
                                                  str(version) + 
                                                  u'] [' + 
                                                  flags + 
                                                  u']'),
                                       'status_bar'))

        pile_top = urwid.Columns([ status_title, status_key_index ])
        pile_bottom = urwid.Columns([ status_date, status_tags_flags ])

        if self.old_note or \
           not (utils.note_published(self.note) and 'publishkey' in self.note):
            return urwid.AttrMap(urwid.Pile([ pile_top, pile_bottom ]),
                                 'status_bar')

        pile_publish = \
            urwid.AttrMap(urwid.Text(u'Published: http://simp.ly/publish/' +
                                     self.note['publishkey']),
                          'status_bar')
        return \
            urwid.AttrMap(urwid.Pile([ pile_top, pile_bottom, pile_publish ]),
                          'status_bar')
コード例 #18
0
ファイル: view.py プロジェクト: mt3/nvpy
 def set_notes(self, notes):
     # clear the listbox
     self.lb_notes.delete(0, tk.END)
     
     for o in notes:
         self.lb_notes.insert(tk.END, utils.get_note_title(o.note))
コード例 #19
0
ファイル: view.py プロジェクト: DivineDominion/nvpy
    def handler_housekeeper(self):
        # nvPY will do saving and syncing!
        self.notify_observers('keep:house', None)
        
        # check if titles need refreshing
        refresh_notes_list = False
        prev_title = None
        prev_modifydate = None
        prev_pinned = 0
        for i,o in enumerate(self.notes_list_model.list):
            # order should be the same as our listbox
            nt = utils.get_note_title(o.note)
            ot = self.notes_list.get_title(i)
            # if we strike a note with an out-of-date title, redo.
            if nt != ot:
                logging.debug('title "%s" resync' % (nt,))
                refresh_notes_list = True
                break

            # compare modifydate timestamp in our notes_list_model to what's displayed
            # if these are more than 60 seconds apart, we want to update our
            # mod-date display.
            md = float(o.note.get('modifydate', 0))
            omd = self.notes_list.get_modifydate(i)
            if abs(md - omd) > 60:
                # we log the title
                logging.debug('modifydate "%s" resync' % (nt,))
                refresh_notes_list = True
                break

            pinned = utils.note_pinned(o.note)
            old_pinned = self.notes_list.get_pinned(i)
            if pinned != old_pinned:
                # we log the title
                logging.debug('pinned "%s" resync' % (nt,))
                refresh_notes_list = True
                break

            tags = o.note.get('tags', 0)
            old_tags = self.notes_list.get_tags(i)
            if tags != old_tags:
                # we log the title
                logging.debug('tags "%s" resync' % (nt,))
                refresh_notes_list = True
                break

            if self.config.sort_mode == 0:
                # alpha
                if prev_title is not None and prev_title > nt:
                    logging.debug("alpha resort triggered")
                    refresh_notes_list = True
                    break
                
                prev_title = nt
                
            else:

                # we go from top to bottom, newest to oldest
                # this means that prev_modifydate (above) needs to be larger
                # than md (below). if it's not, re-sort.
                if prev_modifydate is not None and prev_modifydate < md and \
                   not prev_pinned:
                    logging.debug("modifydate resort triggered")
                    refresh_notes_list = True
                    break
                
                prev_modifydate = md
                if self.config.pinned_ontop:
                    prev_pinned = utils.note_pinned(o.note)
            
        if refresh_notes_list:
            self.refresh_notes_list()
        
        self.root.after(self.config.housekeeping_interval_ms, self.handler_housekeeper)
コード例 #20
0
ファイル: notes_db.py プロジェクト: ewalstad/nvpy
    def filter_notes(self, search_string=None):
        """Return list of notes filtered with search_string, 
        a regular expression, each a tuple with (local_key, note). 
        """

        if search_string:
            try:
                if self.config.case_sensitive == 0:
                    sspat = re.compile(search_string, re.I)
                else:
                    sspat = re.compile(search_string)
            except re.error:
                sspat = None

        else:
            sspat = None

        filtered_notes = []
        for k in self.notes:
            n = self.notes[k]
            c = n.get('content')
            if self.config.search_tags == 1:
                t = n.get('tags')
                if not n.get('deleted') and sspat:
                    # this used to use a filter(), but that would by definition
                    # test all elements, whereas we can stop when the first
                    # matching element is found
                    # now I'm using this awesome trick by Alex Martelli on
                    # http://stackoverflow.com/a/2748753/532513
                    # first parameter of next is a generator
                    # next() executes one step, but due to the if, this will
                    # either be first matching element or None (second param)
                    if next((ti for ti in t if sspat.search(ti)),
                            None) is not None:
                        # we have to store our local key also
                        filtered_notes.append(
                            utils.KeyValueObject(key=k, note=n, tagfound=1))

                    elif sspat.search(c):
                        # we have to store our local key also
                        filtered_notes.append(
                            utils.KeyValueObject(key=k, note=n, tagfound=0))

                elif not n.get('deleted') and not sspat:
                    # we have to store our local key also
                    filtered_notes.append(
                        utils.KeyValueObject(key=k, note=n, tagfound=0))
            else:
                if not n.get('deleted') and (not sspat or sspat.search(c)):
                    # we have to store our local key also
                    filtered_notes.append(
                        utils.KeyValueObject(key=k, note=n, tagfound=0))

        if self.config.sort_mode == 0:
            if self.config.pinned_ontop == 0:
                # sort alphabetically on title
                filtered_notes.sort(key=lambda o: utils.get_note_title(o.note))
            else:
                filtered_notes.sort(utils.sort_by_title_pinned)

        else:
            if self.config.pinned_ontop == 0:
                # last modified on top
                filtered_notes.sort(
                    key=lambda o: -float(o.note.get('modifydate', 0)))
            else:
                filtered_notes.sort(utils.sort_by_modify_date_pinned,
                                    reverse=True)

        return filtered_notes
コード例 #21
0
ファイル: view_titles.py プロジェクト: virasak/sncli
    def format_title(self, note):
        """
        Various formatting tags are supported for dynamically building
        the title string. Each of these formatting tags supports a width
        specifier (decimal) and a left justification (-) like that
        supported by printf.

        %F -- flags
        %T -- tags
        %D -- date
        %N -- note title
        """

        t = time.localtime(float(note['modifydate']))
        mod_time = time.strftime(self.config.get_config('format_strftime'), t)
        title = utils.get_note_title(note)
        flags = utils.get_note_flags(note)
        tags = utils.get_note_tags(note)

        # get the age of the note
        dt = datetime.datetime.fromtimestamp(time.mktime(t))
        if dt > datetime.datetime.now() - datetime.timedelta(days=1):
            note_age = 'd'  # less than a day old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=1):
            note_age = 'w'  # less than a week old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=4):
            note_age = 'm'  # less than a month old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=52):
            note_age = 'y'  # less than a year old
        else:
            note_age = 'a'  # ancient

        def recursive_format(title_format):
            if not title_format:
                return None
            fmt = re.search("^(.*)%([-]*)([0-9]*)([FDTN])(.*)$", title_format)
            if not fmt:
                m = ('pack', urwid.AttrMap(urwid.Text(title_format),
                                           'default'))
                l_fmt = None
                r_fmt = None
            else:
                l = fmt.group(1) if fmt.group(1) else None
                m = None
                r = fmt.group(5) if fmt.group(5) else None
                align = 'left' if fmt.group(2) == '-' else 'right'
                width = int(fmt.group(3)) if fmt.group(3) else 'pack'
                if fmt.group(4) == 'F':
                    m = (width,
                         urwid.AttrMap(
                             urwid.Text(flags, align=align, wrap='clip'),
                             'note_flags'))
                elif fmt.group(4) == 'D':
                    m = (width,
                         urwid.AttrMap(
                             urwid.Text(mod_time, align=align, wrap='clip'),
                             'note_date'))
                elif fmt.group(4) == 'T':
                    m = (width,
                         urwid.AttrMap(
                             urwid.Text(tags, align=align, wrap='clip'),
                             'note_tags'))
                elif fmt.group(4) == 'N':
                    if note_age == 'd': attr = 'note_title_day'
                    elif note_age == 'w': attr = 'note_title_week'
                    elif note_age == 'm': attr = 'note_title_month'
                    elif note_age == 'y': attr = 'note_title_year'
                    elif note_age == 'a': attr = 'note_title_ancient'
                    if width != 'pack':
                        m = (width,
                             urwid.AttrMap(
                                 urwid.Text(title, align=align, wrap='clip'),
                                 attr))
                    else:
                        m = urwid.AttrMap(
                            urwid.Text(title, align=align, wrap='clip'), attr)
                l_fmt = recursive_format(l)
                r_fmt = recursive_format(r)

            tmp = []
            if l_fmt: tmp.extend(l_fmt)
            tmp.append(m)
            if r_fmt: tmp.extend(r_fmt)
            return tmp

        # convert the format string into the actual note title line
        title_line = recursive_format(
            self.config.get_config('format_note_title'))
        return urwid.Columns(title_line)
コード例 #22
0
ファイル: notes_db.py プロジェクト: ewalstad/nvpy
class NotesDB(utils.SubjectMixin):
    """NotesDB will take care of the local notes database and syncing with SN.
    """
    def __init__(self, config):
        utils.SubjectMixin.__init__(self)

        self.config = config

        # create db dir if it does not exist
        if not os.path.exists(config.db_path):
            os.mkdir(config.db_path)

        self.db_path = config.db_path

        # create txt Notes dir if it does not exist
        if self.config.notes_as_txt and not os.path.exists(config.txt_path):
            os.mkdir(config.txt_path)

        now = time.time()
        # now read all .json files from disk
        fnlist = glob.glob(self.helper_key_to_fname('*'))
        txtlist = glob.glob(self.config.txt_path + '/*.txt')
        txtlist += glob.glob(self.config.txt_path + '/*.mkdn')

        # removing json files and force full full sync if using text files
        # and none exists and json files are there
        if self.config.notes_as_txt and not txtlist and fnlist:
            logging.debug('Forcing resync: using text notes, first usage')
            for fn in fnlist:
                os.unlink(fn)
            fnlist = []

        self.notes = {}
        if self.config.notes_as_txt:
            self.titlelist = {}

        for fn in fnlist:
            try:
                n = json.load(open(fn, 'rb'))
                if self.config.notes_as_txt:
                    nt = utils.get_note_title_file(n)
                    tfn = os.path.join(self.config.txt_path, nt)
                    if os.path.isfile(tfn):
                        self.titlelist[n.get('key')] = nt
                        txtlist.remove(tfn)
                        if os.path.getmtime(tfn) > os.path.getmtime(fn):
                            logging.debug('Text note was changed: %s' % (fn, ))
                            #with open(tfn, mode='r') as f:
                            with codecs.open(tfn, mode='rb',
                                             encoding='utf-8') as f:
                                c = f.read()

                            n['content'] = c
                            n['modifydate'] = os.path.getmtime(tfn)
                    else:
                        logging.debug('Deleting note : %s' % (fn, ))
                        if not self.config.simplenote_sync:
                            os.unlink(fn)
                            continue
                        else:
                            n['deleted'] = 1
                            n['modifydate'] = now

            except ValueError, e:
                logging.error('Error parsing %s: %s' % (fn, str(e)))

            else:
                # we always have a localkey, also when we don't have a note['key'] yet (no sync)
                localkey = os.path.splitext(os.path.basename(fn))[0]
                self.notes[localkey] = n
                # we maintain in memory a timestamp of the last save
                # these notes have just been read, so at this moment
                # they're in sync with the disc.
                n['savedate'] = now

        if self.config.notes_as_txt:
            for fn in txtlist:
                logging.debug('New text note found : %s' % (fn), )
                tfn = os.path.join(self.config.txt_path, fn)
                #with open(tfn, mode='r') as f:
                with codecs.open(tfn, mode='rb', encoding='utf-8') as f:
                    c = f.read()

                nk = self.create_note(c)
                nn = os.path.splitext(os.path.basename(fn))[0]
                if nn != utils.get_note_title(self.notes[nk]):
                    self.notes[nk]['content'] = nn + "\n\n" + c

                os.unlink(tfn)

        # save and sync queue
        self.q_save = Queue()
        self.q_save_res = Queue()

        thread_save = Thread(target=self.worker_save)
        thread_save.setDaemon(True)
        thread_save.start()

        # initialise the simplenote instance we're going to use
        # this does not yet need network access
        if self.config.simplenote_sync:
            self.simplenote = Simplenote(config.sn_username,
                                         config.sn_password)

            # we'll use this to store which notes are currently being synced by
            # the background thread, so we don't add them anew if they're still
            # in progress. This variable is only used by the background thread.
            self.threaded_syncing_keys = {}

            # reading a variable or setting this variable is atomic
            # so sync thread will write to it, main thread will only
            # check it sometimes.
            self.waiting_for_simplenote = False

            self.q_sync = Queue()
            self.q_sync_res = Queue()

            thread_sync = Thread(target=self.worker_sync)
            thread_sync.setDaemon(True)
            thread_sync.start()
コード例 #23
0
 def set_notes(self, notes):
     # clear the listbox
     self.lb_notes.delete(0, tk.END)
     
     for o in notes:
         self.lb_notes.insert(tk.END, utils.get_note_title(o.note))
コード例 #24
0
ファイル: view_note.py プロジェクト: JeffreyVdb/sncli
    def get_status_bar(self):
        if not self.key:
            return \
                urwid.AttrMap(urwid.Text(u'No note...'),
                              'status_bar')

        cur = -1
        total = 0
        if len(self.body.positions()) > 0:
            cur = self.focus_position
            total = len(self.body.positions())

        if self.old_note:
            t = time.localtime(float(self.old_note['versiondate']))
            title = utils.get_note_title(self.old_note)
            version = self.old_note['version']
        else:
            t = time.localtime(float(self.note['modifydate']))
            title = utils.get_note_title(self.note)
            flags = utils.get_note_flags(self.note)
            tags = utils.get_note_tags(self.note)
            version = self.note['version']

        mod_time = time.strftime(u'Date: %a, %d %b %Y %H:%M:%S', t)

        status_title = \
            urwid.AttrMap(urwid.Text(u'Title: ' +
                                     title,
                                     wrap='clip'),
                          'status_bar')

        status_key_index = \
            ('pack', urwid.AttrMap(urwid.Text(u' [' +
                                              self.key +
                                              u'] ' +
                                              str(cur + 1) +
                                              u'/' +
                                              str(total)),
                                   'status_bar'))

        status_date = \
            urwid.AttrMap(urwid.Text(mod_time,
                                     wrap='clip'),
                          'status_bar')

        if self.old_note:
            status_tags_flags = \
                ('pack', urwid.AttrMap(urwid.Text(u'[OLD:v' +
                                                  str(version) +
                                                  u']'),
                                       'status_bar'))
        else:
            status_tags_flags = \
                ('pack', urwid.AttrMap(urwid.Text(u'[' +
                                                  tags +
                                                  u'] [v' +
                                                  str(version) +
                                                  u'] [' +
                                                  flags +
                                                  u']'),
                                       'status_bar'))

        pile_top = urwid.Columns([status_title, status_key_index])
        pile_bottom = urwid.Columns([status_date, status_tags_flags])

        if self.old_note or \
           not (utils.note_published(self.note) and 'publishkey' in self.note):
            return urwid.AttrMap(urwid.Pile([pile_top, pile_bottom]),
                                 'status_bar')

        pile_publish = \
            urwid.AttrMap(urwid.Text(u'Published: http://simp.ly/publish/' +
                                     self.note['publishkey']),
                          'status_bar')
        return \
            urwid.AttrMap(urwid.Pile([ pile_top, pile_bottom, pile_publish ]),
                          'status_bar')
コード例 #25
0
ファイル: view_titles.py プロジェクト: JeffreyVdb/sncli
    def format_title(self, note):
        """
        Various formatting tags are supported for dynamically building
        the title string. Each of these formatting tags supports a width
        specifier (decimal) and a left justification (-) like that
        supported by printf.

        %F -- flags
        %T -- tags
        %D -- date
        %N -- note title
        """

        t = time.localtime(float(note['modifydate']))
        mod_time = time.strftime(self.config.get_config('format_strftime'), t)
        title = utils.get_note_title(note)
        flags = utils.get_note_flags(note)
        tags  = utils.get_note_tags(note)

        # get the age of the note
        dt = datetime.datetime.fromtimestamp(time.mktime(t))
        if dt > datetime.datetime.now() - datetime.timedelta(days=1):
            note_age = 'd' # less than a day old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=1):
            note_age = 'w' # less than a week old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=4):
            note_age = 'm' # less than a month old
        elif dt > datetime.datetime.now() - datetime.timedelta(weeks=52):
            note_age = 'y' # less than a year old
        else:
            note_age = 'a' # ancient

        def recursive_format(title_format):
            if not title_format:
                return None
            fmt = re.search("^(.*)%([-]*)([0-9]*)([FDTN])(.*)$", title_format)
            if not fmt:
                m = ('pack', urwid.AttrMap(urwid.Text(title_format),
                                           'default'))
                l_fmt = None
                r_fmt = None
            else:
                l = fmt.group(1) if fmt.group(1) else None
                m = None
                r = fmt.group(5) if fmt.group(5) else None
                align = 'left' if fmt.group(2) == '-' else 'right'
                width = int(fmt.group(3)) if fmt.group(3) else 'pack'
                if fmt.group(4) == 'F':
                    m = (width, urwid.AttrMap(urwid.Text(flags,
                                                         align=align,
                                                         wrap='clip'),
                                              'note_flags'))
                elif fmt.group(4) == 'D':
                    m = (width, urwid.AttrMap(urwid.Text(mod_time,
                                                         align=align,
                                                         wrap='clip'),
                                              'note_date'))
                elif fmt.group(4) == 'T':
                    m = (width, urwid.AttrMap(urwid.Text(tags,
                                                         align=align,
                                                         wrap='clip'),
                                              'note_tags'))
                elif fmt.group(4) == 'N':
                    if   note_age == 'd': attr = 'note_title_day'
                    elif note_age == 'w': attr = 'note_title_week'
                    elif note_age == 'm': attr = 'note_title_month'
                    elif note_age == 'y': attr = 'note_title_year'
                    elif note_age == 'a': attr = 'note_title_ancient'
                    if width != 'pack':
                        m = (width, urwid.AttrMap(urwid.Text(title,
                                                             align=align,
                                                             wrap='clip'),
                                                  attr))
                    else:
                        m = urwid.AttrMap(urwid.Text(title,
                                                     align=align,
                                                     wrap='clip'),
                                          attr)
                l_fmt = recursive_format(l)
                r_fmt = recursive_format(r)

            tmp = []
            if l_fmt: tmp.extend(l_fmt)
            tmp.append(m)
            if r_fmt: tmp.extend(r_fmt)
            return tmp

        # convert the format string into the actual note title line
        title_line = recursive_format(self.config.get_config('format_note_title'))
        return urwid.Columns(title_line)