def process(self): """ Main process. Do all works by «lazy way» — build the only objects, that is not already exists (Nano-«SCons/make»). """ filtereventspath = os.path.join(self.projectdir,"stw-filter-events.py") if not file_is_ok(filtereventspath): lf = open(filtereventspath, "w") lf.write(r"""# -*- coding: utf-8 -*- import re import time def filter_events(event): # You can modify event attribute, or disable (filter) event, returning False # Sample processing below emailre_ = re.compile(r"(?P<email>[-a-z0-9_.]+@(?:[-a-z0-9]+\.)+[a-z]{2,6})", re.IGNORECASE) if event.date > time.time()*1000: return False # Something wrong — event from future event.author = event.author.replace('OFFICE\\', '') event.author = event.author.lower().replace('"',"'") m = emailre_.search(event.author) if m: event.author = m.group('email') event.author = event.author.replace('"',"'") if event.author in ["(no author)"]: event.author = "anonymous" event.comment = re.sub('[Bb][Uu][Gg]\s*\d+\.?', '', event.comment) if event.comment.startswith("*** empty log message ***"): event.comment = "" if len(event.comment) < 10: event.comment = "" # #crap_prefixes=[ # "/Users/dumb/myproject/cvs_root/", # "/home/projects/myproject/cvsroot/" #] #for p in crap_prefixes: # if event.filename.startswith(p): # event.filename=event.filename.replace(p,"/") #event.action=event.action return True """) lf.close() hash_filter = hash4file(filtereventspath) self.activitypath = os.path.join(self.workdir, "".join(["activity-", hash_filter, ".xml"])) activitygourcepath = os.path.join(self.workdir, "".join(["activity-", hash_filter, ".gource"])) events = EventList() if not file_is_ok(self.activitypath) or not file_is_ok(activitygourcepath): localvars = {} try: execfile(filtereventspath, localvars) except: pass if "filter_events" in localvars: events.filter_events = localvars["filter_events"] else: print "Warning: can not load filter for events." events.read_log(self.inputfile) events.write_xml(self.activitypath) events.write_gource_custom(activitygourcepath) else: events.read_log(self.activitypath) self.movielength = self.get_movie_length(self.audiopath) self.analyze_events(events) self.ms4frame = int(float(self.historylength*1000)/(self.movielength*24)) - 1 self.secs4day = float(self.movielength*24*3600)/self.historylength/math.pi self.scenariopath = os.path.join(self.projectdir, "stw-scenario.txt") if not file_is_ok(self.scenariopath): lf = open(self.scenariopath, "w") else: lf = open(self.scenariopath + ".template", "w") lf.write(self.template.encode("utf-8")) lf.close() self.scenariohash = hash4file(self.scenariopath, self.version__) self.configpath = os.path.join(self.projectdir, "stw-config.py") self.configobjpath = os.path.join(self.workdir, "stw-config.txt") if not file_is_ok(self.configpath): self.write_default_config() self.confighash = hash4file(self.configpath, self.version__) self.process_user_config() if self.need_codeswarm: jarsep = ":" if os.name == "nt": jarsep = ";" if not file_is_ok(os.path.join(self.cwsnapshotdir, "cs-00007.png")): s = "".join([ 'java -Xmx1000m -classpath ', self.toolsdir, '/code_swarm.jar', jarsep, self.toolsdir, '/lib/core.jar', jarsep, self.toolsdir, '/lib/xml.jar', jarsep, self.toolsdir, '/lib/vecmath.jar', jarsep, '. ', 'code_swarm ', self.configobjpath, '/' ]) print s os.system(s) gourceconfhash = hash4file(None, "".join([self.exedir, r'\gource', ' -', str(self.width), 'x', str(self.height), ' --background ', self.background, ' --seconds-per-day ', str(self.secs4day), ]) ) grsnapshotdir = os.path.join(self.workdir, "g-"+gourceconfhash) createdir(grsnapshotdir) gourcerawpath = os.path.join(grsnapshotdir, "gource-raw.avi") if not file_is_ok(gourcerawpath): s = "".join([self.exedir, r'\gource', ' -', str(self.width), 'x', str(self.height), ' --user-scale 2 --output-framerate 25 ', ' --background ', self.background, ' --stop-position 1 ', ' --highlight-all-users ', r' --date-format "%Y-%m-%d"', ' --seconds-per-day ', str(self.secs4day), ' --log-format custom ', ' --output-ppm-stream ', gourcerawpath, '.ppm ', activitygourcepath ]) print s os.system(s) #PPM-file is very Huge. We need to compress it to h264-avi, and later kill it. s = "".join([self.exedir, r'\ffmpeg', ' -y -b 9000K -f image2pipe -vcodec ppm ', ' -i "', gourcerawpath, '.ppm"', ' -fpre ', os.path.join(self.toolsdir,'ll.ffpreset'), ' -i "', gourcerawpath, '.ppm"', ' -vcodec libx264 "', gourcerawpath, '"']) print s os.system(s) if file_is_ok(gourcerawpath): os.unlink(gourcerawpath + ".ppm") else: raise Exception("Something goes wrong with \n" + s) srtpath = os.path.join(self.workdir, "".join(["movie-", self.scenariohash, ".srt"])) if not file_is_ok(srtpath): self.process_subtitles(srtpath) if self.need_codeswarm: moviedir = os.path.join(self.cwsnapshotdir, self.scenariohash) createdir(moviedir) codeswarmpath = os.path.join(moviedir, "codeswarm.avi") if not file_is_ok(codeswarmpath): os.chdir(self.cwsnapshotdir) framescount = len(os.listdir(self.cwsnapshotdir)) codeswarmfps = framescount / self.movielength s = "".join([ self.exedir, r'\mencoder ', ' mf://*.png -mf ', ' fps=', str(codeswarmfps), ':type=png', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -oac copy ', ' -audiofile "', self.audiopath, '"', ' -sub "', srtpath, '"', ' -utf8 -font "', self.fontpath, '"', ' -subfont-text-scale 3 -sub-bg-color 20 -sub-bg-alpha 70 ', ' -o "', codeswarmpath, '"']) print s os.system(s) os.chdir(self.homedir) if self.need_gource: moviedir = os.path.join(grsnapshotdir, self.scenariohash) createdir(moviedir) gourcepath = os.path.join(moviedir, "gource.avi") if not file_is_ok(gourcepath): gourcerawlenght = self.get_movie_length(gourcerawpath) gourcefps = float(gourcerawlenght / self.movielength) os.chdir(self.cwsnapshotdir) if not file_is_ok(gourcerawpath + ".fps"): s = "".join([self.exedir, r'\mencoder "', gourcerawpath, '"', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -ofps 25 -speed ' , str(gourcefps), ' -o "', gourcerawpath, '.fps"' ]) print s os.system(s) s = "".join([self.exedir, r'\mencoder ', gourcerawpath,'.fps', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -oac copy -audiofile "', self.audiopath, '"', ' -sub "', srtpath, '"', ' -utf8 -font "', self.fontpath, '"', ' -subfont-text-scale 3 ', ' -sub-bg-color 20 -sub-bg-alpha 70 ', ' -o "', gourcepath, '"' ]) print s os.system(s) os.chdir(self.homedir) def get_result_path(sourcefile, suffix): """ Get path to result video file, using @sourcefile and @suffix """ hash_ = hash4file(sourcefile) res = os.path.join(self.projectdir, "".join([self.projectname,"-", suffix, "-", hash_, ".avi"])) return res if self.need_codeswarm and file_is_ok(codeswarmpath): resultcodeswarmpath = get_result_path(codeswarmpath, "codeswarm") if not file_is_ok(resultcodeswarmpath): shutil.copy(codeswarmpath, resultcodeswarmpath) if self.need_gource and file_is_ok(gourcepath ): resultgourcepath = get_result_path(gourcepath, "gource") if not file_is_ok(resultgourcepath ): shutil.copy(gourcepath, resultgourcepath)
def process(self): """ Main process. Do all works by «lazy way» — build the only objects, that is not already exists (Nano-«SCons/make»). """ filtereventspath = os.path.join(self.projectdir, "stw-filter-events.py") if not file_is_ok(filtereventspath): lf = open(filtereventspath, "w") lf.write(r"""# -*- coding: utf-8 -*- import re import time def filter_events(event): # You can modify event attribute, or disable (filter) event, returning False # Sample processing below emailre_ = re.compile(r"(?P<email>[-a-z0-9_.]+@(?:[-a-z0-9]+\.)+[a-z]{2,6})", re.IGNORECASE) if event.date > time.time()*1000: return False # Something wrong — event from future event.author = event.author.replace('OFFICE\\', '') event.author = event.author.lower().replace('"',"'") m = emailre_.search(event.author) if m: event.author = m.group('email') event.author = event.author.replace('"',"'") if event.author in ["(no author)"]: event.author = "anonymous" event.comment = re.sub('[Bb][Uu][Gg]\s*\d+\.?', '', event.comment) if event.comment.startswith("*** empty log message ***"): event.comment = "" if len(event.comment) < 10: event.comment = "" # #crap_prefixes=[ # "/Users/dumb/myproject/cvs_root/", # "/home/projects/myproject/cvsroot/" #] #for p in crap_prefixes: # if event.filename.startswith(p): # event.filename=event.filename.replace(p,"/") #event.action=event.action return True """) lf.close() hash_filter = hash4file(filtereventspath) self.activitypath = os.path.join( self.workdir, "".join(["activity-", hash_filter, ".xml"])) activitygourcepath = os.path.join( self.workdir, "".join(["activity-", hash_filter, ".gource"])) events = EventList() if not file_is_ok( self.activitypath) or not file_is_ok(activitygourcepath): localvars = {} try: execfile(filtereventspath, localvars) except: pass if "filter_events" in localvars: events.filter_events = localvars["filter_events"] else: print "Warning: can not load filter for events." events.read_log(self.inputfile) events.write_xml(self.activitypath) events.write_gource_custom(activitygourcepath) else: events.read_log(self.activitypath) self.movielength = self.get_movie_length(self.audiopath) self.analyze_events(events) self.ms4frame = int( float(self.historylength * 1000) / (self.movielength * 24)) - 1 self.secs4day = float( self.movielength * 24 * 3600) / self.historylength / math.pi self.scenariopath = os.path.join(self.projectdir, "stw-scenario.txt") if not file_is_ok(self.scenariopath): lf = open(self.scenariopath, "w") else: lf = open(self.scenariopath + ".template", "w") lf.write(self.template.encode("utf-8")) lf.close() self.scenariohash = hash4file(self.scenariopath, self.version__) self.configpath = os.path.join(self.projectdir, "stw-config.py") self.configobjpath = os.path.join(self.workdir, "stw-config.txt") if not file_is_ok(self.configpath): self.write_default_config() self.confighash = hash4file(self.configpath, self.version__) self.process_user_config() if self.need_codeswarm: jarsep = ":" if os.name == "nt": jarsep = ";" if not file_is_ok(os.path.join(self.cwsnapshotdir, "cs-00007.png")): s = "".join([ 'java -Xmx1000m -classpath ', self.toolsdir, '/code_swarm.jar', jarsep, self.toolsdir, '/lib/core.jar', jarsep, self.toolsdir, '/lib/xml.jar', jarsep, self.toolsdir, '/lib/vecmath.jar', jarsep, '. ', 'code_swarm ', self.configobjpath, '/' ]) print s os.system(s) gourceconfhash = hash4file( None, "".join([ self.exedir, r'\gource', ' -', str(self.width), 'x', str(self.height), ' --background ', self.background, ' --seconds-per-day ', str(self.secs4day), ])) grsnapshotdir = os.path.join(self.workdir, "g-" + gourceconfhash) createdir(grsnapshotdir) gourcerawpath = os.path.join(grsnapshotdir, "gource-raw.avi") if not file_is_ok(gourcerawpath): s = "".join([ self.exedir, r'\gource', ' -', str(self.width), 'x', str(self.height), ' --user-scale 2 --output-framerate 25 ', ' --background ', self.background, ' --stop-position 1 ', ' --highlight-all-users ', r' --date-format "%Y-%m-%d"', ' --seconds-per-day ', str(self.secs4day), ' --log-format custom ', ' --output-ppm-stream ', gourcerawpath, '.ppm ', activitygourcepath ]) print s os.system(s) #PPM-file is very Huge. We need to compress it to h264-avi, and later kill it. s = "".join([ self.exedir, r'\ffmpeg', ' -y -b 9000K -f image2pipe -vcodec ppm ', ' -i "', gourcerawpath, '.ppm"', ' -fpre ', os.path.join(self.toolsdir, 'll.ffpreset'), ' -i "', gourcerawpath, '.ppm"', ' -vcodec libx264 "', gourcerawpath, '"' ]) print s os.system(s) if file_is_ok(gourcerawpath): os.unlink(gourcerawpath + ".ppm") else: raise Exception("Something goes wrong with \n" + s) srtpath = os.path.join(self.workdir, "".join(["movie-", self.scenariohash, ".srt"])) if not file_is_ok(srtpath): self.process_subtitles(srtpath) if self.need_codeswarm: moviedir = os.path.join(self.cwsnapshotdir, self.scenariohash) createdir(moviedir) codeswarmpath = os.path.join(moviedir, "codeswarm.avi") if not file_is_ok(codeswarmpath): os.chdir(self.cwsnapshotdir) framescount = len(os.listdir(self.cwsnapshotdir)) codeswarmfps = framescount / self.movielength s = "".join([ self.exedir, r'\mencoder ', ' mf://*.png -mf ', ' fps=', str(codeswarmfps), ':type=png', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -oac copy ', ' -audiofile "', self.audiopath, '"', ' -sub "', srtpath, '"', ' -utf8 -font "', self.fontpath, '"', ' -subfont-text-scale 3 -sub-bg-color 20 -sub-bg-alpha 70 ', ' -o "', codeswarmpath, '"' ]) print s os.system(s) os.chdir(self.homedir) if self.need_gource: moviedir = os.path.join(grsnapshotdir, self.scenariohash) createdir(moviedir) gourcepath = os.path.join(moviedir, "gource.avi") if not file_is_ok(gourcepath): gourcerawlenght = self.get_movie_length(gourcerawpath) gourcefps = float(gourcerawlenght / self.movielength) os.chdir(self.cwsnapshotdir) if not file_is_ok(gourcerawpath + ".fps"): s = "".join([ self.exedir, r'\mencoder "', gourcerawpath, '"', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -ofps 25 -speed ', str(gourcefps), ' -o "', gourcerawpath, '.fps"' ]) print s os.system(s) s = "".join([ self.exedir, r'\mencoder ', gourcerawpath, '.fps', ' -ovc x264 -x264encopts pass=1:bitrate=10000 ', ' -oac copy -audiofile "', self.audiopath, '"', ' -sub "', srtpath, '"', ' -utf8 -font "', self.fontpath, '"', ' -subfont-text-scale 3 ', ' -sub-bg-color 20 -sub-bg-alpha 70 ', ' -o "', gourcepath, '"' ]) print s os.system(s) os.chdir(self.homedir) def get_result_path(sourcefile, suffix): """ Get path to result video file, using @sourcefile and @suffix """ hash_ = hash4file(sourcefile) res = os.path.join( self.projectdir, "".join([self.projectname, "-", suffix, "-", hash_, ".avi"])) return res if self.need_codeswarm and file_is_ok(codeswarmpath): resultcodeswarmpath = get_result_path(codeswarmpath, "codeswarm") if not file_is_ok(resultcodeswarmpath): shutil.copy(codeswarmpath, resultcodeswarmpath) if self.need_gource and file_is_ok(gourcepath): resultgourcepath = get_result_path(gourcepath, "gource") if not file_is_ok(resultgourcepath): shutil.copy(gourcepath, resultgourcepath)