Why I cannot set the value of this hash key? - ruby

task = {:project=>1000,
:order=>0,
:partial_image=>nil,
:options=>{
:height=>50,
:width=>50,
:start_row=>1,
:start_column=>1,
:end_row=>50,
:end_column=>50,
:scene=>0}}
project = redis.hget('active_projects', task[:project])
=>
{:name=>"Pov",
:tasks=>
{0=>
{:project=>1000,
:order=>0,
:partial_image=>nil,
:options=>
{:height=>50,
:width=>50,
:start_row=>1,
:start_column=>1,
:end_row=>50,
:end_column=>50,
:scene=>"blabla"
}
}
},
:id=>1000,
:image=>"",
:options=>
{:height=>100,
:width=>50,
:scene=>"blabla"
}
}
task[:partial_image] = 'blablabla'
project[:tasks][task[:order]] = task # this is line 37
Failure/Error: completed_task = DPovray::Task.perform(task)
TypeError:
can't convert Symbol into Integer
# ./lib/jobs/job.rb:37:in `[]'
# ./lib/jobs/job.rb:37:in `block in perform'
# ./lib/jobs/job.rb:35:in `perform'
# ./spec/task_spec.rb:22:in `block (4 levels) in <top (required)>'
The code is in https://github.com/Nerian/DPovray
The test that fails can be run with rspec spec/task_spec.rb

Actually project = redis.hget('active_projects', task[:project]) is returning a string, not a ruby hash. So that is why it fails.
I am playing with https://github.com/nateware/redis-objects to see if I can do what I want to do.
Also, instead of doing:
Redis.new.hset('active_projects', active_project[:id], active_project)
You can do:
Redis.new.hset('active_projects', active_project[:id], Marshal.dump(active_project))
And it just works, thanks to hash marshaling.
Nonetheless, I do not consider this a good solution. I don't like to use Marshaling as it is much difficult do debug by looking at the database.
Also I just got a:
incompatible marshal file format (can't be read)
format version 4.8 required; 123.58 given
So let us discover a different approach...
edit:
Now I am playing with JSON.dump and JSON.parse. They seem a better approach.
Edit:
I ended up encapsulating this hash into a real object. So I have Project class and a Task class. In each one I define the methods to_json and self.json_create(o) to that they can be convert to and from JSON.
It works quite well.

Related

How to specify time for youtube api in ruby

I'm writing Ruby script to communicate with Youtube Streaming API to create live stream and live broadcast. So far, I have been able to write code to insert new stream and it works but I'm facing problem while inserting broadcast. I'm getting the following error:
/usr/local/rvm/gems/ruby-2.3.0/gems/google-api-client-0.8.0/lib/google/api_client.rb:652:in `block (2 levels) in execute!': Scheduled start time is required (Google::APIClient::ClientError)
from /usr/local/rvm/gems/ruby-2.3.0/gems/retriable-1.4.1/lib/retriable/retry.rb:27:in `perform'
from /usr/local/rvm/gems/ruby-2.3.0/gems/retriable-1.4.1/lib/retriable.rb:15:in `retriable'
from /usr/local/rvm/gems/ruby-2.3.0/gems/google-api-client-0.8.0/lib/google/api_client.rb:635:in `block in execute!'
from /usr/local/rvm/gems/ruby-2.3.0/gems/retriable-1.4.1/lib/retriable/retry.rb:27:in `perform'
from /usr/local/rvm/gems/ruby-2.3.0/gems/retriable-1.4.1/lib/retriable.rb:15:in `retriable'
from /usr/local/rvm/gems/ruby-2.3.0/gems/google-api-client-0.8.0/lib/google/api_client.rb:626:in `execute!'
from ruby_script.rb:44:in `insert_broadcast'
from ruby_script.rb:98:in `<main>'
So, its complaining that I haven't mentioned the scheduled start time. Here's the relevant code:
# Create a liveBroadcast resource and set its title, scheduled start time,
# scheduled end time, and privacy status.
def insert_broadcast(client, youtube, options)
insert_broadcast_response = client.execute!(
api_method: youtube.live_broadcasts.insert,
parameters: {
part: 'snippet,status'
},
body_object: {
snippet: {
title: options[:broadcast_title],
scheduledStartTime: options[:state_time],
scheduledEndTime: options[:end_time]
},
status: {
privacyStatus: options[:privacy_status]
}
}
)
p "Broadcast: #{insert_broadcast_response.data.id}"
return insert_broadcast_response.id
end
options = {
stream_title: 'stream',
broadcast_title: 'dumdum',
start_time: '2018-01-30T00:00:00.000Z',
end_time: '2018-01-30T00:01:00.000Z',
privacy_status: 'private'
}
The format of date time I have borrowed from this code sample which is in Python. I tried with start_time: Time.now hoping Ruby date time object might work but it didn't. How do I solve this?
Edit: Here's the complete script.
Fix the typo as per #Simple-Lime's answer, and if its still doesn't work try the following:
You need to format your time correctly:
Time.now output is 2017-07-27 07:35:38 +0000 which is wrong.
You need to change it to datetime format of ISO-8601 standard with decimal notation of the timezone with Time#iso8601:
require 'time'
# example time format: '2014-01-30T00:00:00.000Z'
Time.now.getutc.iso8601(3)
# => "2017-07-27T07:30:33.742Z"
In your code you have scheduledStartTime: options[:state_time], and are passing it into the method as options[:start_time]

issues with executing cablint-ct part of certlint tool

I am attempting to run the tool certlint, specifically the module called cablint-ct but when we try we get errors. There are three modules, certlint, cablint and cablint-ct -- all of which work except for cablint-ct.
Here is the command I am running in ruby:
ruby -I "/certlint-master/lib" "/certlint-master/bin/cablint-ct" "cert.der"
Here is the error I receive:
/certlint-master/lib/certlint/ct.rb:149:in `initialize': undefined method `+' for nil:NilClass (NoMethodError)
from /certlint-master/bin/cablint-ct:39:in `new'
from /certlint-master/bin/cablint-ct:39:in `<main>'
Here is the referring block of code in ct.rb (line 39):
30 def initialize(tbs_der)
31 asn = OpenSSL::ASN1.decode(tbs_der)
32 # tbsCertificate.version is optional, so we don't have a fixed
33 # offset. Check if the first item is a pure ASN1Data, which
34 # is a strong hint that it is an EXPLICIT wrapper for the first
35 # element in the struct. If so, this is the version, so everything
36 # is offset by one.
37 skip = asn.value[0].instance_of?(OpenSSL::ASN1::ASN1Data) ? 1 : 0
38 sig_alg_der = asn.value[1 + skip].to_der
39 #raw = OpenSSL::ASN1::Sequence.new([tbs_der, sig_alg_der, DER_SIG]).to_der
40 super(#raw)
41 end
42 end
and ct.rb (line 149)
148 def initialize(log)
149 #log = URI.parse(log + '/').normalize
150 end
I've opened an issue #37 on github with the owner of the tool but have not seen a response as of yet.
Will be grateful if someone can see if i am doing something wrong with my command or is there a coding issue somewhere?
UPDATE 1
I have figured that I need to be passing a URL into the command rather then a cert file. For example:
ruby -I "/certlint-master/lib" "/certlint-master/bin/cablint-ct" "https://ct.ws.symantec.com/ct/v1/get-entries?start=932966&end=932966"
I believe the code expect a JSON response from this URL and this link returns a file with JSON data, however, I get the following error:
/usr/share/ruby/json/common.rb:155:in `initialize': A JSON text must at least contain two octets! (JSON::ParserError)
from /usr/share/ruby/json/common.rb:155:in `new'
from /usr/share/ruby/json/common.rb:155:in `parse'
from /certlint-master/lib/certlint/ct.rb:184:in `_call'
from /certlint-master/lib/certlint/ct.rb:160:in `get_entries'
from /certlint-master/bin/cablint-ct:40:in `<main>'
Any ideas?
resolved, the command expects a known ct log url and index id e.g.
ruby -I "/certlint-master/lib" "/certlint-master/bin/cablint-ct" "https://ct.ws.symantec.com" 173977
or
ruby -I "/certlint-master/lib" "/certlint-master/bin/cablint-ct" "symantec" 173977

Ruby: add new fields to YAML file

I've been searching around for a bit and couldn't find anything that really helped me. Especially because sometimes things don't seem to be consistant.
I have the following YAML that I use to store data/ configuration stuff:
---
global:
name: Core Config
cfg_version: 0.0.1
databases:
main_database:
name: Main
path: ~/Documents/main.reevault
read_only: false
...
I know how to update fields with:
cfg = YAML.load_file("test.yml")
cfg['global']['name'] = 'New Name'
File.open("test.yml", "w"){ |f| YAML.dump(cfg, f) }
And that's essentially everybody on the internet talks about. However here is my problem: I want to dynamically be able to add new fields to that file. e.g. under the "databases" section have a "secondary_db" field with it's own name, path and read_only boolean. I would have expected to do that by just adding stuff to the hash:
cfg['global']['databases']['second_db'] = nil
cfg['global']['databases']['second_db']['name'] = "Secondary Database"
cfg['global']['databases']['second_db']['path'] = "http://someurl.remote/blob/db.reevault"
cfg['global']['databases']['second_db']['read_only'] = "true"
File.open("test.yml", "w"){ |f| YAML.dump(cfg, f) }
But I get this error:
`<main>': undefined method `[]=' for nil:NilClass (NoMethodError)
My question now is: how do I do this? Is there a way with the YAML interface? Or do I have to write stuff into the file manually? I would prefer something via the YAML module as it takes care of formatting/ indentation for me.
Hope someone can help me.
Yo have to initialize cfg['global']['database']['second_db'] to be a hash not nil. Try this cfg['global']['database']['second_db'] = {}

MongoDB Ruby driver and mongoS

I am trying to use the MongoDB Ruby driver to pull information from a cluster via mongoS. Here is what I've done.
#mongo_client = Mongo::Connection.new('mongoshost', 27320)
#db = #mongo_client.db("thedatabase")
#auth = #db.authenticate("username", "password")
if(#mongo_client)
print "Successfully connected to mongos\n"
else
print "Connection failed"
end
if(#auth == true)
print "Auth successful\n"
else
print "Auth failed"
end
collection = #db.collection("thecollection")
puts collection.find.to_a
When I run this, everything works up until the point that it tries to print the documents in the collection. Here's what my output looks like:
C:\Code\whatever>ruby getdata.rb
Successfully connected to mongos
Auth successful
C:/Ruby200/lib/ruby/gems/2.0.0/gems/bson-1.9.2/lib/bson/bson_c.rb:24:in `deseria
lize': time must be positive (ArgumentError)
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/bson-1.9.2/lib/bson/bson_c.rb:2
4:in `deserialize'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/networkin
g.rb:223:in `read_documents'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/networkin
g.rb:169:in `receive'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/networkin
g.rb:133:in `receive_message'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:497:in `block in send_initial_query'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/util/logg
ing.rb:55:in `block in instrument'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/util/logg
ing.rb:20:in `instrument'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/util/logg
ing.rb:54:in `instrument'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:493:in `send_initial_query'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:478:in `refresh'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:124:in `next'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:290:in `each'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:314:in `to_a'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/mongo-1.9.2/lib/mongo/cursor.rb
:314:in `to_a'
from getdata.rb:27:in `<main>'
The "time must be positive" error had a few search results, but nothing that helped me figure out what the issue is. One of the fields in these documents does hold a negative number for a date, but I'm not sure why that's an issue since it's reading it and not writing (For example, one of the fields looks like so: {"md" : Date(-62135596800000)})
Is this an issue with the driver, is my code bad, or do I need to figure this out in another manner? I'm pretty new to ruby so any help would be appreciated!
Your data is bad as you have already noted. The problem is that the driver is trying to expand the date value ( which is really just a number internally to mongo within a BSON timestamp field ) into a real DateTime object.
When it tries to do this on read, the number is invalid an the inflation fails. If you fix the date value the problem will be corrected.
Note: If you do this in the shell use the ISOate helper to put a correct value in. If you use code then use a DateTime object. Don't use strings as you will mess your data up further.

How to ignore "invalid byte sequence in US-ASCII" with AptanaStudio Ruby Debugger?

I'm not good English speaker, so please forgive my English problem.
I am using AptanaStudio 3 with Ruby 1.9.2 in Windows 7.
When I try to use Win32 memcpy to get string data from shared memory in ruby debugger, this problem occurs.
# encoding: utf-8
require 'windows/file_mapping'
require 'windows/msvcrt/buffer'
require 'windows/handle'
include Windows::FileMapping
include Windows::MSVCRT::Buffer
include Windows::Handle
buf1 = 0.chr * 256
#mh = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "TAG_NAME")
#address = MapViewOfFile(#mh, FILE_MAP_ALL_ACCESS, 0, 0, 0)
memcpy(buf1, #address, 256)
UnmapViewOfFile(#address)
CloseHandle(#mh)
puts buf1.unpack("Z*")
The problem is below
c:/Ruby192/lib/ruby/1.9.1/syck/rubytypes.rb:151:in `count'
c:/Ruby192/lib/ruby/1.9.1/syck/rubytypes.rb:151:in `is_binary_data?'
C:/Users/Zenbook/SkyDrive/AptanaStudio/workspace/best_practice/test.rb:19:in `<top (required)>'
c:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_load'
c:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_program'
c:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-debug-ide-0.4.16/bin/rdebug-ide:87:in `<top (required)>'
c:/Ruby192/bin/rdebug-ide:19:in `load'
c:/Ruby192/bin/rdebug-ide:19:in `<main>'
Uncaught exception: invalid byte sequence in US-ASCII
It doesn't occur when I don't use any breakpoint after memcpy or I just get only string length. I mean, when char string size is 256 ,char string length is 12 and I just get 12 bytes, the problem doesn't occur.
I think this is because debugger cannot read the text from char string including uninitialized place.
So I want to ignore the error or allow string to have invalid text.
Would anyone help me?

Resources