File Coverage

lib/Sorauta/SVN/AutoCommit.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             #============================================
2             # SVN自動コミットクラス
3             #
4             # -------------------------------------------
5             # アクセサ
6             # svn_mode String SVNのコミットモード
7             # commit ... 自動コミットモード
8             # update ... アップデート実行
9             # work_dir_path String 作業フォルダまでのパス
10             # ex)c:\projects\hoge_svn_dir
11             # debug Integer デバッグモード(コミット防止)
12             # 0 ... コミットする(デフォルト)
13             # 1 ... アップデートされたファイル一覧の列挙などはやるが、AddやCommit自体はしない
14             # thumbnail_width Integer サムネイル横幅
15             # デフォルトは$THUMBNAI_WIDTHの値
16             # thumbnail_height Integer サムネイル縦幅
17             # デフォルトは$THUMBNAI_HEIGHTの値
18             #
19             # changes Integer ローカルのSVNに更新があったか
20             # 0 ... 更新なし(デフォルト)
21             # 1 ... 更新あり
22             # commit_comment String コミット時のコメント
23             # デフォルトは$COMMIT_COMMENTの値
24             #
25             #============================================
26             package Sorauta::SVN::AutoCommit;
27 1     1   21501 use base qw/Class::Accessor::Fast/;
  1         3  
  1         659  
28            
29             use 5.012003;
30             use strict;
31             use warnings;
32             use utf8;
33             use CGI::Carp qw/fatalsToBrowser/;
34             use Data::Dumper;
35             use SVN::Agent;
36             use SVN::Agent::Dummy;
37             use Image::Magick;
38             use Sorauta::Utility;
39            
40             our $VERSION = '0.02';
41            
42             # サムネイルの縦横
43             our($THUMBNAIL_WIDTH, $THUMBNAIL_HEIGHT) = (160, 90);
44            
45             # コミット時のコメント
46             our $COMMIT_COMMENT = "auto commit from Sorauta::SVN::AutoCommit";
47            
48             # コミットするか否か
49             our $DEBUG = 0;
50            
51             __PACKAGE__->mk_accessors(
52             qw/svn_mode work_dir_path debug thumbnail_width thumbnail_height changes commit_comment/);
53            
54             #==========================================
55             # コミットを実行
56             # req:
57             # res:
58             #==========================================
59             sub execute {
60             my $self = shift;
61            
62             if (!$self->thumbnail_width) {
63             $self->thumbnail_width($THUMBNAIL_WIDTH);
64             }
65             if (!$self->thumbnail_height) {
66             $self->thumbnail_height($THUMBNAIL_HEIGHT);
67             }
68             if (!$self->commit_comment) {
69             $self->commit_comment($COMMIT_COMMENT);
70             }
71            
72             # must be defined accessors
73             if (!$self->svn_mode || !$self->work_dir_path) {
74             die 'must be define accessor svn_mode(auto_commit|update), work_dir_path(/Users/user/Desktop/svn_work_folder)';
75             }
76            
77             # set svn agent
78             my $sa;
79             if ($self->debug) {
80             $sa = SVN::Agent::Dummy->load({
81             path => $self->work_dir_path
82             });
83             }
84             else {
85             $sa = SVN::Agent->load({
86             path => $self->work_dir_path
87             });
88             }
89             #print Dumper($sa);
90            
91             # execute command
92             if ($self->svn_mode eq 'auto_commit') {
93             $self->_auto_commit($sa);
94             }
95             elsif ($self->svn_mode eq 'update') {
96             $self->update($sa);
97             }
98             else {
99             die 'must be define svn_mode(auto_commit|update)';
100             }
101             }
102            
103             #==========================================
104             # 自動コミットを実行
105             # TortoiseSVNの画面で全てチェック入れてコミットするイメージ
106             # req:
107             # sa: SVN::Agent(or SVN::Agent::Dummy)のインスタンス
108             # res:
109             # result: updateした結果
110             #==========================================
111             sub _auto_commit {
112             my($self, $sa) = @_;
113            
114             # show files before commit
115             $self->_show($sa);
116            
117             # add unknown files to commit file
118             $self->_add_unknown_files($sa);
119            
120             # scheduling missing file to delete file
121             $self->_remove_missing_files($sa);
122            
123             # show changed files
124             print $sa->prepare_changes, $/;
125             my @changes_files = @{ $sa->changes };
126             if (scalar(@changes_files) > 0) {
127             $self->changes(1);
128             }
129            
130             # execute commit
131             print "[commit]", $/;
132             unless ($self->debug) {
133             if ($self->changes) {
134             print $sa->commit($self->commit_comment);
135             }
136             else {
137             print "the file which should commit does not exist. ", $/;
138             }
139             }
140             else {
141             print "this is debug mode.", $/;
142             }
143             print $/;
144            
145             # update latest revision
146             $self->_update($sa);
147             }
148            
149             #==========================================
150             # アップデートを実行
151             # req:
152             # sa: SVN::Agentのインスタンス
153             # res:
154             # result: updateした結果
155             #==========================================
156             sub _update {
157             my($self, $sa) = @_;
158            
159             print "[update]", $/;
160             print $sa->update;
161             }
162            
163             #==========================================
164             # 削除されたファイル等、コミット前の状態を表示
165             # req:
166             # sa: SVN::Agentのインスタンス
167             # res:
168             # result: null
169             #==========================================
170             sub _show {
171             my($self, $sa) = @_;
172            
173             # find out unknown files
174             my @unknown_files = @{ $sa->unknown };
175             print "====== unknown(will add)", $/;
176             print join($/, @unknown_files), $/, $/;
177            
178             # find out missing files
179             my @missing_files = @{ $sa->missing };
180             print "====== missing(will remove)", $/;
181             print join($/, @missing_files), $/, $/;
182            
183             # find out modified files
184             my @modified_files = @{ $sa->modified };
185             print "====== modified", $/;
186             print join($/, @modified_files), $/, $/;
187            
188             # find out deleted files
189             my @deleted_files = @{ $sa->deleted };
190             print "====== deleted", $/;
191             print join($/, @deleted_files), $/, $/;
192            
193             # 変更がある場合、変更フラグ(changes)をたてておく
194             if (scalar(@modified_files) > 0 || scalar(@deleted_files) > 0) {
195             $self->changes(1);
196             }
197             }
198            
199             #==========================================
200             # SVN未登録のファイルをコミットするようにスケジューリング
201             # req:
202             # sa: SVN::Agentのインスタンス
203             # res:
204             # result: null
205             #==========================================
206             sub _add_unknown_files {
207             my($self, $sa) = @_;
208            
209             my @unknown_files = @{$sa->unknown};
210             foreach my $unknown_file(@unknown_files) {
211             if (is_hidden_file($unknown_file)) {
212             print $unknown_file, " ... Skip.", $/;
213             next;
214             }
215            
216             # ファイルパスをエスケープ
217             $unknown_file = _escape($unknown_file);
218             #print "scheduling:", $$self->work_dir_path.'/'.$unknown_file, $/;
219             print $sa->add($unknown_file);
220            
221             # if unknown file is directory,
222             # recrusive add including files
223             my $d_path = cat($self->work_dir_path, $unknown_file);
224             if (-d $d_path) {
225             # create thumbnail directory
226             my @mathed_pattern = split(/\\/, $unknown_file);
227             my $abs_dir_path = cat($$self->work_dir_path, 'thumbnail', $mathed_pattern[0], $mathed_pattern[1]);
228             if (!($unknown_file =~ /thumbnail/)) {
229             unless (-d $abs_dir_path) {
230             mkdir($abs_dir_path);
231             print $sa->add($abs_dir_path);
232             }
233            
234             #print "\t $d_path is dir", $/;
235             opendir my($D), $d_path;
236             foreach my $file(readdir($D)) {
237             next if is_hidden_file($file);
238            
239             # ファイルパスをエスケープ
240             $file = _escape($file);
241            
242             my $new_unknown_file = cat($unknown_file, $file);
243             #print "[add]", $new_unknown_file, $/;
244             print $sa->add($new_unknown_file);
245            
246             # add thumbnail image
247             if ($new_unknown_file =~ /^([\w\_\-]+)\\([0-9]+)\\([\w\_\.]+)/) {
248             my($type, $id_or_jan_code, $file_name) = ($1, $2, $3);
249             my $abs_dir_path = cat($$self->work_dir_path, 'thumbnail', $type, $id_or_jan_code);
250            
251             $self->_create_thumbnail_image(
252             $sa,
253             cat($self->work_dir_path, $new_unknown_file),
254             cat($abs_dir_path, $file_name));
255             }
256             }
257             close $D;
258             }
259             }
260             else {
261             # add thumbnail image
262             if ($unknown_file =~ /^([\w\_\-]+)\\([0-9]+)\\([\w\_\.]+)/) {
263             my($type, $id_or_jan_code, $file_name) = ($1, $2, $3);
264             my $abs_dir_path = cat($$self->work_dir_path, 'thumbnail', $type, $id_or_jan_code);
265            
266             $self->_create_thumbnail_image(
267             $sa,
268             cat($self->work_dir_path, $unknown_file),
269             cat($abs_dir_path, $file_name));
270             }
271             }
272             }
273             }
274            
275             #==========================================
276             # SVNに登録済みだがローカルに存在しない場合削除するようにスケジューリング
277             # req:
278             # sa: SVN::Agentのインスタンス
279             # res:
280             # result: null
281             #==========================================
282             sub _remove_missing_files {
283             my($self, $sa) = @_;
284            
285             my @missing_files = @{$sa->missing};
286             foreach my $missing_file(@missing_files) {
287             next if is_hidden_file($missing_file);
288            
289             # ファイルパスをエスケープ
290             $missing_file = _escape($missing_file);
291            
292             $sa->remove($missing_file);
293            
294             # サムネイル画像も削除
295             if ($missing_file =~ /^([\w\_\-]+)\\([0-9]+)\\([\w\_\.]+)/) {
296             my($type, $id_or_jan_code, $file_name) = ($1, $2, $3);
297            
298             # ファイルパスをエスケープ
299             $file_name = _escape($file_name);
300            
301             my $dir_path = cat($$self->work_dir_path, 'thumbnail', $type, $id_or_jan_code);
302             if (-e cat($dir_path, $file_name)) {
303             $sa->remove(cat($dir_path, $file_name));
304             }
305             }
306             }
307             }
308            
309             #==========================================
310             # サムネイルを生成する
311             # req:
312             # sa: SVN::Agentのインスタンス
313             # original_file_path: 元ファイルのパス
314             # thumbnail_file_path: サムネイルファイルのパス
315             # res:
316             # result: null
317             #==========================================
318             sub _create_thumbnail_image {
319             my($self, $sa, $original_file_path, $thumbnail_file_path) = @_;
320             my $image = Image::Magick->new;
321            
322             # 元画像を読み込む
323             print $image->Read(
324             $original_file_path
325             );
326            
327             # タテヨコ比率指定
328             print $image->Resize(
329             geometry => $self->thumbnail_width.'x'.$self->thumbnail_height
330             );
331            
332             # ファイル保存
333             print $image->Write(
334             filename => $thumbnail_file_path,
335             compression => 'None'
336             );
337            
338             # 追加する
339             print $sa->add($thumbnail_file_path);
340             }
341            
342             #==========================================
343             # ファイル等をエスケープ
344             # req:
345             # file_str: ファイル文字列
346             # res:
347             # file_str: エスケープ後のファイル文字列
348             #==========================================
349             sub _escape {
350             return quotemeta(shift);
351             }
352            
353             1;
354            
355             __END__