Guest User

Untitled

a guest
Apr 1st, 2017
1,090
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.33 KB | None | 0 0
  1. import requests
  2. from time import sleep
  3. from random import randrange
  4. import argparse
  5. import getpass
  6. from PIL import Image
  7. import numpy as np
  8. import math
  9.  
  10. palette = ([
  11.     (255, 255, 255),
  12.     (228, 228, 228),
  13.     (136, 136, 136),
  14.     (34, 34, 34),
  15.     (255, 167, 209),
  16.     (229, 0, 0),
  17.     (229, 149, 0),
  18.     (160, 106, 66),
  19.     (229, 217, 0),
  20.     (148, 224, 68),
  21.     (2, 190, 1),
  22.     (0, 211, 221),
  23.     (0, 131, 199),
  24.     (0, 0, 234),
  25.     (207, 110, 228),
  26.     (130, 0, 128)
  27. ])
  28.  
  29. def main():
  30.     parser = argparse.ArgumentParser(description='Draw an image on Reddit\'s Place canvas.')
  31.     parser.add_argument('--user', help='Reddit username')
  32.     parser.add_argument('--passwd', help='Reddit password')
  33.     parser.add_argument('--image', help='Image file to draw')
  34.     parser.add_argument('-x', help='X position of the upper left corner of where to draw', type=int)
  35.     parser.add_argument('-y', help='Y position of the upper left corner of where to draw', type=int)
  36.  
  37.     args = parser.parse_args()
  38.     if args.user is None:
  39.         args.user = input("Enter Reddit Username: ")
  40.     if args.passwd is None:
  41.         args.passwd = getpass.getpass()
  42.  
  43.     place = Place(args.user, args.passwd, greedy=True)
  44.     image = Image.open(args.image)
  45.  
  46.     try:
  47.         while True:
  48.             draw_image(place, image, (args.x, args.y), palette)
  49.     except KeyboardInterrupt:
  50.         print("Exiting")
  51.  
  52. def draw_image(place, image, position, palette):
  53.     """Draws an image on the Place canvas.
  54.  
  55.    place: Place object
  56.    image: image to draw
  57.    position: upper left corner of where to draw on the canvas
  58.    palette: list of tuples of allowed colors
  59.    """
  60.  
  61.     pixels = image_to_index_array(image, palette)
  62.  
  63.     x = randrange(0, image.width)
  64.     y = randrange(0, image.height)
  65.     place_x = position[0] + x
  66.     place_y = position[1] + y
  67.  
  68.     place_pixel = place.get(place_x, place_y)
  69.  
  70.     if "color" in place_pixel and place_pixel["color"] != pixels[x, y]:
  71.         print(f"Draw color {pixels[x, y]} at position ({place_x}, {place_y})")
  72.         place.draw(place_x, place_y, pixels[x, y])
  73.  
  74. def get_closest_color_index(color, color_list):
  75.     """"Finds the index in the color list that closest matches the color"""
  76.  
  77.     def dist(a, b):
  78.         """Euclidian distance in RGB space. Could probably be better."""
  79.  
  80.         return math.sqrt((a[0] - b[0]) ** 2 +
  81.                          (a[1] - b[1]) ** 2 +
  82.                          (a[2] - b[2]) ** 2)
  83.  
  84.     closest_color = min(color_list, key=lambda x: dist(x, color))
  85.     return color_list.index(closest_color)
  86.  
  87. def image_to_index_array(image, palette):
  88.     original = image.convert("RGB")
  89.     out = np.zeros(original.size, dtype=np.int8)
  90.  
  91.     for y in range(original.height):
  92.         for x in range(original.width):
  93.             original_clr = original.getpixel((x, y))
  94.             new_clr_num = get_closest_color_index(original_clr, palette)
  95.             out[x, y] = new_clr_num
  96.     return out
  97.  
  98.  
  99. # https://www.reddit.com/r/Python/comments/62ph3u/python_rplace_module/
  100. class Place(object):
  101.     def __init__(self, user, passwd, greedy=False):
  102.         """
  103.        user: reddit username
  104.        pass: reddit password
  105.        greedy: keep trying to perform request
  106.        """
  107.  
  108.         self.session = requests.session()
  109.         self.session.headers.update({"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.1144"})
  110.  
  111.         self.greedy = greedy
  112.  
  113.         payload= {'op': 'login',
  114.                   'user': user,
  115.                   'passwd': passwd}
  116.         self.session.post("https://www.reddit.com/post/login", data=payload)
  117.  
  118.         sleep(1)
  119.  
  120.         self.last = self.session.get("https://reddit.com/api/me.json")
  121.         self.modhash = self.last.json()["data"]["modhash"]
  122.         self.session.headers.update({"x-modhash": self.modhash})
  123.     def _get(self, x, y):
  124.         payload = {"x": x,
  125.                    "y": y}
  126.         return self.session.get("https://www.reddit.com/api/place/pixel.json", params=payload)
  127.     def get(self, x=0, y=0):
  128.         """get the color information at a given pixel
  129.        x: x-coordinates
  130.        y: y-coordinates
  131.        """
  132.         self.last = self._get(x,y)
  133.         if self.greedy:
  134.             while self.last.status_code == 429:
  135.                 sleep(1)
  136.                 self.last = self._get(x,y)
  137.         return self.last.json()
  138.  
  139.     def _draw(self, x=0, y=0, color=0):
  140.         payload = {"x": x,
  141.                    "y": y,
  142.                    "color": color}
  143.         return self.session.post("https://www.reddit.com/api/place/draw.json", data=payload)
  144.  
  145.     def draw(self, x=0, y=0, color=0):
  146.         """draw a color at given coordinates
  147.        x: x-coordinates
  148.        y: y-coordinates
  149.        color: color to draw at coordinates
  150.        """
  151.         self.last = self._draw(x,y, color)
  152.         if self.greedy:
  153.             while self.last.status_code == 429:
  154.                 json = self.last.json()
  155.                 if "wait_seconds" in json:
  156.                     wait=json["wait_seconds"]
  157.                     print("Waiting: {}s".format(wait))
  158.                     sleep(wait)
  159.                 else:
  160.                     sleep(1)
  161.  
  162.                 self.last = self._draw(x,y, color)
  163.         return self.last.json()
  164.  
  165. if __name__ == '__main__':
  166.     main()
Add Comment
Please, Sign In to add comment