##// END OF EJS Templates
Migrate to Mergely 3.3.4....
Migrate to Mergely 3.3.4. RhodeCode 2.2.5 distributed Mergely 3.3.4 with some of the changes that Mergely 3.3.3 in RhodeCode 1.7.2 also had. That do however not seem to be changes we want for Kallithea this way and we take the 3.3.4 files as they are. I've also included the Mergely license file, as downloaded from: http://www.mergely.com/license.php That LICENSE file is kept in HTML just as it was downloaded from their website. While it's a bit annoying to keep the license file in HTML, this is the way it came from upstream so we'll leave it that way. Since the Javascript code is used with other GPLv3 Javascript, we are using the GPL option of Mergely's tri-license. Finally, note that previously, this was incorrectly called "mergerly", so the opportunity is taken here to correct the name. That required changes to diff_2way.html. As commands:: $ wget -N --output-document LICENSE-MERGELY.html http://www.mergely.com/license.php $ hg add LICENSE-MERGELY.html $ hg mv rhodecode/public/css/mergerly.css rhodecode/public/css/mergely.css $ hg mv rhodecode/public/js/mergerly.js rhodecode/public/js/mergely.js $ sed -i 's,mergerly\.,mergely,g' rhodecode/templates/files/diff_2way.html $ ( cd /tmp; \ wget -N http://www.mergely.com/releases/mergely-3.3.4.zip; \ unzip mergely-3.3.4.zip ) $ sha256sum /tmp/mergely-3.3.4.zip 87415d30494bbe829c248881aa7cdc0303f7e70b458a5f687615564d4498cc82 mergely-3.3.4.zip $ cp /tmp/mergely-3.3.4/lib/mergely.js rhodecode/public/js/mergely.js $ cp /tmp/mergely-3.3.4/lib/mergely.css rhodecode/public/css/mergely.css $ sed -i -e '/^ \* Version/a\ *\n * NOTE by bkuhn@sfconservancy.org for Kallithea:\n * Mergely license appears at http://www.mergely.com/license.php and in LICENSE-MERGELY.html' rhodecode/public/js/mergely.js rhodecode/public/css/mergely.css

File last commit:

r3797:d7488551 beta
r4125:aa3b5594 rhodecode-2.2.5-gpl
Show More
compat.py
318 lines | 9.9 KiB | text/x-python | PythonLexer
"""
Various utilities to work with Python < 2.7.
Those utilities may be deleted once ``vcs`` stops support for older Python
versions.
"""
import sys
import array
if sys.version_info >= (2, 7):
unittest = __import__('unittest')
else:
unittest = __import__('unittest2')
if sys.version_info >= (2, 6):
_bytes = bytes
else:
# in py2.6 bytes is a synonim for str
_bytes = str
if sys.version_info >= (2, 6):
_bytearray = bytearray
else:
# no idea if this is correct but all integration tests are passing
# i think we never use bytearray anyway
_bytearray = array
if sys.version_info >= (2, 6):
from collections import deque
else:
#need to implement our own deque with maxlen
class deque(object):
def __init__(self, iterable=(), maxlen= -1):
if not hasattr(self, 'data'):
self.left = self.right = 0
self.data = {}
self.maxlen = maxlen or -1
self.extend(iterable)
def append(self, x):
self.data[self.right] = x
self.right += 1
if self.maxlen != -1 and len(self) > self.maxlen:
self.popleft()
def appendleft(self, x):
self.left -= 1
self.data[self.left] = x
if self.maxlen != -1 and len(self) > self.maxlen:
self.pop()
def pop(self):
if self.left == self.right:
raise IndexError('cannot pop from empty deque')
self.right -= 1
elem = self.data[self.right]
del self.data[self.right]
return elem
def popleft(self):
if self.left == self.right:
raise IndexError('cannot pop from empty deque')
elem = self.data[self.left]
del self.data[self.left]
self.left += 1
return elem
def clear(self):
self.data.clear()
self.left = self.right = 0
def extend(self, iterable):
for elem in iterable:
self.append(elem)
def extendleft(self, iterable):
for elem in iterable:
self.appendleft(elem)
def rotate(self, n=1):
if self:
n %= len(self)
for i in xrange(n):
self.appendleft(self.pop())
def __getitem__(self, i):
if i < 0:
i += len(self)
try:
return self.data[i + self.left]
except KeyError:
raise IndexError
def __setitem__(self, i, value):
if i < 0:
i += len(self)
try:
self.data[i + self.left] = value
except KeyError:
raise IndexError
def __delitem__(self, i):
size = len(self)
if not (-size <= i < size):
raise IndexError
data = self.data
if i < 0:
i += size
for j in xrange(self.left + i, self.right - 1):
data[j] = data[j + 1]
self.pop()
def __len__(self):
return self.right - self.left
def __cmp__(self, other):
if type(self) != type(other):
return cmp(type(self), type(other))
return cmp(list(self), list(other))
def __repr__(self, _track=[]):
if id(self) in _track:
return '...'
_track.append(id(self))
r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
_track.remove(id(self))
return r
def __getstate__(self):
return (tuple(self),)
def __setstate__(self, s):
self.__init__(s[0])
def __hash__(self):
raise TypeError
def __copy__(self):
return self.__class__(self)
def __deepcopy__(self, memo={}):
from copy import deepcopy
result = self.__class__()
memo[id(self)] = result
result.__init__(deepcopy(tuple(self), memo))
return result
#==============================================================================
# threading.Event
#==============================================================================
if sys.version_info >= (2, 6):
from threading import Event, Thread
else:
from threading import _Verbose, Lock, Thread, _time, \
_allocate_lock, RLock, _sleep
def Condition(*args, **kwargs):
return _Condition(*args, **kwargs)
class _Condition(_Verbose):
def __init__(self, lock=None, verbose=None):
_Verbose.__init__(self, verbose)
if lock is None:
lock = RLock()
self.__lock = lock
# Export the lock's acquire() and release() methods
self.acquire = lock.acquire
self.release = lock.release
# If the lock defines _release_save() and/or _acquire_restore(),
# these override the default implementations (which just call
# release() and acquire() on the lock). Ditto for _is_owned().
try:
self._release_save = lock._release_save
except AttributeError:
pass
try:
self._acquire_restore = lock._acquire_restore
except AttributeError:
pass
try:
self._is_owned = lock._is_owned
except AttributeError:
pass
self.__waiters = []
def __enter__(self):
return self.__lock.__enter__()
def __exit__(self, *args):
return self.__lock.__exit__(*args)
def __repr__(self):
return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
def _release_save(self):
self.__lock.release() # No state to save
def _acquire_restore(self, x):
self.__lock.acquire() # Ignore saved state
def _is_owned(self):
# Return True if lock is owned by current_thread.
# This method is called only if __lock doesn't have _is_owned().
if self.__lock.acquire(0):
self.__lock.release()
return False
else:
return True
def wait(self, timeout=None):
if not self._is_owned():
raise RuntimeError("cannot wait on un-acquired lock")
waiter = _allocate_lock()
waiter.acquire()
self.__waiters.append(waiter)
saved_state = self._release_save()
try: # restore state no matter what (e.g., KeyboardInterrupt)
if timeout is None:
waiter.acquire()
if __debug__:
self._note("%s.wait(): got it", self)
else:
# Balancing act: We can't afford a pure busy loop, so we
# have to sleep; but if we sleep the whole timeout time,
# we'll be unresponsive. The scheme here sleeps very
# little at first, longer as time goes on, but never longer
# than 20 times per second (or the timeout time remaining).
endtime = _time() + timeout
delay = 0.0005 # 500 us -> initial delay of 1 ms
while True:
gotit = waiter.acquire(0)
if gotit:
break
remaining = endtime - _time()
if remaining <= 0:
break
delay = min(delay * 2, remaining, .05)
_sleep(delay)
if not gotit:
if __debug__:
self._note("%s.wait(%s): timed out", self, timeout)
try:
self.__waiters.remove(waiter)
except ValueError:
pass
else:
if __debug__:
self._note("%s.wait(%s): got it", self, timeout)
finally:
self._acquire_restore(saved_state)
def notify(self, n=1):
if not self._is_owned():
raise RuntimeError("cannot notify on un-acquired lock")
__waiters = self.__waiters
waiters = __waiters[:n]
if not waiters:
if __debug__:
self._note("%s.notify(): no waiters", self)
return
self._note("%s.notify(): notifying %d waiter%s", self, n,
n != 1 and "s" or "")
for waiter in waiters:
waiter.release()
try:
__waiters.remove(waiter)
except ValueError:
pass
def notifyAll(self):
self.notify(len(self.__waiters))
notify_all = notifyAll
def Event(*args, **kwargs):
return _Event(*args, **kwargs)
class _Event(_Verbose):
# After Tim Peters' event class (without is_posted())
def __init__(self, verbose=None):
_Verbose.__init__(self, verbose)
self.__cond = Condition(Lock())
self.__flag = False
def isSet(self):
return self.__flag
is_set = isSet
def set(self):
self.__cond.acquire()
try:
self.__flag = True
self.__cond.notify_all()
finally:
self.__cond.release()
def clear(self):
self.__cond.acquire()
try:
self.__flag = False
finally:
self.__cond.release()
def wait(self, timeout=None):
self.__cond.acquire()
try:
if not self.__flag:
self.__cond.wait(timeout)
finally:
self.__cond.release()