Προς το περιεχόμενο

System tar & restore Project


Προτεινόμενες αναρτήσεις

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Πολύ πρόχειρα... 

def main():
    root = tk.Tk()
    root.title("backup.sh GUI")
    app = Example(root)
    app.update()
    root.minsize(root.winfo_width(), root.winfo_height())

    termf = Frame(root, height=200, width=200)
    termf.pack(fill=BOTH, expand=YES)
    wid = termf.winfo_id()
    os.system('xterm -into %d -geometry 40x24 -sb &' % wid)

    root.mainloop()
Δημοσ.

New version http://pastebin.com/Vaur3G7f

Αντί για CheckButtons χρησιμοποιεί radiobuttons.

 

@dr-fuzzy

το έχω δει και εγώ το snippet αυτό αλλά για να είμαι ειλικρινής δεν έχω σκεφτεί πως θα επικοινωνήσουμε μετά με το xterm μέσα από την Python. Ίσως να γίνεται με bash. αυτό ίσως βοηθάει, αλλά δεν το έχω κοιτάξει ακόμα.

  • Like 1
Δημοσ.

Ωραια πραματα!

1. Γιατι δεν βαζεις και τα options του /home με dropdown menu οπως και τα αλλα (επιλογες: include, only hidden files and folders, exclude)

2. Eιναι --directory path οχι σκετο path
 
3. Τα user options απο arguments πρεπει να μπαινουν σε quotes, δηλαδη:

-u '--exclude=mpla --include=mpla --format=mpla'

για να τα παρει σωστα το script.

 

4. Γιατι δεν χρησιμοποιεις τα μικρα arguments που δεν πιανουν και πολυ χωρο? :P
 
5. Να σε βαλω κολαμπορατορα να δουλευεις στο git κανονικα?

 

Great Work!

Δημοσ.

New version http://pastebin.com/Vaur3G7f

Αντί για CheckButtons χρησιμοποιεί radiobuttons.

 

@dr-fuzzy

το έχω δει και εγώ το snippet αυτό αλλά για να είμαι ειλικρινής δεν έχω σκεφτεί πως θα επικοινωνήσουμε μετά με το xterm μέσα από την Python. Ίσως να γίνεται με bash. αυτό ίσως βοηθάει, αλλά δεν το έχω κοιτάξει ακόμα.

 

Για δες με βάση το λινκ που λες:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import

# cross-version compatibility
import sys
if sys.version_info.major < 3:
    import Tkinter as tk
    import ttk
    import tkFileDialog as tkfiledialog
else:
    import tkinter as tk
    from tkinter import ttk
    from tkinter import filedialog as tkfiledialog

import os
from collections import OrderedDict

from Tkinter import *
from os import system as cmd

HOME_FOLDER_MODES = OrderedDict(
    [("Include /home/*", ""),
     ("Only include /home/* 's hidden files and folders.", "--exclude-home"),
     ("Exclude /home/*", "--exclude-home --no-hidden")])


class Example(ttk.Frame):
    def __init__(self, parent):
        # We can't use super() because in Python 2 the Tkinter objects
        # derive from old-style classes.
        ttk.Frame.__init__(self, parent, borderwidth=3)
        self.parent = parent

        # set theming
        self.style = ttk.Style()
        self.style.theme_use("default")
        self.pack(fill="both", expand=1)

        # set grid configuration
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=0)

        # Create the Tkinter Variables
        self.destination_folder = tk.StringVar()
        self.archiver = tk.StringVar()
        self.compression = tk.StringVar()
        self.home_folder = tk.StringVar()
        self.user_options = tk.StringVar()
        self.command = tk.StringVar()

        # Trace the Tkinter Variables!
        # http://stackoverflow.com/a/6549535/592289
        self.destination_folder.trace("w", self.construct_command)
        self.archiver.trace("w", self.construct_command)
        self.compression.trace("w", self.construct_command)
        self.home_folder.trace("w", self.construct_command)
        self.user_options.trace("w", self.construct_command)

        # Set default values to the Tkinter Variables
        self.destination_folder.set(os.path.expandvars("$HOME"))
        self.archiver.set("tar")
        self.compression.set("gzip")
        self.user_options.set("")
        self.construct_command()

        self.create_UI()

    def create_UI(self):
        self.add_choose_folder(row=1, text="Destination folder:", variable=self.destination_folder)
        self.add_combobox(row=2, text="Archiver:", variable=self.archiver, values=["tar", "bsdtar"])
        self.add_combobox(row=3, text="Compression:", variable=self.compression, values=["gzip", "xz"])
        self.add_entry(row=4, text="Additional archiver options:", variable=self.user_options)
        self.add_radiobuttons(row=5, variable=self.home_folder, modes=HOME_FOLDER_MODES)
        self.add_entry(row=8, text="Executable command:", variable=self.command)

    def add_radiobuttons(self, row, modes, variable):
        for i, (label, value) in enumerate(modes.items()):
            radio_button = ttk.Radiobutton(self, text=label, value=value, variable=variable)
            radio_button.grid(row=row + i, column=2, columnspan=1, sticky="nsew")

    def add_checkbutton(self, row, text, variable):
        check_button = ttk.Checkbutton(self, text=text, variable=variable)
        check_button.grid(row=row, column=1, columnspan=2, sticky="nsew")

    def add_choose_folder(self, row, text, variable):
        # create the widgets
        label = ttk.Label(self, text=text)
        entry = ttk.Entry(self, textvariable=variable, state="readonly")
        button = ttk.Button(self, text="...", width=2, command=lambda: variable.set(tkfiledialog.askdirectory()))
        # place the widgets
        label.grid(row=row, column=1, sticky="nse")
        entry.grid(row=row, column=2, sticky="nsew")
        button.grid(row=row, column=3)

    def add_combobox(self, row, text, variable, values):
        # create the widgets
        label = ttk.Label(self, text=text)
        box = ttk.Combobox(self, textvariable=variable, state="readonly", values=values)
        # place the widgets
        label.grid(row=row, column=1, sticky="nse")
        box.grid(row=row, column=2, sticky="nsew")

    def add_entry(self, row, text, variable):
        # create the widgets
        label = ttk.Label(self, text=text)
        entry = ttk.Entry(self, textvariable=variable)
        # place the widgets
        label.grid(row=row, column=1, sticky="nse")
        entry.grid(row=row, column=2, sticky="nsew")

    def construct_command(self, *args):
        """
        This callback function is called every time a Tkinter variable is
        changed.
        """
        arguments = [
            self.destination_folder.get(),
            "--archiver " + self.archiver.get(),
            "--compression " + self.compression.get(),
            self.home_folder.get(),
            self.user_options.get(),
        ]
        self.command.set("backup.sh " + " ".join(arguments))



def main():
    root = Tk()
    root.title("backup.sh GUI")
    app = Example(root)
    app.update()
    root.minsize(root.winfo_width(), root.winfo_height())

    termf = Frame(root, height=200, width=200)
    termf.pack(fill=BOTH, expand=YES)
    wid = termf.winfo_id()

    f=Frame(root)
    Label(f,text="/dev/pts/").pack(side=LEFT)
    tty_index = Entry(f, width=3)
    tty_index.insert(0, "1")
    tty_index.pack(side=LEFT)
    Label(f,text="Command:").pack(side=LEFT)
    e = Entry(f)
    e.insert(0, "ls -l")
    e.pack(side=LEFT,fill=X,expand=1)

    def send_entry_to_terminal(*args):
       """*args needed since callback may be called from no arg (button)
       or one arg (entry)
       """
       command=e.get()
       tty="/dev/pts/%s" % tty_index.get()
       cmd("%s <%s >%s 2> %s" % (command,tty,tty,tty))

    e.bind("<Return>",send_entry_to_terminal)
    b = Button(f,text="Send", command=send_entry_to_terminal)
    b.pack(side=LEFT)
    f.pack(fill=X, expand=1)

    cmd('xterm -into %d -geometry 40x24 -sb -e "tty; sh" &' % wid)

    root.mainloop()


if __name__ == '__main__':
    main()
Δημοσ.

δεν ξέρω τι έπρεπε να κάνει, σε εμένα ανοιγει το παράθυρο, αν πατήσω send τρέχει την εντολή στο terminal που έχω ανοιχτό και όχι στο xterm και το xterm δουλεύει ξεχωριστά αν γράψω μέσα του

 

φαντάζομαι δεν είναι αυτή η ιδέα

μήπως υπάρχει κανένας τρόπος να πιάνει με κάποιο stream(?) το stdout

 

update βλέπω πως αν αλλάξω σε /dev/pts/2 τρέχει στο xterm μέσα στο παράθυρο

Δημοσ.

εβαλα --quiet και στο backup.sh, και το εκανα να μην περιμενει user input για να τερματισει, αν δωθει το argument.

 

ετσι ολο το input μπορει να δωθει απο τον wrapper, και το script απλα να τρεχει μεχρι τελους.

 

να θυμησω οτι το --quiet παρακαμπτει ερωτησεις Continue?, edit το fstab, summary και επιλογη View Log στο dialog interface καθως και τις οδηγιες για chroot σε περιπτωση που δεν επιλεξαμε bootloader, ή εβγαλε error η εγκατασταση του.

 

οποτε οταν ολοκληρωθουν οι wrappers, μπορουν να τρεχουν με --quiet απο default.

Δημοσ. (επεξεργασμένο)

1. Λοιπόν. Κοίταξα λίγο αυτό με το embedded xterm. Προσωπικά δεν μου αρέσει σαν λύση. Η os.system έχει διάφορα θέματα (εύκολα διορθώνεται βέβαια με το module subprocess). Επίσης το παράθυρο του xterm που δημιουργείται δεν κάνει resize μαζί με το παράθυρο κτλ. Αυτό με το resize λογικά θα φτιάχνει προγραμματιστικά (πχ κάθε φορά που κάνεις resize το κεντρικό gui να κάνεις catch το event και να βάζεις να κανει resize και το xterm) αλλά γιατί να ζορίζουμε τον εαυτό μας; Επίσης ο τρόπος που βρίσκεις το σωστό /dev/pt* μάλλον αλλάζει σε καθε διανομή.

 

Μια πολύ πιο καθαρή λύση να τρέξουμε το script σε νέο process (για να μην κάνουμε block το GUI), να κάνουμε redirect το stdout, να το διαβάζουμε και να εμφανίζουμε το output γραμμή γραμμή σε ένα ScrolledText Widget. Στο παράδειγμα που ακολουθεί φαίνεται η λειτουργία που προτείνω:

import subprocess

proc = subprocess.Popen(["backup.sh", "--help"],stdout=subprocess.PIPE)

for line in iter(proc.stdout.readline, ""):
    print("line : " + line)

2. Εκτός αυτού, το GUI wrapper μάλλον καλό θα είναι να γίνει σε ένα notebook που θα έχει δυο tabs, ένα για το backup και ένα για το restore. Με τον τρόπο αυτό θα είναι και πιο μαζεμένο και, σε δεύτερη φάση, με την προσθήκη ενός αρχείου *.desktop θα μπορεί να εμφανίζεται και στα menu των Desktop Environments.

 

3. Τέλος τρίτωνα, τα του gui μάλλον θα πρέπει να τα κάνω σε ξεχωριστό branch στο GIT για να μην έχεις θέμα με τα καινούρια releases κτλ. Μόλις το φτιάξουμε, κάνεις merge τα brances.

Επεξ/σία από pmav99
  • Like 3

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...