aria2mon 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/env ruby
  2. # The MIT License
  3. #
  4. # Copyright (c) 2009 Tatsuhiro Tsujikawa
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to deal
  8. # in the Software without restriction, including without limitation the rights
  9. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. # copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included in
  14. # all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. # THE SOFTWARE.
  23. require 'xmlrpc/client'
  24. require 'optparse'
  25. program_name=File.basename($0)
  26. options={}
  27. args=nil
  28. OptionParser.new do |opt|
  29. opt.on("--server SERVER", "hostname of XML-RPC server. Default: localhost"){|val| options["server"]=val }
  30. opt.on("--port PORT", "port of XML-RPC server. Default: 6800"){|val| options["port"]=val }
  31. opt.on("--user USERNAME", "XML-RPC username"){|val| options["user"]=val }
  32. opt.on("--passwd PASSWORD", "XML-RPC password"){|val| options["passwd"]=val }
  33. opt.on("--secret SECRET", "XML-RPC secret authorization token"){|val| options["secret"]=val }
  34. opt.banner=<<EOS
  35. Usage: #{program_name} [options]
  36. EOS
  37. args=opt.parse(ARGV)
  38. end
  39. def compute_eta speed,rem_length
  40. return "n/a" if speed == 0
  41. remsec=rem_length/speed
  42. hr=remsec/3600
  43. remsec=remsec%3600
  44. min=remsec/60
  45. remsec=remsec%60
  46. result=""
  47. result += "#{hr}h" if hr > 0
  48. result += "#{min}m" if min > 0
  49. result += "#{remsec}s"
  50. end
  51. def abbrev value
  52. n=value/1024.0
  53. if n < 1 then
  54. return "#{value}"
  55. end
  56. value=n
  57. n=value/1024.0
  58. if n < 1 then
  59. return sprintf("%.1fKi", value)
  60. else
  61. return sprintf("%.1fMi", n)
  62. end
  63. end
  64. auth=""
  65. if options.has_key?("user") then
  66. auth=options["user"]+":"+options["passwd"]+"@"
  67. end
  68. if not options.has_key?("server") then
  69. options["server"]="localhost"
  70. end
  71. if not options.has_key?("port") then
  72. options["port"]="6800"
  73. end
  74. secret = if options.has_key?("secret") then "token:"+options["secret"] else nil end
  75. client=XMLRPC::Client.new3({:host => options["server"],
  76. :port => options["port"],
  77. :path => "/rpc",
  78. :user => options["user"],
  79. :password => options["passwd"]})
  80. options.delete("server")
  81. options.delete("port")
  82. options.delete("user")
  83. options.delete("passwd")
  84. options.delete("secret")
  85. def client_call client, secret, method, *params
  86. if secret.nil?
  87. client.call(method, *params)
  88. else
  89. client.call(method, secret, *params)
  90. end
  91. end
  92. result=client_call(client, secret, "aria2.tellActive")
  93. print "-- Download Progress --\n"
  94. result.each { |entry|
  95. gid=entry['gid']
  96. total_length=entry['totalLength'].to_i
  97. completed_length=entry['completedLength'].to_i
  98. upload_length=entry['uploadLength'].to_i
  99. download_speed=entry['downloadSpeed'].to_i
  100. print "GID##{gid}"
  101. if total_length == completed_length then
  102. if entry.key? 'infoHash' then
  103. # for BitTorrent print seed status
  104. print " SEEDING"
  105. if completed_length > 0 then
  106. print "(#{upload_length*100/completed_length}%)"
  107. end
  108. end
  109. else
  110. print " SIZE:#{abbrev completed_length}B/#{abbrev total_length}B"
  111. if total_length > 0 then
  112. print "(#{completed_length*100/total_length}%)"
  113. end
  114. end
  115. print " CN:#{entry['connections']}"
  116. if entry.key? 'numSeeders' then
  117. print " SEED:#{entry['numSeeders']}"
  118. end
  119. print " SPD:#{abbrev download_speed}B/s"
  120. if entry.key? 'infoHash'
  121. printf " UP:#{abbrev entry['uploadSpeed'].to_i}B/s(#{abbrev upload_length}B)"
  122. end
  123. print " ETA:#{compute_eta(download_speed, total_length-completed_length)}"
  124. print "\n"
  125. if entry.key? 'infoHash'
  126. print " InfoHash:#{entry['infoHash']}"
  127. end
  128. print "\n"
  129. files=client_call(client,secret,"aria2.getFiles",entry['gid'])
  130. if files.length > 0 then
  131. first_file=files.find{|file| file["selected"]=="true"}
  132. if first_file != nil then
  133. print " File:#{first_file['path']}"
  134. count=0
  135. files.each {|file| count += 1 if file["selected"]=="true"}
  136. if count > 1 then
  137. print "(#{count-1}more)"
  138. end
  139. print "\n"
  140. end
  141. end
  142. print "--------------------------------------------------------------------------------\n"
  143. }