1+ import tkinter as tk
2+ from PIL import Image , ImageTk
3+ import io
4+ from random import randint
5+ import asyncio
6+ import time
7+ import aiohttp
8+ import os
9+ from pygame import mixer
10+
11+
12+ class Tinder :
13+ def __init__ (self ):
14+ mixer .init ()
15+ self .dir = os .path .dirname (os .path .realpath (__file__ ))
16+ self .root = tk .Tk ()
17+ self .root .title ("Cat Tinder" )
18+ self .root .geometry ("400x500" )
19+ self .root .configure (background = 'grey' )
20+ self .root .protocol ("WM_DELETE_WINDOW" , self .on_closing )
21+ #self.root.bind('<Motion>', self.motion)
22+ self .loop = asyncio .get_event_loop ()
23+ self .session = None
24+ self .images = list ()
25+
26+
27+ def start (self ):
28+ self .loop .run_until_complete (self .get_cache ())
29+ self .new_image ()
30+
31+ async def get_cache (self ):
32+ print ("refreshing image cache" )
33+ t = time .time ()
34+ if not self .session :
35+ headers = {'x-api-key' : 'd12e9702-f791-4d13-9ffd-0edeed9cecaf' }
36+ self .session = aiohttp .ClientSession (headers = headers )
37+ for _ in range (10 ):
38+ if randint (0 ,10 ) == 9 :
39+ image_number = randint (1 ,10 )
40+ im = Image .open (os .path .join (self .dir , os .path .join ("res" , os .path .join ("images" , f"{ image_number } .jpg" ))))
41+ im = im .resize ((400 , 400 ), Image .NEAREST )
42+ image = ImageTk .PhotoImage (im )
43+ self .images .append ([image , True ])
44+ else :
45+ async with self .session .get ('https://api.thecatapi.com/v1/images/search' ) as res :
46+ data = await res .json ()
47+ url = data [0 ]['url' ]
48+ async with self .session .get (url ) as res :
49+ image_bytes = await res .read ()
50+ im = Image .open (io .BytesIO (image_bytes ))
51+ im = im .resize ((400 , 400 ), Image .NEAREST )
52+ image = ImageTk .PhotoImage (im )
53+ self .images .append ([image , False ])
54+ print (time .time ()- t )
55+
56+
57+ def all_children (self ):
58+ children = self .root .winfo_children ()
59+ for item in children :
60+ if item .winfo_children ():
61+ children .extend (item .winfo_children ())
62+ return children
63+
64+
65+ def new_image (self ):
66+ widget_list = self .all_children ()
67+ for item in widget_list :
68+ item .pack_forget ()
69+ self .frame = tk .Frame (self .root , bg = "black" )
70+ try :
71+ image , jumpscare = self .images .pop (0 )
72+ except IndexError :
73+ self .loop .run_until_complete (self .get_cache ())
74+ image , jumpscare = self .images .pop (0 )
75+ label = tk .Label (self .frame , image = image )
76+ label .pack (side = tk .TOP , fill = "both" , expand = "yes" )
77+ like = tk .Button (self .frame , text = "Like" , background = "green" , command = self .new_image )
78+ like .pack (side = tk .RIGHT )
79+ dislike = tk .Button (self .frame , text = "Dislike" , background = "red" , command = self .new_image )
80+ dislike .pack (side = tk .LEFT )
81+ if jumpscare :
82+ mixer .music .load (os .path .join (self .dir , os .path .join ("res" , os .path .join ("sounds" , "jumpscare.mp3" ))))
83+ mixer .music .play ()
84+ self .frame .pack ()
85+ self .root .mainloop ()
86+
87+
88+ def on_closing (self ):
89+ x = randint (0 , 1520 )
90+ y = randint (0 , 580 )
91+ self .root .geometry (f"+{ x } +{ y } " )
92+
93+
94+ def motion (self ,event ):
95+ frame_x , frame_y = self .frame .winfo_x (), self .frame .winfo_y ()
96+ x , y = event .x , event .y
97+ if x > 300 and y < 15 :
98+ move_x = (400 - x ) + frame_x
99+ move_y = (15 - y ) - frame_y
100+ self .root .geometry (f"400x500+{ move_x } +{ move_y } " )
101+
102+ if __name__ == "__main__" :
103+ Tinder ().start ()
0 commit comments