How to include Google Chart inside Pisa Document xhtml2pdf with Django - django

I'm trying to embed the Google Chart url below into a Pisa xhtml2pdf PDF, but can't seem to make it work.
http://chart.apis.google.com/chart?cht=bvs&chd=t:425.9,550.6&chs=400x125&chds=0,600&chl=Aug%2009%7CSep%2009&chco=8BC542&chbh=32,24
I was hoping this post would solve my problem but no luck.
I'm using the following code (taken from the aforementioned post)
html = render_to_string('reporting/pdf.html', keys,
context_instance=RequestContext(request))
result = StringIO.StringIO()
pdf = pisa.pisaDocument(
StringIO.StringIO(html.encode('ascii', 'xmlcharrefreplace')),
result, link_callback=link_callback)
return HttpResponse(result.getvalue(), mimetype='application/pdf')
and
def link_callback(uri, rel):
if uri.find('chart.apis.google.com') != -1:
return uri
if uri.find('mydomain.com') != -1:
return uri
return os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
It works when I embed images from mydomain.com but I get nothing when trying to link to chart.apis.google.com
This works:
<img src="http://mydomain.com/foo.jpg>
This is broken:
<img src="http://chart.apis.google.com/chart?cht=bvs&chd=t:425.9,550.6&chs=400x125&chds=0,600&chl=Aug%2009|">
Any help would be greatly appreciated. Cheers.

Related

Django - Get response to return image without saving file to models

I am using the tmdb api to return movie info as well as images.
Steps below of Get logic
Api request is made which provides movie info as well as "backdrop_path"
I then use this path to make another request for the jpg related to that movie.
Blocker
I'm unable to then output that jpg. It currently returns a url path as below.
Views.py
from django.shortcuts import render
from django.views.generic import TemplateView
import requests
import urllib
# Create your views here.
def index(request):
# Query API with user input
if 'movie' in request.GET:
api_key = 'api'
id = request.GET['movie']
url = 'https://api.themoviedb.org/3/search/movie?api_key={}&language=en-US&query={}&include_adult=false'
response = requests.get(url.format(api_key,id))
# successful request
if response.status_code == 200:
# Parse json output for key value pairs
tmdb = response.json()
# save image jpg
backdrop_path = tmdb['results'][0]['backdrop_path']
url = 'https://image.tmdb.org/t/p/original/{}'
gg = urllib.request.urlretrieve(url.format(backdrop_path), 'test.jpg')
context = {
'title': tmdb['results'][0]['original_title'],
'overview': tmdb['results'][0]['overview'],
'release_date': tmdb['results'][0]['release_date'],
'vote_average': tmdb['results'][0]['vote_average'],
'vote_count': tmdb['results'][0]['vote_count'],
'backdrop_path' : tmdb['results'][0]['backdrop_path'],
'jpg' : gg
}
return render(request, 'home.html', {'context': context})
else: # returns homepage if invalid request
return render(request, 'home.html')
else: # Homepage without GET request
return render(request, 'home.html')
urlretrieve doesn't return the image ready to be used, instead it returns a tuple with the local name of the file and the headers (as an HTTPMessage object as you can see in your example), which is what you're seeing.
However, I don't think returning a file in your response is ideal, nor it would work in your scenario. Since you seem to be using templates, what I would do is return the image url and use it in an image HTML tag, like this <img src="{{ jpg }}"/>

How can I serve an image in django?

I have a binary field to save images
photograph = models.BinaryField(default=None)
In my form, I save the image
photograph = cd['photograph'].file.getvalue(),
)
In My view
f = open('my.jpeg', 'bw')
myfile = File(f)
myfile.write(student.photograph)
filepath = os.path.abspath(os.path.realpath('my.jpeg'))
context['urls'] = filepath
return render(request, 'dashboard.html', context)
The image is saved to the database, it is being retrieved successfully.
Screenshot of the image being saved successfully
My template
The HTML in the template renders well.
If I copy the HTML into a local file, the image appears well and good.
However, the image doesn't load properly when I use django.
Right click > copy image address gives me this: about:blank#blocked
Is it a security or a permissions issue?
After much research, this is what I found.
in HTML
<img src = "data/image:jpeg;base64, {{base64_string}}/>
in view
from django.http import urlsafe_b64encode
return render(request, 'template.html', {'base64_string' : urlsafe_b64encode(myobject.photograph)
This works for development. For production, I guess static files could be served the django way.

Flask dynamic graphviz and SVG example

I'm trying to create a Graphviz image, however instead of saving the image and loading into the webpage, pass it as SVG.
Its sort of working, here is the example:
from flask import Flask
from graphviz import Graph
app = Flask(__name__)
#app.route('/svgtest')
def svgtest():
chart_data = Graph()
chart_data.node('H', 'Hello')
chart_data.node('W', 'World')
chart_data.edge('H', 'W')
chart_output = chart_data.pipe(format='svg')
return render_template('svgtest.html', chart_output=chart_output)
In My HTML Page I have
<embed type="image/svg+xml" src={{ chart_output|safe }} />
However the output is not right
Any help would really be great, I'm starting to talk to myself, and even that's not helpful.
Thanks.
You can use svg just like this:
{{ chart_output|safe }}
and also, you can use png format:
#app.route('/')
def svgtest():
chart_data = Graph()
chart_data.node('H', 'Hello')
chart_data.node('W', 'World')
chart_data.edge('H', 'W')
chart_output = chart_data.pipe(format='png')
chart_output = base64.b64encode(chart_output).decode('utf-8')
return render_template('svgtest.html', chart_output=chart_output)
and the html like this:
<img src="data:image/png;base64,{{chart_output|safe}}" />
Happy coding!
This should work. I have modified a bit.
from flask import Flask
from graphviz import Graph
app = Flask(__name__)
#app.route('/svgtest')
def svgtest():
chart_data = Graph()
chart_data.node('H', 'Hello')
chart_data.node('W', 'World')
chart_data.edge('H', 'W')
chart_output = chart_data.pipe(format='svg').encode("utf-8")
return render_template('svgtest.html', chart_output=chart_output)
and the modified html will be:
{{chart_output|safe}}
The src attribute of the embed tag should contain an url to the content to embed, not the content itself:
The HTML <embed> element embeds external content at the specified
point in the document. This content is provided by an external
application ...
src The URL of the resource being embedded.
If you want to use embed, you should serve the svg (without html template) under its own url and use that url in the src attribute of the embed tag.
Or you may insert the svg directly in your html template, without the embed tag.

Append .png image to a pdf using reportlab in Django framework

I'm using Django and reportlab to generate a PDF report
I already can generate the pdf, but I Wanted to append a logo.png to it.
these were the lines I added in
views.py:
from reportlab.platypus import Image
logo = Image("/cdss/static/cdss/img/logo.png")
exam.append(logo)
But it isn't working, Am I exporting the Image() method wrong? Or is Path to the file wrong?
Hope you can help me, thanks ;)
This Worked For me....
def PrintImage(request,std_id):
response = HttpResponse(content_type='application/pdf')
doc = SimpleDocTemplate(response,topMargin=2)
doc.pagesize = landscape(A6)
elements = []
I = Image('http://demoschoolzen.educationzen.com/images/tia.png')
I.drawHeight = 0.7*inch
I.drawWidth = 0.7*inch
elements.append(I)
doc.build(elements)
return response
and Call it from your URLs

Exporting html to pdf using django

I am trying to export my html pages into pdf using Pisa library in django, and here is the code that I use to do that:
def fetch_resources(uri, rel):
path = os.path.join(settings.STATIC_ROOT, uri.replace(settings.STATIC_URL, ""))
return path
def write_pdf(template_src, context_dict):
template = get_template(template_src)
context = Context(context_dict)
html = template.render(context)
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),dest = result, encoding='UTF-8', link_callback=fetch_resources)
if not pdf.err:
return http.HttpResponse(result.getvalue(), mimetype='application/pdf')
return http.HttpResponse('Sorry, no pdf! %s' % cgi.escape(html))
def article(request):
return write_pdf('Storehouse/ReceiptPrint-v2.html',{'pagesize':'A4'})
But I have two problems when I get the pdf output: first, it does not render my css files and all of my styles are missed in the pdf (my css files are very large, so please don't suggest to have the style in the html file) and second it does not understand the specified unicode (UTF-8), my html pages are in Farsi, but when it turns into pdf, it changes into some meaningless squares.
Any help would be appreciated a lot!
Pisa's converter uses the ReportLab Toolkit, which has a difficult time rendering Farsi and other Arabic characters straight out of the box. I found that using the DejaVuSansMono.ttf font allows you to render the characters properly.