{"action":"created","comment":{"url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/comments/80190391","id":80190391,"diff_hunk":"@@ -144,6 +158,36 @@ def splitwords(s):\n \treturn filter(bool, map(str.strip, re.split('[ ,\\n]+', s)))\n \n \n+#\n+# Following \"uni_decode\" function unified python independent any to string converting\n+#\n+# Typical example resp. work-case for understanding the coding/decoding issues:\n+#\n+#   [isinstance('', str), isinstance(b'', str), isinstance(u'', str)]\n+#   [True, True, False]; # -- python2\n+#\t  [True, False, True]; # -- python3\n+#\n+if sys.version_info >= (3,):\n+\tdef uni_decode(x, enc=PREFER_ENC, errors='strict'):\n+\t\ttry:\n+\t\t\tif isinstance(x, bytes):\n+\t\t\t\treturn x.decode(enc, errors)\n+\t\t\treturn x\n+\t\texcept (UnicodeDecodeError, UnicodeEncodeError): # pragma: no cover - unsure if reachable\n+\t\t\tif errors != 'strict': ","path":"fail2ban/helpers.py","position":55,"original_position":55,"commit_id":"e00be5f308c98a53bde277baa24d20b6712b9644","original_commit_id":"e00be5f308c98a53bde277baa24d20b6712b9644","user":{"login":"sebres","id":3769657,"avatar_url":"https://avatars.githubusercontent.com/u/3769657?v=3","gravatar_id":"","url":"https://api.github.com/users/sebres","html_url":"https://github.com/sebres","followers_url":"https://api.github.com/users/sebres/followers","following_url":"https://api.github.com/users/sebres/following{/other_user}","gists_url":"https://api.github.com/users/sebres/gists{/gist_id}","starred_url":"https://api.github.com/users/sebres/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebres/subscriptions","organizations_url":"https://api.github.com/users/sebres/orgs","repos_url":"https://api.github.com/users/sebres/repos","events_url":"https://api.github.com/users/sebres/events{/privacy}","received_events_url":"https://api.github.com/users/sebres/received_events","type":"User","site_admin":false},"body":"Nope, otherwise it would always throw an error (this is test covered also). \r\nThe normal case is to execute it without parameter (so trying strict), then the worst-case:\r\n`uni_decode(str)` produces an error with strict, but does not raise an error (`errors != 'strict'`) and try convert with replace, if it also produces an error, this will be reraised...","created_at":"2016-09-23T06:56:14Z","updated_at":"2016-09-23T06:56:14Z","html_url":"https://github.com/fail2ban/fail2ban/pull/1557#discussion_r80190391","pull_request_url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557","_links":{"self":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/comments/80190391"},"html":{"href":"https://github.com/fail2ban/fail2ban/pull/1557#discussion_r80190391"},"pull_request":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557"}}},"pull_request":{"url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557","id":86414800,"html_url":"https://github.com/fail2ban/fail2ban/pull/1557","diff_url":"https://github.com/fail2ban/fail2ban/pull/1557.diff","patch_url":"https://github.com/fail2ban/fail2ban/pull/1557.patch","issue_url":"https://api.github.com/repos/fail2ban/fail2ban/issues/1557","number":1557,"state":"open","locked":false,"title":" 0.10/reload-and-more","user":{"login":"sebres","id":3769657,"avatar_url":"https://avatars.githubusercontent.com/u/3769657?v=3","gravatar_id":"","url":"https://api.github.com/users/sebres","html_url":"https://github.com/sebres","followers_url":"https://api.github.com/users/sebres/followers","following_url":"https://api.github.com/users/sebres/following{/other_user}","gists_url":"https://api.github.com/users/sebres/gists{/gist_id}","starred_url":"https://api.github.com/users/sebres/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebres/subscriptions","organizations_url":"https://api.github.com/users/sebres/orgs","repos_url":"https://api.github.com/users/sebres/repos","events_url":"https://api.github.com/users/sebres/events{/privacy}","received_events_url":"https://api.github.com/users/sebres/received_events","type":"User","site_admin":false},"body":"- Reload functionality rewritten (now totally without restart, unbanning/rebanning, etc., resp. optional if needed)\r\nCloses #1534 \r\n- Several commands extended and new commands introduced: \r\n  - `restart [--unban] [--if-exists] <JAIL>` - restarts the jail \\<JAIL\\> (alias for `reload --restart ... <JAIL>`)\r\n  - `reload [--restart] [--unban] [--all]` - reloads the configuration without restarting of the server, the option `--restart` activates completely restarting of affected jails, thereby can unban IP addresses (if option `--unban` specified)\r\n  - `reload [--restart] [--unban] [--if-exists] <JAIL>` - reloads the jail \\<JAIL\\>, or restarts it (if option `--restart` specified), at the same time unbans all IP addresses banned in this jail, if option `--unban` specified\r\n  - `unban --all` - unbans all IP addresses (in all jails and database)\r\n  - `unban <IP> ... <IP>` - unbans \\<IP\\> (in all jails and database), Closes #1388 \r\n- Because of major branch further development, lot of things in all the filters was rewritten (e. g. because of reload-possibility).\r\nDefinitelly fixed high-load of pyinotify-backend, see https://github.com/fail2ban/fail2ban/issues/885#issuecomment-248964591\r\n- Now pyinotify and systemd backends are the fastest and least cpu- resp. system-load greedy.\r\n\r\nAdditionally:\r\n* Switch down log level for some annoying messages to tracedebug or heavydebug (to 7 or even 5);\r\n* Added verification of specified log-level before transmitting to the server (now fails in client if wrong level);\r\n* Numeric log-level allowed now in server (resp. fail2ban.conf);\r\n* Increase default wait operation (sleep time, threshold interval) - avowedly greater inertance, but fewer system load by many jails resp. log files; leave smaller inertance inside test-cases\r\n* Waiting in threads with `wait_for` extended with verifying of active flag. \r\n* Implemented better error handling in some multi-threaded routines; shutdown of jails rewritten (faster and safer, does not breaks shutdown process if some error occurred);\r\n* Possibility for overwriting some configuration options (read with config-readers) with command line option, e. g.:\r\n```bash\r\n## start server with DEBUG log-level (ignore level read from fail2ban.conf):\r\nfail2ban-client --loglevel DEBUG start\r\n## or\r\nfail2ban-server -c /cfg/path --loglevel DEBUG start\r\n## keep server log-level by reload (without restart it)\r\nfail2ban-client --loglevel DEBUG reload\r\n## switch log-level back to INFO:\r\nfail2ban-client set loglevel INFO\r\n```\r\n* Normalized usage of preferred encoding (and decode any to string);\r\npython 3.x compatibility (used uni_decode for string representation of stdout/stderr, unified test cases)\r\namend for #1542\r\n* Database: stability fix - repack cursor iterator as long as locked\r\n* Introduced new ticket flag \"banned\" as property, used to recognize the ticket was really banned;\r\nget/set restored flag functions rewritten to property \"restored\" similar to \"banned\";\r\n* file filter backends: stability fix for sporadically errors - always close file handle, otherwise may be locked (prevent log-rotate, etc.)\r\n* pyinotify-backend: stability fix for sporadically errors in multi-threaded environment (without lock)\r\n* New command action parameter `actionrepair` - command executed in order to restore sane environment in error case of `actioncheck`.\r\n<br>**[WARNING]** TODO: be sure all banactions get a new repair command, because otherwise stop/start will theoretically remove all the bans, but the tickets are still in BanManager, so in case of new failures it will not be banned, because \"already banned\" will happen.\r\n* Optimized BanManager: increase performance, fewer system load, try to prevent memory leakage:\r\n  - better ban/unban handling within actions (e.g. used dict instead of list)\r\n  - don't copy bans resp. its list on some operations;\r\n  - added new unbantime handling to relieve unBanList (prevent permanent searching for tickets to unban)\r\n  - prefer failure-ID as identifier of the ticket to its IP (most of the time the same, but it can be something else e.g. user name in some complex jails, as introduced in 0.10)\r\n* Build replacement of `<HOST>` substitution corresponding parameter `usedns` - dns-part will be added only if `usedns` is not `no`; also using fail2ban-regex.\r\n* New replacement for `<ADDR>` in opposition to `<HOST>`, for separate usage of 2 address groups only (regardless of `usedns`), `ip4` and `ip6` together, without host (dns)\r\n* Test-cases:\r\n  - `assertLogged` extended with parameter wait (to wait up to specified timeout, before we throw assert exception) + test cases rewritten using that\r\n  - added `assertDictEqual` for compatibility to early python versions (< 2.7);\r\n  - new `with_foreground_server_thread` decorator to test several client/server commands\r\n  - fixed sporadically error in testCymruInfoNxdomain, because of unsorted values:\r\n```\r\nAssertionError: Dictionaries differ:\r\n{'country': ['unknown', 'nxdomain'], 'asn': ['4565', 'nxdomain'], 'rir': ['other', 'nxdomain']} !=\r\n{'country': ['nxdomain', 'unknown'], 'asn': ['nxdomain', '4565'], 'rir': ['nxdomain', 'other']}\r\n```\r\n","created_at":"2016-09-22T21:07:56Z","updated_at":"2016-09-23T06:56:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3fa963a405c19c93180bda2a7e47907ed9315985","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/fail2ban/fail2ban/milestones/14","html_url":"https://github.com/fail2ban/fail2ban/milestones/0.10.0","labels_url":"https://api.github.com/repos/fail2ban/fail2ban/milestones/14/labels","id":1759181,"number":14,"title":"0.10.0","description":"Major functionality and performance boosts: semantic times, IPv6 support etc","creator":{"login":"yarikoptic","id":39889,"avatar_url":"https://avatars.githubusercontent.com/u/39889?v=3","gravatar_id":"","url":"https://api.github.com/users/yarikoptic","html_url":"https://github.com/yarikoptic","followers_url":"https://api.github.com/users/yarikoptic/followers","following_url":"https://api.github.com/users/yarikoptic/following{/other_user}","gists_url":"https://api.github.com/users/yarikoptic/gists{/gist_id}","starred_url":"https://api.github.com/users/yarikoptic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yarikoptic/subscriptions","organizations_url":"https://api.github.com/users/yarikoptic/orgs","repos_url":"https://api.github.com/users/yarikoptic/repos","events_url":"https://api.github.com/users/yarikoptic/events{/privacy}","received_events_url":"https://api.github.com/users/yarikoptic/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":19,"state":"open","created_at":"2016-05-11T01:19:51Z","updated_at":"2016-09-22T21:07:56Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557/commits","review_comments_url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557/comments","review_comment_url":"https://api.github.com/repos/fail2ban/fail2ban/pulls/comments{/number}","comments_url":"https://api.github.com/repos/fail2ban/fail2ban/issues/1557/comments","statuses_url":"https://api.github.com/repos/fail2ban/fail2ban/statuses/e00be5f308c98a53bde277baa24d20b6712b9644","head":{"label":"sebres:_0.10/fix-reload-bug","ref":"_0.10/fix-reload-bug","sha":"e00be5f308c98a53bde277baa24d20b6712b9644","user":{"login":"sebres","id":3769657,"avatar_url":"https://avatars.githubusercontent.com/u/3769657?v=3","gravatar_id":"","url":"https://api.github.com/users/sebres","html_url":"https://github.com/sebres","followers_url":"https://api.github.com/users/sebres/followers","following_url":"https://api.github.com/users/sebres/following{/other_user}","gists_url":"https://api.github.com/users/sebres/gists{/gist_id}","starred_url":"https://api.github.com/users/sebres/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebres/subscriptions","organizations_url":"https://api.github.com/users/sebres/orgs","repos_url":"https://api.github.com/users/sebres/repos","events_url":"https://api.github.com/users/sebres/events{/privacy}","received_events_url":"https://api.github.com/users/sebres/received_events","type":"User","site_admin":false},"repo":{"id":8566686,"name":"fail2ban","full_name":"sebres/fail2ban","owner":{"login":"sebres","id":3769657,"avatar_url":"https://avatars.githubusercontent.com/u/3769657?v=3","gravatar_id":"","url":"https://api.github.com/users/sebres","html_url":"https://github.com/sebres","followers_url":"https://api.github.com/users/sebres/followers","following_url":"https://api.github.com/users/sebres/following{/other_user}","gists_url":"https://api.github.com/users/sebres/gists{/gist_id}","starred_url":"https://api.github.com/users/sebres/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebres/subscriptions","organizations_url":"https://api.github.com/users/sebres/orgs","repos_url":"https://api.github.com/users/sebres/repos","events_url":"https://api.github.com/users/sebres/events{/privacy}","received_events_url":"https://api.github.com/users/sebres/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sebres/fail2ban","description":"Daemon to ban hosts that cause multiple authentication errors","fork":true,"url":"https://api.github.com/repos/sebres/fail2ban","forks_url":"https://api.github.com/repos/sebres/fail2ban/forks","keys_url":"https://api.github.com/repos/sebres/fail2ban/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sebres/fail2ban/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sebres/fail2ban/teams","hooks_url":"https://api.github.com/repos/sebres/fail2ban/hooks","issue_events_url":"https://api.github.com/repos/sebres/fail2ban/issues/events{/number}","events_url":"https://api.github.com/repos/sebres/fail2ban/events","assignees_url":"https://api.github.com/repos/sebres/fail2ban/assignees{/user}","branches_url":"https://api.github.com/repos/sebres/fail2ban/branches{/branch}","tags_url":"https://api.github.com/repos/sebres/fail2ban/tags","blobs_url":"https://api.github.com/repos/sebres/fail2ban/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sebres/fail2ban/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sebres/fail2ban/git/refs{/sha}","trees_url":"https://api.github.com/repos/sebres/fail2ban/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sebres/fail2ban/statuses/{sha}","languages_url":"https://api.github.com/repos/sebres/fail2ban/languages","stargazers_url":"https://api.github.com/repos/sebres/fail2ban/stargazers","contributors_url":"https://api.github.com/repos/sebres/fail2ban/contributors","subscribers_url":"https://api.github.com/repos/sebres/fail2ban/subscribers","subscription_url":"https://api.github.com/repos/sebres/fail2ban/subscription","commits_url":"https://api.github.com/repos/sebres/fail2ban/commits{/sha}","git_commits_url":"https://api.github.com/repos/sebres/fail2ban/git/commits{/sha}","comments_url":"https://api.github.com/repos/sebres/fail2ban/comments{/number}","issue_comment_url":"https://api.github.com/repos/sebres/fail2ban/issues/comments{/number}","contents_url":"https://api.github.com/repos/sebres/fail2ban/contents/{+path}","compare_url":"https://api.github.com/repos/sebres/fail2ban/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sebres/fail2ban/merges","archive_url":"https://api.github.com/repos/sebres/fail2ban/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sebres/fail2ban/downloads","issues_url":"https://api.github.com/repos/sebres/fail2ban/issues{/number}","pulls_url":"https://api.github.com/repos/sebres/fail2ban/pulls{/number}","milestones_url":"https://api.github.com/repos/sebres/fail2ban/milestones{/number}","notifications_url":"https://api.github.com/repos/sebres/fail2ban/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sebres/fail2ban/labels{/name}","releases_url":"https://api.github.com/repos/sebres/fail2ban/releases{/id}","deployments_url":"https://api.github.com/repos/sebres/fail2ban/deployments","created_at":"2013-03-04T22:36:47Z","updated_at":"2016-09-01T19:35:06Z","pushed_at":"2016-09-22T20:47:27Z","git_url":"git://github.com/sebres/fail2ban.git","ssh_url":"git@github.com:sebres/fail2ban.git","clone_url":"https://github.com/sebres/fail2ban.git","svn_url":"https://github.com/sebres/fail2ban","homepage":"http://www.fail2ban.org","size":7606,"stargazers_count":9,"watchers_count":9,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":0,"forks":2,"open_issues":0,"watchers":9,"default_branch":"0.10-full"}},"base":{"label":"fail2ban:0.10","ref":"0.10","sha":"0a7374dec69bbbe54e0180c80c8d3b653fd1012f","user":{"login":"fail2ban","id":1087378,"avatar_url":"https://avatars.githubusercontent.com/u/1087378?v=3","gravatar_id":"","url":"https://api.github.com/users/fail2ban","html_url":"https://github.com/fail2ban","followers_url":"https://api.github.com/users/fail2ban/followers","following_url":"https://api.github.com/users/fail2ban/following{/other_user}","gists_url":"https://api.github.com/users/fail2ban/gists{/gist_id}","starred_url":"https://api.github.com/users/fail2ban/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fail2ban/subscriptions","organizations_url":"https://api.github.com/users/fail2ban/orgs","repos_url":"https://api.github.com/users/fail2ban/repos","events_url":"https://api.github.com/users/fail2ban/events{/privacy}","received_events_url":"https://api.github.com/users/fail2ban/received_events","type":"Organization","site_admin":false},"repo":{"id":2476162,"name":"fail2ban","full_name":"fail2ban/fail2ban","owner":{"login":"fail2ban","id":1087378,"avatar_url":"https://avatars.githubusercontent.com/u/1087378?v=3","gravatar_id":"","url":"https://api.github.com/users/fail2ban","html_url":"https://github.com/fail2ban","followers_url":"https://api.github.com/users/fail2ban/followers","following_url":"https://api.github.com/users/fail2ban/following{/other_user}","gists_url":"https://api.github.com/users/fail2ban/gists{/gist_id}","starred_url":"https://api.github.com/users/fail2ban/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fail2ban/subscriptions","organizations_url":"https://api.github.com/users/fail2ban/orgs","repos_url":"https://api.github.com/users/fail2ban/repos","events_url":"https://api.github.com/users/fail2ban/events{/privacy}","received_events_url":"https://api.github.com/users/fail2ban/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fail2ban/fail2ban","description":"Daemon to ban hosts that cause multiple authentication errors","fork":false,"url":"https://api.github.com/repos/fail2ban/fail2ban","forks_url":"https://api.github.com/repos/fail2ban/fail2ban/forks","keys_url":"https://api.github.com/repos/fail2ban/fail2ban/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fail2ban/fail2ban/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fail2ban/fail2ban/teams","hooks_url":"https://api.github.com/repos/fail2ban/fail2ban/hooks","issue_events_url":"https://api.github.com/repos/fail2ban/fail2ban/issues/events{/number}","events_url":"https://api.github.com/repos/fail2ban/fail2ban/events","assignees_url":"https://api.github.com/repos/fail2ban/fail2ban/assignees{/user}","branches_url":"https://api.github.com/repos/fail2ban/fail2ban/branches{/branch}","tags_url":"https://api.github.com/repos/fail2ban/fail2ban/tags","blobs_url":"https://api.github.com/repos/fail2ban/fail2ban/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fail2ban/fail2ban/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fail2ban/fail2ban/git/refs{/sha}","trees_url":"https://api.github.com/repos/fail2ban/fail2ban/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fail2ban/fail2ban/statuses/{sha}","languages_url":"https://api.github.com/repos/fail2ban/fail2ban/languages","stargazers_url":"https://api.github.com/repos/fail2ban/fail2ban/stargazers","contributors_url":"https://api.github.com/repos/fail2ban/fail2ban/contributors","subscribers_url":"https://api.github.com/repos/fail2ban/fail2ban/subscribers","subscription_url":"https://api.github.com/repos/fail2ban/fail2ban/subscription","commits_url":"https://api.github.com/repos/fail2ban/fail2ban/commits{/sha}","git_commits_url":"https://api.github.com/repos/fail2ban/fail2ban/git/commits{/sha}","comments_url":"https://api.github.com/repos/fail2ban/fail2ban/comments{/number}","issue_comment_url":"https://api.github.com/repos/fail2ban/fail2ban/issues/comments{/number}","contents_url":"https://api.github.com/repos/fail2ban/fail2ban/contents/{+path}","compare_url":"https://api.github.com/repos/fail2ban/fail2ban/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fail2ban/fail2ban/merges","archive_url":"https://api.github.com/repos/fail2ban/fail2ban/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fail2ban/fail2ban/downloads","issues_url":"https://api.github.com/repos/fail2ban/fail2ban/issues{/number}","pulls_url":"https://api.github.com/repos/fail2ban/fail2ban/pulls{/number}","milestones_url":"https://api.github.com/repos/fail2ban/fail2ban/milestones{/number}","notifications_url":"https://api.github.com/repos/fail2ban/fail2ban/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fail2ban/fail2ban/labels{/name}","releases_url":"https://api.github.com/repos/fail2ban/fail2ban/releases{/id}","deployments_url":"https://api.github.com/repos/fail2ban/fail2ban/deployments","created_at":"2011-09-28T16:24:20Z","updated_at":"2016-09-23T01:48:18Z","pushed_at":"2016-09-22T21:07:56Z","git_url":"git://github.com/fail2ban/fail2ban.git","ssh_url":"git@github.com:fail2ban/fail2ban.git","clone_url":"https://github.com/fail2ban/fail2ban.git","svn_url":"https://github.com/fail2ban/fail2ban","homepage":"http://www.fail2ban.org","size":14921,"stargazers_count":1666,"watchers_count":1666,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":391,"mirror_url":null,"open_issues_count":221,"forks":391,"open_issues":221,"watchers":1666,"default_branch":"0.10"}},"_links":{"self":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557"},"html":{"href":"https://github.com/fail2ban/fail2ban/pull/1557"},"issue":{"href":"https://api.github.com/repos/fail2ban/fail2ban/issues/1557"},"comments":{"href":"https://api.github.com/repos/fail2ban/fail2ban/issues/1557/comments"},"review_comments":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557/comments"},"review_comment":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/fail2ban/fail2ban/pulls/1557/commits"},"statuses":{"href":"https://api.github.com/repos/fail2ban/fail2ban/statuses/e00be5f308c98a53bde277baa24d20b6712b9644"}}}}
{"actor":{"display_login":"sebres"}}