def stream_file(self, path, fast_lane=True):
        """
        Create a temp file, stream it to the server if online and append its content using the write() method. 
        This makes sure that we have all newest data of this file on the server directly.
        
        At the end of the job, the content the server received is stored as git blob on the server. It is then committed 
        locally and pushed. Git detects that the server already has the version (through the continuous streaming)
        and won't push it again. Very handy for rather large files that will append over time (like channel data, logs)
        
        Example:
        
        self.log_stream = git.stream_file('log.txt')
        
        self.log_stream.write("new line\n");
        self.log_stream.write("another line\n");
        """

        # create temp file
        # open temp file

        # register stream file and write locally
        # on end() git_commit that file locally

        # create socket connection to server
        # stream file to server
        # on end() send server end signal, so he can store its content in git as blob as well.
        # A git push would detect that both sides have the same content already,
        # except when server connection broke between start() and end().
        # Result -> already transmitted logs/channel data (probably many MBs) won't transfered twice
        # when doing a git-push.

        # return handler to write to this file

        full_path = os.path.normpath(self.temp_path + '/stream-blob/' + self.job_id + '/' + path)
        if not os.path.exists(os.path.dirname(full_path)):
            os.makedirs(os.path.dirname(full_path))

        handle = open(full_path, 'wb')
        self.streamed_files[path] = handle

        class Stream():
            def __init__(self, git):
                self.git = git

            def write(self, data):
                if path not in self.git.streamed_files:
                    # already committed to server
                    return

                if hasattr(data, 'encode'):
                    data = data.encode("utf-8", 'replace')

                try:
                    self.git.stream_files_lock.acquire()
                    if not handle.closed:
                        handle.write(data)
                        handle.flush()
                except IOError as e:
                    handle.close()

                    if 'No space left' in e.__str__():
                        sys.stderr.write(traceback.format_exc() + '\n')
                        self.git.logger.error(e.__str__())
                finally:
                    self.git.stream_files_lock.release()

                if self.git.client.online is not False:
                    self.git.client.send({'type': 'stream-blob', 'path': path, 'data': data}, channel='' if fast_lane else 'files')

        return Stream(self)
def stream_file ( self , path , fast_lane = True ) : full_path = os . path . normpath ( self . temp_path + '/stream-blob/' + self . job_id + '/' + path ) if not os . path . exists ( os . path . dirname ( full_path ) ) : os . makedirs ( os . path . dirname ( full_path ) ) handle = open ( full_path , 'wb' ) self . streamed_files [ path ] = handle class Stream ( ) : def __init__ ( self , git ) : self . git = git def write ( self , data ) : if path not in self . git . streamed_files : return if hasattr ( data , 'encode' ) : data = data . encode ( "utf-8" , 'replace' ) try : self . git . stream_files_lock . acquire ( ) if not handle . closed : handle . write ( data ) handle . flush ( ) except IOError as e : handle . close ( ) if 'No space left' in e . __str__ ( ) : sys . stderr . write ( traceback . format_exc ( ) + '\n' ) self . git . logger . error ( e . __str__ ( ) ) finally : self . git . stream_files_lock . release ( ) if self . git . client . online is not False : self . git . client . send ( { 'type' : 'stream-blob' , 'path' : path , 'data' : data } , channel = '' if fast_lane else 'files' ) return Stream ( self )
Create a temp file, stream it to the server if online and append its content using the write() method. 
        This makes sure that we have all newest data of this file on the server directly.
        
        At the end of the job, the content the server received is stored as git blob on the server. It is then committed 
        locally and pushed. Git detects that the server already has the version (through the continuous streaming)
        and won't push it again. Very handy for rather large files that will append over time (like channel data, logs)
        
        Example:
        
        self.log_stream = git.stream_file('log.txt')
        
        self.log_stream.write("new line\n");
        self.log_stream.write("another line\n");