Showing 8 changed files with 240 additions and 115 deletions
+10 -2
lib/Gitprep.pm
... ...
@@ -116,7 +116,15 @@ sub startup {
116 116
   
117 117
   # Helper
118 118
   $self->helper(gitprep_api => sub { Gitprep::API->new(shift) });
119
-
119
+  $self->helper(finish_rendering => sub {
120
+    my $self = shift;
121
+    
122
+    $self->stash->{'mojo.routed'} = 1;
123
+    $self->rendered;
124
+    
125
+    return $self;
126
+  });
127
+  
120 128
   # Routes
121 129
   my $r = $self->routes;
122 130
 
... ...
@@ -179,7 +187,7 @@ sub startup {
179 187
       $r->get('/commits/#rev/(*blob)')->name('commits');
180 188
       
181 189
       # Branches
182
-      $r->get('/branches')->name('branches');
190
+      $r->any('/branches')->name('branches');
183 191
 
184 192
       # Tags
185 193
       $r->get('/tags')->name('tags');
+13 -4
lib/Gitprep/API.pm
... ...
@@ -87,21 +87,30 @@ sub logined_admin {
87 87
 }
88 88
 
89 89
 sub logined {
90
-  my $self = shift;
90
+  my ($self, $user) = @_;
91 91
   
92 92
   my $c = $self->cntl;
93 93
   
94 94
   my $dbi = $c->app->dbi;
95 95
   
96
-  my $user = $c->session('user');
96
+  my $current_user = $c->session('user');
97 97
   my $password = $c->session('password');
98 98
   return unless defined $password;
99 99
   
100 100
   my $correct_password
101
-    = $dbi->model('user')->select('password', id => $user)->value;
101
+    = $dbi->model('user')->select('password', id => $current_user)->value;
102 102
   return unless defined $correct_password;
103 103
   
104
-  return $password eq $correct_password;
104
+  my $logined;
105
+  
106
+  if (defined $user) {
107
+    $logined = $user eq $current_user && $password eq $correct_password;
108
+  }
109
+  else {
110
+    $logined = $password eq $correct_password
111
+  }
112
+  
113
+  return $logined;
105 114
 }
106 115
 
107 116
 sub users {
+108 -86
lib/Gitprep/Git.pm
... ...
@@ -172,21 +172,6 @@ sub blob_plain {
172 172
   return $content;
173 173
 }
174 174
 
175
-sub blob_raw {
176
-  my ($self, $user, $project, $rev, $path) = @_;
177
-  
178
-  # Get blob raw
179
-  my @cmd = $self->cmd($user, $project, 'cat-file', 'blob', "$rev:$path");
180
-  open my $fh, "-|", @cmd
181
-    or croak 500, "Open git-cat-file failed";
182
-  local $/;
183
-  my $blob_raw = scalar <$fh>;
184
-
185
-  close $fh or croak 'Reading git-shortlog failed';
186
-  
187
-  return $blob_raw;
188
-}
189
-
190 175
 sub blob_mimetype {
191 176
   my ($self, $user, $project, $rev, $file) = @_;
192 177
   
... ...
@@ -233,6 +218,43 @@ sub blob_contenttype {
233 218
   return $type;
234 219
 }
235 220
 
221
+sub blob_mode {
222
+  my ($self, $user, $project, $rev, $file) = @_;
223
+  
224
+  # Mode
225
+  $file =~ s#/+$##;
226
+  my @cmd = $self->cmd(
227
+    $user,
228
+    $project,
229
+    'ls-tree',
230
+    $rev,
231
+    '--',
232
+    $file
233
+  );
234
+  open my $fh, '-|', @cmd
235
+    or croak 'Open git-ls-tree failed';
236
+  my $line = $self->_dec(scalar <$fh>);
237
+  close $fh or return;
238
+  my ($mode) = ($line || '') =~ m/^([0-9]+) /;
239
+  
240
+  return $mode;
241
+}
242
+
243
+sub blob_raw {
244
+  my ($self, $user, $project, $rev, $path) = @_;
245
+  
246
+  # Get blob raw
247
+  my @cmd = $self->cmd($user, $project, 'cat-file', 'blob', "$rev:$path");
248
+  open my $fh, "-|", @cmd
249
+    or croak 500, "Open git-cat-file failed";
250
+  local $/;
251
+  my $blob_raw = scalar <$fh>;
252
+
253
+  close $fh or croak 'Reading git-shortlog failed';
254
+  
255
+  return $blob_raw;
256
+}
257
+
236 258
 sub blob_size_kb {
237 259
   my ($self, $user, $project, $rev, $file) = @_;
238 260
   
... ...
@@ -341,6 +363,28 @@ sub commits_number {
341 363
   return $commits_num;
342 364
 }
343 365
 
366
+sub delete_branch {
367
+  my ($self, $user, $project, $branch) = @_;
368
+  
369
+  my $branches = $self->branches($user, $project);
370
+  my $exists;
371
+  for my $b (@$branches) {
372
+    if ($branch eq $b->{name}) {
373
+      $exists = 1;
374
+      next;
375
+    }
376
+  }
377
+  
378
+  if ($exists) {
379
+    my @cmd = $self->cmd($user, $project, 'branch', '-D', $branch);
380
+    system(@cmd) == 0
381
+      or croak "Branch deleting failed. Can't delete branch $branch";
382
+  }
383
+  else {
384
+    croak "Branch deleteting failed.. branchg $branch is not exists";
385
+  }
386
+}
387
+
344 388
 sub description {
345 389
   my ($self, $user, $project, $description) = @_;
346 390
   
... ...
@@ -362,77 +406,6 @@ sub description {
362 406
   }
363 407
 }
364 408
 
365
-sub blob_mode {
366
-  my ($self, $user, $project, $rev, $file) = @_;
367
-  
368
-  # Mode
369
-  $file =~ s#/+$##;
370
-  my @cmd = $self->cmd(
371
-    $user,
372
-    $project,
373
-    'ls-tree',
374
-    $rev,
375
-    '--',
376
-    $file
377
-  );
378
-  open my $fh, '-|', @cmd
379
-    or croak 'Open git-ls-tree failed';
380
-  my $line = $self->_dec(scalar <$fh>);
381
-  close $fh or return;
382
-  my ($mode) = ($line || '') =~ m/^([0-9]+) /;
383
-  
384
-  return $mode;
385
-}
386
-
387
-sub file_type {
388
-  my ($self, $mode) = @_;
389
-  
390
-  # File type
391
-  if ($mode !~ m/^[0-7]+$/) { return $mode }
392
-  else { $mode = oct $mode }
393
-  if ($self->_s_isgitlink($mode)) { return 'submodule' }
394
-  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
395
-  elsif (S_ISLNK($mode)) { return 'symlink' }
396
-  elsif (S_ISREG($mode)) { return 'file' }
397
-  else { return 'unknown' }
398
-  
399
-  return
400
-}
401
-
402
-sub file_type_long {
403
-  my ($self, $mode) = @_;
404
-  
405
-  # File type
406
-  if ($mode !~ m/^[0-7]+$/) { return $mode }
407
-  else { $mode = oct $mode }
408
-  if ($self->_s_isgitlink($mode)) { return 'submodule' }
409
-  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
410
-  elsif (S_ISLNK($mode)) { return 'symlink' }
411
-  elsif (S_ISREG($mode)) {
412
-    if ($mode & S_IXUSR) { return 'executable file' }
413
-    else { return 'file' }
414
-  }
415
-  else { return 'unknown' }
416
-  
417
-  return;
418
-}
419
-
420
-sub fill_from_file_info {
421
-  my ($self, $user, $project, $diff, $parents) = @_;
422
-  
423
-  # Fill file info
424
-  $diff->{from_file} = [];
425
-  $diff->{from_file}[$diff->{nparents} - 1] = undef;
426
-  for (my $i = 0; $i < $diff->{nparents}; $i++) {
427
-    if ($diff->{status}[$i] eq 'R' || $diff->{status}[$i] eq 'C') {
428
-      $diff->{from_file}[$i] =
429
-        $self->path_by_id($user, $project, $parents->[$i], $diff->{from_id}[$i]);
430
-    }
431
-  }
432
-
433
-  return $diff;
434
-}
435
-
436 409
 sub difftree {
437 410
   my ($self, $user, $project, $cid, $parent, $parents) = @_;
438 411
   
... ...
@@ -504,6 +477,55 @@ sub difftree {
504 477
   return $diffs;
505 478
 }
506 479
 
480
+sub file_type {
481
+  my ($self, $mode) = @_;
482
+  
483
+  # File type
484
+  if ($mode !~ m/^[0-7]+$/) { return $mode }
485
+  else { $mode = oct $mode }
486
+  if ($self->_s_isgitlink($mode)) { return 'submodule' }
487
+  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
488
+  elsif (S_ISLNK($mode)) { return 'symlink' }
489
+  elsif (S_ISREG($mode)) { return 'file' }
490
+  else { return 'unknown' }
491
+  
492
+  return
493
+}
494
+
495
+sub file_type_long {
496
+  my ($self, $mode) = @_;
497
+  
498
+  # File type
499
+  if ($mode !~ m/^[0-7]+$/) { return $mode }
500
+  else { $mode = oct $mode }
501
+  if ($self->_s_isgitlink($mode)) { return 'submodule' }
502
+  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
503
+  elsif (S_ISLNK($mode)) { return 'symlink' }
504
+  elsif (S_ISREG($mode)) {
505
+    if ($mode & S_IXUSR) { return 'executable file' }
506
+    else { return 'file' }
507
+  }
508
+  else { return 'unknown' }
509
+  
510
+  return;
511
+}
512
+
513
+sub fill_from_file_info {
514
+  my ($self, $user, $project, $diff, $parents) = @_;
515
+  
516
+  # Fill file info
517
+  $diff->{from_file} = [];
518
+  $diff->{from_file}[$diff->{nparents} - 1] = undef;
519
+  for (my $i = 0; $i < $diff->{nparents}; $i++) {
520
+    if ($diff->{status}[$i] eq 'R' || $diff->{status}[$i] eq 'C') {
521
+      $diff->{from_file}[$i] =
522
+        $self->path_by_id($user, $project, $parents->[$i], $diff->{from_id}[$i]);
523
+    }
524
+  }
525
+
526
+  return $diff;
527
+}
528
+
507 529
 sub branches {
508 530
   my ($self, $user, $project, $opts) = @_;
509 531
   
+1 -1
templates/auto/_admin/user/create.html.ep
... ...
@@ -68,7 +68,7 @@
68 68
     % }
69 69
     
70 70
     % if ($errors) {
71
-      <div class="alert">
71
+      <div class="alert alert-error">
72 72
         <button type="button" class="close" data-dismiss="alert">&times;</button>
73 73
         % for my $error (@$errors) {
74 74
           <p><%= $error %></p>
+4
templates/auto/_admin/user/delete.html.ep
... ...
@@ -7,6 +7,10 @@
7 7
   my $errors;
8 8
   if ($op eq 'delete') {
9 9
 
10
+    unless ($api->logined) {
11
+      return $self->render_exception;
12
+    }
13
+
10 14
     # Validation
11 15
     my $params = $api->params;
12 16
     my $validator = $self->app->validator;
-8
templates/auto/a.html.ep
... ...
@@ -1,8 +0,0 @@
1
-    <%
2
-      use Encode 'encode';
3
-      
4
-      $self->res->headers->content_type('text/plain;charset=UTF-8');
5
-      $self->res->body(encode('UTF-8', 'あ'));
6
-      $self->rendered;
7
-      return;
8
-    %>
+101 -9
templates/branches.html.ep
... ...
@@ -5,20 +5,86 @@
5 5
   # Parameters
6 6
   my $user = param('user');
7 7
   my $project = param('project');
8
+  my $op = param('op');
8 9
   
9 10
   # Git
10 11
   my $git = $self->app->git;
11
-  
12
+
12 13
   # Default branch
13 14
   my $default_branch = {};
14
-  $default_branch->{name} = app->manager->default_branch($user, $project);
15
-  $default_branch->{commit} = $git->get_commit($user, $project, $default_branch->{name});
16 15
   
17
-  # No merged branches
18
-  my $branches  = $git->branches($user, $project);
19
-  my $branches_count = $git->branches_count($user, $project);
20
-  my $no_merged_branches_count = $git->no_merged_branches_count($user, $project);
21
-  my $merged_branches_count = $branches_count - $no_merged_branches_count - 1;
16
+  # Branch
17
+  my $branches;
18
+  my $branches_count;
19
+  my $no_merged_branches_count;
20
+  my $merged_branches_count;
21
+  
22
+  # Delete
23
+  my $errors;
24
+  if ($op eq 'delete') {
25
+
26
+    # Validation
27
+    my $params = $api->params;
28
+    my $validator = $self->app->validator;
29
+    my $rule = [
30
+      user => [
31
+        ['not_blank' => 'User name is empty.']
32
+      ],
33
+      project => [
34
+        ['not_blank' => 'Repository name is empty']
35
+      ],
36
+      branch => [
37
+        ['not_blank' => 'Branch name is empty']
38
+      ]
39
+    ];
40
+    my $vresult = $validator->validate($params, $rule);
41
+
42
+    if ($vresult->is_ok) {
43
+      
44
+      # Valid parameters
45
+      my $params = $vresult->data;
46
+      my $user = $params->{user};
47
+      my $project = $params->{project};
48
+      my $branch = $params->{branch};
49
+      
50
+      # Delete branch
51
+      if ($api->logined($user)) {
52
+      
53
+        # Delete user
54
+        eval { $git->delete_branch($user, $project, $branch) };
55
+        if ($@) {
56
+          app->log->error($@);
57
+          $errors = ['Internal Error'];
58
+        }
59
+        else {
60
+          $self->flash(branch_deleted => 1);
61
+          $self->flash(branch => $branch);
62
+          $self->redirect_to;
63
+          $self->finish_rendering;
64
+          return;
65
+        }
66
+      }
67
+      # Forbidden
68
+      else {
69
+        $self->res->code('403');
70
+        $self->finish_rendering;
71
+        return;
72
+      }
73
+    }
74
+    else { $errors = $vresult->messages }
75
+  }
76
+  # List
77
+  else {
78
+    # Default branch
79
+    $default_branch->{name} = app->manager->default_branch($user, $project);
80
+    $default_branch->{commit} = $git->get_commit($user, $project, $default_branch->{name});
81
+    
82
+    # No merged branches
83
+    $branches  = $git->branches($user, $project);
84
+    $branches_count = $git->branches_count($user, $project);
85
+    $no_merged_branches_count = $git->no_merged_branches_count($user, $project);
86
+    $merged_branches_count = $branches_count - $no_merged_branches_count - 1;
87
+  }
22 88
 %>
23 89
 
24 90
 % layout 'common';
... ...
@@ -45,12 +111,32 @@
45 111
         }
46 112
         display_no_merged = !display_no_merged;
47 113
       });
114
+      
115
+      // Click delete button
116
+      $('.delete-branch').on('click', function () {
117
+        if (window.confirm('Are you sure you want to remove this branch?')) {
118
+          return true;
119
+        }
120
+        else {
121
+          return false;
122
+        }
123
+      });
48 124
     });
49 125
   % end
50 126
   
51 127
   %= include '/include/header';
52 128
   
53
-  <div class="container">
129
+  <div class="container" style="padding-bottom:30px">
130
+
131
+    % if ($errors) {
132
+      <div class="alert alert-error">
133
+        <button type="button" class="close" data-dismiss="alert">&times;</button>
134
+        % for my $error (@$errors) {
135
+          <p><%= $error %></p>
136
+        % }
137
+      </div>
138
+    % }
139
+    
54 140
     %= include '/include/project_header';
55 141
     %= include '/include/code_menu', display => 'branches';
56 142
     
... ...
@@ -113,6 +199,12 @@
113 199
             </div>
114 200
           </div>
115 201
           <div class="text-right" style="padding-top:5px">
202
+            % if ($api->logined($user)) {
203
+              <form action="<%= url_for->query(op => 'delete') %>" method="post" style="display:inline-block">
204
+                <input type="submit" class="btn delete-branch" style="color:#900;" value="Delete branch">
205
+                %= hidden_field branch => $bname;
206
+              </form>
207
+            % }
116 208
             <a class="btn" href="<%= url_for("/$user/$project/compare/$default_branch->{name}...$bname") %>">
117 209
               Compare
118 210
             </a>
+3 -5
templates/raw.html.ep
... ...
@@ -36,12 +36,10 @@
36 36
   $content_disposition .= "; filename=$file_name";
37 37
   
38 38
   # Response
39
-  $self->res->code(200);
40 39
   $self->res->headers->content_disposition($content_disposition);
41 40
   $self->res->headers->content_type($type);
42
-  $self->res->body($blob_raw);
43
-  $self->rendered;
44
-  $self->stash->{'mojo.routed'} = 1;
41
+  $self->render(data => $blob_raw);
42
+  $self->finish_rendering;
45 43
   
46 44
   return;
47
-%>
45
+%>