prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  district, topic and localisation for external projects and bplans
  external projects also need district, topic and localisation as the other projects do. 
  
  same is true for b-plans as not all of them come via imperia
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `meinberlin/apps/bplan/tasks.py`
  Content:
  ```
  1 import json
  2 import logging
  3 import urllib
  4 
  5 from background_task import background
  6 
  7 from adhocracy4.administrative_districts.models import AdministrativeDistrict
  8 from meinberlin.apps.bplan.models import Bplan
  9 
  10 logger = logging.getLogger(__name__)
  11 
  12 
  13 def get_features_from_bplan_api(endpoint):
  14     url = 'https://bplan-prod.liqd.net/api/' + endpoint
  15     req = urllib.request.Request(url)
  16     res = urllib.request.urlopen(req)
  17     res_body = res.read()
  18     res_json = json.loads(res_body.decode("utf-8"))
  19 
  20     return res_json.get('features')
  21 
  22 
  23 def get_bplan_point_and_district_pk(bplan_identifier):
  24     url_poi = 'bplan/points/' + \
  25         '?bplan={}'.format(bplan_identifier.replace(' ', '%20'))
  26 
  27     try:
  28         features = get_features_from_bplan_api(url_poi)
  29         if features:
  30             district_pk = features[0]['properties']['bezirk']
  31             point = features[0]
  32 
  33             return point, district_pk
  34 
  35         return None, None
  36 
  37     except UnicodeEncodeError:
  38         # catches bplan-identifiers with problematic chars
  39         pass
  40 
  41 
  42 def get_bplan_api_pk_to_a4_admin_district_dict():
  43     url_dis = 'bezirke/'
  44     features = get_features_from_bplan_api(url_dis)
  45     dis_dict = {}
  46     if features:
  47         for district in features:
  48 
  49             dis_model = AdministrativeDistrict.objects.filter(
  50                 name=district['properties']['name']
  51             )
  52             if dis_model:
  53                 dis_dict[district['properties']['pk']] = \
  54                     dis_model[0]
  55             else:
  56                 dis_dict[district['properties']['pk']] = None
  57 
  58     return dis_dict
  59 
  60 
  61 @background(schedule=0)
  62 def get_location_information(bplan_id):
  63     bplan = Bplan.objects.get(pk=bplan_id)
  64     point, district_pk = get_bplan_point_and_district_pk(bplan.identifier)
  65     dis_dict = get_bplan_api_pk_to_a4_admin_district_dict()
  66 
  67     if district_pk:
  68         bplan.administrative_district = \
  69             dis_dict[district_pk]
  70     else:
  71         logger.error(
  72             "The identifier '{}' for bplan '{}' seems to be wrong. "
  73             "It doesn't exist on https://bplan-prod.liqd.net/api/"
  74             .format(bplan.identifier, bplan)
  75         )
  76     bplan.point = point
  77     bplan.save(update_fields=['point', 'administrative_district'])
  78
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/meinberlin/apps/bplan/tasks.py b/meinberlin/apps/bplan/tasks.py
  --- a/meinberlin/apps/bplan/tasks.py
  +++ b/meinberlin/apps/bplan/tasks.py
  @@ -74,4 +74,5 @@
               .format(bplan.identifier, bplan)
           )
       bplan.point = point
  -    bplan.save(update_fields=['point', 'administrative_district'])
  +    bplan.topics = ['URB']
  +    bplan.save(update_fields=['point', 'administrative_district', 'topics'])
  
verification_info: {"golden_diff": "diff --git a/meinberlin/apps/bplan/tasks.py b/meinberlin/apps/bplan/tasks.py\n--- a/meinberlin/apps/bplan/tasks.py\n+++ b/meinberlin/apps/bplan/tasks.py\n@@ -74,4 +74,5 @@\n             .format(bplan.identifier, bplan)\n         )\n     bplan.point = point\n-    bplan.save(update_fields=['point', 'administrative_district'])\n+    bplan.topics = ['URB']\n+    bplan.save(update_fields=['point', 'administrative_district', 'topics'])\n", "issue": "district, topic and localisation for external projects and bplans\nexternal projects also need district, topic and localisation as the other projects do. \r\n\r\nsame is true for b-plans as not all of them come via imperia\n", "before_files": [{"content": "import json\nimport logging\nimport urllib\n\nfrom background_task import background\n\nfrom adhocracy4.administrative_districts.models import AdministrativeDistrict\nfrom meinberlin.apps.bplan.models import Bplan\n\nlogger = logging.getLogger(__name__)\n\n\ndef get_features_from_bplan_api(endpoint):\n    url = 'https://bplan-prod.liqd.net/api/' + endpoint\n    req = urllib.request.Request(url)\n    res = urllib.request.urlopen(req)\n    res_body = res.read()\n    res_json = json.loads(res_body.decode(\"utf-8\"))\n\n    return res_json.get('features')\n\n\ndef get_bplan_point_and_district_pk(bplan_identifier):\n    url_poi = 'bplan/points/' + \\\n        '?bplan={}'.format(bplan_identifier.replace(' ', '%20'))\n\n    try:\n        features = get_features_from_bplan_api(url_poi)\n        if features:\n            district_pk = features[0]['properties']['bezirk']\n            point = features[0]\n\n            return point, district_pk\n\n        return None, None\n\n    except UnicodeEncodeError:\n        # catches bplan-identifiers with problematic chars\n        pass\n\n\ndef get_bplan_api_pk_to_a4_admin_district_dict():\n    url_dis = 'bezirke/'\n    features = get_features_from_bplan_api(url_dis)\n    dis_dict = {}\n    if features:\n        for district in features:\n\n            dis_model = AdministrativeDistrict.objects.filter(\n                name=district['properties']['name']\n            )\n            if dis_model:\n                dis_dict[district['properties']['pk']] = \\\n                    dis_model[0]\n            else:\n                dis_dict[district['properties']['pk']] = None\n\n    return dis_dict\n\n\n@background(schedule=0)\ndef get_location_information(bplan_id):\n    bplan = Bplan.objects.get(pk=bplan_id)\n    point, district_pk = get_bplan_point_and_district_pk(bplan.identifier)\n    dis_dict = get_bplan_api_pk_to_a4_admin_district_dict()\n\n    if district_pk:\n        bplan.administrative_district = \\\n            dis_dict[district_pk]\n    else:\n        logger.error(\n            \"The identifier '{}' for bplan '{}' seems to be wrong. \"\n            \"It doesn't exist on https://bplan-prod.liqd.net/api/\"\n            .format(bplan.identifier, bplan)\n        )\n    bplan.point = point\n    bplan.save(update_fields=['point', 'administrative_district'])\n", "path": "meinberlin/apps/bplan/tasks.py"}], "after_files": [{"content": "import json\nimport logging\nimport urllib\n\nfrom background_task import background\n\nfrom adhocracy4.administrative_districts.models import AdministrativeDistrict\nfrom meinberlin.apps.bplan.models import Bplan\n\nlogger = logging.getLogger(__name__)\n\n\ndef get_features_from_bplan_api(endpoint):\n    url = 'https://bplan-prod.liqd.net/api/' + endpoint\n    req = urllib.request.Request(url)\n    res = urllib.request.urlopen(req)\n    res_body = res.read()\n    res_json = json.loads(res_body.decode(\"utf-8\"))\n\n    return res_json.get('features')\n\n\ndef get_bplan_point_and_district_pk(bplan_identifier):\n    url_poi = 'bplan/points/' + \\\n        '?bplan={}'.format(bplan_identifier.replace(' ', '%20'))\n\n    try:\n        features = get_features_from_bplan_api(url_poi)\n        if features:\n            district_pk = features[0]['properties']['bezirk']\n            point = features[0]\n\n            return point, district_pk\n\n        return None, None\n\n    except UnicodeEncodeError:\n        # catches bplan-identifiers with problematic chars\n        pass\n\n\ndef get_bplan_api_pk_to_a4_admin_district_dict():\n    url_dis = 'bezirke/'\n    features = get_features_from_bplan_api(url_dis)\n    dis_dict = {}\n    if features:\n        for district in features:\n\n            dis_model = AdministrativeDistrict.objects.filter(\n                name=district['properties']['name']\n            )\n            if dis_model:\n                dis_dict[district['properties']['pk']] = \\\n                    dis_model[0]\n            else:\n                dis_dict[district['properties']['pk']] = None\n\n    return dis_dict\n\n\n@background(schedule=0)\ndef get_location_information(bplan_id):\n    bplan = Bplan.objects.get(pk=bplan_id)\n    point, district_pk = get_bplan_point_and_district_pk(bplan.identifier)\n    dis_dict = get_bplan_api_pk_to_a4_admin_district_dict()\n\n    if district_pk:\n        bplan.administrative_district = \\\n            dis_dict[district_pk]\n    else:\n        logger.error(\n            \"The identifier '{}' for bplan '{}' seems to be wrong. \"\n            \"It doesn't exist on https://bplan-prod.liqd.net/api/\"\n            .format(bplan.identifier, bplan)\n        )\n    bplan.point = point\n    bplan.topics = ['URB']\n    bplan.save(update_fields=['point', 'administrative_district', 'topics'])\n", "path": "meinberlin/apps/bplan/tasks.py"}]}