We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Titles from licenses from a custom file are not translated
Looks like this:

![screenshot_2018-12-18 creeu un conjunt de dades - ckan 1](https://user-images.githubusercontent.com/200230/50148656-59c81180-02b9-11e9-8d20-5bc43f4a75c2.png)


Should look like this:

![screenshot_2018-12-18 creeu un conjunt de dades - ckan](https://user-images.githubusercontent.com/200230/50148662-5d5b9880-02b9-11e9-9995-73ba8fc996f2.png)




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ckan/model/license.py`
Content:
```
1 # encoding: utf-8
2 
3 import datetime
4 import urllib2
5 import re
6 
7 from ckan.common import config
8 from paste.deploy.converters import asbool
9 from six import text_type
10 
11 from ckan.common import _, json
12 import ckan.lib.maintain as maintain
13 
14 log = __import__('logging').getLogger(__name__)
15 
16 
17 class License(object):
18     """Domain object for a license."""
19 
20     def __init__(self, data):
21         # convert old keys if necessary
22         if 'is_okd_compliant' in data:
23             data['od_conformance'] = 'approved' \
24                 if asbool(data['is_okd_compliant']) else ''
25             del data['is_okd_compliant']
26         if 'is_osi_compliant' in data:
27             data['osd_conformance'] = 'approved' \
28                 if asbool(data['is_osi_compliant']) else ''
29             del data['is_osi_compliant']
30 
31         self._data = data
32         for (key, value) in self._data.items():
33             if key == 'date_created':
34                 # Parse ISO formatted datetime.
35                 value = datetime.datetime(*map(int, re.split('[^\d]', value)))
36                 self._data[key] = value
37             elif isinstance(value, str):
38                 # Convert str to unicode (keeps Pylons and SQLAlchemy happy).
39                 value = value.decode('utf8')
40                 self._data[key] = value
41 
42     def __getattr__(self, name):
43         if name == 'is_okd_compliant':
44             log.warn('license.is_okd_compliant is deprecated - use '
45                      'od_conformance instead.')
46             return self._data['od_conformance'] == 'approved'
47         if name == 'is_osi_compliant':
48             log.warn('license.is_osi_compliant is deprecated - use '
49                      'osd_conformance instead.')
50             return self._data['osd_conformance'] == 'approved'
51         return self._data[name]
52 
53     @maintain.deprecated("License.__getitem__() is deprecated and will be "
54                          "removed in a future version of CKAN. Instead, "
55                          "please use attribute access.")
56     def __getitem__(self, key):
57         '''NB This method is deprecated and will be removed in a future version
58         of CKAN. Instead, please use attribute access.
59         '''
60         return self.__getattr__(key)
61 
62     def isopen(self):
63         if not hasattr(self, '_isopen'):
64             self._isopen = self.od_conformance == 'approved' or \
65                 self.osd_conformance == 'approved'
66         return self._isopen
67 
68     @maintain.deprecated("License.as_dict() is deprecated and will be "
69                          "removed in a future version of CKAN. Instead, "
70                          "please use attribute access.")
71     def as_dict(self):
72         '''NB This method is deprecated and will be removed in a future version
73         of CKAN. Instead, please use attribute access.
74         '''
75         data = self._data.copy()
76         if 'date_created' in data:
77             value = data['date_created']
78             value = value.isoformat()
79             data['date_created'] = value
80 
81         # deprecated keys
82         if 'od_conformance' in data:
83             data['is_okd_compliant'] = data['od_conformance'] == 'approved'
84         if 'osd_conformance' in data:
85             data['is_osi_compliant'] = data['osd_conformance'] == 'approved'
86 
87         return data
88 
89 
90 class LicenseRegister(object):
91     """Dictionary-like interface to a group of licenses."""
92 
93     def __init__(self):
94         group_url = config.get('licenses_group_url', None)
95         if group_url:
96             self.load_licenses(group_url)
97         else:
98             default_license_list = [
99                 LicenseNotSpecified(),
100                 LicenseOpenDataCommonsPDDL(),
101                 LicenseOpenDataCommonsOpenDatabase(),
102                 LicenseOpenDataAttribution(),
103                 LicenseCreativeCommonsZero(),
104                 LicenseCreativeCommonsAttribution(),
105                 LicenseCreativeCommonsAttributionShareAlike(),
106                 LicenseGNUFreeDocument(),
107                 LicenseOtherOpen(),
108                 LicenseOtherPublicDomain(),
109                 LicenseOtherAttribution(),
110                 LicenseOpenGovernment(),
111                 LicenseCreativeCommonsNonCommercial(),
112                 LicenseOtherNonCommercial(),
113                 LicenseOtherClosed(),
114                 ]
115             self._create_license_list(default_license_list)
116 
117     def load_licenses(self, license_url):
118         try:
119             response = urllib2.urlopen(license_url)
120             response_body = response.read()
121         except Exception as inst:
122             msg = "Couldn't connect to licenses service %r: %s" % (license_url, inst)
123             raise Exception(msg)
124         try:
125             license_data = json.loads(response_body)
126         except Exception as inst:
127             msg = "Couldn't read response from licenses service %r: %s" % (response_body, inst)
128             raise Exception(inst)
129         self._create_license_list(license_data, license_url)
130 
131     def _create_license_list(self, license_data, license_url=''):
132         if isinstance(license_data, dict):
133             self.licenses = [License(entity) for entity in license_data.values()]
134         elif isinstance(license_data, list):
135             self.licenses = [License(entity) for entity in license_data]
136         else:
137             msg = "Licenses at %s must be dictionary or list" % license_url
138             raise ValueError(msg)
139 
140     def __getitem__(self, key, default=Exception):
141         for license in self.licenses:
142             if key == license.id:
143                 return license
144         if default != Exception:
145             return default
146         else:
147             raise KeyError("License not found: %s" % key)
148 
149     def get(self, key, default=None):
150         return self.__getitem__(key, default=default)
151 
152     def keys(self):
153         return [license.id for license in self.licenses]
154 
155     def values(self):
156         return self.licenses
157 
158     def items(self):
159         return [(license.id, license) for license in self.licenses]
160 
161     def __iter__(self):
162         return iter(self.keys())
163 
164     def __len__(self):
165         return len(self.licenses)
166 
167 
168 class DefaultLicense(dict):
169     ''' The license was a dict but this did not allow translation of the
170     title.  This is a slightly changed dict that allows us to have the title
171     as a property and so translated. '''
172 
173     domain_content = False
174     domain_data = False
175     domain_software = False
176     family = ''
177     is_generic = False
178     od_conformance = 'not reviewed'
179     osd_conformance = 'not reviewed'
180     maintainer = ''
181     status = 'active'
182     url = ''
183     title = ''
184     id = ''
185 
186     keys = ['domain_content',
187             'id',
188             'domain_data',
189             'domain_software',
190             'family',
191             'is_generic',
192             'od_conformance',
193             'osd_conformance',
194             'maintainer',
195             'status',
196             'url',
197             'title']
198 
199     def __getitem__(self, key):
200         ''' behave like a dict but get from attributes '''
201         if key in self.keys:
202             value = getattr(self, key)
203             if isinstance(value, str):
204                 return text_type(value)
205             else:
206                 return value
207         else:
208             raise KeyError()
209 
210     def copy(self):
211         ''' create a dict of the license used by the licenses api '''
212         out = {}
213         for key in self.keys:
214             out[key] = text_type(getattr(self, key))
215         return out
216 
217 class LicenseNotSpecified(DefaultLicense):
218     id = "notspecified"
219     is_generic = True
220 
221     @property
222     def title(self):
223         return _("License not specified")
224 
225 class LicenseOpenDataCommonsPDDL(DefaultLicense):
226     domain_data = True
227     id = "odc-pddl"
228     od_conformance = 'approved'
229     url = "http://www.opendefinition.org/licenses/odc-pddl"
230 
231     @property
232     def title(self):
233         return _("Open Data Commons Public Domain Dedication and License (PDDL)")
234 
235 class LicenseOpenDataCommonsOpenDatabase(DefaultLicense):
236     domain_data = True
237     id = "odc-odbl"
238     od_conformance = 'approved'
239     url = "http://www.opendefinition.org/licenses/odc-odbl"
240 
241     @property
242     def title(self):
243         return _("Open Data Commons Open Database License (ODbL)")
244 
245 class LicenseOpenDataAttribution(DefaultLicense):
246     domain_data = True
247     id = "odc-by"
248     od_conformance = 'approved'
249     url = "http://www.opendefinition.org/licenses/odc-by"
250 
251     @property
252     def title(self):
253         return _("Open Data Commons Attribution License")
254 
255 class LicenseCreativeCommonsZero(DefaultLicense):
256     domain_content = True
257     domain_data = True
258     id = "cc-zero"
259     od_conformance = 'approved'
260     url = "http://www.opendefinition.org/licenses/cc-zero"
261 
262     @property
263     def title(self):
264         return _("Creative Commons CCZero")
265 
266 class LicenseCreativeCommonsAttribution(DefaultLicense):
267     id = "cc-by"
268     od_conformance = 'approved'
269     url = "http://www.opendefinition.org/licenses/cc-by"
270 
271     @property
272     def title(self):
273         return _("Creative Commons Attribution")
274 
275 class LicenseCreativeCommonsAttributionShareAlike(DefaultLicense):
276     domain_content = True
277     id = "cc-by-sa"
278     od_conformance = 'approved'
279     url = "http://www.opendefinition.org/licenses/cc-by-sa"
280 
281     @property
282     def title(self):
283         return _("Creative Commons Attribution Share-Alike")
284 
285 class LicenseGNUFreeDocument(DefaultLicense):
286     domain_content = True
287     id = "gfdl"
288     od_conformance = 'approved'
289     url = "http://www.opendefinition.org/licenses/gfdl"
290     @property
291     def title(self):
292         return _("GNU Free Documentation License")
293 
294 class LicenseOtherOpen(DefaultLicense):
295     domain_content = True
296     id = "other-open"
297     is_generic = True
298     od_conformance = 'approved'
299 
300     @property
301     def title(self):
302         return _("Other (Open)")
303 
304 class LicenseOtherPublicDomain(DefaultLicense):
305     domain_content = True
306     id = "other-pd"
307     is_generic = True
308     od_conformance = 'approved'
309 
310     @property
311     def title(self):
312         return _("Other (Public Domain)")
313 
314 class LicenseOtherAttribution(DefaultLicense):
315     domain_content = True
316     id = "other-at"
317     is_generic = True
318     od_conformance = 'approved'
319 
320     @property
321     def title(self):
322         return _("Other (Attribution)")
323 
324 class LicenseOpenGovernment(DefaultLicense):
325     domain_content = True
326     id = "uk-ogl"
327     od_conformance = 'approved'
328     # CS: bad_spelling ignore
329     url = "http://reference.data.gov.uk/id/open-government-licence"
330 
331     @property
332     def title(self):
333         # CS: bad_spelling ignore
334         return _("UK Open Government Licence (OGL)")
335 
336 class LicenseCreativeCommonsNonCommercial(DefaultLicense):
337     id = "cc-nc"
338     url = "http://creativecommons.org/licenses/by-nc/2.0/"
339 
340     @property
341     def title(self):
342         return _("Creative Commons Non-Commercial (Any)")
343 
344 class LicenseOtherNonCommercial(DefaultLicense):
345     id = "other-nc"
346     is_generic = True
347 
348     @property
349     def title(self):
350         return _("Other (Non-Commercial)")
351 
352 class LicenseOtherClosed(DefaultLicense):
353     id = "other-closed"
354     is_generic = True
355 
356     @property
357     def title(self):
358         return _("Other (Not Open)")
359
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ckan/model/license.py b/ckan/model/license.py
--- a/ckan/model/license.py
+++ b/ckan/model/license.py
@@ -6,7 +6,7 @@
 
 from ckan.common import config
 from paste.deploy.converters import asbool
-from six import text_type
+from six import text_type, string_types
 
 from ckan.common import _, json
 import ckan.lib.maintain as maintain
@@ -126,6 +126,11 @@
         except Exception as inst:
             msg = "Couldn't read response from licenses service %r: %s" % (response_body, inst)
             raise Exception(inst)
+        for license in license_data:
+            if isinstance(license, string_types):
+                license = license_data[license]
+            if license.get('title'):
+                license['title'] = _(license['title'])
         self._create_license_list(license_data, license_url)
 
     def _create_license_list(self, license_data, license_url=''):

{"golden_diff": "diff --git a/ckan/model/license.py b/ckan/model/license.py\n--- a/ckan/model/license.py\n+++ b/ckan/model/license.py\n@@ -6,7 +6,7 @@\n \n from ckan.common import config\n from paste.deploy.converters import asbool\n-from six import text_type\n+from six import text_type, string_types\n \n from ckan.common import _, json\n import ckan.lib.maintain as maintain\n@@ -126,6 +126,11 @@\n         except Exception as inst:\n             msg = \"Couldn't read response from licenses service %r: %s\" % (response_body, inst)\n             raise Exception(inst)\n+        for license in license_data:\n+            if isinstance(license, string_types):\n+                license = license_data[license]\n+            if license.get('title'):\n+                license['title'] = _(license['title'])\n         self._create_license_list(license_data, license_url)\n \n     def _create_license_list(self, license_data, license_url=''):\n", "issue": "Titles from licenses from a custom file are not translated\nLooks like this:\r\n\r\n![screenshot_2018-12-18 creeu un conjunt de dades - ckan 1](https://user-images.githubusercontent.com/200230/50148656-59c81180-02b9-11e9-8d20-5bc43f4a75c2.png)\r\n\r\n\r\nShould look like this:\r\n\r\n![screenshot_2018-12-18 creeu un conjunt de dades - ckan](https://user-images.githubusercontent.com/200230/50148662-5d5b9880-02b9-11e9-9995-73ba8fc996f2.png)\r\n\r\n\r\n\n", "before_files": [{"content": "# encoding: utf-8\n\nimport datetime\nimport urllib2\nimport re\n\nfrom ckan.common import config\nfrom paste.deploy.converters import asbool\nfrom six import text_type\n\nfrom ckan.common import _, json\nimport ckan.lib.maintain as maintain\n\nlog = __import__('logging').getLogger(__name__)\n\n\nclass License(object):\n    \"\"\"Domain object for a license.\"\"\"\n\n    def __init__(self, data):\n        # convert old keys if necessary\n        if 'is_okd_compliant' in data:\n            data['od_conformance'] = 'approved' \\\n                if asbool(data['is_okd_compliant']) else ''\n            del data['is_okd_compliant']\n        if 'is_osi_compliant' in data:\n            data['osd_conformance'] = 'approved' \\\n                if asbool(data['is_osi_compliant']) else ''\n            del data['is_osi_compliant']\n\n        self._data = data\n        for (key, value) in self._data.items():\n            if key == 'date_created':\n                # Parse ISO formatted datetime.\n                value = datetime.datetime(*map(int, re.split('[^\\d]', value)))\n                self._data[key] = value\n            elif isinstance(value, str):\n                # Convert str to unicode (keeps Pylons and SQLAlchemy happy).\n                value = value.decode('utf8')\n                self._data[key] = value\n\n    def __getattr__(self, name):\n        if name == 'is_okd_compliant':\n            log.warn('license.is_okd_compliant is deprecated - use '\n                     'od_conformance instead.')\n            return self._data['od_conformance'] == 'approved'\n        if name == 'is_osi_compliant':\n            log.warn('license.is_osi_compliant is deprecated - use '\n                     'osd_conformance instead.')\n            return self._data['osd_conformance'] == 'approved'\n        return self._data[name]\n\n    @maintain.deprecated(\"License.__getitem__() is deprecated and will be \"\n                         \"removed in a future version of CKAN. Instead, \"\n                         \"please use attribute access.\")\n    def __getitem__(self, key):\n        '''NB This method is deprecated and will be removed in a future version\n        of CKAN. Instead, please use attribute access.\n        '''\n        return self.__getattr__(key)\n\n    def isopen(self):\n        if not hasattr(self, '_isopen'):\n            self._isopen = self.od_conformance == 'approved' or \\\n                self.osd_conformance == 'approved'\n        return self._isopen\n\n    @maintain.deprecated(\"License.as_dict() is deprecated and will be \"\n                         \"removed in a future version of CKAN. Instead, \"\n                         \"please use attribute access.\")\n    def as_dict(self):\n        '''NB This method is deprecated and will be removed in a future version\n        of CKAN. Instead, please use attribute access.\n        '''\n        data = self._data.copy()\n        if 'date_created' in data:\n            value = data['date_created']\n            value = value.isoformat()\n            data['date_created'] = value\n\n        # deprecated keys\n        if 'od_conformance' in data:\n            data['is_okd_compliant'] = data['od_conformance'] == 'approved'\n        if 'osd_conformance' in data:\n            data['is_osi_compliant'] = data['osd_conformance'] == 'approved'\n\n        return data\n\n\nclass LicenseRegister(object):\n    \"\"\"Dictionary-like interface to a group of licenses.\"\"\"\n\n    def __init__(self):\n        group_url = config.get('licenses_group_url', None)\n        if group_url:\n            self.load_licenses(group_url)\n        else:\n            default_license_list = [\n                LicenseNotSpecified(),\n                LicenseOpenDataCommonsPDDL(),\n                LicenseOpenDataCommonsOpenDatabase(),\n                LicenseOpenDataAttribution(),\n                LicenseCreativeCommonsZero(),\n                LicenseCreativeCommonsAttribution(),\n                LicenseCreativeCommonsAttributionShareAlike(),\n                LicenseGNUFreeDocument(),\n                LicenseOtherOpen(),\n                LicenseOtherPublicDomain(),\n                LicenseOtherAttribution(),\n                LicenseOpenGovernment(),\n                LicenseCreativeCommonsNonCommercial(),\n                LicenseOtherNonCommercial(),\n                LicenseOtherClosed(),\n                ]\n            self._create_license_list(default_license_list)\n\n    def load_licenses(self, license_url):\n        try:\n            response = urllib2.urlopen(license_url)\n            response_body = response.read()\n        except Exception as inst:\n            msg = \"Couldn't connect to licenses service %r: %s\" % (license_url, inst)\n            raise Exception(msg)\n        try:\n            license_data = json.loads(response_body)\n        except Exception as inst:\n            msg = \"Couldn't read response from licenses service %r: %s\" % (response_body, inst)\n            raise Exception(inst)\n        self._create_license_list(license_data, license_url)\n\n    def _create_license_list(self, license_data, license_url=''):\n        if isinstance(license_data, dict):\n            self.licenses = [License(entity) for entity in license_data.values()]\n        elif isinstance(license_data, list):\n            self.licenses = [License(entity) for entity in license_data]\n        else:\n            msg = \"Licenses at %s must be dictionary or list\" % license_url\n            raise ValueError(msg)\n\n    def __getitem__(self, key, default=Exception):\n        for license in self.licenses:\n            if key == license.id:\n                return license\n        if default != Exception:\n            return default\n        else:\n            raise KeyError(\"License not found: %s\" % key)\n\n    def get(self, key, default=None):\n        return self.__getitem__(key, default=default)\n\n    def keys(self):\n        return [license.id for license in self.licenses]\n\n    def values(self):\n        return self.licenses\n\n    def items(self):\n        return [(license.id, license) for license in self.licenses]\n\n    def __iter__(self):\n        return iter(self.keys())\n\n    def __len__(self):\n        return len(self.licenses)\n\n\nclass DefaultLicense(dict):\n    ''' The license was a dict but this did not allow translation of the\n    title.  This is a slightly changed dict that allows us to have the title\n    as a property and so translated. '''\n\n    domain_content = False\n    domain_data = False\n    domain_software = False\n    family = ''\n    is_generic = False\n    od_conformance = 'not reviewed'\n    osd_conformance = 'not reviewed'\n    maintainer = ''\n    status = 'active'\n    url = ''\n    title = ''\n    id = ''\n\n    keys = ['domain_content',\n            'id',\n            'domain_data',\n            'domain_software',\n            'family',\n            'is_generic',\n            'od_conformance',\n            'osd_conformance',\n            'maintainer',\n            'status',\n            'url',\n            'title']\n\n    def __getitem__(self, key):\n        ''' behave like a dict but get from attributes '''\n        if key in self.keys:\n            value = getattr(self, key)\n            if isinstance(value, str):\n                return text_type(value)\n            else:\n                return value\n        else:\n            raise KeyError()\n\n    def copy(self):\n        ''' create a dict of the license used by the licenses api '''\n        out = {}\n        for key in self.keys:\n            out[key] = text_type(getattr(self, key))\n        return out\n\nclass LicenseNotSpecified(DefaultLicense):\n    id = \"notspecified\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"License not specified\")\n\nclass LicenseOpenDataCommonsPDDL(DefaultLicense):\n    domain_data = True\n    id = \"odc-pddl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-pddl\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Public Domain Dedication and License (PDDL)\")\n\nclass LicenseOpenDataCommonsOpenDatabase(DefaultLicense):\n    domain_data = True\n    id = \"odc-odbl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-odbl\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Open Database License (ODbL)\")\n\nclass LicenseOpenDataAttribution(DefaultLicense):\n    domain_data = True\n    id = \"odc-by\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-by\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Attribution License\")\n\nclass LicenseCreativeCommonsZero(DefaultLicense):\n    domain_content = True\n    domain_data = True\n    id = \"cc-zero\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-zero\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons CCZero\")\n\nclass LicenseCreativeCommonsAttribution(DefaultLicense):\n    id = \"cc-by\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-by\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Attribution\")\n\nclass LicenseCreativeCommonsAttributionShareAlike(DefaultLicense):\n    domain_content = True\n    id = \"cc-by-sa\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-by-sa\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Attribution Share-Alike\")\n\nclass LicenseGNUFreeDocument(DefaultLicense):\n    domain_content = True\n    id = \"gfdl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/gfdl\"\n    @property\n    def title(self):\n        return _(\"GNU Free Documentation License\")\n\nclass LicenseOtherOpen(DefaultLicense):\n    domain_content = True\n    id = \"other-open\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Open)\")\n\nclass LicenseOtherPublicDomain(DefaultLicense):\n    domain_content = True\n    id = \"other-pd\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Public Domain)\")\n\nclass LicenseOtherAttribution(DefaultLicense):\n    domain_content = True\n    id = \"other-at\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Attribution)\")\n\nclass LicenseOpenGovernment(DefaultLicense):\n    domain_content = True\n    id = \"uk-ogl\"\n    od_conformance = 'approved'\n    # CS: bad_spelling ignore\n    url = \"http://reference.data.gov.uk/id/open-government-licence\"\n\n    @property\n    def title(self):\n        # CS: bad_spelling ignore\n        return _(\"UK Open Government Licence (OGL)\")\n\nclass LicenseCreativeCommonsNonCommercial(DefaultLicense):\n    id = \"cc-nc\"\n    url = \"http://creativecommons.org/licenses/by-nc/2.0/\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Non-Commercial (Any)\")\n\nclass LicenseOtherNonCommercial(DefaultLicense):\n    id = \"other-nc\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"Other (Non-Commercial)\")\n\nclass LicenseOtherClosed(DefaultLicense):\n    id = \"other-closed\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"Other (Not Open)\")\n", "path": "ckan/model/license.py"}], "after_files": [{"content": "# encoding: utf-8\n\nimport datetime\nimport urllib2\nimport re\n\nfrom ckan.common import config\nfrom paste.deploy.converters import asbool\nfrom six import text_type, string_types\n\nfrom ckan.common import _, json\nimport ckan.lib.maintain as maintain\n\nlog = __import__('logging').getLogger(__name__)\n\n\nclass License(object):\n    \"\"\"Domain object for a license.\"\"\"\n\n    def __init__(self, data):\n        # convert old keys if necessary\n        if 'is_okd_compliant' in data:\n            data['od_conformance'] = 'approved' \\\n                if asbool(data['is_okd_compliant']) else ''\n            del data['is_okd_compliant']\n        if 'is_osi_compliant' in data:\n            data['osd_conformance'] = 'approved' \\\n                if asbool(data['is_osi_compliant']) else ''\n            del data['is_osi_compliant']\n\n        self._data = data\n        for (key, value) in self._data.items():\n            if key == 'date_created':\n                # Parse ISO formatted datetime.\n                value = datetime.datetime(*map(int, re.split('[^\\d]', value)))\n                self._data[key] = value\n            elif isinstance(value, str):\n                # Convert str to unicode (keeps Pylons and SQLAlchemy happy).\n                value = value.decode('utf8')\n                self._data[key] = value\n\n    def __getattr__(self, name):\n        if name == 'is_okd_compliant':\n            log.warn('license.is_okd_compliant is deprecated - use '\n                     'od_conformance instead.')\n            return self._data['od_conformance'] == 'approved'\n        if name == 'is_osi_compliant':\n            log.warn('license.is_osi_compliant is deprecated - use '\n                     'osd_conformance instead.')\n            return self._data['osd_conformance'] == 'approved'\n        return self._data[name]\n\n    @maintain.deprecated(\"License.__getitem__() is deprecated and will be \"\n                         \"removed in a future version of CKAN. Instead, \"\n                         \"please use attribute access.\")\n    def __getitem__(self, key):\n        '''NB This method is deprecated and will be removed in a future version\n        of CKAN. Instead, please use attribute access.\n        '''\n        return self.__getattr__(key)\n\n    def isopen(self):\n        if not hasattr(self, '_isopen'):\n            self._isopen = self.od_conformance == 'approved' or \\\n                self.osd_conformance == 'approved'\n        return self._isopen\n\n    @maintain.deprecated(\"License.as_dict() is deprecated and will be \"\n                         \"removed in a future version of CKAN. Instead, \"\n                         \"please use attribute access.\")\n    def as_dict(self):\n        '''NB This method is deprecated and will be removed in a future version\n        of CKAN. Instead, please use attribute access.\n        '''\n        data = self._data.copy()\n        if 'date_created' in data:\n            value = data['date_created']\n            value = value.isoformat()\n            data['date_created'] = value\n\n        # deprecated keys\n        if 'od_conformance' in data:\n            data['is_okd_compliant'] = data['od_conformance'] == 'approved'\n        if 'osd_conformance' in data:\n            data['is_osi_compliant'] = data['osd_conformance'] == 'approved'\n\n        return data\n\n\nclass LicenseRegister(object):\n    \"\"\"Dictionary-like interface to a group of licenses.\"\"\"\n\n    def __init__(self):\n        group_url = config.get('licenses_group_url', None)\n        if group_url:\n            self.load_licenses(group_url)\n        else:\n            default_license_list = [\n                LicenseNotSpecified(),\n                LicenseOpenDataCommonsPDDL(),\n                LicenseOpenDataCommonsOpenDatabase(),\n                LicenseOpenDataAttribution(),\n                LicenseCreativeCommonsZero(),\n                LicenseCreativeCommonsAttribution(),\n                LicenseCreativeCommonsAttributionShareAlike(),\n                LicenseGNUFreeDocument(),\n                LicenseOtherOpen(),\n                LicenseOtherPublicDomain(),\n                LicenseOtherAttribution(),\n                LicenseOpenGovernment(),\n                LicenseCreativeCommonsNonCommercial(),\n                LicenseOtherNonCommercial(),\n                LicenseOtherClosed(),\n                ]\n            self._create_license_list(default_license_list)\n\n    def load_licenses(self, license_url):\n        try:\n            response = urllib2.urlopen(license_url)\n            response_body = response.read()\n        except Exception as inst:\n            msg = \"Couldn't connect to licenses service %r: %s\" % (license_url, inst)\n            raise Exception(msg)\n        try:\n            license_data = json.loads(response_body)\n        except Exception as inst:\n            msg = \"Couldn't read response from licenses service %r: %s\" % (response_body, inst)\n            raise Exception(inst)\n        for license in license_data:\n            if isinstance(license, string_types):\n                license = license_data[license]\n            if license.get('title'):\n                license['title'] = _(license['title'])\n        self._create_license_list(license_data, license_url)\n\n    def _create_license_list(self, license_data, license_url=''):\n        if isinstance(license_data, dict):\n            self.licenses = [License(entity) for entity in license_data.values()]\n        elif isinstance(license_data, list):\n            self.licenses = [License(entity) for entity in license_data]\n        else:\n            msg = \"Licenses at %s must be dictionary or list\" % license_url\n            raise ValueError(msg)\n\n    def __getitem__(self, key, default=Exception):\n        for license in self.licenses:\n            if key == license.id:\n                return license\n        if default != Exception:\n            return default\n        else:\n            raise KeyError(\"License not found: %s\" % key)\n\n    def get(self, key, default=None):\n        return self.__getitem__(key, default=default)\n\n    def keys(self):\n        return [license.id for license in self.licenses]\n\n    def values(self):\n        return self.licenses\n\n    def items(self):\n        return [(license.id, license) for license in self.licenses]\n\n    def __iter__(self):\n        return iter(self.keys())\n\n    def __len__(self):\n        return len(self.licenses)\n\n\nclass DefaultLicense(dict):\n    ''' The license was a dict but this did not allow translation of the\n    title.  This is a slightly changed dict that allows us to have the title\n    as a property and so translated. '''\n\n    domain_content = False\n    domain_data = False\n    domain_software = False\n    family = ''\n    is_generic = False\n    od_conformance = 'not reviewed'\n    osd_conformance = 'not reviewed'\n    maintainer = ''\n    status = 'active'\n    url = ''\n    title = ''\n    id = ''\n\n    keys = ['domain_content',\n            'id',\n            'domain_data',\n            'domain_software',\n            'family',\n            'is_generic',\n            'od_conformance',\n            'osd_conformance',\n            'maintainer',\n            'status',\n            'url',\n            'title']\n\n    def __getitem__(self, key):\n        ''' behave like a dict but get from attributes '''\n        if key in self.keys:\n            value = getattr(self, key)\n            if isinstance(value, str):\n                return text_type(value)\n            else:\n                return value\n        else:\n            raise KeyError()\n\n    def copy(self):\n        ''' create a dict of the license used by the licenses api '''\n        out = {}\n        for key in self.keys:\n            out[key] = text_type(getattr(self, key))\n        return out\n\nclass LicenseNotSpecified(DefaultLicense):\n    id = \"notspecified\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"License not specified\")\n\nclass LicenseOpenDataCommonsPDDL(DefaultLicense):\n    domain_data = True\n    id = \"odc-pddl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-pddl\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Public Domain Dedication and License (PDDL)\")\n\nclass LicenseOpenDataCommonsOpenDatabase(DefaultLicense):\n    domain_data = True\n    id = \"odc-odbl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-odbl\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Open Database License (ODbL)\")\n\nclass LicenseOpenDataAttribution(DefaultLicense):\n    domain_data = True\n    id = \"odc-by\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/odc-by\"\n\n    @property\n    def title(self):\n        return _(\"Open Data Commons Attribution License\")\n\nclass LicenseCreativeCommonsZero(DefaultLicense):\n    domain_content = True\n    domain_data = True\n    id = \"cc-zero\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-zero\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons CCZero\")\n\nclass LicenseCreativeCommonsAttribution(DefaultLicense):\n    id = \"cc-by\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-by\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Attribution\")\n\nclass LicenseCreativeCommonsAttributionShareAlike(DefaultLicense):\n    domain_content = True\n    id = \"cc-by-sa\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/cc-by-sa\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Attribution Share-Alike\")\n\nclass LicenseGNUFreeDocument(DefaultLicense):\n    domain_content = True\n    id = \"gfdl\"\n    od_conformance = 'approved'\n    url = \"http://www.opendefinition.org/licenses/gfdl\"\n    @property\n    def title(self):\n        return _(\"GNU Free Documentation License\")\n\nclass LicenseOtherOpen(DefaultLicense):\n    domain_content = True\n    id = \"other-open\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Open)\")\n\nclass LicenseOtherPublicDomain(DefaultLicense):\n    domain_content = True\n    id = \"other-pd\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Public Domain)\")\n\nclass LicenseOtherAttribution(DefaultLicense):\n    domain_content = True\n    id = \"other-at\"\n    is_generic = True\n    od_conformance = 'approved'\n\n    @property\n    def title(self):\n        return _(\"Other (Attribution)\")\n\nclass LicenseOpenGovernment(DefaultLicense):\n    domain_content = True\n    id = \"uk-ogl\"\n    od_conformance = 'approved'\n    # CS: bad_spelling ignore\n    url = \"http://reference.data.gov.uk/id/open-government-licence\"\n\n    @property\n    def title(self):\n        # CS: bad_spelling ignore\n        return _(\"UK Open Government Licence (OGL)\")\n\nclass LicenseCreativeCommonsNonCommercial(DefaultLicense):\n    id = \"cc-nc\"\n    url = \"http://creativecommons.org/licenses/by-nc/2.0/\"\n\n    @property\n    def title(self):\n        return _(\"Creative Commons Non-Commercial (Any)\")\n\nclass LicenseOtherNonCommercial(DefaultLicense):\n    id = \"other-nc\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"Other (Non-Commercial)\")\n\nclass LicenseOtherClosed(DefaultLicense):\n    id = \"other-closed\"\n    is_generic = True\n\n    @property\n    def title(self):\n        return _(\"Other (Not Open)\")\n", "path": "ckan/model/license.py"}]}