snose

Check-in [3ee3b5e7a8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Break many more common bits out into methods:

- snitems (iterating through items)
- snwrite (writing a file from disk)
- snread (reading a file from disk)
- snremote (getting a remote note from Simplenote)+def snitems(snose):

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | master
Files: files | file ages | folders
SHA3-256: 3ee3b5e7a81193cdd30cba37a861d4985dda1138fbbe89c3bb4daa8077b7b049
User & Date: atomicules 2018-11-17 10:59:15
Context
2019-03-10
01:51
Typo, should have been file not filename Leaf check-in: 44025db081 user: atomicules tags: master, trunk
2018-11-17
10:59
Break many more common bits out into methods:

- snitems (iterating through items)
- snwrite (writing a file from disk)
- snread (reading a file from disk)
- snremote (getting a remote note from Simplenote)+def snitems(snose): check-in: 3ee3b5e7a8 user: atomicules tags: master, trunk

2018-11-16
17:46
Move some move common bits out to a method check-in: 20b98bc9de user: atomicules tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to snose.py.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
        print('No options supplied')


def snort(snclient, filename): 
    snose = load_or_new()
    #Add new file to Simplenote
    #Need to get file contents
    try:
        with open(filename, 'r') as f:
            content = f.read()
    except IOError as e:
        print("Failed to read file %s" % filename)
    else:
        try:
            returned = snclient.add_note({"content": content, "tags": ["snose"]})
            print("Imported %s into Simplenote with key %s" % (filename, returned[0]['key']))
        except IOError as e:
            print("Failed to add note to Simplenote")
            print(e)
        else:
            #Add mapping
            snose[filename] = snobject(returned[0], filename)
            write_index(snose, "But note was successfully imported to Simplenote with key %s. Try sniffing the file")


def sniff(snclient, key, filename): #How to ensure remote gets or has snose tag?
    # Add a new mapping only
    snose = load_or_new()
    #Get details about current Simplenote file
    try:
        remote = snclient.get_note(key)
        #What if can't be found, need to abort...
    except IOError as e:
        print("Failed to find that note on Simplenote")
        print(e)
    else:
        #Add mapping
        snose[filename] = snobject(remote[0], filename)
        write_index(snose)


def sneeze(snclient, key, filename):
    #place an existing note in current directory
    snose = load_or_new()
    #Get remote note
    try:
        remote = snclient.get_note(key) 
    except IOerror as e:
        print("Failed to find that note on Simplenote")
        print(e)
    else:
        #Write file
        #If no filename supplied try to figure out from first three lines of file itself
        if filename is None:
            firstlines = remote[0]['content'].splitlines()[:3]
            for line in firstlines:
                try:
                    filename = re.search(r'file:(\S+)', line).group(1)
                except IndexError:
                    pass
                except AttributeError:
                    pass
            if filename is None:
                print("Failed to identify filename within note, please provide on command line")
                sys.exit()
        filename = os.path.expanduser(filename)
        try:
            if sys.version_info < (3, 0):
                with open(filename, 'w') as f:
                    f.write(remote[0]['content'].encode("utf-8"))
            else:
                with open(filename, 'w', encoding="utf-8") as f:
                    f.write(remote[0]['content'])
        except IOError as e:
            print("Failed to create local copy of that note")
            print(e)
        else:
            #Update index
            snose[filename] = snobject(remote[0], filename)
            write_index(snose, "But note was created locally. Try sniffing the file to add it to the index.")


def blow(snclient, key):
    #With given key from .snose file, roll back to the previous version

    #1) Check exists in .snose index
    #2) Get previous version of remote
    #3) Write it out locally
    #4) Use that to update remote
    #5) Update index file with results

    #1) Check exists in .snose index
    try:
        snose = load_or_new()
        #Need to get filename of note, loop through, performance should be fine as .snose likely to be small
        if sys.version_info < (3, 0):
            sitems = snose.iteritems()
        else:
            sitems = snose.items()
        filename = [name for name, local in sitems if local['key'] == key][0]

        print("Attempting to rollback file %s" % filename)
    except IndexError as e:
        print("Note doesn't exist in local .snose index")
    else:
        #2) Get previous version of remote
        try:
            #fetch once to know version
            remote = snclient.get_note(key)
            rollback = snclient.get_note(key, remote[0]['version']-1)
        except IOError as e:
            print("Failed to fetch previous version")
        else:
            try: 
                #3) Write it out locally
                if sys.version_info < (3, 0):
                    with open(filename, 'w') as f:
                        f.write(rollback[0]['content'].encode("utf-8"))
                else:
                    with open(filename, 'w', encoding="utf-8") as f:
                        f.write(rollback[0]['content'])
                print("Rolled back local copy")
            except IOError as e:
                print("Failed to rollback local copy of that note")
                print(e)
            else:
                #Since rollback doesn't include full meta data, update remote accordingly
                try:
                    del remote[0]['version']
                except KeyError:
                    pass
                finally:
                    #Set modified date







<
|
|
<
<
<
















<
|
<
<
<
<
|









<
|
<
<
<
|















<
<
|
<
<
<
<
<
<
|
<


















<
<
<
|














|
<
|
<
<
<
<
<
|
<
<
<
<







56
57
58
59
60
61
62

63
64



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81




82
83
84
85
86
87
88
89
90
91

92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108


109






110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145





146




147
148
149
150
151
152
153
        print('No options supplied')


def snort(snclient, filename): 
    snose = load_or_new()
    #Add new file to Simplenote
    #Need to get file contents

    content = snread(filename)
    if content:



        try:
            returned = snclient.add_note({"content": content, "tags": ["snose"]})
            print("Imported %s into Simplenote with key %s" % (filename, returned[0]['key']))
        except IOError as e:
            print("Failed to add note to Simplenote")
            print(e)
        else:
            #Add mapping
            snose[filename] = snobject(returned[0], filename)
            write_index(snose, "But note was successfully imported to Simplenote with key %s. Try sniffing the file")


def sniff(snclient, key, filename): #How to ensure remote gets or has snose tag?
    # Add a new mapping only
    snose = load_or_new()
    #Get details about current Simplenote file

    remote = snremote(snclient, key)




    if remote:
        #Add mapping
        snose[filename] = snobject(remote[0], filename)
        write_index(snose)


def sneeze(snclient, key, filename):
    #place an existing note in current directory
    snose = load_or_new()
    #Get remote note

    remote = snremote(snclient, key)



    if remote:
        #Write file
        #If no filename supplied try to figure out from first three lines of file itself
        if filename is None:
            firstlines = remote[0]['content'].splitlines()[:3]
            for line in firstlines:
                try:
                    filename = re.search(r'file:(\S+)', line).group(1)
                except IndexError:
                    pass
                except AttributeError:
                    pass
            if filename is None:
                print("Failed to identify filename within note, please provide on command line")
                sys.exit()
        filename = os.path.expanduser(filename)


        ok = snwrite(filename, remote)






        if ok:

            #Update index
            snose[filename] = snobject(remote[0], filename)
            write_index(snose, "But note was created locally. Try sniffing the file to add it to the index.")


def blow(snclient, key):
    #With given key from .snose file, roll back to the previous version

    #1) Check exists in .snose index
    #2) Get previous version of remote
    #3) Write it out locally
    #4) Use that to update remote
    #5) Update index file with results

    #1) Check exists in .snose index
    try:
        snose = load_or_new()
        #Need to get filename of note, loop through, performance should be fine as .snose likely to be small



        sitems = snitems(snose)
        filename = [name for name, local in sitems if local['key'] == key][0]

        print("Attempting to rollback file %s" % filename)
    except IndexError as e:
        print("Note doesn't exist in local .snose index")
    else:
        #2) Get previous version of remote
        try:
            #fetch once to know version
            remote = snclient.get_note(key)
            rollback = snclient.get_note(key, remote[0]['version']-1)
        except IOError as e:
            print("Failed to fetch previous version")
        else:
            ok = snwrite(filename, rollback, msg="Failed to rollback local copy of that note")

            if ok:





                print("Rolled back local copy of that note")




                #Since rollback doesn't include full meta data, update remote accordingly
                try:
                    del remote[0]['version']
                except KeyError:
                    pass
                finally:
                    #Set modified date
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297


def sync(snclient, dry=False):
    #Need to read in mappings and sync those notes.
    dryremotes = []
    snose = load_or_new()
    #Need to iterate through list.
    if sys.version_info < (3, 0):
        sitems = snose.iteritems()
    else:
        sitems = snose.items()
    for name, local in sitems:
        #First of all check for local modifications
        sysmodifydate = float(os.path.getmtime(name))
        if sysmodifydate > float(local['modifydate']): #ensure full timestamp
            if not dry:
            #Update remote
                try:
                    with open(name, 'r') as f:
                        content = f.read()
                except IOError as e:
                    print("Failed to read local note %s" % name)
                    print("Skipping synchronisation for this note")
                else:
                    try:
                        returned = snclient.update_note(snobject(local, name, tags=['snose'], content=content))
                        print("Updated remote version of %s" % name)
                    except IOError as e:
                        print("Failed to update remote verison of local note %s" % name)
                    else:
                        #Get returned metadata
                        snose[name]['version'] = returned[0]['version']
                        snose[name]['modifydate'] = sysmodifydate #Use local value to avoid differences in accuracy (decimal places. etc) between local and remote timestamps
                        #Update local file if merged content
                        if 'content' in returned[0]:
                            try:
                                if sys.version_info < (3, 0):
                                    with open(name, 'w') as f:
                                        f.write(returned[0]['content'].encode("utf-8"))
                                else:
                                    with open(name, 'w', encoding="utf-8") as f:
                                        f.write(returned[0]['content'])
                                print("Merged local content for %s" % name)
                                #Override the returned value? As otherwise next sync will immediately update the remote version for no reason.
                                snose[name]['modifydate'] = os.path.getmtime(name) 
                            except IOError as e:
                                print("Failed to merge content locally for %s" % name)
                                print("Therefore skipping updating the index for this note")#I think this is a good idea?
                        #Update the index file
                        write_index(snose, "But remote and local copy of the file itself have been updated.")
            elif dry:
                print("Updated remote version of %s" % name)
                #For dry run, collect list of "updated remotes" to ignore in local updates
                dryremotes.append(name)
        #Fetch details from Simplenote
        try:
            remote = snclient.get_note(local['key'])
        except IOError as e:
            print("Failed to fetch remote copy of note %s" % name)
            print("Skipping synchronisation for this file")
        else:
            if remote[0]['version'] > local['version']:
                if not dry:
                    try: 

                        if sys.version_info < (3, 0):
                            with open(name, 'w') as f:
                                f.write(remote[0]['content'].encode("utf-8"))
                        else:
                            with open(name, 'w', encoding="utf-8") as f:
                                f.write(remote[0]['content'])
                        print("Updated local version of %s" % name)
                    except IOError as e:
                        print("Failed to update local note %s with remote content" % name)
                        print("Will not updatet the .snose index file for this file")
                    else:
                        #Also update .snose index
                        snose[name]['version'] = remote[0]['version']
                        snose[name]['modifydate'] = os.path.getmtime(name) #As if set remote modify date, local file will immediately appear 'modified'
                        write_index(snose, "But local copy of the file %s has been updated with remote changes" % name)
                elif (dry and (not (name in dryremotes))):
                    print("Updated local version of %s" % name)








<
<
<
|






<
<
<
<
<
|
|











|
|
<
<
<
<
<



<
<
<







<
<
<
<
|
|


<
>
|
<
<
<
<
<

<
<
<
<







181
182
183
184
185
186
187



188
189
190
191
192
193
194





195
196
197
198
199
200
201
202
203
204
205
206
207
208
209





210
211
212



213
214
215
216
217
218
219




220
221
222
223

224
225





226




227
228
229
230
231
232
233


def sync(snclient, dry=False):
    #Need to read in mappings and sync those notes.
    dryremotes = []
    snose = load_or_new()
    #Need to iterate through list.



    sitems = snitems(snose)
    for name, local in sitems:
        #First of all check for local modifications
        sysmodifydate = float(os.path.getmtime(name))
        if sysmodifydate > float(local['modifydate']): #ensure full timestamp
            if not dry:
            #Update remote





                content = snread(name, "Skipping synchronisation for this note")
                if content:
                    try:
                        returned = snclient.update_note(snobject(local, name, tags=['snose'], content=content))
                        print("Updated remote version of %s" % name)
                    except IOError as e:
                        print("Failed to update remote verison of local note %s" % name)
                    else:
                        #Get returned metadata
                        snose[name]['version'] = returned[0]['version']
                        snose[name]['modifydate'] = sysmodifydate #Use local value to avoid differences in accuracy (decimal places. etc) between local and remote timestamps
                        #Update local file if merged content
                        if 'content' in returned[0]:
                            ok = snwrite(name, returned, msg="Failed to merge content locally for %s, therefore skipping updating the index for this note" % name)
                            if ok:





                                print("Merged local content for %s" % name)
                                #Override the returned value? As otherwise next sync will immediately update the remote version for no reason.
                                snose[name]['modifydate'] = os.path.getmtime(name) 



                        #Update the index file
                        write_index(snose, "But remote and local copy of the file itself have been updated.")
            elif dry:
                print("Updated remote version of %s" % name)
                #For dry run, collect list of "updated remotes" to ignore in local updates
                dryremotes.append(name)
        #Fetch details from Simplenote




        remote = snremote(snclient, local['key'], "Skipping synchronisation for this file")
        if remote:
            if remote[0]['version'] > local['version']:
                if not dry:

                    ok = snwrite(name, remote, msg="Failed to update local note %s with remote content. Will not update the .snose index file for this file" % name)
                    if ok:





                        print("Updated local version of %s" % name)




                        #Also update .snose index
                        snose[name]['version'] = remote[0]['version']
                        snose[name]['modifydate'] = os.path.getmtime(name) #As if set remote modify date, local file will immediately appear 'modified'
                        write_index(snose, "But local copy of the file %s has been updated with remote changes" % name)
                elif (dry and (not (name in dryremotes))):
                    print("Updated local version of %s" % name)

319
320
321
322
323
324
325
326


















































327
    sno = {'key': returned['key'], 'version': returned['version'], 'modifydate': float(os.path.getmtime(filename)) }
    if tags:
        sno['tags'] = tags
    if content:
        sno['content'] = content
    return sno




















































main()








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    sno = {'key': returned['key'], 'version': returned['version'], 'modifydate': float(os.path.getmtime(filename)) }
    if tags:
        sno['tags'] = tags
    if content:
        sno['content'] = content
    return sno


def snitems(snose):
    if sys.version_info < (3, 0):
        sitems = snose.iteritems()
    else:
        sitems = snose.items()
    return sitems


def snwrite(name, remote, msg=None):
    try:
        if sys.version_info < (3, 0):
            with open(name, 'w') as f:
                f.write(remote[0]['content'].encode("utf-8"))
        else:
            with open(name, 'w', encoding="utf-8") as f:
                f.write(remote[0]['content'])
    except IOError as e:
        if msg:
            print(msg)
        print("Failed to create local copy of that note")
        print(e)
    else:
        return True


def snread(filename, msg=None):
    try:
        with open(filename, 'r') as f:
            content = f.read()
    except IOError as e:
        print("Failed to read file %s" % filename)
        if msg:
            print(msg)
    else:
        return content


def snremote(snclient, key, msg=None):
    try:
        remote = snclient.get_note(key)
        #What if can't be found, need to abort...
    except IOError as e:
        print("Failed to find that note on Simplenote")
        print(e)
        if msg:
            print(msg)
    else:
        return remote


main()