Skip to content

Commit 42396cb

Browse files
committed
finished first pass at cli. better documentation and usage to follow
1 parent f2409ce commit 42396cb

3 files changed

Lines changed: 172 additions & 2 deletions

File tree

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
.*~
1+
*~
22
consumer_oauth.json
3-
*\.pkl
3+
*.pkl
4+
*bank*

groupsplit.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#! /usr/bin/python
2+
3+
import requests
4+
import csv
5+
import sys
6+
import oauthlib.oauth1
7+
import pprint
8+
import webbrowser
9+
import subprocess
10+
import os
11+
import pickle
12+
import json
13+
import urllib
14+
from pprint import pprint
15+
from datetime import datetime
16+
17+
if os.path.isfile("consumer_oauth.json"):
18+
with open("consumer_oauth.json", 'rb') as f:
19+
consumer = json.load(f)
20+
ckey=consumer['consumer_key']
21+
csecret = consumer['consumer_secret']
22+
else:
23+
with open("consumer_oauth.json", 'wb') as f:
24+
json.dump({'consumer_key':'YOUR KEY HERE',
25+
'consumer_secret':'YOUR SECRET HERE'}, f)
26+
exit("go to https://secure.splitwise.com/oauth_clients to obtain your keys. place them in consumer_oauth.json")
27+
28+
def get_client():
29+
client = oauthlib.oauth1.Client( ckey, client_secret=csecret )
30+
uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/get_request_token", http_method='POST')
31+
r = requests.post(uri, headers=headers, data=body)
32+
resp = r.text.split('&')
33+
oauth_token = resp[0].split('=')[1]
34+
oauth_secret = resp[1].split('=')[1]
35+
uri = "https://secure.splitwise.com/authorize?oauth_token=%s" % oauth_token
36+
37+
webbrowser.open_new(uri)
38+
39+
p = subprocess.Popen(['./server.py'], stdout=subprocess.PIPE, shell=True)
40+
stdout, stderr = p.communicate()
41+
client = oauthlib.oauth1.Client(ckey, client_secret=csecret,
42+
resource_owner_key=oauth_token, resource_owner_secret=oauth_secret,
43+
verifier=stdout.strip())
44+
45+
uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/get_access_token", http_method='POST')
46+
r = requests.post(uri, headers=headers, data=body)
47+
resp = r.text.split('&')
48+
oauth_token = resp[0].split('=')[1]
49+
oauth_secret = resp[1].split('=')[1]
50+
client = oauthlib.oauth1.Client(ckey, client_secret=csecret,
51+
resource_owner_key=oauth_token, resource_owner_secret=oauth_secret,
52+
verifier=stdout.strip())
53+
with open('oauth_client.pkl', 'wb') as f:
54+
pickle.dump(client, f)
55+
return client
56+
57+
58+
if os.path.isfile("oauth_client.pkl"):
59+
with open('oauth_client.pkl', 'rb') as f:
60+
client = pickle.load(f)
61+
else:
62+
client = get_client()
63+
64+
#uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/get_expenses?limit=3", http_method='GET')
65+
#r = requests.get(uri, headers=headers, data=body)
66+
#r = json.loads(r.text)
67+
68+
uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/get_current_user", http_method='GET')
69+
r = requests.get(uri, headers=headers, data=body)
70+
r = json.loads(r.text)
71+
myId = r['user']['id']
72+
73+
uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/get_groups", http_method='GET')
74+
r = requests.get(uri, headers=headers, data=body)
75+
r = json.loads(r.text)
76+
numFound = 0
77+
gid=''
78+
members={}
79+
for group in r['groups']:
80+
if group['name'].lower() == sys.argv[2].lower():
81+
gid = group['id']
82+
members=[ m['id'] for m in group['members'] if m['id'] != myId ]
83+
numFound += 1
84+
85+
print members
86+
87+
if numFound > 1:
88+
exit("More than 1 group found")
89+
elif numFound < 1:
90+
exit("No matching group")
91+
elif len( members ) < 1:
92+
exit("No members in group")
93+
with open(sys.argv[1], 'rb') as csvfile:
94+
reader = csv.reader(csvfile)
95+
rows = [ x for x in reader ]
96+
97+
98+
print "These are the first two rows of your csv"
99+
print '\n'.join( [ str(t) for t in rows[0:2] ] )
100+
print 'Colnum numbers start at 0'
101+
dateCol = input("Which column has the date?")
102+
amountCol = input("Which column has the amount?")
103+
descCol = input("Which column has the description?")
104+
titleRow = raw_input("Does first row have titles? [Y/n]").lower() != 'n'
105+
if titleRow:
106+
rows = rows[1:]
107+
transactions = [ { "date":datetime.strftime(datetime.strptime(r[dateCol],"%m/%d/%y"), "%Y-%m-%dT%H:%M:%SZ"),
108+
"amount":-1 * float(r[amountCol]),
109+
"desc":r[descCol] }
110+
for r in rows if float(r[amountCol]) < 0 ]
111+
splits = []
112+
for t in transactions:
113+
if raw_input("%s at %s $%s. Split? [y/N]" % (t['date'], t['desc'], t['amount'])).lower() == 'y':
114+
splits.append(t)
115+
116+
117+
118+
for s in splits:
119+
numPeople=len(members) + 1
120+
totalCents = int(s['amount'] * 100)
121+
baseAmount = totalCents // numPeople
122+
extraCents = totalCents - numPeople * baseAmount
123+
params = {
124+
"payment": 'false',
125+
"cost": s["amount"],
126+
"description": s["desc"],
127+
"date": s["date"],
128+
"group_id":gid,
129+
"users__0__user_id":myId,
130+
"users__0__paid_share":s["amount"],
131+
"users__0__owed_share":baseAmount/100.0,
132+
}
133+
for i in range(len(members)):
134+
params['users__%s__user_id' % (i+1)] = members[i]
135+
params['users__%s__paid_share' % (i+1)] = 0
136+
params['users__%s__owed_share' % (i+1)] = (baseAmount + 1)/100.0 if extraCents else baseAmount/100.0
137+
extraCents-=1
138+
params = urllib.urlencode(params)
139+
uri, headers, body = client.sign("https://secure.splitwise.com/api/v3.0/create_expense?%s" % params, http_method='POST')
140+
print "Request"
141+
print uri
142+
print "Headers:"
143+
print headers
144+
print "Body:"
145+
print body
146+
r = requests.post(uri, headers=headers, data=params)
147+
resp = json.loads(r.text)
148+
print "Response:"
149+
pprint(resp)

server.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#! /usr/bin/python
2+
from flask import Flask, request
3+
app = Flask(__name__)
4+
5+
6+
def shutdown_server():
7+
func = request.environ.get('werkzeug.server.shutdown')
8+
if func is None:
9+
raise RuntimeError('Not running with the Werkzeug Server')
10+
func()
11+
12+
@app.route('/', defaults={'path': ''})
13+
@app.route('/<path:path>')
14+
def authorize( path ):
15+
print request.args['oauth_verifier']
16+
shutdown_server()
17+
return "Thank you, you can close the tab"
18+
19+
if __name__ == "__main__":
20+
app.run()

0 commit comments

Comments
 (0)