~umang/indicator-stickynotes/trunk

« back to all changes in this revision

Viewing changes to stickynotes/backend.py

  • Committer: Umang Varma
  • Date: 2022-03-12 23:34:38 UTC
  • Revision ID: git-v1:5c567b9671f55f67086ff6aba645c3fed424813a
Bump version 0.5.9 -> 0.5.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright © 2012 Umang Varma <umang.me@gmail.com>
 
1
# Copyright © 2012-2015 Umang Varma <umang.me@gmail.com>
2
2
3
3
# This file is part of indicator-stickynotes.
4
4
19
19
import uuid
20
20
import json
21
21
from os.path import expanduser
22
 
from stickynotes.info import SETTINGS_FILE
 
22
 
 
23
from stickynotes.info import FALLBACK_PROPERTIES
23
24
 
24
25
class Note:
25
 
    def __init__(self, content=None, gui_class=None, noteset=None):
 
26
    def __init__(self, content=None, gui_class=None, noteset=None,
 
27
            category=None):
 
28
        self.gui_class = gui_class
 
29
        self.noteset = noteset
26
30
        content = content or {}
27
31
        self.uuid = content.get('uuid')
28
32
        self.body = content.get('body','')
29
33
        self.properties = content.get("properties", {})
 
34
        self.category = category or content.get("cat", "")
 
35
        if not self.category in self.noteset.categories:
 
36
            self.category = ""
30
37
        last_modified = content.get('last_modified')
31
38
        if last_modified:
32
39
            self.last_modified = datetime.strptime(last_modified,
33
40
                    "%Y-%m-%dT%H:%M:%S")
34
41
        else:
35
42
            self.last_modified = datetime.now()
36
 
        self.gui_class = gui_class
 
43
        # Don't create GUI until show is called
37
44
        self.gui = None
38
 
        self.noteset = noteset
39
45
 
40
46
    def extract(self):
41
 
        self.gui.update_note()
42
47
        if not self.uuid:
43
48
            self.uuid = str(uuid.uuid4())
44
 
        self.properties = self.gui.properties()
 
49
        if self.gui != None:
 
50
            self.gui.update_note()
 
51
            self.properties = self.gui.properties()
45
52
        return {"uuid":self.uuid, "body":self.body,
46
53
                "last_modified":self.last_modified.strftime(
47
 
                    "%Y-%m-%dT%H:%M:%S"), "properties":self.properties}
 
54
                    "%Y-%m-%dT%H:%M:%S"), "properties":self.properties,
 
55
                "cat": self.category}
48
56
 
49
57
    def update(self,body=None):
50
58
        if not body == None:
56
64
        self.noteset.save()
57
65
        del self
58
66
 
59
 
    def show(self, *args):
60
 
        if not self.gui:
 
67
    def show(self, *args, **kwargs):
 
68
        # If GUI has not been created, create it now
 
69
        if self.gui == None:
61
70
            self.gui = self.gui_class(note=self)
62
 
        self.gui.show(*args)
 
71
        else:
 
72
            self.gui.show(*args, **kwargs)
63
73
 
64
74
    def hide(self):
65
 
        self.gui.hide()
 
75
        if self.gui != None:
 
76
            self.gui.hide()
 
77
 
 
78
    def set_locked_state(self, locked):
 
79
        # if gui hasn't been initialized, just change the property
 
80
        if self.gui == None:
 
81
            self.properties["locked"] = locked
 
82
        else:
 
83
            self.gui.set_locked_state(locked)
 
84
 
 
85
    def cat_prop(self, prop):
 
86
        """Gets a property of the note's category"""
 
87
        return self.noteset.get_category_property(self.category, prop)
66
88
 
67
89
 
68
90
class NoteSet:
69
 
    def __init__(self, gui_class):
 
91
    def __init__(self, gui_class, data_file, indicator):
70
92
        self.notes = []
 
93
        self.properties = {}
 
94
        self.categories = {}
71
95
        self.gui_class = gui_class
 
96
        self.data_file = data_file
 
97
        self.indicator = indicator
72
98
 
73
99
    def _loads_updater(self, dnoteset):
74
100
        """Parses old versions of the Notes structure and updates them"""
77
103
    def loads(self, snoteset):
78
104
        """Loads notes into their respective objects"""
79
105
        notes = self._loads_updater(json.loads(snoteset))
 
106
        self.properties = notes.get("properties", {})
 
107
        self.categories = notes.get("categories", {})
80
108
        self.notes = [Note(note, gui_class=self.gui_class, noteset=self)
81
109
                for note in notes.get("notes",[])]
82
110
 
83
111
    def dumps(self):
84
 
        return json.dumps({"notes":[x.extract() for x in self.notes]})
 
112
        return json.dumps({"notes":[x.extract() for x in self.notes],
 
113
            "properties": self.properties, "categories": self.categories})
85
114
 
86
115
    def save(self, path=''):
87
116
        output = self.dumps()
88
 
        with open(path or expanduser(SETTINGS_FILE),
 
117
        with open(path or expanduser(self.data_file),
89
118
                mode='w', encoding='utf-8') as fsock:
90
119
            fsock.write(output)
91
120
 
92
121
    def open(self, path=''):
93
 
        try:
94
 
            with open(path or expanduser(SETTINGS_FILE), 
95
 
                    encoding='utf-8') as fsock:
96
 
                self.loads(fsock.read())
97
 
        except IOError:
98
 
            self.loads('{}')
99
 
            self.new()
 
122
        with open(path or expanduser(self.data_file), 
 
123
                encoding='utf-8') as fsock:
 
124
            self.loads(fsock.read())
 
125
 
 
126
    def load_fresh(self):
 
127
        """Load empty data"""
 
128
        self.loads('{}')
 
129
        self.new()
 
130
 
 
131
    def merge(self, data):
 
132
        """Update notes based on new data"""
 
133
        jdata = self._loads_updater(json.loads(data))
 
134
        self.hideall()
 
135
        # update categories
 
136
        if "categories" in jdata:
 
137
            self.categories.update(jdata["categories"])
 
138
        # make a dictionary of notes so we can modify existing notes
 
139
        dnotes = {n.uuid : n for n in self.notes}
 
140
        for newnote in jdata.get("notes", []):
 
141
            if "uuid" in newnote and newnote["uuid"] in dnotes:
 
142
                # Update notes that are already in the noteset
 
143
                orignote = dnotes[newnote["uuid"]]
 
144
                if "body" in newnote:
 
145
                    orignote.body = newnote["body"]
 
146
                if "properties" in newnote:
 
147
                    orignote.properties = newnote["properties"]
 
148
                if "cat" in newnote:
 
149
                    orignote.category = newnote["cat"]
 
150
            else:
 
151
                # otherwise create a new note
 
152
                if "uuid" in newnote:
 
153
                    uuid = newnote["uuid"]
 
154
                else:
 
155
                    uuid = str(uuid.uuid4())
 
156
                dnotes[uuid] = Note(newnote, gui_class=self.gui_class,
 
157
                        noteset=self)
 
158
        # copy notes over from dictionary to list
 
159
        self.notes = list(dnotes.values())
 
160
        self.showall(reload_from_backend=True)
100
161
 
101
162
    def new(self):
102
163
        """Creates a new note and adds it to the note set"""
103
 
        note = Note(gui_class=self.gui_class, noteset=self)
 
164
        note = Note(gui_class=self.gui_class, noteset=self,
 
165
                category=self.properties.get("default_cat", ""))
104
166
        self.notes.append(note)
105
167
        note.show()
106
168
        return note
107
169
 
108
 
    def showall(self, *args):
 
170
    def showall(self, *args, **kwargs):
109
171
        for note in self.notes:
110
 
            note.show(*args)
 
172
            note.show(*args, **kwargs)
 
173
        self.properties["all_visible"] = True
111
174
 
112
175
    def hideall(self, *args):
113
176
        self.save()
114
177
        for note in self.notes:
115
178
            note.hide(*args)
 
179
        self.properties["all_visible"] = False
 
180
 
 
181
    def get_category_property(self, cat, prop):
 
182
        """Get a property of a category or the default"""
 
183
        if ((not cat) or (not cat in self.categories)) and \
 
184
                self.properties.get("default_cat", None):
 
185
            cat = self.properties["default_cat"]
 
186
        cat_data = self.categories.get(cat, {})
 
187
        if prop in cat_data:
 
188
            return cat_data[prop]
 
189
        # Otherwise, use fallback categories
 
190
        if prop in FALLBACK_PROPERTIES:
 
191
            return FALLBACK_PROPERTIES[prop]
 
192
        else:
 
193
            raise ValueError("Unknown property")
116
194
 
117
195
class dGUI:
 
196
    """Dummy GUI"""
118
197
    def __init__(self, *args, **kwargs):
119
198
        pass
120
 
    """Dummy GUI"""
121
199
    def show(self):
122
200
        pass
123
201
    def hide(self):