/[Frey]/trunk/lib/Frey/SVN.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/lib/Frey/SVN.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 852 - (hide annotations)
Mon Dec 15 20:36:12 2008 UTC (15 years, 4 months ago) by dpavlin
File size: 4253 byte(s)
cleanup html generation
1 dpavlin 769 package Frey::SVN;
2     use Moose;
3    
4     # Convert output from svn log to html page (with some formatting of
5     # commit messages)
6     #
7     # 2004-04-28 Dobrica Pavlinusic <dpavlin@rot13.org>
8    
9     extends 'Frey';
10     with 'Frey::Web';
11     #with 'Frey::Storage';
12    
13     use XML::Simple;
14 dpavlin 807 use DateTimeX::Easy;
15 dpavlin 769
16     has repository => (
17     is => 'rw',
18     isa => 'Str',
19     required => 1,
20     default => 'file:///home/dpavlin/private/svn/Frey',
21     );
22    
23 dpavlin 770 has limit => (
24     is => 'rw',
25     isa => 'Int',
26     default => 50,
27     );
28    
29 dpavlin 804 sub iterator {
30     my ($self,$coderef) = @_;
31    
32 dpavlin 769 sub sh_regex($$) {
33     my ($cmd,$regex) = @_;
34     open(my $sh, $cmd . ' |') || die "sh_regex failed on $cmd: $!";
35     while(my $l = <$sh>) {
36     chomp($l);
37     if ($l =~ $regex) {
38     if ($1 && $2) {
39     return ($1,$2);
40     } elsif ($1) {
41     return $1;
42     } else {
43     return $l;
44     }
45     }
46     }
47     #warn "can't find $regex in output of $cmd\n";
48     return;
49     }
50    
51     my $path = $self->repository;
52     warn "# path $path\n";
53    
54     my $cmd;
55     if ($path =~ m#file://# || -e "$path/.svn") {
56     $cmd = "svn log -v --xml $path";
57     } else {
58     my $svn_path = sh_regex('svk info', qr#Mirrored From:\s+([^,]+)#i);
59    
60     if (! $svn_path) {
61    
62     my $svk_depot = sh_regex('svk info', qr#Depot Path: (/.+)#i);
63    
64     my $depot = $svk_depot;
65     my $rel_path;
66    
67     my $path = sh_regex('svk depot --list', qr/^$depot\s+(\S+)/i);
68    
69     while (! $path && $depot =~ s{^(/.*/)([^/]+)/?$}{$1} ) {
70     $rel_path = "$2/$rel_path";
71     $path = sh_regex('svk depot --list', qr/^$depot\s+(\S+)/i);
72     }
73    
74     die "can't find depot path '$svk_depot' in svk depot --list\n" unless ($path);
75     $svn_path = "file:///$path/$rel_path";
76     }
77    
78     $cmd = "svn log -v --xml $svn_path";
79     }
80    
81 dpavlin 770 $cmd .= " --limit " . $self->limit if $self->limit;
82    
83 dpavlin 769 warn "# $cmd\n";
84     open(my $fh, $cmd .' |') || die "failed $cmd: $!";
85     my $log;
86     while(<$fh>) {
87     $log .= $_;
88     }
89     close($fh);
90    
91     my $xml = XMLin($log, ForceArray => [ 'logentry', 'path' ]);
92    
93 dpavlin 804 foreach my $e (@{$xml->{'logentry'}}) {
94     warn "# e = ",$self->dump( $e );
95     $coderef->($e);
96     }
97     }
98    
99     sub as_markup {
100     my ($self) = @_;
101    
102     # extract svk revision: r113@athlon (orig r999): dpavlin | 2005-09-01 20:38:07 +0200
103     our $svk_rev_re = '\s+(r\d+@\w+(\s+\(orig\s+r\d+\))*:\s+\w+\s+\|\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+\+\d+)\s*';
104    
105     sub encode {
106     my $foo = shift;
107     $foo =~ s/$svk_rev_re//gsm;
108     $foo =~ s/</&lt;/g;
109     $foo =~ s/>/&gt;/g;
110     $foo =~ s/"/&quot;/g;
111     $foo =~ s/([\n\r][\n\r]+)/<\/p>$1<p>/gis;
112     $foo =~ s/([\n\r]+)([\-\*]\s+)/$1<br\/>$2/gis;
113     $foo =~ s/([\n\r]+)(r\d+:\s+)/$1<br\/>$2/gis;
114     $foo =~ s/([\n\r]+)(\s+r\d+@)/$1<br\/>$2/gis; # svk
115     return $foo;
116     }
117    
118 dpavlin 769 our $html = '';
119    
120 dpavlin 852 $self->add_css(qq|
121     .files { color: #888; }
122     .date, .revision { color: #666; }
123     .message { padding-bottom: 0.5em; }
124    
125     ins { color: #8c8 }
126     del { color: #c88 }
127     |);
128    
129 dpavlin 804 $self->iterator( sub {
130     my $e = shift;
131    
132 dpavlin 769 my $rev = $e->{'revision'};
133     my $date = $e->{'date'};
134    
135     $date =~ s/T/ /;
136     $date =~ s/\.\d+Z$//;
137    
138 dpavlin 852 $html .= qq|<div><span class="date">$date</span> <em>$e->{author}</em> <span class="revision">$e->{revision}</span></div>|;
139 dpavlin 769
140 dpavlin 852 my $msg = $e->{'msg'};
141     $msg = '' if ref($msg); # FIXME why do I need this, dammit?
142     if ( $msg ) {
143     $msg = encode( $msg );
144     $msg = qq|<div class="message">$msg</div>|;
145     }
146    
147 dpavlin 769 my @files;
148    
149     foreach my $p (@{$e->{'paths'}->{'path'}}) {
150     my ($action,$path) = ($p->{'action'},$p->{'content'});
151    
152     if ($action eq "A") {
153     push @files, "<ins>$path</ins>";
154     } elsif ($action eq "D") {
155     push @files, "<del>$path</del>";
156 dpavlin 851 } else {
157 dpavlin 769 push @files, $path;
158     }
159     }
160    
161 dpavlin 852 $html .= qq|<blockquote>$msg<div class="files">| . join(", ",@files) . qq|<div></blockquote>|;
162 dpavlin 769
163 dpavlin 804 });
164 dpavlin 769
165     return $html;
166     }
167    
168 dpavlin 805 sub codeswarm_as_markup {
169     my ($self) = @_;
170    
171     $self->content_type('text/xml');
172    
173     my $file_events = '';
174    
175     $self->iterator( sub {
176     my $e = shift;
177    
178     my $rev = $e->{'revision'};
179 dpavlin 807 my $date = DateTimeX::Easy->new( $e->{'date'} )->epoch . '000'; # ms
180 dpavlin 805 my $author = $e->{'author'};
181    
182     foreach my $p (@{$e->{'paths'}->{'path'}}) {
183     my ($action,$path) = ($p->{'action'},$p->{'content'});
184     $file_events .= qq|\t<event filename="$path" date="$date" author="$author" />\n|;
185     }
186    
187     });
188    
189     return qq|<?xml version="1.0"?>
190     <!-- One commit per day for one month by a documenter and programmer. -->
191     <file_events>
192     $file_events
193     </file_events>
194     |;
195    
196     }
197    
198 dpavlin 769 1;

  ViewVC Help
Powered by ViewVC 1.1.26