diff options
Diffstat (limited to 'src/git_tftpd/writer.py')
-rw-r--r-- | src/git_tftpd/writer.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/git_tftpd/writer.py b/src/git_tftpd/writer.py new file mode 100644 index 0000000..bee731c --- /dev/null +++ b/src/git_tftpd/writer.py @@ -0,0 +1,66 @@ +import os +import shutil +import socket +import tempfile + +from .git import GitRepo + +from tftp.backend import IWriter +from twisted.python import log +from zope import interface + + +class GitWriter(object): + interface.implements(IWriter) + + 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 <backup@spline.inf.fu-berlin.de>' + 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' |