How can I use field selectors in the LinkedIn gem? - ruby

I have been trying to use the LinkedIn gem (0.3.6) to search. I can successfully authenticate and search with just keywords but I want to be able to use the field selectors so that my results contain more than just id, first name, last name.
I have been unsuccessful when doing what is in the spec
fields = [{:people => [:id, :first_name, :last_name, :public_profile_url, :picture_url]}, :num_results]
client.search(:first_name => 'Giliardi', :last_name => 'Pires', :fields => fields)
Has anyone been able to get this to work?

It seems that the gem client.search does not match the github client.search... and the spec is based on the github client.search. And to be honest I cannot figure out how to get it to work with the Gem search. They do not include a spec for search in the Gem example provided in the api_spec.rb (no search_spec) gives a 404: client.search(:first_name => "Javan", :fields => ["num_results", "total"])
My suggestion would to be build the gem from the github source and use the selectors.
Gem:
def search(options={})
path = "/people-search"
options = { :keywords => options } if options.is_a?(String)
if fields = options.delete(:fields)
path +=":(#{fields.map{ |f| f.to_s.gsub("_","-") }.join(',')})"
end
options = format_options_for_query(options)
result_json = get(to_uri(path, options))
Mash.from_json(result_json)
end
GitHub:
def search(options={})
path = "/people-search"
if options.is_a?(Hash)
fields = options.delete(:fields)
path += field_selector(fields) if fields
puts path
end
options = { :keywords => options } if options.is_a?(String)
options = format_options_for_query(options)
result_json = get(to_uri(path, options))
Mash.from_json(result_json)
end

Related

Chef delay attribute assignment via data bag

So i have a bit of a pickle.
I have an encrypted data bag to store LDAP passwords. In my node run list, one of my recipes installs the secret key onto my client machine.
In my problematic cookbook, i have a helper (in /libraries) that pulls data from AD (using LDAP). Problem is, i can't find a way to delay the assignment of my node attribute after initial compile phase.
Take this line of code as example :
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
Im trying to override an attribute by adding an array returned by my helper function "get_sam" which returns an array, but it needs to run AFTER the compile phase since the file "/etc/chef/secret/yp_chefserver" doesnt exist before the convergence of my runlist.
So my question : Is there a way to assign node attributes via data_bag_items during the execution phase?
Some things i've tried :
ruby_block 'attribution' do
only_if { File.exist?('/etc/chef/secret/yp_chefserver')}
block do
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
Chef::Log.warn("content of osAdminUser : #{node['yp_chefserver']['osAdminUser']}")
end
end
This doesn't work because the custom resource ruby_block doesn't have the method "data_bag_item". I've tried using lazy attributes in my "chef_server" custom resource, but same problem.
I also tried having the attribution done directly in my helper module, but since the helper module compiles before the exec phase, the file doesn't exist when it assigns the variable.
Here is the helper function in question should anyone wonder, it pulls the SamAccountName from LDAP to assign admin users to my chef server. :
module YpChefserver
module LDAP
require 'net-ldap'
#ldap
def get_ldap(ldap_password)
if #ldap.nil?
#ldap = Net::LDAP.new :host => "ADSERVER",
:port => 389,
:auth => {
:method => :simple,
:username => "CN=USERNAME,OU=East Service Accounts,OU=System Accounts,DC=ad,DC=ypg,DC=com",
:password => "#{ldap_password}"
}
end
#ldap
end
def get_ldap_users(ldap_password)
filter = Net::LDAP::Filter.eq("cn", "DevOps")
treebase = "dc=ad, dc=ypg, dc=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter) do |entry|
#puts "DN: #{entry.dn}"
entry.each do |attribute, values|
return values if attribute == :member
end
end
end
def get_sam(ldap_password)
samacc = Array.new
get_ldap_users(ldap_password).entries.each{ |elem|
y = elem.to_s.split(/[,=]/)
filter = Net::LDAP::Filter.eq("cn", y[1])
treebase = "OU=Support Users and Groups,OU=CGI Support,DC=ad,DC=ypg,DC=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter, :attributes => "SamAccountName") do |entry|
samacc << entry.samaccountname
end
}
return samacc
end
end
end
Turns out you can actually call it inside a ruby block, just by using the actual Chef call instead of the resource name, as follow :
ruby_block 'attributes' do
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap',"IO.read('/etc/chef/secret/yp_chefserver')")
end
end
Leaving this here for those who might need it
EDIT :
Here is final function using the code mentionned above to pull accounts from AD, using encrypted data bags to provide the password and to then pass those results to my node attributes, all during the execution phase :
ruby_block 'attributes' do
extend YpChefserver::LDAP
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
# Chef::Config[:encrypted_data_bag_secret] = '/etc/chef/secret/yp_chefserver'
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap')
node.override['yp_chefserver']['ldap_pw'] = dtbg['ldap_password']
userarray = Array.new
userarray.push("#{node['yp_chefserver']['osAdminUser']}")
get_sam("#{node['yp_chefserver']['ldap_pw']}").each { |i| userarray.push(i[0]) }
node.override['yp_chefserver']['authorized_users'] = userarray
node.override['yp_chefserver']['local_admin_pw'] = dtbg['local_admin_pw']
end
end

Nested Document error on ES Tire Gem Ruby

I'm using the Tire gem still to work with a 0.9 ES database.
I've got a model that looks like this:
class Influencer
include Tire::Model::Persistence
include Tire::Model::DynamicPersistence
document_type "influencer"
# profiles
property :profiles, :type => 'nested', :class => [Profile], :default => []
end
I've also got a Profile class that looks like this.
class Profile
include Tire::Model::Persistence
include Tire::Model::DynamicPersistence
document_type 'profile'
property :id, :index => :not_analyzed
property :username, :index => :not_analyzed
property :service, :index => 'keyword'
property :url, :index => :not_analyzed
property :score, :type => 'float', :index => :not_analyzed
end
Note I removed many fields.
So, when I blow away the index and recreate it for influencers, I get an empty index. On the first write, it creates the mapping below:
{"influencer"=>
{"properties"=>
{"data"=>{"type"=>"object"},
"demographics"=>{"type"=>"object"},
"domain_names"=>{"type"=>"string"},
"geographics"=>{"type"=>"object"},
"host_names"=>{"type"=>"string"},
"id"=>{"type"=>"string"},
"income_message_numbers"=>{"type"=>"object"},
"influencer_id"=>{"type"=>"string"},
"keyword_scores"=>{"type"=>"object"},
"keywords"=>{"type"=>"string"},
"manual"=>{"type"=>"boolean"},
"name"=>{"type"=>"string"},
"notes"=>{"type"=>"object"},
"profiles"=>
{"properties"=>
{"profile"=>
{"properties"=>
{"contributors_enabled"=>{"type"=>"boolean"},
"default_profile"=>{"type"=>"boolean"},
"description"=>{"type"=>"string"},
"favourites_count"=>{"type"=>"long"},
"followers_count"=>{"type"=>"long"},
"friends_count"=>{"type"=>"long"},
"id"=>{"type"=>"long"},
"lang"=>{"type"=>"string"},
"listed_count"=>{"type"=>"long"},
"location"=>{"type"=>"string"},
"name"=>{"type"=>"string"},
"profile_image_url"=>{"type"=>"string"},
"protected"=>{"type"=>"boolean"},
"service"=>{"type"=>"string"},
"statuses_count"=>{"type"=>"long"},
"url"=>{"type"=>"string"},
"username"=>{"type"=>"string"}}}}},
"project_profiles"=>{"type"=>"object"},
"project_statuses"=>{"type"=>"object"},
"project_tags"=>{"type"=>"object"},
"project_time_additions"=>{"type"=>"object"},
"reachable_via"=>{"type"=>"string"},
"share_counts"=>{"type"=>"object"},
"source_ids"=>{"type"=>"string"},
"sources"=>{"type"=>"string"}}}}
This is what the first hash that writes looks like. I THINK it looks correct, but I could very well be missing something.
{:name=>"DogeWire", :profiles=>[{"service"=>"twitter", "id"=>2465530645, "name"=>"DogeWire", "username"=>"DogeWire", "description"=>"Fast, safe, anonymous, wow", "location"=>"www.DogeWire.com", "protected"=>false, "followers_count"=>466, "friends_count"=>1990, "listed_count"=>2, "favourites_count"=>19, "statuses_count"=>8421, "lang"=>"en", "contributors_enabled"=>false, "profile_image_url"=>"http://pbs.twimg.com/profile_images/460517818555846656/-0Ibxod4_normal.jpeg", "url"=>"http://twitter.com/DogeWire", "default_profile"=>true, "time_zone"=>nil}], :source_ids=>["twitter:2465530645"], :sources=>["twitter"], :keywords=>["altcoin"], :reachable_via=>["twitter"], :tags=>[], :host_names=>["www.lill.com"], :domain_names=>["lill.com"], :id=>"74uF9cNfW6dYEa27kSg5ww", :influencer_id=>"74uF9cNfW6dYEa27kSg5ww"}
And, lastly, the query looks like:
site_influencers = Influencer.search(:page => 1, :per_page => 10) do
query do
nested :path => 'profiles' do
query do
boolean do
must { match 'profiles.service', 'twitter' }
end
end
end
end
end
I'm not sure what i'm missing on this. This is a ruby app.. no Rails (but has ActiveRecord, etc).
Any thoughts?

Ruby DataMapper::ImmutableError

get '/watch/:id' do |id|
#results = Twitchtvst.all( :fields => [:Twitchtv ],
:conditions => { :user_id => "#{id}" }
)
#p #results.inspect
#results.each do |result|
puts result.id
end
erb :mystream
end
I get this error message immutable resource cannot be lazy loaded. How do I fix this?
The Error message is:
DataMapper::ImmutableError at /watch/1
Immutable resource cannot be lazy loaded
According to the official documentation:
Note that if you don't include the primary key in the selected columns, you will not be able to modify the returned resources because DataMapper cannot know how to persist them. DataMapper will raise DataMapper::ImmutableError if you're trying to do so nevertheless.
I know that you are not modifying anything here but I think that the same rule applies for lazy loading. So I will suggest to try it like that:
#results = Twitchtvst.all( :fields => [:Twitchtv, :id],
:conditions => { :user_id => "#{id}" }
) ode here
Note the id as an additional field.

Formatting a cell as Text using the axlsx spreadsheet ruby gem?

I'm using the axlsx ruby gem to create Excel-compatible .xlsx files. I can't figure out how to override the cell type that is generated by it's automatic type detection. For Active Record model attributes of type string the gem is setting the Excel cell format to General, but I want it to use Text explicitly. That way I can avoid stripping leading zeros off of zip codes, etc.
Anybody know how to accomplish this?
You can override the type of data using the types option on add row.
Something like:
worksheet.add_row ['0012342'], :types => [:string]
Grab me on irc (JST) if you need any help getting that to work.
Best
randym
edit --
I've added an example for this to examples/example.rb in the repo.
wb.add_worksheet(:name => "Override Data Type") do |sheet|
sheet.add_row ['dont eat my zeros!', '0088'] , :types => [nil, :string]
end
https://github.com/randym/axlsx/blob/master/examples/example.rb#L349
format_code: '#' will work for you. Please find below code for reference.
def default_data_type_as_string
#xlsx_package = Axlsx::Package.new
#workbook = #xlsx_package.workbook
#worksheet = #workbook.add_worksheet(:name => "Introduction")
default_style = #workbook.styles.add_style({ format_code: '#' })
row_data_array = ['1', '2%', '3$']
#worksheet.add_row row_data_array, :style => [nil, default_style, nil]
#xlsx_package.serialize('default_data_type_as_string.xlsx')
end
For gem versions gem 'axlsx', '2.1.0.pre', gem 'axlsx_rails' in order to have the file columns in text type should specify both style and type
default_style = worksheet.styles.add_style({ format_code: '#' })
worksheet.add_row ['0012687'], :types => [:string], :style => [default_style]

Sinatra haml Select and Delete several files

I'm trying to delete several files based on a list but I'm having problems getting the params from the chekcbox's
This is my list.haml:
%form(method="post" action="/selection" enctype="multipart/form-data")
- #files.each do |file|
%br
%input{:type => "checkbox", :name => "checkbox[]", :value => "#{file}" }
=file
%br
%input(type='submit' value="Delete Selected Files")
Now, for now I was just trying to see what I get in params, so I can later deal with how to delete this list of files.
params.inspect
"Gives me" ≃> {"checkbox"=>["yet_another_file.txt", "file1", "file2"]}
But I can't figure out how do I put this into an Array so I can do something like
var.each do |c|
puts c
end
I tried var = params[:checkbox] but var is empty, does anyone now how can I do this?
Thanks
You should use var = params["checkbox"], since the params key is not a symbol, but a string.

Resources