Skip to content
This repository has been archived by the owner on Mar 20, 2019. It is now read-only.

Commit

Permalink
Begin refactoring
Browse files Browse the repository at this point in the history
While still not done made some progress on cleaning things up

* use logging module
* moved things into packages
* dropped the git version getting madness
* raise exception instead of setting an is_error
* minimum python version is v2.6 (using `with` and removed the check on
  json import which was needed in 2.5)
  • Loading branch information
vrillusions authored and Todd Eddy committed May 27, 2014
1 parent c3b16a3 commit 17e8cfc
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 84 deletions.
10 changes: 10 additions & 0 deletions simplenote/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# vim: set fileencoding=utf-8 :
from __future__ import (division, absolute_import, print_function,
unicode_literals)
from .simplenote import *


# Versioning currently follows sn.py
#__version__ = '0.1.0'
__all__ = ['simplenote', 'exceptions']

10 changes: 10 additions & 0 deletions simplenote/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# vim: set fileencoding=utf-8 :
from __future__ import (division, absolute_import, print_function,
unicode_literals)


__all__ = ['SimplenoteError']


class SimplenoteError(Exception):
pass
56 changes: 15 additions & 41 deletions simplenote.py → simplenote/simplenote.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env python
# vim:ts=4:sw=4:ft=python:fileencoding=utf-8
"""Simplenote
Expand All @@ -22,19 +21,16 @@
import urllib2
import base64
import sys
from subprocess import Popen, PIPE
# Make some effort to be backwards compatible with 2.5
try:
import json
except ImportError:
import simplejson as json
import logging
import json

from .exceptions import SimplenoteError

git_version = Popen(['git', 'describe', '--always'],
stdout=PIPE, stderr=PIPE).stdout.read().strip()
__version__ = git_version if git_version else 'alpha'
# cleanup so this doesn't showup in pydoc
del git_version, PIPE

__all__ = ['Simplenote']


_logger = logging.getLogger(__name__)


class Simplenote(object):
Expand All @@ -46,27 +42,13 @@ def __init__(self, email, password):
password: The users' password
"""
_logger.debug('Entered Simplenote()')
self.base_url = 'https://simple-note.appspot.com/api2/'
self.email = email
self.password = password
self.authtok = ''
self.has_error = False
self.last_error = ''
self.api_count = 0

def _error(self, msg='', exitcode=None):
"""Error handling.
Sets has_error to True and last_error to given message.
Optionally can be told to exit if a critical error occurs.
"""
self.has_error = True
self.last_error = msg
if exitcode != None:
print msg
sys.exit(exitcode)

def _process_query(self, url, query={}, add_authtok=True):
"""Processes the given url and query dictionary
Expand Down Expand Up @@ -98,13 +80,10 @@ def _process_query(self, url, query={}, add_authtok=True):
fh.close()
except urllib2.HTTPError, e:
# Received a non 2xx status code
self._error('http error: ' + str(e.code))
print e.readlines()
return False
raise SimplenoteError('http error: ' + str(e.code))
except urllib2.URLError, e:
# Non http error, like network issue
self._error('url error:' + e.reason)
return False
raise SimplenoteError('url error:' + e.reason)
return json.loads(response)

def login(self):
Expand All @@ -122,13 +101,10 @@ def login(self):
self.authtok = fh.read()
except urllib2.HTTPError, e:
# Received a non 2xx status code
self._error('http error: ' + str(e.code))
print e.readlines()
return False
raise SimplenoteError('http error: ' + str(e.code))
except urllib2.URLError, e:
# Non http error, like network issue
self._error('url error:' + e.reason)
return False
raise SimplenoteError('url error:' + e.reason)
fh.close()
return True

Expand All @@ -139,13 +115,13 @@ def note(self, key=None):
"""
if key == None:
self._error('Unable to get note: Key not given')
raise SimplenoteError('Unable to get note: Key not given')
url = self.base_url + 'data/' + key
note = self._process_query(url)
return note

def delete(self):
pass
raise NotImplementedError()

def index(self, length=100, mark=None):
"""Retrieves index of notes.
Expand All @@ -172,8 +148,6 @@ def full_index(self):
mark = indextmp['mark']
indextmp = ''
indextmp = self.index(mark=mark)
if self.has_error is True:
return False
for note in indextmp['data']:
full_index.append(note)
else:
Expand Down
70 changes: 30 additions & 40 deletions sn.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@
Command line interface to simplenote.
Environment Variables
LOGLEVEL: overrides the level specified here. Default is warning
"""


import sys
import os
import traceback
from optparse import OptionParser
from ConfigParser import SafeConfigParser
from subprocess import Popen, PIPE
import xml.etree.ElementTree as ET
import json
from datetime import datetime
import math
import logging

from simplenote import Simplenote
import progress_bar as pb
import util.progress_bar as pb

# development modules, can be removed later
import pprint


git_version = Popen(['git', 'describe', '--always'],
stdout=PIPE, stderr=PIPE).stdout.read().strip()
__version__ = git_version if git_version else 'alpha'
__version__ = '0.3.0'


def dict_to_xml(dict):
Expand All @@ -54,51 +54,49 @@ def main():
help='Output file name (default: %default)', metavar='FILE')
(options, args) = parser.parse_args()

log = logging.getLogger('sn')

# set script's path and add '/' to end
script_path = os.path.abspath(os.path.dirname(sys.argv[0])) + '/'

if args:
print 'debug: you wanted to run command: ' + args[0]
# TODO: PUT CODE HERE TO PULL XDG DIRECTORIES

if args:
log.debug('you wanted to run command: {}'.format(args[0]))
config = SafeConfigParser()
# can pass multiple files to config.read but it merges them, which we don't want
if not config.read(options.config):
# could not read file, try the script's path
if not config.read(script_path + options.config):
# Still can't find it, error out
print 'Could not read any config file'
sys.exit(1)
log.critical('could not read any config file')
return 1
email = config.get('simplenote', 'email')
password = config.get('simplenote', 'password')

# TODO: GET PATH TO CACHE FILE (PROBABLY THROUGH XDG)

#sn = Simplenote(email, password, cache_file)
sn = Simplenote(email, password)
if not sn.login():
print 'ERROR:', sn.last_error
sys.exit(1)
sn.login()
index = sn.full_index()
#index = sn.index(5)
if sn.has_error:
print 'ERROR:', sn.last_error
sys.exit(1)
#print '- index -'
#pp = pprint.PrettyPrinter(indent=4)
#pp.pprint(index)
print 'number of notes:', str(len(index))
log.info('number of notes: {}'.format(len(index)))
notecount = float(len(index))
#print '- data -'
notes = []
i = 0
#for note_meta in index['data']:
for note_meta in index:
note = sn.note(note_meta['key'])
if sn.has_error:
print 'ERROR:', sn.last_error
sys.exit(1)
notes.append(note)
#pp.pprint(note)
i += 1
pb.progress(50, math.floor(float(i) / notecount * 100.0))
print 'Number of api calls:', str(sn.api_count)
log.debug('Number of api calls: {}'.format(sn.api_count))
# xml format
#xmlnotes = ''
#for note in notes:
Expand All @@ -123,25 +121,17 @@ def main():
json_note_tmp.update({'key': note['key']})
jsonnotes.append(json_note_tmp)
#print json.dumps(jsonnotes)
fh = open(options.output, 'w')
fh.write(json.dumps(jsonnotes))
fh.close()
with open(options.output, 'w') as fh:
fh.write(json.dumps(jsonnotes))


if __name__ == "__main__":
try:
main()
except KeyboardInterrupt, e:
# Ctrl-c
raise e
except SystemExit, e:
# sys.exit()
raise e
except Exception, e:
print "ERROR, UNEXPECTED EXCEPTION"
print str(e)
traceback.print_exc()
sys.exit(1)
else:
# Main function is done, exit cleanly
sys.exit(0)
# Logger config
# DEBUG, INFO, WARNING, ERROR, or CRITICAL
# This will set log level from the environment variable LOGLEVEL or default
# to warning. You can also just hardcode the error if this is simple.
_loglevel = getattr(logging, os.getenv('LOGLEVEL', 'WARNING').upper())
_logformat = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
logging.basicConfig(level=_loglevel, format=_logformat)

sys.exit(main())
6 changes: 6 additions & 0 deletions util/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# vim: set fileencoding=utf-8 :
from __future__ import (division, absolute_import, print_function,
unicode_literals)


__all__ = ['progress_bar']
9 changes: 6 additions & 3 deletions progress_bar.py → util/progress_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
>>> math.floor(currently / float(total) * 100)
54.0
Update: This is solved now with __future__.division
"""
from __future__ import division
import sys
import time
import math
Expand All @@ -27,10 +30,10 @@
def progress(width, percent):
marks = math.floor(width * (percent / 100.0))
spaces = math.floor(width - marks)

loader = '[' + ('=' * int(marks)) + (' ' * int(spaces)) + ']'

sys.stdout.write("%s %d%%\r" % (loader, percent))
if percent >= 100:
sys.stdout.write("\n")
sys.stdout.flush()
sys.stdout.flush()

0 comments on commit 17e8cfc

Please sign in to comment.