phase.coffee | |
---|---|
_ = require("underscore")
cliff = require("cliff")
degrees = require("upon").degrees
Ensemble = require("archai").Ensemble | |
This is just points presentation,
It could later be done with a | module.exports = phase = (streamin, stream) ->
streamin.on "data", (data) ->
json = JSON.parse(data) |
It's just about output format from here on. | if json.length > 0
ensemble = new Ensemble
longitude = " longitude" # the name cliff label
rpad = ' ' # right-padding for better readability
table =
[ { "key": " "
, "req": ["id", "sid"]
, "act": true
, "val": (its, it) ->
lead = if its.sid >= 10000 then "+" else ""
if it.get('u')? then it.get('u').white else lead
}
, { "key": "what"
, "req": ["id"]
, "act": true
, "val": (its, it) ->
if it.get('id') is '?' then its.id else it.get 'name'
}
, { "key": longitude
, "req": ["lon"]
, "act": true
, "val": (its) ->
degrees.lon(its.lon).rep('str')
, sort: "lon"
}
, { "key": "~"
, "req": ["day_lon"]
, "act": true
, "val": (its) ->
if its.day_lon < 0 then '℞'.red else ''
}
, { "key": " speed"
, "req": ["day_lon"]
, "act": true
, "val": (its) ->
if its.day_lon?
front = ('' if its.day_lon < 0 or its.day_lon >= 10) ? ' '
front + its.day_lon.toFixed 3
else ''
}
, { "key": " latitude"
, "req": ["lat"]
, "act": false
, "val": (its) ->
degrees.of(its.lat).str()
}
, { "key": "distance"
, "req": ["dau"]
, "act": true
, "val": (its) ->
return '' unless _.isNumber its.dau
its.dau.toFixed(4 - String(Math.floor its.dau).length) + " AU"
}
, { "key": "reason"
, "req": ["re"]
, "act": true
, "val": (its) ->
its.re
}
] |
Reconsider what will be shown. | show = []
for item in table |
Don't show inactive stuff. | continue if item.act isnt true |
Don't work with columns all of whose values are entirely the same. | continue if 1 is _.size _.uniq _.pluck json, item.req[0]
show.push item
table = show |
The out-values, titles and their color. | out = []
titles = _.pluck table, 'key'
color = []
color.push "white" for count in [0..table.length] |
Add the representations for better readability. | lon = degrees.lon 0 # just for representation symbols
for i in [0..11]
json.push
marker: true
id: lon.representations[i]
lon: i * 30
re: "zodiac".green |
Process and sort. | for i, item of json
out.push { order: [] }
for col in table
it = ensemble.id item.id
piece = col.val item, it
piece += rpad if col.key isnt '~'
out[i][col.key] = piece
if col.sort? and not item.marker
out[i].order.push Number(item[col.sort])
out[i].id = item.id # for post-processing |
Output markers for each representation. | if item.marker is true |
TODO: append | what = out[i]['what']
mark = "#{item.lon}\u00B0"
mark = ' ' + mark for count in [0..(5 - mark.length)]
out[i].marker = true
out[i].order.push Number(item.lon)
out[i]['what'] = what.green
out[i][longitude] = mark.green
out = _.sortBy out, (obj) -> obj['order'][0] |
TODO: an ugly hack - resolve this technical debt! It all comes from lon 0 being 360. Perhaps a 2nd special kind of longitude should be further sub-classed? | for idx in [(out.length-1)..0]
if out[idx].order[0] is 360 then out[idx].order[0] = 0 else break |
Sort again, because of the above... | out = _.sortBy out, (obj) -> obj['order'][0] |
Reduce and write to the stream. | [seq, prev] = [{}, {}]
for i, item of out
out[i].extra = false # innocent by default (i.e. not guilty) |
Instead of | if prev.order?[0] isnt item.order[0]
if _.size(seq) > 1
angled = topical = fortune = false |
One or more of the angles can be found in this sequence. | if (_.union ['AS', 'MC', 'DS', 'IC'], _.keys seq).length >= 1
angled = true
for id, idx of seq |
Makes any house extra. | out[idx].extra = true if id[0] is 'H' and angled is true |
Topical & Fortune Houses. | if id[0] is 'T' or id[0] is 'F'
out[idx].extra = true
switch id[0]
when 'T' then topical = id.substr 1
when 'F' then fortune = id.substr 1
if topical isnt false
out[i_mark].what += " #{topical}".white
if fortune isnt false
out[i_mark].what += " / #{fortune}".white |
Reset the sequence after a longitude change is processed. | seq = {} |
From here on, there is always at least one one id in the sequence. | seq["#{item.id}"] = i |
It's mportant to set the marker index after processing. Otherwise, sometimes the next marker steals the topics. | i_mark = i if item.marker is true
prev = item
outer = _.filter out, (final) -> final.extra is false
stream.write cliff.stringifyObjectRows outer, titles, color
else stream.write "Given no data."
stream.emit "end"
|