I am using this example for file uploader.
Now it works this way:
I upload a file, after the file is saved,the function(do_picture_analyse) calls R and produces a histogram(simplest version, in the more complicated version 2 packages have to be installed in R), picture of the histogram is saved. The problem is that if I want to upload 50 files, it takes lots of time to load 2 packages in R for each file separately(after_save callback).
What I need:
I upload a file, file is saved, I click on a button “Histogram” and the function do_picture analyses is called on all files that are in the database( It doesnt matter if some of the files have already been analyzed)
So I need only to know how to make an interaction between a button and a call of the function and nothing more.
My show.html.erb:
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download fade">
<td></td>
<td class="name">
<a href="{%=file.url%}" download="{%=file.name%}">{%=file.name%}</a>
</td>
<td class="nam">
<a href="{%=file.url_chip_image%}" download="{%=file.name%}">{%=file.name%}</a>
</td>
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
<td class="Pic">
<button class="btn btn-mini btn-info">Pic</button>
</td>
<td class="Hist">
<button class="btn btn-mini btn-primary" >Hist</button>
</td>
<td class="delete">
<button class="btn btn-mini btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
<i class="icon-trash icon-white"></i>
</button>
<input type="checkbox" name="delete" value="1">
</td>
</tr>
{% } %}
</script>
my upload.rb:
def to_jq_upload
{
"name" => (read_attribute(:upload_file_name)).split(".").first,
"size" => read_attribute(:upload_file_size),
"url" => upload.url(:original),
"delete_url" => upload_path(self),
"delete_type" => "DELETE",
"url_chip_image"=>read_attribute(:chip_image),
}
end
after_save :do_picture_analyse
def do_picture_analyse
if read_attribute(:chip_image)==nil
require 'rinruby'
myr = RinRuby.new(echo=false)
myr.filepath=upload.path(:original)
myr.fileurl=upload.url(:original)
myr.eval <<EOF
s=read.table(filepath)
for(j in nchar(filepath):1){
if(substr(filepath,j,j)=="/"){
savepath<-substr(filepath,1,j-1)
file.name<-filepath
file.name<-substr(file.name,j+1,nchar(filepath)-4)
break
}
}
file.name1<-paste(file.name,"image.jpeg",sep="_")
savepath<-paste(savepath,file.name1,sep="/")
jpeg(filename=savepath,width=250, height=250)
hist(s$V1)
dev.off()
EOF
self.update_attributes(
:chip_image => (((myr.fileurl).split("?").first)[6..-5]+'_image.jpeg')
)
end
end
EDIT:
do_picture_analyse can take a folder as a parameter and analyse all files inside it by loading the the packages only one time for entire folder.There are only two folders for the files(two different types of files, let say .txt and .blabla files will be saved either in the txt-Folder or in a blabla-Folder. The type of the folder is saved in the database as well. By clicking the button, two folders should be passed to the do_picture_analyse and it will do everything
Thanks in advance
you need to create a new route for this :
then create a new action on your controller :
you can then link your button to your action :
PS: if your method needs a lot of processing power (if you use R, i assume that you have complex calculations involved), you should consider to extract it in a Worker to run it as a background task.
edit
response to your comments :
i think you should extract this method and make it a class method, that accepts one or more paths.
Then create a collection route that points to your controller ; in your controller action load the files according to some params and does something like this :
It is even possible to create a class methods that automatically handles these two steps for all files in a relation :
then you can do :