prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Medium Articles Bug
  Bug in getting medium articles on the homepage
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `backend/uclapi/dashboard/app_helpers.py`
  Content:
  ```
  1 from binascii import hexlify
  2 from random import SystemRandom
  3 
  4 from common.helpers import generate_api_token
  5 from uclapi.settings import (
  6     MEDIUM_ARTICLE_QUANTITY,
  7     REDIS_UCLAPI_HOST
  8 )
  9 
  10 import os
  11 import redis
  12 import textwrap
  13 import validators
  14 
  15 
  16 def get_articles():
  17     r = redis.Redis(host=REDIS_UCLAPI_HOST)
  18     pipe = r.pipeline()
  19     articles = []
  20     for i in range(0, MEDIUM_ARTICLE_QUANTITY):
  21         articles.append({})
  22         redis_key_url = "Blog:item:{}:url".format(i)
  23         redis_key_title = "Blog:item:{}:title".format(i)
  24         pipe.get(redis_key_url)
  25         pipe.get(redis_key_title)
  26     redis_response = pipe.execute()
  27     for i in range(0, MEDIUM_ARTICLE_QUANTITY):
  28         articles[i]['url'] = redis_response[i*2].decode("utf-8")
  29         articles[i]['title'] = redis_response[i*2+1].decode("utf-8")
  30     return articles
  31 
  32 
  33 def generate_temp_api_token():
  34     return generate_api_token("temp")
  35 
  36 
  37 def get_temp_token():
  38     r = redis.Redis(host=REDIS_UCLAPI_HOST)
  39 
  40     token = generate_temp_api_token()
  41     # We initialise a new temporary token and set it to 1
  42     # as it is generated at its first usage.
  43     r.set(token, 1, 600)
  44     return token
  45 
  46 
  47 def generate_app_id():
  48     key = hexlify(os.urandom(5)).decode()
  49     final = "A" + key
  50 
  51     return final
  52 
  53 
  54 def generate_app_client_id():
  55     sr = SystemRandom()
  56 
  57     client_id = '{}.{}'.format(
  58         ''.join(str(sr.randint(0, 9)) for _ in range(16)),
  59         ''.join(str(sr.randint(0, 9)) for _ in range(16))
  60     )
  61 
  62     return client_id
  63 
  64 
  65 def generate_app_client_secret():
  66     client_secret = hexlify(os.urandom(32)).decode()
  67     return client_secret
  68 
  69 
  70 def is_url_safe(url):
  71     if not url.startswith("https://"):
  72         return False
  73 
  74     if not validators.url(url, public=True):
  75         return False
  76 
  77     whitelist_urls = os.environ["WHITELISTED_CALLBACK_URLS"].split(';')
  78     if url in whitelist_urls:
  79         return True
  80 
  81     forbidden_urls = os.environ["FORBIDDEN_CALLBACK_URLS"].split(';')
  82     for furl in forbidden_urls:
  83         if furl in url:
  84             return False
  85 
  86     return True
  87 
  88 
  89 def generate_secret():
  90     key = hexlify(os.urandom(30)).decode()
  91     dashed = '-'.join(textwrap.wrap(key, 15))
  92 
  93     return dashed
  94
  ```
  --- 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/backend/uclapi/dashboard/app_helpers.py b/backend/uclapi/dashboard/app_helpers.py
  --- a/backend/uclapi/dashboard/app_helpers.py
  +++ b/backend/uclapi/dashboard/app_helpers.py
  @@ -4,9 +4,10 @@
   from common.helpers import generate_api_token
   from uclapi.settings import (
       MEDIUM_ARTICLE_QUANTITY,
  -    REDIS_UCLAPI_HOST
  +    REDIS_UCLAPI_HOST,
  +    DEBUG
   )
  -
  +from django.core.management import call_command
   import os
   import redis
   import textwrap
  @@ -15,6 +16,11 @@
   
   def get_articles():
       r = redis.Redis(host=REDIS_UCLAPI_HOST)
  +    if not r.exists("Blog:item:1:url"):
  +        if DEBUG:
  +            call_command('update_medium')
  +        else:
  +            return []
       pipe = r.pipeline()
       articles = []
       for i in range(0, MEDIUM_ARTICLE_QUANTITY):
  
verification_info: {"golden_diff": "diff --git a/backend/uclapi/dashboard/app_helpers.py b/backend/uclapi/dashboard/app_helpers.py\n--- a/backend/uclapi/dashboard/app_helpers.py\n+++ b/backend/uclapi/dashboard/app_helpers.py\n@@ -4,9 +4,10 @@\n from common.helpers import generate_api_token\n from uclapi.settings import (\n     MEDIUM_ARTICLE_QUANTITY,\n-    REDIS_UCLAPI_HOST\n+    REDIS_UCLAPI_HOST,\n+    DEBUG\n )\n-\n+from django.core.management import call_command\n import os\n import redis\n import textwrap\n@@ -15,6 +16,11 @@\n \n def get_articles():\n     r = redis.Redis(host=REDIS_UCLAPI_HOST)\n+    if not r.exists(\"Blog:item:1:url\"):\n+        if DEBUG:\n+            call_command('update_medium')\n+        else:\n+            return []\n     pipe = r.pipeline()\n     articles = []\n     for i in range(0, MEDIUM_ARTICLE_QUANTITY):\n", "issue": "Medium Articles Bug\nBug in getting medium articles on the homepage\n", "before_files": [{"content": "from binascii import hexlify\nfrom random import SystemRandom\n\nfrom common.helpers import generate_api_token\nfrom uclapi.settings import (\n    MEDIUM_ARTICLE_QUANTITY,\n    REDIS_UCLAPI_HOST\n)\n\nimport os\nimport redis\nimport textwrap\nimport validators\n\n\ndef get_articles():\n    r = redis.Redis(host=REDIS_UCLAPI_HOST)\n    pipe = r.pipeline()\n    articles = []\n    for i in range(0, MEDIUM_ARTICLE_QUANTITY):\n        articles.append({})\n        redis_key_url = \"Blog:item:{}:url\".format(i)\n        redis_key_title = \"Blog:item:{}:title\".format(i)\n        pipe.get(redis_key_url)\n        pipe.get(redis_key_title)\n    redis_response = pipe.execute()\n    for i in range(0, MEDIUM_ARTICLE_QUANTITY):\n        articles[i]['url'] = redis_response[i*2].decode(\"utf-8\")\n        articles[i]['title'] = redis_response[i*2+1].decode(\"utf-8\")\n    return articles\n\n\ndef generate_temp_api_token():\n    return generate_api_token(\"temp\")\n\n\ndef get_temp_token():\n    r = redis.Redis(host=REDIS_UCLAPI_HOST)\n\n    token = generate_temp_api_token()\n    # We initialise a new temporary token and set it to 1\n    # as it is generated at its first usage.\n    r.set(token, 1, 600)\n    return token\n\n\ndef generate_app_id():\n    key = hexlify(os.urandom(5)).decode()\n    final = \"A\" + key\n\n    return final\n\n\ndef generate_app_client_id():\n    sr = SystemRandom()\n\n    client_id = '{}.{}'.format(\n        ''.join(str(sr.randint(0, 9)) for _ in range(16)),\n        ''.join(str(sr.randint(0, 9)) for _ in range(16))\n    )\n\n    return client_id\n\n\ndef generate_app_client_secret():\n    client_secret = hexlify(os.urandom(32)).decode()\n    return client_secret\n\n\ndef is_url_safe(url):\n    if not url.startswith(\"https://\"):\n        return False\n\n    if not validators.url(url, public=True):\n        return False\n\n    whitelist_urls = os.environ[\"WHITELISTED_CALLBACK_URLS\"].split(';')\n    if url in whitelist_urls:\n        return True\n\n    forbidden_urls = os.environ[\"FORBIDDEN_CALLBACK_URLS\"].split(';')\n    for furl in forbidden_urls:\n        if furl in url:\n            return False\n\n    return True\n\n\ndef generate_secret():\n    key = hexlify(os.urandom(30)).decode()\n    dashed = '-'.join(textwrap.wrap(key, 15))\n\n    return dashed\n", "path": "backend/uclapi/dashboard/app_helpers.py"}], "after_files": [{"content": "from binascii import hexlify\nfrom random import SystemRandom\n\nfrom common.helpers import generate_api_token\nfrom uclapi.settings import (\n    MEDIUM_ARTICLE_QUANTITY,\n    REDIS_UCLAPI_HOST,\n    DEBUG\n)\nfrom django.core.management import call_command\nimport os\nimport redis\nimport textwrap\nimport validators\n\n\ndef get_articles():\n    r = redis.Redis(host=REDIS_UCLAPI_HOST)\n    if not r.exists(\"Blog:item:1:url\"):\n        if DEBUG:\n            call_command('update_medium')\n        else:\n            return []\n    pipe = r.pipeline()\n    articles = []\n    for i in range(0, MEDIUM_ARTICLE_QUANTITY):\n        articles.append({})\n        redis_key_url = \"Blog:item:{}:url\".format(i)\n        redis_key_title = \"Blog:item:{}:title\".format(i)\n        pipe.get(redis_key_url)\n        pipe.get(redis_key_title)\n    redis_response = pipe.execute()\n    for i in range(0, MEDIUM_ARTICLE_QUANTITY):\n        articles[i]['url'] = redis_response[i*2].decode(\"utf-8\")\n        articles[i]['title'] = redis_response[i*2+1].decode(\"utf-8\")\n    return articles\n\n\ndef generate_temp_api_token():\n    return generate_api_token(\"temp\")\n\n\ndef get_temp_token():\n    r = redis.Redis(host=REDIS_UCLAPI_HOST)\n\n    token = generate_temp_api_token()\n    # We initialise a new temporary token and set it to 1\n    # as it is generated at its first usage.\n    r.set(token, 1, 600)\n    return token\n\n\ndef generate_app_id():\n    key = hexlify(os.urandom(5)).decode()\n    final = \"A\" + key\n\n    return final\n\n\ndef generate_app_client_id():\n    sr = SystemRandom()\n\n    client_id = '{}.{}'.format(\n        ''.join(str(sr.randint(0, 9)) for _ in range(16)),\n        ''.join(str(sr.randint(0, 9)) for _ in range(16))\n    )\n\n    return client_id\n\n\ndef generate_app_client_secret():\n    client_secret = hexlify(os.urandom(32)).decode()\n    return client_secret\n\n\ndef is_url_safe(url):\n    if not url.startswith(\"https://\"):\n        return False\n\n    if not validators.url(url, public=True):\n        return False\n\n    whitelist_urls = os.environ[\"WHITELISTED_CALLBACK_URLS\"].split(';')\n    if url in whitelist_urls:\n        return True\n\n    forbidden_urls = os.environ[\"FORBIDDEN_CALLBACK_URLS\"].split(';')\n    for furl in forbidden_urls:\n        if furl in url:\n            return False\n\n    return True\n\n\ndef generate_secret():\n    key = hexlify(os.urandom(30)).decode()\n    dashed = '-'.join(textwrap.wrap(key, 15))\n\n    return dashed\n", "path": "backend/uclapi/dashboard/app_helpers.py"}]}