snose

Hex Artifact Content
Login

Artifact 2609a1b7abe39f610f08ac4c93fd1e0cfaf96f05bed784a2e5ff8c761b6d2d67:


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().