I am currently trying out a new gem called "gmail". I am trying to send a message with an attachment file however I seem to encounter this error everytime:
No such file or directory # rb_sysopen - /uploads/upload/avatar/4/filename.png
the line of code where I attach this image is noted below:
def send_message
params = message_params
u = Upload.create(avatar: params[:file])
u.save!
# puts "Upload: #{u.avatar}\nLocation: #{Rails.root.join(u.avatar.url)}"
email = #gmail.compose do
to "#{params[:to]}"
subject "#{params[:subject]}"
body "#{params[:message]}"
add_file "#{Rails.root.join(u.avatar.url)}"
end
email.deliver!
flash[:success] = 'Message sent!'
Upload.destroy_all
redirect_to root_path
end
Please help I've been stuck at this for hours now.
Apparently the path was lacking a bit...managed to solve it by changing the path to:
path = "#{Rails.root}" << "/public" << u.avatar.url
Related
I'm trying to get data from an url as a file and serve it back with the right mimetype.
I've tried a lot of different options this is some of the python flask code I currently have
## download video
#app.route('/download/<string:resource>')
def download(resource):
asset = getasset(resource)
# headers = {"Content-Type":"application/octet-stream","Accept-Encoding":"gzip, deflate, br","Accept":"*/*"}
response = requests.get(asset['downloads']['h264_720'], stream=True)
# length = response.headers.get('Content-Length')
def exhaust(response):
while True:
response.raw.decode_content = True
out = response.content.read(1024*1024)
if not out:
break
yield out
if IS_OFFLINE:
return Response(exhaust(response), mimetype='video/mp4')
else:
return Response(base64.b64decode(exhaust(response)), mimetype='video/mp4')
Offline the response is fine reviewing it locally with "serverless wsgi serve --stage dev"
Online the response is different (after doing "serverless deploy --stage dev"...
Please have a look at the image, left the correct mp4 video file. Right a file that is bigger and not a mp4 file.
It has something to do with base64.b64encode(r.content) but there is more to it.
I started of with this function:
### download video
# #app.route('/download/<string:resource>')
# def download(resource):
# asset = getasset(resource)
# r = requests.get(asset['downloads']['h264_720'],stream=True)
# if IS_OFFLINE:
# return Response(r.content, mimetype='video/mp4')
# else:
# return Response(base64.b64decode(r.content), mimetype='video/mp4')
This results in a file that looks like this and is only 200 bytes:
ftypisomisomiso2avc1mp41moovlmvhdTtraktkhd8edtselst8treftmcdmdiamdhd2UhdlrvideVideoHandlerjminfvmhddinfdrefurlstblstsdavc1HH9avcCMgMPfxrhcolrnclxpaspbtrtq+Vsttsstss3estscstszOBNC7468x69G8BClAiBBKGHAEArLiDGuc=
It has some of the first characters that I can see in the correct file:
Any one knows what's going on and how to fix it?
I did manage to reproduce the issue locally:
import requests
import base64
url = 'to a video file...'
r = requests.get(url)
with open("test.mp4", "wb") as out_file:
#reproducing the issue with this
base64_bytes = base64.b64encode(r.content)
#uncomment this will produce correct output
#message_bytes = base64.b64decode(base64_bytes)
out_file.write(message_bytes)
Ok I found the issue and added this to my serverless.yml
provider:
name: aws
runtime: python3.9
### fix:
apiGateway:
binaryMediaTypes:
- '*/*'
###
source:
https://github.com/dherault/serverless-offline/issues/464
I am receiving an http request from a desktop application with a screenshot. I cannot speak with the developer or see source code, so all I have is the http request I am getting.
The file isn't in request.FILES, it is in request.POST.
#csrf_exempt
def create_contract_event_handler(request, contract_id, event_type):
keyboard_events_count = request.POST.get('keyboard_events_count')
mouse_events_count = request.POST.get('mouse_events_count')
screenshot_file = request.POST.get('screenshot_file')
barr2 = bytes(screenshot_file.encode(encoding='utf8'))
with open('.test/output.jpeg', 'wb') as f:
f.write(barr2)
f.close()
The file is corrupted.
The binary starts like this, I don't know if that helps:
����JFIFHH��C
%# , #&')*)-0-(0%()(��C
(((((((((((((((((((((((((((((((((((((((((((((((((((�� `"��
Also, if I try to open the image with PIL, I get the following error:
from PIL import Image
im = Image.open('./test/output.jpg')
#OSError: cannot identify image file './test/output.jpg'
Finally, I managed to touch the code in the other hand, the 'filename' was missing in the header and for that reason I was getting the file in the POST instead of in the FILES dictionary.
I cannot find any example on how to attach files(pdf) that are within my root folder of the site in python (google app engine) send_mail function.
url_test = "https://mywebsite.com/pdf/test.pdf"
test_file = urlfetch.fetch(url_test)
if test_file.status_code == 200:
test_document = test_file.content
mail.send_mail(sender=EMAIL_SENDER,
to=['test#test.com'],
subject=subject,
body=theBody,
attachments=[("testing",test_document)])
Decided to try it with EmailMessage:
message = mail.EmailMessage( sender=EMAIL_SENDER,
subject=subject,body=theBody,to=['myemail#gmail.com'],attachments=
[(attachname, blob.archivoBlob)])
message.send()
The above blob attachment is successfully sending however attaching a file with relative path always says "invalid attachment"
new_file = open(os.path.dirname(__file__) +
'/../pages/pdf/test.PDF').read()
message = mail.EmailMessage( sender=EMAIL_SENDER,
subject=subject,body=theBody,to=['myemail#gmail.com'],attachments=
[('testing',new_file )])
message.send()
In debugging I have also tried to see if the file is being read by doing this:
logging.info(new_file)
It seems to be reading the file as it outputs some unicode characters
Please help why am I not able to attach a PDF while I can attach a blob
When calling the attachments, the File type has to be indicated on the file title, for example attachments= [('testing.pdf',new_file )]). View this link
I have taken a look at other questions related to multipart/form POST requests in Python but unfortunately, they don't seem to address my exact question. Basically, I normally use CURL in order to hit an API service that allows me to upload zip files in order to create HTML5 assets. The CURL command I use looks like this:
curl -X POST -H "Authorization: api: 222111" --form "type=html" --form "file=Folder1/Folder2/example.zip" "https://example.api.com/upload?ins_id=123"
I am trying to use a python script to iterate through a folder of zip files in order to upload all of these files and receive a "media ID" back. This is what my script looks like:
import os
import requests
import json
ins_id = raw_input("Please enter your member ID: ")
auth = raw_input("Please enter your API authorization token: ")
for filename in os.listdir("zips"):
if filename.endswith(".zip"):
file_path = os.path.abspath(filename)
url = "https://example.api.com/upload?
ins_id="+str(ins_id)
header = {"Authorization": auth}
response = requests.post(url, headers=header, files={"form_type":
(None, "html"), "form_file_upload": (None, str(file_path))})
api_response = response.json()
print api_response
This API service requires the file path to be included when submitting the POST. However, when I use this script, the response indicates that "file not provided". Am I including this information correctly in my script?
Thanks.
Update:
I think I am heading in the right direction now (thanks to the answer provided) but now, I receive an error message stating that there is "no such file or directory". My thinking is that I am not using os.path correctly but even if I change my code to use "relpath" I still get the same message. My script is in a folder and I have a completely different folder called "zips" (in the same directory) which is where all of my zip files are stored.
To upload files with the request library, you can include the file handler directly in the JSON as described in the documentation. This is the corresponding example that I have taken from there:
url = 'http://httpbin.org/post'
files = {'file': open('path_to_your_file', 'rb')}
r = requests.post(url, files=files)
If we integrate this in your script, it would look as follows (I also made it slightly more pythonic):
import os
import requests
import json
folder = 'zips'
ins_id = raw_input("Please enter your member ID: ")
auth = raw_input("Please enter your API authorization token: ")
url = "https://example.api.com/upload?"
header = {"Authorization": auth}
for filename in os.listdir(folder):
if not filename.endswith(".zip"):
continue
file_path = os.path.abspath(os.path.join(folder, filename))
ins_id="+str(ins_id)"
response = requests.post(
url, headers=header,
files={"form_type": (None, "html"),
"form_file_upload": open(file_path, 'rb')}
)
api_response = response.json()
print api_response
As I don't have the API end point, I can't actually test this code block - but it should be something along these lines.
Trying to get Carrierwave multiple file uploads working. I'm following the documentation on the homepage. When I try to upload a file or multiple, I get an no implicit conversion of nil to string
That error is coming from this method in the Carrierwave gem found in uploaders/cache.rb
def workfile_path(for_file=original_filename)
File.join(CarrierWave.tmp_path, #cache_id, version_name.to_s, for_file)
end
The issue is that the original_file is nil. I've tried to trace the issue but can't find where the issue is really beginning. One thing that is odd is that I am following some source code from this repo
https://github.com/bobintornado/sample-gallery-app-with-carrierwave
The sample app is working and you can do multiple uploads. The difference though is that when cache! method is called the new_file is an Array where in sample app that's working it's Http::UploadedFile
Here's the cache method
def cache!(new_file = sanitized_file)
new_file = CarrierWave::SanitizedFile.new(new_file)
return if new_file.empty?
raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
self.cache_id = CarrierWave.generate_cache_id unless cache_id
#filename = new_file.filename
self.original_filename = new_file.filename
begin
# first, create a workfile on which we perform processings
if move_to_cache
#file = new_file.move_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
else
#file = new_file.copy_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
end
with_callbacks(:cache, #file) do
#file = cache_storage.cache!(#file)
end
ensure
FileUtils.rm_rf(workfile_path(''))
end
end
Here are my initial params
"coach"=>{"name"=>"ben", "title"=>"ceo", "description"=>"head dude",
"photos"=>[
#<ActionDispatch::Http::UploadedFile:0x007fc9a5235c78 #tempfile=#<Tempfile:/var/folders/sb/t6rry5j928l3sy96nkhy9f840000gn/T/RackMultipart20160113-67635-avg8ef.jpg>, #original_filename="benn-1.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"coach[photos][]\"; filename=\"benn-1.jpg\"\r\nContent-Type: image/jpeg\r\n">,
#<ActionDispatch::Http::UploadedFile:0x007fc9a5235c50 #tempfile=#<Tempfile:/var/folders/sb/t6rry5j928l3sy96nkhy9f840000gn/T/RackMultipart20160113-67635-r8bdxp.jpg>, #original_filename="benn-2.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"coach[photos][]\"; filename=\"benn-2.jpg\"\r\nContent-Type: image/jpeg\r\n">
]}
Sorry this isn't terribly helpful, but I burned my current working branch and started from the beginning and now everything is working. Not sure what I did differently. If you're running into the same issue I recommend starting over and following this tutorial:
Multiple-Images-Uploading-With-CarrierWave-and-PostgreSQL-Array