148 lines
4.8 KiB
Python
148 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
import json
|
|
import os
|
|
import shutil
|
|
import tkinter
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from io import BytesIO
|
|
from pathlib import Path
|
|
|
|
import filetype
|
|
from PIL import Image, ImageTk
|
|
|
|
|
|
class DownloadedData(object):
|
|
def __init__(self, loadfrom=None):
|
|
self.initialize()
|
|
self.loadfrom(loadfrom)
|
|
|
|
def initialize(self):
|
|
self.control = list()
|
|
self.fb = dict()
|
|
|
|
def loadfrom(self, loadfrom):
|
|
if loadfrom:
|
|
with open(os.path.join(loadfrom, 'meta.json')) as f:
|
|
self.control = json.loads(f.read())
|
|
for ctrl in self.control:
|
|
fnm = ctrl['dname']
|
|
cnt = b''
|
|
with open(os.path.join(loadfrom, fnm), 'rb') as f:
|
|
cnt = f.read()
|
|
self.fb[fnm] = cnt
|
|
|
|
def storedLinks(self):
|
|
return [ctrl['link'] for ctrl in self.control]
|
|
|
|
def put(self, link, downloaded, ext=None):
|
|
global rootWindow
|
|
if ext is None:
|
|
try:
|
|
ext = link.rsplit('/', 1)[-1].rsplit('.', 1)[-1]
|
|
if ext not in ['jpg', 'png', 'gif', 'webp']:
|
|
raise Exception
|
|
except:
|
|
ext = filetype.guess_extension(downloaded)
|
|
if ext is None:
|
|
ext = 'unk'
|
|
fnm = '%04d.%s' % (len(self.control), ext)
|
|
self.control.append({
|
|
'dname': fnm,
|
|
'link': link,
|
|
'ext': ext,
|
|
})
|
|
self.fb[fnm] = downloaded
|
|
if userWantsPreview and rootWindow is None:
|
|
rootWindow = MainApp()
|
|
if rootWindow is not None and downloaded is not None:
|
|
try:
|
|
rootWindow.update_image(Image.open(BytesIO(downloaded)), link)
|
|
except:
|
|
pass
|
|
if (pth := Path('latest_put_image.file')).exists():
|
|
pth.unlink()
|
|
Path('latest_put_image.url').write_text(link)
|
|
Path('latest_put_image.file').write_bytes(downloaded)
|
|
|
|
def remove(self, directory):
|
|
directory = os.path.abspath(directory)
|
|
if os.path.exists(directory):
|
|
shutil.rmtree(directory)
|
|
|
|
def into(self, directory):
|
|
self.remove(directory)
|
|
directory = os.path.abspath(directory)
|
|
os.makedirs(directory)
|
|
try:
|
|
with open(os.path.join(directory, 'meta.json'), 'w') as f:
|
|
f.write(json.dumps(self.control, sort_keys=True, indent=2))
|
|
for seq, (fnm, dtb) in enumerate(self.fb.items()):
|
|
with open(os.path.join(directory, fnm), 'wb') as f:
|
|
f.write(dtb)
|
|
print(' '*50, end='', flush=True)
|
|
print('\r', end='', flush=True)
|
|
print(f' `--> Saving image {seq+1} of {len(self.fb)}', end='', flush=True)
|
|
print('\r', end='', flush=True)
|
|
except KeyboardInterrupt as e:
|
|
shutil.rmtree(directory)
|
|
raise e
|
|
|
|
def merge(self, other):
|
|
for oitem in other.control:
|
|
self.put(oitem['link'], other.fb[oitem['dname']], oitem['ext'])
|
|
|
|
def bulk_merge(self, others):
|
|
for other in others:
|
|
self.merge(other)
|
|
|
|
|
|
class MainApp(tkinter.Tk):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.geometry('500x500')
|
|
self.known_width = 500
|
|
self.known_height = 500
|
|
self.resizable(width=True, height=True)
|
|
self.photo = Image.new('RGB', (256,256), (0,0,0))
|
|
self.display_photo = self.photo.copy()
|
|
self.image = ImageTk.PhotoImage(self.display_photo)
|
|
self.frame = tkinter.Frame(self)
|
|
self.frame.pack(fill=tkinter.BOTH, expand=tkinter.YES)
|
|
self.panel = tkinter.Label(self.frame)
|
|
self.panel.pack(fill=tkinter.BOTH, expand=tkinter.YES)
|
|
self.panel.bind('<Configure>', self._resize_image)
|
|
self.panel.configure(image=self.image)
|
|
self.update()
|
|
self._resize_image2()
|
|
self.update()
|
|
|
|
def _resize_image(self, event):
|
|
self.known_width = event.width
|
|
self.known_height = event.height
|
|
self._resize_image2()
|
|
|
|
def _resize_image2(self):
|
|
size_tuple = (self.known_width, self.known_height)
|
|
self.display_photo = self.photo.copy()
|
|
self.display_photo.thumbnail(size_tuple)
|
|
if self.display_photo is None:
|
|
self.display_photo = self.photo
|
|
self.image = ImageTk.PhotoImage(self.display_photo)
|
|
self.panel.configure(image=self.image)
|
|
|
|
def update_image(self, image, windowTile=None):
|
|
if windowTile is not None:
|
|
self.winfo_toplevel().title(str(windowTile))
|
|
self.photo = image
|
|
self._resize_image2()
|
|
self.update()
|
|
|
|
|
|
userWantsPreview = False
|
|
rootWindow = None
|
|
|
|
if 'REDDITGETTER_PREVIEW' in os.environ and os.environ['REDDITGETTER_PREVIEW'] != '':
|
|
userWantsPreview = True
|