Unn-

mkadvice-0.2

Mar 20th, 2013
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.98 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. from argparse import ArgumentParser
  5. from collections import Counter
  6. from cStringIO import StringIO
  7. from Queue import Empty, Queue
  8. from threading import Thread
  9.  
  10. from PIL import Image, ImageDraw, ImageFont
  11. from progressbar import Bar, ProgressBar, Percentage, SimpleProgress
  12. from requests import get as req_get
  13.  
  14. DEFAULT_OUT = 'output.jpg'
  15. FONT = '/usr/share/fonts/ubuntu-font-family/Ubuntu-C.ttf'
  16. WIDTH = 214  # Poster width
  17. HIGHT = 317  # Poster hight
  18.  
  19. class Movie:
  20.     def __init__(self, imdb_id, title, genre, poster_url=None, poster=None):
  21.         self.imdb_id = imdb_id
  22.         self.title = title
  23.         self.genre = genre
  24.         self.poster_url = poster_url
  25.         self.poster = poster
  26.  
  27.     def dl_poster_url(self):
  28.         payload = {'id': self.imdb_id, 'plot': 'none'}
  29.         json = req_get('http://imdbapi.org/', params=payload).json()
  30.         self.poster_url = json.get('poster')
  31.  
  32.     def dl_poster(self):
  33.         if self.poster_url:
  34.             self.poster = req_get(self.poster_url).content
  35.  
  36.  
  37. def dl_links(q1, q2):
  38.     """Downloads links, move object (movie) from queue1 to queue2."""
  39.     while not q1.empty():
  40.             movie = q1.get()
  41.             q1.task_done()
  42.             movie.dl_poster_url()
  43.             q2.put(movie)
  44.             q2.task_done()
  45.  
  46.  
  47. def dl_posters(q2, q3, Empty, pbar):
  48.     """Downloads posters, move object from queue2 to queue3."""
  49.     while not q3.full():
  50.         try:
  51.             movie = q2.get()
  52.         except Empty:
  53.             pass
  54.         else:
  55.             movie.dl_poster()
  56.             q3.put(movie)
  57.             pbar.update(q3.qsize())
  58.             q3.task_done()
  59.  
  60.  
  61. def make_caption(title):
  62.     """Returns image with caption."""
  63.     fake_poster = Image.new('RGB', (WIDTH, HIGHT), 'lightgrey')
  64.     caption = ImageDraw.Draw(fake_poster)
  65.     caption_font = ImageFont.truetype(FONT, 24)
  66.     caption.text((5, 10), title, fill='black', font=caption_font)
  67.     return fake_poster
  68.  
  69.  
  70. def main(input_file, output_file):
  71.     # Read movies from file
  72.     movies = [Movie(*(i.strip().capitalize() for i in line.split(',', 2)))
  73.               for line in open(input_file, 'r')]
  74.  
  75.     # Get unique genres and maximum number of posters in column
  76.     genres = Counter(mov.genre for mov in movies)
  77.     unique_genres = genres.keys()
  78.     unique_genres.sort()
  79.     max_posters = max(genres.values())
  80.  
  81.     widgets = [Percentage(), Bar(left='[', right=']'), SimpleProgress()]
  82.     pbar = ProgressBar(maxval=len(movies), widgets=widgets).start()
  83.  
  84.     q1, q2, q3 = (Queue(len(movies)) for q in range(3))
  85.     for mov in movies:
  86.         q1.put(mov)
  87.  
  88.     # Create two thread pools
  89.     threads_num = int(len(movies) / 2)  # Should find optimal value
  90.     for thread in range(threads_num):
  91.         link_task = Thread(target=dl_links, args=(q1, q2))
  92.         link_task.setDaemon(True)
  93.         link_task.start()
  94.         poster_task = Thread(target=dl_posters, args=(q2, q3, Empty, pbar))
  95.         poster_task.setDaemon(True)
  96.         poster_task.start()
  97.    
  98.     while not q3.full(): pass  # Wait until all downloads are completed
  99.  
  100.     pbar.finish()
  101.  
  102.     # Create canvas, add genres and posters to canvas
  103.     canv_width = 20 + (WIDTH+20) * len(unique_genres)
  104.     canv_hight = 100 + HIGHT*max_posters + 20
  105.     canvas = Image.new('RGB', (canv_width, canv_hight), 'black')
  106.     draw = ImageDraw.Draw(canvas)
  107.     genre_font = ImageFont.truetype(FONT, 42)
  108.     shift = 0
  109.     for genre in unique_genres:
  110.         draw.text((20 + shift, 20), genre, fill='white', font=genre_font)
  111.         shift += (WIDTH+20)
  112.  
  113.     p_counter = Counter()  # Current number of posters in each column (genre)
  114.     y_counter = Counter()  # Current y value in each column
  115.     x, y = (0, 0)
  116.     for mov in movies:
  117.         if mov.poster:
  118.             poster = Image.open(StringIO(mov.poster))
  119.             if poster.size != (WIDTH, HIGHT):
  120.                 poster = poster.resize((WIDTH, HIGHT))
  121.         else:
  122.             poster = make_caption(mov.title)
  123.  
  124.         # Set the (x, y) in appliance with genre
  125.         for genre in unique_genres:
  126.             if genre == mov.genre:
  127.                 x = 20 + (WIDTH+20) * unique_genres.index(genre)
  128.                 y = 100 + y_counter[genre]
  129.                 p_counter[genre] += 1
  130.                 y_counter[genre] = HIGHT * p_counter[genre]
  131.  
  132.         canvas.paste(poster, (x, y))
  133.     canvas.save(output_file)
  134.    
  135.  
  136. if __name__ == '__main__':
  137.     parser = ArgumentParser(description='Downloads posters and makes "advice"')
  138.     parser.add_argument('input_file',
  139.                         metavar='FILE',
  140.                         help='Text file containing movies (id, title, genre)')
  141.     parser.add_argument('-o',
  142.                         dest='output_file',
  143.                         metavar='OUTPUT',
  144.                         default=DEFAULT_OUT,
  145.                         help='Name of out image (default: '+ DEFAULT_OUT +')')
  146.     args = parser.parse_args()
  147.     main(args.input_file, args.output_file)
Advertisement
Add Comment
Please, Sign In to add comment