Skip to content
51 changes: 45 additions & 6 deletions geeknote/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import Cookie
import uuid
import re
from urllib import urlencode, unquote
import base64
from urllib import urlencode, unquote, getproxies, proxy_bypass
from urlparse import urlparse

import out
Expand Down Expand Up @@ -58,6 +59,26 @@ class GeekNoteAuth(object):
incorrectCode = 0
code = None

def __init__(self):
try:
proxy = getproxies()['https']
except KeyError:
proxy = None
if proxy is None:
self._proxy = None
else:
# This assumes that the proxy is given in URL form.
# A little simpler as _parse_proxy in urllib2.py
self._proxy = urlparse(proxy)

if proxy is None or not self._proxy.username:
self._proxy_auth = None
else:
user_pass = "%s:%s" % (urlparse.unquote(self._proxy.username),
urlparse.unquote(self._proxy.password))
self._proxy_auth = { "Proxy-Authorization":
"Basic " + base64.b64encode(user_pass).strip() }

def getTokenRequestData(self, **kwargs):
params = {
'oauth_consumer_key': self.consumerKey,
Expand All @@ -77,9 +98,11 @@ def loadPage(self, url, uri=None, method="GET", params=""):
logging.error("Request URL undefined")
tools.exitErr()

if not url.startswith("http"):
url = "https://" + url
urlData = urlparse(url)
if not uri:
urlData = urlparse(url)
url = urlData.netloc
url = "%s://%s" (urlData.scheme, urlData.netloc)
uri = urlData.path + '?' + urlData.query

# prepare params, append to uri
Expand All @@ -97,11 +120,27 @@ def loadPage(self, url, uri=None, method="GET", params=""):
if method == "POST":
headers["Content-type"] = "application/x-www-form-urlencoded"

logging.debug("Request URL: %s:/%s > %s # %s", url,
if self._proxy is None or proxy_bypass(urlData.hostname):
host = urlData.hostname
port = urlData.port
real_host = real_port = None
else:
host = self._proxy.hostname
port = self._proxy.port
real_host = urlData.hostname
real_port = urlData.port

logging.debug("Request URL: %s%s > %s # %s", url,
uri, unquote(params), headers["Cookie"])

conn = httplib.HTTPSConnection(url)
conn.request(method, uri, params, headers)
conn = httplib.HTTPSConnection(host, port)

if real_host is not None:
conn.set_tunnel(real_host, real_port, headers=self._proxy_auth)
if config.DEBUG:
conn.set_debuglevel(1)

conn.request(method, url + uri, params, headers)
response = conn.getresponse()
data = response.read()
conn.close()
Expand Down
13 changes: 3 additions & 10 deletions geeknote/out.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,18 +275,11 @@ def rawInput(message, isPass=False):

def printDate(timestamp):

# Author @ash-2000 https://github.com/ash-2000
# Check for crashing when timestamp is 13 digits on python2.7
# pull request #260

if len(str(timestamp)) == 13:
timestamp = int(str(timestamp)[0:-3])

# ---

return datetime.date.strftime(datetime.date.fromtimestamp(timestamp / 1000), "%d.%m.%Y")

def printLine(line, endLine="\n", out=sys.stdout):
def printLine(line, endLine="\n", out=None):
if out is None:
out = sys.stdout
message = line + endLine
message = tools.stdoutEncode(message)
try:
Expand Down
45 changes: 45 additions & 0 deletions proxy_support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
HTTP proxy support for geeknote
===============================

I recommend to make this work with virtualenv, to avoid overwriting system files.
The important part is to install in the order **thrift, then evernote, then geeknote**. This will make sure that path search order is correct for thrift.

```
# Download thrift and geeknote
git clone https://github.com/apache/thrift.git
git clone https://github.com/mwilck/geeknote.git

# create and enter a virtual environment
virtualenv /var/tmp/geeknote
. /var/tmp/geeknote/bin/activate

# Apply proxy-support patches for thrift
cd thrift

## If the patches don't apply, you may need to check out the state that I wrote the patches for:
## git checkout -b proxy e363a34e63
curl https://issues.apache.org/jira/secure/attachment/12801233/0001-python-THttpClient-Add-support-for-system-proxy-sett.patch | git am
curl https://issues.apache.org/jira/secure/attachment/12801234/0002-Python-THttpClient-Support-proxy-authorization.patch | git am

# Install thrift from the patched tree
(cd lib/py; python setup.py install)
cd ..

# Install evernote
pip install evernote

# Install geeknote
cd geeknote
python setup.py install
```

Now `geeknote login`, `geeknote find`, etc. should work behind a proxy if the `http_proxy` environment variable is correctly set. You can now generate a script to activate the virtual environment:

```
cat >~/bin/geeknote <<\EOF
#! /bin/bash
. /var/tmp/geeknote/bin/activate
exec geeknote "$@"
EOF
chmod a+x ~/bin/geeknote
```
1 change: 0 additions & 1 deletion tests/editorTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def setUp(self):
_Line 2_

**Line 3**

"""
self.HTML_TEXT = "<h1>Header 1</h1><h2>Header 2</h2><p>Line 1</p><p>"\
"<em>Line 2</em></p><p><strong>Line 3</strong></p>"
Expand Down
5 changes: 2 additions & 3 deletions tests/geeknoteTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,5 @@ def test_createSearchRequest2(self):
self.assertEqual(testRequest, response)

def testError_createSearchRequest1(self):
testRequest = self.notes._createSearchRequest(search="test text",
date="12.31.1999")
self.assertEqual(testRequest, 'exit')
self.assertRaises(SystemExit, self.notes._createSearchRequest,
search="test text", date="12.31.1999")
42 changes: 25 additions & 17 deletions tests/outTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ class UserStub(object):
accounting = AccountingStub()


class NoteAttributesStub(object):
pass

class NoteStub(object):
title = 'testnote'
created = 10000
updated = 100000
content = '##note content'
tagNames = ['tag1', 'tag2', 'tag3']
guid = 12345

attributes = NoteAttributesStub()

class outTestsWithHackedStdout(unittest.TestCase):

Expand Down Expand Up @@ -73,9 +76,13 @@ def test_separator_empty_args_success(self):
self.assertEquals(sys.stdout.read(), '\n\n')

def test_failure_message_success(self):
sav = sys.stderr
buf = StringIO()
sys.stderr = buf
failureMessage('fail')
sys.stdout.seek(0)
self.assertEquals(sys.stdout.read(), 'fail\n')
sys.stderr = sav
buf.seek(0)
self.assertEquals(buf.read(), 'fail\n')

def test_success_message_success(self):
successMessage('success')
Expand Down Expand Up @@ -106,36 +113,37 @@ def test_show_note_success(self):
note = '''################## TITLE ##################
testnote
=================== META ==================
Created: 01.01.1970 Updated:01.01.1970 \n'''\
'''----------------- CONTENT -----------------
Created: 01.01.1970
Updated: 01.01.1970
----------------- CONTENT -----------------
Tags: tag1, tag2, tag3
##note content\n\n\n'''
##note content\n\n'''
showNote(NoteStub())
sys.stdout.seek(0)
self.assertEquals(sys.stdout.read(), note)

def test_print_list_without_title_success(self):
notes_list = '''Total found: 2
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
printList([NoteStub() for _ in xrange(2)])
sys.stdout.seek(0)
self.assertEquals(sys.stdout.read(), notes_list)

def test_print_list_with_title_success(self):
notes_list = '''=================== test ==================
Total found: 2
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
printList([NoteStub() for _ in xrange(2)], title='test')
sys.stdout.seek(0)
self.assertEquals(sys.stdout.read(), notes_list)

def test_print_list_with_urls_success(self):
notes_list = '''=================== test ==================
Total found: 2
1 : 01.01.1970 testnote >>> https://www.evernote.com/Home.action?#n=12345
2 : 01.01.1970 testnote >>> https://www.evernote.com/Home.action?#n=12345
1 : 01.01.1970 testnote >>> https://www.evernote.com/Home.action?#n=12345
2 : 01.01.1970 testnote >>> https://www.evernote.com/Home.action?#n=12345
'''
printList([NoteStub() for _ in xrange(2)], title='test', showUrl=True)
sys.stdout.seek(0)
Expand All @@ -145,8 +153,8 @@ def test_print_list_with_selector_success(self):
out.rawInput = lambda x: 2
notes_list = '''=================== test ==================
Total found: 2
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote
0 : -Cancel-\n'''
out.printList([NoteStub() for _ in xrange(2)], title='test', showSelector=True)
sys.stdout.seek(0)
Expand All @@ -155,11 +163,11 @@ def test_print_list_with_selector_success(self):
def test_search_result_success(self):
result = '''Search request: test
Total found: 2
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
1 : 01.01.1970 testnote
2 : 01.01.1970 testnote\n'''
SearchResult([NoteStub() for _ in xrange(2)], 'test')
sys.stdout.seek(0)
self.assertEquals(sys.stdout.read(), result)

def test_print_date(self):
self.assertEquals(printDate(1000000), '12.01.1970')
self.assertEquals(printDate(1000000000L), '12.01.1970')