0000: 23 21 2f 75 73 72 2f 62 69 6e 2f 70 79 74 68 6f #!/usr/bin/pytho
0010: 6e 0a 23 73 6e 6f 73 65 20 2d 20 53 69 6d 70 6c n.#snose - Simpl
0020: 65 6e 6f 74 65 20 4f 62 6a 65 63 74 20 53 79 6e enote Object Syn
0030: 63 68 72 6f 6e 69 73 61 74 69 6f 6e 20 28 45 78 chronisation (Ex
0040: 70 6c 69 63 69 74 29 0a 0a 69 6d 70 6f 72 74 20 plicit)..import
0050: 73 79 73 0a 69 6d 70 6f 72 74 20 6a 73 6f 6e 0a sys.import json.
0060: 69 6d 70 6f 72 74 20 73 69 6d 70 6c 65 6e 6f 74 import simplenot
0070: 65 20 23 4e 65 65 64 20 74 6f 20 69 6e 73 74 61 e #Need to insta
0080: 6c 6c 20 74 68 69 73 0a 69 6d 70 6f 72 74 20 6f ll this.import o
0090: 73 2e 70 61 74 68 2c 20 74 69 6d 65 0a 66 72 6f s.path, time.fro
00a0: 6d 20 6f 70 74 70 61 72 73 65 20 69 6d 70 6f 72 m optparse impor
00b0: 74 20 4f 70 74 69 6f 6e 50 61 72 73 65 72 0a 69 t OptionParser.i
00c0: 6d 70 6f 72 74 20 6e 65 74 72 63 0a 69 6d 70 6f mport netrc.impo
00d0: 72 74 20 72 65 0a 0a 64 65 66 20 6d 61 69 6e 28 rt re..def main(
00e0: 29 3a 0a 20 20 20 20 70 61 72 73 65 72 20 3d 20 ):. parser =
00f0: 4f 70 74 69 6f 6e 50 61 72 73 65 72 28 29 0a 20 OptionParser().
0100: 20 20 20 70 61 72 73 65 72 2e 61 64 64 5f 6f 70 parser.add_op
0110: 74 69 6f 6e 28 22 2d 2d 73 6e 6f 72 74 22 2c 20 tion("--snort",
0120: 61 63 74 69 6f 6e 3d 22 73 74 6f 72 65 5f 74 72 action="store_tr
0130: 75 65 22 2c 20 64 65 66 61 75 6c 74 3d 46 61 6c ue", default=Fal
0140: 73 65 2c 20 68 65 6c 70 3d 22 49 6d 70 6f 72 74 se, help="Import
0150: 20 61 20 6e 65 77 20 66 69 6c 65 20 74 6f 20 53 a new file to S
0160: 69 6d 70 6c 65 6e 6f 74 65 22 29 0a 20 20 20 20 implenote").
0170: 70 61 72 73 65 72 2e 61 64 64 5f 6f 70 74 69 6f parser.add_optio
0180: 6e 28 22 2d 2d 73 6e 69 66 66 22 2c 20 61 63 74 n("--sniff", act
0190: 69 6f 6e 3d 22 73 74 6f 72 65 22 2c 20 6e 61 72 ion="store", nar
01a0: 67 73 3d 31 2c 20 74 79 70 65 3d 22 73 74 72 69 gs=1, type="stri
01b0: 6e 67 22 2c 20 68 65 6c 70 3d 22 4c 69 6e 6b 20 ng", help="Link
01c0: 61 20 66 69 6c 65 20 77 69 74 68 20 61 6e 20 61 a file with an a
01d0: 6c 72 65 61 64 79 20 65 78 69 73 74 69 6e 67 20 lready existing
01e0: 6e 6f 74 65 20 69 6e 20 53 69 6d 70 6c 65 6e 6f note in Simpleno
01f0: 74 65 22 2c 20 6d 65 74 61 76 61 72 3d 22 3c 6b te", metavar="<k
0200: 65 79 3e 22 29 0a 20 20 20 20 70 61 72 73 65 72 ey>"). parser
0210: 2e 61 64 64 5f 6f 70 74 69 6f 6e 28 22 2d 2d 73 .add_option("--s
0220: 6e 65 65 7a 65 22 2c 20 61 63 74 69 6f 6e 3d 22 neeze", action="
0230: 73 74 6f 72 65 22 2c 20 6e 61 72 67 73 3d 31 2c store", nargs=1,
0240: 20 74 79 70 65 3d 22 73 74 72 69 6e 67 22 2c 20 type="string",
0250: 68 65 6c 70 3d 22 45 78 70 6f 72 74 20 61 6e 20 help="Export an
0260: 65 78 69 73 74 69 6e 67 20 66 69 6c 65 20 66 72 existing file fr
0270: 6f 6d 20 53 69 6d 70 6c 65 6e 6f 74 65 22 2c 20 om Simplenote",
0280: 6d 65 74 61 76 61 72 3d 22 3c 6b 65 79 3e 22 29 metavar="<key>")
0290: 0a 20 20 20 20 70 61 72 73 65 72 2e 61 64 64 5f . parser.add_
02a0: 6f 70 74 69 6f 6e 28 22 2d 2d 62 6c 6f 77 22 2c option("--blow",
02b0: 20 61 63 74 69 6f 6e 3d 22 73 74 6f 72 65 22 2c action="store",
02c0: 20 74 79 70 65 3d 22 73 74 72 69 6e 67 22 2c 20 type="string",
02d0: 68 65 6c 70 3d 22 52 6f 6c 6c 20 62 61 63 6b 20 help="Roll back
02e0: 6e 6f 74 65 20 6b 65 79 20 74 6f 20 70 72 65 76 note key to prev
02f0: 69 6f 75 73 20 76 65 72 73 69 6f 6e 22 2c 20 6d ious version", m
0300: 65 74 61 76 61 72 3d 22 3c 6b 65 79 3e 22 29 0a etavar="<key>").
0310: 20 20 20 20 70 61 72 73 65 72 2e 61 64 64 5f 6f parser.add_o
0320: 70 74 69 6f 6e 28 22 2d 2d 73 79 6e 63 22 2c 20 ption("--sync",
0330: 68 65 6c 70 3d 22 53 79 6e 63 20 66 69 6c 65 73 help="Sync files
0340: 20 69 6e 20 69 6e 64 65 78 22 2c 20 64 65 66 61 in index", defa
0350: 75 6c 74 3d 46 61 6c 73 65 2c 20 61 63 74 69 6f ult=False, actio
0360: 6e 3d 27 73 74 6f 72 65 5f 74 72 75 65 27 29 0a n='store_true').
0370: 20 20 20 20 70 61 72 73 65 72 2e 61 64 64 5f 6f parser.add_o
0380: 70 74 69 6f 6e 28 22 2d 2d 68 61 6e 6b 79 22 2c ption("--hanky",
0390: 20 68 65 6c 70 3d 22 55 73 65 20 77 69 74 68 20 help="Use with
03a0: 2d 2d 73 79 6e 63 20 74 6f 20 70 65 72 66 6f 72 --sync to perfor
03b0: 6d 20 61 20 64 72 79 20 72 75 6e 22 2c 20 64 65 m a dry run", de
03c0: 66 61 75 6c 74 3d 46 61 6c 73 65 2c 20 61 63 74 fault=False, act
03d0: 69 6f 6e 3d 27 73 74 6f 72 65 5f 74 72 75 65 27 ion='store_true'
03e0: 29 0a 20 20 20 20 70 61 72 73 65 72 2e 61 64 64 ). parser.add
03f0: 5f 6f 70 74 69 6f 6e 28 22 2d 2d 73 6e 6f 74 22 _option("--snot"
0400: 2c 20 68 65 6c 70 3d 22 4c 69 73 74 20 6e 6f 74 , help="List not
0410: 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72 es available for
0420: 20 65 78 70 6f 72 74 20 28 74 61 67 67 65 64 20 export (tagged
0430: 73 6e 6f 73 65 29 22 2c 20 64 65 66 61 75 6c 74 snose)", default
0440: 3d 46 61 6c 73 65 2c 20 61 63 74 69 6f 6e 3d 27 =False, action='
0450: 73 74 6f 72 65 5f 74 72 75 65 27 29 0a 20 20 20 store_true').
0460: 20 70 61 72 73 65 72 2e 61 64 64 5f 6f 70 74 69 parser.add_opti
0470: 6f 6e 28 22 2d 2d 66 69 6c 65 22 2c 20 68 65 6c on("--file", hel
0480: 70 3d 22 46 69 6c 65 6e 61 6d 65 20 66 6f 72 20 p="Filename for
0490: 73 6e 6f 72 74 2c 20 73 6e 69 66 66 2c 20 73 6e snort, sniff, sn
04a0: 65 65 7a 65 22 2c 20 64 65 66 61 75 6c 74 3d 4e eeze", default=N
04b0: 6f 6e 65 2c 20 61 63 74 69 6f 6e 3d 27 73 74 6f one, action='sto
04c0: 72 65 27 29 0a 20 20 20 20 70 61 72 73 65 72 2e re'). parser.
04d0: 61 64 64 5f 6f 70 74 69 6f 6e 28 22 2d 2d 75 73 add_option("--us
04e0: 65 72 6e 61 6d 65 22 2c 20 61 63 74 69 6f 6e 3d ername", action=
04f0: 22 73 74 6f 72 65 22 2c 20 74 79 70 65 3d 22 73 "store", type="s
0500: 74 72 69 6e 67 22 2c 20 68 65 6c 70 3d 22 59 6f tring", help="Yo
0510: 75 72 20 53 69 6d 70 6c 65 6e 6f 74 65 20 65 6d ur Simplenote em
0520: 61 69 6c 20 61 64 64 72 65 73 73 22 29 0a 20 20 ail address").
0530: 20 20 70 61 72 73 65 72 2e 61 64 64 5f 6f 70 74 parser.add_opt
0540: 69 6f 6e 28 22 2d 2d 70 61 73 73 77 6f 72 64 22 ion("--password"
0550: 2c 20 61 63 74 69 6f 6e 3d 22 73 74 6f 72 65 22 , action="store"
0560: 2c 20 74 79 70 65 3d 22 73 74 72 69 6e 67 22 2c , type="string",
0570: 20 68 65 6c 70 3d 22 59 6f 75 72 20 53 69 6d 70 help="Your Simp
0580: 6c 65 6e 6f 74 65 20 70 61 73 73 77 6f 72 64 22 lenote password"
0590: 29 0a 20 20 20 20 28 6f 70 74 69 6f 6e 73 2c 20 ). (options,
05a0: 61 72 67 73 29 20 3d 20 70 61 72 73 65 72 2e 70 args) = parser.p
05b0: 61 72 73 65 5f 61 72 67 73 28 29 0a 0a 20 20 20 arse_args()..
05c0: 20 69 66 20 6e 6f 74 20 6f 70 74 69 6f 6e 73 2e if not options.
05d0: 75 73 65 72 6e 61 6d 65 20 6f 72 20 6e 6f 74 20 username or not
05e0: 6f 70 74 69 6f 6e 73 2e 70 61 73 73 77 6f 72 64 options.password
05f0: 3a 0a 20 20 20 20 20 20 20 20 23 43 68 65 63 6b :. #Check
0600: 20 74 6f 20 73 65 65 20 69 66 20 73 74 6f 72 65 to see if store
0610: 64 20 73 6f 6d 65 77 68 65 72 65 0a 20 20 20 20 d somewhere.
0620: 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 try:.
0630: 20 20 20 20 20 6f 70 74 69 6f 6e 73 2e 75 73 65 options.use
0640: 72 6e 61 6d 65 20 3d 20 6e 65 74 72 63 2e 6e 65 rname = netrc.ne
0650: 74 72 63 28 29 2e 61 75 74 68 65 6e 74 69 63 61 trc().authentica
0660: 74 6f 72 73 28 22 73 69 6d 70 6c 65 2d 6e 6f 74 tors("simple-not
0670: 65 2e 61 70 70 73 70 6f 74 2e 63 6f 6d 22 29 5b e.appspot.com")[
0680: 30 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 6f 0]. o
0690: 70 74 69 6f 6e 73 2e 70 61 73 73 77 6f 72 64 20 ptions.password
06a0: 3d 20 6e 65 74 72 63 2e 6e 65 74 72 63 28 29 2e = netrc.netrc().
06b0: 61 75 74 68 65 6e 74 69 63 61 74 6f 72 73 28 22 authenticators("
06c0: 73 69 6d 70 6c 65 2d 6e 6f 74 65 2e 61 70 70 73 simple-note.apps
06d0: 70 6f 74 2e 63 6f 6d 22 29 5b 32 5d 0a 20 20 20 pot.com")[2].
06e0: 20 20 20 20 20 65 78 63 65 70 74 20 49 4f 45 72 except IOEr
06f0: 72 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 20 20 ror as e:.
0700: 20 20 20 20 20 20 70 72 69 6e 74 28 27 55 73 65 print('Use
0710: 72 6e 61 6d 65 20 61 6e 64 20 70 61 73 73 77 6f rname and passwo
0720: 72 64 20 6d 75 73 74 20 62 65 20 73 75 70 70 6c rd must be suppl
0730: 69 65 64 20 6f 72 20 65 78 69 73 74 20 2e 6e 65 ied or exist .ne
0740: 74 72 63 20 66 69 6c 65 20 75 6e 64 65 72 20 64 trc file under d
0750: 6f 6d 61 69 6e 20 6f 66 20 73 69 6d 70 6c 65 2d omain of simple-
0760: 6e 6f 74 65 2e 61 70 70 73 70 6f 74 2e 63 6f 6d note.appspot.com
0770: 27 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 '). s
0780: 79 73 2e 65 78 69 74 28 29 0a 20 20 20 20 73 6e ys.exit(). sn
0790: 63 6c 69 65 6e 74 20 3d 20 73 69 6d 70 6c 65 6e client = simplen
07a0: 6f 74 65 2e 53 69 6d 70 6c 65 6e 6f 74 65 28 6f ote.Simplenote(o
07b0: 70 74 69 6f 6e 73 2e 75 73 65 72 6e 61 6d 65 2c ptions.username,
07c0: 20 6f 70 74 69 6f 6e 73 2e 70 61 73 73 77 6f 72 options.passwor
07d0: 64 29 0a 20 20 20 20 69 66 20 6f 70 74 69 6f 6e d). if option
07e0: 73 2e 73 6e 6f 72 74 3a 0a 20 20 20 20 20 20 20 s.snort:.
07f0: 20 69 66 20 6f 70 74 69 6f 6e 73 2e 66 69 6c 65 if options.file
0800: 20 69 73 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 is None:.
0810: 20 20 20 20 20 20 70 72 69 6e 74 28 27 2d 2d 66 print('--f
0820: 69 6c 65 20 72 65 71 75 69 72 65 64 27 29 0a 20 ile required').
0830: 20 20 20 20 20 20 20 20 20 20 20 73 79 73 2e 65 sys.e
0840: 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 73 6e xit(). sn
0850: 6f 72 74 28 73 6e 63 6c 69 65 6e 74 2c 20 6f 70 ort(snclient, op
0860: 74 69 6f 6e 73 2e 66 69 6c 65 29 0a 20 20 20 20 tions.file).
0870: 65 6c 69 66 20 6f 70 74 69 6f 6e 73 2e 73 6e 69 elif options.sni
0880: 66 66 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6f ff:. if o
0890: 70 74 69 6f 6e 73 2e 66 69 6c 65 20 69 73 20 4e ptions.file is N
08a0: 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 one:.
08b0: 20 70 72 69 6e 74 28 27 2d 2d 66 69 6c 65 20 72 print('--file r
08c0: 65 71 75 69 72 65 64 27 29 0a 20 20 20 20 20 20 equired').
08d0: 20 20 20 20 20 20 73 79 73 2e 65 78 69 74 28 29 sys.exit()
08e0: 0a 20 20 20 20 20 20 20 20 73 6e 69 66 66 28 73 . sniff(s
08f0: 6e 63 6c 69 65 6e 74 2c 20 6f 70 74 69 6f 6e 73 nclient, options
0900: 2e 73 6e 69 66 66 2c 20 6f 70 74 69 6f 6e 73 2e .sniff, options.
0910: 66 69 6c 65 29 0a 20 20 20 20 65 6c 69 66 20 6f file). elif o
0920: 70 74 69 6f 6e 73 2e 73 6e 65 65 7a 65 3a 0a 20 ptions.sneeze:.
0930: 20 20 20 20 20 20 20 73 6e 65 65 7a 65 28 73 6e sneeze(sn
0940: 63 6c 69 65 6e 74 2c 20 6f 70 74 69 6f 6e 73 2e client, options.
0950: 73 6e 65 65 7a 65 2c 20 6f 70 74 69 6f 6e 73 2e sneeze, options.
0960: 66 69 6c 65 29 0a 20 20 20 20 65 6c 69 66 20 6f file). elif o
0970: 70 74 69 6f 6e 73 2e 62 6c 6f 77 3a 0a 20 20 20 ptions.blow:.
0980: 20 20 20 20 20 62 6c 6f 77 28 73 6e 63 6c 69 65 blow(snclie
0990: 6e 74 2c 20 6f 70 74 69 6f 6e 73 2e 62 6c 6f 77 nt, options.blow
09a0: 29 0a 20 20 20 20 65 6c 69 66 20 6f 70 74 69 6f ). elif optio
09b0: 6e 73 2e 73 6e 6f 74 3a 0a 20 20 20 20 20 20 20 ns.snot:.
09c0: 20 73 6e 6f 74 28 73 6e 63 6c 69 65 6e 74 29 0a snot(snclient).
09d0: 20 20 20 20 65 6c 69 66 20 6f 70 74 69 6f 6e 73 elif options
09e0: 2e 73 79 6e 63 20 61 6e 64 20 6f 70 74 69 6f 6e .sync and option
09f0: 73 2e 68 61 6e 6b 79 3a 0a 20 20 20 20 20 20 20 s.hanky:.
0a00: 20 73 79 6e 63 28 73 6e 63 6c 69 65 6e 74 2c 20 sync(snclient,
0a10: 54 72 75 65 29 0a 20 20 20 20 65 6c 69 66 20 6f True). elif o
0a20: 70 74 69 6f 6e 73 2e 73 79 6e 63 3a 0a 20 20 20 ptions.sync:.
0a30: 20 20 20 20 20 73 79 6e 63 28 73 6e 63 6c 69 65 sync(snclie
0a40: 6e 74 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 nt). else:.
0a50: 20 20 20 20 20 20 70 72 69 6e 74 28 27 4e 6f 20 print('No
0a60: 6f 70 74 69 6f 6e 73 20 73 75 70 70 6c 69 65 64 options supplied
0a70: 27 29 0a 0a 0a 64 65 66 20 73 6e 6f 72 74 28 73 ')...def snort(s
0a80: 6e 63 6c 69 65 6e 74 2c 20 66 69 6c 65 6e 61 6d nclient, filenam
0a90: 65 29 3a 20 0a 20 20 20 20 73 6e 6f 73 65 20 3d e): . snose =
0aa0: 20 6c 6f 61 64 5f 6f 72 5f 6e 65 77 28 29 0a 20 load_or_new().
0ab0: 20 20 20 23 41 64 64 20 6e 65 77 20 66 69 6c 65 #Add new file
0ac0: 20 74 6f 20 53 69 6d 70 6c 65 6e 6f 74 65 0a 20 to Simplenote.
0ad0: 20 20 20 23 4e 65 65 64 20 74 6f 20 67 65 74 20 #Need to get
0ae0: 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73 0a 20 20 file contents.
0af0: 20 20 63 6f 6e 74 65 6e 74 20 3d 20 73 6e 72 65 content = snre
0b00: 61 64 28 66 69 6c 65 6e 61 6d 65 29 0a 20 20 20 ad(filename).
0b10: 20 69 66 20 63 6f 6e 74 65 6e 74 3a 0a 20 20 20 if content:.
0b20: 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 try:.
0b30: 20 20 20 20 20 20 72 65 74 75 72 6e 65 64 20 3d returned =
0b40: 20 73 6e 63 6c 69 65 6e 74 2e 61 64 64 5f 6e 6f snclient.add_no
0b50: 74 65 28 7b 22 63 6f 6e 74 65 6e 74 22 3a 20 63 te({"content": c
0b60: 6f 6e 74 65 6e 74 2c 20 22 74 61 67 73 22 3a 20 ontent, "tags":
0b70: 5b 22 73 6e 6f 73 65 22 5d 7d 29 0a 20 20 20 20 ["snose"]}).
0b80: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 49 print("I
0b90: 6d 70 6f 72 74 65 64 20 25 73 20 69 6e 74 6f 20 mported %s into
0ba0: 53 69 6d 70 6c 65 6e 6f 74 65 20 77 69 74 68 20 Simplenote with
0bb0: 6b 65 79 20 25 73 22 20 25 20 28 66 69 6c 65 6e key %s" % (filen
0bc0: 61 6d 65 2c 20 72 65 74 75 72 6e 65 64 5b 30 5d ame, returned[0]
0bd0: 5b 27 6b 65 79 27 5d 29 29 0a 20 20 20 20 20 20 ['key'])).
0be0: 20 20 65 78 63 65 70 74 20 49 4f 45 72 72 6f 72 except IOError
0bf0: 20 61 73 20 65 3a 0a 20 20 20 20 20 20 20 20 20 as e:.
0c00: 20 20 20 70 72 69 6e 74 28 22 46 61 69 6c 65 64 print("Failed
0c10: 20 74 6f 20 61 64 64 20 6e 6f 74 65 20 74 6f 20 to add note to
0c20: 53 69 6d 70 6c 65 6e 6f 74 65 22 29 0a 20 20 20 Simplenote").
0c30: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 65 print(e
0c40: 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a ). else:.
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 23 41 64 64 #Add
0c60: 20 6d 61 70 70 69 6e 67 0a 20 20 20 20 20 20 20 mapping.
0c70: 20 20 20 20 20 73 6e 6f 73 65 5b 66 69 6c 65 6e snose[filen
0c80: 61 6d 65 5d 20 3d 20 73 6e 6f 62 6a 65 63 74 28 ame] = snobject(
0c90: 72 65 74 75 72 6e 65 64 5b 30 5d 2c 20 66 69 6c returned[0], fil
0ca0: 65 6e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 20 ename).
0cb0: 20 20 20 77 72 69 74 65 5f 69 6e 64 65 78 28 73 write_index(s
0cc0: 6e 6f 73 65 2c 20 22 42 75 74 20 6e 6f 74 65 20 nose, "But note
0cd0: 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 was successfully
0ce0: 20 69 6d 70 6f 72 74 65 64 20 74 6f 20 53 69 6d imported to Sim
0cf0: 70 6c 65 6e 6f 74 65 20 77 69 74 68 20 6b 65 79 plenote with key
0d00: 20 25 73 2e 20 54 72 79 20 73 6e 69 66 66 69 6e %s. Try sniffin
0d10: 67 20 74 68 65 20 66 69 6c 65 22 29 0a 0a 0a 64 g the file")...d
0d20: 65 66 20 73 6e 69 66 66 28 73 6e 63 6c 69 65 6e ef sniff(snclien
0d30: 74 2c 20 6b 65 79 2c 20 66 69 6c 65 6e 61 6d 65 t, key, filename
0d40: 29 3a 20 23 48 6f 77 20 74 6f 20 65 6e 73 75 72 ): #How to ensur
0d50: 65 20 72 65 6d 6f 74 65 20 67 65 74 73 20 6f 72 e remote gets or
0d60: 20 68 61 73 20 73 6e 6f 73 65 20 74 61 67 3f 0a has snose tag?.
0d70: 20 20 20 20 23 20 41 64 64 20 61 20 6e 65 77 20 # Add a new
0d80: 6d 61 70 70 69 6e 67 20 6f 6e 6c 79 0a 20 20 20 mapping only.
0d90: 20 73 6e 6f 73 65 20 3d 20 6c 6f 61 64 5f 6f 72 snose = load_or
0da0: 5f 6e 65 77 28 29 0a 20 20 20 20 23 47 65 74 20 _new(). #Get
0db0: 64 65 74 61 69 6c 73 20 61 62 6f 75 74 20 63 75 details about cu
0dc0: 72 72 65 6e 74 20 53 69 6d 70 6c 65 6e 6f 74 65 rrent Simplenote
0dd0: 20 66 69 6c 65 0a 20 20 20 20 72 65 6d 6f 74 65 file. remote
0de0: 20 3d 20 73 6e 72 65 6d 6f 74 65 28 73 6e 63 6c = snremote(sncl
0df0: 69 65 6e 74 2c 20 6b 65 79 29 0a 20 20 20 20 69 ient, key). i
0e00: 66 20 72 65 6d 6f 74 65 3a 0a 20 20 20 20 20 20 f remote:.
0e10: 20 20 23 41 64 64 20 6d 61 70 70 69 6e 67 0a 20 #Add mapping.
0e20: 20 20 20 20 20 20 20 73 6e 6f 73 65 5b 66 69 6c snose[fil
0e30: 65 6e 61 6d 65 5d 20 3d 20 73 6e 6f 62 6a 65 63 ename] = snobjec
0e40: 74 28 72 65 6d 6f 74 65 5b 30 5d 2c 20 66 69 6c t(remote[0], fil
0e50: 65 6e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 77 ename). w
0e60: 72 69 74 65 5f 69 6e 64 65 78 28 73 6e 6f 73 65 rite_index(snose
0e70: 29 0a 0a 0a 64 65 66 20 73 6e 65 65 7a 65 28 73 )...def sneeze(s
0e80: 6e 63 6c 69 65 6e 74 2c 20 6b 65 79 2c 20 66 69 nclient, key, fi
0e90: 6c 65 6e 61 6d 65 29 3a 0a 20 20 20 20 23 70 6c lename):. #pl
0ea0: 61 63 65 20 61 6e 20 65 78 69 73 74 69 6e 67 20 ace an existing
0eb0: 6e 6f 74 65 20 69 6e 20 63 75 72 72 65 6e 74 20 note in current
0ec0: 64 69 72 65 63 74 6f 72 79 0a 20 20 20 20 73 6e directory. sn
0ed0: 6f 73 65 20 3d 20 6c 6f 61 64 5f 6f 72 5f 6e 65 ose = load_or_ne
0ee0: 77 28 29 0a 20 20 20 20 23 47 65 74 20 72 65 6d w(). #Get rem
0ef0: 6f 74 65 20 6e 6f 74 65 0a 20 20 20 20 72 65 6d ote note. rem
0f00: 6f 74 65 20 3d 20 73 6e 72 65 6d 6f 74 65 28 73 ote = snremote(s
0f10: 6e 63 6c 69 65 6e 74 2c 20 6b 65 79 29 0a 20 20 nclient, key).
0f20: 20 20 69 66 20 72 65 6d 6f 74 65 3a 0a 20 20 20 if remote:.
0f30: 20 20 20 20 20 23 57 72 69 74 65 20 66 69 6c 65 #Write file
0f40: 0a 20 20 20 20 20 20 20 20 23 49 66 20 6e 6f 20 . #If no
0f50: 66 69 6c 65 6e 61 6d 65 20 73 75 70 70 6c 69 65 filename supplie
0f60: 64 20 74 72 79 20 74 6f 20 66 69 67 75 72 65 20 d try to figure
0f70: 6f 75 74 20 66 72 6f 6d 20 66 69 72 73 74 20 74 out from first t
0f80: 68 72 65 65 20 6c 69 6e 65 73 20 6f 66 20 66 69 hree lines of fi
0f90: 6c 65 20 69 74 73 65 6c 66 0a 20 20 20 20 20 20 le itself.
0fa0: 20 20 69 66 20 66 69 6c 65 6e 61 6d 65 20 69 73 if filename is
0fb0: 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 None:.
0fc0: 20 20 20 66 69 72 73 74 6c 69 6e 65 73 20 3d 20 firstlines =
0fd0: 72 65 6d 6f 74 65 5b 30 5d 5b 27 63 6f 6e 74 65 remote[0]['conte
0fe0: 6e 74 27 5d 2e 73 70 6c 69 74 6c 69 6e 65 73 28 nt'].splitlines(
0ff0: 29 5b 3a 33 5d 0a 20 20 20 20 20 20 20 20 20 20 )[:3].
1000: 20 20 66 6f 72 20 6c 69 6e 65 20 69 6e 20 66 69 for line in fi
1010: 72 73 74 6c 69 6e 65 73 3a 0a 20 20 20 20 20 20 rstlines:.
1020: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 try:.
1030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1040: 20 20 20 66 69 6c 65 6e 61 6d 65 20 3d 20 72 65 filename = re
1050: 2e 73 65 61 72 63 68 28 72 27 66 69 6c 65 3a 28 .search(r'file:(
1060: 5c 53 2b 29 27 2c 20 6c 69 6e 65 29 2e 67 72 6f \S+)', line).gro
1070: 75 70 28 31 29 0a 20 20 20 20 20 20 20 20 20 20 up(1).
1080: 20 20 20 20 20 20 65 78 63 65 70 74 20 49 6e 64 except Ind
1090: 65 78 45 72 72 6f 72 3a 0a 20 20 20 20 20 20 20 exError:.
10a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73 pas
10b0: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 s.
10c0: 20 20 65 78 63 65 70 74 20 41 74 74 72 69 62 75 except Attribu
10d0: 74 65 45 72 72 6f 72 3a 0a 20 20 20 20 20 20 20 teError:.
10e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73 pas
10f0: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 s. if
1100: 20 66 69 6c 65 6e 61 6d 65 20 69 73 20 4e 6f 6e filename is Non
1110: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 e:.
1120: 20 20 20 70 72 69 6e 74 28 22 46 61 69 6c 65 64 print("Failed
1130: 20 74 6f 20 69 64 65 6e 74 69 66 79 20 66 69 6c to identify fil
1140: 65 6e 61 6d 65 20 77 69 74 68 69 6e 20 6e 6f 74 ename within not
1150: 65 2c 20 70 6c 65 61 73 65 20 70 72 6f 76 69 64 e, please provid
1160: 65 20 6f 6e 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e e on command lin
1170: 65 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 e").
1180: 20 20 20 20 73 79 73 2e 65 78 69 74 28 29 0a 20 sys.exit().
1190: 20 20 20 20 20 20 20 66 69 6c 65 6e 61 6d 65 20 filename
11a0: 3d 20 6f 73 2e 70 61 74 68 2e 65 78 70 61 6e 64 = os.path.expand
11b0: 75 73 65 72 28 66 69 6c 65 6e 61 6d 65 29 0a 20 user(filename).
11c0: 20 20 20 20 20 20 20 6f 6b 20 3d 20 73 6e 77 72 ok = snwr
11d0: 69 74 65 28 66 69 6c 65 6e 61 6d 65 2c 20 72 65 ite(filename, re
11e0: 6d 6f 74 65 29 0a 20 20 20 20 20 20 20 20 69 66 mote). if
11f0: 20 6f 6b 3a 0a 20 20 20 20 20 20 20 20 20 20 20 ok:.
1200: 20 23 55 70 64 61 74 65 20 69 6e 64 65 78 0a 20 #Update index.
1210: 20 20 20 20 20 20 20 20 20 20 20 73 6e 6f 73 65 snose
1220: 5b 66 69 6c 65 6e 61 6d 65 5d 20 3d 20 73 6e 6f [filename] = sno
1230: 62 6a 65 63 74 28 72 65 6d 6f 74 65 5b 30 5d 2c bject(remote[0],
1240: 20 66 69 6c 65 6e 61 6d 65 29 0a 20 20 20 20 20 filename).
1250: 20 20 20 20 20 20 20 77 72 69 74 65 5f 69 6e 64 write_ind
1260: 65 78 28 73 6e 6f 73 65 2c 20 22 42 75 74 20 6e ex(snose, "But n
1270: 6f 74 65 20 77 61 73 20 63 72 65 61 74 65 64 20 ote was created
1280: 6c 6f 63 61 6c 6c 79 2e 20 54 72 79 20 73 6e 69 locally. Try sni
1290: 66 66 69 6e 67 20 74 68 65 20 66 69 6c 65 20 74 ffing the file t
12a0: 6f 20 61 64 64 20 69 74 20 74 6f 20 74 68 65 20 o add it to the
12b0: 69 6e 64 65 78 2e 22 29 0a 0a 0a 64 65 66 20 62 index.")...def b
12c0: 6c 6f 77 28 73 6e 63 6c 69 65 6e 74 2c 20 6b 65 low(snclient, ke
12d0: 79 29 3a 0a 20 20 20 20 23 57 69 74 68 20 67 69 y):. #With gi
12e0: 76 65 6e 20 6b 65 79 20 66 72 6f 6d 20 2e 73 6e ven key from .sn
12f0: 6f 73 65 20 66 69 6c 65 2c 20 72 6f 6c 6c 20 62 ose file, roll b
1300: 61 63 6b 20 74 6f 20 74 68 65 20 70 72 65 76 69 ack to the previ
1310: 6f 75 73 20 76 65 72 73 69 6f 6e 0a 0a 20 20 20 ous version..
1320: 20 23 31 29 20 43 68 65 63 6b 20 65 78 69 73 74 #1) Check exist
1330: 73 20 69 6e 20 2e 73 6e 6f 73 65 20 69 6e 64 65 s in .snose inde
1340: 78 0a 20 20 20 20 23 32 29 20 47 65 74 20 70 72 x. #2) Get pr
1350: 65 76 69 6f 75 73 20 76 65 72 73 69 6f 6e 20 6f evious version o
1360: 66 20 72 65 6d 6f 74 65 0a 20 20 20 20 23 33 29 f remote. #3)
1370: 20 57 72 69 74 65 20 69 74 20 6f 75 74 20 6c 6f Write it out lo
1380: 63 61 6c 6c 79 0a 20 20 20 20 23 34 29 20 55 73 cally. #4) Us
1390: 65 20 74 68 61 74 20 74 6f 20 75 70 64 61 74 65 e that to update
13a0: 20 72 65 6d 6f 74 65 0a 20 20 20 20 23 35 29 20 remote. #5)
13b0: 55 70 64 61 74 65 20 69 6e 64 65 78 20 66 69 6c Update index fil
13c0: 65 20 77 69 74 68 20 72 65 73 75 6c 74 73 0a 0a e with results..
13d0: 20 20 20 20 23 31 29 20 43 68 65 63 6b 20 65 78 #1) Check ex
13e0: 69 73 74 73 20 69 6e 20 2e 73 6e 6f 73 65 20 69 ists in .snose i
13f0: 6e 64 65 78 0a 20 20 20 20 74 72 79 3a 0a 20 20 ndex. try:.
1400: 20 20 20 20 20 20 73 6e 6f 73 65 20 3d 20 6c 6f snose = lo
1410: 61 64 5f 6f 72 5f 6e 65 77 28 29 0a 20 20 20 20 ad_or_new().
1420: 20 20 20 20 23 4e 65 65 64 20 74 6f 20 67 65 74 #Need to get
1430: 20 66 69 6c 65 6e 61 6d 65 20 6f 66 20 6e 6f 74 filename of not
1440: 65 2c 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 2c e, loop through,
1450: 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 68 6f performance sho
1460: 75 6c 64 20 62 65 20 66 69 6e 65 20 61 73 20 2e uld be fine as .
1470: 73 6e 6f 73 65 20 6c 69 6b 65 6c 79 20 74 6f 20 snose likely to
1480: 62 65 20 73 6d 61 6c 6c 0a 20 20 20 20 20 20 20 be small.
1490: 20 73 69 74 65 6d 73 20 3d 20 73 6e 69 74 65 6d sitems = snitem
14a0: 73 28 73 6e 6f 73 65 29 0a 20 20 20 20 20 20 20 s(snose).
14b0: 20 66 69 6c 65 6e 61 6d 65 20 3d 20 5b 6e 61 6d filename = [nam
14c0: 65 20 66 6f 72 20 6e 61 6d 65 2c 20 6c 6f 63 61 e for name, loca
14d0: 6c 20 69 6e 20 73 69 74 65 6d 73 20 69 66 20 6c l in sitems if l
14e0: 6f 63 61 6c 5b 27 6b 65 79 27 5d 20 3d 3d 20 6b ocal['key'] == k
14f0: 65 79 5d 5b 30 5d 0a 0a 20 20 20 20 20 20 20 20 ey][0]..
1500: 70 72 69 6e 74 28 22 41 74 74 65 6d 70 74 69 6e print("Attemptin
1510: 67 20 74 6f 20 72 6f 6c 6c 62 61 63 6b 20 66 69 g to rollback fi
1520: 6c 65 20 25 73 22 20 25 20 66 69 6c 65 6e 61 6d le %s" % filenam
1530: 65 29 0a 20 20 20 20 65 78 63 65 70 74 20 49 6e e). except In
1540: 64 65 78 45 72 72 6f 72 20 61 73 20 65 3a 0a 20 dexError as e:.
1550: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 4e 6f print("No
1560: 74 65 20 64 6f 65 73 6e 27 74 20 65 78 69 73 74 te doesn't exist
1570: 20 69 6e 20 6c 6f 63 61 6c 20 2e 73 6e 6f 73 65 in local .snose
1580: 20 69 6e 64 65 78 22 29 0a 20 20 20 20 65 6c 73 index"). els
1590: 65 3a 0a 20 20 20 20 20 20 20 20 23 32 29 20 47 e:. #2) G
15a0: 65 74 20 70 72 65 76 69 6f 75 73 20 76 65 72 73 et previous vers
15b0: 69 6f 6e 20 6f 66 20 72 65 6d 6f 74 65 0a 20 20 ion of remote.
15c0: 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 try:.
15d0: 20 20 20 20 20 20 20 23 66 65 74 63 68 20 6f 6e #fetch on
15e0: 63 65 20 74 6f 20 6b 6e 6f 77 20 76 65 72 73 69 ce to know versi
15f0: 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 on. r
1600: 65 6d 6f 74 65 20 3d 20 73 6e 63 6c 69 65 6e 74 emote = snclient
1610: 2e 67 65 74 5f 6e 6f 74 65 28 6b 65 79 29 0a 20 .get_note(key).
1620: 20 20 20 20 20 20 20 20 20 20 20 72 6f 6c 6c 62 rollb
1630: 61 63 6b 20 3d 20 73 6e 63 6c 69 65 6e 74 2e 67 ack = snclient.g
1640: 65 74 5f 6e 6f 74 65 28 6b 65 79 2c 20 72 65 6d et_note(key, rem
1650: 6f 74 65 5b 30 5d 5b 27 76 65 72 73 69 6f 6e 27 ote[0]['version'
1660: 5d 2d 31 29 0a 20 20 20 20 20 20 20 20 65 78 63 ]-1). exc
1670: 65 70 74 20 49 4f 45 72 72 6f 72 20 61 73 20 65 ept IOError as e
1680: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 :. pr
1690: 69 6e 74 28 22 46 61 69 6c 65 64 20 74 6f 20 66 int("Failed to f
16a0: 65 74 63 68 20 70 72 65 76 69 6f 75 73 20 76 65 etch previous ve
16b0: 72 73 69 6f 6e 22 29 0a 20 20 20 20 20 20 20 20 rsion").
16c0: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 else:.
16d0: 20 20 6f 6b 20 3d 20 73 6e 77 72 69 74 65 28 66 ok = snwrite(f
16e0: 69 6c 65 6e 61 6d 65 2c 20 72 6f 6c 6c 62 61 63 ilename, rollbac
16f0: 6b 2c 20 6d 73 67 3d 22 46 61 69 6c 65 64 20 74 k, msg="Failed t
1700: 6f 20 72 6f 6c 6c 62 61 63 6b 20 6c 6f 63 61 6c o rollback local
1710: 20 63 6f 70 79 20 6f 66 20 74 68 61 74 20 6e 6f copy of that no
1720: 74 65 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 te").
1730: 20 69 66 20 6f 6b 3a 0a 20 20 20 20 20 20 20 20 if ok:.
1740: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 52 print("R
1750: 6f 6c 6c 65 64 20 62 61 63 6b 20 6c 6f 63 61 6c olled back local
1760: 20 63 6f 70 79 20 6f 66 20 74 68 61 74 20 6e 6f copy of that no
1770: 74 65 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 te").
1780: 20 20 20 20 20 23 53 69 6e 63 65 20 72 6f 6c 6c #Since roll
1790: 62 61 63 6b 20 64 6f 65 73 6e 27 74 20 69 6e 63 back doesn't inc
17a0: 6c 75 64 65 20 66 75 6c 6c 20 6d 65 74 61 20 64 lude full meta d
17b0: 61 74 61 2c 20 75 70 64 61 74 65 20 72 65 6d 6f ata, update remo
17c0: 74 65 20 61 63 63 6f 72 64 69 6e 67 6c 79 0a 20 te accordingly.
17d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 t
17e0: 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 ry:.
17f0: 20 20 20 20 20 20 20 20 64 65 6c 20 72 65 6d 6f del remo
1800: 74 65 5b 30 5d 5b 27 76 65 72 73 69 6f 6e 27 5d te[0]['version']
1810: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
1820: 20 65 78 63 65 70 74 20 4b 65 79 45 72 72 6f 72 except KeyError
1830: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 :.
1840: 20 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 pass.
1850: 20 20 20 20 20 20 20 20 20 20 20 66 69 6e 61 6c final
1860: 6c 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 ly:.
1870: 20 20 20 20 20 20 20 20 23 53 65 74 20 6d 6f 64 #Set mod
1880: 69 66 69 65 64 20 64 61 74 65 0a 20 20 20 20 20 ified date.
1890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 s
18a0: 79 73 6d 6f 64 69 66 79 64 61 74 65 20 3d 20 66 ysmodifydate = f
18b0: 6c 6f 61 74 28 6f 73 2e 70 61 74 68 2e 67 65 74 loat(os.path.get
18c0: 6d 74 69 6d 65 28 66 69 6c 65 6e 61 6d 65 29 29 mtime(filename))
18d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
18e0: 20 20 20 20 20 72 65 6d 6f 74 65 5b 30 5d 5b 27 remote[0]['
18f0: 6d 6f 64 69 66 79 64 61 74 65 27 5d 20 3d 20 73 modifydate'] = s
1900: 79 73 6d 6f 64 69 66 79 64 61 74 65 0a 20 20 20 ysmodifydate.
1910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1920: 20 72 65 6d 6f 74 65 5b 30 5d 5b 27 63 6f 6e 74 remote[0]['cont
1930: 65 6e 74 27 5d 20 3d 20 72 6f 6c 6c 62 61 63 6b ent'] = rollback
1940: 5b 30 5d 5b 27 63 6f 6e 74 65 6e 74 27 5d 0a 20 [0]['content'].
1950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1960: 20 20 20 23 34 29 20 55 73 65 20 74 68 61 74 20 #4) Use that
1970: 74 6f 20 75 70 64 61 74 65 20 72 65 6d 6f 74 65 to update remote
1980: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
1990: 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 try:.
19a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
19b0: 20 20 72 65 74 75 72 6e 65 64 20 3d 20 73 6e 63 returned = snc
19c0: 6c 69 65 6e 74 2e 75 70 64 61 74 65 5f 6e 6f 74 lient.update_not
19d0: 65 28 72 65 6d 6f 74 65 5b 30 5d 29 0a 20 20 20 e(remote[0]).
19e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
19f0: 20 20 20 20 20 70 72 69 6e 74 28 22 52 6f 6c 6c print("Roll
1a00: 65 64 20 62 61 63 6b 20 72 65 6d 6f 74 65 20 76 ed back remote v
1a10: 65 72 73 69 6f 6e 22 29 0a 20 20 20 20 20 20 20 ersion").
1a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 63 exc
1a30: 65 70 74 20 49 4f 45 72 72 6f 72 20 61 73 20 65 ept IOError as e
1a40: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 :.
1a50: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 print(
1a60: 22 46 61 69 6c 65 64 20 74 6f 20 72 6f 6c 6c 20 "Failed to roll
1a70: 62 61 63 6b 20 72 65 6d 6f 74 65 20 76 65 72 73 back remote vers
1a80: 69 6f 6e 22 29 0a 20 20 20 20 20 20 20 20 20 20 ion").
1a90: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a else:.
1aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1ab0: 20 20 20 20 20 20 20 20 23 47 65 74 20 72 65 74 #Get ret
1ac0: 75 72 6e 65 64 20 6d 65 74 61 64 61 74 61 0a 20 urned metadata.
1ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1ae0: 20 20 20 20 20 20 20 73 6e 6f 73 65 5b 66 69 6c snose[fil
1af0: 65 6e 61 6d 65 5d 5b 27 76 65 72 73 69 6f 6e 27 ename]['version'
1b00: 5d 20 3d 20 72 65 74 75 72 6e 65 64 5b 30 5d 5b ] = returned[0][
1b10: 27 76 65 72 73 69 6f 6e 27 5d 0a 20 20 20 20 20 'version'].
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1b30: 20 20 20 73 6e 6f 73 65 5b 66 69 6c 65 6e 61 6d snose[filenam
1b40: 65 5d 5b 27 6d 6f 64 69 66 79 64 61 74 65 27 5d e]['modifydate']
1b50: 20 3d 20 73 79 73 6d 6f 64 69 66 79 64 61 74 65 = sysmodifydate
1b60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
1b70: 20 20 20 20 20 20 20 20 20 77 72 69 74 65 5f 69 write_i
1b80: 6e 64 65 78 28 73 6e 6f 73 65 2c 20 22 54 72 79 ndex(snose, "Try
1b90: 20 72 75 6e 6e 69 6e 67 20 61 20 73 79 6e 63 20 running a sync
1ba0: 74 6f 20 67 65 74 20 69 6e 64 65 78 20 63 6f 72 to get index cor
1bb0: 72 65 63 74 65 64 2e 22 29 0a 0a 0a 64 65 66 20 rected.")...def
1bc0: 73 6e 6f 74 28 73 6e 63 6c 69 65 6e 74 29 3a 0a snot(snclient):.
1bd0: 20 20 20 20 23 4c 69 73 74 20 73 69 6d 70 6c 65 #List simple
1be0: 6e 6f 74 65 20 6e 6f 74 65 73 20 74 61 67 67 65 note notes tagge
1bf0: 64 20 77 69 74 68 20 22 73 6e 6f 73 65 22 0a 20 d with "snose".
1c00: 20 20 20 6e 6f 74 65 6c 69 73 74 20 3d 20 73 6e notelist = sn
1c10: 63 6c 69 65 6e 74 2e 67 65 74 5f 6e 6f 74 65 5f client.get_note_
1c20: 6c 69 73 74 28 29 0a 20 20 20 20 23 54 68 61 74 list(). #That
1c30: 20 67 65 74 73 20 6c 69 73 74 20 6f 66 20 6b 65 gets list of ke
1c40: 79 73 2e 20 54 68 65 6e 20 6e 65 65 64 20 74 6f ys. Then need to
1c50: 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 iterate through
1c60: 20 61 6e 64 20 67 65 74 20 66 69 72 73 74 20 6c and get first l
1c70: 69 6e 65 20 6f 66 20 74 65 78 74 2e 0a 20 20 20 ine of text..
1c80: 20 23 54 68 69 73 20 69 73 20 67 6f 69 6e 67 20 #This is going
1c90: 74 6f 20 62 65 20 73 6c 6f 77 2e 0a 20 20 20 20 to be slow..
1ca0: 70 72 69 6e 74 28 22 4b 65 79 3a 20 20 20 20 20 print("Key:
1cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1cc0: 20 20 20 20 20 20 20 20 20 20 5c 74 4e 6f 74 65 \tNote
1cd0: 22 29 0a 20 20 20 20 66 6f 72 20 6e 6f 74 65 20 "). for note
1ce0: 69 6e 20 6e 6f 74 65 6c 69 73 74 5b 30 5d 3a 0a in notelist[0]:.
1cf0: 20 20 20 20 20 20 20 20 69 66 20 28 22 73 6e 6f if ("sno
1d00: 73 65 22 20 69 6e 20 6e 6f 74 65 5b 27 74 61 67 se" in note['tag
1d10: 73 27 5d 29 20 26 20 28 69 6e 74 28 6e 6f 74 65 s']) & (int(note
1d20: 5b 27 64 65 6c 65 74 65 64 27 5d 29 20 21 3d 20 ['deleted']) !=
1d30: 31 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 1):.
1d40: 23 67 65 74 20 6e 6f 74 65 20 69 74 73 65 6c 66 #get note itself
1d50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 6d . rem
1d60: 6f 74 65 20 3d 20 73 6e 63 6c 69 65 6e 74 2e 67 ote = snclient.g
1d70: 65 74 5f 6e 6f 74 65 28 6e 6f 74 65 5b 27 6b 65 et_note(note['ke
1d80: 79 27 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 y']).
1d90: 20 70 72 69 6e 74 28 72 65 6d 6f 74 65 5b 30 5d print(remote[0]
1da0: 5b 27 6b 65 79 27 5d 20 20 2b 20 22 20 5c 74 22 ['key'] + " \t"
1db0: 20 2b 20 72 65 6d 6f 74 65 5b 30 5d 5b 27 63 6f + remote[0]['co
1dc0: 6e 74 65 6e 74 27 5d 2e 73 70 6c 69 74 6c 69 6e ntent'].splitlin
1dd0: 65 73 28 29 5b 30 5d 29 0a 0a 0a 64 65 66 20 73 es()[0])...def s
1de0: 79 6e 63 28 73 6e 63 6c 69 65 6e 74 2c 20 64 72 ync(snclient, dr
1df0: 79 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 23 4e y=False):. #N
1e00: 65 65 64 20 74 6f 20 72 65 61 64 20 69 6e 20 6d eed to read in m
1e10: 61 70 70 69 6e 67 73 20 61 6e 64 20 73 79 6e 63 appings and sync
1e20: 20 74 68 6f 73 65 20 6e 6f 74 65 73 2e 0a 20 20 those notes..
1e30: 20 20 64 72 79 72 65 6d 6f 74 65 73 20 3d 20 5b dryremotes = [
1e40: 5d 0a 20 20 20 20 73 6e 6f 73 65 20 3d 20 6c 6f ]. snose = lo
1e50: 61 64 5f 6f 72 5f 6e 65 77 28 29 0a 20 20 20 20 ad_or_new().
1e60: 23 4e 65 65 64 20 74 6f 20 69 74 65 72 61 74 65 #Need to iterate
1e70: 20 74 68 72 6f 75 67 68 20 6c 69 73 74 2e 0a 20 through list..
1e80: 20 20 20 73 69 74 65 6d 73 20 3d 20 73 6e 69 74 sitems = snit
1e90: 65 6d 73 28 73 6e 6f 73 65 29 0a 20 20 20 20 66 ems(snose). f
1ea0: 6f 72 20 6e 61 6d 65 2c 20 6c 6f 63 61 6c 20 69 or name, local i
1eb0: 6e 20 73 69 74 65 6d 73 3a 0a 20 20 20 20 20 20 n sitems:.
1ec0: 20 20 23 46 69 72 73 74 20 6f 66 20 61 6c 6c 20 #First of all
1ed0: 63 68 65 63 6b 20 66 6f 72 20 6c 6f 63 61 6c 20 check for local
1ee0: 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73 0a 20 20 modifications.
1ef0: 20 20 20 20 20 20 73 79 73 6d 6f 64 69 66 79 64 sysmodifyd
1f00: 61 74 65 20 3d 20 66 6c 6f 61 74 28 6f 73 2e 70 ate = float(os.p
1f10: 61 74 68 2e 67 65 74 6d 74 69 6d 65 28 6e 61 6d ath.getmtime(nam
1f20: 65 29 29 0a 20 20 20 20 20 20 20 20 69 66 20 73 e)). if s
1f30: 79 73 6d 6f 64 69 66 79 64 61 74 65 20 3e 20 66 ysmodifydate > f
1f40: 6c 6f 61 74 28 6c 6f 63 61 6c 5b 27 6d 6f 64 69 loat(local['modi
1f50: 66 79 64 61 74 65 27 5d 29 3a 20 23 65 6e 73 75 fydate']): #ensu
1f60: 72 65 20 66 75 6c 6c 20 74 69 6d 65 73 74 61 6d re full timestam
1f70: 70 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 p. if
1f80: 20 6e 6f 74 20 64 72 79 3a 0a 20 20 20 20 20 20 not dry:.
1f90: 20 20 20 20 20 20 23 55 70 64 61 74 65 20 72 65 #Update re
1fa0: 6d 6f 74 65 0a 20 20 20 20 20 20 20 20 20 20 20 mote.
1fb0: 20 20 20 20 20 63 6f 6e 74 65 6e 74 20 3d 20 73 content = s
1fc0: 6e 72 65 61 64 28 6e 61 6d 65 2c 20 22 53 6b 69 nread(name, "Ski
1fd0: 70 70 69 6e 67 20 73 79 6e 63 68 72 6f 6e 69 73 pping synchronis
1fe0: 61 74 69 6f 6e 20 66 6f 72 20 74 68 69 73 20 6e ation for this n
1ff0: 6f 74 65 22 29 0a 20 20 20 20 20 20 20 20 20 20 ote").
2000: 20 20 20 20 20 20 69 66 20 63 6f 6e 74 65 6e 74 if content
2010: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 :.
2020: 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 try:.
2030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2040: 20 20 20 72 65 74 75 72 6e 65 64 20 3d 20 73 6e returned = sn
2050: 63 6c 69 65 6e 74 2e 75 70 64 61 74 65 5f 6e 6f client.update_no
2060: 74 65 28 73 6e 6f 62 6a 65 63 74 28 6c 6f 63 61 te(snobject(loca
2070: 6c 2c 20 6e 61 6d 65 2c 20 74 61 67 73 3d 5b 27 l, name, tags=['
2080: 73 6e 6f 73 65 27 5d 2c 20 63 6f 6e 74 65 6e 74 snose'], content
2090: 3d 63 6f 6e 74 65 6e 74 29 29 0a 20 20 20 20 20 =content)).
20a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20b0: 20 20 20 70 72 69 6e 74 28 22 55 70 64 61 74 65 print("Update
20c0: 64 20 72 65 6d 6f 74 65 20 76 65 72 73 69 6f 6e d remote version
20d0: 20 6f 66 20 25 73 22 20 25 20 6e 61 6d 65 29 0a of %s" % name).
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20f0: 20 20 20 20 65 78 63 65 70 74 20 49 4f 45 72 72 except IOErr
2100: 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 20 20 20 or as e:.
2110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2120: 20 70 72 69 6e 74 28 22 46 61 69 6c 65 64 20 74 print("Failed t
2130: 6f 20 75 70 64 61 74 65 20 72 65 6d 6f 74 65 20 o update remote
2140: 76 65 72 69 73 6f 6e 20 6f 66 20 6c 6f 63 61 6c verison of local
2150: 20 6e 6f 74 65 20 25 73 22 20 25 20 6e 61 6d 65 note %s" % name
2160: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ).
2170: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 else:.
2180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2190: 20 20 20 20 23 47 65 74 20 72 65 74 75 72 6e 65 #Get returne
21a0: 64 20 6d 65 74 61 64 61 74 61 0a 20 20 20 20 20 d metadata.
21b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
21c0: 20 20 20 73 6e 6f 73 65 5b 6e 61 6d 65 5d 5b 27 snose[name]['
21d0: 76 65 72 73 69 6f 6e 27 5d 20 3d 20 72 65 74 75 version'] = retu
21e0: 72 6e 65 64 5b 30 5d 5b 27 76 65 72 73 69 6f 6e rned[0]['version
21f0: 27 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 '].
2200: 20 20 20 20 20 20 20 20 20 20 20 73 6e 6f 73 65 snose
2210: 5b 6e 61 6d 65 5d 5b 27 6d 6f 64 69 66 79 64 61 [name]['modifyda
2220: 74 65 27 5d 20 3d 20 73 79 73 6d 6f 64 69 66 79 te'] = sysmodify
2230: 64 61 74 65 20 23 55 73 65 20 6c 6f 63 61 6c 20 date #Use local
2240: 76 61 6c 75 65 20 74 6f 20 61 76 6f 69 64 20 64 value to avoid d
2250: 69 66 66 65 72 65 6e 63 65 73 20 69 6e 20 61 63 ifferences in ac
2260: 63 75 72 61 63 79 20 28 64 65 63 69 6d 61 6c 20 curacy (decimal
2270: 70 6c 61 63 65 73 2e 20 65 74 63 29 20 62 65 74 places. etc) bet
2280: 77 65 65 6e 20 6c 6f 63 61 6c 20 61 6e 64 20 72 ween local and r
2290: 65 6d 6f 74 65 20 74 69 6d 65 73 74 61 6d 70 73 emote timestamps
22a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
22b0: 20 20 20 20 20 20 20 20 20 23 55 70 64 61 74 65 #Update
22c0: 20 6c 6f 63 61 6c 20 66 69 6c 65 20 69 66 20 6d local file if m
22d0: 65 72 67 65 64 20 63 6f 6e 74 65 6e 74 0a 20 20 erged content.
22e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
22f0: 20 20 20 20 20 20 69 66 20 27 63 6f 6e 74 65 6e if 'conten
2300: 74 27 20 69 6e 20 72 65 74 75 72 6e 65 64 5b 30 t' in returned[0
2310: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 ]:.
2320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f o
2330: 6b 20 3d 20 73 6e 77 72 69 74 65 28 6e 61 6d 65 k = snwrite(name
2340: 2c 20 72 65 74 75 72 6e 65 64 2c 20 6d 73 67 3d , returned, msg=
2350: 22 46 61 69 6c 65 64 20 74 6f 20 6d 65 72 67 65 "Failed to merge
2360: 20 63 6f 6e 74 65 6e 74 20 6c 6f 63 61 6c 6c 79 content locally
2370: 20 66 6f 72 20 25 73 2c 20 74 68 65 72 65 66 6f for %s, therefo
2380: 72 65 20 73 6b 69 70 70 69 6e 67 20 75 70 64 61 re skipping upda
2390: 74 69 6e 67 20 74 68 65 20 69 6e 64 65 78 20 66 ting the index f
23a0: 6f 72 20 74 68 69 73 20 6e 6f 74 65 22 20 25 20 or this note" %
23b0: 6e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 20 20 name).
23c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
23d0: 20 20 69 66 20 6f 6b 3a 0a 20 20 20 20 20 20 20 if ok:.
23e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
23f0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 print("
2400: 4d 65 72 67 65 64 20 6c 6f 63 61 6c 20 63 6f 6e Merged local con
2410: 74 65 6e 74 20 66 6f 72 20 25 73 22 20 25 20 6e tent for %s" % n
2420: 61 6d 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 ame).
2430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2440: 20 20 20 20 20 23 4f 76 65 72 72 69 64 65 20 74 #Override t
2450: 68 65 20 72 65 74 75 72 6e 65 64 20 76 61 6c 75 he returned valu
2460: 65 3f 20 41 73 20 6f 74 68 65 72 77 69 73 65 20 e? As otherwise
2470: 6e 65 78 74 20 73 79 6e 63 20 77 69 6c 6c 20 69 next sync will i
2480: 6d 6d 65 64 69 61 74 65 6c 79 20 75 70 64 61 74 mmediately updat
2490: 65 20 74 68 65 20 72 65 6d 6f 74 65 20 76 65 72 e the remote ver
24a0: 73 69 6f 6e 20 66 6f 72 20 6e 6f 20 72 65 61 73 sion for no reas
24b0: 6f 6e 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20 on..
24c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
24d0: 20 20 20 20 73 6e 6f 73 65 5b 6e 61 6d 65 5d 5b snose[name][
24e0: 27 6d 6f 64 69 66 79 64 61 74 65 27 5d 20 3d 20 'modifydate'] =
24f0: 6f 73 2e 70 61 74 68 2e 67 65 74 6d 74 69 6d 65 os.path.getmtime
2500: 28 6e 61 6d 65 29 20 0a 20 20 20 20 20 20 20 20 (name) .
2510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2520: 23 55 70 64 61 74 65 20 74 68 65 20 69 6e 64 65 #Update the inde
2530: 78 20 66 69 6c 65 0a 20 20 20 20 20 20 20 20 20 x file.
2540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 77 w
2550: 72 69 74 65 5f 69 6e 64 65 78 28 73 6e 6f 73 65 rite_index(snose
2560: 2c 20 22 42 75 74 20 72 65 6d 6f 74 65 20 61 6e , "But remote an
2570: 64 20 6c 6f 63 61 6c 20 63 6f 70 79 20 6f 66 20 d local copy of
2580: 74 68 65 20 66 69 6c 65 20 69 74 73 65 6c 66 20 the file itself
2590: 68 61 76 65 20 62 65 65 6e 20 75 70 64 61 74 65 have been update
25a0: 64 2e 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 d.").
25b0: 20 65 6c 69 66 20 64 72 79 3a 0a 20 20 20 20 20 elif dry:.
25c0: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 print
25d0: 28 22 55 70 64 61 74 65 64 20 72 65 6d 6f 74 65 ("Updated remote
25e0: 20 76 65 72 73 69 6f 6e 20 6f 66 20 25 73 22 20 version of %s"
25f0: 25 20 6e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 % name).
2600: 20 20 20 20 20 20 20 20 23 46 6f 72 20 64 72 79 #For dry
2610: 20 72 75 6e 2c 20 63 6f 6c 6c 65 63 74 20 6c 69 run, collect li
2620: 73 74 20 6f 66 20 22 75 70 64 61 74 65 64 20 72 st of "updated r
2630: 65 6d 6f 74 65 73 22 20 74 6f 20 69 67 6e 6f 72 emotes" to ignor
2640: 65 20 69 6e 20 6c 6f 63 61 6c 20 75 70 64 61 74 e in local updat
2650: 65 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 es.
2660: 20 20 20 64 72 79 72 65 6d 6f 74 65 73 2e 61 70 dryremotes.ap
2670: 70 65 6e 64 28 6e 61 6d 65 29 0a 20 20 20 20 20 pend(name).
2680: 20 20 20 23 46 65 74 63 68 20 64 65 74 61 69 6c #Fetch detail
2690: 73 20 66 72 6f 6d 20 53 69 6d 70 6c 65 6e 6f 74 s from Simplenot
26a0: 65 0a 20 20 20 20 20 20 20 20 72 65 6d 6f 74 65 e. remote
26b0: 20 3d 20 73 6e 72 65 6d 6f 74 65 28 73 6e 63 6c = snremote(sncl
26c0: 69 65 6e 74 2c 20 6c 6f 63 61 6c 5b 27 6b 65 79 ient, local['key
26d0: 27 5d 2c 20 22 53 6b 69 70 70 69 6e 67 20 73 79 '], "Skipping sy
26e0: 6e 63 68 72 6f 6e 69 73 61 74 69 6f 6e 20 66 6f nchronisation fo
26f0: 72 20 74 68 69 73 20 66 69 6c 65 22 29 0a 20 20 r this file").
2700: 20 20 20 20 20 20 69 66 20 72 65 6d 6f 74 65 3a if remote:
2710: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 . if
2720: 72 65 6d 6f 74 65 5b 30 5d 5b 27 76 65 72 73 69 remote[0]['versi
2730: 6f 6e 27 5d 20 3e 20 6c 6f 63 61 6c 5b 27 76 65 on'] > local['ve
2740: 72 73 69 6f 6e 27 5d 3a 0a 20 20 20 20 20 20 20 rsion']:.
2750: 20 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 if not
2760: 64 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 dry:.
2770: 20 20 20 20 20 20 20 20 20 6f 6b 20 3d 20 73 6e ok = sn
2780: 77 72 69 74 65 28 6e 61 6d 65 2c 20 72 65 6d 6f write(name, remo
2790: 74 65 2c 20 6d 73 67 3d 22 46 61 69 6c 65 64 20 te, msg="Failed
27a0: 74 6f 20 75 70 64 61 74 65 20 6c 6f 63 61 6c 20 to update local
27b0: 6e 6f 74 65 20 25 73 20 77 69 74 68 20 72 65 6d note %s with rem
27c0: 6f 74 65 20 63 6f 6e 74 65 6e 74 2e 20 57 69 6c ote content. Wil
27d0: 6c 20 6e 6f 74 20 75 70 64 61 74 65 20 74 68 65 l not update the
27e0: 20 2e 73 6e 6f 73 65 20 69 6e 64 65 78 20 66 69 .snose index fi
27f0: 6c 65 20 66 6f 72 20 74 68 69 73 20 66 69 6c 65 le for this file
2800: 22 20 25 20 6e 61 6d 65 29 0a 20 20 20 20 20 20 " % name).
2810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 if
2820: 20 6f 6b 3a 0a 20 20 20 20 20 20 20 20 20 20 20 ok:.
2830: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 pri
2840: 6e 74 28 22 55 70 64 61 74 65 64 20 6c 6f 63 61 nt("Updated loca
2850: 6c 20 76 65 72 73 69 6f 6e 20 6f 66 20 25 73 22 l version of %s"
2860: 20 25 20 6e 61 6d 65 29 0a 20 20 20 20 20 20 20 % name).
2870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2880: 20 23 41 6c 73 6f 20 75 70 64 61 74 65 20 2e 73 #Also update .s
2890: 6e 6f 73 65 20 69 6e 64 65 78 0a 20 20 20 20 20 nose index.
28a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
28b0: 20 20 20 73 6e 6f 73 65 5b 6e 61 6d 65 5d 5b 27 snose[name]['
28c0: 76 65 72 73 69 6f 6e 27 5d 20 3d 20 72 65 6d 6f version'] = remo
28d0: 74 65 5b 30 5d 5b 27 76 65 72 73 69 6f 6e 27 5d te[0]['version']
28e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
28f0: 20 20 20 20 20 20 20 20 20 73 6e 6f 73 65 5b 6e snose[n
2900: 61 6d 65 5d 5b 27 6d 6f 64 69 66 79 64 61 74 65 ame]['modifydate
2910: 27 5d 20 3d 20 6f 73 2e 70 61 74 68 2e 67 65 74 '] = os.path.get
2920: 6d 74 69 6d 65 28 6e 61 6d 65 29 20 23 41 73 20 mtime(name) #As
2930: 69 66 20 73 65 74 20 72 65 6d 6f 74 65 20 6d 6f if set remote mo
2940: 64 69 66 79 20 64 61 74 65 2c 20 6c 6f 63 61 6c dify date, local
2950: 20 66 69 6c 65 20 77 69 6c 6c 20 69 6d 6d 65 64 file will immed
2960: 69 61 74 65 6c 79 20 61 70 70 65 61 72 20 27 6d iately appear 'm
2970: 6f 64 69 66 69 65 64 27 0a 20 20 20 20 20 20 20 odified'.
2980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2990: 20 77 72 69 74 65 5f 69 6e 64 65 78 28 73 6e 6f write_index(sno
29a0: 73 65 2c 20 22 42 75 74 20 6c 6f 63 61 6c 20 63 se, "But local c
29b0: 6f 70 79 20 6f 66 20 74 68 65 20 66 69 6c 65 20 opy of the file
29c0: 25 73 20 68 61 73 20 62 65 65 6e 20 75 70 64 61 %s has been upda
29d0: 74 65 64 20 77 69 74 68 20 72 65 6d 6f 74 65 20 ted with remote
29e0: 63 68 61 6e 67 65 73 22 20 25 20 6e 61 6d 65 29 changes" % name)
29f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
2a00: 20 65 6c 69 66 20 28 64 72 79 20 61 6e 64 20 28 elif (dry and (
2a10: 6e 6f 74 20 28 6e 61 6d 65 20 69 6e 20 64 72 79 not (name in dry
2a20: 72 65 6d 6f 74 65 73 29 29 29 3a 0a 20 20 20 20 remotes))):.
2a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2a40: 70 72 69 6e 74 28 22 55 70 64 61 74 65 64 20 6c print("Updated l
2a50: 6f 63 61 6c 20 76 65 72 73 69 6f 6e 20 6f 66 20 ocal version of
2a60: 25 73 22 20 25 20 6e 61 6d 65 29 0a 0a 64 65 66 %s" % name)..def
2a70: 20 6c 6f 61 64 5f 6f 72 5f 6e 65 77 28 29 3a 0a load_or_new():.
2a80: 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 try:.
2a90: 20 77 69 74 68 20 6f 70 65 6e 28 27 2e 73 6e 6f with open('.sno
2aa0: 73 65 27 2c 20 27 72 27 29 20 61 73 20 66 3a 0a se', 'r') as f:.
2ab0: 20 20 20 20 20 20 20 20 20 20 20 20 73 6e 6f 73 snos
2ac0: 65 20 3d 20 6a 73 6f 6e 2e 6c 6f 61 64 28 66 29 e = json.load(f)
2ad0: 0a 20 20 20 20 65 78 63 65 70 74 20 49 4f 45 72 . except IOEr
2ae0: 72 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 20 20 ror as e:.
2af0: 20 20 23 44 6f 65 73 6e 27 74 20 65 78 69 73 74 #Doesn't exist
2b00: 20 73 6f 20 63 72 65 61 74 65 20 6e 65 77 0a 20 so create new.
2b10: 20 20 20 20 20 20 20 73 6e 6f 73 65 20 3d 20 7b snose = {
2b20: 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 73 6e 6f }. return sno
2b30: 73 65 0a 0a 0a 64 65 66 20 77 72 69 74 65 5f 69 se...def write_i
2b40: 6e 64 65 78 28 73 6e 6f 73 65 2c 20 6d 73 67 3d ndex(snose, msg=
2b50: 4e 6f 6e 65 29 3a 0a 20 20 20 20 74 72 79 3a 0a None):. try:.
2b60: 20 20 20 20 20 20 20 20 77 69 74 68 20 6f 70 65 with ope
2b70: 6e 28 27 2e 73 6e 6f 73 65 27 2c 20 27 77 27 29 n('.snose', 'w')
2b80: 20 61 73 20 66 3a 0a 20 20 20 20 20 20 20 20 20 as f:.
2b90: 20 20 20 6a 73 6f 6e 2e 64 75 6d 70 28 73 6e 6f json.dump(sno
2ba0: 73 65 2c 20 66 2c 20 69 6e 64 65 6e 74 3d 32 29 se, f, indent=2)
2bb0: 0a 20 20 20 20 65 78 63 65 70 74 20 49 4f 45 72 . except IOEr
2bc0: 72 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 20 20 ror as e:.
2bd0: 20 20 70 72 69 6e 74 28 22 46 61 69 6c 65 64 20 print("Failed
2be0: 74 6f 20 75 70 64 61 74 65 20 69 6e 64 65 78 22 to update index"
2bf0: 29 0a 20 20 20 20 20 20 20 20 69 66 20 6d 73 67 ). if msg
2c00: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 :. pr
2c10: 69 6e 74 28 6d 73 67 29 0a 0a 0a 64 65 66 20 73 int(msg)...def s
2c20: 6e 6f 62 6a 65 63 74 28 72 65 74 75 72 6e 65 64 nobject(returned
2c30: 2c 20 66 69 6c 65 6e 61 6d 65 2c 20 74 61 67 73 , filename, tags
2c40: 3d 4e 6f 6e 65 2c 20 63 6f 6e 74 65 6e 74 3d 4e =None, content=N
2c50: 6f 6e 65 29 3a 0a 20 20 20 20 73 6e 6f 20 3d 20 one):. sno =
2c60: 7b 27 6b 65 79 27 3a 20 72 65 74 75 72 6e 65 64 {'key': returned
2c70: 5b 27 6b 65 79 27 5d 2c 20 27 76 65 72 73 69 6f ['key'], 'versio
2c80: 6e 27 3a 20 72 65 74 75 72 6e 65 64 5b 27 76 65 n': returned['ve
2c90: 72 73 69 6f 6e 27 5d 2c 20 27 6d 6f 64 69 66 79 rsion'], 'modify
2ca0: 64 61 74 65 27 3a 20 66 6c 6f 61 74 28 6f 73 2e date': float(os.
2cb0: 70 61 74 68 2e 67 65 74 6d 74 69 6d 65 28 66 69 path.getmtime(fi
2cc0: 6c 65 6e 61 6d 65 29 29 20 7d 0a 20 20 20 20 69 lename)) }. i
2cd0: 66 20 74 61 67 73 3a 0a 20 20 20 20 20 20 20 20 f tags:.
2ce0: 73 6e 6f 5b 27 74 61 67 73 27 5d 20 3d 20 74 61 sno['tags'] = ta
2cf0: 67 73 0a 20 20 20 20 69 66 20 63 6f 6e 74 65 6e gs. if conten
2d00: 74 3a 0a 20 20 20 20 20 20 20 20 73 6e 6f 5b 27 t:. sno['
2d10: 63 6f 6e 74 65 6e 74 27 5d 20 3d 20 63 6f 6e 74 content'] = cont
2d20: 65 6e 74 0a 20 20 20 20 72 65 74 75 72 6e 20 73 ent. return s
2d30: 6e 6f 0a 0a 0a 64 65 66 20 73 6e 69 74 65 6d 73 no...def snitems
2d40: 28 73 6e 6f 73 65 29 3a 0a 20 20 20 20 69 66 20 (snose):. if
2d50: 73 79 73 2e 76 65 72 73 69 6f 6e 5f 69 6e 66 6f sys.version_info
2d60: 20 3c 20 28 33 2c 20 30 29 3a 0a 20 20 20 20 20 < (3, 0):.
2d70: 20 20 20 73 69 74 65 6d 73 20 3d 20 73 6e 6f 73 sitems = snos
2d80: 65 2e 69 74 65 72 69 74 65 6d 73 28 29 0a 20 20 e.iteritems().
2d90: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 else:.
2da0: 73 69 74 65 6d 73 20 3d 20 73 6e 6f 73 65 2e 69 sitems = snose.i
2db0: 74 65 6d 73 28 29 0a 20 20 20 20 72 65 74 75 72 tems(). retur
2dc0: 6e 20 73 69 74 65 6d 73 0a 0a 0a 64 65 66 20 73 n sitems...def s
2dd0: 6e 77 72 69 74 65 28 6e 61 6d 65 2c 20 72 65 6d nwrite(name, rem
2de0: 6f 74 65 2c 20 6d 73 67 3d 4e 6f 6e 65 29 3a 0a ote, msg=None):.
2df0: 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 try:.
2e00: 20 69 66 20 73 79 73 2e 76 65 72 73 69 6f 6e 5f if sys.version_
2e10: 69 6e 66 6f 20 3c 20 28 33 2c 20 30 29 3a 0a 20 info < (3, 0):.
2e20: 20 20 20 20 20 20 20 20 20 20 20 77 69 74 68 20 with
2e30: 6f 70 65 6e 28 6e 61 6d 65 2c 20 27 77 27 29 20 open(name, 'w')
2e40: 61 73 20 66 3a 0a 20 20 20 20 20 20 20 20 20 20 as f:.
2e50: 20 20 20 20 20 20 66 2e 77 72 69 74 65 28 72 65 f.write(re
2e60: 6d 6f 74 65 5b 30 5d 5b 27 63 6f 6e 74 65 6e 74 mote[0]['content
2e70: 27 5d 2e 65 6e 63 6f 64 65 28 22 75 74 66 2d 38 '].encode("utf-8
2e80: 22 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 ")). else
2e90: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 69 :. wi
2ea0: 74 68 20 6f 70 65 6e 28 6e 61 6d 65 2c 20 27 77 th open(name, 'w
2eb0: 27 2c 20 65 6e 63 6f 64 69 6e 67 3d 22 75 74 66 ', encoding="utf
2ec0: 2d 38 22 29 20 61 73 20 66 3a 0a 20 20 20 20 20 -8") as f:.
2ed0: 20 20 20 20 20 20 20 20 20 20 20 66 2e 77 72 69 f.wri
2ee0: 74 65 28 72 65 6d 6f 74 65 5b 30 5d 5b 27 63 6f te(remote[0]['co
2ef0: 6e 74 65 6e 74 27 5d 29 0a 20 20 20 20 65 78 63 ntent']). exc
2f00: 65 70 74 20 49 4f 45 72 72 6f 72 20 61 73 20 65 ept IOError as e
2f10: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6d 73 67 :. if msg
2f20: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 :. pr
2f30: 69 6e 74 28 6d 73 67 29 0a 20 20 20 20 20 20 20 int(msg).
2f40: 20 70 72 69 6e 74 28 22 46 61 69 6c 65 64 20 74 print("Failed t
2f50: 6f 20 63 72 65 61 74 65 20 6c 6f 63 61 6c 20 63 o create local c
2f60: 6f 70 79 20 6f 66 20 74 68 61 74 20 6e 6f 74 65 opy of that note
2f70: 22 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 "). print
2f80: 28 65 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 (e). else:.
2f90: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 return Tru
2fa0: 65 0a 0a 0a 64 65 66 20 73 6e 72 65 61 64 28 66 e...def snread(f
2fb0: 69 6c 65 6e 61 6d 65 2c 20 6d 73 67 3d 4e 6f 6e ilename, msg=Non
2fc0: 65 29 3a 0a 20 20 20 20 74 72 79 3a 0a 20 20 20 e):. try:.
2fd0: 20 20 20 20 20 77 69 74 68 20 6f 70 65 6e 28 66 with open(f
2fe0: 69 6c 65 6e 61 6d 65 2c 20 27 72 27 29 20 61 73 ilename, 'r') as
2ff0: 20 66 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 f:.
3000: 63 6f 6e 74 65 6e 74 20 3d 20 66 2e 72 65 61 64 content = f.read
3010: 28 29 0a 20 20 20 20 65 78 63 65 70 74 20 49 4f (). except IO
3020: 45 72 72 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 Error as e:.
3030: 20 20 20 20 70 72 69 6e 74 28 22 46 61 69 6c 65 print("Faile
3040: 64 20 74 6f 20 72 65 61 64 20 66 69 6c 65 20 25 d to read file %
3050: 73 22 20 25 20 66 69 6c 65 6e 61 6d 65 29 0a 20 s" % filename).
3060: 20 20 20 20 20 20 20 69 66 20 6d 73 67 3a 0a 20 if msg:.
3070: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 print
3080: 28 6d 73 67 29 0a 20 20 20 20 65 6c 73 65 3a 0a (msg). else:.
3090: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 63 return c
30a0: 6f 6e 74 65 6e 74 0a 0a 0a 64 65 66 20 73 6e 72 ontent...def snr
30b0: 65 6d 6f 74 65 28 73 6e 63 6c 69 65 6e 74 2c 20 emote(snclient,
30c0: 6b 65 79 2c 20 6d 73 67 3d 4e 6f 6e 65 29 3a 0a key, msg=None):.
30d0: 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 try:.
30e0: 20 72 65 6d 6f 74 65 20 3d 20 73 6e 63 6c 69 65 remote = snclie
30f0: 6e 74 2e 67 65 74 5f 6e 6f 74 65 28 6b 65 79 29 nt.get_note(key)
3100: 0a 20 20 20 20 20 20 20 20 23 57 68 61 74 20 69 . #What i
3110: 66 20 63 61 6e 27 74 20 62 65 20 66 6f 75 6e 64 f can't be found
3120: 2c 20 6e 65 65 64 20 74 6f 20 61 62 6f 72 74 2e , need to abort.
3130: 2e 2e 0a 20 20 20 20 65 78 63 65 70 74 20 49 4f ... except IO
3140: 45 72 72 6f 72 20 61 73 20 65 3a 0a 20 20 20 20 Error as e:.
3150: 20 20 20 20 70 72 69 6e 74 28 22 46 61 69 6c 65 print("Faile
3160: 64 20 74 6f 20 66 69 6e 64 20 74 68 61 74 20 6e d to find that n
3170: 6f 74 65 20 6f 6e 20 53 69 6d 70 6c 65 6e 6f 74 ote on Simplenot
3180: 65 22 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e e"). prin
3190: 74 28 65 29 0a 20 20 20 20 20 20 20 20 69 66 20 t(e). if
31a0: 6d 73 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 msg:.
31b0: 20 70 72 69 6e 74 28 6d 73 67 29 0a 20 20 20 20 print(msg).
31c0: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 72 65 else:. re
31d0: 74 75 72 6e 20 72 65 6d 6f 74 65 0a 0a 0a 6d 61 turn remote...ma
31e0: 69 6e 28 29 0a in().