import os import shutil import socket import tempfile from .git import GitRepo from tftp.backend import IWriter from twisted.python import log from zope.interface import implementer @implementer(IWriter) class GitWriter(object): def __init__(self, file_path, repo, remote): file_dir = file_path.parent() if not file_dir.exists(): file_dir.makedirs() self.file_path = file_path self.temp_destination = tempfile.TemporaryFile() self.repo = os.path.abspath(repo) self.remote = remote self.state = 'active' def _get_hostname(self, remote): try: flags = socket.NI_DGRAM | socket.NI_NOFQDN | socket.NI_NAMEREQD (host, _) = socket.getnameinfo(remote, flags) except: (host, _) = remote return host def _do_git_commit(self): git_repo = GitRepo(self.repo) git_repo.stage([self.file_path.path]) if not git_repo.has_changed(): return msg = 'Automatic commit after tftp upload' if self.remote is not None: msg += ' from %s' % self._get_hostname(self.remote) committer = 'Backup Server ' git_repo.commit(msg, committer) git_repo.push('origin') def write(self, data): self.temp_destination.write(data) def finish(self): if self.state not in ('finished', 'cancelled'): self.destination_file = self.file_path.open('w') self.temp_destination.seek(0) shutil.copyfileobj(self.temp_destination, self.destination_file) self.temp_destination.close() self.destination_file.close() self._do_git_commit() self.state = 'finished' def cancel(self): if self.state not in ('finished', 'cancelled'): self.temp_destination.close() self.state = 'cancelled'