Skip to content
Permalink
Browse files
Create gh-pages branch via GitHub
  • Loading branch information
soperd committed Nov 23, 2018
1 parent 78e9b02 commit 1e9f977273bb9472402403d15956a3e411edad13
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 19 deletions.
@@ -2,7 +2,7 @@
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>chatbot-docs by soperd</title>
<title>chatbot by soperd</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
@@ -11,30 +11,63 @@
</head>
<body>
<section class="page-header">
<h1 class="project-name">chatbot-docs</h1>
<h2 class="project-tagline"></h2>
<h1 class="project-name">chatbot</h1>
<h2 class="project-tagline">Year 1 Project</h2>
<a href="https://github.coventry.ac.uk/soperd/chatbot-docs" class="btn">View on GitHub</a>
</section>

<section class="main-content">
<h3>
<a id="welcome-to-github-pages" class="anchor" href="#welcome-to-github-pages" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Welcome to GitHub Pages.</h3>
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here <a href="https://guides.github.com/features/mastering-markdown/">using GitHub Flavored Markdown</a>, select a template crafted by a designer, and publish. After your page is generated, you can check out the new <code>gh-pages</code> branch locally. If you’re using GitHub Desktop, simply sync your repository and you’ll see the new branch.</p>
<a id="introduction" class="anchor" href="#introduction" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Introduction</h3>
<p>This is a reflective piece on my Year 1 group project. Please view the code <a href="https://github.coventry.ac.uk/soperd/chatbot">here</a>.</p>
<p>The project is a chatbot written in Python 3 primarily for use with Discord. Current features include:</p>
<ul>
<li>Some natural language understanding with <a href="https://rasa.com/">RasaNLU</a>.</li>
<li>Weather forecast integration with <a href="https://darksky.net/">DarkSky</a>.</li>
<li>Location services with <a href="https://nominatim.openstreetmap.org/">Nominantim by OpenStreetMaps</a>.</li>
<li>Datastore integration with <a href="https://redis.io/">Redis</a>.</li>
</ul>
<h3>
<a id="designer-templates" class="anchor" href="#designer-templates" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Designer Templates</h3>
<p>We’ve crafted some handsome templates for you to use. Go ahead and click 'Continue to layouts' to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved.</p>
<a id="design" class="anchor" href="#design" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Design</h3>
<p>As the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.</p>
<p>I did this by putting all code that provided some kind of generic services into the <code>handlers</code> folder of the project. Here you can find a file called <code>services.py</code> which contains a class called <code>Service</code> that acts as a configurable base class. All other services in <code>handlers</code> inherits this <code>Service</code> class and implements its own functionality. For example, the <code>WeatherService</code> class in <code>weather.py</code> contains methods like <code>get_weather_at</code> that takes a given longitude and latitude and queries DarkSky's forecast API.</p>
<p>The services can then be registered using the <code>register_service</code> decorator that can be found in <code>services.py</code>. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in <code>config.json</code>, and stores it in the dictionary <code>global_services</code>.</p>
<p>For all the platform specific implementations, I put the code in the <code>wrappers</code> folder. This contains a file called <code>bot.py</code> which has a class <code>ChatBot</code>. This acts as an interface that defines common behaviours for every bot with methods such as <code>start</code> and <code>stop</code>, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in <code>discord.py</code>. Here we can see the bot inherits <code>ChatBot</code>, implements the <code>start</code> method and defines its own. <code>ChatBot</code> also declares three class members:</p>
<ul>
<li>
<code>services</code>: A dictionary containing instances of services for the bot to use.</li>
<li>
<code>datastore</code>: A Redis client object for the bot to access the datastore.</li>
<li>
<code>config</code>: A <code>ConfigDict</code> object that acts as a representation of the bot's config in <code>config.json</code> (see below).</li>
</ul>
<p>Both services and wrappers are configurable via the <code>config.json</code> file, which looks something like this:</p>
<div class="highlight highlight-source-json"><pre>{
<span class="pl-s"><span class="pl-pds">"</span>discord<span class="pl-pds">"</span></span>: {
<span class="pl-s"><span class="pl-pds">"</span>token<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>&lt;DISCORD TOKEN HERE&gt;<span class="pl-pds">"</span></span>,
<span class="pl-s"><span class="pl-pds">"</span>services<span class="pl-pds">"</span></span>: [
<span class="pl-s"><span class="pl-pds">"</span>weather<span class="pl-pds">"</span></span>,
<span class="pl-s"><span class="pl-pds">"</span>location<span class="pl-pds">"</span></span>
]
},
<span class="pl-s"><span class="pl-pds">"</span>services<span class="pl-pds">"</span></span>: {
<span class="pl-s"><span class="pl-pds">"</span>weather<span class="pl-pds">"</span></span>: {
<span class="pl-s"><span class="pl-pds">"</span>token<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>&lt;DARKSKY TOKEN HERE&gt;<span class="pl-pds">"</span></span>
}
},
<span class="pl-s"><span class="pl-pds">"</span>redis<span class="pl-pds">"</span></span>: {
<span class="pl-s"><span class="pl-pds">"</span>host<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>localhost<span class="pl-pds">"</span></span>,
<span class="pl-s"><span class="pl-pds">"</span>port<span class="pl-pds">"</span></span>: <span class="pl-c1">6379</span>
}
}</pre></div>
<p>This details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the <code>run_discord.py</code> script, this passes the <code>discord</code> configuration to the <code>DiscordBot</code> class constructor, which in turn calls <code>ChatBot</code>'s constructor. If the optional parameter <code>services</code> is <code>None</code> then <code>ChatBot</code>'s constructor then will find the services listed in <code>config.json</code> from the <code>global_services</code> and store them in the <code>services</code> class member. This was my attempt to "inject" services into the bot automatically.</p>
<p><code>DiscordBot</code> is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.</p>
<h3>
<a id="creating-pages-manually" class="anchor" href="#creating-pages-manually" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Creating pages manually</h3>
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
<h3>
<a id="authors-and-contributors" class="anchor" href="#authors-and-contributors" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Authors and Contributors</h3>
<p>You can @mention a GitHub username to generate a link to their profile. The resulting <code>&lt;a&gt;</code> element will link to the contributor’s GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.</p>
<h3>
<a id="support-or-contact" class="anchor" href="#support-or-contact" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Support or Contact</h3>
<p>Having trouble with Pages? Check out our <a href="https://help.github.com/pages">documentation</a> or <a href="https://github.com/contact">contact support</a> and we’ll help you sort it out.</p>
<a id="reflection" class="anchor" href="#reflection" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Reflection</h3>
<p>I think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the <code>global_services</code> dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.</p>

<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.coventry.ac.uk/soperd/chatbot-docs">chatbot-docs</a> is maintained by <a href="https://github.coventry.ac.uk/soperd">soperd</a>.</span>
<span class="site-footer-owner"><a href="https://github.coventry.ac.uk/soperd/chatbot-docs">chatbot</a> is maintained by <a href="https://github.coventry.ac.uk/soperd">soperd</a>.</span>

<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
@@ -1,6 +1,6 @@
{
"name": "chatbot-docs",
"tagline": "",
"body": "### Welcome to GitHub Pages.\r\nThis automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here [using GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/), select a template crafted by a designer, and publish. After your page is generated, you can check out the new `gh-pages` branch locally. If you’re using GitHub Desktop, simply sync your repository and you’ll see the new branch.\r\n\r\n### Designer Templates\r\nWe’ve crafted some handsome templates for you to use. Go ahead and click 'Continue to layouts' to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved.\r\n\r\n### Creating pages manually\r\nIf you prefer to not use the automatic generator, push a branch named `gh-pages` to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.\r\n\r\n### Authors and Contributors\r\nYou can @mention a GitHub username to generate a link to their profile. The resulting `<a>` element will link to the contributor’s GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.\r\n\r\n### Support or Contact\r\nHaving trouble with Pages? Check out our [documentation](https://help.github.com/pages) or [contact support](https://github.com/contact) and we’ll help you sort it out.\r\n",
"name": "chatbot",
"tagline": "Year 1 Project",
"body": "### Introduction\r\nThis is a reflective piece on my Year 1 group project. Please view the code [here](https://github.coventry.ac.uk/soperd/chatbot).\r\n\r\nThe project is a chatbot written in Python 3 primarily for use with Discord. Current features include:\r\n- Some natural language understanding with [RasaNLU](https://rasa.com/).\r\n- Weather forecast integration with [DarkSky](https://darksky.net/).\r\n- Location services with [Nominantim by OpenStreetMaps](https://nominatim.openstreetmap.org/).\r\n- Datastore integration with [Redis](https://redis.io/).\r\n\r\n\r\n### Design\r\nAs the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.\r\n\r\nI did this by putting all code that provided some kind of generic services into the `handlers` folder of the project. Here you can find a file called `services.py` which contains a class called `Service` that acts as a configurable base class. All other services in `handlers` inherits this `Service` class and implements its own functionality. For example, the `WeatherService` class in `weather.py` contains methods like `get_weather_at` that takes a given longitude and latitude and queries DarkSky's forecast API. \r\n\r\nThe services can then be registered using the `register_service` decorator that can be found in `services.py`. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in `config.json`, and stores it in the dictionary `global_services`.\r\n\r\nFor all the platform specific implementations, I put the code in the `wrappers` folder. This contains a file called `bot.py` which has a class `ChatBot`. This acts as an interface that defines common behaviours for every bot with methods such as `start` and `stop`, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in `discord.py`. Here we can see the bot inherits `ChatBot`, implements the `start` method and defines its own. `ChatBot` also declares three class members:\r\n- `services`: A dictionary containing instances of services for the bot to use.\r\n- `datastore`: A Redis client object for the bot to access the datastore.\r\n- `config`: A `ConfigDict` object that acts as a representation of the bot's config in `config.json` (see below).\r\n\r\nBoth services and wrappers are configurable via the `config.json` file, which looks something like this:\r\n\r\n```json\r\n{\r\n \"discord\": {\r\n \"token\": \"<DISCORD TOKEN HERE>\",\r\n \"services\": [\r\n \"weather\",\r\n \"location\"\r\n ]\r\n },\r\n \"services\": {\r\n \"weather\": {\r\n \"token\": \"<DARKSKY TOKEN HERE>\"\r\n }\r\n },\r\n \"redis\": {\r\n \"host\": \"localhost\",\r\n \"port\": 6379\r\n }\r\n}\r\n```\r\n\r\nThis details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the `run_discord.py` script, this passes the `discord` configuration to the `DiscordBot` class constructor, which in turn calls `ChatBot`'s constructor. If the optional parameter `services` is `None` then `ChatBot`'s constructor then will find the services listed in `config.json` from the `global_services` and store them in the `services` class member. This was my attempt to \"inject\" services into the bot automatically.\r\n\r\n`DiscordBot` is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.\r\n\r\n### Reflection\r\nI think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the `global_services` dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.",
"note": "Don't delete this file! It's used internally to help with page regeneration."
}

0 comments on commit 1e9f977

Please sign in to comment.