Download xls file from application rails 4 - excel

I am using rails 4 application, where i have a xls file in my applications public folder ,and am having a link in view page after clicking that link that xls file should download to system.no need to write anything in that file its just a default template.
I use:
view:
<%= link_to "Dowload Template", admin_job_templates_path, :file_name => 'Job_Upload_Template.xlsx' %>
controller :
def index
require 'open-uri'
file_path = "#{Rails.root}/public/Job_Upload_Template.xlsx"
send_file file_path, :filename => "Job_Upload_Template.xlsx", :disposition => 'attachment'
end
also tried send_data method
def index
require 'open-uri'
url = "#{Rails.root}/public/Job_Upload_Template.xlsx"
data = open(url).read
send_data data, :filename =>'Job Template'
end
Am getting the below error.
No such file or directory # rb_sysopen -
/home/amp/workspace/LA_Tracker/public/Job_Upload_Template.xlsx
am not able to dowload the file, Plese help.

It's telling you that file doesn't exist. Do you have the capitalization correct? Double check. Also, what happens if you type:
ls /home/amp/workspace/LA_Tracker/public/Job_Upload_Template.xlsx
into the command line? Can your OS find the file?

Related

Python Glob - Get Full Filenames, but no directory-only names

This code works, but it's returning directory names and filenames. I haven't found a parameter that tells it to return only files or only directories.
Can glob.glob do this, or do I have to call os.something to test if I have a directory or file. In my case, my files all end with .csv, but I would like to know for more general knowledge as well.
In the loop, I'm reading each file, so currently bombing when it tries to open a directory name as a filename.
files = sorted(glob.glob(input_watch_directory + "/**", recursive=True))
for loop_full_filename in files:
print(loop_full_filename)
Results:
c:\Demo\WatchDir\
c:\Demo\WatchDir\2202
c:\Demo\WatchDir\2202\07
c:\Demo\WatchDir\2202\07\01
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_51.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_52.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_53.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_54.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_55.csv
c:\Demo\WatchDir\2202\07\05
c:\Demo\WatchDir\2202\07\05\polygonData_2022_07_05__12_00.csv
c:\Demo\WatchDir\2202\07\05\polygonData_2022_07_05__12_01.csv
Results needed:
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_51.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_52.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_53.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_54.csv
c:\Demo\WatchDir\2202\07\01\polygonData_2022_07_01__15_55.csv
c:\Demo\WatchDir\2202\07\05\polygonData_2022_07_05__12_00.csv
c:\Demo\WatchDir\2202\07\05\polygonData_2022_07_05__12_01.csv
For this specific program, I can just check if the file name contains.csv, but I would like to know in general for future reference.
Line:
files = sorted(glob.glob(input_watch_directory + "/**", recursive=True))
replace with the line:
files = sorted(glob.glob(input_watch_directory + "/**/*.*", recursive=True))

Django. TemporaryUploadedFile

I upload a file through the form, check it, and only after checking it I want to add it to my database.
form = BookForm(request.POST, request.FILES)
file = form.files
path = file.get('book_file').temporary_file_path()
in path - '/tmp/tmpbp4klqtw.upload.pdf'
But as soon as I want to transfer this file from the temporary storage to some other folder, I get the following error:
path = os.replace(path, settings.MEDIA_ROOT)
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpbp4klqtw.upload.pdf' -> '/home/oem/bla/bla'
Can't understand why this file is not in reality? What can I do about it? Is it possible to set some special path for the "temporary file"?
UPD:
You should use path = os.replace(path, settings.MEDIA_ROOT + '/name-of-file.pdf') – Willem Van Onsem
os.replace(…) [python-doc] expects a filename as target if you specify a file as source, so you can move this to:
os.replace(path, f'{settings.MEDIA_ROOT}/name-of-file.pdf')
you can also make use of shutil.move(…) [python-doc] to specify the directory, this function will also return the filepath of the target file:
from shutil import move
target_file = move(path, settings.MEDIA_ROOT)

Flask file download: filename persists within the session

I have a flask site and a webform that generates excel files. The problem I'm having is, if I send the user back to the form to submit again, the previous file -- with same file name and data -- is downloaded even though new files are generated in the tmp directory. So, I think this has to do with my session variable.
I add a timestamp to the file name with this function to make sure the file names are unique:
def rightnow():
return dt.datetime.now().strftime("%m%d%y%h%m%S%f")
In routes.py, here is the call for the download:
#app.route('/download/', methods=['POST','GET'])
def download_file():
output_file = session.get('new_file', None)
r = send_file(output_file, attachment_filename=output_file, as_attachment=True)
return r
This is the code for the script that generates the excel files:
new_file = 'output_' + rightnow() + '.xlsx'
writer = pd.ExcelWriter('tmp/' + new_file, engine='xlsxwriter')
df.to_excel(writer, sheet_name="data")
writer.save()
session['new_file'] = 'tmp/' + new_file
The download statement from the template page:
<a class="button" href="{{url_for('download_file')}}">Download new data</a>
I have a "Submit Again" button tied to simple javascript
<button onclick="goBack()">Submit Again</button>
<script>//for "revise search" button
function goBack() {
window.history.back();
}
</script>
I have played around with session.clear() with no success.
How can I drop the session when the user click's the "Submit Again" button so the saved file name is dropped?
EDIT: I checked the variables for the filename and the session variable and they are identical, and different from the file name assigned on download. Forinstance, the file is named 'output_May0554733504.xlsx' by the script that I wrote -- I can see it in the tmp directory. But when I go to download the file, the filename is different: 'output_May0536794357.xlsx'
This other file name is not that of a different file in the tmp directory. Any file I download will be 'output_May0536794357.xlsx'.
If session.pop('new_file') doesn't work, you could try session.modified = True to force the change to the session.

Rails 5.2 Rest API + Active Storage - Upload file blob received from an external service

We are receiving a POST call from an external service, which contains the file blob (in Base64 encoding), and some other parameters.
# POST call to /document/:id/document_data
param = {
file: <base64 encoded file blob>
}
We would want to process the file and upload it to the following model
# MODELS
# document.rb
class Document < ApplicationRecord
has_one_attached :file
end
In the Controller method handling the POST call
# documents_controller.rb - this method handles POST calls on /document/:id/document_data
def document_data
# Process the file, decode the base64 encoded file
#decoded_file = Base64.decode64(params["file"])
#filename = "document_data.pdf" # this will be used to create a tmpfile and also, while setting the filename to attachment
#tmp_file = Tempfile.new(#filename) # When a Tempfile object is garbage collected, or when the Ruby interpreter exits, its associated temporary file is automatically deleted.
#tmp_file.binmode # This helps writing the file in binary mode.
#tmp_file.write #decoded_file
#tmp_file.rewind()
# We create a new model instance
#document = Document.new
#document.file.attach(io: #tmp_file, filename: #filename) # attach the created in-memory file, using the filename defined above
#document.save
#tmp_file.unlink # deletes the temp file
end
Hope this helps.
More about Tempfile can be found here.

not handling the file upload window well

I have a page object called import_transaction_file.rb, which one of the method click_choose_file will invoke a standard file upload windows show below:
the code for the page object is:
class ImportTransactionFile
include PageObject
....
button(:choose_file, :id => 'createBulkPayment:file')
....
def click_choose_file
choose_file
end
end
In my test program below:
....
def test_go_to_direct_credit_payment_page
...
#import_transaction.click_choose_file
# #browser.window(:title => 'File Upload').use do
# #browser.button(:name => 'Cancel').click
# end
# doesn't work
end
the method click_choose_file in the test program will invoke the standard file upload window as attached below:
How do I:
put the path to file name
click open button
click close button
Will you recommend me to do it in the page-object or the test program?
Thanks for your reply.
I have a very similar thing to what you're asking and mine works using:
browser.file_field(:text, "File Upload").set("C:\path\to\file\to\upload")
Hope that helps!

Resources