process-consensus 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/ruby
  2. require "yaml"
  3. require 'db'
  4. require 'db-config'
  5. require 'update-named-status'
  6. $db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
  7. $router_cache = {}
  8. $nickname_cache = {}
  9. def parse_consensus consensus
  10. ts = nil
  11. routers = []
  12. consensus.each do |line|
  13. (key, value) = line.split(' ',2)
  14. case key
  15. when "valid-after", "published": ts = DateTime.parse(value)
  16. when "r":
  17. (nick, fpr, _) = value.split(' ', 3)
  18. nick.downcase!
  19. next if nick == 'unnamed'
  20. routers << {
  21. 'nick' => nick,
  22. 'fingerprint' => (fpr+'=').unpack('m').first.unpack('H*').first
  23. }
  24. end
  25. end
  26. throw "Did not find a timestamp" unless ts
  27. throw "Did not find any routers" unless routers.size > 0
  28. return ts, routers
  29. end
  30. def insert_routers_into_db(router, table, field, value)
  31. pk = table+'_id'
  32. row = $db.query_row("SELECT #{pk} FROM #{table} WHERE #{field}=?", value)
  33. if row
  34. return row[pk]
  35. else
  36. r = { field => value }
  37. $db.insert_row( table, r )
  38. return r[pk]
  39. end
  40. end
  41. def handle_one_consensus(c)
  42. puts "parsing..." if $verbose
  43. timestamp, routers = parse_consensus c
  44. puts "storing..." if $verbose
  45. routers.each do |router|
  46. fpr = router['fingerprint']
  47. nick = router['nick']
  48. $router_cache[fpr] = router_id = ($router_cache[fpr] or insert_routers_into_db(router, 'router', 'fingerprint', router['fingerprint']))
  49. $nickname_cache[nick] = nickname_id = ($nickname_cache[nick] or insert_routers_into_db(router, 'nickname', 'nick', router['nick']))
  50. row = $db.update(
  51. 'router_claims_nickname',
  52. { 'last_seen' => timestamp.to_s },
  53. { 'router_id' => router_id, 'nickname_id' => nickname_id} )
  54. case row
  55. when 0:
  56. $db.insert('router_claims_nickname',
  57. {
  58. 'first_seen' => timestamp.to_s,
  59. 'last_seen' => timestamp.to_s,
  60. 'router_id' => router_id, 'nickname_id' => nickname_id} )
  61. when 1:
  62. else
  63. throw "Update of router_claims_nickname returned unexpected number of affected rows(#{row})"
  64. end
  65. end
  66. end
  67. $db.transaction_begin
  68. if ARGV.first == '-v'
  69. $verbose = true
  70. ARGV.shift
  71. end
  72. if ARGV.size == 0
  73. handle_one_consensus STDIN.readlines
  74. do_update $verbose
  75. else
  76. ARGV.each do |filename|
  77. puts filename if $verbose
  78. handle_one_consensus File.new(filename).readlines
  79. puts "updating..." if $verbose
  80. do_update $verbose
  81. end
  82. end
  83. $db.transaction_commit