Ejemplo n.º 1
0
class PhotoSphere(Frame):
    def __init__(self, master=None):

        Frame.__init__(self, master)

        self.master = master

        self.styles = get_styles()

        self.btn_small_styles = self.styles.copy()
        self.btn_small_styles['padx'] = 7
        self.btn_small_styles['pady'] = 0
        self.btn_small_styles['big_font'] = Font(size=18,
                                                 family="Century Gothic"),

        self.entry_arr = []

        self.num_spaces = 0

        self.rand_word = Rand_Word()

        # self.zoom_amount = 1.0

        self.init_window()

    def init_window(self):
        self.master.title("PhotoSphere")
        self.configure(bg=self.styles['bg'])
        self.pack(fill=BOTH, expand=1)

        # root.tk.call('tk', 'scaling', self.zoom_amount)

        self.container = LabelFrame(self,
                                    bg=self.styles['bg'],
                                    fg=self.styles['fg'],
                                    borderwidth=0)
        self.container.pack(fill=BOTH, expand=1)

        # ------------------- The Menu ---------------------------
        self.menu_structure = [{
            'text': "ClearFresh ⏚",
            'title': "Delete all photos and history in selected folder",
            'command': self.truncate,
            'disabled': False,
            'static': True
        }, {
            'text': "MyTerms ↂ",
            'title':
            "The list of words that will be\nused during the replacement of all your photos",
            'command': self.edit_myterms,
            'disabled': False,
            'static': True
        }, {
            'text': "AutoGet ∯",
            'title':
            "Replace all photos with photos based\non keywords that are chosen by you",
            'command': self.autoget,
            'disabled': False,
            'static': True
        }, {
            'text': "Preferences ƛ",
            'title': None,
            'command': self.edit_preferences,
            'disabled': False,
            'static': True
        }, {
            'text': "Open Active Folder Θ",
            'title': None,
            'command': self.open_active_folder,
            'disabled': False,
            'static': True
        }, {
            'text': "Active folder: " + get_path(),
            'title': None,
            'command': '',
            'disabled': True,
            'static': False
        }]
        self.menu = App_Menu(self.container,
                             root=root,
                             styles=self.styles,
                             structure=self.menu_structure)
        self.menu.pack()

        self.progressbar = App_Progressbar(self.container,
                                           root=root,
                                           below=self.menu,
                                           styles=self.styles)

        # ------------------- The Input Form ---------------------------
        input_field_wrapper = LabelFrame(self.container,
                                         bg=self.styles['bg'],
                                         borderwidth=0)

        # Input
        self.search_entry = App_Entry(input_field_wrapper,
                                      placeholder="Search Images",
                                      styles=self.styles,
                                      entry_arr=self.entry_arr)
        self.search_entry.bind_to_entry("<Return>", self.initiate_download)
        self.search_entry.pack(side=LEFT)

        # Input
        self.rand_word_btn = App_Button(
            input_field_wrapper,
            text="⚙",
            styles=self.btn_small_styles,
            title="Generate a random word, for inspiration",
            command=self.set_rand_word).pack(side=LEFT, padx=15)

        # Input
        self.num_select = App_Num_Select(
            input_field_wrapper,
            min_amount=1,
            styles=self.styles,
            title="The number of images to download")
        self.num_select.pack(side=LEFT)

        self.path_var = get_path()
        # Input
        self.path_btn = App_Button(
            input_field_wrapper,
            text="...",
            styles=self.btn_small_styles,
            command=self.select_file,
            title="Select the target folder for the images")
        self.path_btn.pack(side=LEFT, padx=10)

        input_field_wrapper.pack(pady=(40, 0))

        # Input
        self.download_btn = App_Button(
            self.container,
            text="Download ⤓",
            styles=self.styles,
            command=self.initiate_download).pack(pady=(30, 0))

        self.photo_container = LabelFrame(self.container,
                                          bg=self.styles['bg'],
                                          borderwidth=0)
        self.photo_container.pack(fill=BOTH, expand=1)

        self.download_handle = Download(photo_container=self.photo_container,
                                        root=root)

        fab_structure = [{
            "text": "Hide Ƣ",
            "title": "Hide all Photos on screen",
            "command": self.hide_all_photos
        }, {
            "text": "Delete ɶ",
            "title": "Delete all Photos on screen",
            "command": self.del_all_photos
        }]
        self.fab = App_Fab(self.container,
                           structure=fab_structure,
                           styles=self.styles,
                           root=root)
        self.fab.put()

        # ---------------------- Other -----------------------
        self.truncate_confirm = App_Confirm(
            self,
            text="Are you sure you want to delete all files in \"" +
            self.path_var + "\"",
            styles=self.styles,
            size_determiner="\"" + self.path_var + "\"",
            root=root)

        self.error = App_Popover(self, styles=self.styles)

    # ---------------------- Functions -----------------------------
    def global_onclick(self, event):
        widget = event.widget
        widget_class = widget.winfo_class()

        if widget_class == "Button":
            widget.config(relief=FLAT)

        widget_parent = widget.winfo_parent()

        entry_name_arr = [
            e.winfo_pathname(e.winfo_id()) for e in self.entry_arr
        ]

        if widget_parent not in entry_name_arr or widget not in entry_name_arr:

            if widget_parent in entry_name_arr:
                index = entry_name_arr.index(widget_parent)
                self.entry_arr[index]._focus()
            elif widget in entry_name_arr:
                index = entry_name_arr.index(
                    widget.winfo_pathname(widget.winfo_id()))
                self.entry_arr[index]._focus()
            else:
                root.focus()
                for e in self.entry_arr:
                    e.blur()
                self.search_entry.check_to_blur()

    def set_rand_word(self):
        word = self.rand_word.get_rand_word()
        self.search_entry.delete(0, END)
        self.search_entry.insert(0, word)
        self.search_entry._focus()
        self.validate()

    def refresh_menu(self, filename):
        space = " " if self.num_spaces % 2 == 0 else ""
        self.num_spaces += 1

        for i in range(len(self.menu_structure)):
            if self.menu_structure[i]['static'] == True:
                self.menu.set_text(i, self.menu_structure[i]['text'] + space)

        self.menu.set_text(5, "Active folder: " + filename)

    def select_file(self):
        filename = filedialog.askdirectory()
        if len(filename) > 0:
            set_path(filename)
            self.path_var = filename

            self.truncate_confirm.update(
                "Are you sure you want to delete all files in " + filename)

            self.refresh_menu(filename)

            toast = App_Toast(self,
                              text="Active Folder Updated",
                              styles=self.styles,
                              root=root)
            del toast

    def truncate(self):
        def process():
            def thread():
                truncate(self.path_var)
                self.truncate_confirm.hide()
                toast = App_Toast(self,
                                  text="Folder Cleared",
                                  styles=self.styles,
                                  root=root)
                del toast
                self.download_handle.del_photo_rows()

            t = threading.Thread(target=thread)
            t.daemon = True
            t.start()

        self.truncate_confirm.show(process)

    def validate(self):
        query = self.search_entry.get()
        amount = self.num_select.get()
        savepath = self.path_var

        if len(query) < 1:
            self.error.set_text("Enter a search")
            self.error.move(target=self.search_entry, anchor="left")
            return False

        elif not os.path.isdir(savepath):
            self.error.set_text("Select a valid folder")
            self.error.move(target=self.path_btn, anchor="right")
            return False

        else:
            self.error.hide()
            return True

    def initiate_download(self, event=None):
        valid = self.validate()
        self.progressbar.set_pct(3)
        self.progressbar.show()
        if valid:
            query = self.search_entry.get()
            amount = self.num_select.get()
            savepath = self.path_var

            self.download_handle.set_query(query)
            self.download_handle.set_amount(amount)
            self.download_handle.set_savepath(savepath)
            self.download_handle.set_progressbar(self.progressbar)
            self.download_handle.set_window_width(self.winfo_width())

            def process():
                self.progressbar.set_pct(10)
                num_hits = self.download_handle.set_hits()
                if num_hits > 0:
                    self.progressbar.set_pct(25)
                else:
                    toast = App_Toast(self,
                                      text="No Hits, try again",
                                      styles=self.styles,
                                      root=root)
                    del toast
                    self.progressbar.hide()

                self.download_handle.download_and_show()

            t = threading.Thread(target=process)
            t.daemon = True
            t.start()

    def edit_myterms(self):
        self.new_window = Toplevel(self)
        self.myterms_window = Edit_Myterms(self.new_window)
        self.myterms_window.focus()

    def edit_preferences(self):
        self.new_window = Toplevel(self)
        self.preferences_window = Edit_Preferences(self.new_window)
        self.preferences_window.focus()

    def autoget(self):
        structure = [{
            'label': "Number of Categories: ",
            'widget_class': 'App_Num_Select',
            'widget_args': {
                'min_amount': 1,
                'styles': self.styles
            }
        }, {
            'label': "Number of Photos in each Categories: ",
            'widget_class': 'App_Num_Select',
            'widget_args': {
                'min_amount': 1,
                'styles': self.styles
            }
        }]

        def process(results=None):
            hidden_progressbar = App_Progressbar(self.container,
                                                 root=root,
                                                 below=self.menu,
                                                 styles=self.styles)
            self.pct_complete = 0

            def thread():
                num_categories, num_per_category = results

                self.download_handle.set_window_width(self.winfo_width())
                self.download_handle.set_progressbar(hidden_progressbar)
                self.download_handle.set_savepath(self.path_var)
                self.download_handle.set_amount(num_per_category)
                self.pct_complete += 3
                self.progressbar.set_pct(self.pct_complete)
                self.progressbar.show()

                approved_categories = []
                while True:
                    category = self.rand_word.get_rand_word()
                    self.download_handle.set_query(category)
                    num_hits = self.download_handle.set_hits()
                    if num_hits > num_per_category + 1:
                        approved_categories.append(category)
                        self.pct_complete += 15
                        self.progressbar.set_pct(self.pct_complete)
                    if len(approved_categories) == num_categories:
                        break
                categories_str = ", ".join(approved_categories)
                toast = App_Toast(self,
                                  text=categories_str,
                                  styles=self.styles,
                                  root=root)
                del toast
                self.progressbar.set_pct(25)

                for category in approved_categories:
                    self.download_handle.set_query(category)
                    self.download_handle.download_and_show()
                    self.pct_complete += int((100 - self.pct_complete) /
                                             num_categories / num_per_category)
                    self.progressbar.set_pct(self.pct_complete)

                toast = App_Toast(self,
                                  text="Finished",
                                  styles=self.styles,
                                  root=root)
                del toast
                self.progressbar.hide()

            t = threading.Thread(target=thread)
            t.daemon = True
            t.start()

        prompt = App_Prompt(self,
                            root=root,
                            structure=structure,
                            styles=self.styles,
                            command=process)
        prompt.show()

    def open_active_folder(self):
        def process():
            path = self.path_var
            path = os.path.realpath(path)
            os.startfile(path)

        t = threading.Thread(target=process)
        t.daemon = True
        t.start()

    def hide_all_photos(self, event=None):
        for i in range(len(self.download_handle.app_photo_arr)):
            app_photo = self.download_handle.app_photo_arr[i]
            self.download_handle.hide_photo(photo_label=app_photo,
                                            edit_arr=False)
        self.download_handle.app_photo_arr.clear()

    def del_all_photos(self, event=None):
        for i in range(len(self.download_handle.app_photo_arr)):
            app_photo = self.download_handle.app_photo_arr[i]
            self.download_handle.del_photo(photo_label=app_photo,
                                           photo_path=app_photo.fullsize_path,
                                           edit_arr=False)
        self.download_handle.app_photo_arr.clear()