<s> from . import messages <EOL> from . import utils <EOL> from protorpc import protojson <EOL> import ConfigParser <EOL> import datetime <EOL> import git <EOL> import hashlib <EOL> import logging <EOL> import progressbar <EOL> import texttable <EOL> import threading <EOL> class Error ( Exception ) : <EOL> pass <EOL> class CorruptIndexError ( Error ) : <EOL> pass <EOL> class ProgressBarThread ( threading . Thread ) : <EOL> def __init__ ( self , bar , enabled , * args , ** kwargs ) : <EOL> self . bar = bar <EOL> self . enabled = enabled <EOL> super ( ProgressBarThread , self ) . __init__ ( * args , ** kwargs ) <EOL> def run ( self ) : <EOL> super ( ProgressBarThread , self ) . run ( ) <EOL> if self . enabled : <EOL> self . bar . update ( self . bar . currval + <NUM_LIT:1> ) <EOL> class Diff ( object ) : <EOL> @ classmethod <EOL> def is_empty ( cls , diff ) : <EOL> return not diff . adds and not diff . deletes and not diff . edits <EOL> @ classmethod <EOL> def _format_author ( cls , author , include_email = True ) : <EOL> if include_email : <EOL> return '<STR_LIT>' . format ( author . name , author . email ) if author else '<STR_LIT>' <EOL> return author . name if author else '<STR_LIT>' <EOL> @ classmethod <EOL> def _make_diff_row ( cls , color , label , message ) : <EOL> label = texttable . get_color_string ( color , label ) <EOL> path = texttable . get_color_string ( texttable . bcolors . WHITE , message . path ) <EOL> formatted_author = cls . _format_author ( message . deployed_by , True ) <EOL> deployed = str ( message . deployed ) . split ( '<STR_LIT:.>' ) [ <NUM_LIT:0> ] [ : - <NUM_LIT:3> ] if message . deployed else '<STR_LIT>' <EOL> return [ label , path , deployed , formatted_author ] <EOL> @ classmethod <EOL> def pretty_print ( cls , diff ) : <EOL> last_commit = diff . indexes [ <NUM_LIT:0> ] . commit <EOL> new_commit = diff . indexes [ <NUM_LIT:1> ] . commit <EOL> last_index = diff . indexes [ <NUM_LIT:0> ] <EOL> new_index = diff . indexes [ <NUM_LIT:1> ] <EOL> table = texttable . Texttable ( max_width = <NUM_LIT:0> ) <EOL> table . set_deco ( texttable . Texttable . HEADER ) <EOL> rows = [ ] <EOL> rows . append ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> file_rows = [ ] <EOL> for add in diff . adds : <EOL> file_rows . append ( cls . _make_diff_row ( texttable . bcolors . GREEN , '<STR_LIT>' , add ) ) <EOL> for edit in diff . edits : <EOL> file_rows . append ( cls . _make_diff_row ( texttable . bcolors . PURPLE , '<STR_LIT>' , edit ) ) <EOL> for delete in diff . deletes : <EOL> file_rows . append ( cls . _make_diff_row ( texttable . bcolors . RED , '<STR_LIT>' , delete ) ) <EOL> file_rows . sort ( key = lambda row : row [ <NUM_LIT:1> ] ) <EOL> rows += file_rows <EOL> table . add_rows ( rows ) <EOL> logging . info ( '<STR_LIT:\n>' + table . draw ( ) + '<STR_LIT:\n>' ) <EOL> if last_index . deployed and last_index . deployed_by : <EOL> logging . info ( '<STR_LIT>' . format ( <EOL> last_index . deployed , cls . _format_author ( last_index . deployed_by ) ) ) <EOL> last_commit_sha = last_commit . sha if last_commit else '<STR_LIT>' <EOL> new_commit_sha = new_commit . sha if new_commit else '<STR_LIT>' <EOL> if new_index . deployed_by : <EOL> between_commits = '<STR_LIT>' . format ( <EOL> last_commit_sha [ : <NUM_LIT:7> ] , <EOL> new_commit_sha [ : <NUM_LIT:7> ] ) <EOL> if new_commit : <EOL> if new_commit . has_unstaged_changes : <EOL> between_commits += '<STR_LIT>' <EOL> else : <EOL> between_commits += '<STR_LIT>' <EOL> logging . info ( '<STR_LIT>' . format ( <EOL> between_commits , new_index . deployed_by . email ) ) <EOL> if diff . what_changed : <EOL> logging . info ( diff . what_changed + '<STR_LIT:\n>' ) <EOL> @ classmethod <EOL> def create ( cls , index , theirs , repo = None ) : <EOL> diff = messages . DiffMessage ( ) <EOL> diff . indexes = [ ] <EOL> diff . indexes . append ( theirs or messages . IndexMessage ( ) ) <EOL> diff . indexes . append ( index or messages . IndexMessage ( ) ) <EOL> index_paths_to_shas = { } <EOL> their_paths_to_shas = { } <EOL> for file_message in index . files : <EOL> index_paths_to_shas [ file_message . path ] = file_message . sha <EOL> for file_message in theirs . files : <EOL> their_paths_to_shas [ file_message . path ] = file_message . sha <EOL> for path , sha in index_paths_to_shas . iteritems ( ) : <EOL> if path in their_paths_to_shas : <EOL> if index_paths_to_shas [ path ] == their_paths_to_shas [ path ] : <EOL> file_message = messages . FileMessage ( ) <EOL> file_message . path = path <EOL> file_message . deployed = theirs . deployed <EOL> file_message . deployed_by = theirs . deployed_by <EOL> diff . nochanges . append ( file_message ) <EOL> else : <EOL> file_message = messages . FileMessage ( ) <EOL> file_message . path = path <EOL> file_message . deployed = theirs . deployed <EOL> file_message . deployed_by = theirs . deployed_by <EOL> diff . edits . append ( file_message ) <EOL> del their_paths_to_shas [ path ] <EOL> else : <EOL> file_message = messages . FileMessage ( ) <EOL> file_message . path = path <EOL> diff . adds . append ( file_message ) <EOL> for path , sha in their_paths_to_shas . iteritems ( ) : <EOL> file_message = messages . FileMessage ( ) <EOL> file_message . path = path <EOL> file_message . deployed = theirs . deployed <EOL> file_message . deployed_by = theirs . deployed_by <EOL> diff . deletes . append ( file_message ) <EOL> if ( repo is not None <EOL> and index . commit and index . commit . sha <EOL> and theirs . commit and theirs . commit . sha ) : <EOL> try : <EOL> what_changed = repo . git . log ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( theirs . commit . sha , index . commit . sha ) ) <EOL> diff . what_changed = what_changed . decode ( '<STR_LIT:utf-8>' ) <EOL> except git . exc . GitCommandError : <EOL> logging . info ( '<STR_LIT>' ) <EOL> elif ( repo is not None <EOL> and index . commit and index . commit . sha ) : <EOL> what_changed = repo . git . log ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ) <EOL> diff . what_changed = what_changed . decode ( '<STR_LIT:utf-8>' ) <EOL> return diff <EOL> @ classmethod <EOL> def to_string ( cls , message ) : <EOL> return protojson . encode_message ( message ) <EOL> @ classmethod <EOL> def apply ( cls , message , paths_to_content , write_func , delete_func , threaded = True , <EOL> batch_writes = False ) : <EOL> diff = message <EOL> threads = [ ] <EOL> num_files = len ( diff . adds ) + len ( diff . edits ) + len ( diff . deletes ) <EOL> text = '<STR_LIT>' <EOL> widgets = [ progressbar . FormatLabel ( text . format ( num_files ) ) ] <EOL> bar = progressbar . ProgressBar ( widgets = widgets , maxval = num_files ) <EOL> if batch_writes : <EOL> writes_paths_to_contents = { } <EOL> for file_message in diff . adds : <EOL> writes_paths_to_contents [ file_message . path ] = paths_to_content [ file_message . path ] <EOL> for file_message in diff . edits : <EOL> writes_paths_to_contents [ file_message . path ] = paths_to_content [ file_message . path ] <EOL> deletes_paths = [ file_message . path for file_message in diff . deletes ] <EOL> if writes_paths_to_contents : <EOL> write_func ( writes_paths_to_contents ) <EOL> if deletes_paths : <EOL> delete_func ( deletes_paths ) <EOL> else : <EOL> bar . start ( ) <EOL> for file_message in diff . adds : <EOL> content = paths_to_content [ file_message . path ] <EOL> thread = ProgressBarThread ( <EOL> bar , True , target = write_func , args = ( file_message . path , content ) ) <EOL> threads . append ( thread ) <EOL> thread . start ( ) <EOL> if not threaded : <EOL> thread . join ( ) <EOL> for file_message in diff . edits : <EOL> content = paths_to_content [ file_message . path ] <EOL> thread = ProgressBarThread ( <EOL> bar , True , target = write_func , args = ( file_message . path , content ) ) <EOL> threads . append ( thread ) <EOL> thread . start ( ) <EOL> if not threaded : <EOL> thread . join ( ) <EOL> for file_message in diff . deletes : <EOL> thread = ProgressBarThread ( <EOL> bar , batch_writes , target = delete_func , args = ( file_message . path , ) ) <EOL> threads . append ( thread ) <EOL> thread . start ( ) <EOL> if not threaded : <EOL> thread . join ( ) <EOL> if threaded : <EOL> for thread in threads : <EOL> thread . join ( ) <EOL> if not batch_writes : <EOL> bar . finish ( ) <EOL> class Index ( object ) : <EOL> @ classmethod <EOL> def create ( cls , paths_to_contents = None ) : <EOL> message = messages . IndexMessage ( ) <EOL> message . deployed = datetime . datetime . now ( ) <EOL> message . files = [ ] <EOL> if paths_to_contents is None : <EOL> return message <EOL> for pod_path , contents in paths_to_contents . iteritems ( ) : <EOL> cls . add_file ( message , pod_path , contents ) <EOL> return message <EOL> @ classmethod <EOL> def add_file ( cls , message , path , contents ) : <EOL> pod_path = '<STR_LIT:/>' + path . lstrip ( '<STR_LIT:/>' ) <EOL> m = hashlib . sha1 ( ) <EOL> if isinstance ( contents , unicode ) : <EOL> contents = contents . encode ( '<STR_LIT:utf-8>' ) <EOL> m . update ( contents ) <EOL> sha = m . hexdigest ( ) <EOL> message . files . append ( messages . FileMessage ( path = pod_path , sha = sha ) ) <EOL> return message <EOL> @ classmethod <EOL> def add_repo ( cls , message , repo ) : <EOL> config = repo . config_reader ( ) <EOL> try : <EOL> message . deployed_by = messages . AuthorMessage ( <EOL> name = config . get ( '<STR_LIT:user>' , '<STR_LIT:name>' ) , <EOL> email = config . get ( '<STR_LIT:user>' , '<STR_LIT:email>' ) ) <EOL> except ( ConfigParser . NoSectionError , ConfigParser . NoOptionError ) : <EOL> logging . warning ( "<STR_LIT>" ) <EOL> try : <EOL> message . commit = utils . create_commit_message ( repo ) <EOL> except utils . NoGitHeadError as e : <EOL> logging . warning ( e ) <EOL> return message <EOL> @ classmethod <EOL> def to_string ( cls , message ) : <EOL> return protojson . encode_message ( message ) <EOL> @ classmethod <EOL> def from_string ( cls , content ) : <EOL> return protojson . decode_message ( messages . IndexMessage , content ) </s>
