Changeset beb3922 in osmose-frontend


Ignore:
Timestamp:
Oct 12, 2014 8:35:44 PM (5 years ago)
Author:
Jocelyn Jaubert <jocelyn.jaubert@…>
Children:
e754cfd
Parents:
bac5e95 (diff), bbaed7d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'bottle-0.12'

Files:
32 edited

Legend:

Unmodified
Added
Removed
  • bottle.py

    r51fc529 rbeced85  
    1010Homepage and documentation: http://bottlepy.org/ 
    1111 
    12 Copyright (c) 2012, Marcel Hellkamp. 
     12Copyright (c) 2013, Marcel Hellkamp. 
    1313License: MIT (see LICENSE for details) 
    1414""" 
     
    1717 
    1818__author__ = 'Marcel Hellkamp' 
    19 __version__ = '0.11.5' 
     19__version__ = '0.12.7' 
    2020__license__ = 'MIT' 
    2121 
     
    3737 
    3838import base64, cgi, email.utils, functools, hmac, imp, itertools, mimetypes,\ 
    39         os, re, subprocess, sys, tempfile, threading, time, urllib, warnings 
     39        os, re, subprocess, sys, tempfile, threading, time, warnings 
    4040 
    4141from datetime import date as datedate, datetime, timedelta 
    4242from tempfile import TemporaryFile 
    4343from traceback import format_exc, print_exc 
    44  
    45 try: from json import dumps as json_dumps, loads as json_lds 
     44from inspect import getargspec 
     45from unicodedata import normalize 
     46 
     47 
     48try: from simplejson import dumps as json_dumps, loads as json_lds 
    4649except ImportError: # pragma: no cover 
    47     try: from simplejson import dumps as json_dumps, loads as json_lds 
     50    try: from json import dumps as json_dumps, loads as json_lds 
    4851    except ImportError: 
    4952        try: from django.utils.simplejson import dumps as json_dumps, loads as json_lds 
     
    5962 
    6063py   = sys.version_info 
    61 py3k = py >= (3,0,0) 
    62 py25 = py <  (2,6,0) 
    63 py31 = (3,1,0) <= py < (3,2,0) 
     64py3k = py >= (3, 0, 0) 
     65py25 = py <  (2, 6, 0) 
     66py31 = (3, 1, 0) <= py < (3, 2, 0) 
    6467 
    6568# Workaround for the missing "as" keyword in py3k. 
     
    8588    import pickle 
    8689    from io import BytesIO 
     90    from configparser import ConfigParser 
    8791    basestring = str 
    8892    unicode = str 
     
    9094    callable = lambda x: hasattr(x, '__call__') 
    9195    imap = map 
     96    def _raise(*a): raise a[0](a[1]).with_traceback(a[2]) 
    9297else: # 2.x 
    9398    import httplib 
     
    99104    import cPickle as pickle 
    100105    from StringIO import StringIO as BytesIO 
     106    from ConfigParser import SafeConfigParser as ConfigParser 
    101107    if py25: 
    102         msg = "Python 2.5 support may be dropped in future versions of Bottle." 
     108        msg  = "Python 2.5 support may be dropped in future versions of Bottle." 
    103109        warnings.warn(msg, DeprecationWarning) 
    104110        from UserDict import DictMixin 
     
    107113    else: # 2.6, 2.7 
    108114        from collections import MutableMapping as DictMixin 
     115    unicode = unicode 
    109116    json_loads = json_lds 
     117    eval(compile('def _raise(*a): raise a[0], a[1], a[2]', '<py3fix>', 'exec')) 
    110118 
    111119# Some helpers for string/byte handling 
     
    123131        def close(self): pass # Keep wrapped buffer open. 
    124132 
    125 # File uploads (which are implemented as empty FiledStorage instances...) 
    126 # have a negative truth value. That makes no sense, here is a fix. 
    127 class FieldStorage(cgi.FieldStorage): 
    128     def __nonzero__(self): return bool(self.list or self.file) 
    129     if py3k: __bool__ = __nonzero__ 
    130133 
    131134# A bug in functools causes it to break if the wrapper is an instance method 
     
    139142# And yes, I know PEP-8, but sometimes a lower-case classname makes more sense. 
    140143 
    141 def depr(message): 
     144def depr(message, hard=False): 
    142145    warnings.warn(message, DeprecationWarning, stacklevel=3) 
    143146 
     
    179182 
    180183    def __init__(self, func): 
     184        self.__doc__ = getattr(func, '__doc__') 
    181185        self.func = func 
    182186 
     
    234238 
    235239class RouteSyntaxError(RouteError): 
    236     """ The route parser found something not supported by this router """ 
     240    """ The route parser found something not supported by this router. """ 
    237241 
    238242 
    239243class RouteBuildError(RouteError): 
    240     """ The route could not been built """ 
     244    """ The route could not be built. """ 
     245 
     246 
     247def _re_flatten(p): 
     248    ''' Turn all capturing groups in a regular expression pattern into 
     249        non-capturing groups. ''' 
     250    if '(' not in p: return p 
     251    return re.sub(r'(\\*)(\(\?P<[^>]+>|\((?!\?))', 
     252        lambda m: m.group(0) if len(m.group(1)) % 2 else m.group(1) + '(?:', p) 
    241253 
    242254 
     
    254266 
    255267    default_pattern = '[^/]+' 
    256     default_filter   = 're' 
    257     #: Sorry for the mess. It works. Trust me. 
    258     rule_syntax = re.compile('(\\\\*)'\ 
    259         '(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)'\ 
    260           '|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)'\ 
    261             '(?::((?:\\\\.|[^\\\\>]+)+)?)?)?>))') 
     268    default_filter  = 're' 
     269 
     270    #: The current CPython regexp implementation does not allow more 
     271    #: than 99 matching groups per regular expression. 
     272    _MAX_GROUPS_PER_PATTERN = 99 
    262273 
    263274    def __init__(self, strict=False): 
    264         self.rules    = {} # A {rule: Rule} mapping 
    265         self.builder  = {} # A rule/name->build_info mapping 
    266         self.static   = {} # Cache for static routes: {path: {method: target}} 
    267         self.dynamic  = [] # Cache for dynamic routes. See _compile() 
     275        self.rules    = [] # All rules in order 
     276        self._groups  = {} # index of regexes to find them in dyna_routes 
     277        self.builder  = {} # Data structure for the url builder 
     278        self.static   = {} # Search structure for static routes 
     279        self.dyna_routes   = {} 
     280        self.dyna_regexes  = {} # Search structure for dynamic routes 
    268281        #: If true, static routes are no longer checked first. 
    269282        self.strict_order = strict 
    270         self.filters = {'re': self.re_filter, 'int': self.int_filter, 
    271                         'float': self.float_filter, 'path': self.path_filter} 
    272  
    273     def re_filter(self, conf): 
    274         return conf or self.default_pattern, None, None 
    275  
    276     def int_filter(self, conf): 
    277         return r'-?\d+', int, lambda x: str(int(x)) 
    278  
    279     def float_filter(self, conf): 
    280         return r'-?[\d.]+', float, lambda x: str(float(x)) 
    281  
    282     def path_filter(self, conf): 
    283         return r'.+?', None, None 
     283        self.filters = { 
     284            're':    lambda conf: 
     285                (_re_flatten(conf or self.default_pattern), None, None), 
     286            'int':   lambda conf: (r'-?\d+', int, lambda x: str(int(x))), 
     287            'float': lambda conf: (r'-?[\d.]+', float, lambda x: str(float(x))), 
     288            'path':  lambda conf: (r'.+?', None, None)} 
    284289 
    285290    def add_filter(self, name, func): 
     
    289294        self.filters[name] = func 
    290295 
    291     def parse_rule(self, rule): 
    292         ''' Parses a rule into a (name, filter, conf) token stream. If mode is 
    293             None, name contains a static rule part. ''' 
     296    rule_syntax = re.compile('(\\\\*)'\ 
     297        '(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)'\ 
     298          '|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)'\ 
     299            '(?::((?:\\\\.|[^\\\\>]+)+)?)?)?>))') 
     300 
     301    def _itertokens(self, rule): 
    294302        offset, prefix = 0, '' 
    295303        for match in self.rule_syntax.finditer(rule): 
     
    300308                offset = match.end() 
    301309                continue 
    302             if prefix: yield prefix, None, None 
    303             name, filtr, conf = g[1:4] if not g[2] is None else g[4:7] 
    304             if not filtr: filtr = self.default_filter 
    305             yield name, filtr, conf or None 
     310            if prefix: 
     311                yield prefix, None, None 
     312            name, filtr, conf = g[4:7] if g[2] is None else g[1:4] 
     313            yield name, filtr or 'default', conf or None 
    306314            offset, prefix = match.end(), '' 
    307315        if offset <= len(rule) or prefix: 
     
    309317 
    310318    def add(self, rule, method, target, name=None): 
    311         ''' Add a new route or replace the target for an existing route. ''' 
    312         if rule in self.rules: 
    313             self.rules[rule][method] = target 
    314             if name: self.builder[name] = self.builder[rule] 
    315             return 
    316  
    317         target = self.rules[rule] = {method: target} 
    318  
    319         # Build pattern and other structures for dynamic routes 
    320         anons = 0      # Number of anonymous wildcards 
    321         pattern = ''   # Regular expression  pattern 
    322         filters = []   # Lists of wildcard input filters 
    323         builder = []   # Data structure for the URL builder 
     319        ''' Add a new rule or replace the target for an existing rule. ''' 
     320        anons     = 0    # Number of anonymous wildcards found 
     321        keys      = []   # Names of keys 
     322        pattern   = ''   # Regular expression pattern with named groups 
     323        filters   = []   # Lists of wildcard input filters 
     324        builder   = []   # Data structure for the URL builder 
    324325        is_static = True 
    325         for key, mode, conf in self.parse_rule(rule): 
     326 
     327        for key, mode, conf in self._itertokens(rule): 
    326328            if mode: 
    327329                is_static = False 
     330                if mode == 'default': mode = self.default_filter 
    328331                mask, in_filter, out_filter = self.filters[mode](conf) 
    329                 if key: 
     332                if not key: 
     333                    pattern += '(?:%s)' % mask 
     334                    key = 'anon%d' % anons 
     335                    anons += 1 
     336                else: 
    330337                    pattern += '(?P<%s>%s)' % (key, mask) 
    331                 else: 
    332                     pattern += '(?:%s)' % mask 
    333                     key = 'anon%d' % anons; anons += 1 
     338                    keys.append(key) 
    334339                if in_filter: filters.append((key, in_filter)) 
    335340                builder.append((key, out_filter or str)) 
     
    337342                pattern += re.escape(key) 
    338343                builder.append((None, key)) 
     344 
    339345        self.builder[rule] = builder 
    340346        if name: self.builder[name] = builder 
    341347 
    342348        if is_static and not self.strict_order: 
    343             self.static[self.build(rule)] = target 
     349            self.static.setdefault(method, {}) 
     350            self.static[method][self.build(rule)] = (target, None) 
    344351            return 
    345352 
    346         def fpat_sub(m): 
    347             return m.group(0) if len(m.group(1)) % 2 else m.group(1) + '(?:' 
    348         flat_pattern = re.sub(r'(\\*)(\(\?P<[^>]*>|\((?!\?))', fpat_sub, pattern) 
    349  
    350353        try: 
    351             re_match = re.compile('^(%s)$' % pattern).match 
     354            re_pattern = re.compile('^(%s)$' % pattern) 
     355            re_match = re_pattern.match 
    352356        except re.error: 
    353357            raise RouteSyntaxError("Could not add Route: %s (%s)" % (rule, _e())) 
    354358 
    355         def match(path): 
    356             """ Return an url-argument dictionary. """ 
    357             url_args = re_match(path).groupdict() 
    358             for name, wildcard_filter in filters: 
    359                 try: 
    360                     url_args[name] = wildcard_filter(url_args[name]) 
    361                 except ValueError: 
    362                     raise HTTPError(400, 'Path has wrong format.') 
    363             return url_args 
    364  
    365         try: 
    366             combined = '%s|(^%s$)' % (self.dynamic[-1][0].pattern, flat_pattern) 
    367             self.dynamic[-1] = (re.compile(combined), self.dynamic[-1][1]) 
    368             self.dynamic[-1][1].append((match, target)) 
    369         except (AssertionError, IndexError): # AssertionError: Too many groups 
    370             self.dynamic.append((re.compile('(^%s$)' % flat_pattern), 
    371                                 [(match, target)])) 
    372         return match 
     359        if filters: 
     360            def getargs(path): 
     361                url_args = re_match(path).groupdict() 
     362                for name, wildcard_filter in filters: 
     363                    try: 
     364                        url_args[name] = wildcard_filter(url_args[name]) 
     365                    except ValueError: 
     366                        raise HTTPError(400, 'Path has wrong format.') 
     367                return url_args 
     368        elif re_pattern.groupindex: 
     369            def getargs(path): 
     370                return re_match(path).groupdict() 
     371        else: 
     372            getargs = None 
     373 
     374        flatpat = _re_flatten(pattern) 
     375        whole_rule = (rule, flatpat, target, getargs) 
     376 
     377        if (flatpat, method) in self._groups: 
     378            if DEBUG: 
     379                msg = 'Route <%s %s> overwrites a previously defined route' 
     380                warnings.warn(msg % (method, rule), RuntimeWarning) 
     381            self.dyna_routes[method][self._groups[flatpat, method]] = whole_rule 
     382        else: 
     383            self.dyna_routes.setdefault(method, []).append(whole_rule) 
     384            self._groups[flatpat, method] = len(self.dyna_routes[method]) - 1 
     385 
     386        self._compile(method) 
     387 
     388    def _compile(self, method): 
     389        all_rules = self.dyna_routes[method] 
     390        comborules = self.dyna_regexes[method] = [] 
     391        maxgroups = self._MAX_GROUPS_PER_PATTERN 
     392        for x in range(0, len(all_rules), maxgroups): 
     393            some = all_rules[x:x+maxgroups] 
     394            combined = (flatpat for (_, flatpat, _, _) in some) 
     395            combined = '|'.join('(^%s$)' % flatpat for flatpat in combined) 
     396            combined = re.compile(combined).match 
     397            rules = [(target, getargs) for (_, _, target, getargs) in some] 
     398            comborules.append((combined, rules)) 
    373399 
    374400    def build(self, _name, *anons, **query): 
     
    385411    def match(self, environ): 
    386412        ''' Return a (target, url_agrs) tuple or raise HTTPError(400/404/405). ''' 
    387         path, targets, urlargs = environ['PATH_INFO'] or '/', None, {} 
    388         if path in self.static: 
    389             targets = self.static[path] 
     413        verb = environ['REQUEST_METHOD'].upper() 
     414        path = environ['PATH_INFO'] or '/' 
     415        target = None 
     416        if verb == 'HEAD': 
     417            methods = ['PROXY', verb, 'GET', 'ANY'] 
    390418        else: 
    391             for combined, rules in self.dynamic: 
    392                 match = combined.match(path) 
    393                 if not match: continue 
    394                 getargs, targets = rules[match.lastindex - 1] 
    395                 urlargs = getargs(path) if getargs else {} 
    396                 break 
    397  
    398         if not targets: 
    399             raise HTTPError(404, "Not found: " + repr(environ['PATH_INFO'])) 
    400         method = environ['REQUEST_METHOD'].upper() 
    401         if method in targets: 
    402             return targets[method], urlargs 
    403         if method == 'HEAD' and 'GET' in targets: 
    404             return targets['GET'], urlargs 
    405         if 'ANY' in targets: 
    406             return targets['ANY'], urlargs 
    407         allowed = [verb for verb in targets if verb != 'ANY'] 
    408         if 'GET' in allowed and 'HEAD' not in allowed: 
    409             allowed.append('HEAD') 
    410         raise HTTPError(405, "Method not allowed.", Allow=",".join(allowed)) 
     419            methods = ['PROXY', verb, 'ANY'] 
     420 
     421        for method in methods: 
     422            if method in self.static and path in self.static[method]: 
     423                target, getargs = self.static[method][path] 
     424                return target, getargs(path) if getargs else {} 
     425            elif method in self.dyna_regexes: 
     426                for combined, rules in self.dyna_regexes[method]: 
     427                    match = combined(path) 
     428                    if match: 
     429                        target, getargs = rules[match.lastindex - 1] 
     430                        return target, getargs(path) if getargs else {} 
     431 
     432        # No matching route found. Collect alternative methods for 405 response 
     433        allowed = set([]) 
     434        nocheck = set(methods) 
     435        for method in set(self.static) - nocheck: 
     436            if path in self.static[method]: 
     437                allowed.add(verb) 
     438        for method in set(self.dyna_regexes) - allowed - nocheck: 
     439            for combined, rules in self.dyna_regexes[method]: 
     440                match = combined(path) 
     441                if match: 
     442                    allowed.add(method) 
     443        if allowed: 
     444            allow_header = ",".join(sorted(allowed)) 
     445            raise HTTPError(405, "Method not allowed.", Allow=allow_header) 
     446 
     447        # No matching route and no alternative method found. We give up 
     448        raise HTTPError(404, "Not found: " + repr(path)) 
     449 
     450 
     451 
     452 
    411453 
    412454 
     
    436478        #: decorator are stored in this dictionary. Used for route-specific 
    437479        #: plugin configuration and meta-data. 
    438         self.config = ConfigDict(config) 
     480        self.config = ConfigDict().load_dict(config, make_namespaces=True) 
    439481 
    440482    def __call__(self, *a, **ka): 
    441483        depr("Some APIs changed to return Route() instances instead of"\ 
    442484             " callables. Make sure to use the Route.call method and not to"\ 
    443              " call Route instances directly.") 
     485             " call Route instances directly.") #0.12 
    444486        return self.call(*a, **ka) 
    445487 
     
    461503    @property 
    462504    def _context(self): 
    463         depr('Switch to Plugin API v2 and access the Route object directly.') 
     505        depr('Switch to Plugin API v2 and access the Route object directly.')  #0.12 
    464506        return dict(rule=self.rule, method=self.method, callback=self.callback, 
    465507                    name=self.name, app=self.app, config=self.config, 
     
    493535        return callback 
    494536 
     537    def get_undecorated_callback(self): 
     538        ''' Return the callback. If the callback is a decorated function, try to 
     539            recover the original function. ''' 
     540        func = self.callback 
     541        func = getattr(func, '__func__' if py3k else 'im_func', func) 
     542        closure_attr = '__closure__' if py3k else 'func_closure' 
     543        while hasattr(func, closure_attr) and getattr(func, closure_attr): 
     544            func = getattr(func, closure_attr)[0].cell_contents 
     545        return func 
     546 
     547    def get_callback_args(self): 
     548        ''' Return a list of argument names the callback (most likely) accepts 
     549            as keyword arguments. If the callback is a decorated function, try 
     550            to recover the original function before inspection. ''' 
     551        return getargspec(self.get_undecorated_callback())[0] 
     552 
     553    def get_config(self, key, default=None): 
     554        ''' Lookup a config field and return its value, first checking the 
     555            route.config, then route.app.config.''' 
     556        for conf in (self.config, self.app.conifg): 
     557            if key in conf: return conf[key] 
     558        return default 
     559 
    495560    def __repr__(self): 
    496         return '<%s %r %r>' % (self.method, self.rule, self.callback) 
     561        cb = self.get_undecorated_callback() 
     562        return '<%s %r %r>' % (self.method, self.rule, cb) 
    497563 
    498564 
     
    516582 
    517583    def __init__(self, catchall=True, autojson=True): 
    518         #: If true, most exceptions are caught and returned as :exc:`HTTPError` 
    519         self.catchall = catchall 
     584 
     585        #: A :class:`ConfigDict` for app specific configuration. 
     586        self.config = ConfigDict() 
     587        self.config._on_change = functools.partial(self.trigger_hook, 'config') 
     588        self.config.meta_set('autojson', 'validate', bool) 
     589        self.config.meta_set('catchall', 'validate', bool) 
     590        self.config['catchall'] = catchall 
     591        self.config['autojson'] = autojson 
    520592 
    521593        #: A :class:`ResourceManager` for application files 
    522594        self.resources = ResourceManager() 
    523  
    524         #: A :class:`ConfigDict` for app specific configuration. 
    525         self.config = ConfigDict() 
    526         self.config.autojson = autojson 
    527595 
    528596        self.routes = [] # List of installed :class:`Route` instances. 
     
    532600        # Core plugins 
    533601        self.plugins = [] # List of installed plugins. 
    534         self.hooks = HooksPlugin() 
    535         self.install(self.hooks) 
    536         if self.config.autojson: 
     602        if self.config['autojson']: 
    537603            self.install(JSONPlugin()) 
    538604        self.install(TemplatePlugin()) 
    539605 
     606    #: If true, most exceptions are caught and returned as :exc:`HTTPError` 
     607    catchall = DictProperty('config', 'catchall') 
     608 
     609    __hook_names = 'before_request', 'after_request', 'app_reset', 'config' 
     610    __hook_reversed = 'after_request' 
     611 
     612    @cached_property 
     613    def _hooks(self): 
     614        return dict((name, []) for name in self.__hook_names) 
     615 
     616    def add_hook(self, name, func): 
     617        ''' Attach a callback to a hook. Three hooks are currently implemented: 
     618 
     619            before_request 
     620                Executed once before each request. The request context is 
     621                available, but no routing has happened yet. 
     622            after_request 
     623                Executed once after each request regardless of its outcome. 
     624            app_reset 
     625                Called whenever :meth:`Bottle.reset` is called. 
     626        ''' 
     627        if name in self.__hook_reversed: 
     628            self._hooks[name].insert(0, func) 
     629        else: 
     630            self._hooks[name].append(func) 
     631 
     632    def remove_hook(self, name, func): 
     633        ''' Remove a callback from a hook. ''' 
     634        if name in self._hooks and func in self._hooks[name]: 
     635            self._hooks[name].remove(func) 
     636            return True 
     637 
     638    def trigger_hook(self, __name, *args, **kwargs): 
     639        ''' Trigger a hook and return a list of results. ''' 
     640        return [hook(*args, **kwargs) for hook in self._hooks[__name][:]] 
     641 
     642    def hook(self, name): 
     643        """ Return a decorator that attaches a callback to a hook. See 
     644            :meth:`add_hook` for details.""" 
     645        def decorator(func): 
     646            self.add_hook(name, func) 
     647            return func 
     648        return decorator 
    540649 
    541650    def mount(self, prefix, app, **options): 
     
    552661        ''' 
    553662        if isinstance(app, basestring): 
    554             prefix, app = app, prefix 
    555             depr('Parameter order of Bottle.mount() changed.') # 0.10 
     663            depr('Parameter order of Bottle.mount() changed.', True) # 0.10 
    556664 
    557665        segments = [p for p in prefix.split('/') if p] 
     
    563671                request.path_shift(path_depth) 
    564672                rs = HTTPResponse([]) 
    565                 def start_response(status, headerlist): 
     673                def start_response(status, headerlist, exc_info=None): 
     674                    if exc_info: 
     675                        try: 
     676                            _raise(*exc_info) 
     677                        finally: 
     678                            exc_info = None 
    566679                    rs.status = status 
    567680                    for name, value in headerlist: rs.add_header(name, value) 
    568681                    return rs.body.append 
    569682                body = app(request.environ, start_response) 
    570                 if body: rs.body = itertools.chain(rs.body, body) 
     683                if body and rs.body: body = itertools.chain(rs.body, body) 
     684                rs.body = body or rs.body 
    571685                return rs 
    572686            finally: 
     
    574688 
    575689        options.setdefault('skip', True) 
    576         options.setdefault('method', 'ANY') 
     690        options.setdefault('method', 'PROXY') 
    577691        options.setdefault('mountpoint', {'prefix': prefix, 'target': app}) 
    578692        options['callback'] = mountpoint_wrapper 
     
    619733        return removed 
    620734 
    621     def run(self, **kwargs): 
    622         ''' Calls :func:`run` with the same parameters. ''' 
    623         run(self, **kwargs) 
    624  
    625735    def reset(self, route=None): 
    626736        ''' Reset all routes (force plugins to be re-applied) and clear all 
     
    633743        if DEBUG: 
    634744            for route in routes: route.prepare() 
    635         self.hooks.trigger('app_reset') 
     745        self.trigger_hook('app_reset') 
    636746 
    637747    def close(self): 
     
    640750            if hasattr(plugin, 'close'): plugin.close() 
    641751        self.stopped = True 
     752 
     753    def run(self, **kwargs): 
     754        ''' Calls :func:`run` with the same parameters. ''' 
     755        run(self, **kwargs) 
    642756 
    643757    def match(self, environ): 
     
    725839        return wrapper 
    726840 
    727     def hook(self, name): 
    728         """ Return a decorator that attaches a callback to a hook. Three hooks 
    729             are currently implemented: 
    730  
    731             - before_request: Executed once before each request 
    732             - after_request: Executed once after each request 
    733             - app_reset: Called whenever :meth:`reset` is called. 
    734         """ 
    735         def wrapper(func): 
    736             self.hooks.add(name, func) 
    737             return func 
    738         return wrapper 
    739  
    740     def handle(self, path, method='GET'): 
    741         """ (deprecated) Execute the first matching route callback and return 
    742             the result. :exc:`HTTPResponse` exceptions are caught and returned. 
    743             If :attr:`Bottle.catchall` is true, other exceptions are caught as 
    744             well and returned as :exc:`HTTPError` instances (500). 
    745         """ 
    746         depr("This method will change semantics in 0.10. Try to avoid it.") 
    747         if isinstance(path, dict): 
    748             return self._handle(path) 
    749         return self._handle({'PATH_INFO': path, 'REQUEST_METHOD': method.upper()}) 
    750  
    751841    def default_error_handler(self, res): 
    752842        return tob(template(ERROR_PAGE_TEMPLATE, e=res)) 
    753843 
    754844    def _handle(self, environ): 
     845        path = environ['bottle.raw_path'] = environ['PATH_INFO'] 
     846        if py3k: 
     847            try: 
     848                environ['PATH_INFO'] = path.encode('latin1').decode('utf8') 
     849            except UnicodeError: 
     850                return HTTPError(400, 'Invalid path string. Expected UTF-8') 
     851 
    755852        try: 
    756853            environ['bottle.app'] = self 
    757854            request.bind(environ) 
    758855            response.bind() 
    759             route, args = self.router.match(environ) 
    760             environ['route.handle'] = route 
    761             environ['bottle.route'] = route 
    762             environ['route.url_args'] = args 
    763             return route.call(**args) 
     856            try: 
     857                self.trigger_hook('before_request') 
     858                route, args = self.router.match(environ) 
     859                environ['route.handle'] = route 
     860                environ['bottle.route'] = route 
     861                environ['route.url_args'] = args 
     862                return route.call(**args) 
     863            finally: 
     864                self.trigger_hook('after_request') 
     865 
    764866        except HTTPResponse: 
    765867            return _e() 
     
    818920        # Handle Iterables. We peek into them to detect their inner type. 
    819921        try: 
    820             out = iter(out) 
    821             first = next(out) 
     922            iout = iter(out) 
     923            first = next(iout) 
    822924            while not first: 
    823                 first = next(out) 
     925                first = next(iout) 
    824926        except StopIteration: 
    825927            return self._cast('') 
     
    835937        if isinstance(first, HTTPResponse): 
    836938            return self._cast(first) 
    837         if isinstance(first, bytes): 
    838             return itertools.chain([first], out) 
    839         if isinstance(first, unicode): 
    840             return imap(lambda x: x.encode(response.charset), 
    841                                   itertools.chain([first], out)) 
    842         return self._cast(HTTPError(500, 'Unsupported response type: %s'\ 
    843                                          % type(first))) 
     939        elif isinstance(first, bytes): 
     940            new_iter = itertools.chain([first], iout) 
     941        elif isinstance(first, unicode): 
     942            encoder = lambda x: x.encode(response.charset) 
     943            new_iter = imap(encoder, itertools.chain([first], iout)) 
     944        else: 
     945            msg = 'Unsupported response type: %s' % type(first) 
     946            return self._cast(HTTPError(500, msg)) 
     947        if hasattr(out, 'close'): 
     948            new_iter = _closeiter(new_iter, out.close) 
     949        return new_iter 
    844950 
    845951    def wsgi(self, environ, start_response): 
     
    866972            environ['wsgi.errors'].write(err) 
    867973            headers = [('Content-Type', 'text/html; charset=UTF-8')] 
    868             start_response('500 INTERNAL SERVER ERROR', headers) 
     974            start_response('500 INTERNAL SERVER ERROR', headers, sys.exc_info()) 
    869975            return [tob(err)] 
    870976 
     
    881987# HTTP and WSGI Tools ########################################################## 
    882988############################################################################### 
    883  
    884989 
    885990class BaseRequest(object): 
     
    8961001    #: Maximum size of memory buffer for :attr:`body` in bytes. 
    8971002    MEMFILE_MAX = 102400 
    898     #: Maximum number pr GET or POST parameters per request 
    899     MAX_PARAMS  = 100 
    9001003 
    9011004    def __init__(self, environ=None): 
     
    9111014        raise RuntimeError('This request is not connected to an application.') 
    9121015 
     1016    @DictProperty('environ', 'bottle.route', read_only=True) 
     1017    def route(self): 
     1018        """ The bottle :class:`Route` object that matches this request. """ 
     1019        raise RuntimeError('This request is not connected to a route.') 
     1020 
     1021    @DictProperty('environ', 'route.url_args', read_only=True) 
     1022    def url_args(self): 
     1023        """ The arguments extracted from the URL. """ 
     1024        raise RuntimeError('This request is not connected to a route.') 
     1025 
    9131026    @property 
    9141027    def path(self): 
     
    9361049        """ Cookies parsed into a :class:`FormsDict`. Signed cookies are NOT 
    9371050            decoded. Use :meth:`get_cookie` if you expect signed cookies. """ 
    938         cookies = SimpleCookie(self.environ.get('HTTP_COOKIE','')) 
    939         cookies = list(cookies.values())[:self.MAX_PARAMS] 
     1051        cookies = SimpleCookie(self.environ.get('HTTP_COOKIE','')).values() 
    9401052        return FormsDict((c.key, c.value) for c in cookies) 
    9411053 
     
    9591071        get = self.environ['bottle.get'] = FormsDict() 
    9601072        pairs = _parse_qsl(self.environ.get('QUERY_STRING', '')) 
    961         for key, value in pairs[:self.MAX_PARAMS]: 
     1073        for key, value in pairs: 
    9621074            get[key] = value 
    9631075        return get 
     
    9661078    def forms(self): 
    9671079        """ Form values parsed from an `url-encoded` or `multipart/form-data` 
    968             encoded POST or PUT request body. The result is retuned as a 
     1080            encoded POST or PUT request body. The result is returned as a 
    9691081            :class:`FormsDict`. All keys and values are strings. File uploads 
    9701082            are stored separately in :attr:`files`. """ 
    9711083        forms = FormsDict() 
    9721084        for name, item in self.POST.allitems(): 
    973             if not hasattr(item, 'filename'): 
     1085            if not isinstance(item, FileUpload): 
    9741086                forms[name] = item 
    9751087        return forms 
     
    9881100    @DictProperty('environ', 'bottle.request.files', read_only=True) 
    9891101    def files(self): 
    990         """ File uploads parsed from an `url-encoded` or `multipart/form-data` 
    991             encoded POST or PUT request body. The values are instances of 
    992             :class:`cgi.FieldStorage`. The most important attributes are: 
    993  
    994             filename 
    995                 The filename, if specified; otherwise None; this is the client 
    996                 side filename, *not* the file name on which it is stored (that's 
    997                 a temporary file you don't deal with) 
    998             file 
    999                 The file(-like) object from which you can read the data. 
    1000             value 
    1001                 The value as a *string*; for file uploads, this transparently 
    1002                 reads the file every time you request the value. Do not do this 
    1003                 on big files. 
     1102        """ File uploads parsed from `multipart/form-data` encoded POST or PUT 
     1103            request body. The values are instances of :class:`FileUpload`. 
     1104 
    10041105        """ 
    10051106        files = FormsDict() 
    10061107        for name, item in self.POST.allitems(): 
    1007             if hasattr(item, 'filename'): 
     1108            if isinstance(item, FileUpload): 
    10081109                files[name] = item 
    10091110        return files 
     
    10151116            smaller than :attr:`MEMFILE_MAX` are processed to avoid memory 
    10161117            exhaustion. ''' 
    1017         if 'application/json' in self.environ.get('CONTENT_TYPE', '') \ 
    1018         and 0 < self.content_length < self.MEMFILE_MAX: 
    1019             return json_loads(self.body.read(self.MEMFILE_MAX)) 
     1118        ctype = self.environ.get('CONTENT_TYPE', '').lower().split(';')[0] 
     1119        if ctype == 'application/json': 
     1120            return json_loads(self._get_body_string()) 
    10201121        return None 
    10211122 
     1123    def _iter_body(self, read, bufsize): 
     1124        maxread = max(0, self.content_length) 
     1125        while maxread: 
     1126            part = read(min(maxread, bufsize)) 
     1127            if not part: break 
     1128            yield part 
     1129            maxread -= len(part) 
     1130 
     1131    def _iter_chunked(self, read, bufsize): 
     1132        err = HTTPError(400, 'Error while parsing chunked transfer body.') 
     1133        rn, sem, bs = tob('\r\n'), tob(';'), tob('') 
     1134        while True: 
     1135            header = read(1) 
     1136            while header[-2:] != rn: 
     1137                c = read(1) 
     1138                header += c 
     1139                if not c: raise err 
     1140                if len(header) > bufsize: raise err 
     1141            size, _, _ = header.partition(sem) 
     1142            try: 
     1143                maxread = int(tonat(size.strip()), 16) 
     1144            except ValueError: 
     1145                raise err 
     1146            if maxread == 0: break 
     1147            buff = bs 
     1148            while maxread > 0: 
     1149                if not buff: 
     1150                    buff = read(min(maxread, bufsize)) 
     1151                part, buff = buff[:maxread], buff[maxread:] 
     1152                if not part: raise err 
     1153                yield part 
     1154                maxread -= len(part) 
     1155            if read(2) != rn: 
     1156                raise err 
     1157             
    10221158    @DictProperty('environ', 'bottle.request.body', read_only=True) 
    10231159    def _body(self): 
    1024         maxread = max(0, self.content_length) 
    1025         stream = self.environ['wsgi.input'] 
    1026         body = BytesIO() if maxread < self.MEMFILE_MAX else TemporaryFile(mode='w+b') 
    1027         while maxread > 0: 
    1028             part = stream.read(min(maxread, self.MEMFILE_MAX)) 
    1029             if not part: break 
     1160        body_iter = self._iter_chunked if self.chunked else self._iter_body 
     1161        read_func = self.environ['wsgi.input'].read 
     1162        body, body_size, is_temp_file = BytesIO(), 0, False 
     1163        for part in body_iter(read_func, self.MEMFILE_MAX): 
    10301164            body.write(part) 
    1031             maxread -= len(part) 
     1165            body_size += len(part) 
     1166            if not is_temp_file and body_size > self.MEMFILE_MAX: 
     1167                body, tmp = TemporaryFile(mode='w+b'), body 
     1168                body.write(tmp.getvalue()) 
     1169                del tmp 
     1170                is_temp_file = True 
    10321171        self.environ['wsgi.input'] = body 
    10331172        body.seek(0) 
    10341173        return body 
     1174 
     1175    def _get_body_string(self): 
     1176        ''' read body until content-length or MEMFILE_MAX into a string. Raise 
     1177            HTTPError(413) on requests that are to large. ''' 
     1178        clen = self.content_length 
     1179        if clen > self.MEMFILE_MAX: 
     1180            raise HTTPError(413, 'Request to large') 
     1181        if clen < 0: clen = self.MEMFILE_MAX + 1 
     1182        data = self.body.read(clen) 
     1183        if len(data) > self.MEMFILE_MAX: # Fail fast 
     1184            raise HTTPError(413, 'Request to large') 
     1185        return data 
    10351186 
    10361187    @property 
     
    10431194        self._body.seek(0) 
    10441195        return self._body 
     1196 
     1197    @property 
     1198    def chunked(self): 
     1199        ''' True if Chunked transfer encoding was. ''' 
     1200        return 'chunked' in self.environ.get('HTTP_TRANSFER_ENCODING', '').lower() 
    10451201 
    10461202    #: An alias for :attr:`query`. 
     
    10571213        # is not multipart and take the fast path (also: 3.1 workaround) 
    10581214        if not self.content_type.startswith('multipart/'): 
    1059             maxlen = max(0, min(self.content_length, self.MEMFILE_MAX)) 
    1060             pairs = _parse_qsl(tonat(self.body.read(maxlen), 'latin1')) 
    1061             for key, value in pairs[:self.MAX_PARAMS]: 
     1215            pairs = _parse_qsl(tonat(self._get_body_string(), 'latin1')) 
     1216            for key, value in pairs: 
    10621217                post[key] = value 
    10631218            return post 
     
    10681223        args = dict(fp=self.body, environ=safe_env, keep_blank_values=True) 
    10691224        if py31: 
    1070             args['fp'] = NCTextIOWrapper(args['fp'], encoding='ISO-8859-1', 
     1225            args['fp'] = NCTextIOWrapper(args['fp'], encoding='utf8', 
    10711226                                         newline='\n') 
    10721227        elif py3k: 
    1073             args['encoding'] = 'ISO-8859-1' 
    1074         data = FieldStorage(**args) 
    1075         for item in (data.list or [])[:self.MAX_PARAMS]: 
    1076             post[item.name] = item if item.filename else item.value 
     1228            args['encoding'] = 'utf8' 
     1229        data = cgi.FieldStorage(**args) 
     1230        self['_cgi.FieldStorage'] = data #http://bugs.python.org/issue18394#msg207958 
     1231        data = data.list or [] 
     1232        for item in data: 
     1233            if item.filename: 
     1234                post[item.name] = FileUpload(item.file, item.name, 
     1235                                             item.filename, item.headers) 
     1236            else: 
     1237                post[item.name] = item.value 
    10771238        return post 
    1078  
    1079     @property 
    1080     def COOKIES(self): 
    1081         ''' Alias for :attr:`cookies` (deprecated). ''' 
    1082         depr('BaseRequest.COOKIES was renamed to BaseRequest.cookies (lowercase).') 
    1083         return self.cookies 
    10841239 
    10851240    @property 
     
    12711426        headers, but is NOT a dict. Most notably, iterating over a response 
    12721427        yields parts of the body and not the headers. 
     1428 
     1429        :param body: The response body as one of the supported types. 
     1430        :param status: Either an HTTP status code (e.g. 200) or a status line 
     1431                       including the reason phrase (e.g. '200 OK'). 
     1432        :param headers: A dictionary or a list of name-value pairs. 
     1433 
     1434        Additional keyword arguments are added to the list of headers. 
     1435        Underscores in the header name are replaced with dashes. 
    12731436    """ 
    12741437 
     
    12841447                  'Content-Md5', 'Last-Modified'))} 
    12851448 
    1286     def __init__(self, body='', status=None, **headers): 
     1449    def __init__(self, body='', status=None, headers=None, **more_headers): 
    12871450        self._cookies = None 
    1288         self._headers = {'Content-Type': [self.default_content_type]} 
     1451        self._headers = {} 
    12891452        self.body = body 
    12901453        self.status = status or self.default_status 
    12911454        if headers: 
    1292             for name, value in headers.items(): 
    1293                 self[name] = value 
    1294  
    1295     def copy(self): 
     1455            if isinstance(headers, dict): 
     1456                headers = headers.items() 
     1457            for name, value in headers: 
     1458                self.add_header(name, value) 
     1459        if more_headers: 
     1460            for name, value in more_headers.items(): 
     1461                self.add_header(name, value) 
     1462 
     1463    def copy(self, cls=None): 
    12961464        ''' Returns a copy of self. ''' 
    1297         copy = Response() 
     1465        cls = cls or BaseResponse 
     1466        assert issubclass(cls, BaseResponse) 
     1467        copy = cls() 
    12981468        copy.status = self.status 
    12991469        copy._headers = dict((k, v[:]) for (k, v) in self._headers.items()) 
     1470        if self._cookies: 
     1471            copy._cookies = SimpleCookie() 
     1472            copy._cookies.load(self._cookies.output()) 
    13001473        return copy 
    13011474 
     
    13721545        return self.headerlist 
    13731546 
    1374     def wsgiheader(self): 
    1375         depr('The wsgiheader method is deprecated. See headerlist.') #0.10 
    1376         return self.headerlist 
    1377  
    13781547    @property 
    13791548    def headerlist(self): 
    13801549        ''' WSGI conform list of (header, value) tuples. ''' 
    13811550        out = [] 
    1382         headers = self._headers.items() 
     1551        headers = list(self._headers.items()) 
     1552        if 'Content-Type' not in self._headers: 
     1553            headers.append(('Content-Type', [self.default_content_type])) 
    13831554        if self._status_code in self.bad_headers: 
    13841555            bad_headers = self.bad_headers[self._status_code] 
     
    13921563    content_type = HeaderProperty('Content-Type') 
    13931564    content_length = HeaderProperty('Content-Length', reader=int) 
     1565    expires = HeaderProperty('Expires', 
     1566        reader=lambda x: datetime.utcfromtimestamp(parse_date(x)), 
     1567        writer=lambda x: http_date(x)) 
    13941568 
    13951569    @property 
    1396     def charset(self): 
     1570    def charset(self, default='UTF-8'): 
    13971571        """ Return the charset specified in the content-type header (default: utf8). """ 
    13981572        if 'charset=' in self.content_type: 
    13991573            return self.content_type.split('charset=')[-1].split(';')[0].strip() 
    1400         return 'UTF-8' 
    1401  
    1402     @property 
    1403     def COOKIES(self): 
    1404         """ A dict-like SimpleCookie instance. This should not be used directly. 
    1405             See :meth:`set_cookie`. """ 
    1406         depr('The COOKIES dict is deprecated. Use `set_cookie()` instead.') # 0.10 
    1407         if not self._cookies: 
    1408             self._cookies = SimpleCookie() 
    1409         return self._cookies 
     1574        return default 
    14101575 
    14111576    def set_cookie(self, name, value, secret=None, **options): 
     
    14781643        return out 
    14791644 
    1480 #: Thread-local storage for :class:`LocalRequest` and :class:`LocalResponse` 
    1481 #: attributes. 
    1482 _lctx = threading.local() 
    1483  
    1484 def local_property(name): 
     1645 
     1646def local_property(name=None): 
     1647    if name: depr('local_property() is deprecated and will be removed.') #0.12 
     1648    ls = threading.local() 
    14851649    def fget(self): 
    1486         try: 
    1487             return getattr(_lctx, name) 
     1650        try: return ls.var 
    14881651        except AttributeError: 
    14891652            raise RuntimeError("Request context not initialized.") 
    1490     def fset(self, value): setattr(_lctx, name, value) 
    1491     def fdel(self): delattr(_lctx, name) 
    1492     return property(fget, fset, fdel, 
    1493         'Thread-local property stored in :data:`_lctx.%s`' % name) 
     1653    def fset(self, value): ls.var = value 
     1654    def fdel(self): del ls.var 
     1655    return property(fget, fset, fdel, 'Thread-local property') 
    14941656 
    14951657 
    14961658class LocalRequest(BaseRequest): 
    14971659    ''' A thread-local subclass of :class:`BaseRequest` with a different 
    1498         set of attribues for each thread. There is usually only one global 
     1660        set of attributes for each thread. There is usually only one global 
    14991661        instance of this class (:data:`request`). If accessed during a 
    15001662        request/response cycle, this instance always refers to the *current* 
    15011663        request (even on a multithreaded server). ''' 
    15021664    bind = BaseRequest.__init__ 
    1503     environ = local_property('request_environ') 
     1665    environ = local_property() 
    15041666 
    15051667 
    15061668class LocalResponse(BaseResponse): 
    15071669    ''' A thread-local subclass of :class:`BaseResponse` with a different 
    1508         set of attribues for each thread. There is usually only one global 
     1670        set of attributes for each thread. There is usually only one global 
    15091671        instance of this class (:data:`response`). Its attributes are used 
    15101672        to build the HTTP response at the end of the request/response cycle. 
    15111673    ''' 
    15121674    bind = BaseResponse.__init__ 
    1513     _status_line = local_property('response_status_line') 
    1514     _status_code = local_property('response_status_code') 
    1515     _cookies     = local_property('response_cookies') 
    1516     _headers     = local_property('response_headers') 
    1517     body         = local_property('response_body') 
     1675    _status_line = local_property() 
     1676    _status_code = local_property() 
     1677    _cookies     = local_property() 
     1678    _headers     = local_property() 
     1679    body         = local_property() 
     1680 
    15181681 
    15191682Request = BaseRequest 
    15201683Response = BaseResponse 
    15211684 
     1685 
    15221686class HTTPResponse(Response, BottleException): 
    1523     def __init__(self, body='', status=None, header=None, **headers): 
    1524         if header or 'output' in headers: 
    1525             depr('Call signature changed (for the better)') 
    1526             if header: headers.update(header) 
    1527             if 'output' in headers: body = headers.pop('output') 
    1528         super(HTTPResponse, self).__init__(body, status, **headers) 
     1687    def __init__(self, body='', status=None, headers=None, **more_headers): 
     1688        super(HTTPResponse, self).__init__(body, status, headers, **more_headers) 
    15291689 
    15301690    def apply(self, response): 
     
    15351695        response.body = self.body 
    15361696 
    1537     def _output(self, value=None): 
    1538         depr('Use HTTPResponse.body instead of HTTPResponse.output') 
    1539         if value is None: return self.body 
    1540         self.body = value 
    1541  
    1542     output = property(_output, _output, doc='Alias for .body') 
    15431697 
    15441698class HTTPError(HTTPResponse): 
    15451699    default_status = 500 
    1546     def __init__(self, status=None, body=None, exception=None, traceback=None, header=None, **headers): 
     1700    def __init__(self, status=None, body=None, exception=None, traceback=None, 
     1701                 **options): 
    15471702        self.exception = exception 
    15481703        self.traceback = traceback 
    1549         super(HTTPError, self).__init__(body, status, header, **headers) 
     1704        super(HTTPError, self).__init__(body, status, **options) 
    15501705 
    15511706 
     
    15581713 
    15591714class PluginError(BottleException): pass 
     1715 
    15601716 
    15611717class JSONPlugin(object): 
     
    15701726        if not dumps: return callback 
    15711727        def wrapper(*a, **ka): 
    1572             rv = callback(*a, **ka) 
     1728            try: 
     1729                rv = callback(*a, **ka) 
     1730            except HTTPError: 
     1731                rv = _e() 
     1732 
    15731733            if isinstance(rv, dict): 
    15741734                #Attempt to serialize, raises exception on failure 
     
    15771737                response.content_type = 'application/json' 
    15781738                return json_response 
     1739            elif isinstance(rv, HTTPResponse) and isinstance(rv.body, dict): 
     1740                rv.body = dumps(rv.body) 
     1741                rv.content_type = 'application/json' 
    15791742            return rv 
    1580         return wrapper 
    1581  
    1582  
    1583 class HooksPlugin(object): 
    1584     name = 'hooks' 
    1585     api  = 2 
    1586  
    1587     _names = 'before_request', 'after_request', 'app_reset' 
    1588  
    1589     def __init__(self): 
    1590         self.hooks = dict((name, []) for name in self._names) 
    1591         self.app = None 
    1592  
    1593     def _empty(self): 
    1594         return not (self.hooks['before_request'] or self.hooks['after_request']) 
    1595  
    1596     def setup(self, app): 
    1597         self.app = app 
    1598  
    1599     def add(self, name, func): 
    1600         ''' Attach a callback to a hook. ''' 
    1601         was_empty = self._empty() 
    1602         self.hooks.setdefault(name, []).append(func) 
    1603         if self.app and was_empty and not self._empty(): self.app.reset() 
    1604  
    1605     def remove(self, name, func): 
    1606         ''' Remove a callback from a hook. ''' 
    1607         was_empty = self._empty() 
    1608         if name in self.hooks and func in self.hooks[name]: 
    1609             self.hooks[name].remove(func) 
    1610         if self.app and not was_empty and self._empty(): self.app.reset() 
    1611  
    1612     def trigger(self, name, *a, **ka): 
    1613         ''' Trigger a hook and return a list of results. ''' 
    1614         hooks = self.hooks[name] 
    1615         if ka.pop('reversed', False): hooks = hooks[::-1] 
    1616         return [hook(*a, **ka) for hook in hooks] 
    1617  
    1618     def apply(self, callback, route): 
    1619         if self._empty(): return callback 
    1620         def wrapper(*a, **ka): 
    1621             self.trigger('before_request') 
    1622             rv = callback(*a, **ka) 
    1623             self.trigger('after_request', reversed=True) 
    1624             return rv 
     1743 
    16251744        return wrapper 
    16261745 
     
    16381757        if isinstance(conf, (tuple, list)) and len(conf) == 2: 
    16391758            return view(conf[0], **conf[1])(callback) 
    1640         elif isinstance(conf, str) and 'template_opts' in route.config: 
    1641             depr('The `template_opts` parameter is deprecated.') #0.9 
    1642             return view(conf, **route.config['template_opts'])(callback) 
    16431759        elif isinstance(conf, str): 
    16441760            return view(conf)(callback) 
     
    16601776    def find_module(self, fullname, path=None): 
    16611777        if '.' not in fullname: return 
    1662         packname, modname = fullname.rsplit('.', 1) 
     1778        packname = fullname.rsplit('.', 1)[0] 
    16631779        if packname != self.name: return 
    16641780        return self 
     
    16661782    def load_module(self, fullname): 
    16671783        if fullname in sys.modules: return sys.modules[fullname] 
    1668         packname, modname = fullname.rsplit('.', 1) 
     1784        modname = fullname.rsplit('.', 1)[1] 
    16691785        realname = self.impmask % modname 
    16701786        __import__(realname) 
     
    17571873 
    17581874 
    1759  
    17601875class FormsDict(MultiDict): 
    17611876    ''' This :class:`MultiDict` subclass is used to store request form data. 
     
    17741889    def _fix(self, s, encoding=None): 
    17751890        if isinstance(s, unicode) and self.recode_unicode: # Python 3 WSGI 
    1776             s = s.encode('latin1') 
    1777         if isinstance(s, bytes): # Python 2 WSGI 
     1891            return s.encode('latin1').decode(encoding or self.input_encoding) 
     1892        elif isinstance(s, bytes): # Python 2 WSGI 
    17781893            return s.decode(encoding or self.input_encoding) 
    1779         return s 
     1894        else: 
     1895            return s 
    17801896 
    17811897    def decode(self, encoding=None): 
     
    17911907 
    17921908    def getunicode(self, name, default=None, encoding=None): 
     1909        ''' Return the value as a unicode string, or the default. ''' 
    17931910        try: 
    17941911            return self._fix(self[name], encoding) 
     
    18761993 
    18771994 
     1995 
    18781996class ConfigDict(dict): 
    1879     ''' A dict-subclass with some extras: You can access keys like attributes. 
    1880         Uppercase attributes create new ConfigDicts and act as name-spaces. 
    1881         Other missing attributes return None. Calling a ConfigDict updates its 
    1882         values and returns itself. 
    1883  
    1884         >>> cfg = ConfigDict() 
    1885         >>> cfg.Namespace.value = 5 
    1886         >>> cfg.OtherNamespace(a=1, b=2) 
    1887         >>> cfg 
    1888         {'Namespace': {'value': 5}, 'OtherNamespace': {'a': 1, 'b': 2}} 
     1997    ''' A dict-like configuration storage with additional support for 
     1998        namespaces, validators, meta-data, on_change listeners and more. 
     1999 
     2000        This storage is optimized for fast read access. Retrieving a key 
     2001        or using non-altering dict methods (e.g. `dict.get()`) has no overhead 
     2002        compared to a native dict. 
    18892003    ''' 
    1890  
     2004    __slots__ = ('_meta', '_on_change') 
     2005 
     2006    class Namespace(DictMixin): 
     2007 
     2008        def __init__(self, config, namespace): 
     2009            self._config = config 
     2010            self._prefix = namespace 
     2011 
     2012        def __getitem__(self, key): 
     2013            depr('Accessing namespaces as dicts is discouraged. ' 
     2014                 'Only use flat item access: ' 
     2015                 'cfg["names"]["pace"]["key"] -> cfg["name.space.key"]') #0.12 
     2016            return self._config[self._prefix + '.' + key] 
     2017 
     2018        def __setitem__(self, key, value): 
     2019            self._config[self._prefix + '.' + key] = value 
     2020 
     2021        def __delitem__(self, key): 
     2022            del self._config[self._prefix + '.' + key] 
     2023 
     2024        def __iter__(self): 
     2025            ns_prefix = self._prefix + '.' 
     2026            for key in self._config: 
     2027                ns, dot, name = key.rpartition('.') 
     2028                if ns == self._prefix and name: 
     2029                    yield name 
     2030 
     2031        def keys(self): return [x for x in self] 
     2032        def __len__(self): return len(self.keys()) 
     2033        def __contains__(self, key): return self._prefix + '.' + key in self._config 
     2034        def __repr__(self): return '<Config.Namespace %s.*>' % self._prefix 
     2035        def __str__(self): return '<Config.Namespace %s.*>' % self._prefix 
     2036 
     2037        # Deprecated ConfigDict features 
     2038        def __getattr__(self, key): 
     2039            depr('Attribute access is deprecated.') #0.12 
     2040            if key not in self and key[0].isupper(): 
     2041                self[key] = ConfigDict.Namespace(self._config, self._prefix + '.' + key) 
     2042            if key not in self and key.startswith('__'): 
     2043                raise AttributeError(key) 
     2044            return self.get(key) 
     2045 
     2046        def __setattr__(self, key, value): 
     2047            if key in ('_config', '_prefix'): 
     2048                self.__dict__[key] = value 
     2049                return 
     2050            depr('Attribute assignment is deprecated.') #0.12 
     2051            if hasattr(DictMixin, key): 
     2052                raise AttributeError('Read-only attribute.') 
     2053            if key in self and self[key] and isinstance(self[key], self.__class__): 
     2054                raise AttributeError('Non-empty namespace attribute.') 
     2055            self[key] = value 
     2056 
     2057        def __delattr__(self, key): 
     2058            if key in self: 
     2059                val = self.pop(key) 
     2060                if isinstance(val, self.__class__): 
     2061                    prefix = key + '.' 
     2062                    for key in self: 
     2063                        if key.startswith(prefix): 
     2064                            del self[prefix+key] 
     2065 
     2066        def __call__(self, *a, **ka): 
     2067            depr('Calling ConfDict is deprecated. Use the update() method.') #0.12 
     2068            self.update(*a, **ka) 
     2069            return self 
     2070 
     2071    def __init__(self, *a, **ka): 
     2072        self._meta = {} 
     2073        self._on_change = lambda name, value: None 
     2074        if a or ka: 
     2075            depr('Constructor does no longer accept parameters.') #0.12 
     2076            self.update(*a, **ka) 
     2077 
     2078    def load_config(self, filename): 
     2079        ''' Load values from an *.ini style config file. 
     2080 
     2081            If the config file contains sections, their names are used as 
     2082            namespaces for the values within. The two special sections 
     2083            ``DEFAULT`` and ``bottle`` refer to the root namespace (no prefix). 
     2084        ''' 
     2085        conf = ConfigParser() 
     2086        conf.read(filename) 
     2087        for section in conf.sections(): 
     2088            for key, value in conf.items(section): 
     2089                if section not in ('DEFAULT', 'bottle'): 
     2090                    key = section + '.' + key 
     2091                self[key] = value 
     2092        return self 
     2093 
     2094    def load_dict(self, source, namespace='', make_namespaces=False): 
     2095        ''' Import values from a dictionary structure. Nesting can be used to 
     2096            represent namespaces. 
     2097             
     2098            >>> ConfigDict().load_dict({'name': {'space': {'key': 'value'}}}) 
     2099            {'name.space.key': 'value'} 
     2100        ''' 
     2101        stack = [(namespace, source)] 
     2102        while stack: 
     2103            prefix, source = stack.pop() 
     2104            if not isinstance(source, dict): 
     2105                raise TypeError('Source is not a dict (r)' % type(key)) 
     2106            for key, value in source.items(): 
     2107                if not isinstance(key, str): 
     2108                    raise TypeError('Key is not a string (%r)' % type(key)) 
     2109                full_key = prefix + '.' + key if prefix else key 
     2110                if isinstance(value, dict): 
     2111                    stack.append((full_key, value)) 
     2112                    if make_namespaces: 
     2113                        self[full_key] = self.Namespace(self, full_key) 
     2114                else: 
     2115                    self[full_key] = value 
     2116        return self 
     2117 
     2118    def update(self, *a, **ka): 
     2119        ''' If the first parameter is a string, all keys are prefixed with this 
     2120            namespace. Apart from that it works just as the usual dict.update(). 
     2121            Example: ``update('some.namespace', key='value')`` ''' 
     2122        prefix = '' 
     2123        if a and isinstance(a[0], str): 
     2124            prefix = a[0].strip('.') + '.' 
     2125            a = a[1:] 
     2126        for key, value in dict(*a, **ka).items(): 
     2127            self[prefix+key] = value 
     2128 
     2129    def setdefault(self, key, value): 
     2130        if key not in self: 
     2131            self[key] = value 
     2132        return self[key] 
     2133 
     2134    def __setitem__(self, key, value): 
     2135        if not isinstance(key, str): 
     2136            raise TypeError('Key has type %r (not a string)' % type(key)) 
     2137 
     2138        value = self.meta_get(key, 'filter', lambda x: x)(value) 
     2139        if key in self and self[key] is value: 
     2140            return 
     2141        self._on_change(key, value) 
     2142        dict.__setitem__(self, key, value) 
     2143 
     2144    def __delitem__(self, key): 
     2145        dict.__delitem__(self, key) 
     2146 
     2147    def clear(self): 
     2148        for key in self: 
     2149            del self[key] 
     2150 
     2151    def meta_get(self, key, metafield, default=None): 
     2152        ''' Return the value of a meta field for a key. ''' 
     2153        return self._meta.get(key, {}).get(metafield, default) 
     2154 
     2155    def meta_set(self, key, metafield, value): 
     2156        ''' Set the meta field for a key to a new value. This triggers the 
     2157            on-change handler for existing keys. ''' 
     2158        self._meta.setdefault(key, {})[metafield] = value 
     2159        if key in self: 
     2160            self[key] = self[key] 
     2161 
     2162    def meta_list(self, key): 
     2163        ''' Return an iterable of meta field names defined for a key. ''' 
     2164        return self._meta.get(key, {}).keys() 
     2165 
     2166    # Deprecated ConfigDict features 
    18912167    def __getattr__(self, key): 
     2168        depr('Attribute access is deprecated.') #0.12 
    18922169        if key not in self and key[0].isupper(): 
    1893             self[key] = ConfigDict() 
     2170            self[key] = self.Namespace(self, key) 
     2171        if key not in self and key.startswith('__'): 
     2172            raise AttributeError(key) 
    18942173        return self.get(key) 
    18952174 
    18962175    def __setattr__(self, key, value): 
     2176        if key in self.__slots__: 
     2177            return dict.__setattr__(self, key, value) 
     2178        depr('Attribute assignment is deprecated.') #0.12 
    18972179        if hasattr(dict, key): 
    18982180            raise AttributeError('Read-only attribute.') 
    1899         if key in self and self[key] and isinstance(self[key], ConfigDict): 
     2181        if key in self and self[key] and isinstance(self[key], self.Namespace): 
    19002182            raise AttributeError('Non-empty namespace attribute.') 
    19012183        self[key] = value 
    19022184 
    19032185    def __delattr__(self, key): 
    1904         if key in self: del self[key] 
     2186        if key in self: 
     2187            val = self.pop(key) 
     2188            if isinstance(val, self.Namespace): 
     2189                prefix = key + '.' 
     2190                for key in self: 
     2191                    if key.startswith(prefix): 
     2192                        del self[prefix+key] 
    19052193 
    19062194    def __call__(self, *a, **ka): 
    1907         for key, value in dict(*a, **ka).items(): setattr(self, key, value) 
     2195        depr('Calling ConfDict is deprecated. Use the update() method.') #0.12 
     2196        self.update(*a, **ka) 
    19082197        return self 
     2198 
    19092199 
    19102200 
     
    19372227            if not part: return 
    19382228            yield part 
     2229 
     2230 
     2231class _closeiter(object): 
     2232    ''' This only exists to be able to attach a .close method to iterators that 
     2233        do not support attribute assignment (most of itertools). ''' 
     2234 
     2235    def __init__(self, iterator, close=None): 
     2236        self.iterator = iterator 
     2237        self.close_callbacks = makelist(close) 
     2238 
     2239    def __iter__(self): 
     2240        return iter(self.iterator) 
     2241 
     2242    def close(self): 
     2243        for func in self.close_callbacks: 
     2244            func() 
    19392245 
    19402246 
     
    20222328        fname = self.lookup(name) 
    20232329        if not fname: raise IOError("Resource %r not found." % name) 
    2024         return self.opener(name, mode=mode, *args, **kwargs) 
     2330        return self.opener(fname, mode=mode, *args, **kwargs) 
     2331 
     2332 
     2333class FileUpload(object): 
     2334 
     2335    def __init__(self, fileobj, name, filename, headers=None): 
     2336        ''' Wrapper for file uploads. ''' 
     2337        #: Open file(-like) object (BytesIO buffer or temporary file) 
     2338        self.file = fileobj 
     2339        #: Name of the upload form field 
     2340        self.name = name 
     2341        #: Raw filename as sent by the client (may contain unsafe characters) 
     2342        self.raw_filename = filename 
     2343        #: A :class:`HeaderDict` with additional headers (e.g. content-type) 
     2344        self.headers = HeaderDict(headers) if headers else HeaderDict() 
     2345 
     2346    content_type = HeaderProperty('Content-Type') 
     2347    content_length = HeaderProperty('Content-Length', reader=int, default=-1) 
     2348 
     2349    @cached_property 
     2350    def filename(self): 
     2351        ''' Name of the file on the client file system, but normalized to ensure 
     2352            file system compatibility. An empty filename is returned as 'empty'. 
     2353             
     2354            Only ASCII letters, digits, dashes, underscores and dots are 
     2355            allowed in the final filename. Accents are removed, if possible. 
     2356            Whitespace is replaced by a single dash. Leading or tailing dots 
     2357            or dashes are removed. The filename is limited to 255 characters. 
     2358        ''' 
     2359        fname = self.raw_filename 
     2360        if not isinstance(fname, unicode): 
     2361            fname = fname.decode('utf8', 'ignore') 
     2362        fname = normalize('NFKD', fname).encode('ASCII', 'ignore').decode('ASCII') 
     2363        fname = os.path.basename(fname.replace('\\', os.path.sep)) 
     2364        fname = re.sub(r'[^a-zA-Z0-9-_.\s]', '', fname).strip() 
     2365        fname = re.sub(r'[-\s]+', '-', fname).strip('.-') 
     2366        return fname[:255] or 'empty' 
     2367 
     2368    def _copy_file(self, fp, chunk_size=2**16): 
     2369        read, write, offset = self.file.read, fp.write, self.file.tell() 
     2370        while 1: 
     2371            buf = read(chunk_size) 
     2372            if not buf: break 
     2373            write(buf) 
     2374        self.file.seek(offset) 
     2375 
     2376    def save(self, destination, overwrite=False, chunk_size=2**16): 
     2377        ''' Save file to disk or copy its content to an open file(-like) object. 
     2378            If *destination* is a directory, :attr:`filename` is added to the 
     2379            path. Existing files are not overwritten by default (IOError). 
     2380 
     2381            :param destination: File path, directory or file(-like) object. 
     2382            :param overwrite: If True, replace existing files. (default: False) 
     2383            :param chunk_size: Bytes to read at a time. (default: 64kb) 
     2384        ''' 
     2385        if isinstance(destination, basestring): # Except file-likes here 
     2386            if os.path.isdir(destination): 
     2387                destination = os.path.join(destination, self.filename) 
     2388            if not overwrite and os.path.exists(destination): 
     2389                raise IOError('File exists.') 
     2390            with open(destination, 'wb') as fp: 
     2391                self._copy_file(fp, chunk_size) 
     2392        else: 
     2393            self._copy_file(destination, chunk_size) 
    20252394 
    20262395 
     
    20342403 
    20352404 
    2036 def abort(code=500, text='Unknown Error: Application stopped.'): 
     2405def abort(code=500, text='Unknown Error.'): 
    20372406    """ Aborts execution and causes a HTTP error. """ 
    20382407    raise HTTPError(code, text) 
     
    20422411    """ Aborts execution and causes a 303 or 302 redirect, depending on 
    20432412        the HTTP protocol version. """ 
    2044     if code is None: 
     2413    if not code: 
    20452414        code = 303 if request.get('SERVER_PROTOCOL') == "HTTP/1.1" else 302 
    2046     location = urljoin(request.url, url) 
    2047     res = HTTPResponse("", status=code, Location=location) 
    2048     if response._cookies: 
    2049         res._cookies = response._cookies 
     2415    res = response.copy(cls=HTTPResponse) 
     2416    res.status = code 
     2417    res.body = "" 
     2418    res.set_header('Location', urljoin(request.url, url)) 
    20502419    raise res 
    20512420 
     
    20612430 
    20622431 
    2063 def static_file(filename, root, mimetype='auto', download=False): 
     2432def static_file(filename, root, mimetype='auto', download=False, charset='UTF-8'): 
    20642433    """ Open a file in a safe way and return :exc:`HTTPResponse` with status 
    2065         code 200, 305, 401 or 404. Set Content-Type, Content-Encoding, 
    2066         Content-Length and Last-Modified header. Obey If-Modified-Since header 
    2067         and HEAD requests. 
     2434        code 200, 305, 403 or 404. The ``Content-Type``, ``Content-Encoding``, 
     2435        ``Content-Length`` and ``Last-Modified`` headers are set if possible. 
     2436        Special support for ``If-Modified-Since``, ``Range`` and ``HEAD`` 
     2437        requests. 
     2438 
     2439        :param filename: Name or path of the file to send. 
     2440        :param root: Root path for file lookups. Should be an absolute directory 
     2441            path. 
     2442        :param mimetype: Defines the content-type header (default: guess from 
     2443            file extension) 
     2444        :param download: If True, ask the browser to open a `Save as...` dialog 
     2445            instead of opening the file with the associated program. You can 
     2446            specify a custom filename as a string. If not specified, the 
     2447            original filename is used (default: False). 
     2448        :param charset: The charset to use for files with a ``text/*`` 
     2449            mime-type. (default: UTF-8) 
    20682450    """ 
     2451 
    20692452    root = os.path.abspath(root) + os.sep 
    20702453    filename = os.path.abspath(os.path.join(root, filename.strip('/\\'))) 
     
    20802463    if mimetype == 'auto': 
    20812464        mimetype, encoding = mimetypes.guess_type(filename) 
    2082         if mimetype: headers['Content-Type'] = mimetype 
    20832465        if encoding: headers['Content-Encoding'] = encoding 
    2084     elif mimetype: 
     2466 
     2467    if mimetype: 
     2468        if mimetype[:5] == 'text/' and charset and 'charset' not in mimetype: 
     2469            mimetype += '; charset=%s' % charset 
    20852470        headers['Content-Type'] = mimetype 
    20862471 
     
    21302515    There is only one debug level supported at the moment.""" 
    21312516    global DEBUG 
     2517    if mode: warnings.simplefilter('default') 
    21322518    DEBUG = bool(mode) 
    21332519 
     2520def http_date(value): 
     2521    if isinstance(value, (datedate, datetime)): 
     2522        value = value.utctimetuple() 
     2523    elif isinstance(value, (int, float)): 
     2524        value = time.gmtime(value) 
     2525    if not isinstance(value, basestring): 
     2526        value = time.strftime("%a, %d %b %Y %H:%M:%S GMT", value) 
     2527    return value 
    21342528 
    21352529def parse_date(ims): 
     
    21402534    except (TypeError, ValueError, IndexError, OverflowError): 
    21412535        return None 
    2142  
    21432536 
    21442537def parse_auth(header): 
     
    22172610def html_quote(string): 
    22182611    ''' Escape and quote a string to be used as an HTTP attribute.''' 
    2219     return '"%s"' % html_escape(string).replace('\n','%#10;')\ 
     2612    return '"%s"' % html_escape(string).replace('\n','&#10;')\ 
    22202613                    .replace('\r','&#13;').replace('\t','&#9;') 
    22212614 
     
    22272620 
    22282621        a()         -> '/a' 
    2229         b(x, y)     -> '/b/:x/:y' 
    2230         c(x, y=5)   -> '/c/:x' and '/c/:x/:y' 
    2231         d(x=5, y=6) -> '/d' and '/d/:x' and '/d/:x/:y' 
     2622        b(x, y)     -> '/b/<x>/<y>' 
     2623        c(x, y=5)   -> '/c/<x>' and '/c/<x>/<y>' 
     2624        d(x=5, y=6) -> '/d' and '/d/<x>' and '/d/<x>/<y>' 
    22322625    """ 
    2233     import inspect # Expensive module. Only import if necessary. 
    22342626    path = '/' + func.__name__.replace('__','/').lstrip('/') 
    2235     spec = inspect.getargspec(func) 
     2627    spec = getargspec(func) 
    22362628    argc = len(spec[0]) - len(spec[3] or []) 
    2237     path += ('/:%s' * argc) % tuple(spec[0][:argc]) 
     2629    path += ('/<%s>' * argc) % tuple(spec[0][:argc]) 
    22382630    yield path 
    22392631    for arg in spec[0][argc:]: 
    2240         path += '/:%s' % arg 
     2632        path += '/<%s>' % arg 
    22412633        yield path 
    22422634 
     
    22732665 
    22742666 
    2275 def validate(**vkargs): 
    2276     """ 
    2277     Validates and manipulates keyword arguments by user defined callables. 
    2278     Handles ValueError and missing arguments by raising HTTPError(403). 
    2279     """ 
    2280     depr('Use route wildcard filters instead.') 
    2281     def decorator(func): 
    2282         @functools.wraps(func) 
    2283         def wrapper(*args, **kargs): 
    2284             for key, value in vkargs.items(): 
    2285                 if key not in kargs: 
    2286                     abort(403, 'Missing parameter: %s' % key) 
    2287                 try: 
    2288                     kargs[key] = value(kargs[key]) 
    2289                 except ValueError: 
    2290                     abort(403, 'Wrong parameter format for: %s' % key) 
    2291             return func(*args, **kargs) 
    2292         return wrapper 
    2293     return decorator 
    2294  
    2295  
    22962667def auth_basic(check, realm="private", text="Access denied"): 
    22972668    ''' Callback decorator to require HTTP auth (basic). 
    22982669        TODO: Add route(check_auth=...) parameter. ''' 
    22992670    def decorator(func): 
    2300       def wrapper(*a, **ka): 
    2301         user, password = request.auth or (None, None) 
    2302         if user is None or not check(user, password): 
    2303           response.headers['WWW-Authenticate'] = 'Basic realm="%s"' % realm 
    2304           return HTTPError(401, text) 
    2305         return func(*a, **ka) 
    2306       return wrapper 
     2671        def wrapper(*a, **ka): 
     2672            user, password = request.auth or (None, None) 
     2673            if user is None or not check(user, password): 
     2674                err = HTTPError(401, text) 
     2675                err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm) 
     2676                return err 
     2677            return func(*a, **ka) 
     2678        return wrapper 
    23072679    return decorator 
    23082680 
     
    23432715class ServerAdapter(object): 
    23442716    quiet = False 
    2345     def __init__(self, host='127.0.0.1', port=8080, **config): 
    2346         self.options = config 
     2717    def __init__(self, host='127.0.0.1', port=8080, **options): 
     2718        self.options = options 
    23472719        self.host = host 
    23482720        self.port = int(port) 
     
    23742746 
    23752747class WSGIRefServer(ServerAdapter): 
    2376     def run(self, handler): # pragma: no cover 
    2377         from wsgiref.simple_server import make_server, WSGIRequestHandler 
    2378         if self.quiet: 
    2379             class QuietHandler(WSGIRequestHandler): 
    2380                 def log_request(*args, **kw): pass 
    2381             self.options['handler_class'] = QuietHandler 
    2382         srv = make_server(self.host, self.port, handler, **self.options) 
     2748    def run(self, app): # pragma: no cover 
     2749        from wsgiref.simple_server import WSGIRequestHandler, WSGIServer 
     2750        from wsgiref.simple_server import make_server 
     2751        import socket 
     2752 
     2753        class FixedHandler(WSGIRequestHandler): 
     2754            def address_string(self): # Prevent reverse DNS lookups please. 
     2755                return self.client_address[0] 
     2756            def log_request(*args, **kw): 
     2757                if not self.quiet: 
     2758                    return WSGIRequestHandler.log_request(*args, **kw) 
     2759 
     2760        handler_cls = self.options.get('handler_class', FixedHandler) 
     2761        server_cls  = self.options.get('server_class', WSGIServer) 
     2762 
     2763        if ':' in self.host: # Fix wsgiref for IPv6 addresses. 
     2764            if getattr(server_cls, 'address_family') == socket.AF_INET: 
     2765                class server_cls(server_cls): 
     2766                    address_family = socket.AF_INET6 
     2767 
     2768        srv = make_server(self.host, self.port, app, server_cls, handler_cls) 
    23832769        srv.serve_forever() 
    23842770 
     
    23872773    def run(self, handler): # pragma: no cover 
    23882774        from cherrypy import wsgiserver 
    2389         server = wsgiserver.CherryPyWSGIServer((self.host, self.port), handler) 
     2775        self.options['bind_addr'] = (self.host, self.port) 
     2776        self.options['wsgi_app'] = handler 
     2777         
     2778        certfile = self.options.get('certfile') 
     2779        if certfile: 
     2780            del self.options['certfile'] 
     2781        keyfile = self.options.get('keyfile') 
     2782        if keyfile: 
     2783            del self.options['keyfile'] 
     2784         
     2785        server = wsgiserver.CherryPyWSGIServer(**self.options) 
     2786        if certfile: 
     2787            server.ssl_certificate = certfile 
     2788        if keyfile: 
     2789            server.ssl_private_key = keyfile 
     2790         
    23902791        try: 
    23912792            server.start() 
     
    24032804    def run(self, handler): # pragma: no cover 
    24042805        from paste import httpserver 
    2405         if not self.quiet: 
    2406             from paste.translogger import TransLogger 
    2407             handler = TransLogger(handler) 
     2806        from paste.translogger import TransLogger 
     2807        handler = TransLogger(handler, setup_console_handler=(not self.quiet)) 
    24082808        httpserver.serve(handler, host=self.host, port=str(self.port), 
    24092809                         **self.options) 
     
    24452845        container = tornado.wsgi.WSGIContainer(handler) 
    24462846        server = tornado.httpserver.HTTPServer(container) 
    2447         server.listen(port=self.port) 
     2847        server.listen(port=self.port,address=self.host) 
    24482848        tornado.ioloop.IOLoop.instance().start() 
    24492849 
     
    24892889        * `fast` (default: False) uses libevent's http server, but has some 
    24902890          issues: No streaming, no pipelining, no SSL. 
     2891        * See gevent.wsgi.WSGIServer() documentation for more options. 
    24912892    """ 
    24922893    def run(self, handler): 
    24932894        from gevent import wsgi, pywsgi, local 
    2494         if not isinstance(_lctx, local.local): 
     2895        if not isinstance(threading.local(), local.local): 
    24952896            msg = "Bottle requires gevent.monkey.patch_all() (before import)" 
    24962897            raise RuntimeError(msg) 
    2497         if not self.options.get('fast'): wsgi = pywsgi 
    2498         log = None if self.quiet else 'default' 
    2499         wsgi.WSGIServer((self.host, self.port), handler, log=log).serve_forever() 
     2898        if not self.options.pop('fast', None): wsgi = pywsgi 
     2899        self.options['log'] = None if self.quiet else 'default' 
     2900        address = (self.host, self.port) 
     2901        server = wsgi.WSGIServer(address, handler, **self.options) 
     2902        if 'BOTTLE_CHILD' in os.environ: 
     2903            import signal 
     2904            signal.signal(signal.SIGINT, lambda s, f: server.stop()) 
     2905        server.serve_forever() 
     2906 
     2907 
     2908class GeventSocketIOServer(ServerAdapter): 
     2909    def run(self,handler): 
     2910        from socketio import server 
     2911        address = (self.host, self.port) 
     2912        server.SocketIOServer(address, handler, **self.options).serve_forever() 
    25002913 
    25012914 
     
    25712984    'eventlet': EventletServer, 
    25722985    'gevent': GeventServer, 
     2986    'geventSocketIO':GeventSocketIOServer, 
    25732987    'rocket': RocketServer, 
    25742988    'bjoern' : BjoernServer, 
     
    26223036def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, 
    26233037        interval=1, reloader=False, quiet=False, plugins=None, 
    2624         debug=False, **kargs): 
     3038        debug=None, **kargs): 
    26253039    """ Start a server instance. This method blocks until the server terminates. 
    26263040 
     
    26653079 
    26663080    try: 
    2667         _debug(debug) 
     3081        if debug is not None: _debug(debug) 
    26683082        app = app or default_app() 
    26693083        if isinstance(app, basestring): 
     
    28033217        First without, then with common extensions. Return first hit. """ 
    28043218        if not lookup: 
    2805             depr('The template lookup path list should not be empty.') 
     3219            depr('The template lookup path list should not be empty.') #0.12 
    28063220            lookup = ['.'] 
    28073221 
    28083222        if os.path.isabs(name) and os.path.isfile(name): 
    2809             depr('Absolute template path names are deprecated.') 
     3223            depr('Absolute template path names are deprecated.') #0.12 
    28103224            return os.path.abspath(name) 
    28113225 
     
    28393253        a single byte or unicode string. If it is a byte string, the encoding 
    28403254        must match self.encoding. This method must be thread-safe! 
    2841         Local variables may be provided in dictionaries (*args) 
    2842         or directly, as keywords (**kwargs). 
     3255        Local variables may be provided in dictionaries (args) 
     3256        or directly, as keywords (kwargs). 
    28433257        """ 
    28443258        raise NotImplementedError 
     
    28853299 
    28863300class Jinja2Template(BaseTemplate): 
    2887     def prepare(self, filters=None, tests=None, **kwargs): 
     3301    def prepare(self, filters=None, tests=None, globals={}, **kwargs): 
    28883302        from jinja2 import Environment, FunctionLoader 
    28893303        if 'prefix' in kwargs: # TODO: to be removed after a while 
     
    28933307        if filters: self.env.filters.update(filters) 
    28943308        if tests: self.env.tests.update(tests) 
     3309        if globals: self.env.globals.update(globals) 
    28953310        if self.source: 
    28963311            self.tpl = self.env.from_string(self.source) 
     
    29113326 
    29123327 
    2913 class SimpleTALTemplate(BaseTemplate): 
    2914     ''' Deprecated, do not use. ''' 
    2915     def prepare(self, **options): 
    2916         depr('The SimpleTAL template handler is deprecated'\ 
    2917              ' and will be removed in 0.12') 
    2918         from simpletal import simpleTAL 
    2919         if self.source: 
    2920             self.tpl = simpleTAL.compileHTMLTemplate(self.source) 
    2921         else: 
    2922             with open(self.filename, 'rb') as fp: 
    2923                 self.tpl = simpleTAL.compileHTMLTemplate(tonat(fp.read())) 
    2924  
    2925     def render(self, *args, **kwargs): 
    2926         from simpletal import simpleTALES 
    2927         for dictarg in args: kwargs.update(dictarg) 
    2928         context = simpleTALES.Context() 
    2929         for k,v in self.defaults.items(): 
    2930             context.addGlobal(k, v) 
    2931         for k,v in kwargs.items(): 
    2932             context.addGlobal(k, v) 
    2933         output = StringIO() 
    2934         self.tpl.expand(context, output) 
    2935         return output.getvalue() 
    2936  
    2937  
    29383328class SimpleTemplate(BaseTemplate): 
    2939     blocks = ('if', 'elif', 'else', 'try', 'except', 'finally', 'for', 'while', 
    2940               'with', 'def', 'class') 
    2941     dedent_blocks = ('elif', 'else', 'except', 'finally') 
    2942  
    2943     @lazy_attribute 
    2944     def re_pytokens(cls): 
    2945         ''' This matches comments and all kinds of quoted strings but does 
    2946             NOT match comments (#...) within quoted strings. (trust me) ''' 
    2947         return re.compile(r''' 
    2948             (''(?!')|""(?!")|'{6}|"{6}    # Empty strings (all 4 types) 
    2949              |'(?:[^\\']|\\.)+?'          # Single quotes (') 
    2950              |"(?:[^\\"]|\\.)+?"          # Double quotes (") 
    2951              |'{3}(?:[^\\]|\\.|\n)+?'{3}  # Triple-quoted strings (') 
    2952              |"{3}(?:[^\\]|\\.|\n)+?"{3}  # Triple-quoted strings (") 
    2953              |\#.*                        # Comments 
    2954             )''', re.VERBOSE) 
    2955  
    2956     def prepare(self, escape_func=html_escape, noescape=False, **kwargs): 
     3329 
     3330    def prepare(self, escape_func=html_escape, noescape=False, syntax=None, **ka): 
    29573331        self.cache = {} 
    29583332        enc = self.encoding 
    29593333        self._str = lambda x: touni(x, enc) 
    29603334        self._escape = lambda x: escape_func(touni(x, enc)) 
     3335        self.syntax = syntax 
    29613336        if noescape: 
    29623337            self._str, self._escape = self._escape, self._str 
    2963  
    2964     @classmethod 
    2965     def split_comment(cls, code): 
    2966         """ Removes comments (#...) from python code. """ 
    2967         if '#' not in code: return code 
    2968         #: Remove comments only (leave quoted strings as they are) 
    2969         subf = lambda m: '' if m.group(0)[0]=='#' else m.group(0) 
    2970         return re.sub(cls.re_pytokens, subf, code) 
    29713338 
    29723339    @cached_property 
     
    29763343    @cached_property 
    29773344    def code(self): 
    2978         stack = [] # Current Code indentation 
    2979         lineno = 0 # Current line of code 
    2980         ptrbuffer = [] # Buffer for printable strings and token tuple instances 
    2981         codebuffer = [] # Buffer for generated python code 
    2982         multiline = dedent = oneline = False 
    2983         template = self.source or open(self.filename, 'rb').read() 
    2984  
    2985         def yield_tokens(line): 
    2986             for i, part in enumerate(re.split(r'\{\{(.*?)\}\}', line)): 
    2987                 if i % 2: 
    2988                     if part.startswith('!'): yield 'RAW', part[1:] 
    2989                     else: yield 'CMD', part 
    2990                 else: yield 'TXT', part 
    2991  
    2992         def flush(): # Flush the ptrbuffer 
    2993             if not ptrbuffer: return 
    2994             cline = '' 
    2995             for line in ptrbuffer: 
    2996                 for token, value in line: 
    2997                     if token == 'TXT': cline += repr(value) 
    2998                     elif token == 'RAW': cline += '_str(%s)' % value 
    2999                     elif token == 'CMD': cline += '_escape(%s)' % value 
    3000                     cline +=  ', ' 
    3001                 cline = cline[:-2] + '\\\n' 
    3002             cline = cline[:-2] 
    3003             if cline[:-1].endswith('\\\\\\\\\\n'): 
    3004                 cline = cline[:-7] + cline[-1] # 'nobr\\\\\n' --> 'nobr' 
    3005             cline = '_printlist([' + cline + '])' 
    3006             del ptrbuffer[:] # Do this before calling code() again 
    3007             code(cline) 
    3008  
    3009         def code(stmt): 
    3010             for line in stmt.splitlines(): 
    3011                 codebuffer.append('  ' * len(stack) + line.strip()) 
    3012  
    3013         for line in template.splitlines(True): 
    3014             lineno += 1 
    3015             line = touni(line, self.encoding) 
    3016             sline = line.lstrip() 
    3017             if lineno <= 2: 
    3018                 m = re.match(r"%\s*#.*coding[:=]\s*([-\w.]+)", sline) 
    3019                 if m: self.encoding = m.group(1) 
    3020                 if m: line = line.replace('coding','coding (removed)') 
    3021             if sline and sline[0] == '%' and sline[:2] != '%%': 
    3022                 line = line.split('%',1)[1].lstrip() # Full line following the % 
    3023                 cline = self.split_comment(line).strip() 
    3024                 cmd = re.split(r'[^a-zA-Z0-9_]', cline)[0] 
    3025                 flush() # You are actually reading this? Good luck, it's a mess :) 
    3026                 if cmd in self.blocks or multiline: 
    3027                     cmd = multiline or cmd 
    3028                     dedent = cmd in self.dedent_blocks # "else:" 
    3029                     if dedent and not oneline and not multiline: 
    3030                         cmd = stack.pop() 
    3031                     code(line) 
    3032                     oneline = not cline.endswith(':') # "if 1: pass" 
    3033                     multiline = cmd if cline.endswith('\\') else False 
    3034                     if not oneline and not multiline: 
    3035                         stack.append(cmd) 
    3036                 elif cmd == 'end' and stack: 
    3037                     code('#end(%s) %s' % (stack.pop(), line.strip()[3:])) 
    3038                 elif cmd == 'include': 
    3039                     p = cline.split(None, 2)[1:] 
    3040                     if len(p) == 2: 
    3041                         code("_=_include(%s, _stdout, %s)" % (repr(p[0]), p[1])) 
    3042                     elif p: 
    3043                         code("_=_include(%s, _stdout)" % repr(p[0])) 
    3044                     else: # Empty %include -> reverse of %rebase 
    3045                         code("_printlist(_base)") 
    3046                 elif cmd == 'rebase': 
    3047                     p = cline.split(None, 2)[1:] 
    3048                     if len(p) == 2: 
    3049                         code("globals()['_rebase']=(%s, dict(%s))" % (repr(p[0]), p[1])) 
    3050                     elif p: 
    3051                         code("globals()['_rebase']=(%s, {})" % repr(p[0])) 
    3052                 else: 
    3053                     code(line) 
    3054             else: # Line starting with text (not '%') or '%%' (escaped) 
    3055                 if line.strip().startswith('%%'): 
    3056                     line = line.replace('%%', '%', 1) 
    3057                 ptrbuffer.append(yield_tokens(line)) 
    3058         flush() 
    3059         return '\n'.join(codebuffer) + '\n' 
    3060  
    3061     def subtemplate(self, _name, _stdout, *args, **kwargs): 
    3062         for dictarg in args: kwargs.update(dictarg) 
     3345        source = self.source 
     3346        if not source: 
     3347            with open(self.filename, 'rb') as f: 
     3348                source = f.read() 
     3349        try: 
     3350            source, encoding = touni(source), 'utf8' 
     3351        except UnicodeError: 
     3352            depr('Template encodings other than utf8 are no longer supported.') #0.11 
     3353            source, encoding = touni(source, 'latin1'), 'latin1' 
     3354        parser = StplParser(source, encoding=encoding, syntax=self.syntax) 
     3355        code = parser.translate() 
     3356        self.encoding = parser.encoding 
     3357        return code 
     3358 
     3359    def _rebase(self, _env, _name=None, **kwargs): 
     3360        if _name is None: 
     3361            depr('Rebase function called without arguments.' 
     3362                 ' You were probably looking for {{base}}?', True) #0.12 
     3363        _env['_rebase'] = (_name, kwargs) 
     3364 
     3365    def _include(self, _env, _name=None, **kwargs): 
     3366        if _name is None: 
     3367            depr('Rebase function called without arguments.' 
     3368                 ' You were probably looking for {{base}}?', True) #0.12 
     3369        env = _env.copy() 
     3370        env.update(kwargs) 
    30633371        if _name not in self.cache: 
    30643372            self.cache[_name] = self.__class__(name=_name, lookup=self.lookup) 
    3065         return self.cache[_name].execute(_stdout, kwargs) 
    3066  
    3067     def execute(self, _stdout, *args, **kwargs): 
    3068         for dictarg in args: kwargs.update(dictarg) 
     3373        return self.cache[_name].execute(env['_stdout'], env) 
     3374 
     3375    def execute(self, _stdout, kwargs): 
    30693376        env = self.defaults.copy() 
     3377        env.update(kwargs) 
    30703378        env.update({'_stdout': _stdout, '_printlist': _stdout.extend, 
    3071                '_include': self.subtemplate, '_str': self._str, 
    3072                '_escape': self._escape, 'get': env.get, 
    3073                'setdefault': env.setdefault, 'defined': env.__contains__}) 
    3074         env.update(kwargs) 
     3379            'include': functools.partial(self._include, env), 
     3380            'rebase': functools.partial(self._rebase, env), '_rebase': None, 
     3381            '_str': self._str, '_escape': self._escape, 'get': env.get, 
     3382            'setdefault': env.setdefault, 'defined': env.__contains__ }) 
    30753383        eval(self.co, env) 
    3076         if '_rebase' in env: 
    3077             subtpl, rargs = env['_rebase'] 
    3078             rargs['_base'] = _stdout[:] #copy stdout 
     3384        if env.get('_rebase'): 
     3385            subtpl, rargs = env.pop('_rebase') 
     3386            rargs['base'] = ''.join(_stdout) #copy stdout 
    30793387            del _stdout[:] # clear stdout 
    3080             return self.subtemplate(subtpl,_stdout,rargs) 
     3388            return self._include(env, subtpl, **rargs) 
    30813389        return env 
    30823390 
    30833391    def render(self, *args, **kwargs): 
    30843392        """ Render the template using keyword arguments as local variables. """ 
    3085         for dictarg in args: kwargs.update(dictarg) 
    3086         stdout = [] 
    3087         self.execute(stdout, kwargs) 
     3393        env = {}; stdout = [] 
     3394        for dictarg in args: env.update(dictarg) 
     3395        env.update(kwargs) 
     3396        self.execute(stdout, env) 
    30883397        return ''.join(stdout) 
     3398 
     3399 
     3400class StplSyntaxError(TemplateError): pass 
     3401 
     3402 
     3403class StplParser(object): 
     3404    ''' Parser for stpl templates. ''' 
     3405    _re_cache = {} #: Cache for compiled re patterns 
     3406    # This huge pile of voodoo magic splits python code into 8 different tokens. 
     3407    # 1: All kinds of python strings (trust me, it works) 
     3408    _re_tok = '((?m)[urbURB]?(?:\'\'(?!\')|""(?!")|\'{6}|"{6}' \ 
     3409               '|\'(?:[^\\\\\']|\\\\.)+?\'|"(?:[^\\\\"]|\\\\.)+?"' \ 
     3410               '|\'{3}(?:[^\\\\]|\\\\.|\\n)+?\'{3}' \ 
     3411               '|"{3}(?:[^\\\\]|\\\\.|\\n)+?"{3}))' 
     3412    _re_inl = _re_tok.replace('|\\n','') # We re-use this string pattern later 
     3413    # 2: Comments (until end of line, but not the newline itself) 
     3414    _re_tok += '|(#.*)' 
     3415    # 3,4: Keywords that start or continue a python block (only start of line) 
     3416    _re_tok += '|^([ \\t]*(?:if|for|while|with|try|def|class)\\b)' \ 
     3417               '|^([ \\t]*(?:elif|else|except|finally)\\b)' 
     3418    # 5: Our special 'end' keyword (but only if it stands alone) 
     3419    _re_tok += '|((?:^|;)[ \\t]*end[ \\t]*(?=(?:%(block_close)s[ \\t]*)?\\r?$|;|#))' 
     3420    # 6: A customizable end-of-code-block template token (only end of line) 
     3421    _re_tok += '|(%(block_close)s[ \\t]*(?=$))' 
     3422    # 7: And finally, a single newline. The 8th token is 'everything else' 
     3423    _re_tok += '|(\\r?\\n)' 
     3424    # Match the start tokens of code areas in a template 
     3425    _re_split = '(?m)^[ \t]*(\\\\?)((%(line_start)s)|(%(block_start)s))(%%?)' 
     3426    # Match inline statements (may contain python strings) 
     3427    _re_inl = '%%(inline_start)s((?:%s|[^\'"\n]*?)+)%%(inline_end)s' % _re_inl 
     3428 
     3429    default_syntax = '<% %> % {{ }}' 
     3430 
     3431    def __init__(self, source, syntax=None, encoding='utf8'): 
     3432        self.source, self.encoding = touni(source, encoding), encoding 
     3433        self.set_syntax(syntax or self.default_syntax) 
     3434        self.code_buffer, self.text_buffer = [], [] 
     3435        self.lineno, self.offset = 1, 0 
     3436        self.indent, self.indent_mod = 0, 0 
     3437 
     3438    def get_syntax(self): 
     3439        ''' Tokens as a space separated string (default: <% %> % {{ }}) ''' 
     3440        return self._syntax 
     3441 
     3442    def set_syntax(self, syntax): 
     3443        self._syntax = syntax 
     3444        self._tokens = syntax.split() 
     3445        if not syntax in self._re_cache: 
     3446            names = 'block_start block_close line_start inline_start inline_end' 
     3447            etokens = map(re.escape, self._tokens) 
     3448            pattern_vars = dict(zip(names.split(), etokens)) 
     3449            patterns = (self._re_split, self._re_tok, self._re_inl) 
     3450            patterns = [re.compile(p%pattern_vars) for p in patterns] 
     3451            self._re_cache[syntax] = patterns 
     3452        self.re_split, self.re_tok, self.re_inl = self._re_cache[syntax] 
     3453 
     3454    syntax = property(get_syntax, set_syntax) 
     3455 
     3456    def translate(self): 
     3457        if self.offset: raise RuntimeError('Parser is a one time instance.') 
     3458        while True: 
     3459            m = self.re_split.search(self.source[self.offset:]) 
     3460            if m: 
     3461                text = self.source[self.offset:self.offset+m.start()] 
     3462                self.text_buffer.append(text) 
     3463                self.offset += m.end() 
     3464                if m.group(1): # New escape syntax 
     3465                    line, sep, _ = self.source[self.offset:].partition('\n') 
     3466                    self.text_buffer.append(m.group(2)+m.group(5)+line+sep) 
     3467                    self.offset += len(line+sep)+1 
     3468                    continue 
     3469                elif m.group(5): # Old escape syntax 
     3470                    depr('Escape code lines with a backslash.') #0.12 
     3471                    line, sep, _ = self.source[self.offset:].partition('\n') 
     3472                    self.text_buffer.append(m.group(2)+line+sep) 
     3473                    self.offset += len(line+sep)+1 
     3474                    continue 
     3475                self.flush_text() 
     3476                self.read_code(multiline=bool(m.group(4))) 
     3477            else: break 
     3478        self.text_buffer.append(self.source[self.offset:]) 
     3479        self.flush_text() 
     3480        return ''.join(self.code_buffer) 
     3481 
     3482    def read_code(self, multiline): 
     3483        code_line, comment = '', '' 
     3484        while True: 
     3485            m = self.re_tok.search(self.source[self.offset:]) 
     3486            if not m: 
     3487                code_line += self.source[self.offset:] 
     3488                self.offset = len(self.source) 
     3489                self.write_code(code_line.strip(), comment) 
     3490                return 
     3491            code_line += self.source[self.offset:self.offset+m.start()] 
     3492            self.offset += m.end() 
     3493            _str, _com, _blk1, _blk2, _end, _cend, _nl = m.groups() 
     3494            if code_line and (_blk1 or _blk2): # a if b else c 
     3495                code_line += _blk1 or _blk2 
     3496                continue 
     3497            if _str:    # Python string 
     3498                code_line += _str 
     3499            elif _com:  # Python comment (up to EOL) 
     3500                comment = _com 
     3501                if multiline and _com.strip().endswith(self._tokens[1]): 
     3502                    multiline = False # Allow end-of-block in comments 
     3503            elif _blk1: # Start-block keyword (if/for/while/def/try/...) 
     3504                code_line, self.indent_mod = _blk1, -1 
     3505                self.indent += 1 
     3506            elif _blk2: # Continue-block keyword (else/elif/except/...) 
     3507                code_line, self.indent_mod = _blk2, -1 
     3508            elif _end:  # The non-standard 'end'-keyword (ends a block) 
     3509                self.indent -= 1 
     3510            elif _cend: # The end-code-block template token (usually '%>') 
     3511                if multiline: multiline = False 
     3512                else: code_line += _cend 
     3513            else: # \n 
     3514                self.write_code(code_line.strip(), comment) 
     3515                self.lineno += 1 
     3516                code_line, comment, self.indent_mod = '', '', 0 
     3517                if not multiline: 
     3518                    break 
     3519 
     3520    def flush_text(self): 
     3521        text = ''.join(self.text_buffer) 
     3522        del self.text_buffer[:] 
     3523        if not text: return 
     3524        parts, pos, nl = [], 0, '\\\n'+'  '*self.indent 
     3525        for m in self.re_inl.finditer(text): 
     3526            prefix, pos = text[pos:m.start()], m.end() 
     3527            if prefix: 
     3528                parts.append(nl.join(map(repr, prefix.splitlines(True)))) 
     3529            if prefix.endswith('\n'): parts[-1] += nl 
     3530            parts.append(self.process_inline(m.group(1).strip())) 
     3531        if pos < len(text): 
     3532            prefix = text[pos:] 
     3533            lines = prefix.splitlines(True) 
     3534            if lines[-1].endswith('\\\\\n'): lines[-1] = lines[-1][:-3] 
     3535            elif lines[-1].endswith('\\\\\r\n'): lines[-1] = lines[-1][:-4] 
     3536            parts.append(nl.join(map(repr, lines))) 
     3537        code = '_printlist((%s,))' % ', '.join(parts) 
     3538        self.lineno += code.count('\n')+1 
     3539        self.write_code(code) 
     3540 
     3541    def process_inline(self, chunk): 
     3542        if chunk[0] == '!': return '_str(%s)' % chunk[1:] 
     3543        return '_escape(%s)' % chunk 
     3544 
     3545    def write_code(self, line, comment=''): 
     3546        line, comment = self.fix_backward_compatibility(line, comment) 
     3547        code  = '  ' * (self.indent+self.indent_mod) 
     3548        code += line.lstrip() + comment + '\n' 
     3549        self.code_buffer.append(code) 
     3550 
     3551    def fix_backward_compatibility(self, line, comment): 
     3552        parts = line.strip().split(None, 2) 
     3553        if parts and parts[0] in ('include', 'rebase'): 
     3554            depr('The include and rebase keywords are functions now.') #0.12 
     3555            if len(parts) == 1:   return "_printlist([base])", comment 
     3556            elif len(parts) == 2: return "_=%s(%r)" % tuple(parts), comment 
     3557            else:                 return "_=%s(%r, %s)" % tuple(parts), comment 
     3558        if self.lineno <= 2 and not line.strip() and 'coding' in comment: 
     3559            m = re.match(r"#.*coding[:=]\s*([-\w.]+)", comment) 
     3560            if m: 
     3561                depr('PEP263 encoding strings in templates are deprecated.') #0.12 
     3562                enc = m.group(1) 
     3563                self.source = self.source.encode(self.encoding).decode(enc) 
     3564                self.encoding = enc 
     3565                return line, comment.replace('coding','coding*') 
     3566        return line, comment 
    30893567 
    30903568 
     
    31173595cheetah_template = functools.partial(template, template_adapter=CheetahTemplate) 
    31183596jinja2_template = functools.partial(template, template_adapter=Jinja2Template) 
    3119 simpletal_template = functools.partial(template, template_adapter=SimpleTALTemplate) 
    31203597 
    31213598 
     
    31383615                tplvars.update(result) 
    31393616                return template(tpl_name, **tplvars) 
     3617            elif result is None: 
     3618                return template(tpl_name, defaults) 
    31403619            return result 
    31413620        return wrapper 
     
    31453624cheetah_view = functools.partial(view, template_adapter=CheetahTemplate) 
    31463625jinja2_view = functools.partial(view, template_adapter=Jinja2Template) 
    3147 simpletal_view = functools.partial(view, template_adapter=SimpleTALTemplate) 
    31483626 
    31493627 
     
    32423720 
    32433721    host, port = (opt.bind or 'localhost'), 8080 
    3244     if ':' in host: 
     3722    if ':' in host and host.rfind(']') < host.rfind(':'): 
    32453723        host, port = host.rsplit(':', 1) 
    3246  
    3247     run(args[0], host=host, port=port, server=opt.server, 
     3724    host = host.strip('[]') 
     3725 
     3726    run(args[0], host=host, port=int(port), server=opt.server, 
    32483727        reloader=opt.reload, plugins=opt.plugin, debug=opt.debug) 
    32493728 
  • map.py

    r659227a r9150aa4  
    288288@route('/tpl/popup.tpl') 
    289289def popup_template(lang): 
    290     return template('map/popup', mustache_delimiter="{{=<% %>=}}", website=utils.website) 
     290    return template('map/popup', mustache_delimiter="{{={% %}=}}", website=utils.website) 
    291291 
    292292@route('/tpl/editor.tpl') 
    293293def editor_template(lang): 
    294     return template('map/editor', mustache_delimiter="{{=<% %>=}}") 
     294    return template('map/editor', mustache_delimiter="{{={% %}=}}") 
  • osmose.wsgi

    rd57e859 rbeced85  
    1616import bottle 
    1717app = bottle.default_app() 
    18 app.plugins = filter(lambda x: isinstance(x,bottle.JSONPlugin) or isinstance(x,bottle.HooksPlugin) or isinstance(x,bottle.TemplatePlugin), app.plugins) 
     18app.plugins = filter(lambda x: isinstance(x,bottle.JSONPlugin) or isinstance(x,bottle.TemplatePlugin), app.plugins) 
    1919 
    2020import osmose 
  • views/404.tpl

    r95a622e rbbaed7d  
    1 %rebase layout title="Error: 404 Not Found" 
     1%rebase('layout.tpl', title="Error: 404 Not Found") 
    22<h1>Error: 404 Not Found</h1> 
    33<p>File does not exist.</p> 
    44<ul> 
    5 %import bottle, urllib, cgi 
    6 % routes = bottle.default_app().router.rules.keys() 
     5%import bottle, urllib 
     6% routes = [i[0] for i in bottle.default_app().router.dyna_routes["GET"]] 
     7% routes.extend(bottle.default_app().router.static["GET"]) 
    78% routes.sort() 
    89%for rule in routes: 
  • views/byuser/byuser-stats.tpl

    r300533f r32fbb9f  
    1 %rebase layout title=_("Users statistics") 
     1%rebase('layout.tpl', title=_("Users statistics")) 
    22<table> 
    33  <tr> 
  • views/byuser/byuser.tpl

    r370abfd r84f6b00  
    11%rss="http://"+website+"/byuser/"+username+".rss" 
    2 %rebase layout title=(_("Statistics for user %s") % ", ".join(users)), rss=rss 
     2%rebase('layout.tpl', title=(_("Statistics for user %s") % ", ".join(users)), rss=rss) 
    33<h1>{{_("User statistics for %s") % ", ".join(users)}}</h1> 
    44<p>{{_("This page shows errors on elements that were last modified by '%s'. This doesn't means that this user is responsible for all these errors.") % "', '".join(users)}}</p> 
     
    1414</p> 
    1515 
    16 %include views/errors/list.tpl errors=errors, gen="info", opt_date="-1", translate=translate 
     16%include("views/errors/list.tpl", errors=errors, gen="info", opt_date="-1", translate=translate) 
  • views/byuser/index.tpl

    r95a622e r32fbb9f  
    1 %rebase layout title=_("Statistics for user") 
     1%rebase('layout.tpl', title=_("Statistics for user")) 
    22<h1>{{_("User statistics")}}</h1> 
    33{{_("Osmose allows you to control your own errors.")}}<br> 
  • views/contact.tpl

    r5124c50 r32fbb9f  
    1 %rebase layout title=_("Contact") 
     1%rebase('layout.tpl', title=_("Contact")) 
    22<h1>{{_("Bug tracker")}}</h1> 
    33<p>{{! _("Bug should be reported on <a href='http://trac.openstreetmap.fr'>trac</a>. The component to pick should be osmose-frontend for issues around the website, and osmose-backend for issues on the reported errors, or for suggestion for new analyses.")}}</p> 
  • views/control/update.tpl

    r91dcf8c r32fbb9f  
    1 %rebase layout title=_("Update") 
     1%rebase('layout.tpl', title=_("Update")) 
    22<table> 
    33<tr> 
  • views/control/updates.tpl

    ra300c14 r32fbb9f  
    1 %rebase layout title=_("Last updates") 
     1%rebase('layout.tpl', title=_("Last updates")) 
    22<p>{{_("Median delay:")}} {{(liste[len(liste)/2][2]) if len(liste)>0 else ""}}</p> 
    33<table> 
  • views/control/updates_matrix.tpl

    r483e49e r32fbb9f  
    1 %rebase layout title=_("Last updates") 
     1%rebase('layout.tpl', title=_("Last updates")) 
    22%def col(t, v): 
    33%            if v > 4.05: 
  • views/copyright.tpl

    rcbe72ac r32fbb9f  
    1 %rebase layout title=_("Copyright informations") 
     1%rebase('layout.tpl', title=_("Copyright informations")) 
    22<h1>{{_("License")}}</h1> 
    33<p>This program is free software: you can redistribute it and/or modify 
  • views/error/index.tpl

    r300533f r32fbb9f  
    1 %rebase layout title=_("Information on error %d") % err_id, favicon="../images/markers/marker-l-%s.png" % marker['item'] 
     1%rebase('layout.tpl', title=_("Information on error %d") % err_id, favicon="../images/markers/marker-l-%s.png" % marker['item']) 
    22%def show_html_results(columns, res): 
    33<table class="sortable" id ="table_marker"> 
  • views/errors/index.tpl

    rf054b5c r84f6b00  
    77%end 
    88%rss="http://"+website+"/errors.rss?%s" % query 
    9 %rebase layout title=title, favicon=favicon, rss=rss 
     9%rebase('layout.tpl', title=title, favicon=favicon, rss=rss) 
    1010<a href=".?{{query}}">{{_("Informations")}}</a> 
    1111<a href="done?{{query}}">{{_("Fixed")}}</a> 
     
    7878%    if count == -1: 
    7979%        count = "N/A" 
    80 %    end: 
     80%    end 
    8181    <td><a href="?source={{res["source"]}}&amp;item={{res["item"]}}&amp;class={{res["class"]}}">{{count}}</a></td> 
    8282</tr> 
     
    9595%if errors: 
    9696%    str_more = _("Show more errors") 
    97 %    include views/errors/list.tpl errors=errors, gen=gen, opt_date=opt_date, translate=translate 
     97%    include("views/errors/list.tpl", errors=errors, gen=gen, opt_date=opt_date, translate=translate) 
    9898% 
    9999%    import urlparse, urllib 
  • views/false-positive/index.tpl

    r034ae3f r32fbb9f  
    1 %rebase layout title=_("Information on error %d") % err_id, favicon="../images/markers/marker-l-%s.png" % marker['item'] 
     1%rebase('layout.tpl', title=_("Information on error %d") % err_id, favicon="../images/markers/marker-l-%s.png" % marker['item']) 
    22%def show_html_results(columns, res): 
    33<table class="sortable" id ="table_marker"> 
  • views/index.tpl

    r95a622e r32fbb9f  
    1 %rebase layout title=_('OpenStreetMap Oversight Search Engine') 
     1%rebase('layout.tpl', title=_('OpenStreetMap Oversight Search Engine')) 
    22<h1>Osmose</h1> 
    33<ul> 
  • views/map/editor.tpl

    r3859df0 r9150aa4  
    22<h1>{{_("Tags Editor")}}</h1> 
    33<form> 
    4   <%#elems%> 
    5   <a target="_blank" href="http://www.openstreetmap.org/browse/<%type%>/<%id%>"><%type%> <%id%></a> 
    6   <div class="tags" data-type="<%type%>" data-id="<%id%>" data-version="<%version%>"> 
     4  {%#elems%} 
     5  <a target="_blank" href="http://www.openstreetmap.org/browse/{%type%}/{%id%}">{%type%} {%id%}</a> 
     6  <div class="tags" data-type="{%type%}" data-id="{%id%}" data-version="{%version%}"> 
    77    <div class="del"> 
    88    </div> 
     
    1414    </div> 
    1515  </div> 
    16   <%/elems%> 
     16  {%/elems%} 
    1717  </br> 
    1818  <div id="buttons"> 
  • views/map/popup.tpl

    re207440 r9150aa4  
    11{{!mustache_delimiter}} 
    2 <div id="popup-<%error_id%>"> 
     2<div id="popup-{%error_id%}"> 
    33  <div class="bulle_msg"> 
    44    <div class="closebubble"> 
    5       <div class="help"><a target="_blank" href='<%url_help%>#<%item%>'>&nbsp;?&nbsp;</a></div> 
    6       <div class="error-link"><a target="_blank" href="../error/<%error_id%>">&nbsp;E&nbsp;</a></div> 
     5      <div class="help"><a target="_blank" href='{%url_help%}#{%item%}'>&nbsp;?&nbsp;</a></div> 
     6      <div class="error-link"><a target="_blank" href="../error/{%error_id%}">&nbsp;E&nbsp;</a></div> 
    77    </div> 
    88    <div class="bulle_err"> 
    9       <b><% title %></b> 
     9      <b>{% title %}</b> 
    1010      <br> 
    11       <%subtitle%> 
     11      {%subtitle%} 
    1212    </div> 
    13 <%#elems%> 
     13{%#elems%} 
    1414    <div class="bulle_elem"> 
    15   <%^infos%> 
    16       <b><a target="_blank" href="http://www.openstreetmap.org/browse/<%type%>/<%id%>"><%type%> <%id%></a></b> 
    17       <a href="#" onclick="window.open('http://rawedit.openstreetmap.fr/edit/<%type%>/<%id%>','rawedit','height=360,width=710');">rawedit</a> 
    18   <%/infos%> 
    19   <%#relation%> 
    20       <a target="_blank" href="http://analyser.openstreetmap.fr/cgi-bin/index.py?relation=<%id%>">analyse1</a> 
    21       <a target="_blank" href="http://osm8.openstreetmap.fr/~osmbin/analyse-relation-open.py?<%id%>">analyse2</a> 
    22   <%/relation%> 
    23   <%#node%> 
    24       <a href="http://localhost:8111/load_object?objects=n<%id%>" target="hiddenIframe" class="josm">josm</a> 
    25   <%/node%> 
    26   <%#way%> 
    27       <a href="http://localhost:8111/load_object?objects=w<%id%>" target="hiddenIframe" class="josm">josm</a> 
    28   <%/way%> 
    29   <%#relation%> 
    30       <a href="http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/<%type%>/<%id%>/full" target="hiddenIframe" class="josm">josm</a> 
    31   <%/relation%> 
    32       <a href="#" class="editor_edit" data-type="<%type%>" data-id="<%id%>" data-error="<%error_id%>">edit</a> 
     15  {%^infos%} 
     16      <b><a target="_blank" href="http://www.openstreetmap.org/browse/{%type%}/{%id%}">{%type%} {%id%}</a></b> 
     17      <a href="#" onclick="window.open('http://rawedit.openstreetmap.fr/edit/{%type%}/{%id%}','rawedit','height=360,width=710');">rawedit</a> 
     18  {%/infos%} 
     19  {%#relation%} 
     20      <a target="_blank" href="http://analyser.openstreetmap.fr/cgi-bin/index.py?relation={%id%}">analyse1</a> 
     21      <a target="_blank" href="http://osm8.openstreetmap.fr/~osmbin/analyse-relation-open.py?{%id%}">analyse2</a> 
     22  {%/relation%} 
     23  {%#node%} 
     24      <a href="http://localhost:8111/load_object?objects=n{%id%}" target="hiddenIframe" class="josm">josm</a> 
     25  {%/node%} 
     26  {%#way%} 
     27      <a href="http://localhost:8111/load_object?objects=w{%id%}" target="hiddenIframe" class="josm">josm</a> 
     28  {%/way%} 
     29  {%#relation%} 
     30      <a href="http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/{%type%}/{%id%}/full" target="hiddenIframe" class="josm">josm</a> 
     31  {%/relation%} 
     32      <a href="#" class="editor_edit" data-type="{%type%}" data-id="{%id%}" data-error="{%error_id%}">edit</a> 
    3333      <br> 
    34   <%#fixes%> 
     34  {%#fixes%} 
    3535      <div class="fix"> 
    3636        <div class="fix_links"> 
    37             <a href="http://localhost:8111/import?url=http://{{website}}/api/0.2/error/<%error_id%>/fix/<%num%>" target="hiddenIframe" class="josm">fix-josm</a> 
    38             <a href="#" class="editor_fix" data-type="<%type%>" data-id="<%id%>" data-error="<%error_id%>" data-fix="<%num%>">fix-edit</a> 
     37            <a href="http://localhost:8111/import?url=http://{{website}}/api/0.2/error/{%error_id%}/fix/{%num%}" target="hiddenIframe" class="josm">fix-josm</a> 
     38            <a href="#" class="editor_fix" data-type="{%type%}" data-id="{%id%}" data-error="{%error_id%}" data-fix="{%num%}">fix-edit</a> 
    3939        </div> 
    40     <%#add%> 
    41         <div class="add"> + <b><%k%></b> = <%v%></div> 
    42     <%/add%> 
    43     <%#mod%> 
    44         <div class="mod"> ~ <b><%k%></b> = <%v%></div> 
    45     <%/mod%> 
    46     <%#del%> 
    47         <div class="del"> - <b><%k%></b></div> 
    48     <%/del%> 
     40    {%#add%} 
     41        <div class="add"> + <b>{%k%}</b> = {%v%}</div> 
     42    {%/add%} 
     43    {%#mod%} 
     44        <div class="mod"> ~ <b>{%k%}</b> = {%v%}</div> 
     45    {%/mod%} 
     46    {%#del%} 
     47        <div class="del"> - <b>{%k%}</b></div> 
     48    {%/del%} 
    4949      </div> 
    50   <%/fixes%> 
    51   <%#tags%> 
    52       <b><%k%></b> = 
    53       <%#vlink%><a href="<%vlink%>" target="_blank"><%/vlink%> 
    54       <%v%> 
    55       <%#vlink%></a><%/vlink%> 
     50  {%/fixes%} 
     51  {%#tags%} 
     52      <b>{%k%}</b> = 
     53      {%#vlink%}<a href="{%vlink%}" target="_blank">{%/vlink%} 
     54      {%v%} 
     55      {%#vlink%}</a>{%/vlink%} 
    5656      <br> 
    57   <%/tags%> 
     57  {%/tags%} 
    5858    </div> 
    59 <%/elems%> 
    60 <%#new_elems%> 
     59{%/elems%} 
     60{%#new_elems%} 
    6161    <div class="bulle_elem"> 
    6262      <div class="fix"> 
    6363        <div class="fix_links"> 
    64           <a href="http://localhost:8111/import?url=http://{{website}}/api/0.2/error/<%error_id%>/fix/<%num%>" target="hiddenIframe" class="josm">fix-josm</a> 
     64          <a href="http://localhost:8111/import?url=http://{{website}}/api/0.2/error/{%error_id%}/fix/{%num%}" target="hiddenIframe" class="josm">fix-josm</a> 
    6565        </div> 
    66   <%#add%> 
    67         <div class="add"> + <b><%k%></b> = <%v%></div> 
    68   <%/add%> 
    69   <%#mod%> 
    70         <div class="mod"> ~ <b><%k%></b> = <%v%></div> 
    71   <%/mod%> 
    72   <%#del%> 
    73         <div class="del"> - <b><%k%></b></div> 
    74   <%/del%> 
     66  {%#add%} 
     67        <div class="add"> + <b>{%k%}</b> = {%v%}</div> 
     68  {%/add%} 
     69  {%#mod%} 
     70        <div class="mod"> ~ <b>{%k%}</b> = {%v%}</div> 
     71  {%/mod%} 
     72  {%#del%} 
     73        <div class="del"> - <b>{%k%}</b></div> 
     74  {%/del%} 
    7575      </div> 
    7676    </div> 
    77 <%/new_elems%> 
    78 {{_("Error reported on: ")}} <%b_date%> 
     77{%/new_elems%} 
     78{{_("Error reported on: ")}} {%b_date%} 
    7979  </div> 
    8080  <div class="bulle_verif"> 
    81     <a href="http://www.openstreetmap.org/?lat=<%lat%>&lon=<%lon%>&zoom=18" target="_blank">osm-show</a> 
    82     <a href="http://www.openstreetmap.org/edit?lat=<%lat%>&lon=<%lon%>&zoom=18" target="_blank">osm-edit</a> 
    83     <a href="http://localhost:8111/load_and_zoom?left=<%minlon%>&bottom=<%minlat%>&right=<%maxlon%>&top=<%maxlat%>&select=<%elems_id%>" target="hiddenIframe" class="josm">josm zone</a> 
     81    <a href="http://www.openstreetmap.org/?lat={%lat%}&lon={%lon%}&zoom=18" target="_blank">osm-show</a> 
     82    <a href="http://www.openstreetmap.org/edit?lat={%lat%}&lon={%lon%}&zoom=18" target="_blank">osm-edit</a> 
     83    <a href="http://localhost:8111/load_and_zoom?left={%minlon%}&bottom={%minlat%}&right={%maxlon%}&top={%maxlat%}&select={%elems_id%}" target="hiddenIframe" class="josm">josm zone</a> 
    8484  </div> 
    8585  <div class="bulle_maj"> 
    8686    <b>{{_("change status")}} :</b> 
    87     <a class="closePopup corrected" href="../api/0.2/error/<%error_id%>/done" target="hiddenIframe">{{_("corrected")}}</a> 
    88     <a class="closePopup false_positive" href="../api/0.2/error/<%error_id%>/false" target="hiddenIframe">{{_("false positive")}}</a> 
     87    <a class="closePopup corrected" href="../api/0.2/error/{%error_id%}/done" target="hiddenIframe">{{_("corrected")}}</a> 
     88    <a class="closePopup false_positive" href="../api/0.2/error/{%error_id%}/false" target="hiddenIframe">{{_("false positive")}}</a> 
    8989</div> 
    9090 
  • views/translation.tpl

    raca963f r32fbb9f  
    1 %rebase layout title=(_("How to help translation")) 
     1%rebase('layout.tpl', title=(_("How to help translation"))) 
    22<h1>{{_("How to help translation")}}</h1> 
    33<p>{{_("OsmOse tool is mainly developped by french people, and we aim to add more languages. We currently cover almost all the languages used by countries covered by analyses.")}} 
  • po/de.po

    ra387bb0 rd8568e7  
    1414"Report-Msgid-Bugs-To: \n" 
    1515"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    16 "PO-Revision-Date: 2014-09-08 21:51+0000\n" 
    17 "Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n" 
     16"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     17"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1818"Language-Team: German (http://www.transifex.com/projects/p/osmose/language/de/)\n" 
    1919"MIME-Version: 1.0\n" 
     
    761761msgstr "Straßenkreuzung" 
    762762 
    763 #: ../tools/database/item_menu.txt:32 
     763#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    764764msgid "pharmacy" 
    765765msgstr "Apotheke" 
     
    957957msgstr "Stromleitungen" 
    958958 
    959 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     959#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    960960msgid "post office" 
    961961msgstr "Postamt" 
     
    977977msgstr "Höhengleicher Übergang" 
    978978 
    979 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     979#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    980980msgid "train station" 
    981981msgstr "Bahnhof" 
     
    993993msgstr "Tunnel/Brücke" 
    994994 
    995 #: ../tools/database/item_menu.txt:92 
     995#: ../tools/database/item_menu.txt:93 
    996996msgid "monument, museum" 
    997997msgstr "Denkmal" 
    998998 
    999 #: ../tools/database/item_menu.txt:93 
     999#: ../tools/database/item_menu.txt:94 
    10001000msgid "monument, museum, could be integrated" 
    10011001msgstr "Denkmal, Eintragung möglich" 
    10021002 
    1003 #: ../tools/database/item_menu.txt:95 
     1003#: ../tools/database/item_menu.txt:96 
    10041004msgid "post office, could be integrated" 
    10051005msgstr "Postfiliale, Eintragung möglich" 
    10061006 
    1007 #: ../tools/database/item_menu.txt:96 
     1007#: ../tools/database/item_menu.txt:97 
    10081008msgid "school" 
    10091009msgstr "Schule" 
    10101010 
    1011 #: ../tools/database/item_menu.txt:97 
     1011#: ../tools/database/item_menu.txt:98 
    10121012msgid "school, could be integrated" 
    10131013msgstr "Schule, Eintragung möglich" 
    10141014 
    1015 #: ../tools/database/item_menu.txt:98 
     1015#: ../tools/database/item_menu.txt:99 
    10161016msgid "public transport" 
    10171017msgstr "Öffentlichen verkehrsmitteln" 
    10181018 
    1019 #: ../tools/database/item_menu.txt:99 
     1019#: ../tools/database/item_menu.txt:100 
    10201020msgid "public transport, could be integrated" 
    10211021msgstr "Öffentlichen verkehrsmitteln, Eintragung möglich" 
    10221022 
    1023 #: ../tools/database/item_menu.txt:101 
     1023#: ../tools/database/item_menu.txt:102 
    10241024msgid "train station, could be integrated" 
    10251025msgstr "Bahnhof, Eintragung möglich" 
    10261026 
    1027 #: ../tools/database/item_menu.txt:102 
     1027#: ../tools/database/item_menu.txt:103 
    10281028msgid "level crossing" 
    10291029msgstr "Höhengleicher Übergang" 
    10301030 
    1031 #: ../tools/database/item_menu.txt:103 
     1031#: ../tools/database/item_menu.txt:104 
    10321032msgid "geodesic point" 
    10331033msgstr "fehlender geodätischer Punkt" 
    10341034 
    1035 #: ../tools/database/item_menu.txt:104 
     1035#: ../tools/database/item_menu.txt:105 
    10361036msgid "postal address" 
    10371037msgstr "Adresse, Eintragung möglich" 
    10381038 
    1039 #: ../tools/database/item_menu.txt:105 
     1039#: ../tools/database/item_menu.txt:106 
    10401040msgid "wikipedia, could be integrated" 
    10411041msgstr "Wikipedia, Eintragung möglich" 
    10421042 
    1043 #: ../tools/database/item_menu.txt:106 
     1043#: ../tools/database/item_menu.txt:107 
    10441044msgid "public service" 
    10451045msgstr "öffentlicher Dienst" 
    10461046 
    1047 #: ../tools/database/item_menu.txt:107 
     1047#: ../tools/database/item_menu.txt:108 
    10481048msgid "recycling" 
    10491049msgstr "Recycling" 
    10501050 
    1051 #: ../tools/database/item_menu.txt:108 
     1051#: ../tools/database/item_menu.txt:109 
    10521052msgid "recycling, could be integrated" 
    10531053msgstr "Recycling, Eintragung möglich" 
    10541054 
    1055 #: ../tools/database/item_menu.txt:109 
     1055#: ../tools/database/item_menu.txt:110 
    10561056msgid "parking" 
    10571057msgstr "Parken" 
    10581058 
    1059 #: ../tools/database/item_menu.txt:110 
     1059#: ../tools/database/item_menu.txt:111 
    10601060msgid "parking, could be integrated" 
    10611061msgstr "Parken, Eintragung möglich" 
    10621062 
    1063 #: ../tools/database/item_menu.txt:111 
     1063#: ../tools/database/item_menu.txt:112 
    10641064msgid "accommodation" 
    10651065msgstr "Unterkunft" 
    10661066 
    1067 #: ../tools/database/item_menu.txt:112 
     1067#: ../tools/database/item_menu.txt:113 
    10681068msgid "accommodation, could be integrated" 
    10691069msgstr "Unterkunft, " 
    10701070 
    1071 #: ../tools/database/item_menu.txt:113 
     1071#: ../tools/database/item_menu.txt:114 
    10721072msgid "cycle parking" 
    10731073msgstr "Fahrradstellplatz" 
    10741074 
    1075 #: ../tools/database/item_menu.txt:114 
     1075#: ../tools/database/item_menu.txt:115 
    10761076msgid "cycle parking, could be integrated" 
    10771077msgstr "Fahrradstellplatz, Eintragung möglich" 
    10781078 
    1079 #: ../tools/database/item_menu.txt:115 
     1079#: ../tools/database/item_menu.txt:116 
    10801080msgid "transport sharing" 
    10811081msgstr "" 
    10821082 
    1083 #: ../tools/database/item_menu.txt:116 
     1083#: ../tools/database/item_menu.txt:117 
    10841084msgid "transport sharing, could be integrated" 
    10851085msgstr "" 
    10861086 
    1087 #: ../tools/database/item_menu.txt:117 
     1087#: ../tools/database/item_menu.txt:118 
    10881088msgid "sport" 
    10891089msgstr "Sport" 
    10901090 
    1091 #: ../tools/database/item_menu.txt:118 
     1091#: ../tools/database/item_menu.txt:119 
    10921092msgid "sport, could be integrated" 
    10931093msgstr "Sport, Eintragung möglich" 
     
    11391139msgstr "" 
    11401140 
    1141 #: ../tools/database/item_menu.txt:119 
     1141#: ../tools/database/item_menu.txt:120 
    11421142msgid "toilets" 
    11431143msgstr "Toiletten" 
     
    11471147msgstr "" 
    11481148 
    1149 #: ../tools/database/item_menu.txt:120 
     1149#: ../tools/database/item_menu.txt:121 
    11501150msgid "police" 
    11511151msgstr "Polizei" 
    11521152 
    1153 #: ../tools/database/item_menu.txt:121 
     1153#: ../tools/database/item_menu.txt:122 
    11541154msgid "police, could be integrated" 
    11551155msgstr "" 
     1156 
     1157#: ../tools/database/item_menu.txt:92 
     1158msgid "pharmacy, not integrated " 
     1159msgstr "" 
     1160 
     1161#: ../tools/database/item_menu.txt:124 
     1162msgid "pharmacy, could be integrated" 
     1163msgstr "" 
  • po/es.po

    rcf2a0e3 rd8568e7  
    1010"Report-Msgid-Bugs-To: \n" 
    1111"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    12 "PO-Revision-Date: 2014-07-20 18:35+0000\n" 
     12"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
    1313"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1414"Language-Team: Spanish (http://www.transifex.com/projects/p/osmose/language/es/)\n" 
     
    757757msgstr "paso de carretera" 
    758758 
    759 #: ../tools/database/item_menu.txt:32 
     759#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    760760msgid "pharmacy" 
    761761msgstr "farmacia" 
     
    953953msgstr "líneas eléctricas" 
    954954 
    955 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     955#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    956956msgid "post office" 
    957957msgstr "oficina de correos" 
     
    973973msgstr "nodo en vías" 
    974974 
    975 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     975#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    976976msgid "train station" 
    977977msgstr "estación de tren" 
     
    989989msgstr "túnel/puente" 
    990990 
    991 #: ../tools/database/item_menu.txt:92 
     991#: ../tools/database/item_menu.txt:93 
    992992msgid "monument, museum" 
    993993msgstr "monumento, museo" 
    994994 
    995 #: ../tools/database/item_menu.txt:93 
     995#: ../tools/database/item_menu.txt:94 
    996996msgid "monument, museum, could be integrated" 
    997997msgstr "monumento, museo, podrían integrarse" 
    998998 
    999 #: ../tools/database/item_menu.txt:95 
     999#: ../tools/database/item_menu.txt:96 
    10001000msgid "post office, could be integrated" 
    10011001msgstr "oficina de correos, podría integrarse" 
    10021002 
    1003 #: ../tools/database/item_menu.txt:96 
     1003#: ../tools/database/item_menu.txt:97 
    10041004msgid "school" 
    10051005msgstr "escuela" 
    10061006 
    1007 #: ../tools/database/item_menu.txt:97 
     1007#: ../tools/database/item_menu.txt:98 
    10081008msgid "school, could be integrated" 
    10091009msgstr "escuela, podría integrarse" 
    10101010 
    1011 #: ../tools/database/item_menu.txt:98 
     1011#: ../tools/database/item_menu.txt:99 
    10121012msgid "public transport" 
    10131013msgstr "transporte público" 
    10141014 
    1015 #: ../tools/database/item_menu.txt:99 
     1015#: ../tools/database/item_menu.txt:100 
    10161016msgid "public transport, could be integrated" 
    10171017msgstr "transporte público, podría integrarse" 
    10181018 
    1019 #: ../tools/database/item_menu.txt:101 
     1019#: ../tools/database/item_menu.txt:102 
    10201020msgid "train station, could be integrated" 
    10211021msgstr "estación de tren, podría integrarse" 
    10221022 
    1023 #: ../tools/database/item_menu.txt:102 
     1023#: ../tools/database/item_menu.txt:103 
    10241024msgid "level crossing" 
    10251025msgstr "paso a nivel" 
    10261026 
    1027 #: ../tools/database/item_menu.txt:103 
     1027#: ../tools/database/item_menu.txt:104 
    10281028msgid "geodesic point" 
    10291029msgstr "punto geodésico" 
    10301030 
    1031 #: ../tools/database/item_menu.txt:104 
     1031#: ../tools/database/item_menu.txt:105 
    10321032msgid "postal address" 
    10331033msgstr "dirección postal" 
    10341034 
    1035 #: ../tools/database/item_menu.txt:105 
     1035#: ../tools/database/item_menu.txt:106 
    10361036msgid "wikipedia, could be integrated" 
    10371037msgstr "wikipedia, podría integrarse" 
    10381038 
    1039 #: ../tools/database/item_menu.txt:106 
     1039#: ../tools/database/item_menu.txt:107 
    10401040msgid "public service" 
    10411041msgstr "servicio público" 
    10421042 
    1043 #: ../tools/database/item_menu.txt:107 
     1043#: ../tools/database/item_menu.txt:108 
    10441044msgid "recycling" 
    10451045msgstr "reciclaje" 
    10461046 
    1047 #: ../tools/database/item_menu.txt:108 
     1047#: ../tools/database/item_menu.txt:109 
    10481048msgid "recycling, could be integrated" 
    10491049msgstr "reciclaje, podría integrarse" 
    10501050 
    1051 #: ../tools/database/item_menu.txt:109 
     1051#: ../tools/database/item_menu.txt:110 
    10521052msgid "parking" 
    10531053msgstr "aparcamiento" 
    10541054 
    1055 #: ../tools/database/item_menu.txt:110 
     1055#: ../tools/database/item_menu.txt:111 
    10561056msgid "parking, could be integrated" 
    10571057msgstr "aparcamiento, podría integrarse" 
    10581058 
    1059 #: ../tools/database/item_menu.txt:111 
     1059#: ../tools/database/item_menu.txt:112 
    10601060msgid "accommodation" 
    10611061msgstr "alojamiento" 
    10621062 
    1063 #: ../tools/database/item_menu.txt:112 
     1063#: ../tools/database/item_menu.txt:113 
    10641064msgid "accommodation, could be integrated" 
    10651065msgstr "alojamiento, podría integrarse" 
    10661066 
    1067 #: ../tools/database/item_menu.txt:113 
     1067#: ../tools/database/item_menu.txt:114 
    10681068msgid "cycle parking" 
    10691069msgstr "aparcamiento para bicicletas" 
    10701070 
    1071 #: ../tools/database/item_menu.txt:114 
     1071#: ../tools/database/item_menu.txt:115 
    10721072msgid "cycle parking, could be integrated" 
    10731073msgstr "aparcamiento para bicicletas, podría integrarse" 
    10741074 
    1075 #: ../tools/database/item_menu.txt:115 
     1075#: ../tools/database/item_menu.txt:116 
    10761076msgid "transport sharing" 
    10771077msgstr "transporte compartido" 
    10781078 
    1079 #: ../tools/database/item_menu.txt:116 
     1079#: ../tools/database/item_menu.txt:117 
    10801080msgid "transport sharing, could be integrated" 
    10811081msgstr "transporte compartido, podría integrarse" 
    10821082 
    1083 #: ../tools/database/item_menu.txt:117 
     1083#: ../tools/database/item_menu.txt:118 
    10841084msgid "sport" 
    10851085msgstr "deporte" 
    10861086 
    1087 #: ../tools/database/item_menu.txt:118 
     1087#: ../tools/database/item_menu.txt:119 
    10881088msgid "sport, could be integrated" 
    10891089msgstr "deporte, podría integrarse" 
     
    11351135msgstr "vía de un nodo" 
    11361136 
    1137 #: ../tools/database/item_menu.txt:119 
     1137#: ../tools/database/item_menu.txt:120 
    11381138msgid "toilets" 
    11391139msgstr "baños" 
     
    11431143msgstr "transporte compartido, no inetgrado" 
    11441144 
    1145 #: ../tools/database/item_menu.txt:120 
     1145#: ../tools/database/item_menu.txt:121 
    11461146msgid "police" 
    11471147msgstr "" 
    11481148 
    1149 #: ../tools/database/item_menu.txt:121 
     1149#: ../tools/database/item_menu.txt:122 
    11501150msgid "police, could be integrated" 
    11511151msgstr "" 
     1152 
     1153#: ../tools/database/item_menu.txt:92 
     1154msgid "pharmacy, not integrated " 
     1155msgstr "" 
     1156 
     1157#: ../tools/database/item_menu.txt:124 
     1158msgid "pharmacy, could be integrated" 
     1159msgstr "" 
  • po/fr.po

    r4721d71 rd8568e7  
    55# Translators: 
    66# frodrigo <fred.rodrigo@gmail.com>, 2014 
     7# frodrigo <fred.rodrigo@gmail.com>, 2014 
    78#  <frodrigo@openstreetmap.fr>, 2012 
     9# Jean-Baptiste H <jb.holcroft@gmail.com>, 2014 
    810# Jocelyn Jaubert <jjaubert@openstreetmap.fr>, 2012 
    9 # Jocelyn Jaubert <jjaubert@openstreetmap.fr>, 2014 
     11# Jocelyn Jaubert <jjaubert@openstreetmap.fr>, 2012,2014 
    1012# Jocelyn Jaubert <jjaubert@openstreetmap.fr>, 2012,2014 
    1113# operon, 2014 
     
    1719"Report-Msgid-Bugs-To: \n" 
    1820"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    19 "PO-Revision-Date: 2014-07-26 13:51+0000\n" 
    20 "Last-Translator: operon\n" 
     21"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     22"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    2123"Language-Team: French (http://www.transifex.com/projects/p/osmose/language/fr/)\n" 
    2224"MIME-Version: 1.0\n" 
     
    764766msgstr "croisement de routes" 
    765767 
    766 #: ../tools/database/item_menu.txt:32 
     768#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    767769msgid "pharmacy" 
    768770msgstr "pharmacie" 
     
    960962msgstr "lignes électriques" 
    961963 
    962 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     964#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    963965msgid "post office" 
    964966msgstr "bureau de poste" 
     
    980982msgstr "nœud sur chemins" 
    981983 
    982 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     984#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    983985msgid "train station" 
    984986msgstr "gare" 
     
    996998msgstr "tunnel/pont" 
    997999 
    998 #: ../tools/database/item_menu.txt:92 
     1000#: ../tools/database/item_menu.txt:93 
    9991001msgid "monument, museum" 
    10001002msgstr "monument, musée" 
    10011003 
    1002 #: ../tools/database/item_menu.txt:93 
     1004#: ../tools/database/item_menu.txt:94 
    10031005msgid "monument, museum, could be integrated" 
    10041006msgstr "monument, musée, intégration possible" 
    10051007 
    1006 #: ../tools/database/item_menu.txt:95 
     1008#: ../tools/database/item_menu.txt:96 
    10071009msgid "post office, could be integrated" 
    10081010msgstr "poste, intégration possible" 
    10091011 
    1010 #: ../tools/database/item_menu.txt:96 
     1012#: ../tools/database/item_menu.txt:97 
    10111013msgid "school" 
    10121014msgstr "école" 
    10131015 
    1014 #: ../tools/database/item_menu.txt:97 
     1016#: ../tools/database/item_menu.txt:98 
    10151017msgid "school, could be integrated" 
    10161018msgstr "école, intégration possible" 
    10171019 
    1018 #: ../tools/database/item_menu.txt:98 
     1020#: ../tools/database/item_menu.txt:99 
    10191021msgid "public transport" 
    10201022msgstr "transport en commun" 
    10211023 
    1022 #: ../tools/database/item_menu.txt:99 
     1024#: ../tools/database/item_menu.txt:100 
    10231025msgid "public transport, could be integrated" 
    10241026msgstr "transport en commun, intégration possible" 
    10251027 
    1026 #: ../tools/database/item_menu.txt:101 
     1028#: ../tools/database/item_menu.txt:102 
    10271029msgid "train station, could be integrated" 
    10281030msgstr "gare, intégration possible" 
    10291031 
    1030 #: ../tools/database/item_menu.txt:102 
     1032#: ../tools/database/item_menu.txt:103 
    10311033msgid "level crossing" 
    10321034msgstr "passage à niveau" 
    10331035 
    1034 #: ../tools/database/item_menu.txt:103 
     1036#: ../tools/database/item_menu.txt:104 
    10351037msgid "geodesic point" 
    10361038msgstr "point géodésique manquant" 
    10371039 
    1038 #: ../tools/database/item_menu.txt:104 
     1040#: ../tools/database/item_menu.txt:105 
    10391041msgid "postal address" 
    10401042msgstr "adresse" 
    10411043 
    1042 #: ../tools/database/item_menu.txt:105 
     1044#: ../tools/database/item_menu.txt:106 
    10431045msgid "wikipedia, could be integrated" 
    10441046msgstr "Wikipedia, peut-être intégré" 
    10451047 
    1046 #: ../tools/database/item_menu.txt:106 
     1048#: ../tools/database/item_menu.txt:107 
    10471049msgid "public service" 
    10481050msgstr "service public" 
    10491051 
    1050 #: ../tools/database/item_menu.txt:107 
     1052#: ../tools/database/item_menu.txt:108 
    10511053msgid "recycling" 
    10521054msgstr "recyclage" 
    10531055 
    1054 #: ../tools/database/item_menu.txt:108 
     1056#: ../tools/database/item_menu.txt:109 
    10551057msgid "recycling, could be integrated" 
    10561058msgstr "recyclage, intégration possible" 
    10571059 
    1058 #: ../tools/database/item_menu.txt:109 
     1060#: ../tools/database/item_menu.txt:110 
    10591061msgid "parking" 
    10601062msgstr "parking" 
    10611063 
    1062 #: ../tools/database/item_menu.txt:110 
     1064#: ../tools/database/item_menu.txt:111 
    10631065msgid "parking, could be integrated" 
    10641066msgstr "parking, intégration possible" 
    10651067 
    1066 #: ../tools/database/item_menu.txt:111 
     1068#: ../tools/database/item_menu.txt:112 
    10671069msgid "accommodation" 
    10681070msgstr "hébergement" 
    10691071 
    1070 #: ../tools/database/item_menu.txt:112 
     1072#: ../tools/database/item_menu.txt:113 
    10711073msgid "accommodation, could be integrated" 
    10721074msgstr "hébergement, intégration possible" 
    10731075 
    1074 #: ../tools/database/item_menu.txt:113 
     1076#: ../tools/database/item_menu.txt:114 
    10751077msgid "cycle parking" 
    10761078msgstr "parking vélo" 
    10771079 
    1078 #: ../tools/database/item_menu.txt:114 
     1080#: ../tools/database/item_menu.txt:115 
    10791081msgid "cycle parking, could be integrated" 
    10801082msgstr "parking vélo, intégration possible" 
    10811083 
    1082 #: ../tools/database/item_menu.txt:115 
     1084#: ../tools/database/item_menu.txt:116 
    10831085msgid "transport sharing" 
    10841086msgstr "voiture et vélopartage" 
    10851087 
    1086 #: ../tools/database/item_menu.txt:116 
     1088#: ../tools/database/item_menu.txt:117 
    10871089msgid "transport sharing, could be integrated" 
    10881090msgstr "voiture et vélopartage, intégration possible" 
    10891091 
    1090 #: ../tools/database/item_menu.txt:117 
     1092#: ../tools/database/item_menu.txt:118 
    10911093msgid "sport" 
    10921094msgstr "sport" 
    10931095 
    1094 #: ../tools/database/item_menu.txt:118 
     1096#: ../tools/database/item_menu.txt:119 
    10951097msgid "sport, could be integrated" 
    10961098msgstr "sport, intégration possible" 
     
    11421144msgstr "Chemin à un noeud" 
    11431145 
    1144 #: ../tools/database/item_menu.txt:119 
     1146#: ../tools/database/item_menu.txt:120 
    11451147msgid "toilets" 
    11461148msgstr "Toilettes" 
     
    11481150#: ../tools/database/item_menu.txt:91 
    11491151msgid "transport sharing, not integrated" 
    1150 msgstr "voiture et vélopartage non intégrée" 
    1151  
    1152 #: ../tools/database/item_menu.txt:120 
     1152msgstr "Voiture et vélopartage non intégrés" 
     1153 
     1154#: ../tools/database/item_menu.txt:121 
    11531155msgid "police" 
    11541156msgstr "Police" 
    11551157 
    1156 #: ../tools/database/item_menu.txt:121 
     1158#: ../tools/database/item_menu.txt:122 
    11571159msgid "police, could be integrated" 
    1158 msgstr "Police, pouvant être intégré" 
     1160msgstr "Police, peut être intégré" 
     1161 
     1162#: ../tools/database/item_menu.txt:92 
     1163msgid "pharmacy, not integrated " 
     1164msgstr "" 
     1165 
     1166#: ../tools/database/item_menu.txt:124 
     1167msgid "pharmacy, could be integrated" 
     1168msgstr "" 
  • po/hu.po

    r468cea5 rd8568e7  
    1212"Report-Msgid-Bugs-To: \n" 
    1313"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    14 "PO-Revision-Date: 2014-07-30 12:16+0000\n" 
    15 "Last-Translator: kla <kl-o@freemail.hu>\n" 
     14"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     15"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1616"Language-Team: Hungarian (http://www.transifex.com/projects/p/osmose/language/hu/)\n" 
    1717"MIME-Version: 1.0\n" 
     
    759759msgstr "útkereszteződés" 
    760760 
    761 #: ../tools/database/item_menu.txt:32 
     761#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    762762msgid "pharmacy" 
    763763msgstr "gyógyszertár" 
     
    955955msgstr "elektromos hálózat" 
    956956 
    957 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     957#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    958958msgid "post office" 
    959959msgstr "posta" 
     
    975975msgstr "pont a szakaszokon" 
    976976 
    977 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     977#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    978978msgid "train station" 
    979979msgstr "vasútállomás" 
     
    991991msgstr "alagút/híd" 
    992992 
    993 #: ../tools/database/item_menu.txt:92 
     993#: ../tools/database/item_menu.txt:93 
    994994msgid "monument, museum" 
    995995msgstr "szobor, múzeum" 
    996996 
    997 #: ../tools/database/item_menu.txt:93 
     997#: ../tools/database/item_menu.txt:94 
    998998msgid "monument, museum, could be integrated" 
    999999msgstr "szobor, múzeum talán integrálható" 
    10001000 
    1001 #: ../tools/database/item_menu.txt:95 
     1001#: ../tools/database/item_menu.txt:96 
    10021002msgid "post office, could be integrated" 
    10031003msgstr "postahivatal talán integrálható" 
    10041004 
    1005 #: ../tools/database/item_menu.txt:96 
     1005#: ../tools/database/item_menu.txt:97 
    10061006msgid "school" 
    10071007msgstr "iskola" 
    10081008 
    1009 #: ../tools/database/item_menu.txt:97 
     1009#: ../tools/database/item_menu.txt:98 
    10101010msgid "school, could be integrated" 
    10111011msgstr "iskola, talán integrálható" 
    10121012 
    1013 #: ../tools/database/item_menu.txt:98 
     1013#: ../tools/database/item_menu.txt:99 
    10141014msgid "public transport" 
    10151015msgstr "tömegközlekedés" 
    10161016 
    1017 #: ../tools/database/item_menu.txt:99 
     1017#: ../tools/database/item_menu.txt:100 
    10181018msgid "public transport, could be integrated" 
    10191019msgstr "tömegközlekeség, talán integrálható" 
    10201020 
    1021 #: ../tools/database/item_menu.txt:101 
     1021#: ../tools/database/item_menu.txt:102 
    10221022msgid "train station, could be integrated" 
    10231023msgstr "vasútállomás, talán integrálható" 
    10241024 
    1025 #: ../tools/database/item_menu.txt:102 
     1025#: ../tools/database/item_menu.txt:103 
    10261026msgid "level crossing" 
    10271027msgstr "azonos szintú kereszteződés" 
    10281028 
    1029 #: ../tools/database/item_menu.txt:103 
     1029#: ../tools/database/item_menu.txt:104 
    10301030msgid "geodesic point" 
    10311031msgstr "geodéziai pont" 
    10321032 
    1033 #: ../tools/database/item_menu.txt:104 
     1033#: ../tools/database/item_menu.txt:105 
    10341034msgid "postal address" 
    10351035msgstr "postacím" 
    10361036 
    1037 #: ../tools/database/item_menu.txt:105 
     1037#: ../tools/database/item_menu.txt:106 
    10381038msgid "wikipedia, could be integrated" 
    10391039msgstr "Wikipédia, talán integrálható" 
    10401040 
    1041 #: ../tools/database/item_menu.txt:106 
     1041#: ../tools/database/item_menu.txt:107 
    10421042msgid "public service" 
    10431043msgstr "nyilvános szolgáltatás" 
    10441044 
    1045 #: ../tools/database/item_menu.txt:107 
     1045#: ../tools/database/item_menu.txt:108 
    10461046msgid "recycling" 
    10471047msgstr "újrahasznosítás" 
    10481048 
    1049 #: ../tools/database/item_menu.txt:108 
     1049#: ../tools/database/item_menu.txt:109 
    10501050msgid "recycling, could be integrated" 
    10511051msgstr "újrahasznosítás, talán integrálható" 
    10521052 
    1053 #: ../tools/database/item_menu.txt:109 
     1053#: ../tools/database/item_menu.txt:110 
    10541054msgid "parking" 
    10551055msgstr "parkoló" 
    10561056 
    1057 #: ../tools/database/item_menu.txt:110 
     1057#: ../tools/database/item_menu.txt:111 
    10581058msgid "parking, could be integrated" 
    10591059msgstr "parkoló, talán integrálható" 
    10601060 
    1061 #: ../tools/database/item_menu.txt:111 
     1061#: ../tools/database/item_menu.txt:112 
    10621062msgid "accommodation" 
    10631063msgstr "szállás" 
    10641064 
    1065 #: ../tools/database/item_menu.txt:112 
     1065#: ../tools/database/item_menu.txt:113 
    10661066msgid "accommodation, could be integrated" 
    10671067msgstr "szállás, talán integrálható" 
    10681068 
    1069 #: ../tools/database/item_menu.txt:113 
     1069#: ../tools/database/item_menu.txt:114 
    10701070msgid "cycle parking" 
    10711071msgstr "bicikli parkoló" 
    10721072 
    1073 #: ../tools/database/item_menu.txt:114 
     1073#: ../tools/database/item_menu.txt:115 
    10741074msgid "cycle parking, could be integrated" 
    10751075msgstr "bicikli parkoló, talán integrálható" 
    10761076 
    1077 #: ../tools/database/item_menu.txt:115 
     1077#: ../tools/database/item_menu.txt:116 
    10781078msgid "transport sharing" 
    10791079msgstr "" 
    10801080 
    1081 #: ../tools/database/item_menu.txt:116 
     1081#: ../tools/database/item_menu.txt:117 
    10821082msgid "transport sharing, could be integrated" 
    10831083msgstr "" 
    10841084 
    1085 #: ../tools/database/item_menu.txt:117 
     1085#: ../tools/database/item_menu.txt:118 
    10861086msgid "sport" 
    10871087msgstr "sport" 
    10881088 
    1089 #: ../tools/database/item_menu.txt:118 
     1089#: ../tools/database/item_menu.txt:119 
    10901090msgid "sport, could be integrated" 
    10911091msgstr "sport, talán integrálható" 
     
    11371137msgstr "pont a szakaszokon" 
    11381138 
    1139 #: ../tools/database/item_menu.txt:119 
     1139#: ../tools/database/item_menu.txt:120 
    11401140msgid "toilets" 
    11411141msgstr "mosdók" 
     
    11451145msgstr "" 
    11461146 
    1147 #: ../tools/database/item_menu.txt:120 
     1147#: ../tools/database/item_menu.txt:121 
    11481148msgid "police" 
    11491149msgstr "rendőrség" 
    11501150 
    1151 #: ../tools/database/item_menu.txt:121 
     1151#: ../tools/database/item_menu.txt:122 
    11521152msgid "police, could be integrated" 
    11531153msgstr "rendőrség, talán integrálható" 
     1154 
     1155#: ../tools/database/item_menu.txt:92 
     1156msgid "pharmacy, not integrated " 
     1157msgstr "" 
     1158 
     1159#: ../tools/database/item_menu.txt:124 
     1160msgid "pharmacy, could be integrated" 
     1161msgstr "" 
  • po/it.po

    rcf2a0e3 rd8568e7  
    1212"Report-Msgid-Bugs-To: \n" 
    1313"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    14 "PO-Revision-Date: 2014-07-20 18:35+0000\n" 
     14"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
    1515"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1616"Language-Team: Italian (http://www.transifex.com/projects/p/osmose/language/it/)\n" 
     
    759759msgstr "attraversamento pedonale" 
    760760 
    761 #: ../tools/database/item_menu.txt:32 
     761#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    762762msgid "pharmacy" 
    763763msgstr "farmacia" 
     
    955955msgstr "linee elettriche" 
    956956 
    957 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     957#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    958958msgid "post office" 
    959959msgstr "ref ufficio postale" 
     
    975975msgstr "attraversamento pedonale" 
    976976 
    977 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     977#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    978978msgid "train station" 
    979979msgstr "stazione ferroviaria" 
     
    991991msgstr "tunnel/bridge" 
    992992 
    993 #: ../tools/database/item_menu.txt:92 
     993#: ../tools/database/item_menu.txt:93 
    994994msgid "monument, museum" 
    995995msgstr "monumento" 
    996996 
    997 #: ../tools/database/item_menu.txt:93 
     997#: ../tools/database/item_menu.txt:94 
    998998msgid "monument, museum, could be integrated" 
    999999msgstr "monument da integrare" 
    10001000 
    1001 #: ../tools/database/item_menu.txt:95 
     1001#: ../tools/database/item_menu.txt:96 
    10021002msgid "post office, could be integrated" 
    10031003msgstr "ufficio postale da integrare" 
    10041004 
    1005 #: ../tools/database/item_menu.txt:96 
     1005#: ../tools/database/item_menu.txt:97 
    10061006msgid "school" 
    10071007msgstr "scuola" 
    10081008 
    1009 #: ../tools/database/item_menu.txt:97 
     1009#: ../tools/database/item_menu.txt:98 
    10101010msgid "school, could be integrated" 
    10111011msgstr "scuola da integrare" 
    10121012 
    1013 #: ../tools/database/item_menu.txt:98 
     1013#: ../tools/database/item_menu.txt:99 
    10141014msgid "public transport" 
    10151015msgstr "trasporto pubblico" 
    10161016 
    1017 #: ../tools/database/item_menu.txt:99 
     1017#: ../tools/database/item_menu.txt:100 
    10181018msgid "public transport, could be integrated" 
    10191019msgstr "trasporto pubblico da integrare" 
    10201020 
    1021 #: ../tools/database/item_menu.txt:101 
     1021#: ../tools/database/item_menu.txt:102 
    10221022msgid "train station, could be integrated" 
    10231023msgstr "stazione dei treni da integrare" 
    10241024 
    1025 #: ../tools/database/item_menu.txt:102 
     1025#: ../tools/database/item_menu.txt:103 
    10261026msgid "level crossing" 
    10271027msgstr "passaggio ferroviario" 
    10281028 
    1029 #: ../tools/database/item_menu.txt:103 
     1029#: ../tools/database/item_menu.txt:104 
    10301030msgid "geodesic point" 
    10311031msgstr "punto geodetico" 
    10321032 
    1033 #: ../tools/database/item_menu.txt:104 
     1033#: ../tools/database/item_menu.txt:105 
    10341034msgid "postal address" 
    10351035msgstr "indirizzo da integrare" 
    10361036 
    1037 #: ../tools/database/item_menu.txt:105 
     1037#: ../tools/database/item_menu.txt:106 
    10381038msgid "wikipedia, could be integrated" 
    10391039msgstr "wikipedia da integrare" 
    10401040 
    1041 #: ../tools/database/item_menu.txt:106 
     1041#: ../tools/database/item_menu.txt:107 
    10421042msgid "public service" 
    10431043msgstr "public service" 
    10441044 
    1045 #: ../tools/database/item_menu.txt:107 
     1045#: ../tools/database/item_menu.txt:108 
    10461046msgid "recycling" 
    10471047msgstr "riciclaggio" 
    10481048 
    1049 #: ../tools/database/item_menu.txt:108 
     1049#: ../tools/database/item_menu.txt:109 
    10501050msgid "recycling, could be integrated" 
    10511051msgstr "riciclaggio da integrare" 
    10521052 
    1053 #: ../tools/database/item_menu.txt:109 
     1053#: ../tools/database/item_menu.txt:110 
    10541054msgid "parking" 
    10551055msgstr "parcheggi" 
    10561056 
    1057 #: ../tools/database/item_menu.txt:110 
     1057#: ../tools/database/item_menu.txt:111 
    10581058msgid "parking, could be integrated" 
    10591059msgstr "parcheggi da integrare" 
    10601060 
    1061 #: ../tools/database/item_menu.txt:111 
     1061#: ../tools/database/item_menu.txt:112 
    10621062msgid "accommodation" 
    10631063msgstr "alloggi" 
    10641064 
    1065 #: ../tools/database/item_menu.txt:112 
     1065#: ../tools/database/item_menu.txt:113 
    10661066msgid "accommodation, could be integrated" 
    10671067msgstr "alloggi da integrare" 
    10681068 
    1069 #: ../tools/database/item_menu.txt:113 
     1069#: ../tools/database/item_menu.txt:114 
    10701070msgid "cycle parking" 
    10711071msgstr "parcheggi bici" 
    10721072 
    1073 #: ../tools/database/item_menu.txt:114 
     1073#: ../tools/database/item_menu.txt:115 
    10741074msgid "cycle parking, could be integrated" 
    10751075msgstr "parcheggi bici da integrare" 
    10761076 
    1077 #: ../tools/database/item_menu.txt:115 
     1077#: ../tools/database/item_menu.txt:116 
    10781078msgid "transport sharing" 
    10791079msgstr "trasporti condivisi" 
    10801080 
    1081 #: ../tools/database/item_menu.txt:116 
     1081#: ../tools/database/item_menu.txt:117 
    10821082msgid "transport sharing, could be integrated" 
    10831083msgstr "trasporti condivisi da integrare" 
    10841084 
    1085 #: ../tools/database/item_menu.txt:117 
     1085#: ../tools/database/item_menu.txt:118 
    10861086msgid "sport" 
    10871087msgstr "sport" 
    10881088 
    1089 #: ../tools/database/item_menu.txt:118 
     1089#: ../tools/database/item_menu.txt:119 
    10901090msgid "sport, could be integrated" 
    10911091msgstr "sport da integrare" 
     
    11371137msgstr "way con un solo nodo" 
    11381138 
    1139 #: ../tools/database/item_menu.txt:119 
     1139#: ../tools/database/item_menu.txt:120 
    11401140msgid "toilets" 
    11411141msgstr "toilette" 
     
    11451145msgstr "trasporti condivisi non integrati" 
    11461146 
    1147 #: ../tools/database/item_menu.txt:120 
     1147#: ../tools/database/item_menu.txt:121 
    11481148msgid "police" 
    11491149msgstr "" 
    11501150 
    1151 #: ../tools/database/item_menu.txt:121 
     1151#: ../tools/database/item_menu.txt:122 
    11521152msgid "police, could be integrated" 
    11531153msgstr "" 
     1154 
     1155#: ../tools/database/item_menu.txt:92 
     1156msgid "pharmacy, not integrated " 
     1157msgstr "" 
     1158 
     1159#: ../tools/database/item_menu.txt:124 
     1160msgid "pharmacy, could be integrated" 
     1161msgstr "" 
  • po/ja.po

    rcf2a0e3 rd8568e7  
    1010"Report-Msgid-Bugs-To: \n" 
    1111"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    12 "PO-Revision-Date: 2014-07-20 18:35+0000\n" 
     12"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
    1313"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1414"Language-Team: Japanese (http://www.transifex.com/projects/p/osmose/language/ja/)\n" 
     
    757757msgstr "横断歩道" 
    758758 
    759 #: ../tools/database/item_menu.txt:32 
     759#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    760760msgid "pharmacy" 
    761761msgstr "薬局" 
     
    953953msgstr "電力線" 
    954954 
    955 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     955#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    956956msgid "post office" 
    957957msgstr "郵便局" 
     
    973973msgstr "ウェイ上のノード" 
    974974 
    975 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     975#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    976976msgid "train station" 
    977977msgstr "鉄道駅" 
     
    989989msgstr "トンネル/橋" 
    990990 
    991 #: ../tools/database/item_menu.txt:92 
     991#: ../tools/database/item_menu.txt:93 
    992992msgid "monument, museum" 
    993993msgstr "記念堂、博物館" 
    994994 
    995 #: ../tools/database/item_menu.txt:93 
     995#: ../tools/database/item_menu.txt:94 
    996996msgid "monument, museum, could be integrated" 
    997997msgstr "含められる記念堂、博物館" 
    998998 
    999 #: ../tools/database/item_menu.txt:95 
     999#: ../tools/database/item_menu.txt:96 
    10001000msgid "post office, could be integrated" 
    10011001msgstr "含められる郵便局" 
    10021002 
    1003 #: ../tools/database/item_menu.txt:96 
     1003#: ../tools/database/item_menu.txt:97 
    10041004msgid "school" 
    10051005msgstr "学校" 
    10061006 
    1007 #: ../tools/database/item_menu.txt:97 
     1007#: ../tools/database/item_menu.txt:98 
    10081008msgid "school, could be integrated" 
    10091009msgstr "含められる学校" 
    10101010 
    1011 #: ../tools/database/item_menu.txt:98 
     1011#: ../tools/database/item_menu.txt:99 
    10121012msgid "public transport" 
    10131013msgstr "公共交通" 
    10141014 
    1015 #: ../tools/database/item_menu.txt:99 
     1015#: ../tools/database/item_menu.txt:100 
    10161016msgid "public transport, could be integrated" 
    10171017msgstr "含められる公共交通" 
    10181018 
    1019 #: ../tools/database/item_menu.txt:101 
     1019#: ../tools/database/item_menu.txt:102 
    10201020msgid "train station, could be integrated" 
    10211021msgstr "含められる鉄道駅" 
    10221022 
    1023 #: ../tools/database/item_menu.txt:102 
     1023#: ../tools/database/item_menu.txt:103 
    10241024msgid "level crossing" 
    10251025msgstr "踏切" 
    10261026 
    1027 #: ../tools/database/item_menu.txt:103 
     1027#: ../tools/database/item_menu.txt:104 
    10281028msgid "geodesic point" 
    10291029msgstr "測地点" 
    10301030 
    1031 #: ../tools/database/item_menu.txt:104 
     1031#: ../tools/database/item_menu.txt:105 
    10321032msgid "postal address" 
    10331033msgstr "住所" 
    10341034 
    1035 #: ../tools/database/item_menu.txt:105 
     1035#: ../tools/database/item_menu.txt:106 
    10361036msgid "wikipedia, could be integrated" 
    10371037msgstr "含められるwikipedia" 
    10381038 
    1039 #: ../tools/database/item_menu.txt:106 
     1039#: ../tools/database/item_menu.txt:107 
    10401040msgid "public service" 
    10411041msgstr "公共交通機関" 
    10421042 
    1043 #: ../tools/database/item_menu.txt:107 
     1043#: ../tools/database/item_menu.txt:108 
    10441044msgid "recycling" 
    10451045msgstr "資源回収場所" 
    10461046 
    1047 #: ../tools/database/item_menu.txt:108 
     1047#: ../tools/database/item_menu.txt:109 
    10481048msgid "recycling, could be integrated" 
    10491049msgstr "含められる資源回収場所" 
    10501050 
    1051 #: ../tools/database/item_menu.txt:109 
     1051#: ../tools/database/item_menu.txt:110 
    10521052msgid "parking" 
    10531053msgstr "駐車場" 
    10541054 
    1055 #: ../tools/database/item_menu.txt:110 
     1055#: ../tools/database/item_menu.txt:111 
    10561056msgid "parking, could be integrated" 
    10571057msgstr "含められる駐車場" 
    10581058 
    1059 #: ../tools/database/item_menu.txt:111 
     1059#: ../tools/database/item_menu.txt:112 
    10601060msgid "accommodation" 
    10611061msgstr "宿泊施設" 
    10621062 
    1063 #: ../tools/database/item_menu.txt:112 
     1063#: ../tools/database/item_menu.txt:113 
    10641064msgid "accommodation, could be integrated" 
    10651065msgstr "含められる宿泊施設" 
    10661066 
    1067 #: ../tools/database/item_menu.txt:113 
     1067#: ../tools/database/item_menu.txt:114 
    10681068msgid "cycle parking" 
    10691069msgstr "駐輪場" 
    10701070 
    1071 #: ../tools/database/item_menu.txt:114 
     1071#: ../tools/database/item_menu.txt:115 
    10721072msgid "cycle parking, could be integrated" 
    10731073msgstr "含められる駐輪場" 
    10741074 
    1075 #: ../tools/database/item_menu.txt:115 
     1075#: ../tools/database/item_menu.txt:116 
    10761076msgid "transport sharing" 
    10771077msgstr "乗り物のシェア" 
    10781078 
    1079 #: ../tools/database/item_menu.txt:116 
     1079#: ../tools/database/item_menu.txt:117 
    10801080msgid "transport sharing, could be integrated" 
    10811081msgstr "含められる乗り物のシェア" 
    10821082 
    1083 #: ../tools/database/item_menu.txt:117 
     1083#: ../tools/database/item_menu.txt:118 
    10841084msgid "sport" 
    10851085msgstr "スポーツ" 
    10861086 
    1087 #: ../tools/database/item_menu.txt:118 
     1087#: ../tools/database/item_menu.txt:119 
    10881088msgid "sport, could be integrated" 
    10891089msgstr "含められるスポーツ" 
     
    11351135msgstr "ノードが1つのウェイ" 
    11361136 
    1137 #: ../tools/database/item_menu.txt:119 
     1137#: ../tools/database/item_menu.txt:120 
    11381138msgid "toilets" 
    11391139msgstr "トイレ" 
     
    11431143msgstr "" 
    11441144 
    1145 #: ../tools/database/item_menu.txt:120 
     1145#: ../tools/database/item_menu.txt:121 
    11461146msgid "police" 
    11471147msgstr "" 
    11481148 
    1149 #: ../tools/database/item_menu.txt:121 
     1149#: ../tools/database/item_menu.txt:122 
    11501150msgid "police, could be integrated" 
    11511151msgstr "" 
     1152 
     1153#: ../tools/database/item_menu.txt:92 
     1154msgid "pharmacy, not integrated " 
     1155msgstr "" 
     1156 
     1157#: ../tools/database/item_menu.txt:124 
     1158msgid "pharmacy, could be integrated" 
     1159msgstr "" 
  • po/nl.po

    rcf2a0e3 rd8568e7  
    1010"Report-Msgid-Bugs-To: \n" 
    1111"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    12 "PO-Revision-Date: 2014-07-20 18:35+0000\n" 
     12"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
    1313"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1414"Language-Team: Dutch (http://www.transifex.com/projects/p/osmose/language/nl/)\n" 
     
    757757msgstr "kruising van wegen" 
    758758 
    759 #: ../tools/database/item_menu.txt:32 
     759#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    760760msgid "pharmacy" 
    761761msgstr "apotheker" 
     
    953953msgstr "hoogspanningslijnen" 
    954954 
    955 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     955#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    956956msgid "post office" 
    957957msgstr "postkantoor" 
     
    973973msgstr "overgang" 
    974974 
    975 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     975#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    976976msgid "train station" 
    977977msgstr "trein station" 
     
    989989msgstr "tunnel/brug" 
    990990 
    991 #: ../tools/database/item_menu.txt:92 
     991#: ../tools/database/item_menu.txt:93 
    992992msgid "monument, museum" 
    993993msgstr "monumenten" 
    994994 
    995 #: ../tools/database/item_menu.txt:93 
     995#: ../tools/database/item_menu.txt:94 
    996996msgid "monument, museum, could be integrated" 
    997997msgstr "monumenten, mogelijk invoegen" 
    998998 
    999 #: ../tools/database/item_menu.txt:95 
     999#: ../tools/database/item_menu.txt:96 
    10001000msgid "post office, could be integrated" 
    10011001msgstr "postkantoor, mogelijk invoegen" 
    10021002 
    1003 #: ../tools/database/item_menu.txt:96 
     1003#: ../tools/database/item_menu.txt:97 
    10041004msgid "school" 
    10051005msgstr "school" 
    10061006 
    1007 #: ../tools/database/item_menu.txt:97 
     1007#: ../tools/database/item_menu.txt:98 
    10081008msgid "school, could be integrated" 
    10091009msgstr "school, mogelijk invoegen" 
    10101010 
    1011 #: ../tools/database/item_menu.txt:98 
     1011#: ../tools/database/item_menu.txt:99 
    10121012msgid "public transport" 
    10131013msgstr "franse trein station" 
    10141014 
    1015 #: ../tools/database/item_menu.txt:99 
     1015#: ../tools/database/item_menu.txt:100 
    10161016msgid "public transport, could be integrated" 
    10171017msgstr "franse trein station, mogelijk invoegen" 
    10181018 
    1019 #: ../tools/database/item_menu.txt:101 
     1019#: ../tools/database/item_menu.txt:102 
    10201020msgid "train station, could be integrated" 
    10211021msgstr "trein station, mogelijk invoegen" 
    10221022 
    1023 #: ../tools/database/item_menu.txt:102 
     1023#: ../tools/database/item_menu.txt:103 
    10241024msgid "level crossing" 
    10251025msgstr "overweg" 
    10261026 
    1027 #: ../tools/database/item_menu.txt:103 
     1027#: ../tools/database/item_menu.txt:104 
    10281028msgid "geodesic point" 
    10291029msgstr "geodesic punt ontbreekt" 
    10301030 
    1031 #: ../tools/database/item_menu.txt:104 
     1031#: ../tools/database/item_menu.txt:105 
    10321032msgid "postal address" 
    10331033msgstr "adres" 
    10341034 
    1035 #: ../tools/database/item_menu.txt:105 
     1035#: ../tools/database/item_menu.txt:106 
    10361036msgid "wikipedia, could be integrated" 
    10371037msgstr "" 
    10381038 
    1039 #: ../tools/database/item_menu.txt:106 
     1039#: ../tools/database/item_menu.txt:107 
    10401040msgid "public service" 
    10411041msgstr "openbare dienst" 
    10421042 
    1043 #: ../tools/database/item_menu.txt:107 
     1043#: ../tools/database/item_menu.txt:108 
    10441044msgid "recycling" 
    10451045msgstr "" 
    10461046 
    1047 #: ../tools/database/item_menu.txt:108 
     1047#: ../tools/database/item_menu.txt:109 
    10481048msgid "recycling, could be integrated" 
    10491049msgstr "" 
    10501050 
    1051 #: ../tools/database/item_menu.txt:109 
     1051#: ../tools/database/item_menu.txt:110 
    10521052msgid "parking" 
    10531053msgstr "" 
    10541054 
    1055 #: ../tools/database/item_menu.txt:110 
     1055#: ../tools/database/item_menu.txt:111 
    10561056msgid "parking, could be integrated" 
    10571057msgstr "parking, kan toegevoegd worden" 
    10581058 
    1059 #: ../tools/database/item_menu.txt:111 
     1059#: ../tools/database/item_menu.txt:112 
    10601060msgid "accommodation" 
    10611061msgstr "accommodatie" 
    10621062 
    1063 #: ../tools/database/item_menu.txt:112 
     1063#: ../tools/database/item_menu.txt:113 
    10641064msgid "accommodation, could be integrated" 
    10651065msgstr "" 
    10661066 
    1067 #: ../tools/database/item_menu.txt:113 
     1067#: ../tools/database/item_menu.txt:114 
    10681068msgid "cycle parking" 
    10691069msgstr "fiets parking" 
    10701070 
    1071 #: ../tools/database/item_menu.txt:114 
     1071#: ../tools/database/item_menu.txt:115 
    10721072msgid "cycle parking, could be integrated" 
    10731073msgstr "" 
    10741074 
    1075 #: ../tools/database/item_menu.txt:115 
     1075#: ../tools/database/item_menu.txt:116 
    10761076msgid "transport sharing" 
    10771077msgstr "fietsverhuur" 
    10781078 
    1079 #: ../tools/database/item_menu.txt:116 
     1079#: ../tools/database/item_menu.txt:117 
    10801080msgid "transport sharing, could be integrated" 
    10811081msgstr "" 
    10821082 
    1083 #: ../tools/database/item_menu.txt:117 
     1083#: ../tools/database/item_menu.txt:118 
    10841084msgid "sport" 
    10851085msgstr "sport" 
    10861086 
    1087 #: ../tools/database/item_menu.txt:118 
     1087#: ../tools/database/item_menu.txt:119 
    10881088msgid "sport, could be integrated" 
    10891089msgstr "" 
     
    11351135msgstr "" 
    11361136 
    1137 #: ../tools/database/item_menu.txt:119 
     1137#: ../tools/database/item_menu.txt:120 
    11381138msgid "toilets" 
    11391139msgstr "" 
     
    11431143msgstr "" 
    11441144 
    1145 #: ../tools/database/item_menu.txt:120 
     1145#: ../tools/database/item_menu.txt:121 
    11461146msgid "police" 
    11471147msgstr "" 
    11481148 
    1149 #: ../tools/database/item_menu.txt:121 
     1149#: ../tools/database/item_menu.txt:122 
    11501150msgid "police, could be integrated" 
    11511151msgstr "" 
     1152 
     1153#: ../tools/database/item_menu.txt:92 
     1154msgid "pharmacy, not integrated " 
     1155msgstr "" 
     1156 
     1157#: ../tools/database/item_menu.txt:124 
     1158msgid "pharmacy, could be integrated" 
     1159msgstr "" 
  • po/osmose-frontend.pot

    rcf2a0e3 rbac5e95  
    754754msgstr "" 
    755755 
    756 #: ../tools/database/item_menu.txt:32 
     756#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:124 
    757757msgid "pharmacy" 
    758758msgstr "" 
     
    950950msgstr "" 
    951951 
    952 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     952#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    953953msgid "post office" 
    954954msgstr "" 
     
    970970msgstr "" 
    971971 
    972 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     972#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    973973msgid "train station" 
    974974msgstr "" 
     
    986986msgstr "" 
    987987 
    988 #: ../tools/database/item_menu.txt:92 
     988#: ../tools/database/item_menu.txt:93 
    989989msgid "monument, museum" 
    990990msgstr "" 
    991991 
    992 #: ../tools/database/item_menu.txt:93 
     992#: ../tools/database/item_menu.txt:94 
    993993msgid "monument, museum, could be integrated" 
    994994msgstr "" 
    995995 
    996 #: ../tools/database/item_menu.txt:95 
     996#: ../tools/database/item_menu.txt:96 
    997997msgid "post office, could be integrated" 
    998998msgstr "" 
    999999 
    1000 #: ../tools/database/item_menu.txt:96 
     1000#: ../tools/database/item_menu.txt:97 
    10011001msgid "school" 
    10021002msgstr "" 
    10031003 
    1004 #: ../tools/database/item_menu.txt:97 
     1004#: ../tools/database/item_menu.txt:98 
    10051005msgid "school, could be integrated" 
    10061006msgstr "" 
    10071007 
    1008 #: ../tools/database/item_menu.txt:98 
     1008#: ../tools/database/item_menu.txt:99 
    10091009msgid "public transport" 
    10101010msgstr "" 
    10111011 
    1012 #: ../tools/database/item_menu.txt:99 
     1012#: ../tools/database/item_menu.txt:100 
    10131013msgid "public transport, could be integrated" 
    10141014msgstr "" 
    10151015 
    1016 #: ../tools/database/item_menu.txt:101 
     1016#: ../tools/database/item_menu.txt:102 
    10171017msgid "train station, could be integrated" 
    10181018msgstr "" 
    10191019 
    1020 #: ../tools/database/item_menu.txt:102 
     1020#: ../tools/database/item_menu.txt:103 
    10211021msgid "level crossing" 
    10221022msgstr "" 
    10231023 
    1024 #: ../tools/database/item_menu.txt:103 
     1024#: ../tools/database/item_menu.txt:104 
    10251025msgid "geodesic point" 
    10261026msgstr "" 
    10271027 
    1028 #: ../tools/database/item_menu.txt:104 
     1028#: ../tools/database/item_menu.txt:105 
    10291029msgid "postal address" 
    10301030msgstr "" 
    10311031 
    1032 #: ../tools/database/item_menu.txt:105 
     1032#: ../tools/database/item_menu.txt:106 
    10331033msgid "wikipedia, could be integrated" 
    10341034msgstr "" 
    10351035 
    1036 #: ../tools/database/item_menu.txt:106 
     1036#: ../tools/database/item_menu.txt:107 
    10371037msgid "public service" 
    10381038msgstr "" 
    10391039 
    1040 #: ../tools/database/item_menu.txt:107 
     1040#: ../tools/database/item_menu.txt:108 
    10411041msgid "recycling" 
    10421042msgstr "" 
    10431043 
    1044 #: ../tools/database/item_menu.txt:108 
     1044#: ../tools/database/item_menu.txt:109 
    10451045msgid "recycling, could be integrated" 
    10461046msgstr "" 
    10471047 
    1048 #: ../tools/database/item_menu.txt:109 
     1048#: ../tools/database/item_menu.txt:110 
    10491049msgid "parking" 
    10501050msgstr "" 
    10511051 
    1052 #: ../tools/database/item_menu.txt:110 
     1052#: ../tools/database/item_menu.txt:111 
    10531053msgid "parking, could be integrated" 
    10541054msgstr "" 
    10551055 
    1056 #: ../tools/database/item_menu.txt:111 
     1056#: ../tools/database/item_menu.txt:112 
    10571057msgid "accommodation" 
    10581058msgstr "" 
    10591059 
    1060 #: ../tools/database/item_menu.txt:112 
     1060#: ../tools/database/item_menu.txt:113 
    10611061msgid "accommodation, could be integrated" 
    10621062msgstr "" 
    10631063 
    1064 #: ../tools/database/item_menu.txt:113 
     1064#: ../tools/database/item_menu.txt:114 
    10651065msgid "cycle parking" 
    10661066msgstr "" 
    10671067 
    1068 #: ../tools/database/item_menu.txt:114 
     1068#: ../tools/database/item_menu.txt:115 
    10691069msgid "cycle parking, could be integrated" 
    10701070msgstr "" 
    10711071 
    1072 #: ../tools/database/item_menu.txt:115 
     1072#: ../tools/database/item_menu.txt:116 
    10731073msgid "transport sharing" 
    10741074msgstr "" 
    10751075 
    1076 #: ../tools/database/item_menu.txt:116 
     1076#: ../tools/database/item_menu.txt:117 
    10771077msgid "transport sharing, could be integrated" 
    10781078msgstr "" 
    10791079 
    1080 #: ../tools/database/item_menu.txt:117 
     1080#: ../tools/database/item_menu.txt:118 
    10811081msgid "sport" 
    10821082msgstr "" 
    10831083 
    1084 #: ../tools/database/item_menu.txt:118 
     1084#: ../tools/database/item_menu.txt:119 
    10851085msgid "sport, could be integrated" 
    10861086msgstr "" 
     
    11321132msgstr "" 
    11331133 
    1134 #: ../tools/database/item_menu.txt:119 
     1134#: ../tools/database/item_menu.txt:120 
    11351135msgid "toilets" 
    11361136msgstr "" 
     
    11401140msgstr "" 
    11411141 
    1142 #: ../tools/database/item_menu.txt:120 
     1142#: ../tools/database/item_menu.txt:121 
    11431143msgid "police" 
    11441144msgstr "" 
    11451145 
    1146 #: ../tools/database/item_menu.txt:121 
     1146#: ../tools/database/item_menu.txt:122 
    11471147msgid "police, could be integrated" 
    11481148msgstr "" 
     1149 
     1150#: ../tools/database/item_menu.txt:92 
     1151msgid "pharmacy, not integrated " 
     1152msgstr "" 
     1153 
     1154#: ../tools/database/item_menu.txt:125 
     1155msgid "pharmacy, could be integrated" 
     1156msgstr "" 
     1157 
     1158#: ../tools/database/item_menu.txt:123 
     1159msgid "gas station" 
     1160msgstr "" 
  • po/pl.po

    rbde5fe9 rd8568e7  
    1212"Report-Msgid-Bugs-To: \n" 
    1313"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    14 "PO-Revision-Date: 2014-10-07 22:25+0000\n" 
    15 "Last-Translator: Daniel Koć <daniel@xn--ko-wla.pl>\n" 
     14"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     15"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1616"Language-Team: Polish (http://www.transifex.com/projects/p/osmose/language/pl/)\n" 
    1717"MIME-Version: 1.0\n" 
     
    759759msgstr "skrzyżowanie" 
    760760 
    761 #: ../tools/database/item_menu.txt:32 
     761#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    762762msgid "pharmacy" 
    763763msgstr "apteka" 
     
    955955msgstr "linia energetyczna" 
    956956 
    957 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     957#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    958958msgid "post office" 
    959959msgstr "urząd pocztowy" 
     
    975975msgstr "węzeł na drogach" 
    976976 
    977 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     977#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    978978msgid "train station" 
    979979msgstr "stacja kolejowa" 
     
    991991msgstr "tunel/most" 
    992992 
    993 #: ../tools/database/item_menu.txt:92 
     993#: ../tools/database/item_menu.txt:93 
    994994msgid "monument, museum" 
    995995msgstr "pomnik, muzeum" 
    996996 
    997 #: ../tools/database/item_menu.txt:93 
     997#: ../tools/database/item_menu.txt:94 
    998998msgid "monument, museum, could be integrated" 
    999999msgstr "pomnik, muzeum, powinno być zintegrowane" 
    10001000 
    1001 #: ../tools/database/item_menu.txt:95 
     1001#: ../tools/database/item_menu.txt:96 
    10021002msgid "post office, could be integrated" 
    10031003msgstr "urząd pocztowy, powinien być zintegrowany" 
    10041004 
    1005 #: ../tools/database/item_menu.txt:96 
     1005#: ../tools/database/item_menu.txt:97 
    10061006msgid "school" 
    10071007msgstr "szkoła" 
    10081008 
    1009 #: ../tools/database/item_menu.txt:97 
     1009#: ../tools/database/item_menu.txt:98 
    10101010msgid "school, could be integrated" 
    10111011msgstr "szkoła, powinna być zintegrowana" 
    10121012 
    1013 #: ../tools/database/item_menu.txt:98 
     1013#: ../tools/database/item_menu.txt:99 
    10141014msgid "public transport" 
    10151015msgstr "transport publiczny" 
    10161016 
    1017 #: ../tools/database/item_menu.txt:99 
     1017#: ../tools/database/item_menu.txt:100 
    10181018msgid "public transport, could be integrated" 
    10191019msgstr "transport publiczny, może być zintegrowany" 
    10201020 
    1021 #: ../tools/database/item_menu.txt:101 
     1021#: ../tools/database/item_menu.txt:102 
    10221022msgid "train station, could be integrated" 
    10231023msgstr "stacja kolejowa, może być zintegrowana" 
    10241024 
    1025 #: ../tools/database/item_menu.txt:102 
     1025#: ../tools/database/item_menu.txt:103 
    10261026msgid "level crossing" 
    10271027msgstr "przejazd kolejowy" 
    10281028 
    1029 #: ../tools/database/item_menu.txt:103 
     1029#: ../tools/database/item_menu.txt:104 
    10301030msgid "geodesic point" 
    10311031msgstr "punkt geodezyjny" 
    10321032 
    1033 #: ../tools/database/item_menu.txt:104 
     1033#: ../tools/database/item_menu.txt:105 
    10341034msgid "postal address" 
    10351035msgstr "adres pocztowy" 
    10361036 
    1037 #: ../tools/database/item_menu.txt:105 
     1037#: ../tools/database/item_menu.txt:106 
    10381038msgid "wikipedia, could be integrated" 
    10391039msgstr "wikipedia, może być zintegrowana" 
    10401040 
    1041 #: ../tools/database/item_menu.txt:106 
     1041#: ../tools/database/item_menu.txt:107 
    10421042msgid "public service" 
    10431043msgstr "usługa publiczna" 
    10441044 
    1045 #: ../tools/database/item_menu.txt:107 
     1045#: ../tools/database/item_menu.txt:108 
    10461046msgid "recycling" 
    10471047msgstr "recykling" 
    10481048 
    1049 #: ../tools/database/item_menu.txt:108 
     1049#: ../tools/database/item_menu.txt:109 
    10501050msgid "recycling, could be integrated" 
    10511051msgstr "recykling, może być zintegrowany" 
    10521052 
    1053 #: ../tools/database/item_menu.txt:109 
     1053#: ../tools/database/item_menu.txt:110 
    10541054msgid "parking" 
    10551055msgstr "parking" 
    10561056 
    1057 #: ../tools/database/item_menu.txt:110 
     1057#: ../tools/database/item_menu.txt:111 
    10581058msgid "parking, could be integrated" 
    10591059msgstr "parking, może być zintegrowany" 
    10601060 
    1061 #: ../tools/database/item_menu.txt:111 
     1061#: ../tools/database/item_menu.txt:112 
    10621062msgid "accommodation" 
    10631063msgstr "mieszkanie" 
    10641064 
    1065 #: ../tools/database/item_menu.txt:112 
     1065#: ../tools/database/item_menu.txt:113 
    10661066msgid "accommodation, could be integrated" 
    10671067msgstr "mieszkanie, może być zintegrowane" 
    10681068 
    1069 #: ../tools/database/item_menu.txt:113 
     1069#: ../tools/database/item_menu.txt:114 
    10701070msgid "cycle parking" 
    10711071msgstr "parking rowerowy" 
    10721072 
    1073 #: ../tools/database/item_menu.txt:114 
     1073#: ../tools/database/item_menu.txt:115 
    10741074msgid "cycle parking, could be integrated" 
    10751075msgstr "parking rowerowy, może być zintegrowany" 
    10761076 
    1077 #: ../tools/database/item_menu.txt:115 
     1077#: ../tools/database/item_menu.txt:116 
    10781078msgid "transport sharing" 
    10791079msgstr "udostępnianie transportu" 
    10801080 
    1081 #: ../tools/database/item_menu.txt:116 
     1081#: ../tools/database/item_menu.txt:117 
    10821082msgid "transport sharing, could be integrated" 
    10831083msgstr "udostępnianie transportu, może być zintegrowane" 
    10841084 
    1085 #: ../tools/database/item_menu.txt:117 
     1085#: ../tools/database/item_menu.txt:118 
    10861086msgid "sport" 
    10871087msgstr "sport" 
    10881088 
    1089 #: ../tools/database/item_menu.txt:118 
     1089#: ../tools/database/item_menu.txt:119 
    10901090msgid "sport, could be integrated" 
    10911091msgstr "sport, może być zintegrowany" 
     
    11371137msgstr "droga z jednym węzłem" 
    11381138 
    1139 #: ../tools/database/item_menu.txt:119 
     1139#: ../tools/database/item_menu.txt:120 
    11401140msgid "toilets" 
    11411141msgstr "toalety" 
     
    11451145msgstr "udostępnianie transportu, nie zintegrowane" 
    11461146 
    1147 #: ../tools/database/item_menu.txt:120 
     1147#: ../tools/database/item_menu.txt:121 
    11481148msgid "police" 
    11491149msgstr "policja" 
    11501150 
    1151 #: ../tools/database/item_menu.txt:121 
     1151#: ../tools/database/item_menu.txt:122 
    11521152msgid "police, could be integrated" 
    11531153msgstr "policja, może być zintegrowany" 
     1154 
     1155#: ../tools/database/item_menu.txt:92 
     1156msgid "pharmacy, not integrated " 
     1157msgstr "" 
     1158 
     1159#: ../tools/database/item_menu.txt:124 
     1160msgid "pharmacy, could be integrated" 
     1161msgstr "" 
  • po/pt.po

    ra1f0c25 rd8568e7  
    1212"Report-Msgid-Bugs-To: \n" 
    1313"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    14 "PO-Revision-Date: 2014-09-17 20:59+0000\n" 
    15 "Last-Translator: ViriatoLusitano <marcosoliveira.2405@gmail.com>\n" 
     14"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     15"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1616"Language-Team: Portuguese (http://www.transifex.com/projects/p/osmose/language/pt/)\n" 
    1717"MIME-Version: 1.0\n" 
     
    759759msgstr "cruzamento" 
    760760 
    761 #: ../tools/database/item_menu.txt:32 
     761#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    762762msgid "pharmacy" 
    763763msgstr "farmácia" 
     
    955955msgstr "cabos de força" 
    956956 
    957 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     957#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    958958msgid "post office" 
    959959msgstr "Correios" 
     
    975975msgstr "nós no caminho" 
    976976 
    977 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     977#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    978978msgid "train station" 
    979979msgstr "estação ferroviária" 
     
    991991msgstr "túnel / ponte" 
    992992 
    993 #: ../tools/database/item_menu.txt:92 
     993#: ../tools/database/item_menu.txt:93 
    994994msgid "monument, museum" 
    995995msgstr "monumento / museu" 
    996996 
    997 #: ../tools/database/item_menu.txt:93 
     997#: ../tools/database/item_menu.txt:94 
    998998msgid "monument, museum, could be integrated" 
    999999msgstr "monumento, museu, pode ser integrado" 
    10001000 
    1001 #: ../tools/database/item_menu.txt:95 
     1001#: ../tools/database/item_menu.txt:96 
    10021002msgid "post office, could be integrated" 
    10031003msgstr "Correios, pode ser integrado" 
    10041004 
    1005 #: ../tools/database/item_menu.txt:96 
     1005#: ../tools/database/item_menu.txt:97 
    10061006msgid "school" 
    10071007msgstr "escola" 
    10081008 
    1009 #: ../tools/database/item_menu.txt:97 
     1009#: ../tools/database/item_menu.txt:98 
    10101010msgid "school, could be integrated" 
    10111011msgstr "escola, pode ser integrada" 
    10121012 
    1013 #: ../tools/database/item_menu.txt:98 
     1013#: ../tools/database/item_menu.txt:99 
    10141014msgid "public transport" 
    10151015msgstr "transporte público" 
    10161016 
    1017 #: ../tools/database/item_menu.txt:99 
     1017#: ../tools/database/item_menu.txt:100 
    10181018msgid "public transport, could be integrated" 
    10191019msgstr "transporte público, poderia ser integrado" 
    10201020 
    1021 #: ../tools/database/item_menu.txt:101 
     1021#: ../tools/database/item_menu.txt:102 
    10221022msgid "train station, could be integrated" 
    10231023msgstr "estação ferroviária, poderia ser integrada" 
    10241024 
    1025 #: ../tools/database/item_menu.txt:102 
     1025#: ../tools/database/item_menu.txt:103 
    10261026msgid "level crossing" 
    10271027msgstr "passagem de nível" 
    10281028 
    1029 #: ../tools/database/item_menu.txt:103 
     1029#: ../tools/database/item_menu.txt:104 
    10301030msgid "geodesic point" 
    10311031msgstr "ponto geodésico" 
    10321032 
    1033 #: ../tools/database/item_menu.txt:104 
     1033#: ../tools/database/item_menu.txt:105 
    10341034msgid "postal address" 
    10351035msgstr "endereço postal" 
    10361036 
    1037 #: ../tools/database/item_menu.txt:105 
     1037#: ../tools/database/item_menu.txt:106 
    10381038msgid "wikipedia, could be integrated" 
    10391039msgstr "wikipedia, poderia ser integrado" 
    10401040 
    1041 #: ../tools/database/item_menu.txt:106 
     1041#: ../tools/database/item_menu.txt:107 
    10421042msgid "public service" 
    10431043msgstr "serviço público" 
    10441044 
    1045 #: ../tools/database/item_menu.txt:107 
     1045#: ../tools/database/item_menu.txt:108 
    10461046msgid "recycling" 
    10471047msgstr "reciclagem" 
    10481048 
    1049 #: ../tools/database/item_menu.txt:108 
     1049#: ../tools/database/item_menu.txt:109 
    10501050msgid "recycling, could be integrated" 
    10511051msgstr "reciclagem, poderia ser integrado" 
    10521052 
    1053 #: ../tools/database/item_menu.txt:109 
     1053#: ../tools/database/item_menu.txt:110 
    10541054msgid "parking" 
    10551055msgstr "estacionamento" 
    10561056 
    1057 #: ../tools/database/item_menu.txt:110 
     1057#: ../tools/database/item_menu.txt:111 
    10581058msgid "parking, could be integrated" 
    10591059msgstr "estacionamento, poderia ser integrado" 
    10601060 
    1061 #: ../tools/database/item_menu.txt:111 
     1061#: ../tools/database/item_menu.txt:112 
    10621062msgid "accommodation" 
    10631063msgstr "acomodação" 
    10641064 
    1065 #: ../tools/database/item_menu.txt:112 
     1065#: ../tools/database/item_menu.txt:113 
    10661066msgid "accommodation, could be integrated" 
    10671067msgstr "acomodação, poderia ser integrado" 
    10681068 
    1069 #: ../tools/database/item_menu.txt:113 
     1069#: ../tools/database/item_menu.txt:114 
    10701070msgid "cycle parking" 
    10711071msgstr "estacionamento de bicicleta" 
    10721072 
    1073 #: ../tools/database/item_menu.txt:114 
     1073#: ../tools/database/item_menu.txt:115 
    10741074msgid "cycle parking, could be integrated" 
    10751075msgstr "estacionamento de bicicletas, poderia ser integrado" 
    10761076 
    1077 #: ../tools/database/item_menu.txt:115 
     1077#: ../tools/database/item_menu.txt:116 
    10781078msgid "transport sharing" 
    10791079msgstr "compartilhamento de transporte" 
    10801080 
    1081 #: ../tools/database/item_menu.txt:116 
     1081#: ../tools/database/item_menu.txt:117 
    10821082msgid "transport sharing, could be integrated" 
    10831083msgstr "compartilhamento de transporte, poderia ser integrado" 
    10841084 
    1085 #: ../tools/database/item_menu.txt:117 
     1085#: ../tools/database/item_menu.txt:118 
    10861086msgid "sport" 
    10871087msgstr "esporte" 
    10881088 
    1089 #: ../tools/database/item_menu.txt:118 
     1089#: ../tools/database/item_menu.txt:119 
    10901090msgid "sport, could be integrated" 
    10911091msgstr "esporte, poderia ser integrado" 
     
    11371137msgstr "via de um nó" 
    11381138 
    1139 #: ../tools/database/item_menu.txt:119 
     1139#: ../tools/database/item_menu.txt:120 
    11401140msgid "toilets" 
    11411141msgstr "banheiros" 
     
    11451145msgstr "compartilhamento de transporte, não integrado" 
    11461146 
    1147 #: ../tools/database/item_menu.txt:120 
     1147#: ../tools/database/item_menu.txt:121 
    11481148msgid "police" 
    11491149msgstr "polícia" 
    11501150 
    1151 #: ../tools/database/item_menu.txt:121 
     1151#: ../tools/database/item_menu.txt:122 
    11521152msgid "police, could be integrated" 
    11531153msgstr "polícia, poderia ser integrado" 
     1154 
     1155#: ../tools/database/item_menu.txt:92 
     1156msgid "pharmacy, not integrated " 
     1157msgstr "" 
     1158 
     1159#: ../tools/database/item_menu.txt:124 
     1160msgid "pharmacy, could be integrated" 
     1161msgstr "" 
  • po/ru.po

    r84327ce rd8568e7  
    1111"Report-Msgid-Bugs-To: \n" 
    1212"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    13 "PO-Revision-Date: 2014-09-15 15:45+0000\n" 
    14 "Last-Translator: jekader <jekader@gmail.com>\n" 
     13"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     14"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1515"Language-Team: Russian (http://www.transifex.com/projects/p/osmose/language/ru/)\n" 
    1616"MIME-Version: 1.0\n" 
     
    758758msgstr "перекрёсток" 
    759759 
    760 #: ../tools/database/item_menu.txt:32 
     760#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    761761msgid "pharmacy" 
    762762msgstr "аптека" 
     
    954954msgstr "линии электропередач" 
    955955 
    956 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     956#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    957957msgid "post office" 
    958958msgstr "почтовое отделение" 
     
    974974msgstr "точка на линиях" 
    975975 
    976 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     976#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    977977msgid "train station" 
    978978msgstr "железнодорожная станция" 
     
    990990msgstr "туннель/мост" 
    991991 
    992 #: ../tools/database/item_menu.txt:92 
     992#: ../tools/database/item_menu.txt:93 
    993993msgid "monument, museum" 
    994994msgstr "монумент, музей" 
    995995 
    996 #: ../tools/database/item_menu.txt:93 
     996#: ../tools/database/item_menu.txt:94 
    997997msgid "monument, museum, could be integrated" 
    998998msgstr "" 
    999999 
    1000 #: ../tools/database/item_menu.txt:95 
     1000#: ../tools/database/item_menu.txt:96 
    10011001msgid "post office, could be integrated" 
    10021002msgstr "" 
    10031003 
    1004 #: ../tools/database/item_menu.txt:96 
     1004#: ../tools/database/item_menu.txt:97 
    10051005msgid "school" 
    10061006msgstr "школа" 
    10071007 
    1008 #: ../tools/database/item_menu.txt:97 
     1008#: ../tools/database/item_menu.txt:98 
    10091009msgid "school, could be integrated" 
    10101010msgstr "" 
    10111011 
    1012 #: ../tools/database/item_menu.txt:98 
     1012#: ../tools/database/item_menu.txt:99 
    10131013msgid "public transport" 
    10141014msgstr "общественный транспорт" 
    10151015 
    1016 #: ../tools/database/item_menu.txt:99 
     1016#: ../tools/database/item_menu.txt:100 
    10171017msgid "public transport, could be integrated" 
    10181018msgstr "" 
    10191019 
    1020 #: ../tools/database/item_menu.txt:101 
     1020#: ../tools/database/item_menu.txt:102 
    10211021msgid "train station, could be integrated" 
    10221022msgstr "" 
    10231023 
    1024 #: ../tools/database/item_menu.txt:102 
     1024#: ../tools/database/item_menu.txt:103 
    10251025msgid "level crossing" 
    10261026msgstr "переезд" 
    10271027 
    1028 #: ../tools/database/item_menu.txt:103 
     1028#: ../tools/database/item_menu.txt:104 
    10291029msgid "geodesic point" 
    10301030msgstr "геодезический пункт" 
    10311031 
    1032 #: ../tools/database/item_menu.txt:104 
     1032#: ../tools/database/item_menu.txt:105 
    10331033msgid "postal address" 
    10341034msgstr "почтовый адрес" 
    10351035 
    1036 #: ../tools/database/item_menu.txt:105 
     1036#: ../tools/database/item_menu.txt:106 
    10371037msgid "wikipedia, could be integrated" 
    10381038msgstr "" 
    10391039 
    1040 #: ../tools/database/item_menu.txt:106 
     1040#: ../tools/database/item_menu.txt:107 
    10411041msgid "public service" 
    10421042msgstr "публичная служба" 
    10431043 
    1044 #: ../tools/database/item_menu.txt:107 
     1044#: ../tools/database/item_menu.txt:108 
    10451045msgid "recycling" 
    10461046msgstr "мусоросборник" 
    10471047 
    1048 #: ../tools/database/item_menu.txt:108 
     1048#: ../tools/database/item_menu.txt:109 
    10491049msgid "recycling, could be integrated" 
    10501050msgstr "" 
    10511051 
    1052 #: ../tools/database/item_menu.txt:109 
     1052#: ../tools/database/item_menu.txt:110 
    10531053msgid "parking" 
    10541054msgstr "парковка" 
    10551055 
    1056 #: ../tools/database/item_menu.txt:110 
     1056#: ../tools/database/item_menu.txt:111 
    10571057msgid "parking, could be integrated" 
    10581058msgstr "" 
    10591059 
    1060 #: ../tools/database/item_menu.txt:111 
     1060#: ../tools/database/item_menu.txt:112 
    10611061msgid "accommodation" 
    10621062msgstr "жильё" 
    10631063 
    1064 #: ../tools/database/item_menu.txt:112 
     1064#: ../tools/database/item_menu.txt:113 
    10651065msgid "accommodation, could be integrated" 
    10661066msgstr "" 
    10671067 
    1068 #: ../tools/database/item_menu.txt:113 
     1068#: ../tools/database/item_menu.txt:114 
    10691069msgid "cycle parking" 
    10701070msgstr "парковка для велосипедов" 
    10711071 
    1072 #: ../tools/database/item_menu.txt:114 
     1072#: ../tools/database/item_menu.txt:115 
    10731073msgid "cycle parking, could be integrated" 
    10741074msgstr "" 
    10751075 
    1076 #: ../tools/database/item_menu.txt:115 
     1076#: ../tools/database/item_menu.txt:116 
    10771077msgid "transport sharing" 
    10781078msgstr "" 
    10791079 
    1080 #: ../tools/database/item_menu.txt:116 
     1080#: ../tools/database/item_menu.txt:117 
    10811081msgid "transport sharing, could be integrated" 
    10821082msgstr "" 
    10831083 
    1084 #: ../tools/database/item_menu.txt:117 
     1084#: ../tools/database/item_menu.txt:118 
    10851085msgid "sport" 
    10861086msgstr "спорт" 
    10871087 
    1088 #: ../tools/database/item_menu.txt:118 
     1088#: ../tools/database/item_menu.txt:119 
    10891089msgid "sport, could be integrated" 
    10901090msgstr "" 
     
    11361136msgstr "линия из одной точки" 
    11371137 
    1138 #: ../tools/database/item_menu.txt:119 
     1138#: ../tools/database/item_menu.txt:120 
    11391139msgid "toilets" 
    11401140msgstr "туалеты" 
     
    11441144msgstr "" 
    11451145 
    1146 #: ../tools/database/item_menu.txt:120 
     1146#: ../tools/database/item_menu.txt:121 
    11471147msgid "police" 
    11481148msgstr "полиция" 
    11491149 
    1150 #: ../tools/database/item_menu.txt:121 
     1150#: ../tools/database/item_menu.txt:122 
    11511151msgid "police, could be integrated" 
    11521152msgstr "" 
     1153 
     1154#: ../tools/database/item_menu.txt:92 
     1155msgid "pharmacy, not integrated " 
     1156msgstr "" 
     1157 
     1158#: ../tools/database/item_menu.txt:124 
     1159msgid "pharmacy, could be integrated" 
     1160msgstr "" 
  • po/uk.po

    rd758785 rd8568e7  
    1010"Report-Msgid-Bugs-To: \n" 
    1111"POT-Creation-Date: 2014-03-18 22:25+0100\n" 
    12 "PO-Revision-Date: 2014-08-26 15:43+0000\n" 
    13 "Last-Translator: andygol <andygol@ua.fm>\n" 
     12"PO-Revision-Date: 2014-10-12 15:47+0000\n" 
     13"Last-Translator: Jocelyn Jaubert <jjaubert@openstreetmap.fr>\n" 
    1414"Language-Team: Ukrainian (http://www.transifex.com/projects/p/osmose/language/uk/)\n" 
    1515"MIME-Version: 1.0\n" 
     
    757757msgstr "" 
    758758 
    759 #: ../tools/database/item_menu.txt:32 
     759#: ../tools/database/item_menu.txt:32 ../tools/database/item_menu.txt:123 
    760760msgid "pharmacy" 
    761761msgstr "" 
     
    953953msgstr "" 
    954954 
    955 #: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:94 
     955#: ../tools/database/item_menu.txt:82 ../tools/database/item_menu.txt:95 
    956956msgid "post office" 
    957957msgstr "" 
     
    973973msgstr "" 
    974974 
    975 #: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:100 
     975#: ../tools/database/item_menu.txt:87 ../tools/database/item_menu.txt:101 
    976976msgid "train station" 
    977977msgstr "" 
     
    989989msgstr "" 
    990990 
    991 #: ../tools/database/item_menu.txt:92 
     991#: ../tools/database/item_menu.txt:93 
    992992msgid "monument, museum" 
    993993msgstr "" 
    994994 
    995 #: ../tools/database/item_menu.txt:93 
     995#: ../tools/database/item_menu.txt:94 
    996996msgid "monument, museum, could be integrated" 
    997997msgstr "" 
    998998 
    999 #: ../tools/database/item_menu.txt:95 
     999#: ../tools/database/item_menu.txt:96 
    10001000msgid "post office, could be integrated" 
    10011001msgstr "" 
    10021002 
    1003 #: ../tools/database/item_menu.txt:96 
     1003#: ../tools/database/item_menu.txt:97 
    10041004msgid "school" 
    10051005msgstr "" 
    10061006 
    1007 #: ../tools/database/item_menu.txt:97 
     1007#: ../tools/database/item_menu.txt:98 
    10081008msgid "school, could be integrated" 
    10091009msgstr "" 
    10101010 
    1011 #: ../tools/database/item_menu.txt:98 
     1011#: ../tools/database/item_menu.txt:99 
    10121012msgid "public transport" 
    10131013msgstr "" 
    10141014 
    1015 #: ../tools/database/item_menu.txt:99 
     1015#: ../tools/database/item_menu.txt:100 
    10161016msgid "public transport, could be integrated" 
    10171017msgstr "" 
    10181018 
    1019 #: ../tools/database/item_menu.txt:101 
     1019#: ../tools/database/item_menu.txt:102 
    10201020msgid "train station, could be integrated" 
    10211021msgstr "" 
    10221022 
    1023 #: ../tools/database/item_menu.txt:102 
     1023#: ../tools/database/item_menu.txt:103 
    10241024msgid "level crossing" 
    10251025msgstr "" 
    10261026 
    1027 #: ../tools/database/item_menu.txt:103 
     1027#: ../tools/database/item_menu.txt:104 
    10281028msgid "geodesic point" 
    10291029msgstr "" 
    10301030 
    1031 #: ../tools/database/item_menu.txt:104 
     1031#: ../tools/database/item_menu.txt:105 
    10321032msgid "postal address" 
    10331033msgstr "" 
    10341034 
    1035 #: ../tools/database/item_menu.txt:105 
     1035#: ../tools/database/item_menu.txt:106 
    10361036msgid "wikipedia, could be integrated" 
    10371037msgstr "" 
    10381038 
    1039 #: ../tools/database/item_menu.txt:106 
     1039#: ../tools/database/item_menu.txt:107 
    10401040msgid "public service" 
    10411041msgstr "" 
    10421042 
    1043 #: ../tools/database/item_menu.txt:107 
     1043#: ../tools/database/item_menu.txt:108 
    10441044msgid "recycling" 
    10451045msgstr "" 
    10461046 
    1047 #: ../tools/database/item_menu.txt:108 
     1047#: ../tools/database/item_menu.txt:109 
    10481048msgid "recycling, could be integrated" 
    10491049msgstr "" 
    10501050 
    1051 #: ../tools/database/item_menu.txt:109 
     1051#: ../tools/database/item_menu.txt:110 
    10521052msgid "parking" 
    10531053msgstr "" 
    10541054 
    1055 #: ../tools/database/item_menu.txt:110 
     1055#: ../tools/database/item_menu.txt:111 
    10561056msgid "parking, could be integrated" 
    10571057msgstr "" 
    10581058 
    1059 #: ../tools/database/item_menu.txt:111 
     1059#: ../tools/database/item_menu.txt:112 
    10601060msgid "accommodation" 
    10611061msgstr "" 
    10621062 
    1063 #: ../tools/database/item_menu.txt:112 
     1063#: ../tools/database/item_menu.txt:113 
    10641064msgid "accommodation, could be integrated" 
    10651065msgstr "" 
    10661066 
    1067 #: ../tools/database/item_menu.txt:113 
     1067#: ../tools/database/item_menu.txt:114 
    10681068msgid "cycle parking" 
    10691069msgstr "" 
    10701070 
    1071 #: ../tools/database/item_menu.txt:114 
     1071#: ../tools/database/item_menu.txt:115 
    10721072msgid "cycle parking, could be integrated" 
    10731073msgstr "" 
    10741074 
    1075 #: ../tools/database/item_menu.txt:115 
     1075#: ../tools/database/item_menu.txt:116 
    10761076msgid "transport sharing" 
    10771077msgstr "" 
    10781078 
    1079 #: ../tools/database/item_menu.txt:116 
     1079#: ../tools/database/item_menu.txt:117 
    10801080msgid "transport sharing, could be integrated" 
    10811081msgstr "" 
    10821082 
    1083 #: ../tools/database/item_menu.txt:117 
     1083#: ../tools/database/item_menu.txt:118 
    10841084msgid "sport" 
    10851085msgstr "" 
    10861086 
    1087 #: ../tools/database/item_menu.txt:118 
     1087#: ../tools/database/item_menu.txt:119 
    10881088msgid "sport, could be integrated" 
    10891089msgstr "" 
     
    11351135msgstr "" 
    11361136 
    1137 #: ../tools/database/item_menu.txt:119 
     1137#: ../tools/database/item_menu.txt:120 
    11381138msgid "toilets" 
    11391139msgstr "" 
     
    11431143msgstr "" 
    11441144 
    1145 #: ../tools/database/item_menu.txt:120 
     1145#: ../tools/database/item_menu.txt:121 
    11461146msgid "police" 
    11471147msgstr "" 
    11481148 
    1149 #: ../tools/database/item_menu.txt:121 
     1149#: ../tools/database/item_menu.txt:122 
    11501150msgid "police, could be integrated" 
    11511151msgstr "" 
     1152 
     1153#: ../tools/database/item_menu.txt:92 
     1154msgid "pharmacy, not integrated " 
     1155msgstr "" 
     1156 
     1157#: ../tools/database/item_menu.txt:124 
     1158msgid "pharmacy, could be integrated" 
     1159msgstr "" 
  • tools/database/item_menu.txt

    rc724dbe rbac5e95  
    9090 7130 | _("tunnel/bridge") 
    9191 7140 | _("transport sharing, not integrated") 
     92 7150 | _("pharmacy, not integrated ") 
    9293 8010 | _("monument, museum") 
    9394 8011 | _("monument, museum, could be integrated") 
     
    120121 8190 | _("police") 
    121122 8191 | _("police, could be integrated") 
     123 8200 | _("gas station") 
     124 8210 | _("pharmacy") 
     125 8211 | _("pharmacy, could be integrated") 
Note: See TracChangeset for help on using the changeset viewer.