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.
Related
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)
I am currently working with several XML files that require the text of the element mods:namePart changed. I have created a script that should loop through all the XML files I have specified in a particular directory and make the intended changes. However, when I run the script the changes are not reflected in the new files. It executes as expected, and I even get the "namepart changed" output in my console, but the text I want to replace remains the same. PLEASE HELP!! I am extremely new to coding so any tips/comments are welcome. Here is the code I'm using:
list_of_files = glob.glob('/Users/#####/Documents/test_xml_files/*.xml')
for file in list_of_files: xmlObject = ET.parse(file)
root = xmlObject.getroot()
namespaces = {'mods':'http://www.loc.gov/mods/v3'}
for namePart in root.iterfind('mods:name/mods:namePart', namespaces):
if namePart.text == 'Tsukioka, Kōgyo, 1869-1927':
new_namePart = namePart.text.replace('Tsukioka, Kōgyo, 1869-1927', 'Tsukioka Kōgyo, 1869-1927', 1)
namePart.text == new_namePart
print('namepart changed')
else:
continue
nf = open(os.path.join('/Users/####/Documents/updated_test_directory', os.path.basename(file)), 'wb')
xmlString = ET.tostring(root, encoding="utf-8", method="xml", xml_declaration=None)
nf.write(xmlString)
nf.close()
Here's my sample code which works:
import os, io, dropbox
def createFolder(dropboxBaseFolder, newFolder):
# creating a temp dummy destination file path
dummyFileTo = dropboxBaseFolder + newFolder + '/' + 'temp.bin'
# creating a virtual in-memory binary file
f = io.BytesIO(b"\x00")
# uploading the dummy file in order to cause creation of the containing folder
dbx.files_upload(f.read(), dummyFileTo)
# now that the folder is created, delete the dummy file
dbx.files_delete_v2(dummyFileTo)
accessToken = '....'
dbx = dropbox.Dropbox(accessToken)
dropboxBaseDir = '/test_dropbox'
dropboxNewSubDir = '/new_empty_sub_dir'
createFolder(dropboxBaseDir, dropboxNewSubDir)
But is there a more efficient/simpler way to do the task ?
Yes, as Ronald mentioned in the comments, you can use the files_create_folder_v2 method to create a new folder.
That would look like this, modifying your code:
import dropbox
accessToken = '....'
dbx = dropbox.Dropbox(accessToken)
dropboxBaseDir = '/test_dropbox'
dropboxNewSubDir = '/new_empty_sub_dir'
res = dbx.files_create_folder_v2(dropboxBaseDir + dropboxNewSubDir)
# access the information for the newly created folder in `res`
My main task is to have the user press a Download button and download file "A.zip" from the query directory.
The reason I have a elif request.POST..... is because I have another condition checking if the "Execute" button was pressed. This execute button runs a script. Both POST actions work, and the dir_file is C:\Data\Folder.
I followed and read many tutorials and responses as to how to download a file from Django, and I cannot figure out why my simple code does not download a file.
What am I missing? The code does not return any errors. Does anybody have any documentation that can explain what I am doing wrong?
I am expecting an automatic download of the file, but does not occur.
elif request.POST['action'] == 'Download':
query = request.POST['q']
dir_file = query + "A.zip"
zip_file = open(dir_file, 'rb')
response = HttpResponse(zip_file, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=%s' % 'foo_zip'
zip_file.close()
I found out my answer.
After reading through many documentation about this, I left out the most important aspect of this feature which is the url.
Basically, the function download_zip is called by the POST and runs script where the zip is downloaded.
Here is what I ended up doing:
elif request.POST['action'] == 'Download':
return(HttpResponseRedirect('/App/download'))
Created a view:
def download_zip(request):
zip_path = root + "A.zip"
zip_file = open(zip_path, 'rb')
response = HttpResponse(zip_file, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=%s' % 'A.zip'
response['Content-Length'] = os.path.getsize(zip_path)
zip_file.close()
return response
Finally in urls.py:
url(r'^download/$', views.download_zip, name='download_zip'),
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?