def persy_start(self): """ initializes the worker thread and notifier """ self.log.info("start working") self.log.setStart() self.running = True FLAGS=EventsCodes.ALL_FLAGS mask = FLAGS['IN_MODIFY'] | FLAGS['IN_DELETE_SELF']|FLAGS['IN_DELETE'] | FLAGS['IN_CREATE'] | FLAGS['IN_CLOSE_WRITE'] | FLAGS['IN_MOVE_SELF'] | FLAGS['IN_MOVED_TO'] | FLAGS['IN_MOVED_FROM'] # watched events wm = WatchManager() #addin the watched directories for watch in self.config['local']['watched']: wdd = wm.add_watch("%s"%(watch), mask, rec=True, auto_add=True) #watch for changes of the configurationfile if self.config['general']['autoshare']: wdd = wm.add_watch(self.config.getAttribute('CONFIGFILE'), mask, rec=True, auto_add=True) self.log.debug("init the syncer") self.worker = TheSyncer(self, self.config, self.log, self.config['remote']['sleep'], self.config['local']['sleep']) self.log.debug("init the filesystem notifier") self.notifier = ThreadedNotifier(wm, FileChangeHandler(self.log, self.worker.newEvent)) self.log.resetError() self.log.debug("starting syncer") self.worker.start() self.notifier.start()
class _Core(): """ the core functionaliy for persy """ def init(self, config, log): """ initializes the git binding """ self.config = config self.log = log self.worker = None self.notifier = None self.running = False #initialzing the git binding #=========================== #if persy is interrupted while git was running, a git.lockfile may be present. we have to remove it! if os.path.exists(self.config.getAttribute('GIT_LOCKFILE')): try: os.remove(self.config.getAttribute('GIT_LOCKFILE')) except Exception as err: log.warn(str(err)) else: log.warn(_("removed git lock file")) #init pug os.popen("touch %s"%self.config.getAttribute('LOGFILE_GIT')) std = open(self.config.getAttribute('LOGFILE_GIT'), 'a') stdin = None #default stdin stdout = std #default stdout stderr = std #default stderr cwd = os.environ["HOME"] self.vcs = pug.PuG(cwd=cwd, GIT_WORK_TREE=config['general']['gitworktree'], GIT_DIR=config['general']['gitdir'], stdin=stdin, stdout=subprocess2.PIPE, stderr=stderr) def init_local(self): """ initialises the local repository """ if not self.config.has_key('general') or not self.config['general'].has_key('name') or not self.config['general']['name'] : self.log.critical(_('username not set, cannot create git repository. use "persy --config --name=NAME" to set one'), verbose=True) sys.exit(-1) if not self.config.has_key('general') or not self.config['general'].has_key('mail') or not self.config['general']['mail']: self.log.critical(_('mail not set, cannot create git repository. use "persy --config --mail=MAIL" to set one'), verbose=True) sys.exit(-1) self.log.info(_("initialising local repository..."), verbose=True) try: self.vcs.init() self.vcs.config('user.name',self.config['general']['name']) self.vcs.config('user.email',self.config['general']['mail']) self.vcsignore() except Exception as err: self.log.critical(str(err), verbose=True) else: self.log.info(_("done"), verbose=True) def vcslog(self): """ runs the vcs(git)-log command and writs the output to stdout """ self.vcs.log(stdout=sys.stdout, stdin=sys.stdin, stderr=sys.stderr) def vcsstatus(self): """ runs the vcs(git)-status command """ self.vcs.status(stdout=sys.stdout, stdin=sys.stdin, stderr=sys.stderr) def initRemote(self): """ initialises the remote repository and adds it to the synchronization pack tries to connect to the remote server and creates the destination folder and initializes the remote git repository """ self.log.info(_("initialising and adding remote repository..."), verbose=True) try: client = paramiko.SSHClient() client.load_system_host_keys() client.connect(self.config['remote']['hostname'], username=self.config['remote']['username'], port=int(self.config['remote']['port'])) # the follow commands are executet on a remote host. we can not know the path to git, # mkdir and cd so we will not replace them with a absolute path stdin1, stdout1, stderr1 = client.exec_command("mkdir -m 700 %s"%self.config['remote']['path']) stdin2, stdout2, stderr2 = client.exec_command("cd %s && git --bare init"%self.config['remote']['path']) client.close() if stderr1: self.log.warn(_("error creating dir, maybe it exists already?"), verbose=True) elif stderr2: self.log.critical(_("error on remote git init"), verbose=True) elif not self.config['remote']['use_remote']: #no errors:so we are save to use the remote self.config['remote']['use_remote'] = True self.config.write() self.vcs.remoteAdd(self.config.getAttribute('SERVER_NICK'),"ssh://%s@%s/%s"%(self.config['remote']['username'],self.config['remote']['hostname'],self.config['remote']['path'])) except Exception as e: self.log.critical(str(e), verbose=True) else: self.log.info(_("done"), verbose=True) def syncWithRemote(self): """ Syncs with a remote server adds a new remote repository with the information from config to the local git repository and performs a pull """ # i dont use clone because of massive errors when using it # the best way iś to add the remote server and pull from it self.log.debug('persy-core-sync called') #check to only do this if all of the remote watched directoris do NOT exist for f in self.config['local']['watched']: if os.path.exists(f): self.log.critical(_("%f does already exist but it should not! Please remove it and try it again.")) return False try: self.log.debug('persy-core-sync remote add') self.vcs.remoteAdd(self.config.getAttribute('SERVER_NICK'),"ssh://%s@%s/%s"%(self.config['remote']['username'],self.config['remote']['hostname'],self.config['remote']['path'])) self.log.debug('persy-core-sync pull') self.vcs.pull(self.config.getAttribute('SERVER_NICK'),self.config.getAttribute('BRANCH')) except Exception as e: self.log.critical(str(e)) self.log.debug('persy-core-sync ende') self.config['remote']['use_remote'] = True self.config.write() def isInSyncWithRemote(self): """ returns true if it is already in sync "in sync" means: git remote returns an entry for an "origin" repository. """ try: self.vcs.command('git', params=['remote']) except Exception as e: self.log.critical(str(e)) std = self.vcs.getLastOutput().strip("\n ") if std == 'origin': return True return False def vcsignore(self): """ creates a file for ignoring unwatched directories so they dont appear in the status (and cant be removed exidently with "git clean") list every file in /home/USER. add every file and folder (if not already done) to .vcsignore if they are not part WATCHED """ current = os.listdir(self.config.getAttribute('USERHOME')) for f in self.config['local']['watched']: #if not f.startswith(USERHOME): if f.startswith(self.config.getAttribute('USERHOME')): #if absolute path #strip dir stuff, the +1 is for the file seperator f = f[len(self.config.getAttribute('USERHOME'))+1:] elif f.startswith('~/'): f = f[2:] #strip the ~/ elif f.startswith('./'): f = f[2:] #strip the ./ elif f.startswith('/'): #continue #savetycheck #i assume if it still starts with /, its outside of /home continue if os.sep in f: f = f[:f.index(os.sep)] if f in current: current.remove(f) if self.config['local']['maxfilesize'] and self.config['local']['maxfilesize'] > 0: #add files to the ignorelist if they are larger than maxfilesize callcmd = [] callcmd.append('find') callcmd.append(os.path.join(self.config.getAttribute('USERHOME'),f)) callcmd.append('-type') callcmd.append('f') callcmd.append('-size') callcmd.append("+" + str(self.config['local']['maxfilesize']) + "k") (stdoutdata, stderrdata) = subprocess.Popen(callcmd, stdout=subprocess.PIPE).communicate() for entry in stdoutdata.split("\n"): current.append(entry) for entry in self.config['local']['exclude']: current.append(entry) with open(os.path.join(self.config.getAttribute('PERSY_DIR'),self.config.getAttribute('GITIGNOREFILE')), "w+") as f: for c in current: f.write(c+"\n") def optimize(self): """ tries to optimize the local repository. executes the git-gc command. """ self.log.info('starting optimization', verbose=True) class Starter(Thread): def __init__(self,vcs, log): Thread.__init__(self) self.vcs = vcs self.log = log def run(self): try: self.log.debug('git gc') self.vcs.gc() except Exception as e: self.log.warn(str(e), verbose=True) try: Starter(self.vcs, self.log).start() except Exception as e: self.log.warn(str(e), verbose=True) def browse(self): """ starts the default git browser """ class Starter(Thread): def __init__(self,vcs, config): Thread.__init__(self) self.vcs = vcs self.config = config def run(self): self.vcs.command(self.config['general']['prefgitbrowser'], stdout=sys.stdout, stdin=sys.stdin, stderr=sys.stderr) Starter(self.vcs, self.config).start() def persy_stop(self): """ Stops persys working thread and the notifier. """ self.log.info("stop working") self.log.setStop() self.running = False if self.worker: try: self.worker.stop() self.worker.join() except RuntimeError: pass if self.notifier: try: self.notifier.stop() except RuntimeError: pass except OSError: pass except KeyError: pass def persy_start(self): """ initializes the worker thread and notifier """ self.log.info("start working") self.log.setStart() self.running = True FLAGS=EventsCodes.ALL_FLAGS mask = FLAGS['IN_MODIFY'] | FLAGS['IN_DELETE_SELF']|FLAGS['IN_DELETE'] | FLAGS['IN_CREATE'] | FLAGS['IN_CLOSE_WRITE'] | FLAGS['IN_MOVE_SELF'] | FLAGS['IN_MOVED_TO'] | FLAGS['IN_MOVED_FROM'] # watched events wm = WatchManager() #addin the watched directories for watch in self.config['local']['watched']: wdd = wm.add_watch("%s"%(watch), mask, rec=True, auto_add=True) #watch for changes of the configurationfile if self.config['general']['autoshare']: wdd = wm.add_watch(self.config.getAttribute('CONFIGFILE'), mask, rec=True, auto_add=True) self.log.debug("init the syncer") self.worker = TheSyncer(self, self.config, self.log, self.config['remote']['sleep'], self.config['local']['sleep']) self.log.debug("init the filesystem notifier") self.notifier = ThreadedNotifier(wm, FileChangeHandler(self.log, self.worker.newEvent)) self.log.resetError() self.log.debug("starting syncer") self.worker.start() self.notifier.start() #if self.statusIcon: # statusIcon.set_from_file(config.getAttribute('ICON_OK'))#from_stock(gtk.STOCK_HOME) def setonetimesync(self): """ if the worker is running, execute the setonetimesync function of the worker """ if self.worker: try: self.worker.setonetimesync() except RuntimeError: pass def isLocalInitialized(self): """ returns true if the local GIT_DIR exists """ return os.path.exists(self.config.getAttribute('GIT_DIR')) def git_add(self, item): """ adds an item to git """ self.vcs.add(item) def git_commit(self, message): """ executes a commit with "message" as the commit message """ self.vcs.commit(message) def git_pull(self, nickname, branch): """ executes a pull from "branch" on "nickname" """ self.vcs.pull(nickname, branch) def git_push(self, nickname, branch): """ executes a push to "branch" on "nickname" """ self.vcs.push(nickname,branch) def git_svn_pull(self): self.vcs.svn_pull() def git_svn_push(self): self.vcs.svn_push() def git_get_submodules(self): """ returns all submodules in watched directories """ return self.vcs.get_submodules(include_dir = self.config['local']['watched'])