bloomberg.tcl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #
  2. # 20/07/2011
  3. #
  4. package require http
  5. namespace eval ::bloomberg {
  6. bind pub -|- !metals ::bloomberg::metals
  7. bind pub -|- !gold ::bloomberg::gold
  8. bind pub -|- !silver ::bloomberg::silver
  9. bind pub -|- !oil ::bloomberg::oil
  10. variable futures_url {http://www.bloomberg.com/markets/commodities/futures/}
  11. variable user_agent "Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.7e"
  12. # ms
  13. variable http_timeout 60000
  14. setudef flag bloomberg
  15. }
  16. proc ::bloomberg::fetch_data {} {
  17. ::http::config -useragent $::bloomberg::user_agent
  18. set token [::http::geturl $::bloomberg::futures_url -timeout $::bloomberg::http_timeout]
  19. set data [::http::data $token]
  20. set ncode [::http::ncode $token]
  21. ::http::cleanup $token
  22. if {$ncode != 200} {
  23. error "HTTP error code $ncode $data"
  24. }
  25. return $data
  26. }
  27. # Returns a dict, each key name of commodity
  28. # Each value for key is itself a dict with values
  29. # name, value, updown, change, change_percent, datetime
  30. proc ::bloomberg::parse_html {html} {
  31. # Get rid of everything before energy table
  32. regexp -- {<a class="nohov">(.*)} $html -> html
  33. set bulk_commodity_regexp {<tr.*?>.*?<td class="change value_.*?">.*?</tr>}
  34. set commodity_regexp {<td class="name">(.*?)</td>.*?<td class="value">(.*?)</td>.*?<td class="change value_(.*?)">(.*?)</td>.*?<td class="change value_.*?">(.*?)</td>.*?<td class="datetime">(.*?)</td>}
  35. set commodity_dict [dict create]
  36. foreach commodity_html [regexp -all -inline -- $bulk_commodity_regexp $html] {
  37. #puts "comm $commodity_html"
  38. regexp -- $commodity_regexp $commodity_html -> name value updown change change_percent datetime
  39. # Name can have excessive spacing
  40. set name [regsub -all -- {\s+} $name " "]
  41. #puts "name $name value $value updown $updown change $change change_percent $change_percent datetime $datetime"
  42. dict append commodity_dict $name [list name $name value $value updown $updown change $change change_percent $change_percent datetime $datetime]
  43. }
  44. return $commodity_dict
  45. }
  46. # Get commodities with names matching the names in list_of_commodities
  47. proc ::bloomberg::get_futures {list_of_commodities} {
  48. set raw_data [::bloomberg::fetch_data]
  49. set futures_dict [::bloomberg::parse_html $raw_data]
  50. set wanted_commodities [list]
  51. foreach commodity_key [dict keys $futures_dict] {
  52. foreach wanted_commodity $list_of_commodities {
  53. if {[regexp -nocase -- $wanted_commodity $commodity_key]} {
  54. lappend wanted_commodities [dict get $futures_dict $commodity_key]
  55. }
  56. }
  57. }
  58. return $wanted_commodities
  59. }
  60. proc ::bloomberg::colour {updown str} {
  61. if {[regexp -nocase -- {up} $updown]} {
  62. return \00309+$str\017\003
  63. } elseif {[regexp -nocase -- {down} $updown]} {
  64. return \00304$str\017\003
  65. } else {
  66. return $str\003
  67. }
  68. }
  69. proc ::bloomberg::output_commodity {chan commodity_dict} {
  70. set colour []
  71. set name [dict get $commodity_dict name]
  72. set value [dict get $commodity_dict value]
  73. set change [::bloomberg::colour [dict get $commodity_dict updown] "[dict get $commodity_dict change] [dict get $commodity_dict change_percent]"]
  74. set datetime [dict get $commodity_dict datetime]
  75. putserv "PRIVMSG $chan :$name: \00310$value $change $datetime"
  76. }
  77. proc ::bloomberg::oil {nick uhost hand chan argv} {
  78. if {![channel get $chan bloomberg]} { return }
  79. set commodities [::bloomberg::get_futures [list crude]]
  80. foreach commodity_dict $commodities {
  81. ::bloomberg::output_commodity $chan $commodity_dict
  82. }
  83. }
  84. proc ::bloomberg::metals {nick uhost hand chan argv} {
  85. if {![channel get $chan bloomberg]} { return }
  86. set commodities [::bloomberg::get_futures [list copper gold silver]]
  87. foreach commodity_dict $commodities {
  88. ::bloomberg::output_commodity $chan $commodity_dict
  89. }
  90. }
  91. proc ::bloomberg::gold {nick uhost hand chan argv} {
  92. if {![channel get $chan bloomberg]} { return }
  93. set commodities [::bloomberg::get_futures [list gold]]
  94. foreach commodity_dict $commodities {
  95. ::bloomberg::output_commodity $chan $commodity_dict
  96. }
  97. }
  98. proc ::bloomberg::silver {nick uhost hand chan argv} {
  99. if {![channel get $chan bloomberg]} { return }
  100. set commodities [::bloomberg::get_futures [list silver]]
  101. foreach commodity_dict $commodities {
  102. ::bloomberg::output_commodity $chan $commodity_dict
  103. }
  104. }
  105. putlog "bloomberg.tcl loaded"