zoukankan      html  css  js  c++  java
  • Gitweb增加增量更新功能

    很久以前开发的功能,在服务器上执行,因为Git对utf-8支持的问题,走了很多弯路,放出所有代码供大家参考:

    View Code
      1 #fei add for dl_patch download
      2 
      3 
      4 #############    some tools for pretty codes   #########
      5 sub git_write_xml_file
      6 {
      7     git_header_html(); 
      8     my $zipfile = $file_name ;#from paramter
      9     my $xmlfilename = "diff.xml";
     10     $xmlfilename = "data.$pversion.xml" if( $zipfile=~ m/pages|Documents/ );
     11     
     12     my $xmlfilepath = ($zipfile=~m/(.*\/)(.*).zip/ ? $1 : "").$xmlfilename;
     13     # now , we open the diff.xml again to fill the md5 of the zip file
     14     # by the way,we check the whether the zip file is pages,or documents
     15     if( -e $xmlfilepath && $zipfile )
     16     {
     17         my $md5 = file_md5_hex($zipfile);
     18         $md5 = uc($md5);
     19         #print "<p>$zipfile MD5: $md5</p>";
     20         my $parser = new XML::DOM::Parser ;
     21         my $doc = $parser->parsefile($xmlfilepath,ProtocolEncoding => 'UTF-8');
     22         my $root = $doc->getElementsByTagName("update")->[0];
     23         my $url = $doc->getElementsByTagName("url")->[-1];
     24         my $item = $doc->getElementsByTagName("item")->[-1];
     25         my $tmp_url = $doc->getElementsByTagName("url")->[-2];
     26         #
     27         if( defined($tmp_url) && $tmp_url->getAttribute("md5") eq "" )
     28         {
     29                 $tmp_url->setAttribute("md5",$md5);
     30         }
     31         else
     32         {
     33                 $url->setAttribute("md5",$md5);
     34         }
     35         #write the file again
     36         my $xml = ($doc->createXMLDecl('1.0')->toString).($root->toString);
     37         open my $myfd, " > $xmlfilepath ";
     38         print $myfd $xml ;
     39             close $myfd ;
     40         
     41         print_links($xmlfilepath,$xmlfilename);
     42         
     43     }
     44     git_footer_html();
     45 }
     46 
     47 sub get_timestamp
     48 {
     49    my($sec,$min,$hour,$day,$mon,$year) = (localtime(time));
     50    $mon +=1 ;
     51    $day = ($day < 10 )?"0$day":$day;
     52    $mon = ($mon < 10 )?"0$mon":$mon;
     53 
     54    return "$mon$day$hour$min" ; 
     55 }
     56 
     57 #打包文件所在路径,例如kingdom.pak
     58 sub get_project_path
     59 {
     60    my $projectName = ( $project =~ m/(.*).git/) ? $1 : ""; 
     61    #   $projectName =~  s#(\.?)#\.pak/# ;
     62    my @project_array =  split( /\./ , $projectName );
     63    my ($pak_path,$p_path) ;
     64    
     65    foreach my $folder (@project_array)
     66    {
     67        $p_path .= $folder."/" ; 
     68    }
     69    $hometouchProjectRoot = $hometouchRoot.$p_path;
     70    
     71    $project_array[0] .= ".pak" ;
     72    foreach my $folder (@project_array)
     73    {
     74        $pak_path .= $folder."/" ; 
     75    }
     76    $hometouchPakRoot = $hometouchRoot.$pak_path ;
     77 }
     78 
     79 #write the whole xml file 
     80 #input : filepath 
     81 #           check if file esist  
     82 sub write_xml_file
     83 {
     84     my ( $xmlfilepath , $zipfile , $del_array ) = @_ ;
     85     #print @$del_array;
     86     my $version = 0 ;
     87     my $newItem ;
     88     my $doc ;
     89     my $root ; 
     90     if( -e $xmlfilepath )
     91     {
     92         my $parser = new XML::DOM::Parser ; 
     93         #print "xml file existed , now adding update node to it...<br />";
     94         $doc = $parser->parsefile($xmlfilepath);
     95         my $item = $doc->getElementsByTagName("item")->[-1];
     96             $version = $item->getAttributeNode("version")->getValue;
     97             #print $version ;
     98             $root = $doc->getElementsByTagName("update")->[0];
     99         $newItem = $doc->createElement("item");
    100     }
    101     else
    102     {
    103         #print "writing first xml...";
    104         #if file doesn't exist, create one
    105         $doc = new XML::DOM::Document ;
    106         $root = $doc->createElement("update");
    107         $newItem = $doc->createElement("item");
    108     }
    109     
    110     $root->appendChild($newItem);
    111     $newItem->setAttribute("version",$version+1);
    112     $newItem->setAttribute("descript","update at:".get_timestamp);
    113     $newItem->setAttribute("clear","0");
    114     
    115     $newItem->setAttribute("target","1");
    116     $newItem->setAttribute("target","0") if($zipfile =~/Documents/) ;
    117     
    118     $newItem->setAttribute("data","$zipfile");
    119         
    120     my $url = $doc->createElement("url");
    121     $url->setAttribute("src","$zipfile",);
    122     $url->setAttribute("dest","",);
    123     $url->setAttribute("md5","",);
    124     $url->setAttribute("depress","1",);
    125     $newItem->appendChild($url);
    126     if( @$del_array )
    127     {
    128         foreach my $del (@$del_array)
    129         {
    130             my $delNode = $doc->createElement("del");
    131                     $newItem->appendChild($delNode);
    132             $delNode->setAttribute("file","$del");
    133         }
    134     }
    135     #else {print "nothing has been deleted...";}
    136     my $xml = ($doc->createXMLDecl('1.0','UTF-8')->toString).($root->toString) ;
    137     
    138     open my $myfd, " > $xmlfilepath ";
    139     print $myfd $xml ;
    140     close $myfd ;
    141     #xml tidy
    142     my $tidy_obj = XML::Tidy->new('filename' => $xmlfilepath);
    143     $tidy_obj->tidy();
    144     $tidy_obj->write();
    145     
    146 }
    147 
    148 #<feixiang> useless , for backup
    149 sub extra_zip_cmd_for_hometouch
    150 {
    151     #in order to suite hometouch , we zip the file first ,
    152     #and then ,unzip it so that we can get in the folder , then zip it again
    153     my ($fullpath , $target ) = @_ ;
    154     my $goto_path = "" ; 
    155     if( -e $fullpath )
    156     {
    157         $fullpath =~ /(.*\/)(.*\.zip)/ ;
    158         #print $fullpath;
    159         my $output_folder = $1;
    160         my $file_name = $2 ; 
    161         #chdir($output_folder);
    162         my $cmd = "unzip -o $file_name";
    163         $goto_path = $output_folder ; 
    164         qx(cd $goto_path && $cmd);
    165         qx(cd $output_folder && rm -rf $file_name );
    166         #chdir("$output_folder$target");
    167         $cmd = "zip -qr ../$file_name *";
    168         $goto_path = "$output_folder$target" ; 
    169         qx(cd $goto_path && $cmd);
    170         #chdir($output_folder);
    171         $goto_path = $output_folder ; 
    172         qx(cd $goto_path && rm -rf $target);
    173     }
    174 }
    175 
    176 #<feixiang> useless , for backup 
    177 sub exec_zip_cmd_old
    178 {
    179     my ( $fullpath , @am_array ) = @_ ; 
    180     my $cmd = "$GIT archive HEAD -o $fullpath @am_array";
    181         chdir($git_dir);
    182     qx($cmd);
    183 }
    184 #由于中文UTF-8问题,转换思路。
    185 #我们纯粹为了得到差异文件列表,所以,现在我们先将文件复制出来,再压缩这些文件得到差异包
    186 sub exec_zip_cmd
    187 {
    188     #参数:$dir ->PAK根路径+version,用于得到压缩文件的绝对路径 。
    189     my ( $dir ,$zipFileName , $am_array ) = @_ ;
    190     #print "@$am_array";
    191     
    192         if( chdir($hometouchPakRoot) )
    193     {
    194         my $tmp = "tmp";
    195         mkdir($tmp,0777) or die "createFolder error!" unless (-e $tmp);
    196         chdir($tmp) or die "chdir error";
    197         foreach my $file (@$am_array)
    198         {
    199         #print "<br />file: $file <br />";
    200             copyFileToTmp($file);
    201         }
    202         #压缩tmp文件夹,得到压缩包
    203         my $tag = "" ;
    204         $tag = "pages" if( $zipFileName =~ m/^pages/ ); 
    205         $tag = "Documents" if( $zipFileName =~ m/^Documents/ );
    206         chdir($tag) or die "chdir error" if($tag ne "");
    207         my $cmd = "zip -r $dir$zipFileName *";
    208         qx($cmd);
    209         #删除tmp文件夹内容
    210         $cmd = "rm -rf *";
    211         qx($cmd);
    212     }
    213 }
    214 #将文件复制到临时目录下,用mkpath支持创建多重目录
    215 sub copyFileToTmp
    216 {
    217     my $fileName = shift ;
    218     $fileName =~ m|(.*)/.+$| ;
    219     my $subFolder = $1 ;
    220     #print "$hometouchProjectRoot$fileName<br />";
    221     mkpath($subFolder) or die "createFolder error!" unless( -e $subFolder ) ;
    222     if( !copy("$hometouchProjectRoot$fileName" , $subFolder) )
    223     {
    224          #有一些文件无法复制,例如thumbs.db,不管它     
    225          #print "copy $hometouchProjectRoot$fileName error: $!<br />";
    226     };
    227 }
    228 
    229 
    230 sub print_zip_links
    231 {
    232    my ( $link ,$zip_fullpath , $displayName ) = @_ ; 
    233    
    234    print <<"TEXT";
    235         <h1> 
    236             <a href="$link">$displayName</a>
    237             <a style="margin:0 10px;" href="/gitweb/?p=$project;pv=$pversion;a=show_patch_xml;f=$zip_fullpath" target="_new">Generate XML File</a> 
    238         </h1><br />    
    239 TEXT
    240 
    241 }
    242 # in order to get md5 , we hide the xml file links first , when user click zip download link , we do an action to get md5 and print xml links ;   
    243 sub print_links
    244 {
    245      my ( $link  , $displayName ) = @_ ;
    246      $link =~ s/home\/webftp\/// ;
    247     print <<EOT;
    248     <h1 class="center">
    249         Please right click <a href="$link">$displayName</a> and select "Save as" to download the file. 
    250     </h1>
    251     
    252 EOT
    253 
    254 }
    255 #for all projects common codes 
    256 # at this step , we have got the added , modified  and deleted files arrays
    257 
    258 sub git_dl_patch_common
    259 {
    260     #修复多个数组传递问题,使用引用解决
    261     my ( $output_folder, $zip_filename , $xml_filename , $am_array , $del_array ) = @_ ;
    262     
    263     $output_folder=~ m/\/home\/webftp\/(.*)/;
    264     my $linkUrl = "../".$1 ;
    265     unless ( -e $output_folder )
    266     {
    267         mkdir($output_folder, 0777) or die_error(500,"cannot create output folder,check your permission!");
    268     }
    269     if( @$am_array )
    270     {
    271         exec_zip_cmd( $output_folder,$zip_filename , $am_array ) ; 
    272         print_zip_links("$linkUrl$zip_filename","$output_folder$zip_filename",$zip_filename);
    273             write_xml_file("$output_folder$xml_filename",$zip_filename,$del_array ) ;
    274     }else
    275     {
    276         print "<h1>no update available</h1>";
    277     }
    278 
    279 }
    280 #special for hometouch projects: divide into pages and Documents 
    281 sub git_dl_patch_hometouch
    282 {
    283    $pversion = "1" if(!defined $pversion || $pversion eq "");
    284    my $timestamp = get_timestamp ; 
    285    my $zip_pages_name = "pages_$timestamp.zip";
    286    my $zip_Documents_name = "Documents_$timestamp.zip";
    287    my $xml_pages_name = "data.$pversion.xml" ;
    288    my $xml_Documents_name = "data.$pversion.xml" ;
    289 
    290    my $output_folder = $hometouchPakRoot.$pversion."/" ;
    291    #print $output_folder ;
    292    # now , check if the file existed ? 
    293    
    294    if( (-e "$output_folder$zip_pages_name") 
    295           && (-e "$output_folder$xml_pages_name")
    296             && (-e "$output_folder$zip_Documents_name")
    297                && (-e "$output_folder$xml_Documents_name")
    298       )
    299    {
    300        print "<h1>files existed,right click the links and select 'save as' to download...</h1>" ;
    301          print_links("$output_folder$zip_pages_name",$zip_pages_name);
    302          print_links("$output_folder$xml_pages_name",$xml_pages_name);
    303          print_links("$output_folder$zip_Documents_name",$zip_Documents_name);
    304    }
    305    else{
    306        my @pages_amfiles = ( ) ;
    307        my @pages_delfiles = ( ) ;
    308        my @documents_amfiles = ( );
    309        my @documents_delfiles = ( );
    310        
    311        # now , we get the diff in two hashCode 
    312        my @difftree = git_diff_in2hash();
    313 
    314        foreach my $difftree_line (@difftree)
    315        {
    316         #print "<p>$difftree_line</p>";
    317            my %difftree = parse_difftree_raw_line($difftree_line);
    318            my $file = esc_path($difftree{'to_file'}) ;
    319 #print "file: $file";
    320            my $file_status = $difftree{'status'};
    321 #print "file: $file ++++ status: $file_status <br />";
    322 
    323            if( $file =~ m/^pages/ )
    324            { #if is pages fils .zip into pages.zip
    325                parse_amd_status($file,$file_status,\@pages_amfiles,\@pages_delfiles);
    326            } 
    327            if( $file =~ m/Documents/ )
    328            { #if is pages fils .zip into pages.zip
    329                parse_amd_status($file,$file_status,\@documents_amfiles,\@documents_delfiles);
    330            }
    331        }
    332        #print @documents_amfiles;#<for test>
    333        # use common methods for pages and Documents
    334        git_dl_patch_common($output_folder,$zip_pages_name,$xml_pages_name, \@pages_amfiles,\@pages_delfiles) ;
    335            #extra_zip_cmd_for_hometouch($output_folder,$zip_pages_name,"pages");
    336        git_dl_patch_common($output_folder,$zip_Documents_name,$xml_Documents_name, \@documents_amfiles,\@documents_delfiles) ;
    337        #extra_zip_cmd_for_hometouch($output_folder,$zip_Documents_name,"Documents");
    338        # then every thing is OK !
    339    }
    340 }
    341 
    342 sub parse_amd_status
    343 {
    344     #非常奇怪的问题,am_arrya和del_array反了!!!
    345    my ($file, $status ,$am_array, $del_array) = @_ ;
    346    #<2012年11月14日 修正bug : 文件名中含有括号正则会出错,需要转义>
    347    #$file =~ s#(\(|\)|\s)#\\$1#g;
    348    
    349    #<2013年1月10日>对于相似度为100%(目录不同)的文件,差异文件列表竟然没有!原因是上面取文件名时索引用错了!应该是$difftree{'to_file'}而不是$difftree{'file'}
    350    #并且将重命名与拷贝文件加入差异列表
    351    #print "<p>$file:  $status</p>";
    352    if( $status eq "A" || $status eq "M" || $status eq "R" || $status eq "C")
    353    {
    354     #print "add:$file++++$status<br />";#<for test>
    355        push @$am_array,$file ; 
    356    } 
    357    if( $status eq "D" )
    358    {
    359     #print "del:$file<br />";
    360       push @$del_array, $file ; 
    361    }
    362 }
    363 
    364 # for all projects 
    365 sub git_dl_patch_forall
    366 {
    367      my $timestamp = get_timestamp ;
    368      my $zip_filename = $timestamp.".zip";
    369      my $xml_filename = "diff.xml" ;
    370      my $output_folder = $hometouchPakRoot ;
    371      my $zip_fullpath = $output_folder.$zip_filename ; 
    372      my $xml_fullpath = $output_folder.$xml_filename ;
    373      
    374      if( -e $zip_fullpath && $xml_fullpath )
    375      {
    376          print_links($zip_fullpath,$zip_filename) ;
    377          print_links($xml_fullpath,$xml_filename) ;
    378      }
    379      else
    380      {
    381          my @difftree = git_diff_in2hash();
    382          my @am_array = () ;
    383          my @del_array = () ; 
    384          foreach my $difftree_line (@difftree)
    385          {
    386              my %difftree = parse_difftree_raw_line($difftree_line);
    387              my $file = esc_path($difftree{'file'});
    388              my $file_status = $difftree{'status'};
    389              
    390              parse_amd_status($file,$file_status,\@am_array,\@del_array);
    391              
    392           }
    393          
    394      #print "added file and modified files : @am_array.<br />" ;      
    395          git_dl_patch_common($output_folder,$zip_filename,$xml_filename,\@am_array,\@del_array);
    396      }
    397     
    398 }
    399 
    400 
    401 sub git_diff_in2hash()
    402 {
    403     $hash_base = "HEAD" if (!$hash_base) ; 
    404 
    405     open my $fd ,"-|" , git_cmd(),"diff-tree","-r",@diff_opts,"--root",$hash_base,$hash,"--",or die_error(500,"Get Diff Status Error");
    406 
    407     my @difftree = map { chomp; $_ }<$fd>;
    408     close $fd ; 
    409     return @difftree ; 
    410 }
    411 ##It's ok here , we can run the command by qx
    412 sub git_dl_patch_test
    413 {
    414     git_header_html();  
    415     qx(cd /home/git/repositories/tmp && mkdir test);
    416     git_footer_html();
    417 }
    418 
    419 #差异函数入口
    420 #事实上,只需要两个参数:工程根目录和输入路径
    421 sub git_dl_patch
    422 {
    423    git_header_html();  
    424    print << "TEXT";
    425        <div class="center">
    426        
    427 TEXT
    428 
    429     get_project_path();#使用全局变量设置工程目录与打包目录
    430     #print "$hometouchProjectRoot<br />$hometouchPakRoot<br />";
    431     
    432     if( $project =~ m/hometouch/ )
    433     {
    434         git_dl_patch_hometouch();
    435     }
    436     else   # we do common jobs 
    437     {
    438             git_dl_patch_forall();
    439     }
    440 
    441    print << "TEXT";
    442      </div>
    443 TEXT
    444 
    445    git_footer_html();
    446 }
    447 #fei add 
  • 相关阅读:
    awk去重以某列重复的行
    awk 统计文件中按照某列统计某列的和(sum)
    使用jdk压缩war包
    histoty显示时间戳
    awk统计文件中某关键词出现次数
    Jbox帮助文档,默认的属性含义
    net之session漫谈及分布式session解决方案
    StackExchange.Redis 基本使用 (一) (转)
    Sql Server 表创建以及Ef浅谈
    数据验证(自定义特性)
  • 原文地址:https://www.cnblogs.com/trying/p/3010577.html
Copyright © 2011-2022 走看看