{"action":"created","comment":{"url":"https://api.github.com/repos/ultrabug/py3status/pulls/comments/147790324","pull_request_review_id":72927029,"id":147790324,"diff_hunk":"@@ -0,0 +1,152 @@\n+# -*- coding: utf-8 -*-\n+\"\"\"\n+Display number of unread messages from IMAP account. (using IMAP4 IDLE)\n+\n+Configuration parameters:\n+    allow_urgent: display urgency on unread messages (default False)\n+    criterion: status of emails to check for (default 'UNSEEN')\n+    format: display format for this module (default 'Mail: {unseen}')\n+    hide_if_zero: hide this module when no new mail (default False)\n+    mailbox: name of the mailbox to check (default 'INBOX')\n+    password: login password (default None)\n+    port: number to use (default '993')\n+    security: login authentication method: 'ssl' or 'starttls'\n+        (startssl needs python 3.2 or later) (default 'ssl')\n+    server: server to connect (default None)\n+    user: login user (default None)\n+\n+Format placeholders:\n+    {unseen} number of unread emails\n+\n+Color options:\n+    color_new_mail: use color when new mail arrives, default to color_good\n+\n+@author obb and girst\n+\n+SAMPLE OUTPUT\n+{'full_text': 'Mail: 36', 'color': '#00FF00'}\n+\"\"\"\n+from imaplib2 import imaplib2\n+from threading import Thread\n+from ssl import create_default_context\n+STRING_UNAVAILABLE = 'N/A'\n+\n+\n+class Py3status:\n+    \"\"\"\n+    \"\"\"\n+    # available configuration parameters\n+    allow_urgent = False\n+    criterion = 'UNSEEN'\n+    format = 'Mail: {unseen}'\n+    hide_if_zero = False\n+    mailbox = 'INBOX'\n+    password = None\n+    port = '993'\n+    security = 'ssl'\n+    server = None\n+    user = None\n+\n+    class Meta:\n+        deprecated = {\n+            'rename': [\n+                {\n+                    'param': 'new_mail_color',\n+                    'new': 'color_new_mail',\n+                    'msg': 'obsolete parameter use `color_new_mail`',\n+                },\n+                {\n+                    'param': 'imap_server',\n+                    'new': 'server',\n+                    'msg': 'obsolete parameter use `server`',\n+                },\n+            ],\n+        }\n+\n+    def post_config_hook(self):\n+        self.mail_count = 0 # will be used to store\n+        if self.security not in [\"ssl\", \"starttls\"]:\n+            raise ValueError(\"Unknown security protocol\")\n+        self.idle_thread = self.Idle_Thread(\n+            mailbox=self.mailbox,\n+            criterion=self.criterion,\n+            user=self.user,\n+            password=self.password,\n+            server=self.server,\n+            port=self.port,\n+            security=self.security)\n+        self.idle_thread.start()\n+\n+    class Idle_Thread(Thread):\n+        def __init__(self, mailbox, criterion, user, password, server, port, security):\n+            Thread.__init__(self)\n+            self.connection = None\n+            self.mailbox = mailbox\n+            self.criterion = criterion\n+            self.user = user\n+            self.password = password\n+            self.server = server\n+            self.port = int(port)\n+            self.security = security\n+            self.mail_count = 0\n+        def get_mail_count(self):\n+            return self.mail_count\n+        def run(self):\n+            while True:\n+                try:\n+                    if self.connection is None:\n+                        if self.security == \"ssl\":\n+                            self.connection = imaplib2.IMAP4_SSL(self.server, self.port)\n+                        elif self.security == \"starttls\":\n+                            self.connection = imaplib2.IMAP4(self.server, self.port)\n+                            self.connection.starttls(create_default_context())\n+                        self.connection.login(self.user, self.password)\n+\n+                    self.mail_count = 0\n+                    directories = self.mailbox.split(',')\n+\n+                    for directory in directories:\n+                        self.connection.select(directory)\n+                        unseen_response = self.connection.search(None, self.criterion)\n+                        mails = unseen_response[1][0].split()\n+                        self.mail_count += len(mails)\n+\n+                    self.connection.idle()\n+                except Exception as e:\n+                    import time\n+                    time.sleep(1)","path":"py3status/modules/imap_idle.py","position":117,"original_position":117,"commit_id":"ab9e4442a36ce8dff92c348212c9d8f5eaaf32a5","original_commit_id":"ab9e4442a36ce8dff92c348212c9d8f5eaaf32a5","user":{"login":"lasers","id":852504,"avatar_url":"https://avatars2.githubusercontent.com/u/852504?v=4","gravatar_id":"","url":"https://api.github.com/users/lasers","html_url":"https://github.com/lasers","followers_url":"https://api.github.com/users/lasers/followers","following_url":"https://api.github.com/users/lasers/following{/other_user}","gists_url":"https://api.github.com/users/lasers/gists{/gist_id}","starred_url":"https://api.github.com/users/lasers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lasers/subscriptions","organizations_url":"https://api.github.com/users/lasers/orgs","repos_url":"https://api.github.com/users/lasers/repos","events_url":"https://api.github.com/users/lasers/events{/privacy}","received_events_url":"https://api.github.com/users/lasers/received_events","type":"User","site_admin":false},"body":"Explain the `time` delay?","created_at":"2017-10-30T18:18:09Z","updated_at":"2017-10-30T18:20:24Z","html_url":"https://github.com/ultrabug/py3status/pull/1136#discussion_r147790324","pull_request_url":"https://api.github.com/repos/ultrabug/py3status/pulls/1136","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/comments/147790324"},"html":{"href":"https://github.com/ultrabug/py3status/pull/1136#discussion_r147790324"},"pull_request":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/1136"}}},"pull_request":{"url":"https://api.github.com/repos/ultrabug/py3status/pulls/1136","id":149558716,"html_url":"https://github.com/ultrabug/py3status/pull/1136","diff_url":"https://github.com/ultrabug/py3status/pull/1136.diff","patch_url":"https://github.com/ultrabug/py3status/pull/1136.patch","issue_url":"https://api.github.com/repos/ultrabug/py3status/issues/1136","number":1136,"state":"open","locked":false,"title":"WIP/feedback please: IMAP4 IDLE unread emails","user":{"login":"girst","id":11820748,"avatar_url":"https://avatars0.githubusercontent.com/u/11820748?v=4","gravatar_id":"","url":"https://api.github.com/users/girst","html_url":"https://github.com/girst","followers_url":"https://api.github.com/users/girst/followers","following_url":"https://api.github.com/users/girst/following{/other_user}","gists_url":"https://api.github.com/users/girst/gists{/gist_id}","starred_url":"https://api.github.com/users/girst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/girst/subscriptions","organizations_url":"https://api.github.com/users/girst/orgs","repos_url":"https://api.github.com/users/girst/repos","events_url":"https://api.github.com/users/girst/events{/privacy}","received_events_url":"https://api.github.com/users/girst/received_events","type":"User","site_admin":false},"body":"## What\r\nImplements the imap module with imaplib2's .idle()\r\n\r\n## Why\r\ninstead of polling at a regular interval (which takes some time to update) IDLE keeps a connection alive. The server notifies the client when something changes, so we can react immediately. \r\n\r\n### More\r\nI've hacked this together over the weekend, and before I'm continuing I'd like to know if this has chances of getting included, otherwise I won't bother cleaning it up.    \r\nThe code is still missing some error handling (although I don't see any being done in the original imap module)\r\n\r\nReason for a new module instead of extending the old one is mainly convenience during development (I have restructured it a bit). **Also note that IDLE is not supported by the builtin `imaplib`**, so I use `imaplib2` (same author) available from the Ubuntu repo or `pip`. ","created_at":"2017-10-30T15:42:53Z","updated_at":"2017-10-30T18:20:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"343a28b0aa4a348831d3150472311d2fb3f1ac93","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/ultrabug/py3status/pulls/1136/commits","review_comments_url":"https://api.github.com/repos/ultrabug/py3status/pulls/1136/comments","review_comment_url":"https://api.github.com/repos/ultrabug/py3status/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ultrabug/py3status/issues/1136/comments","statuses_url":"https://api.github.com/repos/ultrabug/py3status/statuses/ab9e4442a36ce8dff92c348212c9d8f5eaaf32a5","head":{"label":"girst:master","ref":"master","sha":"ab9e4442a36ce8dff92c348212c9d8f5eaaf32a5","user":{"login":"girst","id":11820748,"avatar_url":"https://avatars0.githubusercontent.com/u/11820748?v=4","gravatar_id":"","url":"https://api.github.com/users/girst","html_url":"https://github.com/girst","followers_url":"https://api.github.com/users/girst/followers","following_url":"https://api.github.com/users/girst/following{/other_user}","gists_url":"https://api.github.com/users/girst/gists{/gist_id}","starred_url":"https://api.github.com/users/girst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/girst/subscriptions","organizations_url":"https://api.github.com/users/girst/orgs","repos_url":"https://api.github.com/users/girst/repos","events_url":"https://api.github.com/users/girst/events{/privacy}","received_events_url":"https://api.github.com/users/girst/received_events","type":"User","site_admin":false},"repo":{"id":105298768,"name":"py3status","full_name":"girst/py3status","owner":{"login":"girst","id":11820748,"avatar_url":"https://avatars0.githubusercontent.com/u/11820748?v=4","gravatar_id":"","url":"https://api.github.com/users/girst","html_url":"https://github.com/girst","followers_url":"https://api.github.com/users/girst/followers","following_url":"https://api.github.com/users/girst/following{/other_user}","gists_url":"https://api.github.com/users/girst/gists{/gist_id}","starred_url":"https://api.github.com/users/girst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/girst/subscriptions","organizations_url":"https://api.github.com/users/girst/orgs","repos_url":"https://api.github.com/users/girst/repos","events_url":"https://api.github.com/users/girst/events{/privacy}","received_events_url":"https://api.github.com/users/girst/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/girst/py3status","description":"py3status is an extensible i3status wrapper written in python","fork":true,"url":"https://api.github.com/repos/girst/py3status","forks_url":"https://api.github.com/repos/girst/py3status/forks","keys_url":"https://api.github.com/repos/girst/py3status/keys{/key_id}","collaborators_url":"https://api.github.com/repos/girst/py3status/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/girst/py3status/teams","hooks_url":"https://api.github.com/repos/girst/py3status/hooks","issue_events_url":"https://api.github.com/repos/girst/py3status/issues/events{/number}","events_url":"https://api.github.com/repos/girst/py3status/events","assignees_url":"https://api.github.com/repos/girst/py3status/assignees{/user}","branches_url":"https://api.github.com/repos/girst/py3status/branches{/branch}","tags_url":"https://api.github.com/repos/girst/py3status/tags","blobs_url":"https://api.github.com/repos/girst/py3status/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/girst/py3status/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/girst/py3status/git/refs{/sha}","trees_url":"https://api.github.com/repos/girst/py3status/git/trees{/sha}","statuses_url":"https://api.github.com/repos/girst/py3status/statuses/{sha}","languages_url":"https://api.github.com/repos/girst/py3status/languages","stargazers_url":"https://api.github.com/repos/girst/py3status/stargazers","contributors_url":"https://api.github.com/repos/girst/py3status/contributors","subscribers_url":"https://api.github.com/repos/girst/py3status/subscribers","subscription_url":"https://api.github.com/repos/girst/py3status/subscription","commits_url":"https://api.github.com/repos/girst/py3status/commits{/sha}","git_commits_url":"https://api.github.com/repos/girst/py3status/git/commits{/sha}","comments_url":"https://api.github.com/repos/girst/py3status/comments{/number}","issue_comment_url":"https://api.github.com/repos/girst/py3status/issues/comments{/number}","contents_url":"https://api.github.com/repos/girst/py3status/contents/{+path}","compare_url":"https://api.github.com/repos/girst/py3status/compare/{base}...{head}","merges_url":"https://api.github.com/repos/girst/py3status/merges","archive_url":"https://api.github.com/repos/girst/py3status/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/girst/py3status/downloads","issues_url":"https://api.github.com/repos/girst/py3status/issues{/number}","pulls_url":"https://api.github.com/repos/girst/py3status/pulls{/number}","milestones_url":"https://api.github.com/repos/girst/py3status/milestones{/number}","notifications_url":"https://api.github.com/repos/girst/py3status/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/girst/py3status/labels{/name}","releases_url":"https://api.github.com/repos/girst/py3status/releases{/id}","deployments_url":"https://api.github.com/repos/girst/py3status/deployments","created_at":"2017-09-29T17:19:52Z","updated_at":"2017-09-29T17:19:55Z","pushed_at":"2017-10-30T15:32:48Z","git_url":"git://github.com/girst/py3status.git","ssh_url":"git@github.com:girst/py3status.git","clone_url":"https://github.com/girst/py3status.git","svn_url":"https://github.com/girst/py3status","homepage":"","size":3326,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ultrabug:master","ref":"master","sha":"c73521aa12ef4fa088fa5bf64632db15bd86aad8","user":{"login":"ultrabug","id":474389,"avatar_url":"https://avatars3.githubusercontent.com/u/474389?v=4","gravatar_id":"","url":"https://api.github.com/users/ultrabug","html_url":"https://github.com/ultrabug","followers_url":"https://api.github.com/users/ultrabug/followers","following_url":"https://api.github.com/users/ultrabug/following{/other_user}","gists_url":"https://api.github.com/users/ultrabug/gists{/gist_id}","starred_url":"https://api.github.com/users/ultrabug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ultrabug/subscriptions","organizations_url":"https://api.github.com/users/ultrabug/orgs","repos_url":"https://api.github.com/users/ultrabug/repos","events_url":"https://api.github.com/users/ultrabug/events{/privacy}","received_events_url":"https://api.github.com/users/ultrabug/received_events","type":"User","site_admin":false},"repo":{"id":8292338,"name":"py3status","full_name":"ultrabug/py3status","owner":{"login":"ultrabug","id":474389,"avatar_url":"https://avatars3.githubusercontent.com/u/474389?v=4","gravatar_id":"","url":"https://api.github.com/users/ultrabug","html_url":"https://github.com/ultrabug","followers_url":"https://api.github.com/users/ultrabug/followers","following_url":"https://api.github.com/users/ultrabug/following{/other_user}","gists_url":"https://api.github.com/users/ultrabug/gists{/gist_id}","starred_url":"https://api.github.com/users/ultrabug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ultrabug/subscriptions","organizations_url":"https://api.github.com/users/ultrabug/orgs","repos_url":"https://api.github.com/users/ultrabug/repos","events_url":"https://api.github.com/users/ultrabug/events{/privacy}","received_events_url":"https://api.github.com/users/ultrabug/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ultrabug/py3status","description":"py3status is an extensible i3status wrapper written in python","fork":false,"url":"https://api.github.com/repos/ultrabug/py3status","forks_url":"https://api.github.com/repos/ultrabug/py3status/forks","keys_url":"https://api.github.com/repos/ultrabug/py3status/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ultrabug/py3status/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ultrabug/py3status/teams","hooks_url":"https://api.github.com/repos/ultrabug/py3status/hooks","issue_events_url":"https://api.github.com/repos/ultrabug/py3status/issues/events{/number}","events_url":"https://api.github.com/repos/ultrabug/py3status/events","assignees_url":"https://api.github.com/repos/ultrabug/py3status/assignees{/user}","branches_url":"https://api.github.com/repos/ultrabug/py3status/branches{/branch}","tags_url":"https://api.github.com/repos/ultrabug/py3status/tags","blobs_url":"https://api.github.com/repos/ultrabug/py3status/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ultrabug/py3status/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ultrabug/py3status/git/refs{/sha}","trees_url":"https://api.github.com/repos/ultrabug/py3status/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ultrabug/py3status/statuses/{sha}","languages_url":"https://api.github.com/repos/ultrabug/py3status/languages","stargazers_url":"https://api.github.com/repos/ultrabug/py3status/stargazers","contributors_url":"https://api.github.com/repos/ultrabug/py3status/contributors","subscribers_url":"https://api.github.com/repos/ultrabug/py3status/subscribers","subscription_url":"https://api.github.com/repos/ultrabug/py3status/subscription","commits_url":"https://api.github.com/repos/ultrabug/py3status/commits{/sha}","git_commits_url":"https://api.github.com/repos/ultrabug/py3status/git/commits{/sha}","comments_url":"https://api.github.com/repos/ultrabug/py3status/comments{/number}","issue_comment_url":"https://api.github.com/repos/ultrabug/py3status/issues/comments{/number}","contents_url":"https://api.github.com/repos/ultrabug/py3status/contents/{+path}","compare_url":"https://api.github.com/repos/ultrabug/py3status/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ultrabug/py3status/merges","archive_url":"https://api.github.com/repos/ultrabug/py3status/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ultrabug/py3status/downloads","issues_url":"https://api.github.com/repos/ultrabug/py3status/issues{/number}","pulls_url":"https://api.github.com/repos/ultrabug/py3status/pulls{/number}","milestones_url":"https://api.github.com/repos/ultrabug/py3status/milestones{/number}","notifications_url":"https://api.github.com/repos/ultrabug/py3status/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ultrabug/py3status/labels{/name}","releases_url":"https://api.github.com/repos/ultrabug/py3status/releases{/id}","deployments_url":"https://api.github.com/repos/ultrabug/py3status/deployments","created_at":"2013-02-19T14:59:13Z","updated_at":"2017-10-26T15:03:30Z","pushed_at":"2017-10-30T15:42:54Z","git_url":"git://github.com/ultrabug/py3status.git","ssh_url":"git@github.com:ultrabug/py3status.git","clone_url":"https://github.com/ultrabug/py3status.git","svn_url":"https://github.com/ultrabug/py3status","homepage":"https://py3status.readthedocs.io/","size":3325,"stargazers_count":454,"watchers_count":454,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":166,"mirror_url":null,"archived":false,"open_issues_count":81,"forks":166,"open_issues":81,"watchers":454,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/1136"},"html":{"href":"https://github.com/ultrabug/py3status/pull/1136"},"issue":{"href":"https://api.github.com/repos/ultrabug/py3status/issues/1136"},"comments":{"href":"https://api.github.com/repos/ultrabug/py3status/issues/1136/comments"},"review_comments":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/1136/comments"},"review_comment":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ultrabug/py3status/pulls/1136/commits"},"statuses":{"href":"https://api.github.com/repos/ultrabug/py3status/statuses/ab9e4442a36ce8dff92c348212c9d8f5eaaf32a5"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"lasers"}}