I need to read the body of each email to find a specific number.
my code:
imap.search(["ON","20-Jan-2021"]).each do |message_id|
body = imap.fetch(message_id, "BODY[]")[0].attr["BODY[]"]
mail = Mail.new(body)
pp mail.body
end
the result is something like
"L0Rlc3RbOCAwIFIvRml0SCA4MzJdL1BhcmVudCAxNiAwIFIvVGl0bGUoKT4+CmVuZG9iagoxOCAw\r\n" +
"IG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAxMyAwIFIvT3V0bGluZXMgMTYgMCBSPj4KZW5kb2Jq\r\n" +
"CjE5IDAgb2JqPDwvQ3JlYXRpb25EYXRlKEQ6MjAyMTAxMjAxMDQ2NDUrMDInMDAnKS9Qcm9kdWNl\r\n" +
I have tried to use:
mail.body.decoded # same result like above.
mail.text_part.decoded # error: undefined method `decoded' for nil:NilClass
mail.text_part.body.to_s # error: undefined method `body' for nil:NilClass
I would check the contents of the body for the Content-Transfer-Encoding, which is more than likely base64. Ruby provides a base64 module which makes it easy to decode:
require "base64"
# IMAP authentication and whatnot
imap.search(["ON","20-Jan-2021"]).each do |message_id|
body = imap.fetch(message_id, "BODY[]")[0].attr["BODY[]"]
body = Base64.decode64(body)
mail = Mail.new(body)
pp mail.body
end
FWIW, your provided text yields
/Dest[8 0 R/FitH 832]/Parent 16 0 R/Title()>>
endobj
18 0 obj<</Type/Catalog/Pages 13 0 R/Outlines 16 0 R>>
endobj
19 0 obj<</CreationDate(D:20210120104645+02'00')/Produce
when decoded from base64.
Related
I'm using a Ruby RLP library to encode one value and then decode it. However, I'm getting different values for encoding and decoding:
require 'rlp'
class Transaction
include RLP::Sedes::Serializable
set_serializable_fields(
to: RLP::Sedes::Binary.fixed_length(20, allow_empty: true)
)
def initialize(*args)
fields = parse_field_args(args)
fields[:to] = [fields[:to]].pack('H*')
serializable_initialize(fields)
end
def encoded
RLP.encode(self)
end
def self.decode(data_in)
deserialize(RLP.decode(data_in))
end
end
recipient = "6ba381ce15b19c7e44b8603ad7e698059c09a39b"
tx = Transaction.new(recipient)
puts "Should decode to #{recipient}"
puts "Actually decodes to #{Transaction.decode(tx.encoded).to.unpack('H*').first}"
Running it, the decoded value is actually 431e51ced80a7685c93b, instead of the inputed value. This doesn't even seem to be related to what was encoded.
Is the library at fault here? I'm using this library:
https://github.com/cryptape/ruby-rlp
Yes, it is always the same and you can go back and forth.
require "eth"
recipient = "6ba381ce15b19c7e44b8603ad7e698059c09a39b"
# => "6ba381ce15b19c7e44b8603ad7e698059c09a39b"
encoded = Eth::Rlp.encode "6ba381ce15b19c7e44b8603ad7e698059c09a39b"
# => "\xA86ba381ce15b19c7e44b8603ad7e698059c09a39b"
decoded = Eth::Rlp.decode encoded
# => "6ba381ce15b19c7e44b8603ad7e698059c09a39b"
decoded === recipient
# => true
If you are trying to build a transaction serializer in Ruby, take a look at the eth gem.
I'm getting read_body called twice (IOError) using the net/http library. I'm trying to download files and use http sessions efficiently. Looking for some help or advice to fix my issues. From my debug message it appears when I log the response code, readbody=true. Is that why read_body is read twice when I try to write the large file in chunks?
D, [2015-04-12T21:17:46.954928 #24741] DEBUG -- : #<Net::HTTPOK 200 OK readbody=true>
I, [2015-04-12T21:17:46.955060 #24741] INFO -- : file found at http://hidden:8080/job/project/1/maven-repository/repository/org/project/service/1/service-1.zip.md5
/usr/lib/ruby/2.2.0/net/http/response.rb:195:in `read_body': Net::HTTPOK#read_body called twice (IOError)
from ./deploy_application.rb:36:in `block in get_file'
from ./deploy_application.rb:35:in `open'
from ./deploy_application.rb:35:in `get_file'
from ./deploy_application.rb:59:in `block in <main>'
from ./deploy_application.rb:58:in `each'
from ./deploy_application.rb:58:in `<main>'
require 'net/http'
require 'logger'
STAMP = Time.now.utc.to_i
#log = Logger.new(STDOUT)
# project , build, service remove variables above
project = "project"
build = "1"
service = "service"
version = "1"
BASE_URI = URI("http://hidden:8080/job/#{project}/#{build}/maven-repository/repository/org/#{service}/#{version}/")
# file pattern for application is zip / jar. Hopefully the lib in the zipfile is acceptable.
# example for module download /#{service}/#{version}.zip /#{service}/#{version}.zip.md5 /#{service}/#{version}.jar /#{service}/#{version}.jar.md5
def clean_exit(code)
# remove temp files on exit
end
def get_file(file)
puts BASE_URI
uri = URI.join(BASE_URI,file)
#log.debug(uri)
request = Net::HTTP::Get.new uri #.request_uri
#log.debug(request)
response = #http.request request
#log.debug(response)
case response
when Net::HTTPOK
size = 0
progress = 0
total = response.header["Content-Length"].to_i
#log.info("file found at #{uri}")
# need to handle file open error
Dir.mkdir "/tmp/#{STAMP}"
File.open "/tmp/#{STAMP}/#{file}", 'wb' do |io|
response.read_body do |chunk|
size += chunk.size
new_progress = (size * 100) / total
unless new_progress == progress
#log.info("\rDownloading %s (%3d%%) " % [file, new_progress])
end
progress = new_progress
io.write chunk
end
end
when 404
#log.error("maven repository file #{uri} not found")
exit 4
when 500...600
#log.error("error getting #{uri}, server returned #{response.code}")
exit 5
else
#log.error("unknown http response code #{response.code}")
end
end
#http = Net::HTTP.new(BASE_URI.host, BASE_URI.port)
files = [ "#{service}-#{version}.zip.md5", "#{service}-#{version}.jar", "#{service}-#{version}.jar.md5" ].each do |file| #"#{service}-#{version}.zip",
get_file(file)
end
Edit: Revised answer!
Net::HTTP#request, when called without a block, will pre-emptively read the body. The documentation isn't clear about this, but it hints at it by suggesting that the body is not read if a block is passed.
If you want to make the request without reading the body, you'll need to pass a block to the request call, and then read the body from within that. That is, you want something like this:
#http.request request do |response|
# ...
response.read_body do |chunk|
# ...
end
end
This is made clear in the implementation; Response#reading_body will first yield the unread response to a block if given (from #transport_request, which is called from #request), then read the body unconditionally. The block parameter to #request gives you that chance to intercept the response before the body is read.
I am trying to find the needle in the haystack. I already received the dictionary with the two values and keys.
ruby haystack.rb
{"haystack"=>["D0zVh", "F1PFc", "j1WMn", "Ebz3k", "SE7gZ", "kOa7j", "0vCJb", "px18q", "NJSyl", "nRsOK", "T7t8F", "2jvwZ", "5414s", "q5z8U", "TI2Zm", "v4Bn9", "5dRcM", "M84vp", "8nQ0o", "OxEKw"], "needle"=>"v4Bn9"}
The first value, needle, is the string. The second value, haystack, is an array of strings.
The next step is to tell the API where the needle is in the haystack array.
I need to post my result to "api/validateneedle", using the key token for my token, and the key needle for the integer representing where the needle is in the haystack array.
When I run this file, I get the following error:
haystack.rb:59:in `<main>': undefined local variable or method `token' for main:Object (NameError)
Can anyone tell me why I'm receiving this error message? I really appreciate any help/feedback!
token_info = {:token => "SVilLuY0OU"}
require 'net/http'
http = Net::HTTP.new("challenge.code2040.org")
# Sending json in body of http request
# Creating a request that will use the post http method
require "json"
body = token_info.to_json
request = Net::HTTP::Post.new("/api/haystack")
# Setting the request body to be our json
request.body = body
# Storing my token in a variable
response = http.request(request)
# Printing my token to complete rest of assignment
#Printing the body of the response
response_hash = JSON.parse(response.body)
puts response_hash["result"]
def getIndex(response)
needle = response["result"]["needle"]
haystack = response["result"]["haystack"]
i = 0
while i < haystack.length
# if we find it, break the loop and return i
if haystack[i] == needle
return i.to_s
end
i += 1
end
return "not found"
end
def sendIndex(token)
response = getItems(token)
index = getIndex(response)
params = {'token' => token, 'needle' => index}
request = Net::HTTP::Post.new("/api/validateneedle")
end
sendIndex(token)
The error message is self-explanatory: on line 59, you are passing the argument token to the method sendIndex, but token isn't defined, neither as a method nor as a local variable.
I'm using Celluloid IO to read from sockets. The incoming message has the following syntax
sometextsometextsometext
where
SOH = Hex 1
FS = Hex 1C
STX = Hex 2
ETX = Hex 3
EOT = Hex 4
My read code is something like this -
message = ""
begin
data = socket.readpartial(4096)
message << data
end until message =~ /not sure what goes here/
I'm looking for a reliable way to read from the socket until EOT. Once the message is read, i'll regex out the relevant sections.
Some guidance on detecting the above mentioned hex characters in socket read stream and in regex would be very helpful. Guidance?
And this does the trick for me thanks
def parse(message)
if message =~ /\001(.*)\01C(.*)\002(.*)\003\004/
return ($1,$2,$3)
end
end
def read_until_eot(socket)
eot_found = false
message = ''
begin
data = socket.read()
eot_found = !!data['\004']
message << data
end until eot_found
message.chomp!
end
def handle_connection(socket)
# read from socket until EOT
message = read_until_eot(socket) # <-- need help with
if (origin,target,payload) = parse(message) #message can be parsed
# process message
output_message = process(payload)
end
# write to socket
socket.write output_message
# close socket
socket.close
end
I am using the Mongo Ruby driver and have this block of Ruby code before and after line 171 in my code, which is apparently the source of the error below it (the query.each line is line 171):
query = get_callback.call( "databases", id )
if query.count > 0
puts query.count.inspect + " results: " + query.inspect
res = {}
query.each do |result|
puts result.inspect
end
else
puts "No results" + res.inspect
res = {}
end
The error:
1 results: <Mongo::Cursor:0x3fc15642c154 namespace='myproj.databases' #selector={"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')} #cursor_id=>
TypeError - can't convert Mongo::Cursor into Integer:
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `pack'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `put_int'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:603:in `construct_query_message'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:466:in `send_initial_query'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:459:in `refresh'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:128:in `next'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:291:in `each'
/Users/myuser/Code/myproj/my_file.rb:171:in `block in initialize'
My query object: {"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')}
I have not the faintest idea what's causing this. I've verified the object I'm finding exists and the query.count shows that there's a result in my Mongo::Cursor.
I've not found any examples of the issue on Google and every Mongo/Ruby on the web I've found uses an each iterator just like I do. Anyone know what's the cause of this error? I notice I also get it when trying to use to_a to cast the collection to a JSON-usable object.
For what it's worth, here's the relevant part of byte_buffer.rb is below. The line with << is line 156.
def put_int(i, offset=nil)
#cursor = offset if offset
if more?
#str[#cursor, 4] = [i].pack(#int_pack_order)
else
ensure_length(#cursor)
#str << [i].pack(#int_pack_order)
end
#cursor += 4
end
This happens when you pass nil to a Ruby Mongo driver limit() method.