示例#1
0
def nacti_cislo(otazka='Zadej číslo'):
    """Zeptá se uživatele na otázku a vrátí odpověď jako celé číslo."""
    root = Tk()
    root.title(otazka)

    entry = Spinbox(root, from_=0, to=100)
    entry.set('0')
    entry.pack(side=LEFT)

    # Předbíháme: vnořená funkce může přistupovat
    # k proměnným "entry" a "root", které jsou
    # lokální pro "vnější" funkci (nacti_cislo)

    def ok_pressed():
        text = entry.get()
        try:
            value = int(text)
        except ValueError:
            entry.set('sem zadej číslo!')
        else:
            root.quit()

    button = Button(root, text="OK", command=ok_pressed)
    button.pack(side=RIGHT)

    root.mainloop()

    value = int(entry.get())
    root.destroy()

    return value
示例#2
0
def startPassGen():
    global root
    root = Toplevel()
    root.attributes('-topmost', True)
    root.title("  Password Generator")
    root.geometry("350x380")
    # root.resizable(0,0)
    root.configure(bg="white")
    root.iconphoto(True, PhotoImage(file=assetpath + 'padlock.png'))
    root.tk.call('tk', 'scaling', 1.6)

    style = Style()
    style.configure("TLabel", background="white")
    style.configure('TCheckbutton', background='white')

    mainf = Frame(root, bg="white")
    mainf.pack(pady=20, padx=20, ipadx=10, ipady=10)

    f1 = Frame(mainf, bg="white")
    f1.pack()
    icon = ImageTk.PhotoImage(
        Image.open(assetpath + 'key.png').resize((45, 45)))
    Label(f1, image=icon, bg="white").grid(row=0,
                                           column=0,
                                           rowspan=2,
                                           padx=2,
                                           pady=5)
    Label(f1, text="Pass-Gen", font=('ARIAL', 15, 'bold'),
          bg="white").grid(row=0, column=2)
    Label(f1, text="Password Generator", bg="white").grid(row=1, column=2)

    f2 = Frame(mainf, bg="white")
    f2.pack(padx=10, pady=(30, 15))
    global passe
    passe = Entry(f2, width=30)
    passe.pack(side=LEFT)
    copyi = ImageTk.PhotoImage(
        Image.open(assetpath + 'copy.png').resize((25, 25)))
    copyb = Button(f2,
                   image=copyi,
                   bg="white",
                   bd=0,
                   activebackground="white",
                   command=lambda: copy2clip(passe.get()))
    copyb.pack(side=LEFT, padx=2)

    global length
    length = 8

    lenf = Frame(mainf)
    lenf.pack()
    Label(lenf, text="Length  ", bg="white").pack(side=LEFT)
    s = Spinbox(lenf,
                from_=4,
                to=25,
                width=5,
                command=lambda: setlength(s.get()))
    s.set(8)
    s.pack(side=LEFT)

    upper = BooleanVar()
    digit = BooleanVar()
    special = BooleanVar()
    upper.set(True)
    digit.set(True)
    special.set(True)
    f3 = Frame(mainf, bg="white")
    f3.pack(padx=10, pady=10)
    capb = Checkbutton(f3,
                       text="Include Capitals",
                       variable=upper,
                       offvalue=False,
                       onvalue=True)
    capb.pack(anchor=W, pady=5)
    digitb = Checkbutton(f3,
                         text="Include Digits",
                         variable=digit,
                         offvalue=False,
                         onvalue=True)
    digitb.pack(anchor=W, pady=5)
    specialb = Checkbutton(f3,
                           text="Include Special Symbols",
                           variable=special,
                           offvalue=False,
                           onvalue=True)
    specialb.pack(anchor=W, pady=5)

    genb = Button(mainf,
                  text="Generate",
                  command=lambda: passGen(length, upper.get(), digit.get(),
                                          special.get()),
                  bg="turquoise3",
                  activebackground="turquoise3",
                  bd=0)
    genb.pack(pady=10, ipadx=20, padx=(43, 10), side=LEFT)
    exitb = Button(mainf,
                   text="Exit",
                   command=exitPassGen,
                   bg="firebrick1",
                   activebackground="firebrick1",
                   bd=0,
                   width=37)
    exitb.pack(pady=10, ipadx=20, padx=(10, 30), side=LEFT)

    root.mainloop()
示例#3
0
class Window:
    def __init__(self, workstation: WorkstationSettings,
                 wallpaper: Image.Image):
        self._root = Tk()
        self._root.title("wallcrop")
        self._root.minsize(*_MINSIZE)

        self._show_monitor_labels = BooleanVar(self._root, value=False)
        self._show_unselected_area = BooleanVar(self._root, value=True)

        frame = Frame(self._root, padding=_PADDING)
        frame.grid(column=0, row=0, sticky="n w s e")
        self._root.columnconfigure(0, weight=1)  # type: ignore
        self._root.rowconfigure(0, weight=1)  # type: ignore

        frame_top = Frame(frame)
        frame_top.grid(column=0, row=0, sticky="n w s e")

        frame_bot = Frame(frame)
        frame_bot.grid(column=0, row=2, sticky="n w s e")

        self._selection = Selection(aspect_ratio=np.divide(*wallpaper.size))
        self._selection.register_onchange_handler(self._reset_spinbox_values)

        self._selection_widget = SelectionWidget(
            parent=frame,
            workstation=workstation,
            wallpaper=wallpaper,
            selection=self._selection,
        )
        self._selection_widget.set_show_monitor_labels(
            self._show_monitor_labels.get())
        self._selection_widget.set_show_unselected_area(
            self._show_unselected_area.get())
        self._selection_widget.grid(column=0,
                                    row=1,
                                    sticky="n w s e",
                                    pady=_PADDING)
        frame.columnconfigure(0, weight=1)  # type: ignore
        frame.rowconfigure(1, weight=1)  # type: ignore

        label_wallpaper = Label(frame_top, text=workstation.name)
        label_wallpaper.grid(column=0, row=0)

        # Center columns 1-6 on frame_bot.
        frame_bot.columnconfigure(0, weight=1)  # type: ignore
        frame_bot.columnconfigure(7, weight=1)  # type: ignore

        # TODO: Figure out how to not have spinbox show zero when using
        #  increment/decrement buttons.
        label_selection_position_x = Label(frame_bot, text="X: ")
        label_selection_position_x.grid(column=1, row=0)
        self._spinbox_selection_position_x = Spinbox(frame_bot,
                                                     width=5,
                                                     validate="focusout")
        self._spinbox_selection_position_x.grid(column=2, row=0)

        label_selection_position_y = Label(frame_bot, text="  Y: ")
        label_selection_position_y.grid(column=3, row=0)
        self._spinbox_selection_position_y = Spinbox(frame_bot,
                                                     width=5,
                                                     validate="focusout")
        self._spinbox_selection_position_y.grid(column=4, row=0)

        label_selection_zoom = Label(frame_bot, text="  Zoom: ")
        label_selection_zoom.grid(column=5, row=0)
        self._spinbox_selection_zoom = Spinbox(frame_bot,
                                               width=5,
                                               validate="focusout")
        self._spinbox_selection_zoom.grid(column=6, row=0)

        self._bind_actions()
        self._set_up_menubar()
        self._reset_spinbox_values()

    def _bind_actions(self) -> None:
        self._root.bind("<Escape>", lambda _event: self.quit())
        self._root.bind("<q>", lambda _event: self.quit())

        self._root.bind(
            "<m>",
            lambda _event: self._show_monitor_labels.set(not (
                self._show_monitor_labels.get())),
        )
        self._root.bind(
            "<n>",
            lambda _event: self._show_unselected_area.set(not (
                self._show_unselected_area.get())),
        )

        self._root.bind("<i>", lambda _event: self._selection.zoom_increase())
        self._root.bind(
            "<I>", lambda _event: self._selection.zoom_increase(precise=True))

        self._root.bind("<o>", lambda _event: self._selection.zoom_decrease())
        self._root.bind(
            "<O>", lambda _event: self._selection.zoom_decrease(precise=True))

        self._root.bind("<h>", lambda _event: self._selection.move_left())
        self._root.bind("<H>",
                        lambda _event: self._selection.move_left(precise=True))
        self._root.bind("<Left>", lambda _event: self._selection.move_left())
        self._root.bind("<Shift-Left>",
                        lambda _event: self._selection.move_left(precise=True))

        self._root.bind("<l>", lambda _event: self._selection.move_right())
        self._root.bind(
            "<L>", lambda _event: self._selection.move_right(precise=True))
        self._root.bind("<Right>", lambda _event: self._selection.move_right())
        self._root.bind(
            "<Shift-Right>",
            lambda _event: self._selection.move_right(precise=True))

        self._root.bind("<k>", lambda _event: self._selection.move_up())
        self._root.bind("<K>",
                        lambda _event: self._selection.move_up(precise=True))
        self._root.bind("<Up>", lambda _event: self._selection.move_up())
        self._root.bind("<Shift-Up>",
                        lambda _event: self._selection.move_up(precise=True))

        self._root.bind("<j>", lambda _event: self._selection.move_down())
        self._root.bind("<J>",
                        lambda _event: self._selection.move_down(precise=True))
        self._root.bind("<Down>", lambda _event: self._selection.move_down())
        self._root.bind("<Shift-Down>",
                        lambda _event: self._selection.move_down(precise=True))

        self._spinbox_selection_position_x.configure(
            validatecommand=lambda *_args: self._set_selection_position_x())
        self._spinbox_selection_position_x.bind(
            "<Return>",
            lambda _event: self._set_selection_position_x()  # type: ignore
        )
        self._spinbox_selection_position_x.bind(
            "<<Decrement>>", lambda _event: self._selection.move_left())
        self._spinbox_selection_position_x.bind(
            "<<Increment>>", lambda _event: self._selection.move_right())

        self._spinbox_selection_position_y.configure(
            validatecommand=lambda *_args: self._set_selection_position_y())
        self._spinbox_selection_position_y.bind(
            "<Return>",
            lambda _event: self._set_selection_position_y()  # type: ignore
        )
        self._spinbox_selection_position_y.bind(
            "<<Decrement>>", lambda _event: self._selection.move_up())
        self._spinbox_selection_position_y.bind(
            "<<Increment>>", lambda _event: self._selection.move_down())

        self._spinbox_selection_zoom.configure(
            validatecommand=lambda *_args: self._set_selection_zoom())
        self._spinbox_selection_zoom.bind(
            "<Return>",
            lambda _event: self._set_selection_zoom()  # type: ignore
        )
        self._spinbox_selection_zoom.bind(
            "<<Decrement>>", lambda _event: self._selection.zoom_decrease())
        self._spinbox_selection_zoom.bind(
            "<<Increment>>", lambda _event: self._selection.zoom_increase())

        self._show_monitor_labels.trace_add(
            "write",
            lambda *_args: self._selection_widget.set_show_monitor_labels(
                self._show_monitor_labels.get()),
        )
        self._show_unselected_area.trace_add(
            "write",
            lambda *_args: self._selection_widget.set_show_unselected_area(
                self._show_unselected_area.get()),
        )

    def _set_up_menubar(self) -> None:
        # TODO: check that this look good on macOS, as described here:
        #   https://tkdocs.com/tutorial/menus.html#platformmenus

        self._root.option_add("*tearOff", False)

        menu = Menu(self._root)

        menu_file = Menu(menu)
        menu_file.add_command(  # type: ignore
            label="Quit",
            underline=0,
            accelerator="Q, Escape",
            command=self.quit)
        menu.add_cascade(menu=menu_file, label="File",
                         underline=0)  # type: ignore

        menu_edit = Menu(menu)
        menu_edit.add_command(  # type: ignore
            label="Move Left",
            underline=5,
            accelerator="H, Left",
            command=self._selection.move_left,
        )
        menu_edit.add_command(  # type: ignore
            label="Move Right",
            underline=5,
            accelerator="L, Right",
            command=self._selection.move_right,
        )
        menu_edit.add_command(  # type: ignore
            label="Move Up",
            underline=5,
            accelerator="K, Up",
            command=self._selection.move_up,
        )
        menu_edit.add_command(  # type: ignore
            label="Move Down",
            underline=5,
            accelerator="J, Down",
            command=self._selection.move_down,
        )
        menu_edit.add_separator()  # type: ignore
        menu_edit.add_command(  # type: ignore
            label="Increase Zoom",
            underline=0,
            accelerator="I",
            command=self._selection.zoom_increase,
        )
        menu_edit.add_command(  # type: ignore
            label="Decrease Zoom",
            underline=10,
            accelerator="O",
            command=self._selection.zoom_decrease,
        )
        menu.add_cascade(menu=menu_edit, label="Edit",
                         underline=0)  # type: ignore

        menu_view = Menu(menu)
        menu_view.add_checkbutton(  # type: ignore
            label="Label Monitors",
            variable=self._show_monitor_labels,
            underline=6,
            accelerator="M",
        )
        menu_view.add_checkbutton(  # type: ignore
            label="Show Unselected",
            variable=self._show_unselected_area,
            underline=6,
            accelerator="N",
        )
        menu.add_cascade(menu=menu_view, label="View",
                         underline=0)  # type: ignore

        menu_help = Menu(menu, name="help")
        menu_help.add_command(  # type: ignore
            label="About Wallcrop",
            underline=0,
            command=lambda: messagebox.showinfo(
                parent=self._root,
                title="About Wallcrop",
                message=f"Wallcrop {wallcrop.__version__}",
                detail=("Copyright 2021 Lukas Schmelzeisen.\n"
                        "Licensed under the Apache License, Version 2.0.\n"
                        "https://github.com/lschmelzeisen/wallcrop/"),
            ),
        )
        menu.add_cascade(menu=menu_help, label="Help",
                         underline=3)  # type: ignore

        self._root["menu"] = menu

    def mainloop(self) -> None:
        self._root.mainloop()

    def quit(self) -> None:
        self._root.destroy()

    def _set_selection_position_x(self) -> bool:
        try:
            value = float(
                self._spinbox_selection_position_x.get())  # type: ignore
        except ValueError:
            self._spinbox_selection_position_x.set(self._selection.position[0])
            return False
        self._selection.set_position(
            np.array((value, self._selection.position[1])))
        return True

    def _set_selection_position_y(self) -> bool:
        try:
            value = float(
                self._spinbox_selection_position_y.get())  # type: ignore
        except ValueError:
            self._spinbox_selection_position_y.set(self._selection.position[1])
            return False
        self._selection.set_position(
            np.array((self._selection.position[0], value)))
        return True

    def _set_selection_zoom(self) -> bool:
        try:
            value = float(self._spinbox_selection_zoom.get())  # type: ignore
        except ValueError:
            self._spinbox_selection_zoom.set(self._selection.zoom)
            return False
        self._selection.set_zoom(value)
        return True

    def _reset_spinbox_values(self) -> None:
        self._spinbox_selection_position_x.set(
            f"{self._selection.position[0]:.3f}")
        self._spinbox_selection_position_y.set(
            f"{self._selection.position[1]:.3f}")
        self._spinbox_selection_zoom.set(f"{self._selection.zoom:.3f}")
示例#4
0
class Page1(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.style = Style()

        self.time_frame = LabelFrame(self, text='Time Setting')
        self.hour_label = Label(self.time_frame, text='Hours')
        self.hour_box = Spinbox(self.time_frame, from_=0, to=24)

        self.minute_label = Label(self.time_frame, text='Minutes')
        self.minute_box = Spinbox(self.time_frame, from_=0, to=60)

        self.second_label = Label(self.time_frame, text='Seconds')
        self.second_box = Spinbox(self.time_frame, from_=0, to=60)

        self.break_label = Label(self.time_frame, text='Time During Sessions')
        self.break_var = IntVar()
        self.break_var.set(4)
        self.break_radio_button_3 = Radiobutton(self.time_frame,
                                                text='3 min',
                                                variable=self.break_var,
                                                value=3)
        self.break_radio_button_4 = Radiobutton(self.time_frame,
                                                text='4 min',
                                                variable=self.break_var,
                                                value=4)
        self.break_radio_button_5 = Radiobutton(self.time_frame,
                                                text='5 min',
                                                variable=self.break_var,
                                                value=5)
        self.break_radio_button_6 = Radiobutton(self.time_frame,
                                                text='6 min',
                                                variable=self.break_var,
                                                value=6)
        self.break_radio_button_7 = Radiobutton(self.time_frame,
                                                text='7 min',
                                                variable=self.break_var,
                                                value=7)

        self.name_label = Label(self.time_frame, text='Task Name')
        self.name_entry = Entry(self.time_frame)

        self.reminder_label = Label(self.time_frame, text='Reminder')
        self.reminder_entry = Entry(self.time_frame)

        self.generate_button = Button(self,
                                      text='Generate Task',
                                      command=self.create_task)
        self.save_button = Button(self,
                                  text='Save Configuration',
                                  command=self.save_config)
        self.load_button = Button(self,
                                  text='Load Configuration',
                                  command=self.load_config)
        self.clear_button = Button(self, text='Clear', command=self.clear)

        # GRIDDING OPERATIONS
        self.hour_label.grid(row=1, column=0)
        self.hour_box.grid(row=1, column=1)
        self.minute_label.grid(row=1, column=2)
        self.minute_box.grid(row=1, column=3)
        self.second_label.grid(row=1, column=4)
        self.second_box.grid(row=1, column=5)

        self.break_label.grid(row=2, column=0)
        self.break_radio_button_3.grid(row=2, column=1)
        self.break_radio_button_4.grid(row=2, column=2)
        self.break_radio_button_5.grid(row=2, column=3)
        self.break_radio_button_6.grid(row=2, column=4)
        self.break_radio_button_7.grid(row=2, column=5)

        self.name_label.grid(row=3, column=0)
        self.name_entry.grid(row=3, column=1, columnspan=5, sticky='ew')
        self.reminder_label.grid(row=4, column=0)
        self.reminder_entry.grid(row=4, column=1, columnspan=5, sticky='ew')

        self.generate_button.grid(row=1, column=0, sticky='snew')
        self.save_button.grid(row=2, column=0, sticky='snew')
        self.load_button.grid(row=3, column=0, sticky='snew')
        self.clear_button.grid(row=4, column=0, sticky='snew')

        self.time_frame.grid(row=0, column=0)
        self.grid(row=0, column=0)

    def create_task(self):
        # Task signature: (task_name, task_duration, break_duration, task_reminder=None)
        hours = self.hour_box.get()
        minutes = self.minute_box.get()
        seconds = self.second_box.get()
        break_time = self.break_var.get()
        if hours and seconds and minutes:
            total_time = int(hours) * 3600 + int(minutes) * 60 + int(seconds)
            return Task(self.name_entry.get(), total_time, break_time)
        elif hours == 's':
            return Task('sample task', 5, 3 / 60)

    def save_config(self):
        with open('config.pickle', 'wb+') as config:
            pickle.dump(self.create_task(), config)

    def load_config(self):
        with open('config.pickle', 'rb') as config:
            unpickled_task = pickle.load(config)
            Task.tasks.append(unpickled_task)

    def clear(self):
        self.name_entry.delete(0, 'end')
        self.reminder_entry.delete(0, 'end')
        self.hour_box.set('')
        self.minute_box.set('')
        self.second_box.set('')
def set_config():
    sys_para = sys.argv
    file_path = os.path.split(sys_para[0])[0]
    gui = False
    if platform.uname()[0] == 'Windows':  # Win默认打开
        gui = True
    if platform.uname()[0] == 'Linux':  # Linux 默认关闭
        gui = False
    if '--gui' in sys.argv:  # 指定 gui 模式
        gui = True
    if '--nogui' in sys.argv:  # 带 nogui 就覆盖前面Win打开要求
        gui = False

    config_file = os.path.join(file_path, 's3_download_config.ini')
    # If no config file, read the default config
    if not os.path.exists(config_file):
        config_file += '.default'
        print("No customized config, use the default config")
    cfg = ConfigParser()
    print(f'Reading config file: {config_file}')

    try:
        global SrcBucket, S3Prefix, SrcFileIndex, SrcProfileName, DesDir, MaxRetry, MaxThread, MaxParallelFile, LoggingLevel
        cfg.read(config_file, encoding='utf-8-sig')
        SrcBucket = cfg.get('Basic', 'SrcBucket')
        S3Prefix = cfg.get('Basic', 'S3Prefix')
        SrcFileIndex = cfg.get('Basic', 'SrcFileIndex')
        SrcProfileName = cfg.get('Basic', 'SrcProfileName')
        DesDir = cfg.get('Basic', 'DesDir')
        Megabytes = 1024 * 1024
        ChunkSize = cfg.getint('Advanced', 'ChunkSize') * Megabytes
        MaxRetry = cfg.getint('Advanced', 'MaxRetry')
        MaxThread = cfg.getint('Advanced', 'MaxThread')
        MaxParallelFile = cfg.getint('Advanced', 'MaxParallelFile')
        LoggingLevel = cfg.get('Advanced', 'LoggingLevel')
    except Exception as e:
        print("ERR loading s3_download_config.ini", str(e))
        input('PRESS ENTER TO QUIT')
        sys.exit(0)

    if gui:
        # For GUI
        from tkinter import Tk, filedialog, END, StringVar, BooleanVar, messagebox
        from tkinter.ttk import Combobox, Label, Button, Entry, Spinbox, Checkbutton
        # get profile name list in ./aws/credentials
        pro_conf = RawConfigParser()
        pro_path = os.path.join(os.path.expanduser("~"), ".aws")
        cre_path = os.path.join(pro_path, "credentials")
        if os.path.exists(cre_path):
            pro_conf.read(cre_path)
            profile_list = pro_conf.sections()
        else:
            print(
                f"There is no aws_access_key in {cre_path}, please input for S3 Bucket: "
            )
            os.mkdir(pro_path)
            aws_access_key_id = input('aws_access_key_id: ')
            aws_secret_access_key = input('aws_secret_access_key: ')
            region = input('region: ')
            pro_conf.add_section('default')
            pro_conf['default']['aws_access_key_id'] = aws_access_key_id
            pro_conf['default'][
                'aws_secret_access_key'] = aws_secret_access_key
            pro_conf['default']['region'] = region
            profile_list = ['default']
            with open(cre_path, 'w') as f:
                print(f"Saving credentials to {cre_path}")
                pro_conf.write(f)

        # Click Select Folder
        def browse_folder():
            local_dir = filedialog.askdirectory(
                initialdir=os.path.dirname(__file__))
            url_txt.delete(0, END)
            url_txt.insert(0, local_dir)
            file_txt.delete(0, END)
            file_txt.insert(0, "*")
            # Finsih browse folder

        # Click List Buckets
        def ListBuckets(*args):
            SrcProfileName = SrcProfileName_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            bucket_list = []
            try:
                response = client.list_buckets()
                if 'Buckets' in response:
                    bucket_list = [b['Name'] for b in response['Buckets']]
            except Exception as e:
                messagebox.showerror(
                    'Error', f'Failt to List buckets. \n'
                    f'Please verify your aws_access_key of profile: [{SrcProfileName}]\n'
                    f'{str(e)}')
                bucket_list = ['CAN_NOT_GET_BUCKET_LIST']
            SrcBucket_txt['values'] = bucket_list
            SrcBucket_txt.current(0)
            # Finish ListBuckets

        # Click List Prefix
        def ListPrefix(*args):
            SrcProfileName = SrcProfileName_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            prefix_list = []
            this_bucket = SrcBucket_txt.get()
            max_get = 100
            try:
                response = client.list_objects_v2(
                    Bucket=this_bucket,
                    Delimiter='/',
                    RequestPayer='requester'
                )  # Only get the max 1000 prefix for simply list
                if 'CommonPrefixes' in response:
                    prefix_list = [
                        c['Prefix'] for c in response['CommonPrefixes']
                    ]
                if not prefix_list:
                    messagebox.showinfo(
                        'Message', f'There is no "/" Prefix in: {this_bucket}')
                if response['IsTruncated']:
                    messagebox.showinfo(
                        'Message',
                        f'More than {max_get} Prefix, cannot fully list here.')
            except Exception as e:
                messagebox.showinfo(
                    'Error',
                    f'Cannot get prefix list from bucket: {this_bucket}, {str(e)}'
                )
            S3Prefix_txt['values'] = prefix_list
            S3Prefix_txt.current(0)
            # Finish list prefix

        def browse_file(*args):
            SrcProfileName = SrcProfileName_txt.get()
            S3Prefix = S3Prefix_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            file_list = []
            this_bucket = SrcBucket_txt.get()
            max_get = 100
            try:
                response = client.list_objects_v2(
                    Bucket=this_bucket,
                    Prefix=str(PurePosixPath(S3Prefix)) + '/',
                    RequestPayer='requester',
                    Delimiter='/'
                )  # Only get the max 1000 files for simply list

                # For delete prefix in des_prefix
                if S3Prefix == '' or S3Prefix == '/':
                    # 目的bucket没有设置 Prefix
                    dp_len = 0
                else:
                    # 目的bucket的 "prefix/"长度
                    dp_len = len(str(PurePosixPath(S3Prefix))) + 1

                if 'Contents' in response:
                    file_list = [
                        c['Key'][dp_len:] for c in response['Contents']
                    ]  # 去掉Prefix
                if not file_list:
                    messagebox.showinfo(
                        'Message',
                        f'There is no files in s3://{this_bucket}/{S3Prefix}')
                if response['IsTruncated']:
                    messagebox.showinfo(
                        'Message',
                        f'More than {max_get} files, cannot fully list here.')
            except Exception as e:
                messagebox.showinfo(
                    'Error',
                    f'Cannot get file list from bucket s3://{this_bucket}/{S3Prefix}, {str(e)}'
                )
            file_txt['values'] = file_list
            file_txt.current(0)
            # Finish list files

        # Click START button
        def close():
            window.withdraw()
            ok = messagebox.askokcancel(
                'Start downloading job',
                f'DOWNLOAD FROM s3://{SrcBucket_txt.get()}/{S3Prefix_txt.get()}\n'
                f'TO LOCAL {url_txt.get()}\n'
                f'Click OK to START')
            if not ok:
                window.deiconify()
                return
            window.quit()
            return
            # Finish close()

        # Start GUI
        window = Tk()
        window.title(
            "LONGBOW - AMAZON S3 DOWNLOAD TOOL WITH BREAK-POINT RESUMING")
        window.geometry('705x350')
        window.configure(background='#ECECEC')
        window.protocol("WM_DELETE_WINDOW", sys.exit)

        Label(window, text="S3 Bucket").grid(column=0,
                                             row=1,
                                             sticky='w',
                                             padx=2,
                                             pady=2)
        SrcBucket_txt = Combobox(window, width=48)
        SrcBucket_txt.grid(column=1, row=1, sticky='w', padx=2, pady=2)
        SrcBucket_txt['values'] = SrcBucket
        SrcBucket_txt.current(0)
        Button(window, text="List Buckets", width=10, command=ListBuckets) \
            .grid(column=2, row=1, sticky='w', padx=2, pady=2)

        Label(window, text="S3 Prefix").grid(column=0,
                                             row=2,
                                             sticky='w',
                                             padx=2,
                                             pady=2)
        S3Prefix_txt = Combobox(window, width=48)
        S3Prefix_txt.grid(column=1, row=2, sticky='w', padx=2, pady=2)
        S3Prefix_txt['values'] = S3Prefix
        if S3Prefix != '':
            S3Prefix_txt.current(0)
        Button(window, text="List Prefix", width=10, command=ListPrefix) \
            .grid(column=2, row=2, sticky='w', padx=2, pady=2)

        Label(window, text="Filename or *").grid(column=0,
                                                 row=3,
                                                 sticky='w',
                                                 padx=2,
                                                 pady=2)
        file_txt = Combobox(window, width=48)
        file_txt.grid(column=1, row=3, sticky='w', padx=2, pady=2)
        file_txt['values'] = SrcFileIndex
        if SrcFileIndex != '':
            file_txt.current(0)
        Button(window, text="Select File", width=10, command=browse_file) \
            .grid(column=2, row=3, sticky='w', padx=2, pady=2)

        Label(window, text="AWS Profile").grid(column=0,
                                               row=4,
                                               sticky='w',
                                               padx=2,
                                               pady=2)
        SrcProfileName_txt = Combobox(window, width=15, state="readonly")
        SrcProfileName_txt['values'] = tuple(profile_list)
        SrcProfileName_txt.grid(column=1, row=4, sticky='w', padx=2, pady=2)
        if SrcProfileName in profile_list:
            position = profile_list.index(SrcProfileName)
            SrcProfileName_txt.current(position)
        else:
            SrcProfileName_txt.current(0)
        SrcProfileName = SrcProfileName_txt.get()
        SrcProfileName_txt.bind("<<ComboboxSelected>>", ListBuckets)

        Label(window, text="Folder").grid(column=0,
                                          row=5,
                                          sticky='w',
                                          padx=2,
                                          pady=2)
        url_txt = Entry(window, width=50)
        url_txt.grid(column=1, row=5, sticky='w', padx=2, pady=2)
        url_btn = Button(window,
                         text="Select Folder",
                         width=10,
                         command=browse_folder)
        url_btn.grid(column=2, row=5, sticky='w', padx=2, pady=2)
        url_txt.insert(0, DesDir)

        Label(window, text="MaxThread/File").grid(column=0,
                                                  row=6,
                                                  sticky='w',
                                                  padx=2,
                                                  pady=2)
        if MaxThread < 1 or MaxThread > 100:
            MaxThread = 5
        var_t = StringVar()
        var_t.set(str(MaxThread))
        MaxThread_txt = Spinbox(window,
                                from_=1,
                                to=100,
                                width=15,
                                textvariable=var_t)
        MaxThread_txt.grid(column=1, row=6, sticky='w', padx=2, pady=2)

        Label(window, text="MaxParallelFile").grid(column=0,
                                                   row=7,
                                                   sticky='w',
                                                   padx=2,
                                                   pady=2)
        if MaxParallelFile < 1 or MaxParallelFile > 100:
            MaxParallelFile = 5
        var_f = StringVar()
        var_f.set(str(MaxParallelFile))
        MaxParallelFile_txt = Spinbox(window,
                                      from_=1,
                                      to=100,
                                      width=15,
                                      textvariable=var_f)
        MaxParallelFile_txt.grid(column=1, row=7, sticky='w', padx=2, pady=2)

        save_config = BooleanVar()
        save_config.set(True)
        save_config_txt = Checkbutton(window,
                                      text="Save to s3_download_config.ini",
                                      var=save_config)
        save_config_txt.grid(column=1, row=9, padx=2, pady=2)

        Button(window, text="Start Download", width=15,
               command=close).grid(column=1, row=10, padx=5, pady=5)
        window.mainloop()

        DesDir = url_txt.get()
        SrcFileIndex = file_txt.get()
        SrcBucket = SrcBucket_txt.get()
        S3Prefix = S3Prefix_txt.get()
        SrcProfileName = SrcProfileName_txt.get()
        MaxThread = int(MaxThread_txt.get())
        MaxParallelFile = int(MaxParallelFile_txt.get())

        if save_config:
            cfg['Basic']['SrcBucket'] = SrcBucket
            cfg['Basic']['S3Prefix'] = S3Prefix
            cfg['Basic']['SrcFileIndex'] = SrcFileIndex
            cfg['Basic']['SrcProfileName'] = SrcProfileName
            cfg['Basic']['DesDir'] = DesDir
            cfg['Advanced']['MaxThread'] = str(MaxThread)
            cfg['Advanced']['MaxParallelFile'] = str(MaxParallelFile)

            config_file = os.path.join(file_path, 's3_download_config.ini')
            with codecs.open(config_file, 'w', 'utf-8') as f:
                cfg.write(f)
                print(f"Save config to {config_file}")
        # GUI window finish

    if S3Prefix == '/':
        S3Prefix = ''
    # Finish set_config()
    return ChunkSize
示例#6
0
class Slider(Frame):
    MINIMO = 100
    MAXIMO = 2400
    
    def __init__(self, master, label, *args, **kwargs):
        '''
        parametros
        ----------
        master : tkinter.widget
        
        label : str
        
        '''
        super(Slider, self).__init__(master, *args, **kwargs)
        self._criar_estilo_label()
       
        self._criar_scale()
        self._criar_spinbox()
        self._criar_label(label)
        self.set_atual(self.MINIMO)

    def _criar_estilo_label(self):
        estilo = Style()
        estilo.configure('Slider.TLabel', font=('Arial', 14, 'normal'))
          
    def _criar_label(self, label):
        '''
        Criar label.
        '''
        frame = Frame(self, width=150, height=50)
        label = Label(frame, text=label, anchor='center', style='Slider.TLabel')
        
        label.bind('<Double-Button-1>', lambda e: self._spinbox.focus())

        label.pack(fill='both', expand=True, padx=5, pady=5)
        frame.pack(side='left')
        frame.pack_propagate(False)
                                       
    def _criar_spinbox(self):
        '''
        Criar Widget spinbox.
        '''
        self._spinbox = Spinbox(self, from_=self.MINIMO, 
                                         to=self.MAXIMO,
                            font=('Arial', 14, 'normal'),
                            width=10)
        
        self._spinbox['command'] = lambda: \
            self.set_atual(self._spinbox.get(), widget=self._spinbox)
        
        self._spinbox.bind('<Return>', lambda e: \
            self.set_atual(self._spinbox.get()))
        
        self._spinbox.pack(side='left', anchor='center')
    
    def _criar_scale(self):
        '''
        Criar widget Scale.
        '''
        self._scale = Scale(self, from_=self.MINIMO, 
                                    to=self.MAXIMO, 
                                orient='horizontal')
        
        self._scale['command'] = lambda e: \
            self.set_atual(self._scale.get(), widget=self._scale)  
                                        
        self._scale.pack(side='left', fill='x', anchor='center', expand=True, )
        
    def atual(self):
        '''
        Obter o valor atual
        
        retornos
        --------
        int
        '''
        return self._scale.get()
        
    def set_atual(self, atual, **kwargs):
        '''
        Define o valor atual.
        
        parametros
        ----------
        atual : int
        '''
        # caractere númerico é convertido em inteiro.
        if isinstance(atual, str) and atual.isdigit():
            atual = int(atual)
        
        # caractere não númerico convertido em inteiro.
        if not isinstance(atual, int):
            atual = self._scale.get()
        
        # atual fora do range.
        if atual not in range(self.MINIMO, self.MAXIMO):
            atual = self._scale.get()        
        
        widget = kwargs.get('widget')
        if widget:
            if isinstance(widget, Scale):
                self._spinbox.delete(0, 'end')
                self._spinbox.insert(0, str(atual))
            elif isinstance(widget, Spinbox):
                self._scale.set(atual)
        
        else:
            self._spinbox.delete(0, 'end')
            self._spinbox.insert(0, str(atual))
            self._scale.set(atual)