{"action":"created","comment":{"url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/comments/87658549","pull_request_review_id":8266219,"id":87658549,"diff_hunk":"@@ -0,0 +1,280 @@\n+from bytebot_config import BYTEBOT_PLUGIN_CONFIG\n+from irc3 import asyncio\n+from irc3.plugins.command import command\n+from irc3.plugins.cron import cron\n+\n+import aiohttp\n+import datetime\n+import dateutil.parser\n+import pytz\n+import os\n+import json\n+\n+\n+@command(permission=\"view\")\n+@asyncio.coroutine\n+def cccongress(bot, mask, target, args):\n+    \"\"\"Show information about Chaos Communication Congress\n+\n+        %%cccongress [<command>]\n+    \"\"\"\n+\n+    config = BYTEBOT_PLUGIN_CONFIG['cccongress']\n+\n+    if not os.path.isfile(config['cache']):\n+        yield from _update_cache(bot)\n+        return \"Schedule cache is unavailable. \" + \\\n+               \"Please try again in a few minutes!\"\n+\n+    if args['<command>'] is None:\n+        yield from _output_talks(0, bot, target)\n+    elif args['<command>'] == 'halls':\n+        bot.privmsg(target, \"Available halls: %s\" % ', '.join(_get_halls()))\n+    elif args['<command>'] == 'next':\n+        yield from _output_talks(1, bot, target)\n+    elif args['<command>'] == 'schedule':\n+        yield from _schedule_information(bot, target)\n+    elif args['<command>'] == \"help\":\n+        yield from _output_help(bot, target)\n+\n+\n+@cron('1 * 1-26,31 12 *')\n+@cron('*/15 * 27-30 12 *')\n+@asyncio.coroutine\n+def cccongress_update_cron(bot):\n+    \"\"\"Update schedule in December\"\"\"\n+\n+    yield from _update_cache(bot)\n+\n+\n+@cron('* * 27-30 12 *')\n+@asyncio.coroutine\n+def cccongress_announce_next_talks(bot):\n+    \"\"\"Announce next talks\"\"\"\n+\n+    config = BYTEBOT_PLUGIN_CONFIG['cccongress']\n+\n+    announcelist = []\n+    for hall in _get_halls():\n+        \"\"\"Get next event for hall\"\"\"\n+        event = _get_talk(hall, 1)\n+        if event is not None:\n+            \"\"\"Check if event starts in a few minutes\"\"\"\n+            event_start = dateutil.parser.parse(event['date'])\n+            designated_start = \\\n+                datetime.datetime.now(pytz.timezone('Europe/Berlin')) + \\\n+                datetime.timedelta(minutes=config['announce_minutes'])\n+            if event_start == designated_start:\n+                \"\"\"Save hall information in event and add to announcelist\"\"\"\n+                event['hall'] = hall\n+                announcelist.append(event)\n+\n+    \"\"\"Announce found events\"\"\"\n+    if len(announcelist) > 0:\n+        bot.privmsg(\n+            bot.config.autojoins[0],\n+            \"The following talks will start in %d minutes\" % (\n+                config['announce_minutes']\n+            )\n+        )\n+        for event in announcelist:\n+            yield from _output_single_talk(event['hall'],\n+                                           event,\n+                                           bot,\n+                                           bot.config.autojoins[0])\n+\n+\n+@asyncio.coroutine\n+def _output_talks(slot, bot, target):\n+    \"\"\"Output talks\n+\n+        slot: Output talks running now (slot = 0) or next (slot = 1)\n+    \"\"\"\n+\n+    event_counter = 0\n+    for hall in _get_halls():\n+        event = _get_talk(hall, slot)\n+        if event is not None:\n+            event_counter += 1\n+            yield from _output_single_talk(hall, event, bot, target)\n+\n+    if event_counter == 0:\n+        bot.privmsg(target, \"No talks found.\")\n+\n+\n+@asyncio.coroutine\n+def _output_single_talk(hall, event, bot, target):\n+    \"\"\"Output single talk\n+\n+        hall: Name of hall\n+        event: Event information\n+    \"\"\"\n+\n+    bot.privmsg(\n+        target,\n+        \"[%s] %s %s\" % (hall, event['start'], event['title'])\n+    )\n+    bot.privmsg(\n+        target,\n+        \"%s (%s / %s)\" % (\n+            '{:<14}'.format(''), event['language'], _get_persons(event)\n+        )\n+    )\n+\n+\n+@asyncio.coroutine\n+def _schedule_information(bot, target):\n+    \"\"\"Output information about schedule\"\"\"\n+\n+    config = BYTEBOT_PLUGIN_CONFIG['cccongress']\n+    json_data = _get_json_data()\n+\n+    bot.privmsg(\n+        target,\n+        \"%s (%s)\" % (\n+            json_data['schedule']['conference']['title'],\n+            json_data['schedule']['conference']['acronym']\n+        )\n+    )\n+\n+    file_mtime = os.path.getmtime(config['cache'])\n+    file_dtime = datetime.datetime.fromtimestamp(file_mtime)\n+    bot.privmsg(\n+        target,\n+        \"Schedule was last updated on %s\" % (\n+            file_dtime.strftime('%Y-%m-%d %H:%M:%S')\n+        )\n+    )\n+\n+    bot.privmsg(\n+        target,\n+        \"Current schedule version is %s\" % json_data['schedule']['version']\n+    )\n+\n+\n+@asyncio.coroutine\n+def _output_help(bot, target):\n+    \"\"\"Output help\"\"\"\n+\n+    bot.privmsg(target, \"The following commands are available:\")\n+    bot.privmsg(target, \"!cccongress          - Show current talks\")\n+    bot.privmsg(target, \"!cccongress halls    - Show available halls\")\n+    bot.privmsg(target, \"!cccongress next     - Show next talks\")\n+    bot.privmsg(target, \"!cccongress schedule - Show schedule information\")\n+\n+\n+def _get_json_data():\n+    \"\"\"Get json from cached file\"\"\"\n+\n+    with open(BYTEBOT_PLUGIN_CONFIG['cccongress']['cache']) as json_file:\n+        return json.load(json_file)","path":"plugins/cccongress.py","position":null,"original_position":170,"commit_id":"af49e9291f5537efd721182b8a7a37893ba039c3","original_commit_id":"bbf0a8ccb1ad803489fec91f0a36e9ddcfe27686","user":{"login":"mape2k","id":533874,"avatar_url":"https://avatars.githubusercontent.com/u/533874?v=3","gravatar_id":"","url":"https://api.github.com/users/mape2k","html_url":"https://github.com/mape2k","followers_url":"https://api.github.com/users/mape2k/followers","following_url":"https://api.github.com/users/mape2k/following{/other_user}","gists_url":"https://api.github.com/users/mape2k/gists{/gist_id}","starred_url":"https://api.github.com/users/mape2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mape2k/subscriptions","organizations_url":"https://api.github.com/users/mape2k/orgs","repos_url":"https://api.github.com/users/mape2k/repos","events_url":"https://api.github.com/users/mape2k/events{/privacy}","received_events_url":"https://api.github.com/users/mape2k/received_events","type":"User","site_admin":false},"body":"Good catch, fixed Exception handling in many places - also http update exception handling","created_at":"2016-11-11T21:06:52Z","updated_at":"2016-11-11T21:06:52Z","html_url":"https://github.com/Bytespeicher/Bytebot/pull/159#discussion_r87658549","pull_request_url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159","_links":{"self":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/comments/87658549"},"html":{"href":"https://github.com/Bytespeicher/Bytebot/pull/159#discussion_r87658549"},"pull_request":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159"}}},"pull_request":{"url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159","id":93049690,"html_url":"https://github.com/Bytespeicher/Bytebot/pull/159","diff_url":"https://github.com/Bytespeicher/Bytebot/pull/159.diff","patch_url":"https://github.com/Bytespeicher/Bytebot/pull/159.patch","issue_url":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/159","number":159,"state":"open","locked":false,"title":"Refactor ccc32c3 plugin","user":{"login":"mape2k","id":533874,"avatar_url":"https://avatars.githubusercontent.com/u/533874?v=3","gravatar_id":"","url":"https://api.github.com/users/mape2k","html_url":"https://github.com/mape2k","followers_url":"https://api.github.com/users/mape2k/followers","following_url":"https://api.github.com/users/mape2k/following{/other_user}","gists_url":"https://api.github.com/users/mape2k/gists{/gist_id}","starred_url":"https://api.github.com/users/mape2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mape2k/subscriptions","organizations_url":"https://api.github.com/users/mape2k/orgs","repos_url":"https://api.github.com/users/mape2k/repos","events_url":"https://api.github.com/users/mape2k/events{/privacy}","received_events_url":"https://api.github.com/users/mape2k/received_events","type":"User","site_admin":false},"body":"* Rename to cccongress because plugin is more common\r\n* Automatic update of cached \"Fahrplan\" with cron\r\n* Talk and Hall detection rewritten\r\n* Command to get current and next talks\r\n* Command to get halls\r\n* Command to get schedule informations\r\n* Automatic announcements of talks which will start in a\r\n  configurable time\r\n\r\nFixes #127 ","created_at":"2016-11-09T22:18:04Z","updated_at":"2016-11-11T21:06:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8836b3ab5033b997c6eea2e627546d8be9fd855e","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159/commits","review_comments_url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159/comments","review_comment_url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/159/comments","statuses_url":"https://api.github.com/repos/Bytespeicher/Bytebot/statuses/af49e9291f5537efd721182b8a7a37893ba039c3","head":{"label":"mape2k:refactor-irc3","ref":"refactor-irc3","sha":"af49e9291f5537efd721182b8a7a37893ba039c3","user":{"login":"mape2k","id":533874,"avatar_url":"https://avatars.githubusercontent.com/u/533874?v=3","gravatar_id":"","url":"https://api.github.com/users/mape2k","html_url":"https://github.com/mape2k","followers_url":"https://api.github.com/users/mape2k/followers","following_url":"https://api.github.com/users/mape2k/following{/other_user}","gists_url":"https://api.github.com/users/mape2k/gists{/gist_id}","starred_url":"https://api.github.com/users/mape2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mape2k/subscriptions","organizations_url":"https://api.github.com/users/mape2k/orgs","repos_url":"https://api.github.com/users/mape2k/repos","events_url":"https://api.github.com/users/mape2k/events{/privacy}","received_events_url":"https://api.github.com/users/mape2k/received_events","type":"User","site_admin":false},"repo":{"id":25047763,"name":"Bytebot","full_name":"mape2k/Bytebot","owner":{"login":"mape2k","id":533874,"avatar_url":"https://avatars.githubusercontent.com/u/533874?v=3","gravatar_id":"","url":"https://api.github.com/users/mape2k","html_url":"https://github.com/mape2k","followers_url":"https://api.github.com/users/mape2k/followers","following_url":"https://api.github.com/users/mape2k/following{/other_user}","gists_url":"https://api.github.com/users/mape2k/gists{/gist_id}","starred_url":"https://api.github.com/users/mape2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mape2k/subscriptions","organizations_url":"https://api.github.com/users/mape2k/orgs","repos_url":"https://api.github.com/users/mape2k/repos","events_url":"https://api.github.com/users/mape2k/events{/privacy}","received_events_url":"https://api.github.com/users/mape2k/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mape2k/Bytebot","description":"IRC bot for the #Bytespeicher channel","fork":true,"url":"https://api.github.com/repos/mape2k/Bytebot","forks_url":"https://api.github.com/repos/mape2k/Bytebot/forks","keys_url":"https://api.github.com/repos/mape2k/Bytebot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mape2k/Bytebot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mape2k/Bytebot/teams","hooks_url":"https://api.github.com/repos/mape2k/Bytebot/hooks","issue_events_url":"https://api.github.com/repos/mape2k/Bytebot/issues/events{/number}","events_url":"https://api.github.com/repos/mape2k/Bytebot/events","assignees_url":"https://api.github.com/repos/mape2k/Bytebot/assignees{/user}","branches_url":"https://api.github.com/repos/mape2k/Bytebot/branches{/branch}","tags_url":"https://api.github.com/repos/mape2k/Bytebot/tags","blobs_url":"https://api.github.com/repos/mape2k/Bytebot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mape2k/Bytebot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mape2k/Bytebot/git/refs{/sha}","trees_url":"https://api.github.com/repos/mape2k/Bytebot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mape2k/Bytebot/statuses/{sha}","languages_url":"https://api.github.com/repos/mape2k/Bytebot/languages","stargazers_url":"https://api.github.com/repos/mape2k/Bytebot/stargazers","contributors_url":"https://api.github.com/repos/mape2k/Bytebot/contributors","subscribers_url":"https://api.github.com/repos/mape2k/Bytebot/subscribers","subscription_url":"https://api.github.com/repos/mape2k/Bytebot/subscription","commits_url":"https://api.github.com/repos/mape2k/Bytebot/commits{/sha}","git_commits_url":"https://api.github.com/repos/mape2k/Bytebot/git/commits{/sha}","comments_url":"https://api.github.com/repos/mape2k/Bytebot/comments{/number}","issue_comment_url":"https://api.github.com/repos/mape2k/Bytebot/issues/comments{/number}","contents_url":"https://api.github.com/repos/mape2k/Bytebot/contents/{+path}","compare_url":"https://api.github.com/repos/mape2k/Bytebot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mape2k/Bytebot/merges","archive_url":"https://api.github.com/repos/mape2k/Bytebot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mape2k/Bytebot/downloads","issues_url":"https://api.github.com/repos/mape2k/Bytebot/issues{/number}","pulls_url":"https://api.github.com/repos/mape2k/Bytebot/pulls{/number}","milestones_url":"https://api.github.com/repos/mape2k/Bytebot/milestones{/number}","notifications_url":"https://api.github.com/repos/mape2k/Bytebot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mape2k/Bytebot/labels{/name}","releases_url":"https://api.github.com/repos/mape2k/Bytebot/releases{/id}","deployments_url":"https://api.github.com/repos/mape2k/Bytebot/deployments","created_at":"2014-10-10T18:23:50Z","updated_at":"2016-07-23T10:32:26Z","pushed_at":"2016-11-11T21:05:44Z","git_url":"git://github.com/mape2k/Bytebot.git","ssh_url":"git@github.com:mape2k/Bytebot.git","clone_url":"https://github.com/mape2k/Bytebot.git","svn_url":"https://github.com/mape2k/Bytebot","homepage":null,"size":352,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Bytespeicher:refactor-irc3","ref":"refactor-irc3","sha":"55e31510f2178cf51f0704743fa8a401df56669f","user":{"login":"Bytespeicher","id":5994656,"avatar_url":"https://avatars.githubusercontent.com/u/5994656?v=3","gravatar_id":"","url":"https://api.github.com/users/Bytespeicher","html_url":"https://github.com/Bytespeicher","followers_url":"https://api.github.com/users/Bytespeicher/followers","following_url":"https://api.github.com/users/Bytespeicher/following{/other_user}","gists_url":"https://api.github.com/users/Bytespeicher/gists{/gist_id}","starred_url":"https://api.github.com/users/Bytespeicher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bytespeicher/subscriptions","organizations_url":"https://api.github.com/users/Bytespeicher/orgs","repos_url":"https://api.github.com/users/Bytespeicher/repos","events_url":"https://api.github.com/users/Bytespeicher/events{/privacy}","received_events_url":"https://api.github.com/users/Bytespeicher/received_events","type":"Organization","site_admin":false},"repo":{"id":17847033,"name":"Bytebot","full_name":"Bytespeicher/Bytebot","owner":{"login":"Bytespeicher","id":5994656,"avatar_url":"https://avatars.githubusercontent.com/u/5994656?v=3","gravatar_id":"","url":"https://api.github.com/users/Bytespeicher","html_url":"https://github.com/Bytespeicher","followers_url":"https://api.github.com/users/Bytespeicher/followers","following_url":"https://api.github.com/users/Bytespeicher/following{/other_user}","gists_url":"https://api.github.com/users/Bytespeicher/gists{/gist_id}","starred_url":"https://api.github.com/users/Bytespeicher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bytespeicher/subscriptions","organizations_url":"https://api.github.com/users/Bytespeicher/orgs","repos_url":"https://api.github.com/users/Bytespeicher/repos","events_url":"https://api.github.com/users/Bytespeicher/events{/privacy}","received_events_url":"https://api.github.com/users/Bytespeicher/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Bytespeicher/Bytebot","description":"IRC bot for the #Bytespeicher channel","fork":false,"url":"https://api.github.com/repos/Bytespeicher/Bytebot","forks_url":"https://api.github.com/repos/Bytespeicher/Bytebot/forks","keys_url":"https://api.github.com/repos/Bytespeicher/Bytebot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Bytespeicher/Bytebot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Bytespeicher/Bytebot/teams","hooks_url":"https://api.github.com/repos/Bytespeicher/Bytebot/hooks","issue_events_url":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/events{/number}","events_url":"https://api.github.com/repos/Bytespeicher/Bytebot/events","assignees_url":"https://api.github.com/repos/Bytespeicher/Bytebot/assignees{/user}","branches_url":"https://api.github.com/repos/Bytespeicher/Bytebot/branches{/branch}","tags_url":"https://api.github.com/repos/Bytespeicher/Bytebot/tags","blobs_url":"https://api.github.com/repos/Bytespeicher/Bytebot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Bytespeicher/Bytebot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Bytespeicher/Bytebot/git/refs{/sha}","trees_url":"https://api.github.com/repos/Bytespeicher/Bytebot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Bytespeicher/Bytebot/statuses/{sha}","languages_url":"https://api.github.com/repos/Bytespeicher/Bytebot/languages","stargazers_url":"https://api.github.com/repos/Bytespeicher/Bytebot/stargazers","contributors_url":"https://api.github.com/repos/Bytespeicher/Bytebot/contributors","subscribers_url":"https://api.github.com/repos/Bytespeicher/Bytebot/subscribers","subscription_url":"https://api.github.com/repos/Bytespeicher/Bytebot/subscription","commits_url":"https://api.github.com/repos/Bytespeicher/Bytebot/commits{/sha}","git_commits_url":"https://api.github.com/repos/Bytespeicher/Bytebot/git/commits{/sha}","comments_url":"https://api.github.com/repos/Bytespeicher/Bytebot/comments{/number}","issue_comment_url":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/comments{/number}","contents_url":"https://api.github.com/repos/Bytespeicher/Bytebot/contents/{+path}","compare_url":"https://api.github.com/repos/Bytespeicher/Bytebot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Bytespeicher/Bytebot/merges","archive_url":"https://api.github.com/repos/Bytespeicher/Bytebot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Bytespeicher/Bytebot/downloads","issues_url":"https://api.github.com/repos/Bytespeicher/Bytebot/issues{/number}","pulls_url":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls{/number}","milestones_url":"https://api.github.com/repos/Bytespeicher/Bytebot/milestones{/number}","notifications_url":"https://api.github.com/repos/Bytespeicher/Bytebot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Bytespeicher/Bytebot/labels{/name}","releases_url":"https://api.github.com/repos/Bytespeicher/Bytebot/releases{/id}","deployments_url":"https://api.github.com/repos/Bytespeicher/Bytebot/deployments","created_at":"2014-03-17T23:20:04Z","updated_at":"2016-07-23T10:37:28Z","pushed_at":"2016-11-11T21:05:44Z","git_url":"git://github.com/Bytespeicher/Bytebot.git","ssh_url":"git@github.com:Bytespeicher/Bytebot.git","clone_url":"https://github.com/Bytespeicher/Bytebot.git","svn_url":"https://github.com/Bytespeicher/Bytebot","homepage":null,"size":377,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":11,"mirror_url":null,"open_issues_count":35,"forks":11,"open_issues":35,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159"},"html":{"href":"https://github.com/Bytespeicher/Bytebot/pull/159"},"issue":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/159"},"comments":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/issues/159/comments"},"review_comments":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159/comments"},"review_comment":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/pulls/159/commits"},"statuses":{"href":"https://api.github.com/repos/Bytespeicher/Bytebot/statuses/af49e9291f5537efd721182b8a7a37893ba039c3"}}}}
{"actor":{"display_login":"mape2k"}}