We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Should we drop Python 3.5 support
It has been raised a few times in the Matrix chat that we should consider dropping Python 3.5 support.

There are a number of improvements in [Python 3.6](https://docs.python.org/3/whatsnew/3.6.html) which we could benefit from. This would also be a breaking change for users still on 3.5 and will require them to upgrade to continue using opsdroid.

The reason this has cropped up for me again is because there appears to be a bug still in 3.5.7 which causes problems with catching exceptions within coroutines. This problem is not present in 3.6.8. I would rather not have to work around this bug if I can help it.

We decided to support 3.5+ because that is the default version which comes pre-installed on the latest release of Debian and variations like Raspbian. This should ensure good support for many users without them having to tinker with their Python and provide a good beginner experience.

As this is an open source software project with a motivation around self hosting and privacy it isn't possible to collect user metrics on Python versions being used. Otherwise we could use this data to asses the impact of dropping 3.5.

[Home Assistant](https://www.home-assistant.io/) (the project which inspired much of opsdroid's community practices) are moving to only supporting the two most recent minor versions of Python, which means they will also be dropping 3.5 in the near future.

My proposal would be to follow their lead. This does put a responsibility on us to keep an eye on Python releases (3.8 is [pencilled in](https://www.python.org/dev/peps/pep-0569/) for the end of the year) and remove support as versions are released.

I would love thoughts and feedback from the community.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setup.py`
Content:
```
1 #!/usr/bin/env python3
2 import os
3 from setuptools import setup, find_packages
4 from setuptools.command.build_py import build_py
5 from setuptools.command.sdist import sdist
6 from setuptools.command.develop import develop
7 import versioneer
8 
9 PACKAGE_NAME = 'opsdroid'
10 HERE = os.path.abspath(os.path.dirname(__file__))
11 README = open(os.path.join(HERE, 'README.md'), encoding="utf8").read()
12 
13 PACKAGES = find_packages(exclude=['tests', 'tests.*', 'modules',
14                                   'modules.*', 'docs', 'docs.*'])
15 
16 
17 # For now we simply define the install_requires based on the contents
18 # of requirements.txt. In the future, install_requires may become much
19 # looser than the (automatically) resolved requirements.txt.
20 with open(os.path.join(HERE, 'requirements.txt'), 'r') as fh:
21     REQUIRES = [line.strip() for line in fh]
22 
23 
24 class Develop(develop):
25     """Custom `develop` command to always build mo files on install -e."""
26 
27     def run(self):
28         self.run_command('compile_catalog')
29         develop.run(self)  # old style class
30 
31 
32 class BuildPy(build_py):
33     """Custom `build_py` command to always build mo files for wheels."""
34 
35     def run(self):
36         self.run_command('compile_catalog')
37         build_py.run(self)  # old style class
38 
39 
40 class Sdist(sdist):
41     """Custom `sdist` command to ensure that mo files are always created."""
42 
43     def run(self):
44         self.run_command('compile_catalog')
45         sdist.run(self)   # old style class
46 
47 
48 setup(
49     name=PACKAGE_NAME,
50     version=versioneer.get_version(),
51     license='Apache License 2.0',
52     url='https://opsdroid.github.io/',
53     download_url='https://github.com/opsdroid/opsdroid/releases',
54     author='Jacob Tomlinson',
55     author_email='jacob@tom.linson.uk',
56     description='An open source ChatOps bot framework.',
57     long_description=README,
58     long_description_content_type='text/markdown',
59     packages=PACKAGES,
60     include_package_data=True,
61     zip_safe=False,
62     platforms='any',
63     classifiers=[
64         'Development Status :: 4 - Beta',
65         'Environment :: Console',
66         'Framework :: AsyncIO',
67         'Intended Audience :: Developers',
68         'Intended Audience :: System Administrators',
69         'Intended Audience :: Information Technology',
70         'License :: OSI Approved :: Apache Software License',
71         'Programming Language :: Python',
72         'Programming Language :: Python :: 3',
73         'Programming Language :: Python :: 3 :: Only',
74         'Programming Language :: Python :: 3.5',
75         'Programming Language :: Python :: 3.6',
76         'Programming Language :: Python :: 3.7',
77         'Topic :: Communications :: Chat',
78         'Topic :: Scientific/Engineering :: Artificial Intelligence',
79         'Topic :: Software Development :: Libraries :: Python Modules'
80     ],
81     install_requires=REQUIRES,
82     test_suite='tests',
83     keywords=[
84         'bot',
85         'bot-framework',
86         'opsdroid',
87         'botkit',
88         'python3',
89         'asyncio',
90         'chatops',
91         'devops',
92         'nlu'
93     ],
94     setup_requires=['Babel'],
95     cmdclass=versioneer.get_cmdclass({'sdist': Sdist,
96                                       'build_py': BuildPy,
97                                       'develop': Develop}),
98     entry_points={
99         'console_scripts': [
100             'opsdroid = opsdroid.__main__:main'
101         ]
102     },
103 )
104
```

Path: `opsdroid/__main__.py`
Content:
```
1 """Starts opsdroid."""
2 
3 import os
4 import subprocess
5 import sys
6 import logging
7 import gettext
8 import time
9 import contextlib
10 
11 import click
12 
13 from opsdroid import __version__
14 from opsdroid.core import OpsDroid
15 from opsdroid.loader import Loader
16 from opsdroid.const import DEFAULT_LOG_FILENAME, LOCALE_DIR, \
17     EXAMPLE_CONFIG_FILE, DEFAULT_LANGUAGE, DEFAULT_CONFIG_PATH
18 
19 
20 gettext.install('opsdroid')
21 _LOGGER = logging.getLogger("opsdroid")
22 
23 
24 def configure_lang(config):
25     """Configure app language based on user config.
26 
27     Args:
28         config: Language Configuration and it uses ISO 639-1 code.
29         for more info https://en.m.wikipedia.org/wiki/List_of_ISO_639-1_codes
30 
31 
32     """
33     lang_code = config.get("lang", DEFAULT_LANGUAGE)
34     if lang_code != DEFAULT_LANGUAGE:
35         lang = gettext.translation(
36             'opsdroid', LOCALE_DIR, (lang_code,), fallback=True)
37         lang.install()
38 
39 
40 def configure_logging(config):
41     """Configure the root logger based on user config."""
42     rootlogger = logging.getLogger()
43     while rootlogger.handlers:
44         rootlogger.handlers.pop()
45 
46     try:
47         if config["logging"]["path"]:
48             logfile_path = os.path.expanduser(config["logging"]["path"])
49         else:
50             logfile_path = config["logging"]["path"]
51     except KeyError:
52         logfile_path = DEFAULT_LOG_FILENAME
53 
54     try:
55         log_level = get_logging_level(
56             config["logging"]["level"])
57     except KeyError:
58         log_level = logging.INFO
59 
60     rootlogger.setLevel(log_level)
61     formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')
62 
63     console_handler = logging.StreamHandler()
64     console_handler.setLevel(log_level)
65     console_handler.setFormatter(formatter)
66     rootlogger.addHandler(console_handler)
67 
68     with contextlib.suppress(KeyError):
69         if not config["logging"]["console"]:
70             console_handler.setLevel(logging.CRITICAL)
71 
72     if logfile_path:
73         logdir = os.path.dirname(os.path.realpath(logfile_path))
74         if not os.path.isdir(logdir):
75             os.makedirs(logdir)
76         file_handler = logging.FileHandler(logfile_path)
77         file_handler.setLevel(log_level)
78         file_handler.setFormatter(formatter)
79         rootlogger.addHandler(file_handler)
80     _LOGGER.info("="*40)
81     _LOGGER.info(_("Started opsdroid %s"), __version__)
82 
83 
84 def get_logging_level(logging_level):
85     """Get the logger level based on the user configuration.
86 
87     Args:
88         logging_level: logging level from config file
89 
90     Returns:
91         logging LEVEL ->
92             CRITICAL = 50
93             FATAL = CRITICAL
94             ERROR = 40
95             WARNING = 30
96             WARN = WARNING
97             INFO = 20
98             DEBUG = 10
99             NOTSET = 0
100 
101     """
102     if logging_level == 'critical':
103         return logging.CRITICAL
104 
105     if logging_level == 'error':
106         return logging.ERROR
107     if logging_level == 'warning':
108         return logging.WARNING
109 
110     if logging_level == 'debug':
111         return logging.DEBUG
112 
113     return logging.INFO
114 
115 
116 def check_dependencies():
117     """Check for system dependencies required by opsdroid."""
118     if sys.version_info.major < 3 or sys.version_info.minor < 5:
119         logging.critical(_("Whoops! opsdroid requires python 3.5 or above."))
120         sys.exit(1)
121 
122 
123 def print_version(ctx, param, value):
124     """Print out the version of opsdroid that is installed."""
125     if not value or ctx.resilient_parsing:
126         return
127     click.echo('opsdroid {version}'.format(version=__version__))
128     ctx.exit(0)
129 
130 
131 def print_example_config(ctx, param, value):
132     """Print out the example config."""
133     if not value or ctx.resilient_parsing:
134         return
135     with open(EXAMPLE_CONFIG_FILE, 'r') as conf:
136         click.echo(conf.read())
137     ctx.exit(0)
138 
139 
140 def edit_files(ctx, param, value):
141     """Open config/log file with favourite editor."""
142     if value == 'config':
143         file = DEFAULT_CONFIG_PATH
144     elif value == 'log':
145         file = DEFAULT_LOG_FILENAME
146     else:
147         return
148 
149     editor = os.environ.get('EDITOR', 'vi')
150     if editor == 'vi':
151         click.echo('You are about to edit a file in vim. \n'
152                    'Read the tutorial on vim at: https://bit.ly/2HRvvrB')
153         time.sleep(3)
154 
155     subprocess.run([editor, file])
156     ctx.exit(0)
157 
158 
159 def welcome_message(config):
160     """Add welcome message if set to true in configuration.
161 
162     Args:
163         config: config loaded by Loader
164 
165     Raises:
166         KeyError: If 'welcome-message' key is not found in configuration file
167 
168     """
169     try:
170         if config['welcome-message']:
171             _LOGGER.info("=" * 40)
172             _LOGGER.info(_("You can customise your opsdroid by modifying "
173                            "your configuration.yaml"))
174             _LOGGER.info(_("Read more at: "
175                            "http://opsdroid.readthedocs.io/#configuration"))
176             _LOGGER.info(_("Watch the Get Started Videos at: "
177                            "http://bit.ly/2fnC0Fh"))
178             _LOGGER.info(_("Install Opsdroid Desktop at: \n"
179                            "https://github.com/opsdroid/opsdroid-desktop/"
180                            "releases"))
181             _LOGGER.info("=" * 40)
182     except KeyError:
183         _LOGGER.warning(_("'welcome-message: true/false' is missing in "
184                           "configuration.yaml"))
185 
186 
187 @click.command()
188 @click.option('--gen-config', is_flag=True, callback=print_example_config,
189               expose_value=False, default=False,
190               help='Print an example config and exit.')
191 @click.option('--version', '-v', is_flag=True, callback=print_version,
192               expose_value=False, default=False, is_eager=True,
193               help='Print the version and exit.')
194 @click.option('--edit-config', '-e', is_flag=True, callback=edit_files,
195               default=False, flag_value='config', expose_value=False,
196               help='Opens configuration.yaml with your favorite editor'
197                    ' and exits.')
198 @click.option('--view-log', '-l', is_flag=True, callback=edit_files,
199               default=False, flag_value='log', expose_value=False,
200               help='Opens opsdroid logs with your favorite editor'
201                    ' and exits.')
202 def main():
203     """Opsdroid is a chat bot framework written in Python.
204 
205     It is designed to be extendable, scalable and simple.
206     See https://opsdroid.github.io/ for more information.
207     """
208     check_dependencies()
209 
210     config = Loader.load_config_file([
211         "configuration.yaml",
212         DEFAULT_CONFIG_PATH,
213         "/etc/opsdroid/configuration.yaml"
214         ])
215     configure_lang(config)
216     configure_logging(config)
217     welcome_message(config)
218 
219     with OpsDroid(config=config) as opsdroid:
220         opsdroid.load()
221         opsdroid.run()
222 
223 
224 def init():
225     """Enter the application."""
226     if __name__ == "__main__":
227         main()
228 
229 
230 init()
231
```
--- 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/opsdroid/__main__.py b/opsdroid/__main__.py
--- a/opsdroid/__main__.py
+++ b/opsdroid/__main__.py
@@ -115,8 +115,8 @@
 
 def check_dependencies():
     """Check for system dependencies required by opsdroid."""
-    if sys.version_info.major < 3 or sys.version_info.minor < 5:
-        logging.critical(_("Whoops! opsdroid requires python 3.5 or above."))
+    if sys.version_info.major < 3 or sys.version_info.minor < 6:
+        logging.critical(_("Whoops! opsdroid requires python 3.6 or above."))
         sys.exit(1)
 
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -71,7 +71,6 @@
         'Programming Language :: Python',
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3 :: Only',
-        'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Topic :: Communications :: Chat',

{"golden_diff": "diff --git a/opsdroid/__main__.py b/opsdroid/__main__.py\n--- a/opsdroid/__main__.py\n+++ b/opsdroid/__main__.py\n@@ -115,8 +115,8 @@\n \n def check_dependencies():\n     \"\"\"Check for system dependencies required by opsdroid.\"\"\"\n-    if sys.version_info.major < 3 or sys.version_info.minor < 5:\n-        logging.critical(_(\"Whoops! opsdroid requires python 3.5 or above.\"))\n+    if sys.version_info.major < 3 or sys.version_info.minor < 6:\n+        logging.critical(_(\"Whoops! opsdroid requires python 3.6 or above.\"))\n         sys.exit(1)\n \n \ndiff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -71,7 +71,6 @@\n         'Programming Language :: Python',\n         'Programming Language :: Python :: 3',\n         'Programming Language :: Python :: 3 :: Only',\n-        'Programming Language :: Python :: 3.5',\n         'Programming Language :: Python :: 3.6',\n         'Programming Language :: Python :: 3.7',\n         'Topic :: Communications :: Chat',\n", "issue": "Should we drop Python 3.5 support\nIt has been raised a few times in the Matrix chat that we should consider dropping Python 3.5 support.\r\n\r\nThere are a number of improvements in [Python 3.6](https://docs.python.org/3/whatsnew/3.6.html) which we could benefit from. This would also be a breaking change for users still on 3.5 and will require them to upgrade to continue using opsdroid.\r\n\r\nThe reason this has cropped up for me again is because there appears to be a bug still in 3.5.7 which causes problems with catching exceptions within coroutines. This problem is not present in 3.6.8. I would rather not have to work around this bug if I can help it.\r\n\r\nWe decided to support 3.5+ because that is the default version which comes pre-installed on the latest release of Debian and variations like Raspbian. This should ensure good support for many users without them having to tinker with their Python and provide a good beginner experience.\r\n\r\nAs this is an open source software project with a motivation around self hosting and privacy it isn't possible to collect user metrics on Python versions being used. Otherwise we could use this data to asses the impact of dropping 3.5.\r\n\r\n[Home Assistant](https://www.home-assistant.io/) (the project which inspired much of opsdroid's community practices) are moving to only supporting the two most recent minor versions of Python, which means they will also be dropping 3.5 in the near future.\r\n\r\nMy proposal would be to follow their lead. This does put a responsibility on us to keep an eye on Python releases (3.8 is [pencilled in](https://www.python.org/dev/peps/pep-0569/) for the end of the year) and remove support as versions are released.\r\n\r\nI would love thoughts and feedback from the community.\n", "before_files": [{"content": "#!/usr/bin/env python3\nimport os\nfrom setuptools import setup, find_packages\nfrom setuptools.command.build_py import build_py\nfrom setuptools.command.sdist import sdist\nfrom setuptools.command.develop import develop\nimport versioneer\n\nPACKAGE_NAME = 'opsdroid'\nHERE = os.path.abspath(os.path.dirname(__file__))\nREADME = open(os.path.join(HERE, 'README.md'), encoding=\"utf8\").read()\n\nPACKAGES = find_packages(exclude=['tests', 'tests.*', 'modules',\n                                  'modules.*', 'docs', 'docs.*'])\n\n\n# For now we simply define the install_requires based on the contents\n# of requirements.txt. In the future, install_requires may become much\n# looser than the (automatically) resolved requirements.txt.\nwith open(os.path.join(HERE, 'requirements.txt'), 'r') as fh:\n    REQUIRES = [line.strip() for line in fh]\n\n\nclass Develop(develop):\n    \"\"\"Custom `develop` command to always build mo files on install -e.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        develop.run(self)  # old style class\n\n\nclass BuildPy(build_py):\n    \"\"\"Custom `build_py` command to always build mo files for wheels.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        build_py.run(self)  # old style class\n\n\nclass Sdist(sdist):\n    \"\"\"Custom `sdist` command to ensure that mo files are always created.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        sdist.run(self)   # old style class\n\n\nsetup(\n    name=PACKAGE_NAME,\n    version=versioneer.get_version(),\n    license='Apache License 2.0',\n    url='https://opsdroid.github.io/',\n    download_url='https://github.com/opsdroid/opsdroid/releases',\n    author='Jacob Tomlinson',\n    author_email='jacob@tom.linson.uk',\n    description='An open source ChatOps bot framework.',\n    long_description=README,\n    long_description_content_type='text/markdown',\n    packages=PACKAGES,\n    include_package_data=True,\n    zip_safe=False,\n    platforms='any',\n    classifiers=[\n        'Development Status :: 4 - Beta',\n        'Environment :: Console',\n        'Framework :: AsyncIO',\n        'Intended Audience :: Developers',\n        'Intended Audience :: System Administrators',\n        'Intended Audience :: Information Technology',\n        'License :: OSI Approved :: Apache Software License',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3 :: Only',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n        'Topic :: Communications :: Chat',\n        'Topic :: Scientific/Engineering :: Artificial Intelligence',\n        'Topic :: Software Development :: Libraries :: Python Modules'\n    ],\n    install_requires=REQUIRES,\n    test_suite='tests',\n    keywords=[\n        'bot',\n        'bot-framework',\n        'opsdroid',\n        'botkit',\n        'python3',\n        'asyncio',\n        'chatops',\n        'devops',\n        'nlu'\n    ],\n    setup_requires=['Babel'],\n    cmdclass=versioneer.get_cmdclass({'sdist': Sdist,\n                                      'build_py': BuildPy,\n                                      'develop': Develop}),\n    entry_points={\n        'console_scripts': [\n            'opsdroid = opsdroid.__main__:main'\n        ]\n    },\n)\n", "path": "setup.py"}, {"content": "\"\"\"Starts opsdroid.\"\"\"\n\nimport os\nimport subprocess\nimport sys\nimport logging\nimport gettext\nimport time\nimport contextlib\n\nimport click\n\nfrom opsdroid import __version__\nfrom opsdroid.core import OpsDroid\nfrom opsdroid.loader import Loader\nfrom opsdroid.const import DEFAULT_LOG_FILENAME, LOCALE_DIR, \\\n    EXAMPLE_CONFIG_FILE, DEFAULT_LANGUAGE, DEFAULT_CONFIG_PATH\n\n\ngettext.install('opsdroid')\n_LOGGER = logging.getLogger(\"opsdroid\")\n\n\ndef configure_lang(config):\n    \"\"\"Configure app language based on user config.\n\n    Args:\n        config: Language Configuration and it uses ISO 639-1 code.\n        for more info https://en.m.wikipedia.org/wiki/List_of_ISO_639-1_codes\n\n\n    \"\"\"\n    lang_code = config.get(\"lang\", DEFAULT_LANGUAGE)\n    if lang_code != DEFAULT_LANGUAGE:\n        lang = gettext.translation(\n            'opsdroid', LOCALE_DIR, (lang_code,), fallback=True)\n        lang.install()\n\n\ndef configure_logging(config):\n    \"\"\"Configure the root logger based on user config.\"\"\"\n    rootlogger = logging.getLogger()\n    while rootlogger.handlers:\n        rootlogger.handlers.pop()\n\n    try:\n        if config[\"logging\"][\"path\"]:\n            logfile_path = os.path.expanduser(config[\"logging\"][\"path\"])\n        else:\n            logfile_path = config[\"logging\"][\"path\"]\n    except KeyError:\n        logfile_path = DEFAULT_LOG_FILENAME\n\n    try:\n        log_level = get_logging_level(\n            config[\"logging\"][\"level\"])\n    except KeyError:\n        log_level = logging.INFO\n\n    rootlogger.setLevel(log_level)\n    formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')\n\n    console_handler = logging.StreamHandler()\n    console_handler.setLevel(log_level)\n    console_handler.setFormatter(formatter)\n    rootlogger.addHandler(console_handler)\n\n    with contextlib.suppress(KeyError):\n        if not config[\"logging\"][\"console\"]:\n            console_handler.setLevel(logging.CRITICAL)\n\n    if logfile_path:\n        logdir = os.path.dirname(os.path.realpath(logfile_path))\n        if not os.path.isdir(logdir):\n            os.makedirs(logdir)\n        file_handler = logging.FileHandler(logfile_path)\n        file_handler.setLevel(log_level)\n        file_handler.setFormatter(formatter)\n        rootlogger.addHandler(file_handler)\n    _LOGGER.info(\"=\"*40)\n    _LOGGER.info(_(\"Started opsdroid %s\"), __version__)\n\n\ndef get_logging_level(logging_level):\n    \"\"\"Get the logger level based on the user configuration.\n\n    Args:\n        logging_level: logging level from config file\n\n    Returns:\n        logging LEVEL ->\n            CRITICAL = 50\n            FATAL = CRITICAL\n            ERROR = 40\n            WARNING = 30\n            WARN = WARNING\n            INFO = 20\n            DEBUG = 10\n            NOTSET = 0\n\n    \"\"\"\n    if logging_level == 'critical':\n        return logging.CRITICAL\n\n    if logging_level == 'error':\n        return logging.ERROR\n    if logging_level == 'warning':\n        return logging.WARNING\n\n    if logging_level == 'debug':\n        return logging.DEBUG\n\n    return logging.INFO\n\n\ndef check_dependencies():\n    \"\"\"Check for system dependencies required by opsdroid.\"\"\"\n    if sys.version_info.major < 3 or sys.version_info.minor < 5:\n        logging.critical(_(\"Whoops! opsdroid requires python 3.5 or above.\"))\n        sys.exit(1)\n\n\ndef print_version(ctx, param, value):\n    \"\"\"Print out the version of opsdroid that is installed.\"\"\"\n    if not value or ctx.resilient_parsing:\n        return\n    click.echo('opsdroid {version}'.format(version=__version__))\n    ctx.exit(0)\n\n\ndef print_example_config(ctx, param, value):\n    \"\"\"Print out the example config.\"\"\"\n    if not value or ctx.resilient_parsing:\n        return\n    with open(EXAMPLE_CONFIG_FILE, 'r') as conf:\n        click.echo(conf.read())\n    ctx.exit(0)\n\n\ndef edit_files(ctx, param, value):\n    \"\"\"Open config/log file with favourite editor.\"\"\"\n    if value == 'config':\n        file = DEFAULT_CONFIG_PATH\n    elif value == 'log':\n        file = DEFAULT_LOG_FILENAME\n    else:\n        return\n\n    editor = os.environ.get('EDITOR', 'vi')\n    if editor == 'vi':\n        click.echo('You are about to edit a file in vim. \\n'\n                   'Read the tutorial on vim at: https://bit.ly/2HRvvrB')\n        time.sleep(3)\n\n    subprocess.run([editor, file])\n    ctx.exit(0)\n\n\ndef welcome_message(config):\n    \"\"\"Add welcome message if set to true in configuration.\n\n    Args:\n        config: config loaded by Loader\n\n    Raises:\n        KeyError: If 'welcome-message' key is not found in configuration file\n\n    \"\"\"\n    try:\n        if config['welcome-message']:\n            _LOGGER.info(\"=\" * 40)\n            _LOGGER.info(_(\"You can customise your opsdroid by modifying \"\n                           \"your configuration.yaml\"))\n            _LOGGER.info(_(\"Read more at: \"\n                           \"http://opsdroid.readthedocs.io/#configuration\"))\n            _LOGGER.info(_(\"Watch the Get Started Videos at: \"\n                           \"http://bit.ly/2fnC0Fh\"))\n            _LOGGER.info(_(\"Install Opsdroid Desktop at: \\n\"\n                           \"https://github.com/opsdroid/opsdroid-desktop/\"\n                           \"releases\"))\n            _LOGGER.info(\"=\" * 40)\n    except KeyError:\n        _LOGGER.warning(_(\"'welcome-message: true/false' is missing in \"\n                          \"configuration.yaml\"))\n\n\n@click.command()\n@click.option('--gen-config', is_flag=True, callback=print_example_config,\n              expose_value=False, default=False,\n              help='Print an example config and exit.')\n@click.option('--version', '-v', is_flag=True, callback=print_version,\n              expose_value=False, default=False, is_eager=True,\n              help='Print the version and exit.')\n@click.option('--edit-config', '-e', is_flag=True, callback=edit_files,\n              default=False, flag_value='config', expose_value=False,\n              help='Opens configuration.yaml with your favorite editor'\n                   ' and exits.')\n@click.option('--view-log', '-l', is_flag=True, callback=edit_files,\n              default=False, flag_value='log', expose_value=False,\n              help='Opens opsdroid logs with your favorite editor'\n                   ' and exits.')\ndef main():\n    \"\"\"Opsdroid is a chat bot framework written in Python.\n\n    It is designed to be extendable, scalable and simple.\n    See https://opsdroid.github.io/ for more information.\n    \"\"\"\n    check_dependencies()\n\n    config = Loader.load_config_file([\n        \"configuration.yaml\",\n        DEFAULT_CONFIG_PATH,\n        \"/etc/opsdroid/configuration.yaml\"\n        ])\n    configure_lang(config)\n    configure_logging(config)\n    welcome_message(config)\n\n    with OpsDroid(config=config) as opsdroid:\n        opsdroid.load()\n        opsdroid.run()\n\n\ndef init():\n    \"\"\"Enter the application.\"\"\"\n    if __name__ == \"__main__\":\n        main()\n\n\ninit()\n", "path": "opsdroid/__main__.py"}], "after_files": [{"content": "#!/usr/bin/env python3\nimport os\nfrom setuptools import setup, find_packages\nfrom setuptools.command.build_py import build_py\nfrom setuptools.command.sdist import sdist\nfrom setuptools.command.develop import develop\nimport versioneer\n\nPACKAGE_NAME = 'opsdroid'\nHERE = os.path.abspath(os.path.dirname(__file__))\nREADME = open(os.path.join(HERE, 'README.md'), encoding=\"utf8\").read()\n\nPACKAGES = find_packages(exclude=['tests', 'tests.*', 'modules',\n                                  'modules.*', 'docs', 'docs.*'])\n\n\n# For now we simply define the install_requires based on the contents\n# of requirements.txt. In the future, install_requires may become much\n# looser than the (automatically) resolved requirements.txt.\nwith open(os.path.join(HERE, 'requirements.txt'), 'r') as fh:\n    REQUIRES = [line.strip() for line in fh]\n\n\nclass Develop(develop):\n    \"\"\"Custom `develop` command to always build mo files on install -e.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        develop.run(self)  # old style class\n\n\nclass BuildPy(build_py):\n    \"\"\"Custom `build_py` command to always build mo files for wheels.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        build_py.run(self)  # old style class\n\n\nclass Sdist(sdist):\n    \"\"\"Custom `sdist` command to ensure that mo files are always created.\"\"\"\n\n    def run(self):\n        self.run_command('compile_catalog')\n        sdist.run(self)   # old style class\n\n\nsetup(\n    name=PACKAGE_NAME,\n    version=versioneer.get_version(),\n    license='Apache License 2.0',\n    url='https://opsdroid.github.io/',\n    download_url='https://github.com/opsdroid/opsdroid/releases',\n    author='Jacob Tomlinson',\n    author_email='jacob@tom.linson.uk',\n    description='An open source ChatOps bot framework.',\n    long_description=README,\n    long_description_content_type='text/markdown',\n    packages=PACKAGES,\n    include_package_data=True,\n    zip_safe=False,\n    platforms='any',\n    classifiers=[\n        'Development Status :: 4 - Beta',\n        'Environment :: Console',\n        'Framework :: AsyncIO',\n        'Intended Audience :: Developers',\n        'Intended Audience :: System Administrators',\n        'Intended Audience :: Information Technology',\n        'License :: OSI Approved :: Apache Software License',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3 :: Only',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n        'Topic :: Communications :: Chat',\n        'Topic :: Scientific/Engineering :: Artificial Intelligence',\n        'Topic :: Software Development :: Libraries :: Python Modules'\n    ],\n    install_requires=REQUIRES,\n    test_suite='tests',\n    keywords=[\n        'bot',\n        'bot-framework',\n        'opsdroid',\n        'botkit',\n        'python3',\n        'asyncio',\n        'chatops',\n        'devops',\n        'nlu'\n    ],\n    setup_requires=['Babel'],\n    cmdclass=versioneer.get_cmdclass({'sdist': Sdist,\n                                      'build_py': BuildPy,\n                                      'develop': Develop}),\n    entry_points={\n        'console_scripts': [\n            'opsdroid = opsdroid.__main__:main'\n        ]\n    },\n)\n", "path": "setup.py"}, {"content": "\"\"\"Starts opsdroid.\"\"\"\n\nimport os\nimport subprocess\nimport sys\nimport logging\nimport gettext\nimport time\nimport contextlib\n\nimport click\n\nfrom opsdroid import __version__\nfrom opsdroid.core import OpsDroid\nfrom opsdroid.loader import Loader\nfrom opsdroid.const import DEFAULT_LOG_FILENAME, LOCALE_DIR, \\\n    EXAMPLE_CONFIG_FILE, DEFAULT_LANGUAGE, DEFAULT_CONFIG_PATH\n\n\ngettext.install('opsdroid')\n_LOGGER = logging.getLogger(\"opsdroid\")\n\n\ndef configure_lang(config):\n    \"\"\"Configure app language based on user config.\n\n    Args:\n        config: Language Configuration and it uses ISO 639-1 code.\n        for more info https://en.m.wikipedia.org/wiki/List_of_ISO_639-1_codes\n\n\n    \"\"\"\n    lang_code = config.get(\"lang\", DEFAULT_LANGUAGE)\n    if lang_code != DEFAULT_LANGUAGE:\n        lang = gettext.translation(\n            'opsdroid', LOCALE_DIR, (lang_code,), fallback=True)\n        lang.install()\n\n\ndef configure_logging(config):\n    \"\"\"Configure the root logger based on user config.\"\"\"\n    rootlogger = logging.getLogger()\n    while rootlogger.handlers:\n        rootlogger.handlers.pop()\n\n    try:\n        if config[\"logging\"][\"path\"]:\n            logfile_path = os.path.expanduser(config[\"logging\"][\"path\"])\n        else:\n            logfile_path = config[\"logging\"][\"path\"]\n    except KeyError:\n        logfile_path = DEFAULT_LOG_FILENAME\n\n    try:\n        log_level = get_logging_level(\n            config[\"logging\"][\"level\"])\n    except KeyError:\n        log_level = logging.INFO\n\n    rootlogger.setLevel(log_level)\n    formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')\n\n    console_handler = logging.StreamHandler()\n    console_handler.setLevel(log_level)\n    console_handler.setFormatter(formatter)\n    rootlogger.addHandler(console_handler)\n\n    with contextlib.suppress(KeyError):\n        if not config[\"logging\"][\"console\"]:\n            console_handler.setLevel(logging.CRITICAL)\n\n    if logfile_path:\n        logdir = os.path.dirname(os.path.realpath(logfile_path))\n        if not os.path.isdir(logdir):\n            os.makedirs(logdir)\n        file_handler = logging.FileHandler(logfile_path)\n        file_handler.setLevel(log_level)\n        file_handler.setFormatter(formatter)\n        rootlogger.addHandler(file_handler)\n    _LOGGER.info(\"=\"*40)\n    _LOGGER.info(_(\"Started opsdroid %s\"), __version__)\n\n\ndef get_logging_level(logging_level):\n    \"\"\"Get the logger level based on the user configuration.\n\n    Args:\n        logging_level: logging level from config file\n\n    Returns:\n        logging LEVEL ->\n            CRITICAL = 50\n            FATAL = CRITICAL\n            ERROR = 40\n            WARNING = 30\n            WARN = WARNING\n            INFO = 20\n            DEBUG = 10\n            NOTSET = 0\n\n    \"\"\"\n    if logging_level == 'critical':\n        return logging.CRITICAL\n\n    if logging_level == 'error':\n        return logging.ERROR\n    if logging_level == 'warning':\n        return logging.WARNING\n\n    if logging_level == 'debug':\n        return logging.DEBUG\n\n    return logging.INFO\n\n\ndef check_dependencies():\n    \"\"\"Check for system dependencies required by opsdroid.\"\"\"\n    if sys.version_info.major < 3 or sys.version_info.minor < 6:\n        logging.critical(_(\"Whoops! opsdroid requires python 3.6 or above.\"))\n        sys.exit(1)\n\n\ndef print_version(ctx, param, value):\n    \"\"\"Print out the version of opsdroid that is installed.\"\"\"\n    if not value or ctx.resilient_parsing:\n        return\n    click.echo('opsdroid {version}'.format(version=__version__))\n    ctx.exit(0)\n\n\ndef print_example_config(ctx, param, value):\n    \"\"\"Print out the example config.\"\"\"\n    if not value or ctx.resilient_parsing:\n        return\n    with open(EXAMPLE_CONFIG_FILE, 'r') as conf:\n        click.echo(conf.read())\n    ctx.exit(0)\n\n\ndef edit_files(ctx, param, value):\n    \"\"\"Open config/log file with favourite editor.\"\"\"\n    if value == 'config':\n        file = DEFAULT_CONFIG_PATH\n    elif value == 'log':\n        file = DEFAULT_LOG_FILENAME\n    else:\n        return\n\n    editor = os.environ.get('EDITOR', 'vi')\n    if editor == 'vi':\n        click.echo('You are about to edit a file in vim. \\n'\n                   'Read the tutorial on vim at: https://bit.ly/2HRvvrB')\n        time.sleep(3)\n\n    subprocess.run([editor, file])\n    ctx.exit(0)\n\n\ndef welcome_message(config):\n    \"\"\"Add welcome message if set to true in configuration.\n\n    Args:\n        config: config loaded by Loader\n\n    Raises:\n        KeyError: If 'welcome-message' key is not found in configuration file\n\n    \"\"\"\n    try:\n        if config['welcome-message']:\n            _LOGGER.info(\"=\" * 40)\n            _LOGGER.info(_(\"You can customise your opsdroid by modifying \"\n                           \"your configuration.yaml\"))\n            _LOGGER.info(_(\"Read more at: \"\n                           \"http://opsdroid.readthedocs.io/#configuration\"))\n            _LOGGER.info(_(\"Watch the Get Started Videos at: \"\n                           \"http://bit.ly/2fnC0Fh\"))\n            _LOGGER.info(_(\"Install Opsdroid Desktop at: \\n\"\n                           \"https://github.com/opsdroid/opsdroid-desktop/\"\n                           \"releases\"))\n            _LOGGER.info(\"=\" * 40)\n    except KeyError:\n        _LOGGER.warning(_(\"'welcome-message: true/false' is missing in \"\n                          \"configuration.yaml\"))\n\n\n@click.command()\n@click.option('--gen-config', is_flag=True, callback=print_example_config,\n              expose_value=False, default=False,\n              help='Print an example config and exit.')\n@click.option('--version', '-v', is_flag=True, callback=print_version,\n              expose_value=False, default=False, is_eager=True,\n              help='Print the version and exit.')\n@click.option('--edit-config', '-e', is_flag=True, callback=edit_files,\n              default=False, flag_value='config', expose_value=False,\n              help='Opens configuration.yaml with your favorite editor'\n                   ' and exits.')\n@click.option('--view-log', '-l', is_flag=True, callback=edit_files,\n              default=False, flag_value='log', expose_value=False,\n              help='Opens opsdroid logs with your favorite editor'\n                   ' and exits.')\ndef main():\n    \"\"\"Opsdroid is a chat bot framework written in Python.\n\n    It is designed to be extendable, scalable and simple.\n    See https://opsdroid.github.io/ for more information.\n    \"\"\"\n    check_dependencies()\n\n    config = Loader.load_config_file([\n        \"configuration.yaml\",\n        DEFAULT_CONFIG_PATH,\n        \"/etc/opsdroid/configuration.yaml\"\n        ])\n    configure_lang(config)\n    configure_logging(config)\n    welcome_message(config)\n\n    with OpsDroid(config=config) as opsdroid:\n        opsdroid.load()\n        opsdroid.run()\n\n\ndef init():\n    \"\"\"Enter the application.\"\"\"\n    if __name__ == \"__main__\":\n        main()\n\n\ninit()\n", "path": "opsdroid/__main__.py"}]}