I have a script which let to generate a PDF file and then send it to another application (LogicalDOC) in order to save it.
I'm getting a problem with payload line. The filename should be my filename variable but it doesn't take account.
If I write filename.pdf, I find filename.pdf in LogicalDOC with the good content.
But filename have to change automatically for each new BirthCertificate.
How I can pass the path as filename ?
This is my script :
#login_required
def BirthCertificate_PDF(request, id) :
birthcertificate = get_object_or_404(BirthCertificate, pk=id)
data = {"birthcertificate" : birthcertificate}
template = get_template('BC_raw.html')
html = template.render(Context(data))
filename_directory = str(BirthCertificate.objects.get(pk=id).lastname.encode('utf-8')) + "_" + str(BirthCertificate.objects.get(pk=id).firstname.encode('utf-8')) + "_" + str(BirthCertificate.objects.get(pk=id).birthday)
filename = 'Acte_Naissance_' + filename_directory + '.pdf'
path = '/Users/valentinjungbluth/Desktop/Django/Individus/' + filename
file = open(path, "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), dest=file, encoding='utf-8')
file.seek(0)
pdf = file.read()
if pdf :
payload = '{ "language":"fr","fileName":filename,"folderId":3309569 }'
upfile = path
files = {
'document': (None, payload, 'application/json'),
'content': (os.path.basename(upfile), open(upfile, 'rb'), 'application/octet-stream')
}
url = 'http://localhost:8080/services/rest/document/create'
headers = {'Content-Type': 'multipart/form-data'}
r = requests.post(url, files=files, headers=headers, auth=('admin', 'admin'))
context = {"birthcertificate":birthcertificate,
"path":path}
return render(request, 'BC_PDF.html', context)
file.close()
return HttpResponse(pdf, 'application/pdf')
If I wrote :
"FileName":"test.pdf" I obtain the test.pdf file in logicalDoc (see picture)
"FileName":"filename" I obtain the filename file with unknown format in logicalDoc (see picture)
I would like to get my filename variable as document name
You can use string formatting for this. Just do follow:
payload = '{{ "language":"fr","fileName":"{0}","folderId":3309569 }}'.format(filename)
Related
I'm trying to send documents via Telegram API but I'm getting an error.
The class I have created is the following:
def sendDocument(self):
url = self.url + '/sendDocument'
fPath = 'C:/Users/users/user/OneDrive - Personal/syslog.txt'
params = {
'chat_id': self.chat_id,
'document': open(fPath, 'rb')
}
resp = requests.post(url, params=params)
if resp.status_code != 200: print('Status: ', resp.status_code)
I have relied on documentation I have found on the internet, as well as on the class I have already created and IT DOES WORK, to send text messages:
def sendMessage(self, text):
url = self.url + '/sendMessage'
params = {
'chat_id': self.chat_id,
'text': text,
'parse_mode': 'HTML'
}
resp = requests.post(url, params=params).
if resp.status_code != 200: print('Status: ', resp.status_code)
Could someone help me understand where the error is? Thank you very much!
The params adds query parameters to url, and it's impossible to send files this way. To send files with the requests library, you should use files parameter:
def sendDocument(self):
url = self.url + '/sendDocument'
fPath = 'C:/Users/users/user/OneDrive - Personal/syslog.txt'
params = {
'chat_id': self.chat_id,
}
files = {
'document': open(fPath, 'rb'),
}
resp = requests.post(url, params=params, files=files)
...
I think you should share file name in prams like below:
c_id = '000011'
filename = '/tmp/googledoc.docx'
context.bot.send_document(chat_id='c_id', document=open('googledoc.docx', 'rb'), filename="googledoc.docx")
I need to execute below function based on user input:
If X=0, then from line URL ....Print('Success should be written to a file & get saved as test.py.
At the backend, the saved file (Test.py) would automatically get fetched by Task scheduler from the saved location & would run periodically.
And yes, we have many example to write a file / run python from another file, but couldn't get any resemblance to write the python script from another file.
I am sure missing few basic steps.
if x=0:
### Need to write below content to a file & save as test.py######
URL = "https://.../login"
headers = {"Content-Type":"application/json"}
params = {
"userName":"xx",
"password":"yy"
}
resp = requests.post(URL, headers = headers, data=json.dumps(params))
if resp.status_code != 200:
print('fail')
else:
print('Success')]
else:
### Need to write below content to a file ######
URL = "https://.../login"
headers = {"Content-Type":"application/json"}
params = {
"userName":"RR",
"password":"TT"
}
resp = requests.post(URL, headers = headers, data=json.dumps(params))
if resp.status_code != 200:
print('fail')
else:
print('Success')
You can use triple-quotes to simplify things.
if x==0:
path = "test.py"
string = """\
import requests, json
URL = "https://.../login"
headers = {"Content-Type":"application/json"}
params = {
"userName":"xx",
"password":"yy"
}
resp = requests.post(URL, headers = headers, data=json.dumps(params))
if resp.status_code != 200:
print('fail')
else:
print('Success')
"""
else:
path = "other.py"
string = """\
import requests, json
URL = "https://.../login"
headers = {"Content-Type":"application/json"}
params = {
"userName":"RR",
"password":"TT"
}
resp = requests.post(URL, headers = headers, data=json.dumps(params))
if resp.status_code != 200:
print('fail')
else:
print('Success')
"""
with open(path, 'w') as f:
f.write(string)
See docs. About a third of the way down the page.
new_file = "print('line1')\n" \
"print('line2')\n" \
"print('line3')"
f = open('new_python.py', 'w')
print(new_file, file=f)
If you want to save it to a file, in the end, it must be a string.
Your two variations of the file look quite similar, so don't write it twice:
template ='''
URL = "https://.../login"
headers = {"Content-Type":"application/json"}
params = {
"userName":"%s",
"password":"%s"
}
resp = requests.post(URL, headers = headers, data=json.dumps(params))
if resp.status_code != 200:
print('fail')
else:
print('Success')
'''
if x == 0:
content = template % ("xx", "yy")
else:
content = tempalte % ("RR", "TT")
with open("test.py", "w") as f:
f.write(content)
I've created a PDF Creator with WeasyPrint and included the download function. Is it now possible to store that PDF File immediately into a Model-FileField (called Invoice)? How should this code look like?
def generate_pdf(request):
# Rendered
html_string = render_to_string('bills/pdf/invoice.html', context)
html = HTML(string=html_string, base_url=request.build_absolute_uri())
result = html.write_pdf(stylesheets=[CSS(settings.STATIC_ROOT + '/css/bills.css')], presentational_hints=True);
# Creating http response
response = HttpResponse(content_type='application/pdf;')
invoice_number = context['invoice_id']
filename = "Invoice" + str(invoice_number) + ".pdf"
response['Content-Disposition'] = 'inline; filename="{}"'.format(filename)
pdf_file = HTML(string=html_string,
base_url=settings.MEDIA_ROOT).write_pdf()
new_bill = Invoice(invoice_no=billNumber, invoice_file=temp)
new_bill.save()
response['Content-Transfer-Encoding'] = 'binary'
with tempfile.NamedTemporaryFile(delete=True) as output:
output.write(result)
output.flush()
output = open(output.name, 'rb')
response.write(output.read())
download = request.GET.get("download")
if download:
content = "attachment; filename='%s'" %(filename)
response['Content-Disposition'] = output
return response
Here is a complete example from Django documentation, to access instance information in your models to build path with user id :
models.py
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class YourClass(models.Model):
invoice = models.FileField(default='default.pdf', upload_to=user_directory_path)
I have such php function which I try to rewrite in my Django project. What should be an analogue in python for php methods like header() and show_error()? Also how to send file to response?
php:
function waprfile($date=false) {
if(!isset($date) || $date==false) $date = date("d.m.y");
$timestmp = date2timestamp($date);
$filepath = "https://www.example.com/files/".$this->lang_code."/";
if(file_get_contents($filepath.date("dmy",$timestmp).".xls"))
{
header("Location: ".$filepath."wapr".date("dmy",$timestmp).".xls");
}
else
{
show_error(_langWrite("No file for specified date", "Файл на указанную дату отсутствует"));
}
}
python:
import urllib.request
import datatime
import time
from django.utils import translation
def isset(variable):
return variable in locals() or variable in globals()
def waprfile(request, date):
if(not isset(date) or date==False):
date = datetime.datetime.now().strftime('%d.%m.%Y')
timestmp = time.mktime(datatime.datetime.strptime(date, "%d.%m.%Y").timetuple())
filepath = "https://www.example.com/files/" + str(translation.get_language()) + "/"
formatted_date = datetime.datetime.fromtimestamp(timestmp).strftime('%d%m%y')
if(urllib.request.urlopen(filepath + formatted_date + '.xls')):
# What must be here?
else:
# What must be here?
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename=' + fileName
return response
Read file first and then send it in response.
from django.http import HttpResponse, HttpResponseNotFound
def waprfile(request, date):
...
file_location = '/path/to/file/foo.xls'
try:
with open(file_location, 'r') as f:
file_data = f.read()
# sending response
response = HttpResponse(file_data, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="foo.xls"'
except IOError:
# handle file not exist case here
response = HttpResponseNotFound('<h1>File not exist</h1>')
return response
Read docs for more info:
telling browser to treat the response as a file attachment and returning errors
To return a PDF file in response in Django, use below code.
def index(request):
data = dict()
data["name"] = "https://www.pythoncircle.Com"
data["DOB"] = "Jan 10, 2015"
template = get_template('testapp/test.html')
html = template.render(data)
pdf = pdfkit.from_string(html, False)
filename = "sample_pdf.pdf"
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="' + filename + '"'
return response
[1] https://www.pythoncircle.com/post/470/generating-and-returning-pdf-as-response-in-django/
If you want to return an image don't forget to format it as png or jpeg and return the bytes with getvalue()
img = "Suppose I am a pil image"
fomatted_img = BytesIO()
img.save(fomatted_img, format="png")
response = HttpResponse(fomatted_img.getvalue(),content_type='image/png')
response['Content-Disposition'] = 'attachment; filename="output.png"'
return response
Or you can save the formatted image directly into the response
img = "Suppose I am a pil image"
response = HttpResponse(content_type='image/png')
response['Content-Disposition'] = 'attachment; filename="output.png"'
img.save(response,"PNG")
return response
I'm getting a new little problem with API Rest Python between Django and LogicalDOC.
I'm creating a folder inside LogicalDOC, then I would like to save my pdf file inside this new folder taking the folderId.
But, when it seems work because the syntax is good from my point of view : none pdf file appears.
I create a folder, I pick up his ID number : 348930 for example with the command data["id"] and I insert str(data["id"]) in FolderId when I want to save my pdf file in the new folder.
The new folder is created and worked well, but the pdf file is not save inside. Something wrong ?
This is my script :
#login_required
def BirthCertificate_PDF(request, id) :
birthcertificate = get_object_or_404(BirthCertificate, pk=id)
data = {"birthcertificate" : birthcertificate}
template = get_template('BC_raw.html')
html = template.render(Context(data))
filename_directory = str(BirthCertificate.objects.get(pk=id).lastname.encode('utf-8')) + "_" + str(BirthCertificate.objects.get(pk=id).firstname.encode('utf-8')) + "_" + str(BirthCertificate.objects.get(pk=id).birthday)
filename = 'Acte_Naissance_' + filename_directory + '.pdf'
path = '/Users/valentinjungbluth/Desktop/Django/Individus/' + filename
file = open(path, "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), dest=file, encoding='utf-8')
file.seek(0)
pdf = file.read()
if pdf :
payload = '{{ "name":"{0}", "parentId":3309569 }}'.format(filename_directory) #Fix parent folder
url = 'http://localhost:8080/services/rest/folder/create'
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
resp = requests.post(url, data=payload, headers=headers, auth=('admin', 'admin'))
rbody = resp.content
data = json.loads(rbody)
print data["id"] #Get ID from the new folder
payload = '{{ "language":"fr","fileName":"{0}","FolderId":'+str(data["id"]) +'}}'.format(filename) #save pdf file inside the new folder thanks to his ID
upfile = path
files = {
'document': (None, payload, 'application/json'),
'content': (os.path.basename(upfile), open(upfile, 'rb'), 'application/octet-stream')
}
url = 'http://localhost:8080/services/rest/document/create'
headers = {'Content-Type': 'multipart/form-data'}
r = requests.post(url, files=files, headers=headers, auth=('admin', 'admin'))
context = {"birthcertificate":birthcertificate,
"path":path}
return render(request, 'BC_PDF.html', context)
file.close()
return HttpResponse(pdf, 'application/pdf')
This is a screen capture which shows that folderID should be : 3538970
This number is also given by : data["id"]
As I said in my comment you don't need to use string concatenation to pass FolderId as payload, just use second argument of format method:
d = '{{ "language":"fr","fileName":"{0}","FolderId":"{1}"}}'.format(filename, str(data["id"]))