... | ... |
@@ -101,5 +101,28 @@ sub delete_project { |
101 | 101 |
my $dbi = $c->app->dbi; |
102 | 102 |
$dbi->model('project')->delete(id => [$user, $project]); |
103 | 103 |
} |
104 |
+ |
|
105 |
+sub exists_project { |
|
106 |
+ my ($self, $user, $project) = @_; |
|
107 |
+ |
|
108 |
+ my $c = $self->cntl; |
|
109 |
+ my $dbi = $c->app->dbi; |
|
110 |
+ my $row = $dbi->model('project')->select(id => [$user, $project])->one; |
|
111 |
+ |
|
112 |
+ return $row ? 1 : 0; |
|
113 |
+} |
|
114 |
+ |
|
115 |
+sub rename_project { |
|
116 |
+ my ($self, $user, $project, $renamed_project) = @_; |
|
117 |
+ |
|
118 |
+ my $c = $self->cntl; |
|
119 |
+ my $dbi = $c->app->dbi; |
|
120 |
+ |
|
121 |
+ croak "Invalid parameters" |
|
122 |
+ unless defined $user && defined $project && defined $renamed_project; |
|
123 |
+ |
|
124 |
+ $dbi->model('project')->update({name => $renamed_project}, id => [$user, $project]); |
|
125 |
+} |
|
126 |
+ |
|
104 | 127 |
1; |
105 | 128 |
|
... | ... |
@@ -341,6 +341,27 @@ sub delete_project { |
341 | 341 |
rmtree($rep); |
342 | 342 |
} |
343 | 343 |
|
344 |
+sub description { |
|
345 |
+ my ($self, $user, $project, $description) = @_; |
|
346 |
+ |
|
347 |
+ my $rep = $self->rep($user, $project); |
|
348 |
+ my $file = "$rep/description"; |
|
349 |
+ |
|
350 |
+ if (defined $description) { |
|
351 |
+ # Write description |
|
352 |
+ open my $fh, '>',$file |
|
353 |
+ or croak "Can't open file $rep: $!"; |
|
354 |
+ print $fh encode('UTF-8', $description) |
|
355 |
+ or croak "Can't write description: $!"; |
|
356 |
+ close $fh; |
|
357 |
+ } |
|
358 |
+ else { |
|
359 |
+ # Read description |
|
360 |
+ my $description = $self->_slurp($file) || ''; |
|
361 |
+ return $description; |
|
362 |
+ } |
|
363 |
+} |
|
364 |
+ |
|
344 | 365 |
sub exists_repository { |
345 | 366 |
my ($self, $user, $project) = @_; |
346 | 367 |
|
... | ... |
@@ -583,27 +604,6 @@ sub path_by_id { |
583 | 604 |
return; |
584 | 605 |
} |
585 | 606 |
|
586 |
-sub description { |
|
587 |
- my ($self, $user, $project, $description) = @_; |
|
588 |
- |
|
589 |
- my $rep = $self->rep($user, $project); |
|
590 |
- my $file = "$rep/description"; |
|
591 |
- |
|
592 |
- if (defined $description) { |
|
593 |
- # Write description |
|
594 |
- open my $fh, '>',$file |
|
595 |
- or croak "Can't open file $rep: $!"; |
|
596 |
- print $fh encode('UTF-8', $description) |
|
597 |
- or croak "Can't write description: $!"; |
|
598 |
- close $fh; |
|
599 |
- } |
|
600 |
- else { |
|
601 |
- # Read description |
|
602 |
- my $description = $self->_slurp($file) || ''; |
|
603 |
- return $description; |
|
604 |
- } |
|
605 |
-} |
|
606 |
- |
|
607 | 607 |
sub last_activity { |
608 | 608 |
my ($self, $user, $project) = @_; |
609 | 609 |
|
... | ... |
@@ -735,6 +735,26 @@ sub references { |
735 | 735 |
return \%refs; |
736 | 736 |
} |
737 | 737 |
|
738 |
+sub rename_project { |
|
739 |
+ my ($self, $user, $project, $renamed_project) = @_; |
|
740 |
+ |
|
741 |
+ croak "Invalid user name or project" |
|
742 |
+ unless defined $user && defined $project && defined $renamed_project; |
|
743 |
+ my $rep = $self->rep($user, $project); |
|
744 |
+ my $renamed_rep = $self->rep($user, $renamed_project); |
|
745 |
+ |
|
746 |
+ move($rep, $renamed_rep) |
|
747 |
+ or croak "Can't move $rep to $renamed_rep: $!"; |
|
748 |
+} |
|
749 |
+ |
|
750 |
+sub exists_project { |
|
751 |
+ my ($self, $user, $project) = @_; |
|
752 |
+ |
|
753 |
+ my $rep = $self->rep($user, $project); |
|
754 |
+ |
|
755 |
+ return -e $rep; |
|
756 |
+} |
|
757 |
+ |
|
738 | 758 |
sub rep { |
739 | 759 |
my ($self, $user, $project) = @_; |
740 | 760 |
|
... | ... |
@@ -0,0 +1,36 @@ |
1 |
+package Gitprep::RepManager; |
|
2 |
+use Mojo::Base -base; |
|
3 |
+ |
|
4 |
+has 'c'; |
|
5 |
+ |
|
6 |
+sub rename_project { |
|
7 |
+ my ($self, $user, $project, $renamed_project) = @_; |
|
8 |
+ |
|
9 |
+ my $c = $self->c; |
|
10 |
+ my $api = $c->gitprep_api($c); |
|
11 |
+ my $git = $c->app->git; |
|
12 |
+ my $dbi = $c->app->dbi; |
|
13 |
+ |
|
14 |
+ my $error = {}; |
|
15 |
+ |
|
16 |
+ if ($api->exists_project($user, $renamed_project) |
|
17 |
+ || $git->exists_project($user, $renamed_project)) |
|
18 |
+ { |
|
19 |
+ $error->{message} = 'Already exists'; |
|
20 |
+ return $error; |
|
21 |
+ } |
|
22 |
+ else { |
|
23 |
+ $dbi->connector->txn(sub { |
|
24 |
+ $api->rename_project($user, $project, $renamed_project); |
|
25 |
+ $git->rename_project($user, $project, $renamed_project); |
|
26 |
+ }); |
|
27 |
+ if ($@) { |
|
28 |
+ $error->{message} = 'Rename failed'; |
|
29 |
+ return $error; |
|
30 |
+ } |
|
31 |
+ } |
|
32 |
+ |
|
33 |
+ return 1; |
|
34 |
+} |
|
35 |
+ |
|
36 |
+1; |
... | ... |
@@ -1,4 +1,6 @@ |
1 | 1 |
<% |
2 |
+ use Gitprep::RepManager; |
|
3 |
+ |
|
2 | 4 |
my $api = gitprep_api; |
3 | 5 |
my $logined = $api->logined; |
4 | 6 |
my $user_is_valid = $logined && $user eq session('user_id'); |
... | ... |
@@ -9,7 +11,46 @@ |
9 | 11 |
|
10 | 12 |
$api->croak("Fobbiden") if !$user_is_valid; |
11 | 13 |
|
12 |
- if ($op eq 'change_description') { |
|
14 |
+ if ($op eq 'rename-project') { |
|
15 |
+ |
|
16 |
+ # Validation |
|
17 |
+ my $params = $api->params; |
|
18 |
+ my $rule = [ |
|
19 |
+ user => [ |
|
20 |
+ 'user_name' |
|
21 |
+ ], |
|
22 |
+ project => [ |
|
23 |
+ 'project_name' |
|
24 |
+ ], |
|
25 |
+ 'renamed-project' => [ |
|
26 |
+ 'project_name' |
|
27 |
+ ] |
|
28 |
+ ]; |
|
29 |
+ my $vresult = app->validator->validate($params, $rule); |
|
30 |
+ |
|
31 |
+ if ($vresult->is_ok) { |
|
32 |
+ # Valida parameters |
|
33 |
+ my $data = $vresult->data; |
|
34 |
+ my $user = $data->{user}; |
|
35 |
+ my $project = $data->{project}; |
|
36 |
+ my $renamed_project = $data->{'renamed-project'}; |
|
37 |
+ |
|
38 |
+ # Rename |
|
39 |
+ my $manager = Gitprep::RepManager->new(c => $self); |
|
40 |
+ my $error = $manager->rename_project($user, $project, $renamed_project); |
|
41 |
+ if (ref $error) { |
|
42 |
+ $self->render(json => {ok => 0, message => $error->{message}}); |
|
43 |
+ } |
|
44 |
+ else { |
|
45 |
+ $self->render(json => {ok => 1}); |
|
46 |
+ } |
|
47 |
+ return $self->res->body; |
|
48 |
+ } |
|
49 |
+ else { |
|
50 |
+ $self->render(json => {ok => 0, message => 'Invalid Parameters'}); |
|
51 |
+ } |
|
52 |
+ } |
|
53 |
+ elsif ($op eq 'change_description') { |
|
13 | 54 |
my $description = param('description'); |
14 | 55 |
$description = '' unless defined $description; |
15 | 56 |
|
... | ... |
@@ -60,6 +101,28 @@ |
60 | 101 |
|
61 | 102 |
$(document).ready(function () { |
62 | 103 |
|
104 |
+ // Rename project name |
|
105 |
+ $('#rename').on('click', function () { |
|
106 |
+ var renamed_project = $('input[name="renamed-project"]').val(); |
|
107 |
+ |
|
108 |
+ var url = "<%= url_for %>"; |
|
109 |
+ var data = { |
|
110 |
+ op : "rename-project", |
|
111 |
+ user: "<%= $user %>", |
|
112 |
+ project: "<%= $project %>", |
|
113 |
+ 'renamed-project': renamed_project |
|
114 |
+ }; |
|
115 |
+ $.post(url, data, function (result) { |
|
116 |
+ if (result.ok) { |
|
117 |
+ location.href = "<%= url_for("/$user") %>" + '/' + renamed_project; |
|
118 |
+ } |
|
119 |
+ else { |
|
120 |
+ $('#modal-message').text('Rename failed:' + result.message); |
|
121 |
+ $('#success').modal('show'); |
|
122 |
+ } |
|
123 |
+ }); |
|
124 |
+ }); |
|
125 |
+ |
|
63 | 126 |
// Change description |
64 | 127 |
$('a[href="#description"]').on('click', function () { |
65 | 128 |
var description = $('input[name="description"]').val(); |
... | ... |
@@ -125,8 +188,10 @@ |
125 | 188 |
<div class="padding5 border-gray" style="border-top:none"> |
126 | 189 |
<div >Repository Name</div> |
127 | 190 |
<div> |
128 |
- %= text_field 'project' => $project, style => 'margin-top:9px'; |
|
129 |
- <a class="btn" href="#rename">Rename</a> |
|
191 |
+ %= text_field 'renamed-project' => $project, style => 'margin-top:9px'; |
|
192 |
+ <a href="#rename-confirm" role="button" class="btn" data-toggle="modal"> |
|
193 |
+ Rename |
|
194 |
+ </a> |
|
130 | 195 |
</div> |
131 | 196 |
</div> |
132 | 197 |
<div class="padding5 border-gray" style="border-top:none"> |
... | ... |
@@ -136,6 +201,10 @@ |
136 | 201 |
%= text_field 'description' => $description, class => 'span8', style => 'margin-top:9px'; |
137 | 202 |
<a class="btn" href="#description">Save</a> |
138 | 203 |
</div> |
204 |
+ <div id="description-success" class="alert alert-success" style="width:150px;display:none"> |
|
205 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
206 |
+ Savaed! |
|
207 |
+ </div> |
|
139 | 208 |
</div> |
140 | 209 |
<div class="border-gray padding5" style="border-top:none"> |
141 | 210 |
Default Branch |
... | ... |
@@ -168,7 +237,32 @@ |
168 | 237 |
<button class="btn" data-dismiss="modal" aria-hidden="true">OK</button> |
169 | 238 |
</div> |
170 | 239 |
</div> |
171 |
- |
|
240 |
+ |
|
241 |
+ <div id="rename-confirm" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="rename-confirm-label" aria-hidden="true"> |
|
242 |
+ <div class="modal-header"> |
|
243 |
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
|
244 |
+ <div id="modal-message" style="font-weight:bold">Are you sure you want to rename?</div> |
|
245 |
+ </div> |
|
246 |
+ <div class="modal-body"> |
|
247 |
+ <p> |
|
248 |
+ Unexpected bad things will happen if you don't read this |
|
249 |
+ </p> |
|
250 |
+ <ul> |
|
251 |
+ <li> |
|
252 |
+ We will not set up any redirects from the old location |
|
253 |
+ </li> |
|
254 |
+ <li> |
|
255 |
+ You will need to update your local repositories to point to the new location |
|
256 |
+ </li> |
|
257 |
+ </ul> |
|
258 |
+ </div> |
|
259 |
+ <div class="modal-footer"> |
|
260 |
+ <button id="rename" class="btn" data-dismiss="modal" aria-hidden="true"> |
|
261 |
+ I understand, rename this repository |
|
262 |
+ </button> |
|
263 |
+ </div> |
|
264 |
+ </div> |
|
265 |
+ |
|
172 | 266 |
<div id="delete-confirm" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="delete-confirm-label" aria-hidden="true"> |
173 | 267 |
<div class="modal-header"> |
174 | 268 |
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
... | ... |
@@ -194,4 +288,5 @@ |
194 | 288 |
</div> |
195 | 289 |
</div> |
196 | 290 |
|
291 |
+ |
|
197 | 292 |
%= include '/include/footer'; |