-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.coffee
164 lines (141 loc) · 4.28 KB
/
index.coffee
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
###
This URL should be "one size fits all"
###
command: """
echo "[
`curl -s https://api.coinmarketcap.com/v1/ticker/`,
`cat ~/.cryptoholdings.json`
]"
"""
refreshFrequency: '5m'
render: (output) ->
holdingsArray = JSON.parse(output)[1]
boxes = ""
for coin, attrs of holdingsArray
boxes += @genHtmlBox(attrs.ticker) + "\n"
boxes += @genHtmlBox('total', 'USD')
return boxes
###
A method that generates a HTML block
for a coin
coinName - Name of a coin to generate box for (e.g. bitcoin)
ticker - Ticker for a given coin (e.g. BTC). Defaults to coinName
###
genHtmlBox: (coinName, ticker = coinName) ->
return """
<div class='#{coinName.toLowerCase()} box'>
<div class='ticker'>1 #{ticker.toUpperCase()}</div>
<div class='badge lastUpdated'>Last Updated</div>
<div class='price'></div>
</div>
"""
###
A function that gets current date in a form of HH:MM
returns formatted date
###
getDate: () ->
d = new Date()
hours = d.getHours()
mins = d.getMinutes()
return "Updated: " + [
(if hours > 9 then '' else '0') + hours,
(if mins > 9 then '' else '0') + mins
].join(':')
update: (output, domEl) ->
resArr = JSON.parse(output)[0]
holdingsArray = JSON.parse(output)[1]
fmtDate = @getDate()
portfolio = {value: 0, cost_basis: 0, html: "", color: ""}
for coin, attrs of holdingsArray
coinRes = @findCoinResults(resArr, coin)
box = $(domEl).find('.' + attrs.ticker.toLowerCase())
info = @getPriceInfo(coinRes, attrs)
portfolio.value += info.value
portfolio.cost_basis += if (coin.cost_basis == undefined) then 0 else coin.cost_basis
@updateBox(box, info.html, fmtDate)
# update 'total' portfolio value rounded to cents
totalBox = $(domEl).find('.total')
portfolio.color = if (portfolio.value >= portfolio.cost_basis) then 'green' else 'red'
portfolio.html = "<div class='value #{portfolio.color}'>$ #{@roundAmount(portfolio.value, 2)}</div>"
@updateBox(totalBox, portfolio.html, fmtDate)
###
Finds a coin to generate data for from json response
jsonResponse - JSON with info about all coins
coinName - name of a coin to search for
###
findCoinResults: (jsonResponse, coinName) ->
for coin in jsonResponse
if (coin['id'] == coinName)
return coin
return {}
###
Sets date and value to a HTML box
boxName - class name for a HTML box to update
value - current price for a given coin
date - date string when it was last updated
###
updateBox: (boxName, value, date) ->
$(boxName).find('.price').html value
$(boxName).find('.lastUpdated').html date
###
Rounds a value to a number of decimals
amount - number to round
precision - number of numbers after decimal point
###
roundAmount: (amount, precision) ->
prec = Math.pow(10, precision)
rv = Math.round(amount * prec) / prec
return rv
###
Gets price information for a given coin
json - JSON object for a given coin
coin - coin config from holdings
returns JSON object containing HTML to be rendered
and raw value of holdings
###
getPriceInfo: (json, coin) ->
price = json['price_usd']
change = json['percent_change_1h']
value = coin.holdings * price
if coin.cost_basis == undefined
color = if (change >= 0) then 'green' else 'red'
else
color = if (value > coin.cost_basis) then 'green' else 'red'
return {html: """
<div class='price default'>$ #{@roundAmount(price, coin.round)}<div>
<div class='badge default'>Last Price</div>
<div class='value #{color}'>$ #{@roundAmount(value, 2)}</div>
<div class='currency default'>USD</div>
""", value: value}
style: """
bottom: 0.5%
right: 0.5%
color: white
font-family: 'Helvetica Neue'
font-weight: 100
text-align: left
margin: 5px
width: 200px
text-align: center
background-color: black
.box
padding: 3px
border: 1px solid rgba(#FFF, 50%)
font-size: 24px
.price
font-size: 32px
.ticker, .lastUpdated
text-align: left
.currency, .badge
text-align: right
.currency, .ticker, .badge, .lastUpdated
font-size: 10px
font-weight: 500
letter-spacing: 1px
.green
color: green
.red
color: red
.default
color: white
"""