Source code for view

#!/usr/bin/env python
import Tkinter as tk        
from Tkinter import *
import controller
import os
from git import *
from git import Repo
import shutil
import Tkinter, Tkconstants, tkFileDialog
# from pyparsing import Each

[docs]class View(tk.Frame): """ ..class:: View This class is used for getting user inputs. It uses the tkinter GUI package. ..data::master_file StringVar() variable holds the name of the master file ..data::local_file StringVar() variable holds the name of the local file ..data::master_path StringVar() variable holds the name of the directory which holds the master file ..data::local_path StringVar() variable holds the name of the directory which holds the local file """ def __init__(self, *args, **kwargs): """This method creates a window for the user to select whether his files are on disk or git""" tk.Frame.__init__(self, *args, **kwargs) self.option = IntVar() self.master_file = StringVar() self.local_file = StringVar() self.master_path = os.getcwd()+"/"+"testing_01" self.local_path = os.getcwd()+"/"+"testing_02" Radiobutton(self, text = "Files on Disk",variable = self.option,value = 1).grid(row = 0, column = 1) Radiobutton(self, text = "Files on Git",variable = self.option, value = 2).grid(row = 1, column = 1) ok_button = Button(self,text = "Submit",command = self.choose_option) ok_button.grid(columnspan=2)
[docs] def openmasterfile(self,event): """method is used to select a file from the local hard disk""" self.master_file.set(tkFileDialog.askopenfilename())
[docs] def openlocalfile(self,event): """method is used to select a file from the local hard disk""" self.local_file.set(tkFileDialog.askopenfilename())
[docs] def choose_option(self): """check for the option user selected and help the user select his files""" if(self.option.get()==1): self.select_disk_files() else: self.select_git_files()
[docs] def select_disk_files(self): """create a new window to input the two repositories from which the two bibtex files will be selected""" def onFrameConfigure(canvas): #'''Reset the scroll region to encompass the inner frame''' canvas.configure(scrollregion=canvas.bbox("all")) new_window = tk.Toplevel(self) canvas = tk.Canvas(new_window, borderwidth=0, background="#ffffff") window = tk.Frame(canvas, background="#ffffff") vsb = tk.Scrollbar(new_window, orient="vertical", command=canvas.yview) hsb = tk.Scrollbar(new_window, orient="horizontal", command=canvas.xview) canvas.configure(xscrollcommand = hsb.set,yscrollcommand=vsb.set) vsb.pack(side="right", fill="y") hsb.pack(side="top", fill="x") canvas.pack(side="left", fill="both", expand=True) canvas.create_window((4,4), window=window, anchor="nw") window.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas)) label_1 = Label(window, text = "Local File") label_2 = Label(window, text = "Master File") master_file_entry = Entry(window, textvariable=self.master_file) master_file_entry.bind("<Button-1>", self.openmasterfile) local_file_entry = Entry(window, textvariable=self.local_file) local_file_entry.bind("<Button-1>", self.openlocalfile) label_1.grid(row = 0,sticky=E) label_2.grid(row = 1,sticky=E) master_file_entry.grid(row = 0, column = 1) local_file_entry.grid(row=1,column=1) ok_button = Button(window,text = "Submit",command = self.call_controller) ok_button.grid(columnspan=2)
[docs] def select_git_files(self): """creates a new window and accepts the names of the two git repositories to be used by the application""" master_repo = StringVar() local_repo = StringVar() branch_name_master = StringVar() branch_name_local = StringVar() def onFrameConfigure(canvas): '''Reset the scroll region to encompass the inner frame''' canvas.configure(scrollregion=canvas.bbox("all")) new_window = tk.Toplevel(self) canvas = tk.Canvas(new_window, borderwidth=0, background="#ffffff") window = tk.Frame(canvas, background="#ffffff") vsb = tk.Scrollbar(new_window, orient="vertical", command=canvas.yview) hsb = tk.Scrollbar(new_window, orient="horizontal", command=canvas.xview) canvas.configure(xscrollcommand = hsb.set,yscrollcommand=vsb.set) vsb.pack(side="right", fill="y") hsb.pack(side="top", fill="x") canvas.pack(side="left", fill="both", expand=True) canvas.create_window((4,4), window=window, anchor="nw") window.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas)) label_1 = Label(window, text = "Git Repo 1") label_2 = Label(window, text = "Git Repo 2") label_3 = Label(window, text = "Branch_Name") label_4 = Label(window, text = "Branch_Name") r1 = Entry(window, textvariable=master_repo) br_master = Entry(window, textvariable=branch_name_master) r2 = Entry(window, textvariable=local_repo) br_local = Entry(window, textvariable=branch_name_local) text = master_repo.get() master_repo.set(text) text = local_repo.get() local_repo.set(text) label_1.grid(row = 0,sticky=E) label_4.grid(row = 1,sticky=E) label_2.grid(row = 2,sticky=E) label_3.grid(row = 3,sticky=E) r1.grid(row = 0, column = 1) br_master.grid(row=1,column=1) r2.grid(row=2,column=1) br_local.grid(row=3,column=1) ok_button = Button(window,text = "Submit",command =lambda: self.select_files(master_repo.get(),local_repo.get(),branch_name_master.get(),branch_name_local.get())) ok_button.grid(columnspan=2)
[docs] def select_files(self,repo1,repo2,branch1,branch2): """given the names of two repositories and their branch names this method creates a local repository and pulls down the content from git""" if(os.path.exists(self.master_path)): shutil.rmtree(self.master_path) self.repo_master = create_local_repo(repo1,self.master_path,branch1) if(os.path.exists(self.local_path)): shutil.rmtree(self.local_path) self.repo_local = create_local_repo(repo2,self.local_path,branch2) self.repo_master.remotes.origin.pull() self.repo_local.remotes.origin.pull() self.select_rb_files()
[docs] def select_rb_files(self): """creates a window which list the different bibtex files present in the local directories of both the master and local repositories """ def onFrameConfigure(canvas): '''Reset the scroll region to encompass the inner frame''' canvas.configure(scrollregion=canvas.bbox("all")) new_window = tk.Toplevel(self) canvas = tk.Canvas(new_window, borderwidth=0, background="#ffffff") window = tk.Frame(canvas, background="#ffffff") vsb = tk.Scrollbar(new_window, orient="vertical", command=canvas.yview) hsb = tk.Scrollbar(new_window, orient="horizontal", command=canvas.xview) canvas.configure(xscrollcommand = hsb.set,yscrollcommand=vsb.set) vsb.pack(side="right", fill="y") hsb.pack(side="top", fill="x") canvas.pack(side="left", fill="both", expand=True) canvas.create_window((4,4), window=window, anchor="nw") window.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas)) self.list_master_repo = extract_bib_files(self.master_path) self.list_local_repo = extract_bib_files(self.local_path) line = 0 #line variable holds the current row number on the gui for our grid formatting if(len(self.list_master_repo)>0): Label(window,text="Select the master file",font=("Times", 16),foreground="Blue").grid(row = line+1,columnspan=2,sticky=W,padx=2,pady=2) for idx,val in enumerate(self.list_master_repo): line = line+1 Radiobutton(window, text=self.list_master_repo[idx],variable=self.master_file,value = self.list_master_repo[idx]).grid(row=line+1,column=0,sticky=W,padx=1,pady=1) line = line+2 if(len(self.list_local_repo)>0): Label(window,text="Select the local file",font=("Times", 16),foreground="Blue").grid(row = line+1,columnspan=2,sticky=W,padx=1,pady=1) for idx,val in enumerate(self.list_local_repo): line = line+1 Radiobutton(window, text=self.list_local_repo[idx],variable=self.local_file,value = self.list_local_repo[idx]).grid(row=line+1,column=0,sticky=W,padx=1,pady=1) Button(window, text="Done", command=self.call_controller).grid(columnspan=2,sticky=W,padx=1,pady=1)
[docs] def list_differences(self,list,list2): """create a window to display the differences between the two files as two categories: one shows the differences between values of the two properties for a record and the other shows the property present in the master file but not in the local file Args: list: list of record that have a difference in properties on the master file and the local file list2:list of record that have a property on the master file which is not present on the local file """ def onFrameConfigure(canvas): '''Reset the scroll region to encompass the inner frame''' canvas.configure(scrollregion=canvas.bbox("all")) new_window = tk.Toplevel(self) canvas = tk.Canvas(new_window, borderwidth=0, background="#ffffff") window = tk.Frame(canvas, background="#ffffff") vsb = tk.Scrollbar(new_window, orient="vertical", command=canvas.yview) hsb = tk.Scrollbar(new_window, orient="horizontal", command=canvas.xview) canvas.configure(xscrollcommand = hsb.set,yscrollcommand=vsb.set) vsb.pack(side="right", fill="y") hsb.pack(side="top", fill="x") canvas.pack(side="left", fill="both", expand=True) canvas.create_window((4,4), window=window, anchor="nw") window.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas)) line = 0 if(len(list)>0): current_elem = list[0][0] Label(window,text="There is a difference in the below properties for the master and local file",font=("Times", 16),foreground="Blue").grid(columnspan=2,sticky=W,padx=2,pady=2) for idx,val in enumerate(list): line = line+1 new_elem = list[idx][0] if(new_elem!=current_elem or idx==0): Label(window,text="ID:"+current_elem,font=("Times", 14,"bold")).grid(row=line+1,sticky=W,padx=1,pady=1) current_elem=new_elem line = line +1 Label(window,text=list[idx][1][0]+":").grid(row=line+1,column=0,sticky=W,padx=1,pady=1) Label(window, text=list[idx][1][1]).grid(row=line+1,column=1,sticky=W,padx=1,pady=1) Label(window,text=list[idx][2][0]+":").grid(row=line+1,column=2,sticky=W,padx=1,pady=1) Radiobutton(window, text=list[idx][2][1],variable=list[idx][2][3],value = 1).grid(row=line+1,column=3,sticky=W,padx=1,pady=1) line = line+2 if(len(list2)>0): Label(window,text="Below property is not present in the local file",font=("Times", 16),foreground="Blue").grid(row = line,columnspan=2,sticky=W,padx=1,pady=1) Label(window,text="Select properties you want to add",font=("Times", 16),foreground="Blue").grid(row = line+1,columnspan=2,sticky=W,padx=1,pady=1) line = line +2 current_elem = list2[0][0] for idx,val in enumerate(list2): line = line+1 new_elem = list2[idx][0] if(new_elem!=current_elem or idx==0): Label(window,text="ID:"+current_elem,font =("Times", 14,"bold")).grid(row=line+1,columnspan=2,sticky=W,padx=1,pady=1) current_elem=new_elem line = line+1 Label(window,text=list2[idx][1][0]+":").grid(row=line+1,sticky=W,padx=1,pady=1) Radiobutton(window, text=list2[idx][1][1],variable=list2[idx][1][3],value = 1).grid(row=line+1,column=1,sticky=W,padx=1,pady=1) self.update = True if(len(list)==0 and len(list2)==0): Label(window,text="No differences between the two files",font=("Times", 16),foreground="Blue").grid(row = line,columnspan=2,sticky=W,padx=1,pady=1) self.update = False Button(window, text="Done", command=lambda:self.controller.update(self.update,list,list2)).grid(columnspan=2,sticky=W,padx=1,pady=1)
[docs] def call_controller(self): """Create the controller instance """ self.controller = controller.Controller(self)
[docs] def close(self): """deletes the instance of View , commits the new added features to the local file to the remote repository and deletes all the temporary directories that were created for this application """ if(self.option.get()==2): commit_remote(self.repo_local,self.local_file.get()) shutil.rmtree(self.master_path) shutil.rmtree(self.local_path) self.destroy() root_close()
[docs]def commit_remote(repo,file): """ Commits to the index of the local git repository and calls the git push Args: repo: Reference to the head of the local git repository file: File that will be added to the index for the commit and push to the remote git repository Raises: git.exc.GitCommandError: If git.push() fails """ try: repo.index.add([file]) commit = repo.index.commit("Modified File"+file) for each in repo.heads: branch = each merge_base = repo.merge_base(repo.remotes.origin,branch) repo.index.merge_tree(branch,base=merge_base) repo.remotes.origin.push() except git.exc.GitCommandError: print "Git Push Error"
#outside
[docs]def create_local_repo(remote_git,dir,branch): """ Uses the git.clone_from method to clone a remote git repository locally Args: remote_git: Url of the remote git repository dir: Local directory where the contents of the remote git will be downloaded branch: Name of the branch on the remote git which will be used for cloning Returns: git.repo: Reference to the local git repository Raises: git.exc.InvalidGitRepositoryError: If remote git repository is bare git.exc.GitCommandError: If remote git repository does not exist """ if(os.path.exists(dir)): shutil.rmtree(dir) try: repo = Repo.clone_from( url=remote_git, to_path=dir, branch=branch ) if repo.bare: raise git.exc.InvalidGitRepositoryError else: return repo except git.exc.GitCommandError: print "Please make sure you have the correct access rights and the repository exists"
[docs]def extract_bib_files(path): """ Extracts all the bib files from the given path Args: path : The directory name from which bib files will be extracted Returns: List[string]: Returns a list of bib files present in path """ list = [] for root, dirs, files in os.walk(path): for name in files: if(os.path.join(root, name)).endswith(".bib"): list.append(((os.path.join(root, name)))) for name in dirs: if(os.path.join(root, name)).endswith(".bib"): list.append(((os.path.join(root, name)))) return list
if __name__ == "__main__": root = tk.Tk() view = View(root) view.pack(side="top", fill="both", expand=True) def root_close(): root.destroy() root.mainloop()