Show More
@@ -2,71 +2,71 b' import os' | |||||
2 |
|
2 | |||
3 |
|
3 | |||
4 | class LockFile(object): |
|
4 | class LockFile(object): | |
5 |
|
|
5 | """Provides methods to obtain, check for, and release a file based lock which | |
6 |
|
|
6 | should be used to handle concurrent access to the same file. | |
7 |
|
7 | |||
8 |
|
|
8 | As we are a utility class to be derived from, we only use protected methods. | |
9 |
|
9 | |||
10 |
|
|
10 | Locks will automatically be released on destruction""" | |
11 |
|
|
11 | __slots__ = ("_file_path", "_owns_lock") | |
12 |
|
12 | |||
13 |
|
|
13 | def __init__(self, file_path): | |
14 |
|
|
14 | self._file_path = file_path | |
15 |
|
|
15 | self._owns_lock = False | |
16 |
|
16 | |||
17 |
|
|
17 | def __del__(self): | |
18 |
|
|
18 | self._release_lock() | |
19 |
|
19 | |||
20 |
|
|
20 | def _lock_file_path(self): | |
21 |
|
|
21 | """:return: Path to lockfile""" | |
22 |
|
|
22 | return "%s.lock" % (self._file_path) | |
23 |
|
23 | |||
24 |
|
|
24 | def _has_lock(self): | |
25 |
|
|
25 | """:return: True if we have a lock and if the lockfile still exists | |
26 |
|
|
26 | :raise AssertionError: if our lock-file does not exist""" | |
27 |
|
|
27 | if not self._owns_lock: | |
28 |
|
|
28 | return False | |
29 |
|
29 | |||
30 |
|
|
30 | return True | |
31 |
|
31 | |||
32 |
|
|
32 | def _obtain_lock_or_raise(self): | |
33 |
|
|
33 | """Create a lock file as flag for other instances, mark our instance as lock-holder | |
34 |
|
34 | |||
35 |
|
|
35 | :raise IOError: if a lock was already present or a lock file could not be written""" | |
36 |
|
|
36 | if self._has_lock(): | |
37 | return |
|
37 | return | |
38 |
|
|
38 | lock_file = self._lock_file_path() | |
39 |
|
|
39 | if os.path.isfile(lock_file): | |
40 |
|
|
40 | raise IOError("Lock for file %r did already exist, delete %r in case the lock is illegal" % (self._file_path, lock_file)) | |
41 |
|
41 | |||
42 | try: |
|
42 | try: | |
43 |
|
|
43 | fd = os.open(lock_file, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0) | |
44 |
|
|
44 | os.close(fd) | |
45 |
|
|
45 | except OSError,e: | |
46 |
|
|
46 | raise IOError(str(e)) | |
47 |
|
47 | |||
48 |
|
|
48 | self._owns_lock = True | |
49 |
|
49 | |||
50 |
|
|
50 | def _obtain_lock(self): | |
51 |
|
|
51 | """The default implementation will raise if a lock cannot be obtained. | |
52 |
|
|
52 | Subclasses may override this method to provide a different implementation""" | |
53 |
|
|
53 | return self._obtain_lock_or_raise() | |
54 |
|
54 | |||
55 |
|
|
55 | def _release_lock(self): | |
56 |
|
|
56 | """Release our lock if we have one""" | |
57 |
|
|
57 | if not self._has_lock(): | |
58 | return |
|
58 | return | |
59 |
|
59 | |||
60 |
|
|
60 | # if someone removed our file beforhand, lets just flag this issue | |
61 |
|
|
61 | # instead of failing, to make it more usable. | |
62 |
|
|
62 | lfp = self._lock_file_path() | |
63 | try: |
|
63 | try: | |
64 |
|
|
64 | # on bloody windows, the file needs write permissions to be removable. | |
65 | # Why ... |
|
65 | # Why ... | |
66 |
|
|
66 | if os.name == 'nt': | |
67 |
|
|
67 | os.chmod(lfp, 0777) | |
68 |
|
|
68 | # END handle win32 | |
69 |
|
|
69 | os.remove(lfp) | |
70 |
|
|
70 | except OSError: | |
71 | pass |
|
71 | pass | |
72 |
|
|
72 | self._owns_lock = False |
@@ -312,7 +312,7 b' div:hover > a.permalink {' | |||||
312 | } |
|
312 | } | |
313 |
|
313 | |||
314 | #header-dd:hover{ |
|
314 | #header-dd:hover{ | |
315 |
|
|
315 | opacity: 0.2; | |
316 | -webkit-transition: opacity 0.5s ease-in-out; |
|
316 | -webkit-transition: opacity 0.5s ease-in-out; | |
317 | -moz-transition: opacity 0.5s ease-in-out; |
|
317 | -moz-transition: opacity 0.5s ease-in-out; | |
318 | transition: opacity 0.5s ease-in-out; |
|
318 | transition: opacity 0.5s ease-in-out; | |
@@ -4598,21 +4598,21 b' PULL REQUESTS' | |||||
4598 | DIFFS CSS |
|
4598 | DIFFS CSS | |
4599 | ******************************************************************************/ |
|
4599 | ******************************************************************************/ | |
4600 | .diff-collapse{ |
|
4600 | .diff-collapse{ | |
4601 |
|
|
4601 | text-align: center; | |
4602 |
|
|
4602 | margin-bottom: -15px; | |
4603 | } |
|
4603 | } | |
4604 | .diff-collapse-button{ |
|
4604 | .diff-collapse-button{ | |
4605 |
|
|
4605 | cursor: pointer; | |
4606 |
|
|
4606 | color: #666; | |
4607 |
|
|
4607 | font-size: 16px; | |
4608 | } |
|
4608 | } | |
4609 | .diff-container { |
|
4609 | .diff-container { | |
4610 |
|
4610 | |||
4611 | } |
|
4611 | } | |
4612 |
|
4612 | |||
4613 | .diff-container.hidden{ |
|
4613 | .diff-container.hidden{ | |
4614 |
|
|
4614 | display: none; | |
4615 |
|
|
4615 | overflow: hidden; | |
4616 | } |
|
4616 | } | |
4617 |
|
4617 | |||
4618 |
|
4618 |
@@ -148,7 +148,7 b' var show_pullrequests = function(e){' | |||||
148 |
|
148 | |||
149 | var url = pyroutes.url('admin_settings_my_pullrequests'); |
|
149 | var url = pyroutes.url('admin_settings_my_pullrequests'); | |
150 | if(YUD.get('show_closed') && YUD.get('show_closed').checked) { |
|
150 | if(YUD.get('show_closed') && YUD.get('show_closed').checked) { | |
151 |
|
|
151 | var url = pyroutes.url('admin_settings_my_pullrequests', {'pr_show_closed': '1'}); | |
152 | } |
|
152 | } | |
153 | ypjax(url, 'pullrequests_container', function(){ |
|
153 | ypjax(url, 'pullrequests_container', function(){ | |
154 | YUE.on('show_closed','change',function (e) { |
|
154 | YUE.on('show_closed','change',function (e) { |
@@ -174,8 +174,8 b'' | |||||
174 | rev_start+'...'+rev_end); |
|
174 | rev_start+'...'+rev_end); | |
175 |
|
175 | |||
176 | var link = (rev_start == rev_end) |
|
176 | var link = (rev_start == rev_end) | |
177 |
|
|
177 | ? _TM['Show selected change __S'] | |
178 |
|
|
178 | : _TM['Show selected changes __S -> __E']; | |
179 |
|
179 | |||
180 | link = link.replace('__S',rev_start.substr(0,6)); |
|
180 | link = link.replace('__S',rev_start.substr(0,6)); | |
181 | link = link.replace('__E',rev_end.substr(0,6)); |
|
181 | link = link.replace('__E',rev_end.substr(0,6)); |
@@ -9,10 +9,10 b'' | |||||
9 | <div>${_('View this comment here')}: ${pr_comment_url}</div> |
|
9 | <div>${_('View this comment here')}: ${pr_comment_url}</div> | |
10 |
|
10 | |||
11 | %if status_change: |
|
11 | %if status_change: | |
12 |
|
|
12 | %if closing_pr: | |
13 |
|
|
13 | <span>${_('Closing pull request with status')} -> ${status_change}</span> | |
14 |
|
|
14 | %else: | |
15 |
|
|
15 | <span>${_('New status')} -> ${status_change}</span> | |
16 |
|
|
16 | %endif | |
17 | %endif |
|
17 | %endif | |
18 | </p> |
|
18 | </p> |
@@ -155,7 +155,7 b'' | |||||
155 | }; // gather the org/other ref and repo here |
|
155 | }; // gather the org/other ref and repo here | |
156 |
|
156 | |||
157 | for (k in rev_data){ |
|
157 | for (k in rev_data){ | |
158 |
|
|
158 | url = url.replace('__'+k+'__',rev_data[k]); | |
159 | } |
|
159 | } | |
160 |
|
160 | |||
161 | YUD.get('pull_request_overview').innerHTML = "${_('Loading ...')}"; |
|
161 | YUD.get('pull_request_overview').innerHTML = "${_('Loading ...')}"; | |
@@ -172,8 +172,8 b'' | |||||
172 | // reset && add the reviewer based on selected repo |
|
172 | // reset && add the reviewer based on selected repo | |
173 | YUD.get('review_members').innerHTML = ''; |
|
173 | YUD.get('review_members').innerHTML = ''; | |
174 | addReviewMember(_data.user.user_id, _data.user.firstname, |
|
174 | addReviewMember(_data.user.user_id, _data.user.firstname, | |
175 |
|
|
175 | _data.user.lastname, _data.user.username, | |
176 |
|
|
176 | _data.user.gravatar_link); | |
177 | }) |
|
177 | }) | |
178 | } |
|
178 | } | |
179 |
|
179 |
General Comments 0
You need to be logged in to leave comments.
Login now