Unn-

mkadvice-0.2.1

Mar 22nd, 2013
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.28 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 Queue
  8. from threading import Lock, 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=None):
  21.         self.imdb_id = imdb_id
  22.         self.title = title
  23.         self.genre = genre
  24.         self.poster = poster
  25.  
  26.     def dl_poster(self):
  27.         payload = {'id': self.imdb_id, 'plot': 'none'}
  28.         json = req_get('http://imdbapi.org/', params=payload).json()
  29.         link = json.get('poster')
  30.         if link:
  31.             self.poster = req_get(link).content
  32.  
  33.  
  34. def worker(mov_queue, pbar, pbar_lock):
  35.     """Downloads posters."""
  36.     while True:
  37.         movie = mov_queue.get()
  38.         movie.dl_poster()
  39.         mov_queue.task_done()
  40.         with pbar_lock:
  41.             pbar.update(mov_queue.qsize())
  42.  
  43.  
  44. def make_caption(title):
  45.     """Returns image with caption."""
  46.     fake_poster = Image.new('RGB', (WIDTH, HIGHT), 'lightgrey')
  47.     caption = ImageDraw.Draw(fake_poster)
  48.     caption_font = ImageFont.truetype(FONT, 24)
  49.     caption.text((5, 10), title, fill='black', font=caption_font)
  50.     return fake_poster
  51.  
  52.  
  53. def main(input_file, output_file):
  54.     # Read movies from file
  55.     movies = [Movie(*(i.strip().capitalize() for i in line.split(',', 2)))
  56.               for line in open(input_file, 'r') if not line.isspace()]
  57.  
  58.     # Get unique genres and maximum number of posters in column
  59.     genres = Counter(mov.genre for mov in movies)
  60.     unique_genres = genres.keys()
  61.     unique_genres.sort()
  62.     max_posters = max(genres.values())
  63.  
  64.     # Create progress bar, lock, queue and thread pool
  65.     widgets = [Percentage(), Bar(left='[', right=']'), SimpleProgress()]
  66.     pbar = ProgressBar(maxval=len(movies), widgets=widgets).start()
  67.     pbar_lock = Lock()
  68.     mov_queue = Queue(len(movies))
  69.     threads_num = (len(movies) if len(movies) < 30 else 30)
  70.     for i in xrange(threads_num):
  71.         download = Thread(target=worker, args=(mov_queue, pbar, pbar_lock))
  72.         download.daemon = True
  73.         download.start()
  74.    
  75.     for mov in movies:
  76.         mov_queue.put(mov)
  77.        
  78.     mov_queue.join()
  79.     pbar.finish()
  80.  
  81.     # Create canvas, add genres and posters to canvas
  82.     canv_width = 20 + (WIDTH+20) * len(unique_genres)
  83.     canv_hight = 100 + HIGHT*max_posters + 20
  84.     canvas = Image.new('RGB', (canv_width, canv_hight), 'black')
  85.     draw = ImageDraw.Draw(canvas)
  86.     genre_font = ImageFont.truetype(FONT, 42)
  87.     shift = 0
  88.     for genre in unique_genres:
  89.         draw.text((20 + shift, 20), genre, fill='white', font=genre_font)
  90.         shift += (WIDTH+20)
  91.  
  92.     p_counter = Counter()  # Current number of posters in each column (genre)
  93.     y_counter = Counter()  # Current y value in each column
  94.     x, y = (0, 0)
  95.     for mov in movies:
  96.         if mov.poster:
  97.             poster = Image.open(StringIO(mov.poster))
  98.             if poster.size != (WIDTH, HIGHT):
  99.                 poster = poster.resize((WIDTH, HIGHT))
  100.         else:
  101.                 poster = make_caption(mov.title)
  102.  
  103.         # Set the (x, y) in appliance with genre
  104.         x = 20 + (WIDTH+20) * unique_genres.index(mov.genre)
  105.         y = 100 + y_counter[mov.genre]
  106.         p_counter[mov.genre] += 1
  107.         y_counter[mov.genre] = HIGHT * p_counter[mov.genre]
  108.  
  109.         canvas.paste(poster, (x, y))
  110.     canvas.save(output_file)
  111.    
  112.  
  113. if __name__ == '__main__':
  114.     parser = ArgumentParser(description='Downloads posters and makes "advice"')
  115.     parser.add_argument('input_file',
  116.                         metavar='FILE',
  117.                         help='Text file containing movies (id, title, genre)')
  118.     parser.add_argument('-o',
  119.                         dest='output_file',
  120.                         metavar='OUTPUT',
  121.                         default=DEFAULT_OUT,
  122.                         help='Name of out image (default: '+ DEFAULT_OUT +')')
  123.     args = parser.parse_args()
  124.     main(args.input_file, args.output_file)
Advertisement
Add Comment
Please, Sign In to add comment