1

I'm making a website with Python and flask, and in my HTML table it prints: Rory O\u0027Shea Was Here instead of Rory O'Shea Was Here.

When I run the Python program in my terminal it will print out just fine, but there seems to be an issue when I put it into my HTML template which makes it print the \u0027.

How can I get it to print the expected Rory O'Shea Was Here?

Here is main.py (this runs the flask app):

from flask import Flask, render_template, request
from hboA import HbobyRating

app = Flask(__name__)

@app.route("/hbo")
def hbo():
    name = "HBO"
    logo = "/static/pics/hbo-logo.jpg"
    hbomovies = HbobyRating
    db = hbomovies
    return render_template('channel_template.html', hbomovies=hbomovies, name=name, db=db, logo=logo)

Here is the imdbHbo.py (this creates the movies database using IMDB api ):

import json
import urllib2


with open('/home/chim/Documents/moveit/hbomovies.json') as data_file:   #opens the movie database from Guidebox api
    moviedata = json.load(data_file)

Id = [x['imdb'] for x in moviedata['results']]              #extracts the imdbid from guidebox api

pyList = []
def getMovieRating():                           #creates a new json file containing the imdb data from the channels of guidebox api
    for i in Id:
        imdbid = i      
        imdbapi = "http://www.omdbapi.com/?i=%s&plot=short&r=json" % imdbid
        response = urllib2.urlopen(imdbapi)
        result = json.load(response)
        pyList.append(result)
        with open('/home/chim/Documents/moveit/static/hboImdb.json', 'w') as outfile:
                json.dump(pyList, outfile)

getMovieRating()

Here is the hboA.py python(This sorts the movies into a list by their IMDB rating):

import json


with open('/home/chim/Documents/moveit/final/hboImdb.json') as data_file:   #opens the imdb database we created
    response = json.load(data_file)


def getKeyRat(item):
    return item[1]

def getKeyAlpha(item):  
    return item[0]



TitleRating = [[x["Title"].encode('utf-8'), x['imdbRating'], x['Year'], x['Rated'], x['Genre'], x['Runtime']] for x in response]


for each in TitleRating:
    each.append("HBO")


HbobyRating = sorted(TitleRating, key=getKeyRat, reverse=True)
HbobyAlpha = sorted(TitleRating, key=getKeyAlpha)

Here is the HTML:

<!DOCTYPE html>


<img src={{logo}} alt="logo" style="width:512px;height:320px;" align="right">
<head>
    <title>Welcome to MoveIt</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<h1> Welcome to MoveIt</h1>

<p>check out HBO <a href="/hbo">click here</a></p>
<p>check out Cinemax <a href="/cinemax">click here</a></p>
<p>check out Showtime <a href="/showtime">click here</a></p>

<p> Or see a list by channel</p>
<form action="/select" method="POST">
<fieldset>
  <input type="checkbox" name="channels" value="hbomovies" />HBO<br>
  <input type="checkbox" name="channels" value="cinemaxmovies" />Cinemax<br>
  <input type="checkbox" name="channels" value="showtimemovies" />Showtime<br>
  <input type="submit" value="Submit">
</fieldset>
</form> 


<h2>These are the movies on {{name}} <i>right now</i>, listed by their IMDB rating:</h2>
<table border="1">
<tr>
    <th>Title</th>
    <th>Imdb Rating</th>        
    <th>Year</th>
    <th>Rated</th>
    <th>Genre</th>      
    <th>Runtime</th>
  </tr>
{% for row in db %}
    <tr>
      <td>{{ row[0]|tojson|safe }}</td>
      <td>{{ row[1] }}</td>
      <td>{{ row[2] }}</td>
      <td>{{ row[3] }}</td>
      <td>{{ row[4] }}</td>
      <td>{{ row[5] }}</td>
    </tr>
{% endfor %}
</table>

2 Answers2

1

You have problems with your code at different places.

First, why is Title encoded with utf-8? Internal strings must use unicode, only when writing to a stream, encoding is necessary:

import json
from operator import attrgetter

DATABASE = '/home/chim/Documents/moveit/final/hboImdb.json'

def read_database(database):
    with open(database) as data_file:   #opens the imdb database we created
        response = json.load(data_file)

    hbo_by_rating = sorted(response, key=attrgetter('imdbRating'), reverse=True)
    hbo_by_alpha = sorted(response, key=attrgetter('Title'))
    return hbo_by_rating, hbo_by_alpha

hbo_by_rating, hbo_by_alpha = read_database(DATABASE)

Next, in your template, you say explicitly 'tojson' which escapes every non-ASCII character to unicode \uxxxx. Simply remove this:

<h2>These are the movies on {{name}} <i>right now</i>, listed by their IMDB rating:</h2>
<table border="1">
<tr>
    <th>Title</th>
    <th>Imdb Rating</th>        
    <th>Year</th>
    <th>Rated</th>
    <th>Genre</th>      
    <th>Runtime</th>
  </tr>
{% for row in db %}
    <tr>
      <td>{{ row.Title }}</td>
      <td>{{ row.imdbRating }}</td>
      <td>{{ row.Year }}</td>
      <td>{{ row.Rated }}</td>
      <td>{{ row.Genre }}</td>
      <td>{{ row.Runtime }}</td>
    </tr>
{% endfor %}
</table>
Daniel
  • 42,087
  • 4
  • 55
  • 81
0

You need to encode it before you upload it. Use foo.encode('utf-8') where foo is the variable containing the string.

Leb
  • 15,483
  • 10
  • 56
  • 75
  • When I do that it changes the python output in the terminal to: "Rory O'Shea Was Here" instead of "u'Rory O'Shea Was Here" but the html looks the same... – Tim Donnelly Jun 27 '15 at 21:34