Pypaste / friendpaste / utils /

The default branch has multiple heads

# -*- coding: utf-8 -
# Copyright 2008 by Benoît Chesneau <>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.

import binascii
from calendar import timegm
from datetime import datetime, timedelta, time, tzinfo
from time import strptime, localtime, struct_time
from gettext import gettext, ngettext
import os
import socket
import sys
from glob import glob

# compatibility with python 2.4
    from hashlib import sha1 as _sha
except ImportError:
    import sha
    _sha =

from werkzeug import Local, LocalManager
from friendpaste import settings

from friendpaste.utils import stomp

_hex = binascii.hexlify
local = Local()
local_manager = LocalManager([local])

_install_hooks = []

def install_hook(f):
    return f

def install():
    global _install_hooks
    print "Setup"
    for a in _install_hooks:
        sys.stderr.write("do %s\n" % a.__name__)

def create_db():
    """create the db if it don't exist"""
    from couchdb.client import Server
    couchdb_server = Server(settings.SERVER_URI)
        db = couchdb_server.create(settings.DATABASE_NAME)
def load_file(fname):
    f = file(fname, 'r')
    data =
    return data
def load_views():
    from couchdb.client import Server
    couchdb_server = Server(settings.SERVER_URI)
    db = couchdb_server[settings.DATABASE_NAME]
    design_path = os.path.join(os.path.dirname(__file__), '../_design')
    print "\nLoad CouchDB views ..."
    for name in os.listdir(design_path):
        path = os.path.join(design_path,name)
        views = {}
        for view in os.listdir(path):
            views[view] = {}
            for js in glob(os.path.join(path, view, '*.js')):
                if os.path.basename(js) == 'map.js':
                    views[view]['map'] = load_file(js)
                if os.path.basename(js) == 'reduce.js':
                    views[view]['reduce'] = load_file(js)
            print "add %s/%s" % (name, view)
            db['_design/%s' % name] = {
                'language': 'javascript',
                'views': views
            v = db['_design/%s' % name] 
            v['views'] = views
            db['_design/%s' % name] = v

def ungettext(singular, plural, number):
    """ stupid wrapper yet waiting internationalisation """
    return ngettext(singular, plural, number)

def ugettext(message):
    """ stupid wrapper yet waiting internationalisation """
    return gettext(message)

def timesince(d, now=None):
    chunks = (
      (60 * 60 * 24, lambda n : ungettext('day', 'days', n)),
      (60 * 60, lambda n: ungettext('hour', 'hours', n)),
      (60, lambda n: ungettext('minute', 'minutes', n))
    tz = None
    if d.__class__ is not datetime:
        type= d.__class__
        d = datetime(d.year, d.month,
    if now:
        t = now.timetuple()
        t = localtime()
    # get timezone
    if d.tzinfo:
        tt = (d.year, d.month,, d.hour, d.minute, d.second, d.weekday(), 0, -1)
            stamp = time.mktime(tt)
        except OverflowError:
            # 32 bit systems can't handle dates after Jan 2038, so we fake it
            # in that case (since we only care about the DST flag here).
            tt = (2037,) + tt[1:]
            stamp = time.mktime(tt)
        if tt.tm_isdst > 0:
            tz = utf8(time.tzname[tt])
    now = datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz).utcnow()
    delta = now - (d - timedelta(0, 0, d.microsecond))
    since = delta.days * 24 * 60 * 60 + delta.seconds
    if since <= 0:
        # d is in the future compared to now, stop processing.
        return u'0 ' + ugettext('minutes ago')
    if since <= 604800:
        for i, (seconds, name) in enumerate(chunks):
            count = since // seconds
            if count != 0:
        s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
        if i + 1 < len(chunks):
            # Now get the second item
            seconds2, name2 = chunks[i + 1]
            count2 = (since - (seconds * count)) // seconds2
            if count2 != 0:
                s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
        return s + ugettext(' ago')
    return d.strftime ("%b %d, %Y")

def utf8(text):
    """Encodes text in utf-8.
        >> utf8(u'\u1234') # doctest doesn't seem to like utf-8

        >>> utf8('hello')
        >>> utf8(42)
    if isinstance(text, unicode):
        return text.encode('utf-8')
    elif isinstance(text, str):
        return text
        return str(text)

def to_str(s):
    return a bytestring version of s, encoded in utf8

    if not isinstance(s, basestring):
            return str(s)
        except UnicodeEncodeError:
            return unicode(s).encode('utf-8', 'strict')
    elif isinstance(s, unicode):
        return s.encode('utf-8', 'strict')
        return s

def iri_to_uri(iri):
    Convert an Internationalized Resource Identifier (IRI) portion to a URI
    portion that is suitable for inclusion in a URL.

    Returns an ASCII string containing the encoded result.
    code from djangoprohect.
    # The list of safe characters here is constructed from the printable ASCII
    # characters that are not explicitly excluded by the list at the end of
    # section 3.1 of RFC 3987.
    if iri is None:
        return iri

    return urllib.quote(to_str(iri), safe='/#%[]=:;$&()+,!?*')

def datetimestr_topython(value):
    if isinstance(value, basestring):
            value = value.split('.', 1)[0] # strip out microseconds
            value = value.rstrip('Z') # remove timezone separator
            timestamp = timegm(strptime(value, '%Y-%m-%dT%H:%M:%S'))
            value = datetime.utcfromtimestamp(timestamp)
        except ValueError, e:
            raise ValueError('Invalid ISO date/time %r' % value)
    return value

def datetime_tojson(value):
    if isinstance(value, struct_time):
        value = datetime.utcfromtimestamp(timegm(value))
    elif not isinstance(value, datetime):
        value = datetime.combine(value, time(0))
    return value.replace(microsecond=0).isoformat() + 'Z'

def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
    Similar to smart_unicode, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    if strings_only and isinstance(s, (types.NoneType, int, long, datetime.datetime,, datetime.time, float)):
        return s
        if not isinstance(s, basestring,):
            if hasattr(s, '__unicode__'):
                s = unicode(s)
                    s = unicode(str(s), encoding, errors)
                except UnicodeEncodeError:
                    if not isinstance(s, Exception):
                    # If we get to here, the caller has passed in an Exception
                    # subclass populated with non-ASCII data without special
                    # handling to display as a string. We need to handle this
                    # without raising a further exception. We do an
                    # approximation to what the Exception's standard str()
                    # output should be.
                    s = ' '.join([force_unicode(arg, encoding, strings_only,
                            errors) for arg in s])
        elif not isinstance(s, unicode):
            # Note: We use .decode() here, instead of unicode(s, encoding,
            # errors), so that if s is a SafeString, it ends up being a
            # SafeUnicode at the end.
            s = s.decode(encoding, errors)
    except UnicodeDecodeError, e:
        raise CouchitUnicodeDecodeError(s, *e.args)
    return s
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
    Returns a bytestring version of 's', encoded as specified in 'encoding'.

    If strings_only is True, don't convert (some) non-string-like objects.
    if strings_only and isinstance(s, (types.NoneType, int)):
        return s
    if not isinstance(s, basestring):
            return str(s)
        except UnicodeEncodeError:
            if isinstance(s, Exception):
                # An Exception subclass containing non-ASCII data that doesn't
                # know how to print itself properly. We shouldn't raise a
                # further exception.
                return ' '.join([smart_str(arg, encoding, strings_only,
                        errors) for arg in s])
            return unicode(s).encode(encoding, errors)
    elif isinstance(s, unicode):
        return s.encode(encoding, errors)
    elif s and encoding != 'utf-8':
        return s.decode('utf-8', errors).encode(encoding, errors)
        return s

def make_hash(*args):
    if len(args) <= 0:
        return None
    s = _sha()
    for arg in args:

    return _hex(s.digest())
def short(node):
    return _hex(node[:6])

def send_stomp_msg(message, destination):
    connected = False
    while not connected:
            conn = stomp.Connection()
            conn.send(' ' + message, destination=destination)
            connected = True
        except socket.error: