Remove part of file path in Ruby - ruby

I am are receiving an array as a variable
Is an example
["/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx", "/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf"]
The following statement creates this list:
<%= var(file_list_array).map{|file| "<li>#{File.basename(file)}</li>"}.join("\n")%>
MI201711200143.xlsx
MI201703030110.pdf
The following statement creates this list
<%= var(file_list_array).map{|file| "<li>#{file}</li>"}.join("\n")%>
/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx
/a/b/01_Sources/02_Transferred/06_CPAS/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf
But what I would really like:
/Redbull/from_MediaHouse/Transcripts/MI201711200143.xlsx
/Redbull/from_MediaHouse/Transcripts/MI201703030110.pdf
What do I need to change to get that ?

Assuming you have your array of file paths in an array you could do.
file_paths.map{|path| path.gsub(/.*(\/Redbull\/.*)/, $1) }
This will replace each item with whatever is below the "Redbull" directory
Alternatively if you didn't want to preprocess that list you could just put it in your display code, but that will make it less clear as to what you need to send the displaying logic.
<%= var(file_list_array).map{|file| "<li>#{file.gsub(/.*(\/Redbull\/.*)/, $1)}</li>"}.join("\n")%>

Try this
file_list_array[0].split("06_CPAS")[1]
assuming you want to split from "06_CPAS" . You can pass it as a variable too like this
split_str = "06_CPAS"
index = 0
file_list_array[index].split(split_str)[1]

Related

Ruby String to access an object attribute

I have a text file (objects.txt) which contains Objects and its attributes.
The content of the file is something like:
Object.attribute = "data"
On a different file, I am Loading the objects.txt file and if I type:
puts object.attribute it prints out data
The issue comes when I am trying to access the object and/or the attribute with a string. What I am doing is:
var = "object" + "." + "access"
puts var
It prints out object.access and not the content of it "data".
I have already tried with instance_variable_get and it works, but I have to modify the object.txt and append an # at the beginning to make it an instance variable, but I cannot do this, because I am not the owner of the object.txt file.
As a workaround I can parse the object.txt file and get the data that I need but I don't want to do this, as I want take advantage of what is already there.
Any suggestions?
Yes, puts is correctly spitting out "object.access" because you are creating that string exactly.
In order to evaluate a string as if it were ruby code, you need to use eval()
eg:
var = "object" + "." + "access"
puts eval(var)
=> "data"
Be aware that doing this is quite dangerous if you are evaluating anything that potentially comes from another user.

Printing this variable in smarty

I'm having an array $customPre. I want to print the element of the array "Please specify which fund". I am doing like this:
{$customPre.Please specify which fund}
But it's not working.
In this case you need to use PHP-like syntax that is similar to PHP: {$variable['key']}.
If In PHP you have:
$smarty->assign('customPre', array ('Please specify which fund' => 'This is value'));
In Smarty you need to use:
{$customPre['Please specify which fund']}
And the output for this will be:
This is value
I believe you cannot use in this case dot syntax ( {$customPre.Please specify which fund}) because it's probably looks for whitespaces in keys. Even adding quotes won't help.

Replacing scan by gsub in Ruby: how to allow code in gsub block?

I am parsing a Wiki text from an XML dump, for a string named 'section' which includes templates in double braces, including some arguments, which I want to reorganize.
This has an example named TextTerm:
section="Sample of a text with a first template {{TextTerm|arg1a|arg2a|arg3a...}} and then a second {{TextTerm|arg1b|arg2b|arg3b...}} etc."
I can use scan and a regex to get each template and work on it on a loop using:
section.scan(/\{\{(TextTerm)\|(.*?)\|(.*?)\}\}/i).each { |item| puts "1=" + item[1] # arg1a etc.}
And, I have been able to extract the database of the first argument of the template.
Now I also want to replace the name of the template "NewTextTerm" and reorganize its arguments by placing the second argument in place of the first.
Can I do it in the same loop? For example by changing scan by a gsub(rgexp){ block}:
section.gsub!(/\{\{(TextTerm)\|(.*?)\|(.*?)\}\}/) { |item| '{{NewTextTerm|\2|\1}}'}
I get:
"Sample of a text with a first template {{NewTextTerm|\\2|\\1}} and then a second {{NewTextTerm|\\2|\\1}} etc."
meaning that the arguments of the regexp are not recognized. Even if it worked, I would like to have some place within the gsub block to work on the arguments. For example, I can't have a puts in the gsub block similar to the scan().each block but only a string to be substituted.
Any ideas are welcome.
PS: Some editing: braces and "section= added", code is complete.
When you have the replacement as a string argument, you can use '\1', etc. like this:
string.gsub!(regex, '...\1...\2...')
When you have the replacement as a block, you can use "#$1", etc. like this:
string.gsub!(regex){"...#$1...#$2..."}
You are mixing the uses. Stick to either one.
Yes, changing the quote by a double quote isn't enough, #$1 is the answer. Here is the complete code:
section="Sample of a text with a first template {{TextTerm|arg1a|arg2a|arg3a...}} and then a second {{TextTerm|arg1b|arg2b|arg3b...}} etc."
section.gsub(/\{\{(TextTerm)\|(.*?)\|(.*?)\}\}/) { |item| "{{New#$1|#$3|#$2}}"}
"Sample of a text with a first template {{NewTextTerm|arg2a|arg3a...|arg1a}} and then a second {{NewTextTerm|arg2b|arg3b...|arg1b}} etc."
Thus, it works. Thanks.
But now I have to replace the string, by a "function" returning the changed string:
def stringreturn(arg1,arg2,arg3) strr = "{{New"+arg1 + arg3 +arg2 + "}}"; return strr ; end
and
section.gsub(/\{\{(TextTerm)\|(.*?)\|(.*?)\}\}/) { |item| stringreturn("#$1","|#$2","|#$3") }
will return:
"Sample of a text with a first template {{NewTextTerm|arg2a|arg3a...|arg1a}} and then a second {{NewTextTerm|arg2b|arg3b...|arg1b}} etc."
Thanks to all!
There is probably a better way to manipulate arguments in MediaWiki templates using Ruby.

Extract the filepath from this ruby string

I am using the ruby Dir method to get all the filenames within a directory. Like this:
dir_files = Dir["/Users/AM/Desktop/07/week1/dailies/regionals/*.csv"]
This gives me an array with each element listed below:
/Users/AM/Desktop/07/week1/dailies/regionals/ch002.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch014.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch90.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch112.csv
/Users/AM/Desktop/07/week1/dailies/regionals/ch234.csv
Im trying to extract just the part of the above strings that matches: "regionals/*.csv"
How do I do that in Ruby?
The following didn't work
#files_array.each do |f|
f = f.split("/").match(/*.csv/)
i = f.include?(".csv")
puts "#{i.inspect}"
#self.process_file(f[i])
end
Whats a clever way of doing this? I intend to pass the returned string of each filename to a helper method for processing. But as you can see all the csv files are located in a different directory as my executing script.
My script thats executing this is located at
/Users/AM/Desktop/07/week1/dailies/myScript.rb
Thanks
This will always post back the final directory and file name, regardless of the file pattern:
#files_array.map { |f| f.split("/")[-2..-1].join("/") }
#=> ["regionals/ch002.csv", "regionals/ch014.csv", "regionals/ch90.csv", "regionals/ch112.csv", "regionals/ch234.csv"]
This gives you the desired values :)
dir_files.map {|path| path[/regionals\/.*.csv/]}
#=> ["regionals/ch002.csv", "regionals/ch014.csv", "regionals/ch90.csv", "regionals/ch112.csv", "regionals/ch234.csv"]

ruby block questions loop variables

comics = load_comics( '/comics.txt' )
Popup.make do
h1 "Comics on the Web"
list do
comics.each do |name, url|
link name, url
end
end
end
I am new to ruby. This is a piece of code from a ruby website.
I cant find what 'link' and 'list' keyword in the menu.
can someone explain it a little bit those two keywords, and where is the definition of those two keyword .
I am also confused on how they read the variables name and url, they are reading it by the space at the same line or what?
so if I have
Comics1 link_of_comics_site_1
Comics2 link_of_comics_site_2
Comics3 link_of_comics_site_3
so for the first iteration, name=Comics1, and url =link_of_comics_site_1
Thanks.
That's not just Ruby. That's a template for a webpage using ruby add-on methods for HTML generation.
But presumably, the result of the call to load_comics is a Hash, where the keys are names and the values are URLs. You could make one of those yourself:
my_comics_hash = { "name1" => "url1", "name2" => "url2" }
which you can then iterate over the same way:
my_comics_hash.each do |name, url|
puts "Name #{name} goes with URL #{url}"
end
In your code, it's building up an HTML list inside a popup window, but it's the same idea. The each method iterates over a collection - in this case a Hash - and runs some code on every item in that collection - in this case, each key/value pair. When you call each, you pass it a block of code inside do ... end; that's the code that gets run on each item. The current item is passed to the code block, which declares a variable to hold it inside the pipes right after the word do. Since we're iterating over key/value pairs, we can declare two variables, and the key goes in the first and the value in the second.
In ruby function, parenthesis is optional and the ";" end of statement is also optional. ej
link "click here" , "http://myweb.com"
is equivalent to :
link("click here", "http://myweb.com");
But If you have more than one statement in a line the ";" is a must, ej
link("click here1", "http://myweb.com"); link("click here2", "http://myweb.com");
In your code it could be written in
link(name, url)
or just
link(name, url);
or
link name, url
But it is highly recommended to put parenthesis around function parameters for readability unless you have other reason . The ";" is not common in ruby world .

Resources