diff --git a/main.py b/main.py index 64d13b1..66e957d 100644 --- a/main.py +++ b/main.py @@ -1,117 +1,270 @@ import os -import json -import requests -import glob import exifread - -from PIL import Image, ExifTags +import json +import gettext +import tkinter as tk +from PixelfedAPI import * +from tkinter import filedialog, Menu, Toplevel +from PIL import Image, ImageTk, ExifTags from PIL.ExifTags import TAGS from PIL.PngImagePlugin import PngImageFile, PngInfo -def load_config(file_path): - with open(file_path, "r") as config_file: - config_data = json.load(config_file) - return config_data +class ImageUploaderApp: + def __init__(self, root): + serverURL = self.get_setting_serverURL + serverAccesskey = self.get_setting_accessKey + self.Pixelfed = PixelfedAPI(serverURL, serverAccesskey) -def getTags(file_path): - try: - file = open(file_path,'r') - fileContent = file.read() - file.close - except: - fileContent = '' - return fileContent + self.root = root + self.root.title("Pixelfed Uploader") -def getImages(dir): - result = glob.glob(dir + '/*.jpg') - return result + self.image_paths = [] + self.current_index = 0 -def getItemDescription(filename): - type = Image.open(filename) + self.create_menu() - exif_tags = open(filename, 'rb') - tags = exifread.process_file(exif_tags) + self.button_frame = tk.Frame(self.root) + self.prev_button = tk.Button(self.button_frame, text="Previous", command=self.show_previous_image) + self.prev_button.pack(side=tk.LEFT) + self.canvas = tk.Canvas(self.button_frame, width=400, height=400) + self.canvas.pack(side=tk.LEFT) + self.next_button = tk.Button(self.button_frame, text="Next", command=self.show_next_image) + self.next_button.pack(side=tk.RIGHT) + self.button_frame.pack() - exif_array = [] + self.description_label = tk.Label(self.root, text="Post Content:") + self.description_label.pack() - if type.format != "PNG": - for i in tags: - compile = i, str(tags[i]) - exif_array.append(compile) + self.description_text = tk.Text(self.root, height=10, wrap=tk.WORD) + self.description_text.pack() - if type.format == "PNG": - image = PngImageFile(filename) - metadata = PngInfo() + self.description_length_var = tk.StringVar() + self.description_length_label = tk.Label(self.root, textvariable=self.description_length_var) + self.description_length_label.pack() - for i in image.text: - compile = i, str(image.text[i]) - exif_array.append(compile) + self.description_text.bind("", self.update_description_length) - Description = exif_array[0][1] - return Description + self.tag_text_label = tk.Label(self.root, text="Tags:") + self.tag_text_label.pack() -def mediaUpload(access_token, url, file): - api_url = url + "/api/v1/media" - - headers = { - "Authorization": f"Bearer {access_token}" - } + self.tag_text = tk.Text(self.root, height=5, wrap=tk.WORD) + self.tag_text.pack() - try: - with open(file, "rb") as imageFile: - f = {"file": imageFile} - response = requests.post(api_url, headers=headers, files=f) - response.raise_for_status() # Wirft eine HTTPError-Exception, wenn der Statuscode nicht erfolgreich ist + defaultTags = self.getTags() + self.tag_text.delete("1.0", tk.END) + self.tag_text.insert(tk.END, defaultTags) - try: - data = response.json() - return(data) - except json.decoder.JSONDecodeError: - print("API response contains non-valid JSON data:") - print(response.text) - except requests.exceptions.RequestException as e: - print(f"An error occurred during the API call: {e}") + #self.alt_text_label = tk.Label(self.root, text="Alt-Text:") + #self.alt_text_label.pack() -def createNewPost(access_token, url, ImageID, ImageDescription): - api_url = url + "/api/v1/statuses" - - headers = { - "Authorization": f"Bearer {access_token}" - } + #self.alt_text = tk.Text(self.root, height=10, wrap=tk.WORD) + #self.alt_text.pack() - data = { - "status": ImageDescription, - "media_ids": [ImageID] - } + #self.alt_length_var = tk.StringVar() + #self.alt_length_label = tk.Label(self.root, textvariable=self.alt_length_var) + #self.alt_length_label.pack() - try: - response = requests.post(api_url, headers=headers, json=data) + #self.alt_text.bind("", self.update_alt_length) + + self.upload_button = tk.Button(self.root, text="Upload", command=self.upload_image) + self.upload_button.pack() + + self.open_folder() + + def open_folder(self): + self.load_images() + + def create_menu(self): + self.menu_bar = Menu(self.root) + self.root.config(menu=self.menu_bar) + + self.file_menu = Menu(self.menu_bar, tearoff=0) + self.menu_bar.add_cascade(label="File", menu=self.file_menu) + self.file_menu.add_command(label="Open Folder", command=self.load_images) + self.file_menu.add_command(label="Settings", command=self.open_settings) + + def open_settings(self): + settings_window = Toplevel(self.root) + settings_window.title("Settings") + settings_window.geometry("500x250") + + server_url_label = tk.Label(settings_window, text="Server-URL:") + server_url_label.pack() + server_url_entry = tk.Entry(settings_window, width=50) + server_url_entry.pack() + + access_key_label = tk.Label(settings_window, text="API AccessKey:") + access_key_label.pack() + access_key_entry = tk.Entry(settings_window, width=50) + access_key_entry.pack() + + image_folder_label = tk.Label(settings_window, text="Default Folder:") + image_folder_label.pack() + image_folder_entry = tk.Entry(settings_window, width=50) + image_folder_entry.pack() + + enableLogVar = tk.BooleanVar() + enableLog_label = tk.Label(settings_window, text="Log:") + enableLog_label.pack() + enableLog = tk.Checkbutton(settings_window, variable=enableLogVar) + enableLog.pack() + + save_button = tk.Button(settings_window, text="Speichern", command=lambda: self.save_settings(server_url_entry.get(), access_key_entry.get(), image_folder_entry.get(), enableLogVar.get())) + save_button.pack() + + config = self.load_config() + if config: + server_url_entry.insert(0, config.get("server_url", "")) + access_key_entry.insert(0, config.get("access_token", "")) + image_folder_entry.insert(0, config.get("image_path", "")) + + def load_config(self): try: - responsedata = response.json() - return(responsedata) - except json.decoder.JSONDecodeError: - print("API response contains non-valid JSON data:") - print(response.text) - except requests.exceptions.RequestException as e: - print(f"An error occurred during the API call: {e}") + with open("config.json", "r") as config_file: + settings = json.load(config_file) + return settings + except FileNotFoundError: + return {} + + def get_config_File(self): + config = self.load_config() -def sendImages(Token, url, imagedir): - files = getImages(imagedir) - tags = getTags("tags.txt") - for f in files: - description = getItemDescription(f) - tagDescription = description + ' ' + tags - newFile = mediaUpload(Token, url, f) - newFileID = newFile.get("id") - createNewPost(Token, url, newFileID, tagDescription) - return True + return config + + def get_setting_serverURL(self): + config = self.get_config_File() + url = config.get("server_url") + + return url + + def get_setting_accessKey(self): + config = self.get_config_File() + accessToken = config.get("access_token") + + return accessToken + + def get_setting_imageFolder(self): + config = self.get_config_File() + imagedir = config.get("image_path") + + return imagedir + + def get_setting_log(self): + config = self.get_config_File() + isLogEnable = config.get("log") + + return isLogEnable + + def save_settings(self, server_url, access_key, image_path, log=False): + settings = { + "server_url": server_url, + "access_token": access_key, + "image_path": image_path, + "log": log + } + + with open("config.json", "w") as config_file: + json.dump(settings, config_file) + + print("Settings have been saved.") + + def update_description_length(self, event): + description = self.description_text.get("1.0", tk.END) + description_length = len(description) + self.description_length_var.set(f"({description_length})") + + def update_alt_length(self, event): + alt = self.alt_text.get("1.0", tk.END) + alt_length = len(alt) + self.alt_length_var.set(f"({alt_length})") + + def load_images(self): + imagedir = self.get_setting_imageFolder() + if not imagedir: + folder_path = filedialog.askdirectory() + else: + folder_path = imagedir + + if folder_path: + self.image_paths = [os.path.join(folder_path, filename) for filename in os.listdir(folder_path) if filename.lower().endswith(('.jpg', '.jpeg'))] + self.current_index = 0 + self.show_current_image() + + def show_current_image(self): + if self.image_paths: + image_path = self.image_paths[self.current_index] + image = Image.open(image_path) + image.thumbnail((400, 400)) + photo = ImageTk.PhotoImage(image) + self.canvas.create_image(0, 0, anchor=tk.NW, image=photo) + self.canvas.image = photo + + description = self.getItemDescription(image_path) + self.description_text.delete("1.0", tk.END) + self.description_text.insert(tk.END, description) + + def getItemDescription(self, filename): + type = Image.open(filename) + + exif_tags = open(filename, 'rb') + tags = exifread.process_file(exif_tags) + + exif_array = [] + + if type.format != "PNG": + for i in tags: + compile = i, str(tags[i]) + exif_array.append(compile) + + if type.format == "PNG": + image = PngImageFile(filename) + metadata = PngInfo() + + for i in image.text: + compile = i, str(image.text[i]) + exif_array.append(compile) + + Description = exif_array[0][1] + return Description + + def getTags(self): + try: + file = open('tags.txt','r') + fileContent = file.read() + file.close + return fileContent + except Exception as e: + print("Error reading File:", e) + return "" + + def show_previous_image(self): + if self.image_paths: + self.current_index = (self.current_index - 1) % len(self.image_paths) + self.show_current_image() + + def show_next_image(self): + if self.image_paths: + self.current_index = (self.current_index + 1) % len(self.image_paths) + self.show_current_image() + + def upload_image(self): + description = self.description_text.get("1.0", tk.END) + description = description + self.tag_text.get("1.0", tk.END) + #alt_text = self.alt_text.get("1.0", tk.END) + selected_image_path = self.image_paths[self.current_index] + + media = self.Pixelfed.mediaUpload(selected_image_path) + if media: + mediaID = media.get("id") + #self.Pixelfed.createNewPost(mediaID, description, alt_text) + self.Pixelfed.createNewPost(mediaID, description) + + print("Post created:") + print("Content:", description) + #print("Alt-Text:", alt_text) + print("Image:", selected_image_path) if __name__ == "__main__": - config_file_path = "config.json" - config = load_config(config_file_path) - - url = config.get("server_url") - accessToken = config.get("access_token") - imagedir = config.get("image_path") - - sendImages(accessToken, url, imagedir) \ No newline at end of file + root = tk.Tk() + app = ImageUploaderApp(root) + root.mainloop()