You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

client.rb 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/usr/bin/ruby
  2. require 'colored'
  3. require 'json'
  4. require 'net/http'
  5. require 'time'
  6. require 'uri'
  7. require 'blowfish'
  8. class Client
  9. attr_accessor :output, :key
  10. def initialize input
  11. # @key = Blowfish::Key.generate( ENV['AUTHKEY'] )
  12. input = input.length < 1 ? '' : input
  13. #input = crypt input, true
  14. [:send, :parse, :prettify].each do |step|
  15. input = self.class
  16. .instance_method( step )
  17. .bind( self )
  18. .call input
  19. @output = input
  20. end
  21. end
  22. def crypt content, en = false
  23. return !en ?
  24. Blowfish.decrypt( [content].pack("H*"), @key ) : Blowfish.encrypt( content, @key ).unpack("H*").first
  25. end
  26. def send input
  27. tokenfile = File.expand_path( 'token.txt', File.dirname( __FILE__ ) )
  28. # endpoint = ( ENV['COMPLETER_URL'] || 'completer-eu.herokuapp.com' )
  29. http = Net::HTTP.new( 'localhost', 8087 )
  30. #http.use_ssl = true
  31. request = Net::HTTP::Post.new( '/' )
  32. request.body = { input: input }.to_json
  33. if File.exists? tokenfile
  34. request['Authorization'] = "Bearer #{File.read( tokenfile )}"
  35. end
  36. response = http.request request
  37. response = JSON.parse response.body
  38. # write token if exists
  39. if response.keys.include? 'token'
  40. File.write tokenfile, response['token']
  41. return send @default
  42. end
  43. system( 'clear' ) # if response['clear']
  44. return response['problems'] ||
  45. response['branches'] ||
  46. response['message']
  47. end
  48. def parse data
  49. if data.class != Array
  50. return data
  51. end
  52. data = data.sort_by {|problem| problem['z'].to_i }
  53. # TODO uncle entries have smaller X values
  54. # TODO and should break the Xsibling Xsibling Xsibling sequenc
  55. # find ancestors
  56. data = data.map do |problem|
  57. # ancestor entries are last in the array of (x==X-1 and ID < problem.id) entries
  58. ancestors = data.select { |ancestor| ancestor['x'] == problem['x'] - 1 && ancestor['id'] < problem['id'] }
  59. problem['ancestor'] = (ancestors.max_by { |s| s['y'] } || { id: 0 })['id']
  60. problem
  61. end
  62. # find final entries
  63. data = data.map do |problem|
  64. siblings = data.select { |p| p['x'] == problem['x'] && p['ancestor'] == problem['ancestor'] }
  65. if siblings.last == problem || problem == data.last;
  66. problem['final'] = true
  67. end
  68. problem
  69. end
  70. return data.sort_by { |e| e['id'] }
  71. end
  72. def prettify raw
  73. if raw.class != Array
  74. return raw
  75. end
  76. pretty = []
  77. unsolved = raw.reverse.select { |p| !p['current'].nil? }.first
  78. sought = raw.select { |p| !p['sought'].nil? }.first
  79. slice_age = Time.now.to_i - Time.parse( raw.first['created_at'] ).to_i
  80. entry_frequence = "%.9f" % ( raw.count.to_f / slice_age )
  81. offsets = raw.first['x']
  82. raw.each do |problem|
  83. resolved = problem['solution'].class == String
  84. problem['indent'] = (0..(problem['x'] - offsets)).to_a.map { |_e| ' ' }.join
  85. problem['symbol'] = resolved ?
  86. 'x' : '○'
  87. problem['problem'] = problem == sought ?
  88. ' ! '.green.concat( problem['problem'] ).concat( ' {', ['how', 'why'].shuffle.join(', ').green, '} ') : problem['problem']
  89. problem['problem'] = problem == unsolved ?
  90. ' ! '.red.concat( problem['problem'] ).concat( ' (', ['how?'.red, 'why?'.red, 'assumptions?'.red, 'what is missing?'.red].shuffle.join(', '), ')') : problem['problem']
  91. problem['solution'] = resolved ?
  92. '------ '.concat( problem['solution'] ) : nil
  93. problem['tag'] = problem['tag'] ? '@'.concat(problem['tag']) : ''
  94. problem['parent'] = problem['parent'] ? ', parent: '.concat(problem['parent'].to_s) : ''
  95. text = "#{problem['indent']}#{problem['symbol']} #{problem['problem']} #{problem['solution']} (#{problem['x']};#{problem['y']};#{problem['z']}@#{problem['id']})#{problem['parent']}"
  96. pretty.push text
  97. end
  98. pretty.push "Frequence score: #{entry_frequence}"
  99. return pretty.join("\n")
  100. end
  101. end
  102. puts (Client.new ARGV.join ' ').output