This repository has been archived by the owner on Nov 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrlib1.py
303 lines (243 loc) · 9.2 KB
/
rlib1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# rlib1.py :: General library module
# http://sites.google.com/site/pocketsense/
# Intial version: rlc: Dec-2010
# - Initially contains QuoteHTMwriter() and supporting functions
# 10-Jan-2011*rlc
# Moved _header, _field, _tag, _genuid, and _date functios from quotes.py. Renamed and edited.
# 23Aug2012*rlc
# - Added combineOFX()
# 19Jan2014*rlc:
# -Added support for Google Finance quotes
# 02Feb2016*nt
# -Add support for opening ofx on Mac
import os, glob, site_cfg, time, uuid, re, random, platform
from control2 import *
from datetime import datetime
def QuoteHTMwriter(qList):
# Write quotes.htm containing quote data contained in quote list (qList)
# Supports Yahoo! finance links
# See quotes.py for qList structure
global userdat
userdat = site_cfg.site_cfg()
# CREATE FILE
filename = xfrdir + "quotes.htm"
fullpath = '"' + os.path.realpath(filename) + '"' #encapsulate spaces
f = open(filename,"w")
print "Writing", filename
# Write HEADER
_QHTMheader(f)
# Write BODY
shade = False
for quote in qList:
_QHTMrow(f, quote, shade)
shade = not shade
# Write FOOTER
_QHTMfooter(f)
f.close()
return fullpath
def _QHTMheader(f):
#header for quotes.htm
header = """
<!
Generated using PocketSense Python scripts for Microsoft Money
http://sites.google.com/site/pocketsense
Ver 1.0: Dec-2010: RLC
/!>
<style type="text/css">
body {font-family: Verdana;
font-size: 13;
background-color: white}
table {
text-align: center;
font-family: Verdana;
font-weight: normal;
font-size: 16px;
border: 2px solid gray;
border-collapse: collapse;
empty-cells: show
}
/* header */
th {
border: 2px solid gray;
font-weight: bold;
padding: 5;
}
/* cell */
td {
font-family: monospace;
border: 1px;
border-style: dotted solid;
padding-left: 6;
padding-right: 6;
}
td.s0 {background-color: FFFFFF} /* background */
td.s1 {background-color: F5F5F5} /* shaded cell */
td.s2 {background-color: 98FB98} /* green bkg */
td.s3 {background-color: EE5C42} /* red bkg */
</style>
<body topmargin=30 leftmargin=50>
<h1 align=left><font color=blue>My Quotes</font>
<a href='""" + userdat.YahooURL + """'><img width=140 border="0" src="http://l.yimg.com/a/i/brand/purplelogo/uh/us/fin.gif"></a>
<a href='""" + userdat.GoogleURL + """'><img width=70 border="0"
src="http://www.google.com/images/logos/google_logo_41.png"></a>
</h1>
<p>
<table>
<tr><th>Source</th><th>Symbol</th><th>Name</th><th>Price</th><th>Time</th>
<th >%Change<sup>(1)</sup></th></tr>
"""
f.write(header)
return
def _QHTMrow(f, quote, shade):
#write table row for quote to file f
#see quote.py for quote data structure
#shade = shade row?
if shade:
td1 = '<td class="s1">'
td1L = '<td align="left" class="s1">'
td1R = '<td align="right" class="s1">'
else:
td1 = '<td class="s0">'
td1L = '<td align="left" class="s0">'
td1R = '<td align="right" class="s0">'
if '-' in quote.pchange:
td2 = '<td class="s3">'
elif 'N/A' in quote.pchange or '?' in quote.pchange:
td2 = td1 # no change given... no shade
else:
td2 = '<td class="s2">'
tspace = ' ' * (8-len(quote.time)) #right just time
lspace = ' ' * (10-len(quote.date)) #leave space for double-digit month
row = td1 + quote.source + '</td>' + \
td1 + '<a href=' + quote.quoteURL +'>'+quote.symbol+'</a></td>' + \
td1L+ quote.name+'</td>' + \
td1R+ quote.price + '</td>' + \
td1 + lspace + quote.date + tspace + quote.time +'</td>' + \
td2 + quote.pchange + '</td></tr>'
f.write(row)
return
def _QHTMfooter(f):
#footer for quotes.htm
qTime = datetime.today().strftime("%m-%d-%Y at %H:%M:%S")
sitepath = os.path.realpath('sites.dat')
sitepath = '<a href="file:///' + sitepath + '"><b>sites.dat</b></a>'
footer = """
</table>
1. %Change = Percent change in price since the last close.
<p><br>
This page was generated by the <a href="http://sites.google.com/site/pocketsense/home/msmoneyfixp1">PocketSense Python scripts</a> for Money (on """ + qTime + """)</br>
Quotes provided by <a href='""" + userdat.YahooURL + """'>Yahoo! Finance</a>
and <a href='""" + userdat.GoogleURL + """'>Google Finance</a>.<br>
Stock and fund symbols are defined in your """ + sitepath + """ file.
</p>
</body>
"""
f.write(footer)
return
def OfxSGMLHeader():
#Standard OFX SGML Header
return """OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
"""
def OfxField(tag,value):
field = ''
#skip empty values
if tag <> '' and value <> '':
field = "<"+tag+">"+value
return field
def OfxTag(tag,*contents):
tag1 = '<' + tag + '>'
tag2 = '</' + tag + '>'
return '\n'.join([tag1]+list(contents)+[tag2])
def OfxDate():
return time.strftime("%Y%m%d%H%M%S",time.localtime())
def ofxUUID():
return str(uuid.uuid4())
def int2(str):
#convert str to int, without throwing exception. If str is not a "number", returns zero.
try:
f = int(str)
except:
f = 0
return f
def float2(str):
#convert str to float, without throwing exception. If str is not a "number", returns zero.
try:
f = float(str)
except:
f = 0.0
return f
def runFile(filename):
#ecapsulate call to os.system in quotes
#need to use open command on mac
if "Darwin" == platform.system():
os.system('open "'+filename+'"')
else:
os.system('"'+filename+'"')
return
def copy_txt_file(infile, outfile):
#copy text file
#for some reason, the shutil.copy() routines don't handle windows cr/lf correctly
inp = open(infile,'r')
out = open(outfile,'w')
out.write(inp.read())
return
def combineOfx(ofxList):
#combine ofx statements into a single file in a manner that Money seems to accept
dtnow = time.strftime("%Y%m%d%H%M%S",time.localtime())
signon = "\r".join([
"<SIGNONMSGSRSV1><SONRS>",
"<STATUS><CODE>0<SEVERITY>INFO<MESSAGE>Successful Sign On</STATUS>",
"<DTSERVER>" + dtnow,
"<LANGUAGE>ENG<DTPROFUP>20010101010000",
"<FI><ORG>PocketSense</FI></SONRS></SIGNONMSGSRSV1>"])
#these regexes capture everything between the tags, but not the tags
bRe = re.compile('(?:<BANKMSGSRSV1>)(.*?)(?:</BANKMSGSRSV1>)', re.IGNORECASE)
cRe = re.compile('(?:<CREDITCARDMSGSRSV1>)(.*?)(?:</CREDITCARDMSGSRSV1>)', re.IGNORECASE)
iRe = re.compile('(?:<INVSTMTMSGSRSV1>)(.*?)(?:</INVSTMTMSGSRSV1>)', re.IGNORECASE)
sRe = re.compile('(?:<SECLIST>)(.*?)(?:</SECLIST>)', re.IGNORECASE)
bantrn=''
crdtrn=''
invtrn=''
sectrn=''
for file in ofxList:
f=open(file[2])
ofx = f.read()
f.close()
ofx = ofx.replace(chr(13),'') #remove CRs
ofx = ofx.replace(chr(10),'') #remove LFs
#create a string for each section found in the file
#re.findall() returns a list of all matching sections
b = '\r'.join(bRe.findall(ofx))
c = '\r'.join(cRe.findall(ofx))
i = '\r'.join(iRe.findall(ofx))
s = '\r'.join(sRe.findall(ofx))
#add statements to each section
if b: bantrn = bantrn + '\r' + b
if c: crdtrn = crdtrn + '\r' + c
if i: invtrn = invtrn + '\r' + i
if s: sectrn = sectrn + '\r' + s
if bantrn: bantrn = OfxTag('BANKMSGSRSV1', bantrn)
if crdtrn: crdtrn = OfxTag('CREDITCARDMSGSRSV1', crdtrn)
if invtrn: invtrn = OfxTag('INVSTMTMSGSRSV1', invtrn)
if sectrn: sectrn = OfxTag('SECLISTMSGSRSV1', OfxTag('SECLIST', sectrn))
combOfx = '\r'.join(['<OFX>', signon, bantrn, crdtrn, invtrn, sectrn, '</OFX>'])
#remove blank lines (not required... just to clean it up)
combOfx2=''
for line in combOfx.splitlines():
if line: combOfx2 = combOfx2 + line + '\r'
combOfx = OfxSGMLHeader() + combOfx2
#there should never be two combined*.ofx files here, but we'll use a unique name just in case
cfile = xfrdir + 'combined' + str(random.randrange(1e5,1e6)) + '.ofx'
f=open(cfile,'w')
f.write(combOfx)
f.close()
print "Combined OFX created: " + cfile
return cfile