コード例 #1
0
ファイル: rema.py プロジェクト: PegasisForever/remapy
class Main(object):
    def __init__(self, window):
        self.rm_client = RemarkableClient()

        # Define app settings
        scale = cfg.get("scaling", 1 / window.tk.call('tk', 'scaling'))
        window.tk.call('tk', 'scaling', 1 / scale)
        window_width = 750 * scale
        window_height = 700 * scale

        # Subscribe to events
        self.rm_client.listen_sign_in_event(self)

        # Window settings
        window.title("RemaPy Explorer")

        # Try to start remapy always on the first screen and in the middle.
        # We assume a resolution width of 1920... if 1920 is too large use
        # the real resolution
        x = min(window.winfo_screenwidth(), 1920) / 2 - (window_width / 2)
        y = (window.winfo_screenheight() / 2) - (window_height / 2)
        window.geometry("%dx%d+%d+%d" % (window_width, window_height, x, y))

        # Create different tabs on notebook
        self.notebook = ttk.Notebook(window)
        self.notebook.pack(expand=1, fill="both")

        frame = ttk.Frame(self.notebook)
        self.file_explorer = FileExplorer(frame, window)
        self.notebook.add(frame, text="File Explorer")

        frame = ttk.Frame(self.notebook)
        self.notebook.add(frame, text="Backup", state="hidden")

        frame = ttk.Frame(self.notebook)
        self.notebook.add(frame, text="Zotero", state="hidden")

        frame = ttk.Frame(self.notebook)
        self.notebook.add(frame, text="Mirror", state="hidden")

        frame = ttk.Frame(self.notebook)
        self.notebook.add(frame, text="SSH", state="hidden")

        frame = ttk.Frame(self.notebook)
        self.settings = Settings(frame)
        self.notebook.add(frame, text="Settings")

        frame = ttk.Frame(self.notebook)
        self.about = About(frame)
        self.notebook.add(frame, text="About")

        # Try to sign in to the rm cloud without a onetime code i.e. we
        # assume that the user token is already available. If it is not
        # possible we get a signal to disable "My remarkable" and settings
        # are shown...
        self.rm_client.sign_in()

    #
    # EVENT HANDLER
    #
    def sign_in_event_handler(self, event, data):
        # If we fail to get a user token, we are e.g. offline. So we continue
        # and try if we can get it later; otherwise we go into an offline mode
        if event == api.remarkable_client.EVENT_SUCCESS or event == api.remarkable_client.EVENT_USER_TOKEN_FAILED:
            self.notebook.tab(0, state="normal")
        else:
            self.notebook.tab(0, state="disabled")
コード例 #2
0
class Settings(object):
    def __init__(self, root, font_size):
        self.rm_client = RemarkableClient()
        self.item_manager = ItemManager()

        root.grid_columnconfigure(4, minsize=180)
        root.grid_rowconfigure(1, minsize=50)
        root.grid_rowconfigure(2, minsize=30)
        root.grid_rowconfigure(3, minsize=30)
        root.grid_rowconfigure(4, minsize=30)
        root.grid_rowconfigure(6, minsize=50)
        root.grid_rowconfigure(7, minsize=30)
        root.grid_rowconfigure(8, minsize=30)
        root.grid_rowconfigure(9, minsize=50)

        # gaps between columns
        label = tk.Label(root, text="    ")
        label.grid(row=1, column=1)
        label = tk.Label(root, text="    ")
        label.grid(row=1, column=3)
        label = tk.Label(root, text="  ")
        label.grid(row=1, column=5)

        label = tk.Label(root, text="Authentication", font="Helvetica 14 bold")
        label.grid(row=1, column=2, sticky="W")

        self.onetime_code_link = "https://my.remarkable.com#desktop"
        self.label_onetime_code = tk.Label(
            root,
            justify="left",
            anchor="w",
            fg="blue",
            cursor="hand2",
            text="\nDownload one-time code from \n" + self.onetime_code_link)
        self.label_onetime_code.grid(row=2, column=7, sticky="SW")
        self.label_onetime_code.bind(
            "<Button-1>",
            lambda e: webbrowser.open_new(self.onetime_code_link))

        label = tk.Label(root, justify="left", anchor="w", text="Status: ")
        label.grid(row=2, column=2, sticky="W")
        self.label_auth_status = tk.Label(root, text="Unknown")
        self.label_auth_status.grid(row=2, column=4, sticky="W")

        label = tk.Label(root,
                         justify="left",
                         anchor="w",
                         text="One-time code:")
        label.grid(row=3, column=2, sticky="W")
        self.entry_onetime_code_text = tk.StringVar()
        self.entry_onetime_code = tk.Entry(
            root, textvariable=self.entry_onetime_code_text)
        self.entry_onetime_code.grid(row=3, column=4, sticky="W")

        self.btn_sign_in = tk.Button(root,
                                     text="Sign In",
                                     command=self.btn_sign_in_click,
                                     width=17)
        self.btn_sign_in.grid(row=4, column=4, sticky="W")

        label = tk.Label(root, text="General", font="Helvetica 14 bold")
        label.grid(row=6, column=2, sticky="W")

        label = tk.Label(root, text="Templates path:")
        label.grid(row=7, column=2, sticky="W")
        self.entry_templates_text = tk.StringVar()
        self.entry_templates_text.set(cfg.get("general.templates", default=""))
        self.entry_templates = tk.Entry(root,
                                        textvariable=self.entry_templates_text)
        self.entry_templates.grid(row=7, column=4, sticky="W")

        label = tk.Label(
            root,
            justify="left",
            anchor="w",
            text=
            "A local folder that contains all template PNG files. \nYou can copy the template files from your tablet: \n'/usr/share/remarkable'"
        )
        label.grid(row=7, column=7, sticky="W")

        label = tk.Label(root, text="Backup root path:")
        label.grid(row=8, column=2, sticky="W")
        self.backup_root_text = tk.StringVar()
        backup_root_default = Path.joinpath(Path.home(), "Backup",
                                            "Remarkable")
        backup_root = cfg.get("general.backuproot",
                              default=str(backup_root_default))
        self.backup_root_text.set(backup_root)
        self.entry_backup_root = tk.Entry(root,
                                          textvariable=self.backup_root_text)
        self.entry_backup_root.grid(row=8, column=4, sticky="W")

        label = tk.Label(
            root,
            justify="left",
            anchor="w",
            text=
            "A local folder that will be used as the root folder for backups.")
        label.grid(row=8, column=7, sticky="W")

        self.btn_save = tk.Button(root,
                                  text="Save",
                                  command=self.btn_save_click,
                                  width=17)
        self.btn_save.grid(row=9, column=4, sticky="W")

        label = tk.Label(root, text="Backup", font="Helvetica 14 bold")
        label.grid(row=10, column=2, sticky="W")

        label = tk.Label(root, text="Backup path:")
        label.grid(row=11, column=2, sticky="W")
        self.backup_folder_text = tk.StringVar()

        backup_folder = str(date.today().strftime("%Y-%m-%d"))
        self.backup_folder_text.set(backup_folder)
        self.entry_backup_folder = tk.Entry(
            root, textvariable=self.backup_folder_text)
        self.entry_backup_folder.grid(row=11, column=4, sticky="W")

        self.label_backup_progress = tk.Label(root)
        self.label_backup_progress.grid(row=11, column=6)

        label = tk.Label(
            root,
            justify="left",
            anchor="w",
            text=
            "Copy currently downloaded and annotated PDF files \ninto the given directory. Note that those files can not \nbe restored on the tablet."
        )
        label.grid(row=11, column=7, sticky="W")

        self.btn_create_backup = tk.Button(root,
                                           text="Create backup",
                                           command=self.btn_create_backup,
                                           width=17)
        self.btn_create_backup.grid(row=12, column=4, sticky="W")

        # Subscribe to sign in event. Outer logic (i.e. main) can try to
        # sign in automatically...
        self.rm_client.listen_sign_in_event(self)

    #
    # EVENT HANDLER
    #
    def sign_in_event_handler(self, event, config):

        self.btn_sign_in.config(state="normal")
        self.entry_onetime_code.config(state="normal")
        self.btn_create_backup.config(state="disabled")
        self.btn_save.config(state="disabled")
        self.entry_backup_root.config(state="disabled")
        self.entry_backup_folder.config(state="disabled")
        self.entry_templates.config(state="disabled")

        if event == api.remarkable_client.EVENT_SUCCESS:
            self.btn_sign_in.config(state="disabled")
            self.entry_onetime_code.config(state="disabled")
            self.btn_create_backup.config(state="normal")
            self.btn_save.config(state="normal")
            self.entry_backup_root.config(state="normal")
            self.entry_backup_folder.config(state="normal")
            self.entry_templates.config(state="normal")
            self.label_auth_status.config(text="Successfully signed in",
                                          fg="green")

        elif event == api.remarkable_client.EVENT_USER_TOKEN_FAILED:
            self.label_auth_status.config(
                text="Could not renew user token\n(please try again).",
                fg="red")
            self.entry_onetime_code.config(state="disabled")

        elif event == api.remarkable_client.EVENT_ONETIMECODE_NEEDED:
            self.label_auth_status.config(text="Enter one-time code.",
                                          fg="red")

        else:
            self.label_auth_status.config(text="Could not sign in.", fg="red")

    def btn_sign_in_click(self):
        onetime_code = self.entry_onetime_code_text.get()
        self.rm_client.sign_in(onetime_code)

    def btn_save_click(self):
        general = {
            "templates": self.entry_templates_text.get(),
            "backuproot": self.backup_root_text.get()
        }
        cfg.save({"general": general})

    def btn_create_backup(self):
        message = "If your explorer is not synchronized, some files are not included in the backup. Should we continue?"
        result = messagebox.askquestion("Info", message, icon='warning')

        if result != "yes":
            return

        backup_root = self.backup_root_text.get()
        backup_folder = self.backup_folder_text.get()
        backup_path = Path.joinpath(Path(backup_root), backup_folder)
        self.label_backup_progress.config(text="Writing backup '%s'" %
                                          backup_path)

        def run():
            self.item_manager.create_backup(backup_path)
            self.label_backup_progress.config(text="")
            messagebox.showinfo(
                "Info", "Successfully created backup '%s'" % backup_path)

        threading.Thread(target=run).start()