1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
# -*- coding: utf-8 -*-
"""JIRA utils used internally."""
from __future__ import unicode_literals
import threading
from jira.resilientsession import raise_on_error
class CaseInsensitiveDict(dict):
"""A case-insensitive ``dict``-like object.
Implements all methods and operations of
``collections.MutableMapping`` as well as dict's ``copy``. Also
provides ``lower_items``.
All keys are expected to be strings. The structure remembers the
case of the last key to be set, and ``iter(instance)``,
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
will contain case-sensitive keys. However, querying and contains
testing is case insensitive::
cid = CaseInsensitiveDict()
cid['Accept'] = 'application/json'
cid['accept'] == 'application/json' # True
list(cid) == ['Accept'] # True
For example, ``headers['content-encoding']`` will return the
value of a ``'Content-Encoding'`` response header, regardless
of how the header name was originally stored.
If the constructor, ``.update``, or equality comparison
operations are given keys that have equal ``.lower()``s, the
behavior is undefined.
"""
def __init__(self, *args, **kw):
super(CaseInsensitiveDict, self).__init__(*args, **kw)
self.itemlist = {}
for key, value in super(CaseInsensitiveDict, self).items():
if key != key.lower():
self[key.lower()] = value
self.pop(key, None)
# self.itemlist[key.lower()] = value
def __setitem__(self, key, value):
"""Overwrite [] implementation."""
super(CaseInsensitiveDict, self).__setitem__(key.lower(), value)
# def __iter__(self):
# return iter(self.itemlist)
# def keys(self):
# return self.itemlist
# def values(self):
# return [self[key] for key in self]
# def itervalues(self):
# return (self[key] for key in self)
def threaded_requests(requests):
for fn, url, request_args in requests:
th = threading.Thread(
target=fn, args=(url,), kwargs=request_args, name=url,
)
th.start()
for th in threading.enumerate():
if th.name.startswith('http'):
th.join()
def json_loads(r):
raise_on_error(r)
try:
return r.json()
except ValueError:
# json.loads() fails with empty bodies
if not r.text:
return {}
raise
|