diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b8414d8..b0f9c31 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,10 @@ - - + + + + @@ -16,9 +18,10 @@ + - + @@ -45,22 +48,22 @@ - + - + - + - + @@ -70,11 +73,13 @@ - - + + - + + + @@ -83,7 +88,7 @@ - + @@ -92,20 +97,73 @@ - - + + + + + + + + + + + + + + + + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -123,6 +181,7 @@ self.remotes + save @@ -131,14 +190,17 @@ @@ -207,7 +269,7 @@ - + + + + @@ -340,15 +433,15 @@ - - + + - - + + @@ -388,38 +481,92 @@ - + - - + + - + - - + + - - + - + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/change.py b/change.py new file mode 100644 index 0000000..1a86431 --- /dev/null +++ b/change.py @@ -0,0 +1,111 @@ +from tkinter import * +from tkinter.ttk import * +from tkinter.messagebox import * +import os +import window +import info + + +class Changes(window.Window): + def __init__(self, master=None, broad=None): + super().__init__(master) + super().set_position(50,50) + super().set_width(870) + super().apply() + self.list = Listbox(self, width=35, height=30) + self.text = Text(self, width=75, height=35) + self.sb = Scrollbar(self) + self.discard = Button(self, width=18) + self.commit = Button(self, width=12) + self.message = Entry(self, width=40) + self.draw_widgets() + self.change_files =[] + self.discard_status = [] + self.list.bind("<>",self.show_change) + self.current_index = None + self.broad = broad + + def draw_widgets(self): + self.list.grid(row=0, column=0) + self.text.grid(row=0, column=1) + self.sb.grid(row=0, column=2, rowspan=2, sticky=W) + self.text.config(yscrollcommand=self.sb) + self.discard["command"] = self.discard_change + self.discard['text'] = 'Discard' + self.discard.grid(row=1, column=0, sticky=E) + self.commit["text"] = "Commit" + self.commit.grid(row=1, column=1, sticky=E) + self.message.grid(row=1, column=1, sticky=W) + self.message.insert(INSERT,"Default Commit.") + self.commit["command"] = self.do_commit + self.text.tag_configure('ADD',foreground="#00FF7F",font=('Verdana', 12)) + self.text.tag_configure('DEL', foreground="#DC143C",font=('Verdana', 12)) + self.text.tag_configure('INFO', foreground="#87CEEB",font=('Verdana', 12)) + self.text.tag_configure('TITLE', font=('Verdana', 12, 'bold')) + self.text.tag_configure('DATA', font=('Verdana', 12)) + + def discard_change(self): + if self.current_index is not None: + if self.discard_status[self.current_index]: + os.popen("git checkout -- {0}".format(self.change_files[self.current_index])) + self.discard_status[self.current_index] = False + self.discard['text'] = 'Add' + else: + os.popen("git add {0}".format(self.change_files[self.current_index])) + self.discard_status[self.current_index] = True + self.discard['text'] = 'Discard' + else: + raise ValueError("Current_Index Is None.") + + def do_commit(self): + stdout = os.popen("git commit --message=\"{0}\"".format(self.message.get())).read() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + self.master.destroy() + + + def show_change(self, *args): + self.current_index = self.list.curselection()[0] + if self.discard_status[self.current_index]: + self.discard['text'] = 'Discard' + else: + self.discard['text'] = 'Add' + + stdout = os.popen("git diff --cached {0}".format(self.change_files[self.current_index])).read() + self.text.delete('1.0', END) + self.text.insert(INSERT,self.change_files[self.current_index]+"\n","TITLE") + self.text.insert(INSERT, "-----------------------------------------------\n","TITLE") + if_data = False + lines = [] + str = "" + for char in stdout: + if char is not '\n': + str += char + else: + lines.append(str) + str = "" + for line in lines: + if line[0] is '@': + if_data = True + if line[0] is '+' and if_data: + self.text.insert(INSERT,line+"\n","ADD") + elif line[0] is '-' and if_data: + self.text.insert(INSERT, line + "\n", "DEL") + elif line[0] is '@': + self.text.insert(INSERT, line + "\n", "INFO") + else: + if if_data: + self.text.insert(INSERT, line + "\n","DATA") + else: + self.text.insert(INSERT, line + "\n","TITLE") + + self.text.see(END) + + def set_list(self, list): + for item in list: + self.list.insert(END, item) + ret_code = re.compile(r"[:]") + tmp_ret = ret_code.split(item) + self.change_files.append(tmp_ret[1]) + self.discard_status.append(True) \ No newline at end of file diff --git a/git.py b/git.py index 0615d98..76acf39 100644 --- a/git.py +++ b/git.py @@ -29,6 +29,10 @@ class Git(ssh.SSH): self.fix_name = None self.git_user = None self.git_email = None + self.ssh_user = user + self.ssh_hostname = hostname + self.passwd = passwd + self.path = path def global_init(self, git_user, git_email): self.git_user = git_user @@ -70,8 +74,8 @@ class Git(ssh.SSH): stdout, stderr = self.run("mkdir {0}/{1}.git".format(self.base_path[1], name)) if self.check_error(stderr): print("Succeed In Making Directory.") - self.projects[name] = {"path": "{0}/{1}".format(self.base_path[1], name), "branch": []} - cmd = "cd {0}.git;".format(self.projects[name]["path"]) + self.projects[name+".git"] = {"path": "{0}/{1}.git".format(self.base_path[1], name), "branch": []} + cmd = "cd {0};".format(self.projects[name+".git"]["path"]) cmd += "git init --bare;" stdout, stderr = self.run(cmd) if self.check_error(stderr): @@ -100,7 +104,7 @@ class Git(ssh.SSH): raise AttributeError("Set Local & Fix Project First.") def init_project_local(self, name): - if self.if_set_local: + if self.if_set_local and self.if_fix_project: os.chdir(self.local_path) try: os.mkdir(name) @@ -109,14 +113,15 @@ class Git(ssh.SSH): print("Local Project Already Exist.") os.chdir(os.path.join(self.local_path, name)) cmd = "git init" - readme = open(os.path.join(self.local_path, name,"ReadME.md"),"w") - readme.write("#Default Project Introduction.#\n") - readme.close() - cmd += "git add *" - cmd += "git commit --message=\"Initial Commit\"" os.popen(cmd) + readme = open(os.path.join(self.local_path, name,"ReadME.md"),"w") + readme.write("# Default Project Introduction.\n") + readme.close() + cmd = "git add *" + os.popen(cmd) + # self.add_remote("origin") else: - raise AttributeError("Set Local First.") + raise AttributeError("Set Local & Fix Project First.") def global_init_local(self): cmd = "git config --global user.email \"{0}\"".format(self.git_email) @@ -127,6 +132,7 @@ class Git(ssh.SSH): def update_projects(self): if self.base_path[0]: + self.projects = {} stdout, stderr = self.run("ls {0}".format(self.base_path[1])) if self.check_error(stderr): reform = re.compile("\w+") @@ -135,6 +141,8 @@ class Git(ssh.SSH): self.projects[project_name] = {"path": "{0}/{1}".format(self.base_path[1], project_name), "branch": []} self.if_get_project = True + if self.if_fix_project: + self.get_branch() else: raise ValueError("Base Path Abnormal") @@ -145,6 +153,7 @@ class Git(ssh.SSH): def list_projects(self): if self.if_get_project: + self.projects_list = [] for project in self.projects.keys(): self.projects_list.append(project) else: @@ -158,6 +167,7 @@ class Git(ssh.SSH): os.chdir(self.local_path) else: raise AttributeError("Connect First.") + def add_remote(self, name="origin"): if self.if_base_init and self.if_get_project and self.if_fix_project: stdout = os.popen("git remote add {3} ssh://{0}@{1}:{2}/{4}.git".format(self.user, self.hostname, @@ -176,6 +186,7 @@ class Git(ssh.SSH): if self.if_fix_project and self.if_base_init and self.if_set_local: if name in self.remotes.keys(): os.popen("git fetch {0}".format(name)) + print("git fetch {0}".format(name)) self.if_fetch_remote = True else: raise AttributeError("Set Local & Fix Project & Base Init First.") @@ -186,11 +197,13 @@ class Git(ssh.SSH): for remote in os.popen("git remote -v").readlines(): results = ret_code.split(remote) results = list(results) + print(results) if len(results) >= 1: self.remotes = {} for item in results: - if item[0] not in self.remotes.keys(): + if results[0] not in self.remotes.keys(): self.remotes[results[0]] = {"name": results[0], "url": results[1]} + print(self.remotes[results[0]]) self.if_get_remote = True else: raise AttributeError("Set Local & Fix Project & Base Init First.") @@ -215,6 +228,32 @@ class Git(ssh.SSH): else: raise AttributeError("Set Local & Fix Project & Base Init & Get Remote & Get Branches First.") + def get_changes(self): + if self.if_fix_project and self.if_base_init and self.if_set_local \ + and self.if_get_remote: + stdout = os.popen("git status") + modified_ret_code = re.compile("modified:[ ]*[\w,/,.]+") + new_ret_code = re.compile("new file:[ ]*[\w,/,.]+") + changed_files = [] + + for line in stdout: + modified_tmp_ret = modified_ret_code.search(line) + new_tmp_ret = new_ret_code.search(line) + if modified_tmp_ret is not None: + modified_file = modified_tmp_ret.group() + print(modified_file) + changed_files.append(modified_file) + elif new_tmp_ret is not None: + new_file = new_tmp_ret.group() + print(new_file) + changed_files.append(new_file) + + + return changed_files + + else: + raise AttributeError("Set Local & Fix Project & Base Init & Get Remote & Get Branches First.") + def fix_project(self, name): if self.if_get_project and self.if_base_init: if name+".git" in self.projects_list: @@ -231,7 +270,7 @@ class Git(ssh.SSH): def commit_local(self, message): if self.if_set_local and self.if_fix_local and self.if_base_init: if self.base_path[0]: - stdout = os.popen("git commit --message={0}".format(message)).read() + stdout = os.popen("git commit --message=\"{0}\"".format(message)).read() return stdout else: raise UnboundLocalError("Init Base First") @@ -240,7 +279,7 @@ class Git(ssh.SSH): def add(self): if self.if_set_local and self.if_fix_local and self.if_base_init: - stdout = os.popen("git add *") + stdout = os.popen("git add *").read() return stdout else: raise AttributeError("Set Local & Fix Local & Base Init First.") @@ -260,6 +299,13 @@ class Git(ssh.SSH): else: raise AttributeError("Get Project & Base Init & Fix Local First.") + def status(self): + if self.fix_name and self.if_fix_local and self.if_base_init: + stdout = os.popen("git status").read() + return stdout + else: + raise AttributeError("Fix Project & Base Init & Fix Local First.") + def list_branch(self): if self.if_get_branches: for project in self.projects.items(): diff --git a/info.py b/info.py new file mode 100644 index 0000000..f6bece0 --- /dev/null +++ b/info.py @@ -0,0 +1,26 @@ +from tkinter import * +from tkinter.ttk import * +from tkinter.messagebox import * +import window + +class Info(window.Window): + def __init__(self, master=None, type="Entry"): + super().__init__(master) + if type is "Combobox": + info_type = Combobox(self) + else: + info_type = Entry(self) + self.information_label = Label(self) + self.information = info_type + self.ok = Button(self) + self.draw_widgets() + + def draw_widgets(self): + self.information_label["text"] = "Info: " + self.information_label.grid(row=0, column=0) + self.information.grid(row=0, column=1) + self.ok["text"] = "OK" + self.ok.grid(row=0, column=2) + + def set_click(self, func): + self.ok["command"] = func \ No newline at end of file diff --git a/keygen.py b/keygen.py index 1b560e8..47b03c4 100644 --- a/keygen.py +++ b/keygen.py @@ -15,16 +15,26 @@ class Key(ssh.SSH): self.public_key = None def add_key(self): - self.run("echo \"{0}\" >> ~/.ssh/authorized_keys".format(self.public_key)) + stdout, stderr = self.run("echo \"{0}\" >> ~/.ssh/authorized_keys".format(self.public_key)) + return stdout @staticmethod def create_key(): - ret_code = subprocess.Popen(["ssh-keygen", "-b 4096"], shell=True, + if os.path.exists(os.path.join(os.environ["HOME"],".ssh","id_rsa.pub")): + os.remove(os.path.join(os.environ["HOME"],".ssh","id_rsa.pub")) + os.remove(os.path.join(os.environ["HOME"], ".ssh", "id_rsa")) + + print("Key Path:","{0}".format(os.path.join(os.environ["HOME"],".ssh","id_rsa"))) + ret_code = subprocess.Popen(["ssh-keygen", "-b 4096","-N ''", "-q", + "-f {0}".format(os.path.join(os.environ["HOME"],".ssh","id_rsa")), + ], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - stdout, stderr = ret_code.communicate(input=b"\n \n \n \n") + stdout, stderr = ret_code.communicate(input=b"\ny\n") + return stdout.decode("utf-8") def get_key(self): self.public_key = open(self.public_key_path, 'r').readline() + return self.public_key if __name__ == "__main__": diff --git a/main.py b/main.py new file mode 100644 index 0000000..1b81f62 --- /dev/null +++ b/main.py @@ -0,0 +1,444 @@ +from tkinter import * +from tkinter.ttk import * +from tkinter.messagebox import * +import json +import git +import os +import window +from info import * +from change import * +from sshtool import * + + +class Main(window.Window): + def __init__(self, master=None): + super().__init__(master) + self.style.configure("M.MButton",) + self.connect = None + self.hostname_label = Label(self, width=8) + self.user_name_label = Label(self, width=12) + self.password_label = Label(self, width=8) + self.connection_status = Label(self, width=8) + self.hostname = Entry(self, width=15) + self.user_name = Entry(self, width=15) + self.password = Entry(self, width=15, show="*") + self.list_projects = Button(self, width=12) + self.fix_project = Button(self, width=12) + self.create_project = Button(self, width=12) + self.broad = Text(self, width=85, height=30) + self.fix_project_label = Label(self, width=15) + self.local_path_label = Label(self, width=25) + self.get_branch = Button(self, width=12) + self.set_local = Button(self, width=12) + self.add_remote = Button(self, width=12) + self.list_remote = Button(self, width=12) + self.clone_project = Button(self, width=12) + self.project_status = Button(self, width=12) + self.pull = Button(self, width=12) + self.push = Button(self, width=12) + self.add = Button(self, width=12) + self.commit = Button(self, width=12) + self.save = Button(self, width=12) + self.ssh_tools = Button(self, width=12) + self.info = None + self.save_info = None + + self.git = None + self.draw_widget() + + if os.path.exists(os.path.join(os.environ['HOME'],"save_data.json")): + self.get_save_data() + + def get_save_data(self): + save_file = open(os.path.join(os.environ['HOME'],"save_data.json"),"r") + json_data = save_file.readline() + save_infos = json.loads(json_data) + self.save_info = save_infos[0] + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Get Saved Data\n") + self.broad.insert(INSERT, "Hostname: {0}\n".format(self.save_info["hostname"])) + self.broad.insert(INSERT, "User: {0}\n".format(self.save_info["user"])) + self.broad.insert(INSERT, "Local Path: {0}\n".format(self.save_info["local_path"])) + self.broad.insert(INSERT, "Fix Project: {0}\n".format(self.save_info["fix_project"])) + + self.user_name.insert(INSERT, self.save_info["user"]) + self.hostname.insert(INSERT, self.save_info["hostname"]) + self.password.insert(INSERT, self.save_info["password"]) + self.do_connect() + + def do_connect(self): + try: + self.git = git.Git(hostname=self.hostname.get(), + user=self.user_name.get(), passwd=self.password.get(), + path="/home/git/") + finally: + self.connection_status["text"] = "Failed" + self.connection_status["text"] = "Succeed" + try: + self.git.base_init() + self.git.update_projects() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "SSH Connection [Succeed]\n") + self.broad.insert(INSERT, "Hostame: "+self.hostname.get()+"\n") + self.broad.insert(INSERT, "User: "+self.user_name.get()+"\n") + if self.save_info is not None: + self.git.set_local(self.save_info["local_path"]) + self.broad.insert(INSERT, "Set Local Path...OK" + "\n") + self.local_path_label["text"] = "Local Path:"+self.save_info["local_path"] + self.do_list() + if self.save_info["fix_project"]+".git" in self.git.projects_list: + self.git.fix_project(self.save_info["fix_project"]) + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Auto Fix Project {0}\n".format(self.save_info["fix_project"]+".git")) + self.broad.see(END) + self.fix_project_label["text"] = "Fixed Project: {0}".format(self.save_info["fix_project"]) + + self.broad.see(END) + + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + def do_list(self): + try: + self.git.update_projects() + self.git.list_projects() + except AttributeError as errinfo: + showinfo(message=errinfo) + return + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Projects In Server: \n") + for project in self.git.projects.items(): + self.broad.insert(INSERT, "(*) "+project[0]+"\n") + self.broad.see(END) + + def new_project(self): + self.info = Info(Tk()) + self.info.information_label["text"] = "New Project Name: " + self.info.set_click(self.new_project_callback) + + def do_fix_project(self): + if self.git.if_set_local: + self.info = Info(Tk(),"Combobox") + self.info.information_label["text"] = "Select Project: " + self.info.information["value"] = self.git.projects_list + if len(self.git.projects_list) > 0: + self.info.information.current(0) + + self.info.set_click(self.do_fix_project_callback) + else: + showinfo(message="Please Set Local Path First.") + + def destroy_info(self): + self.info.master.eval('::ttk::CancelRepeat') + self.info.master.destroy() + self.info = None + + def new_project_callback(self): + if self.info is not None: + try: + self.git.create_project(self.info.information.get()) + self.git.update_projects() + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "New Project {0} \n".format(self.info.information.get())) + self.broad.see(END) + self.info.master.protocol("WM_DELETE_WINDOW", self.destroy_info) + self.info.master.destroy() + + def do_fix_project_callback(self): + if self.info is not None: + try: + self.broad.insert(INSERT, "--------------------------\n") + fix_name_raw = self.info.information.get() + fix_name = fix_name_raw[0:len(fix_name_raw)-4]; + self.broad.insert(INSERT, "Fixing Project {0} \n".format(fix_name)) + self.git.fix_project(fix_name) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + self.fix_project_label["text"] = "Fixed Project: {0}".format(self.info.information.get()) + try: + + if os.path.exists(os.path.join(self.git.local_path, self.git.fix_name)) and self.git.if_set_local: + self.broad.insert(INSERT, "Check Local Project...OK \n") + else: + self.do_clone_project() + self.broad.insert(INSERT, "Set Local Project...OK \n") + + self.do_fix_project_local() + self.broad.insert(INSERT, "Fix Local Project...OK \n") + self.git.get_remote() + if "origin" not in self.git.remotes.keys(): + self.git.add_remote("origin") + self.broad.insert(INSERT, "Get Local Project's Remote...OK \n") + + self.git.fetch_remote("origin") + self.broad.insert(INSERT, "Fetch Server Project...OK \n") + + self.git.get_branch() + self.broad.insert(INSERT, "Get Local Project's Branches...OK \n") + + self.broad.see(END) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + self.info.master.protocol("WM_DELETE_WINDOW", self.destroy_info) + self.info.master.destroy() + + def do_get_branch(self): + try: + self.git.get_branch() + except AttributeError as errinfo: + showinfo(message=errinfo) + return + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Branches: \n") + for branch in self.git.projects[self.git.fix_name+".git"]["branch"]: + print(branch) + self.broad.insert(INSERT, "(*) " + branch + "\n") + self.broad.see(END) + + def do_set_local(self): + self.info = Info(Tk()) + self.info.information_label["text"] = "Local Path: " + self.info.information.insert(END, "") + self.info.set_click(self.do_set_local_callback) + + def do_fix_project_local(self): + try: + self.git.fix_project_local() + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + def do_set_local_callback(self): + if self.info is not None: + try: + if os.path.exists(self.info.information.get()): + self.git.set_local(self.info.information.get()) + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Local Path: {0}\n".format(self.info.information.get())) + self.broad.see(END) + else: + showinfo(message="{0} not exists.".format(self.info.information.get())) + return + except AttributeError as errinfo: + showinfo(message=errinfo) + return + except FileNotFoundError as errinfo: + showinfo(message=errinfo) + return + self.local_path_label["text"] = "Local Path: {0}".format(self.info.information.get()) + self.info.master.protocol("WM_DELETE_WINDOW", self.destroy_info) + self.info.master.destroy() + + def do_clone_project(self): + self.git.init_project_local(self.git.fix_name) + # self.git.add_remote() + + def do_add_remote(self): + try: + self.git.add_remote("origin") + except AttributeError as errinfo: + showinfo(errinfo) + return + + def do_list_remote(self): + try: + self.git.get_remote() + except AttributeError as errinfo: + showinfo(errinfo) + return + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Remotes: \n") + for remote in self.git.remotes.items(): + print(remote) + self.broad.insert(INSERT, "(*) " + remote[1]["name"] + " " + remote[1]["url"] + "\n") + self.broad.see(END) + + def do_pull(self): + try: + stdout = self.git.pull_remote("origin", "master") + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + def do_push(self): + try: + stdout = self.git.push_remote("origin", "master") + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + def do_add(self): + if self.git is not None and self.git.if_fix_local: + try: + stdout=self.git.add() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + self.changes_info = Changes(Tk(),self.broad) + self.changes_info.set_list(self.git.get_changes()) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + else: + showinfo(message="Connect and Fix Local Project First") + + def do_save(self): + save_infos = [] + try: + if self.git.if_set_local and self.git.if_connected: + save_info = {} + save_info["local_path"] = self.git.local_path + save_info["user"] = self.git.ssh_user + save_info["hostname"] = self.git.ssh_hostname + save_info["password"] = self.git.passwd + save_info["fix_project"] = self.git.fix_name + save_infos.append(save_info) + json_info = json.dumps(save_infos) + save_file = open(os.path.join(os.environ['HOME'],"save_data.json"),"w") + save_file.write(json_info) + save_file.close() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "Data Information Saved\n") + self.broad.insert(INSERT, "Path: "+os.path.join(os.environ['HOME'],"save_data.json")) + else: + raise AttributeError("Please Connect And Set Local Path First.") + except AttributeError as errinfo: + showinfo(message=errinfo) + return + + def do_commit(self): + self.info = Info(Tk()) + self.info.information_label["text"] = "Local Path: " + self.info.information.insert(END, "Default") + self.info.set_click(self.do_commit_callback) + + def do_commit_callback(self): + try: + stdout=self.git.commit_local(self.info.information.get()) + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + except AttributeError as errinfo: + showinfo(message=errinfo) + return + self.info.master.destroy() + self.info = None + + def do_status(self): + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(self.git.status())) + self.broad.see(END) + + def start_ssh_tools(self): + if self.git is not None: + self.ssh_interface = SSH_Tools(master=Tk(), broad=self.broad, + hostname=self.git.ssh_hostname, user=self.git.ssh_user, + passwd= self.git.passwd, path=self.git.path) + else: + showinfo(message="Connect First") + + def draw_widget(self): + self.hostname_label["text"] = "Hostname: " + self.hostname_label.grid(row=0, column=0, sticky=W) + self.hostname.grid(row=0, column=1, sticky=W) + self.user_name_label["text"] = "Username: " + self.user_name_label.grid(row=0, column=2, sticky=W) + self.user_name.grid(row=0, column=3, sticky=W) + self.password_label["text"] = "Password: " + self.password_label.grid(row=0, column=4, sticky=W) + self.password.grid(row=0, column=5, sticky=W) + self.connection_status.grid(row=9, column=6) + + self.connect = Button(self) + self.connect["text"] = "Connect" + self.connect["command"] = self.do_connect + self.connect.grid(row=0, column=6) + + self.list_projects["text"] = "Server Projects" + self.list_projects["command"] = self.do_list + self.list_projects.grid(row=1, column=0) + + self.fix_project["text"] = "Fix Project" + self.fix_project["command"] = self.do_fix_project + self.fix_project.grid(row=2, column=0) + + self.create_project["text"] = "Create Project" + self.create_project["command"] = self.new_project + self.create_project.grid(row=1, column=1) + + self.fix_project_label["text"] = "Fixed Project: None" + self.fix_project_label.grid(row=8, column=6, sticky=W) + self.local_path_label["text"] = "Local Path: None" + self.local_path_label.grid(row=9, column=0, columnspan=2, sticky=W) + + # self.get_branch["text"] = "Get Branch" + # self.get_branch["command"] = self.do_get_branch + # self.get_branch.grid(row=3,column=0) + + self.set_local["text"] = "Set Local Path" + self.set_local["command"] = self.do_set_local + self.set_local.grid(row=7, column=1) + + # self.clone_project["text"] = "Clone Project" + # self.clone_project["command"] = self.do_clone_project + # self.clone_project.grid(row=2, column=1) + + # self.add_remote["text"] = "Add Remote" + # self.add_remote["command"] = self.do_add_remote + # self.add_remote.grid(row=4, column=0) + + # self.list_remote["text"] = "List Remote" + # self.list_remote["command"] = self.do_list_remote + # self.list_remote.grid(row=4, column=1) + + self.pull["text"] = "Pull" + self.pull["command"] = self.do_pull + self.pull.grid(row=3, column=0) + + self.push["text"] = "Push" + self.push["command"] = self.do_push + self.push.grid(row=3, column=1) + + self.add["text"] = "Add" + self.add["command"] = self.do_add + self.add.grid(row=4, column=0) + + self.commit["text"] = "Commit" + self.commit["command"] = self.do_commit + self.commit.grid(row=4, column=1) + + self.save["text"] = "Save Information" + self.save["command"] = self.do_save + self.save.grid(row=5, column=0) + + self.project_status["text"] = "Status" + self.project_status["command"] = self.do_status + self.project_status.grid(row=5, column=1) + + self.ssh_tools["text"] = "SSH Tools" + self.ssh_tools["command"] = self.start_ssh_tools + self.ssh_tools.grid(row=7, column=0) + + self.broad.grid(row=1, column=2, columnspan=7, rowspan=6) + + +if __name__ == "__main__": + root = Tk() + main = Main(root) + main.set_width(930) + main.set_height(530) + main.apply() + main.mainloop() \ No newline at end of file diff --git a/sshtool.py b/sshtool.py new file mode 100644 index 0000000..4714604 --- /dev/null +++ b/sshtool.py @@ -0,0 +1,56 @@ +from tkinter import * +from tkinter.ttk import * +from tkinter.messagebox import * +import os +from keygen import * +import window + + +class SSH_Tools(window.Window,Key): + def __init__(self, hostname, user, passwd, path, master=None, broad=None): + window.Window.__init__(self,master) + Key.__init__(self,hostname=hostname, user=user, password=passwd, path=path) + self.broad = broad + self.hostname = hostname + self.user = user + self.add_btn = Button(self, width=12) + self.set_btn = Button(self, width=12) + self.check_btn = Button(self, width=12) + self.draw_window() + + def do_add_key(self): + stdout = self.create_key() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + self.broad.see(END) + + def do_set_key(self): + stdout = self.get_key() + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout)) + stdout = self.add_key() + self.broad.see(END) + + def do_check_key(self): + ret_code = subprocess.Popen("ssh -T {0}@{1}".format(self.user, self.hostname), + shell=True, + stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + stdout, stderr = ret_code.communicate(input=b"\x03") + self.broad.insert(INSERT, "--------------------------\n") + self.broad.insert(INSERT, "{0}\n".format(stdout.decode("utf-8"))) + self.broad.see(END) + + + def draw_window(self): + self.add_btn["text"] = "New Key" + self.set_btn["text"] = "Set Key" + self.check_btn["text"] = "Check Key" + + self.add_btn["command"] = self.do_add_key + self.set_btn["command"] = self.do_set_key + self.check_btn["command"] = self.do_check_key + self.add_btn.grid(row=0,column=0) + self.set_btn.grid(row=1, column=0) + self.check_btn.grid(row=2, column=0) + diff --git a/window.py b/window.py index 37c417c..23ce51b 100644 --- a/window.py +++ b/window.py @@ -1,12 +1,12 @@ from tkinter import * +from tkinter.ttk import * from tkinter.messagebox import * -import git -import os class Window(Frame): def __init__(self, master = None): - Frame.__init__(self, master) + super().__init__(master) + self.style = Style() self.master = master self.master = master self.pack() @@ -27,334 +27,4 @@ class Window(Frame): self.master.geometry("{0}x{1}+{2}+{3}".format(self.width, self.height, self.position[0], self.position[1])) -class Info(Window): - def __init__(self, master=None): - super().__init__(master) - self.information_label = Label(self) - self.information = Entry(self) - self.ok = Button(self) - self.draw_widgets() - - def draw_widgets(self): - self.information_label["text"] = "Info: " - self.information_label.grid(row=0, column=0) - self.information.grid(row=0, column=1) - self.ok["text"] = "OK" - self.ok.grid(row=0, column=2) - - def set_click(self, func): - self.ok["command"] = func - - -class Main(Window): - def __init__(self, master=None): - super().__init__(master) - self.connect = None - self.hostname_label = Label(self) - self.user_name_label = Label(self) - self.password_label = Label(self) - self.connection_status = Label(self) - self.hostname = Entry(self) - self.user_name = Entry(self) - self.password = Entry(self) - self.list_projects = Button(self) - self.fix_project = Button(self) - self.create_project = Button(self) - self.broad = Text(self) - self.fix_project_label = Label(self) - self.local_path_label = Label(self) - self.get_branch = Button(self) - self.set_local = Button(self) - self.add_remote = Button(self) - self.list_remote = Button(self) - self.clone_project = Button(self) - self.pull = Button(self) - self.push = Button(self) - self.add = Button(self) - self.commit = Button(self) - self.fix_local = Button(self) - self.info = None - - self.git = None - self.draw_widget() - - def do_connect(self): - try: - self.git = git.Git(hostname=self.hostname.get(), - user=self.user_name.get(), passwd=self.password.get(), - path="/home/git/") - finally: - self.connection_status["text"] = "Failed" - self.connection_status["fg"] = "red" - self.connection_status["text"] = "Succeed" - self.connection_status["fg"] = "green" - try: - self.git.base_init() - self.git.update_projects() - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "SSH Connection [Succeed]\n") - self.broad.insert(INSERT, self.hostname.get()+"\n") - self.broad.insert(INSERT, self.user_name.get()+"\n") - except AttributeError as errinfo: - showinfo(message=errinfo) - return - - def do_list(self): - try: - self.git.list_projects() - except AttributeError as errinfo: - showinfo(message=errinfo) - return - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "Projects: \n") - for project in self.git.projects.items(): - self.broad.insert(INSERT, "(*) "+project[0]+"\n") - - def new_project(self): - self.info = Info(Tk()) - self.info.information_label["text"] = "Project Name: " - self.info.set_click(self.new_project_callback) - - def do_fix_project(self): - self.info = Info(Tk()) - self.info.information_label["text"] = "Project Name: " - self.info.set_click(self.do_fix_project_callback) - - def new_project_callback(self): - if self.info is not None: - self.git.create_project(self.info.information.get()) - self.git.update_projects() - self.info.master.destroy() - self.info = None - - def do_fix_project_callback(self): - if self.info is not None: - try: - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "Fixing Project {0} \n".format(self.info.information.get())) - self.git.fix_project(self.info.information.get()) - except AttributeError as errinfo: - showinfo(message=errinfo) - return - self.fix_project_label["text"] = "Fixed Project: {0}".format(self.info.information.get()) - try: - self.git.get_remote() - self.broad.insert(INSERT, "Get Remote...OK \n") - if os.path.exists(os.path.join(self.git.local_path, self.git.fix_name)): - self.broad.insert(INSERT, "Check Local Project...OK \n") - else: - self.do_clone_project() - self.broad.insert(INSERT, "Set Local Project...OK \n") - - self.do_fix_project_local() - self.broad.insert(INSERT, "Fix Local Project...OK \n") - self.git.get_branch() - self.broad.insert(INSERT, "Get Local Project's Branches...OK \n") - self.git.get_remote() - self.broad.insert(INSERT, "Set Local Project's Remote...OK \n") - except AttributeError as errinfo: - showinfo(message=errinfo) - return - self.info.master.destroy() - self.info = None - - def do_get_branch(self): - try: - self.git.get_branch() - except AttributeError as errinfo: - showinfo(message=errinfo) - return - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "Branches: \n") - for branch in self.git.projects[self.git.fix_name+".git"]["branch"]: - print(branch) - self.broad.insert(INSERT, "(*) " + branch + "\n") - - def do_set_local(self): - self.info = Info(Tk()) - self.info.information_label["text"] = "Local Path: " - self.info.information.insert(END, "C:\\Users\\Saturneric\\Documents\\Code\\") - self.info.set_click(self.do_set_local_callback) - - def do_set_local_callback(self): - if self.info is not None: - try: - if os.path.exists(self.info.information.get()): - self.git.set_local(self.info.information.get()) - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "Set Local Path: {0}\n".format(self.info.information.get())) - else: - showinfo(message="{0} not exists.".format(self.info.information.get())) - return - except AttributeError as errinfo: - showinfo(message=errinfo) - return - except FileNotFoundError as errinfo: - showinfo(message=errinfo) - return - self.local_path_label["text"] = "Local Path: {0}".format(self.info.information.get()) - self.info.master.destroy() - self.info = None - - def do_clone_project(self): - self.git.init_project_local(self.git.fix_name) - # self.git.add_remote() - - def do_add_remote(self): - try: - self.git.add_remote("origin") - except AttributeError as errinfo: - showinfo(errinfo) - return - - def do_list_remote(self): - try: - self.git.get_remote() - except AttributeError as errinfo: - showinfo(errinfo) - return - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "Remotes: \n") - for remote in self.git.remotes.items(): - print(remote) - self.broad.insert(INSERT, "(*) " + remote[1]["name"] + " " + remote[1]["url"] + "\n") - - def do_pull(self): - try: - stdout = self.git.pull_remote("origin", "master") - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "{0}\n".format(stdout)) - - except AttributeError as errinfo: - showinfo(message=errinfo) - return - - def do_push(self): - try: - stdout = self.git.push_remote("origin", "master") - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "{0}\n".format(stdout)) - except AttributeError as errinfo: - showinfo(message=errinfo) - return - - def do_add(self): - try: - stdout=self.git.add() - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "{0}\n".format(stdout)) - except AttributeError as errinfo: - showinfo(message=errinfo) - return - - def do_fix_project_local(self): - try: - self.git.fix_project_local() - except AttributeError as errinfo: - showinfo(message=errinfo) - return - - def do_commit(self): - self.info = Info(Tk()) - self.info.information_label["text"] = "Local Path: " - self.info.information.insert(END, "Default") - self.info.set_click(self.do_commit_callback) - - def do_commit_callback(self): - try: - stdout=self.git.commit_local(self.info.information.get()) - self.broad.insert(INSERT, "--------------------------\n") - self.broad.insert(INSERT, "{0}\n".format(stdout)) - except AttributeError as errinfo: - showinfo(message=errinfo) - return - self.info.master.destroy() - self.info = None - - def draw_widget(self): - self.hostname_label["text"] = "Hostname: " - self.hostname_label.grid(row=0, column=0) - self.hostname.insert(END, "compute.bktus.com") - self.hostname.grid(row=0, column=1) - self.user_name_label["text"] = "Username: " - self.user_name_label.grid(row=0, column=2) - self.user_name.insert(END, "git") - self.user_name.grid(row=0, column=3) - self.password_label["text"] = "Password: " - self.password_label.grid(row=0, column=4) - self.password.grid(row=0, column=5) - self.connection_status.grid(row=0, column=7) - - self.connect = Button(self) - self.connect["text"] = "Connect" - self.connect["command"] = self.do_connect - self.connect.grid(row=0, column=6) - - self.list_projects["text"] = "List Projects" - self.list_projects["command"] = self.do_list - self.list_projects.grid(row=1, column=0) - - self.fix_project["text"] = " Fix Project " - self.fix_project["command"] = self.do_fix_project - self.fix_project.grid(row=2, column=0) - - self.create_project["text"] = "Create Project" - self.create_project["command"] = self.new_project - self.create_project.grid(row=1, column=1) - - self.fix_project_label["text"] = "Fixed Project: None" - self.fix_project_label.grid(row=8, column=6) - self.local_path_label["text"] = "Local Path: None" - self.local_path_label.grid(row=9, column=0, columnspan=6) - - self.get_branch["text"] = "Get Branch" - self.get_branch["command"] = self.do_get_branch - self.get_branch.grid(row=3,column=0) - - self.set_local["text"] = "Set Local" - self.set_local["command"] = self.do_set_local - self.set_local.grid(row=3, column=1) - - self.clone_project["text"] = "Clone Project" - self.clone_project["command"] = self.do_clone_project - self.clone_project.grid(row=2, column=1) - - self.add_remote["text"] = "Add Remote" - self.add_remote["command"] = self.do_add_remote - self.add_remote.grid(row=4, column=0) - - self.list_remote["text"] = "List Remote" - self.list_remote["command"] = self.do_list_remote - self.list_remote.grid(row=4, column=1) - - self.pull["text"] = "Pull" - self.pull["command"] = self.do_pull - self.pull.grid(row=5, column=0) - - self.push["text"] = "Push" - self.push["command"] = self.do_push - self.push.grid(row=5, column=1) - - self.add["text"] = "Add" - self.add["command"] = self.do_add - self.add.grid(row=6, column=0) - - self.commit["text"] = "Commit" - self.commit["command"] = self.do_commit - self.commit.grid(row=6, column=1) - - self.fix_local["text"] = "Fix Local" - self.fix_local["command"] = self.do_fix_project_local - self.fix_local.grid(row=7, column=0) - - self.broad.grid(row=1, column=2, columnspan=7, rowspan=6) - - -if __name__ == "__main__": - root = Tk() - main = Main(root) - main.set_width(1150) - main.apply() - main.mainloop() -