How to access data within variable? Error: undefined method - ruby

Printing the contents of a variable gives me a bunch of data.
I want to access part of that data, but get an error.
I'm using Viewpoint::EWS and am successfully accessing the data I need.
calendaritems = folder.find_items({:folder_id => folder.folder_id, :calendar_view => {:start_date => sd.rfc3339(), :end_date => ed.rfc3339()}})
calendaritems.each do |event|
...
end
Printing the variable "event", I can see the data I need: "date_time_stamp" (or "appointment_reply_time").
#<Viewpoint::EWS::Types::CalendarItem:0x00005652b332dfa0
#ews_item=
:date_time_stamp=>{:text=>"2019-03-18T12:01:49Z"},
:appointment_reply_time=>{:text=>"2019-03-18T13:01:55+01:00"},
However, trying to access using "event.date_time_stamp" (or "event.appointment_reply_time") leads to the error
undefined method `date_time_stamp' for <Viewpoint::EWS::Types::CalendarItem:0x00005622f83c3d38> (NoMethodError)
Here's the code:
calendaritems = folder.find_items({:folder_id => folder.folder_id, :calendar_view => {:start_date => sd.rfc3339(), :end_date => ed.rfc3339()}})
calendaritems.each do |event|
if event.recurring?
puts "#{event.date_time_stamp} | #{(event.start-event.date_time_stamp).to_i} | #{event.organizer.email_address}"
if (event.start-event.date_time_stamp).to_i == reminderDays
executeSomething()
end
end
end
I'm looking through recurring appointments for a resource within a week. Since those will be silently dropped after a year, the plan is to set up a system to remind people that this will happen, so they can rebook the resource.
At first I tried using the creation date of the appointment (event.date_time_created), which works as expected, but then noticed, that people can update their appointments, thus resetting the 1 year timer.
That's why I also need the date of the last update.

The debug output you supplied says that event variable has an attribute "ews_item" and then it has a hash with an attribute "date_time_stamp", so try event.ews_item[:date_time_stamp]

Related

Google ad manager try to read revenue per hour fails on ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS

I have a simple script that fetch data from google ad manager.
Everything is working pretty fine, Now I am trying to read the same data but instead of date aggregation, I am trying by day and hour.
I get the following error:
AdManagerApi::V201905::ReportService::ApiException: [ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS # columns; trigger:'TOTAL_LINE_ITEM_LEVEL_CPM_AND_CPC_REVENUE']
My report query in ruby is:
# Create report query.
report_query = {
:date_range_type => 'CUSTOM_DATE',
:start_date => AdManagerApi::AdManagerDate.new(#ad_manager, start_date).to_h,
:end_date => AdManagerApi::AdManagerDate.new(#ad_manager, end_date).to_h,
:dimensions => ['DAY', 'HOUR', 'CUSTOM_CRITERIA'],
:columns => ['TOTAL_LINE_ITEM_LEVEL_CPM_AND_CPC_REVENUE']
}
I took the full example from here
I am pretty new with the google ad manager api, I will appreciate any suggestion.
Try removing CUSTOM_CRITERIA from the :dimensions list

Ruby : SoftLayer API : getPendingEvents fails to show many relational properties

I'm trying to make a softlayer API call using Ruby to see upcoming maintenance and the machines that may be effected by the maintenance. I have a few questions but I'm running into an issue seeing many of the relational properties documented here:
http://sldn.softlayer.com/reference/datatypes/SoftLayer_Notification_Occurrence_Event
Here is my simple program:
require 'rubygems'
require 'softlayer_api'
require 'pp'
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 99999999)
account = client['Account'].object_mask("mask[pendingEventCount]").getObject()
pending_event_count = account["pendingEventCount"]
current_time = Time.now.to_i
for i in 0..(pending_event_count/30.0).ceil - 1
list_of_pending_events = client['Account'].result_limit(i*30,30).object_mask("mask[id, startDate, endDate, recoveryTime, subject, summary]").getPendingEvents
for x in 0..list_of_pending_events.length - 1
start_time = DateTime.parse(list_of_pending_events[x]['startDate']).to_time.to_i
if start_time > current_time
pp list_of_pending_events[x]
end
end
end
The above works, but if I try to add a relational property to the mask, such as "impactedResources" it will fail saying that property does not belong to SoftLayer_Notification_Occurrence_Event. Can someone help explain why this, and many other, relational properties are not valid in the above call?
Also, two quick other questions on this topic:
1) Why do some of the results in getPendingEvents have start AND end times in the past? And why do some have a missing end time altogether? Notice I'm checking if the start time is greater than the current time as there seems to be old maintenance data in the results.
2) Am I taking the right approach for getting upcoming maintenance and figuring out machines that will be impacted? (Using getPendingEvents and then the 'impactedResources' property)
I used your code and I added the "impactedResources" to the object mask and it worked fine. You may be getting the issue, because your API user does not have enough permissions, I recomend you try with the master user.
regarding to your other questions:
1.- When I ran your code I got only 3 events whose startDate is greater than the current time, so it worked fine for me. If you still are getting that issue you can try using objectFilters.
require 'rubygems'
require 'softlayer_api'
require 'pp'
client = SoftLayer::Client.new(:username => user, :api_key => apikey, :timeout => 99999999)
object_filter = SoftLayer::ObjectFilter.new
object_filter.set_criteria_for_key_path('pendingEvents.startDate', 'operation' => 'greaterThanDate',
'options' => [{
'name' => 'date',
'value' => ['9/8/2016']
}])
list_of_pending_events = client['Account'].object_filter(object_filter).object_mask("mask[id, startDate, endDate, recoveryTime, subject, summary]").getPendingEvents
pp list_of_pending_events
2.- Yes, that approach wil work.
Regards

Ruby exception occurred: undefined method `localtime'

I am using logstash 2.1.3,I want to show the #timestamp field in my timezone, like "#timestamp" => "2015-03-09T04:24:29.718+08:00", I try to using ruby conversion in filter.
filter
{
ruby {
code => "event['#timestamp'] =
event['#timestamp'].localtime('+08:00')"
}
}
but i got the error msg as below,
Ruby exception occurred: undefined method `localtime' for "2016-04-29T00:40:51.926Z":LogStash::Timestamp {:level=>:error}
Any help is welcome to resolve this.
It looks like you're trying to call localtime on a String (the result of event['#timestamp'], and it should instead be called on a Time object. You'll need to parse that String into a Time object.
Check out this irb session:
> require 'date'
true
> fmt = '%Y-%m-%dT%H:%M:%S.%L%z'
"%Y-%m-%dT%H:%M:%S.%L%z"
> s = "2016-04-29T00:40:51.926Z"
"2016-04-29T00:40:51.926Z"
> localtime_as_string = DateTime.strptime(s,fmt).to_time.localtime('+08:00').strftime(fmt)
"2016-04-29T08:40:51.926+0800"
In your case, you could use:
require 'date'
fmt = '%Y-%m-%dT%H:%M:%S.%L%z'
s = event['#timestamp'].to_s
tz = '+08:00'
event['#timestamp'] = DateTime.strptime(s, fmt).to_time.localtime(tz).strftime(fmt)
On further examination, it looks from the output like event['#timestamp'] contains an instance of Logstash::Timestamp. I looked at that API (https://github.com/elastic/logstash/blob/master/logstash-core-event/lib/logstash/timestamp.rb) and it looks like there is a publicly accessible time method that I presume returns an instance of Time. If that is the case, then the above will not work but this may:
require 'date'
# For fmt you may also be able to use Logstash::Timestamp::ISO8601_STRFTIME
fmt = '%Y-%m-%dT%H:%M:%S.%L%z'
time = event['#timestamp'].time
tz = '+08:00'
event['#timestamp'] = time.localtime(tz).strftime(fmt)
However, are you sure you want to replace event['#timestamp']? Another approach would be to use it for display but not modify the original variable. This might be safer because if the variable is used elsewhere it will not be known which of the 2 it is.

PG::ERROR: another command is already in progress

I have an importer which takes a list of emails and saves them into a postgres database. Here is a snippet of code within a tableless importer class:
query_temporary_table = "CREATE TEMPORARY TABLE subscriber_imports (email CHARACTER VARYING(255)) ON COMMIT DROP;"
query_copy = "COPY subscriber_imports(email) FROM STDIN WITH CSV;"
query_delete = "DELETE FROM subscriber_imports WHERE email IN (SELECT email FROM subscribers WHERE suppressed_at IS NOT NULL OR list_id = #{list.id}) RETURNING email;"
query_insert = "INSERT INTO subscribers(email, list_id, created_at, updated_at) SELECT email, #{list.id}, NOW(), NOW() FROM subscriber_imports RETURNING id;"
conn = ActiveRecord::Base.connection_pool.checkout
conn.transaction do
raw = conn.raw_connection
raw.exec(query_temporary_table)
raw.exec(query_copy)
CSV.read(csv.path, headers: true).each do |row|
raw.put_copy_data row['email']+"\n" unless row.nil?
end
raw.put_copy_end
while res = raw.get_result do; end # very important to do this after a copy
result_delete = raw.exec(query_delete)
result_insert = raw.exec(query_insert)
ActiveRecord::Base.connection_pool.checkin(conn)
{
deleted: result_delete.count,
inserted: result_insert.count,
updated: 0
}
end
The issue I am having is that when I try to upload I get an exception:
PG::ERROR: another command is already in progress: ROLLBACK
This is all done in one action, the only other queries I am making are user validation and I have a DB mutex preventing overlapping imports. This query worked fine up until my latest push which included updating my pg gem to 0.14.1 from 0.13.2 (along with other "unrelated" code).
The error initially started on our staging server, but I was then able to reproduce it locally and am out of ideas.
If I need to be more clear with my question, let me know.
Thanks
Found my own answer, and this might be useful if anyone finds the same issue when importing loads of data using "COPY"
An exception is being thrown within the CSV.read() block, and I do catch it, but I was not ending the process correctly.
begin
CSV.read(csv.path, headers: true).each do |row|
raw.put_copy_data row['email']+"\n" unless row.nil?
end
ensure
raw.put_copy_end
while res = raw.get_result do; end # very important to do this after a copy
end
This block ensures that the COPY command is completed. I also added this at the end to release the connection back into the pool, without disrupting the flow in the case of a successful import:
rescue
ActiveRecord::Base.connection_pool.checkin(conn)

What is a dirty resource?

I just started using Datamapper.
I am trying to update an object. I get the object/model using its id:
u1 = User.get(1)
u1.name = "xyz"
u1.update
which throws a error/raises an exception. I tried again:
u1 = User.get(1)
and after that:
u1.update({:name => "xyz"})
will throw false and dirty? returns true.
After that any call to update would fail saying it is dirty.
I can do a save by:
u1.name = "xyz"
u1.save
Here are my questions:
What should I be using: Save or update?
Should I say get(id) even to just change one field?
When should I use update? What is the syntax: user.update({ ....}) or user.name = "xyz"; user.update?
What is dirty?, and is it once I make a object dirty do I have to
get the object fresh from the database to the variable?
When you fetched a resource from the db and then changed its attributes then the resource becomes 'dirty'. This means that the resource is loaded into memory and its state has changed and changes can be persisted in the db.
You use #save to persist changes made to a loaded resource and you use #update when you want to immediately persist changes without changing resource's state to 'dirty'. Here's an example session:
User.create(:name => 'Ted')
# update user via #save
user = User.get(1)
user.name = 'John'
user.dirty? # => true
user.save
# update user via #update
user = User.get(1)
user.update(:name => 'John')
user.dirty? # => false

Resources