How to generate content in yml file with this format:
required_groups:
- ["member", "cn=serviceboard-users,cn=groups,cn=accounts,dc=int,dc=dostack,dc=io"]
Instead of this format:
required_groups:
- - member
- cn=serviceboard-users,cn=groups,cn=accounts,dc=int,dc=dostack,dc=io
Input:
[["member", "cn=serviceboard-users,cn=groups,cn=accounts,dc=int,dc=dostack,dc=io"]]
Current Code:
File.open("config/ldap/#{Rails.env}.yml", "w") do |file|
data = {}
formatted_groups_array = []
Setting.ldap_users_filter_required_groups.each { |group| formatted_groups_array.push([Setting.ldap_group_membership_attribute.to_s, group.to_s])}
data["required_groups"] = formatted_groups_array
file.write(data.to_yaml)
end
As stated in this answer, the default ruby library Psych does not have many options available, and you cannot customize the output the way you are trying to do.
In the meantime I've found an old possibile custom solution to your problem, but I had to rewrite a small part of it to make it compatible to the most recent ruby version (I am using 2.7.0 for this example). This is my updated script. Basically it will introduce a new way to edit the YAML output using a more concise syntax.
You can use it this way:
File.open("config/ldap/#{Rails.env}.yml", "w") do |file|
data = {}
formatted_groups_array = []
Setting.ldap_users_filter_required_groups.each { |group| formatted_groups_array.push([Setting.ldap_group_membership_attribute.to_s, group.to_s])}
data["required_groups"] = formatted_groups_array
styled_yaml = StyledYAML.inline(data)
file.write(StyledYAML.dump(styled_yaml))
end
Related
I'm trying to use a groovy Config entry to parse an xml file with XmlSlurper.
Here's the Config file:
sample {
xml {
frompath = "Email.From"
}
}
Here's the XML
<xml>
<Email>
<From>
<Address>foo#bar.com</Address>
<Alias>Foo Bar</Alias>
</From>
<Email>
</xml>
This is what I tried initially:
XmlSlurper slurper = new XmlSlurper()
def record = slurper.parseText((new File("myfile.xml")).text)
def emailFrom = record?."${grailsApplication.config.sample.xml.frompath}".Address.text()
This doesn't work because XmlSlurper allows one to use special characters in path names as long as they're surrounded by quotes, so the app is translating this as:
def emailFrom = record?."Email.From".Address.text()
and not
def emailFrom = record?.Email.From.Address.text()
I tried setting the frompath property to be "Email"."From" and then '"Email"."From"'. I tried tokenizing the property in the middle of the parse statement (don't ask.)
Can someone please point me towards some resources to find out if/how I can do this?
I feel like this issue getting dynamic Config parameter in Grails taglib and this https://softnoise.wordpress.com/2013/07/29/grails-injecting-config-parameters/ may have whispers of a solution, but I need fresh eyes to see it.
The solution in issue getting dynamic Config parameter in Grails taglib is a proper way to deref down such a path. E.g.
def emailFrom = 'Email.From'.tokenize('.').inject(record){ r,it -> r."$it" }
def emailFromAddress = emailFrom.Address.text()
If your path there can get complex and you rather go with the potentially more dangerous way, you could also use Eval. E.g.
def path = "a[0].b.c"
def map = [a:[[b:[c:666]]]] // dummy map, same as xmlslurper
assert Eval.x(map, "x.$path") == 666
I'm a rails newb - in a little over my head and could use some help.
I have an existing rails app, and I'm trying to integrate the Amazon Products API with the gem "ruby-aaws"....i.e., place items inside a model, show them in the view, etc.
I've never worked with an external API before, so I'm not sure where to begin to start integration. Any help at all is much appreciated!
Here is some of the code that I've used to pull data with the API:
require 'amazon/aws'
require 'amazon/aws/search'
include Amazon::AWS
include Amazon::AWS::Search
is = ItemSearch.new( 'Watches', { 'Keywords' => 'Gucci' } )
rg = ResponseGroup.new( 'Large' )
req = Request.new
req.locale = 'us'
resp = req.search( is, rg )
items = resp.item_search_response[0].items[0].item
# Available properties for first item:
#
puts items[0].properties
items.each do |item|
attribs = item.item_attributes[0]
puts attribs.label
if attribs.list_price
puts attribs.title, attribs.list_price[0].formatted_price, item.medium_image, ''
end
end
I am also a newbie and trying to do something similar. I found this example on GitHub that looks really promising.
https://github.com/hundredwatt/Amazon-Product-Search-Example
But there are also some great related questions here that have answers for you:
Ruby Amazon book search
Good luck!
I have found several websites pointing to using the following code to add support for custom parameter formats:
ActionController::Base.param_parsers[Mime::PLIST] = lambda do |body|
str = StringIO.new(body)
plist = CFPropertyList::List.new({:data => str.string})
CFPropertyList.native_types(plist.value)
end
This one here is for the Apple plist format, which is what I am looking to do. However, using Rails 3.2.1, The dev server won't start, saying that param_parsers is undefined. I cannot seam to find any documentation for it being deprecated or any alternative to use, just that it is indeed included in the 2.x documentation and not the 3.x documentation.
Is there any other way in Rails 3 to support custom parameter formats in POST and PUT requests?
The params parsing moved to a Rack middleware. It is now part of ActionDispatch.
To register new parsers, you can either redeclare the use of the middleware like so:
MyRailsApp::Application.config.middleware.delete "ActionDispatch::ParamsParser"
MyRailsApp::Application.config.middleware.use(ActionDispatch::ParamsParser, {
Mime::PLIST => lambda do |body|
str = StringIO.new(body)
plist = CFPropertyList::List.new({:data => str.string})
CFPropertyList.native_types(plist.value)
end
})
or you can change the constant containing the default parsers like so
ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime::PLIST] = lambda do |body|
str = StringIO.new(body)
plist = CFPropertyList::List.new({:data => str.string})
CFPropertyList.native_types(plist.value)
end
The first variant is probably the cleanest. But you need to be aware that the last one to replace the middleware declaration wins there.
I have a structure from a data source that's not providing an ftp source (ie, I can't simply walk the folder structures so easily as I would with net/ftp) so I'm having to parse each http file list (the default apache generated folder browse html) , then descend, rinse and repeat until at the floor level that contains the files to harvest out into a more appropriate file hierarchy.
I feel that I could probably use mechanize along with nokogiri to do something much more efficient. Could you provide and example of what would work better in this scenario?
Presently I'm doing something like:
doc = Nokogiri::HTML(open("some_base_url"))
link_list = []
doc.xpath('//a').each do |node|
unless node.text =~ /Name|Last modified|Size|Description|Parent Directory/
link_list.push(url + node.text)
end
end
link_list.each do |sub_folder_url|
doc = Nokogiri::HTML(open(sub_folder_url))
# ... rinse and repeat until at the bottom level with files, then we have all file urls to pull
end
output_path = []
url_list.each do |url|
filepath_elements = url.split('/')
filename_elements = filepath_elements.last.split('_.')
date = filename_elements[0]
time = filename_elements[1]
detail = filename_elements[2]
data_type_and_filetype = filename_elements[3].split('.')
data_type = data_type_and_filetype[0]
file_type = data_type_and_filetype[1]
output_path = [date, time, resoution, lense_type] * '_' + '.' + file_type
end
# pull in all final_urls_to_retrieve to it's respective new output_path[location_in_final_urls_to_retrieve]
I need to load a yaml file into Hash,
What should I do?
I would use something like:
hash = YAML.load(File.read("file_path"))
A simpler version of venables' answer:
hash = YAML.load_file("file_path")
Use the YAML module:
http://ruby-doc.org/stdlib-1.9.3/libdoc/yaml/rdoc/YAML.html
node = YAML::parse( <<EOY )
one: 1
two: 2
EOY
puts node.type_id
# prints: 'map'
p node.value['one']
# prints key and value nodes:
# [ #<YAML::YamlNode:0x8220278 #type_id="str", #value="one", #kind="scalar">,
# #<YAML::YamlNode:0x821fcd8 #type_id="int", #value="1", #kind="scalar"> ]'
# Mappings can also be accessed for just the value by accessing as a Hash directly
p node['one']
# prints: #<YAML::YamlNode:0x821fcd8 #type_id="int", #value="1", #kind="scalar">
http://yaml4r.sourceforge.net/doc/page/parsing_yaml_documents.htm
You may run into a problem mentioned at this related question, namely, that the YAML file or stream specifies an object into which the YAML loader will attempt to convert the data into. The problem is that you will need a related Gem that knows about the object in question.
My solution was quite trivial and is provided as an answer to that question. Do this:
yamltext = File.read("somefile","r")
yamltext.sub!(/^--- \!.*$/,'---')
hash = YAML.load(yamltext)
In essence, you strip the object-classifier text from the yaml-text. Then you parse/load it.