{"action":"created","comment":{"url":"https://api.github.com/repos/odoo/odoo/pulls/comments/233052026","pull_request_review_id":174380522,"id":233052026,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMzA1MjAyNg==","diff_hunk":"@@ -0,0 +1,46 @@\n+# -*- coding: utf-8 -*-\n+# Part of Odoo. See LICENSE file for full copyright and licensing details.\n+\n+from odoo import api, fields, models, tools, _\n+from odoo.exceptions import UserError\n+\n+\n+class MailAddressMixin(models.AbstractModel):\n+    \"\"\" This Mixin can be used to store a normalized version of the primary email address of the parent model.\n+        The email_normalized field can than be used on that model to search quickly on emails (by simple comparison\n+        and not using time consuming regex anymore).\n+        USAGE : the field '_primary_email' must be overridden in the model that inherit the mixin\n+        and must contain the email field of the model.\n+        \"\"\"\n+    _name = 'mail.address.mixin'\n+    _description = 'Email address mixin'\n+    _primary_email = ['email']\n+\n+    email_normalized = fields.Char(string='Normalized email address', compute=\"_compute_email_normalized\", invisible=True,\n+                                  compute_sudo=True, store=True, help=\"\"\"This field is used to search on email address,\n+                                  as the primary email field can contain more than strictly an email address.\"\"\")\n+\n+    @api.depends(lambda self: self._primary_email)\n+    def _compute_email_normalized(self):\n+        self._assert_primary_email()\n+        [email_field] = self._primary_email\n+        for record in self:\n+            record.email_normalized = self._normalize_email(record[email_field])\n+\n+    def _normalize_email(self, email):","path":"addons/mail/models/mail_address_mixin.py","position":null,"original_position":30,"commit_id":"f39d113d7c14b116644976b0049f3170c328898f","original_commit_id":"33a8f6408e7bf0d73e27ba153250a3336fc8f208","user":{"login":"dbeguin","id":38424442,"node_id":"MDQ6VXNlcjM4NDI0NDQy","avatar_url":"https://avatars2.githubusercontent.com/u/38424442?v=4","gravatar_id":"","url":"https://api.github.com/users/dbeguin","html_url":"https://github.com/dbeguin","followers_url":"https://api.github.com/users/dbeguin/followers","following_url":"https://api.github.com/users/dbeguin/following{/other_user}","gists_url":"https://api.github.com/users/dbeguin/gists{/gist_id}","starred_url":"https://api.github.com/users/dbeguin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbeguin/subscriptions","organizations_url":"https://api.github.com/users/dbeguin/orgs","repos_url":"https://api.github.com/users/dbeguin/repos","events_url":"https://api.github.com/users/dbeguin/events{/privacy}","received_events_url":"https://api.github.com/users/dbeguin/received_events","type":"User","site_admin":false},"body":"done in one of the next commits","created_at":"2018-11-13T14:11:53Z","updated_at":"2018-11-13T14:13:39Z","html_url":"https://github.com/odoo/odoo/pull/28205#discussion_r233052026","pull_request_url":"https://api.github.com/repos/odoo/odoo/pulls/28205","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments/233052026"},"html":{"href":"https://github.com/odoo/odoo/pull/28205#discussion_r233052026"},"pull_request":{"href":"https://api.github.com/repos/odoo/odoo/pulls/28205"}},"in_reply_to_id":229250325},"pull_request":{"url":"https://api.github.com/repos/odoo/odoo/pulls/28205","id":226124299,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI2MTI0Mjk5","html_url":"https://github.com/odoo/odoo/pull/28205","diff_url":"https://github.com/odoo/odoo/pull/28205.diff","patch_url":"https://github.com/odoo/odoo/pull/28205.patch","issue_url":"https://api.github.com/repos/odoo/odoo/issues/28205","number":28205,"state":"open","locked":false,"title":"mail : Store normalized email addresses","user":{"login":"dbeguin","id":38424442,"node_id":"MDQ6VXNlcjM4NDI0NDQy","avatar_url":"https://avatars2.githubusercontent.com/u/38424442?v=4","gravatar_id":"","url":"https://api.github.com/users/dbeguin","html_url":"https://github.com/dbeguin","followers_url":"https://api.github.com/users/dbeguin/followers","following_url":"https://api.github.com/users/dbeguin/following{/other_user}","gists_url":"https://api.github.com/users/dbeguin/gists{/gist_id}","starred_url":"https://api.github.com/users/dbeguin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbeguin/subscriptions","organizations_url":"https://api.github.com/users/dbeguin/orgs","repos_url":"https://api.github.com/users/dbeguin/repos","events_url":"https://api.github.com/users/dbeguin/events{/privacy}","received_events_url":"https://api.github.com/users/dbeguin/received_events","type":"User","site_admin":false},"body":"Add a mixin that can be used to store a normalized version of the primary\r\nemail address of the parent model. The email_normalized field can\r\nthan be used on that model to search quickly on emails (by simple\r\ncomparison and not using time consuming regex anymore)\r\n\r\nApply the mail.address.mixin on blacklist mixin. So that every model\r\ninheriting the blacklist.mixin will also inherit the address.mixin.\r\nThat simplify also the comparaison to - and the searches on - the\r\nblacklist.\r\n\r\nUse the email.normalized from mail.address.mixin to get always a normalized\r\nemail address in the unsubscribe link. That allows to simplify the search\r\non email address in the controllers -> Check blacklist, send feedback, etc..\r\n\r\nTask ID 1896677\r\n\r\n--\r\nI confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr\r\n","created_at":"2018-10-26T14:45:38Z","updated_at":"2018-11-13T14:13:39Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c5b841494cf3dcf2a481fdbc232e924802e6cf1c","assignee":null,"assignees":[],"requested_reviewers":[{"login":"tde-banana-odoo","id":7501424,"node_id":"MDQ6VXNlcjc1MDE0MjQ=","avatar_url":"https://avatars2.githubusercontent.com/u/7501424?v=4","gravatar_id":"","url":"https://api.github.com/users/tde-banana-odoo","html_url":"https://github.com/tde-banana-odoo","followers_url":"https://api.github.com/users/tde-banana-odoo/followers","following_url":"https://api.github.com/users/tde-banana-odoo/following{/other_user}","gists_url":"https://api.github.com/users/tde-banana-odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/tde-banana-odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tde-banana-odoo/subscriptions","organizations_url":"https://api.github.com/users/tde-banana-odoo/orgs","repos_url":"https://api.github.com/users/tde-banana-odoo/repos","events_url":"https://api.github.com/users/tde-banana-odoo/events{/privacy}","received_events_url":"https://api.github.com/users/tde-banana-odoo/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":1044840932,"node_id":"MDU6TGFiZWwxMDQ0ODQwOTMy","url":"https://api.github.com/repos/odoo/odoo/labels/CI%20%F0%9F%A4%96","name":"CI 🤖","color":"ededed","default":false},{"id":106173385,"node_id":"MDU6TGFiZWwxMDYxNzMzODU=","url":"https://api.github.com/repos/odoo/odoo/labels/RD","name":"RD","color":"5319e7","default":false},{"id":1044215768,"node_id":"MDU6TGFiZWwxMDQ0MjE1NzY4","url":"https://api.github.com/repos/odoo/odoo/labels/seen%20%F0%9F%99%82","name":"seen 🙂","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/odoo/odoo/pulls/28205/commits","review_comments_url":"https://api.github.com/repos/odoo/odoo/pulls/28205/comments","review_comment_url":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/odoo/odoo/issues/28205/comments","statuses_url":"https://api.github.com/repos/odoo/odoo/statuses/f39d113d7c14b116644976b0049f3170c328898f","head":{"label":"odoo-dev:master-mail-address-mixin-dbe","ref":"master-mail-address-mixin-dbe","sha":"f39d113d7c14b116644976b0049f3170c328898f","user":{"login":"odoo-dev","id":7466976,"node_id":"MDEyOk9yZ2FuaXphdGlvbjc0NjY5NzY=","avatar_url":"https://avatars0.githubusercontent.com/u/7466976?v=4","gravatar_id":"","url":"https://api.github.com/users/odoo-dev","html_url":"https://github.com/odoo-dev","followers_url":"https://api.github.com/users/odoo-dev/followers","following_url":"https://api.github.com/users/odoo-dev/following{/other_user}","gists_url":"https://api.github.com/users/odoo-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo-dev/subscriptions","organizations_url":"https://api.github.com/users/odoo-dev/orgs","repos_url":"https://api.github.com/users/odoo-dev/repos","events_url":"https://api.github.com/users/odoo-dev/events{/privacy}","received_events_url":"https://api.github.com/users/odoo-dev/received_events","type":"Organization","site_admin":false},"repo":{"id":19853934,"node_id":"MDEwOlJlcG9zaXRvcnkxOTg1MzkzNA==","name":"odoo","full_name":"odoo-dev/odoo","private":false,"owner":{"login":"odoo-dev","id":7466976,"node_id":"MDEyOk9yZ2FuaXphdGlvbjc0NjY5NzY=","avatar_url":"https://avatars0.githubusercontent.com/u/7466976?v=4","gravatar_id":"","url":"https://api.github.com/users/odoo-dev","html_url":"https://github.com/odoo-dev","followers_url":"https://api.github.com/users/odoo-dev/followers","following_url":"https://api.github.com/users/odoo-dev/following{/other_user}","gists_url":"https://api.github.com/users/odoo-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo-dev/subscriptions","organizations_url":"https://api.github.com/users/odoo-dev/orgs","repos_url":"https://api.github.com/users/odoo-dev/repos","events_url":"https://api.github.com/users/odoo-dev/events{/privacy}","received_events_url":"https://api.github.com/users/odoo-dev/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/odoo-dev/odoo","description":"RD Dev Repository","fork":true,"url":"https://api.github.com/repos/odoo-dev/odoo","forks_url":"https://api.github.com/repos/odoo-dev/odoo/forks","keys_url":"https://api.github.com/repos/odoo-dev/odoo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odoo-dev/odoo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odoo-dev/odoo/teams","hooks_url":"https://api.github.com/repos/odoo-dev/odoo/hooks","issue_events_url":"https://api.github.com/repos/odoo-dev/odoo/issues/events{/number}","events_url":"https://api.github.com/repos/odoo-dev/odoo/events","assignees_url":"https://api.github.com/repos/odoo-dev/odoo/assignees{/user}","branches_url":"https://api.github.com/repos/odoo-dev/odoo/branches{/branch}","tags_url":"https://api.github.com/repos/odoo-dev/odoo/tags","blobs_url":"https://api.github.com/repos/odoo-dev/odoo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odoo-dev/odoo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odoo-dev/odoo/git/refs{/sha}","trees_url":"https://api.github.com/repos/odoo-dev/odoo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odoo-dev/odoo/statuses/{sha}","languages_url":"https://api.github.com/repos/odoo-dev/odoo/languages","stargazers_url":"https://api.github.com/repos/odoo-dev/odoo/stargazers","contributors_url":"https://api.github.com/repos/odoo-dev/odoo/contributors","subscribers_url":"https://api.github.com/repos/odoo-dev/odoo/subscribers","subscription_url":"https://api.github.com/repos/odoo-dev/odoo/subscription","commits_url":"https://api.github.com/repos/odoo-dev/odoo/commits{/sha}","git_commits_url":"https://api.github.com/repos/odoo-dev/odoo/git/commits{/sha}","comments_url":"https://api.github.com/repos/odoo-dev/odoo/comments{/number}","issue_comment_url":"https://api.github.com/repos/odoo-dev/odoo/issues/comments{/number}","contents_url":"https://api.github.com/repos/odoo-dev/odoo/contents/{+path}","compare_url":"https://api.github.com/repos/odoo-dev/odoo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odoo-dev/odoo/merges","archive_url":"https://api.github.com/repos/odoo-dev/odoo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odoo-dev/odoo/downloads","issues_url":"https://api.github.com/repos/odoo-dev/odoo/issues{/number}","pulls_url":"https://api.github.com/repos/odoo-dev/odoo/pulls{/number}","milestones_url":"https://api.github.com/repos/odoo-dev/odoo/milestones{/number}","notifications_url":"https://api.github.com/repos/odoo-dev/odoo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odoo-dev/odoo/labels{/name}","releases_url":"https://api.github.com/repos/odoo-dev/odoo/releases{/id}","deployments_url":"https://api.github.com/repos/odoo-dev/odoo/deployments","created_at":"2014-05-16T11:16:19Z","updated_at":"2018-11-03T19:22:39Z","pushed_at":"2018-11-13T14:11:12Z","git_url":"git://github.com/odoo-dev/odoo.git","ssh_url":"git@github.com:odoo-dev/odoo.git","clone_url":"https://github.com/odoo-dev/odoo.git","svn_url":"https://github.com/odoo-dev/odoo","homepage":"https://www.odoo.com","size":2386442,"stargazers_count":82,"watchers_count":82,"language":null,"has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":40,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":40,"open_issues":0,"watchers":82,"default_branch":"master"}},"base":{"label":"odoo:master","ref":"master","sha":"2ff49c5fcb584c8215ecbcb0034690e53732fb49","user":{"login":"odoo","id":6368483,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYzNjg0ODM=","avatar_url":"https://avatars2.githubusercontent.com/u/6368483?v=4","gravatar_id":"","url":"https://api.github.com/users/odoo","html_url":"https://github.com/odoo","followers_url":"https://api.github.com/users/odoo/followers","following_url":"https://api.github.com/users/odoo/following{/other_user}","gists_url":"https://api.github.com/users/odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo/subscriptions","organizations_url":"https://api.github.com/users/odoo/orgs","repos_url":"https://api.github.com/users/odoo/repos","events_url":"https://api.github.com/users/odoo/events{/privacy}","received_events_url":"https://api.github.com/users/odoo/received_events","type":"Organization","site_admin":false},"repo":{"id":19745004,"node_id":"MDEwOlJlcG9zaXRvcnkxOTc0NTAwNA==","name":"odoo","full_name":"odoo/odoo","private":false,"owner":{"login":"odoo","id":6368483,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYzNjg0ODM=","avatar_url":"https://avatars2.githubusercontent.com/u/6368483?v=4","gravatar_id":"","url":"https://api.github.com/users/odoo","html_url":"https://github.com/odoo","followers_url":"https://api.github.com/users/odoo/followers","following_url":"https://api.github.com/users/odoo/following{/other_user}","gists_url":"https://api.github.com/users/odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo/subscriptions","organizations_url":"https://api.github.com/users/odoo/orgs","repos_url":"https://api.github.com/users/odoo/repos","events_url":"https://api.github.com/users/odoo/events{/privacy}","received_events_url":"https://api.github.com/users/odoo/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/odoo/odoo","description":"Odoo. Open Source Apps To Grow Your Business.","fork":false,"url":"https://api.github.com/repos/odoo/odoo","forks_url":"https://api.github.com/repos/odoo/odoo/forks","keys_url":"https://api.github.com/repos/odoo/odoo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odoo/odoo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odoo/odoo/teams","hooks_url":"https://api.github.com/repos/odoo/odoo/hooks","issue_events_url":"https://api.github.com/repos/odoo/odoo/issues/events{/number}","events_url":"https://api.github.com/repos/odoo/odoo/events","assignees_url":"https://api.github.com/repos/odoo/odoo/assignees{/user}","branches_url":"https://api.github.com/repos/odoo/odoo/branches{/branch}","tags_url":"https://api.github.com/repos/odoo/odoo/tags","blobs_url":"https://api.github.com/repos/odoo/odoo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odoo/odoo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odoo/odoo/git/refs{/sha}","trees_url":"https://api.github.com/repos/odoo/odoo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odoo/odoo/statuses/{sha}","languages_url":"https://api.github.com/repos/odoo/odoo/languages","stargazers_url":"https://api.github.com/repos/odoo/odoo/stargazers","contributors_url":"https://api.github.com/repos/odoo/odoo/contributors","subscribers_url":"https://api.github.com/repos/odoo/odoo/subscribers","subscription_url":"https://api.github.com/repos/odoo/odoo/subscription","commits_url":"https://api.github.com/repos/odoo/odoo/commits{/sha}","git_commits_url":"https://api.github.com/repos/odoo/odoo/git/commits{/sha}","comments_url":"https://api.github.com/repos/odoo/odoo/comments{/number}","issue_comment_url":"https://api.github.com/repos/odoo/odoo/issues/comments{/number}","contents_url":"https://api.github.com/repos/odoo/odoo/contents/{+path}","compare_url":"https://api.github.com/repos/odoo/odoo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odoo/odoo/merges","archive_url":"https://api.github.com/repos/odoo/odoo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odoo/odoo/downloads","issues_url":"https://api.github.com/repos/odoo/odoo/issues{/number}","pulls_url":"https://api.github.com/repos/odoo/odoo/pulls{/number}","milestones_url":"https://api.github.com/repos/odoo/odoo/milestones{/number}","notifications_url":"https://api.github.com/repos/odoo/odoo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odoo/odoo/labels{/name}","releases_url":"https://api.github.com/repos/odoo/odoo/releases{/id}","deployments_url":"https://api.github.com/repos/odoo/odoo/deployments","created_at":"2014-05-13T15:38:58Z","updated_at":"2018-11-13T14:07:59Z","pushed_at":"2018-11-13T14:11:19Z","git_url":"git://github.com/odoo/odoo.git","ssh_url":"git@github.com:odoo/odoo.git","clone_url":"https://github.com/odoo/odoo.git","svn_url":"https://github.com/odoo/odoo","homepage":"https://www.odoo.com","size":2376919,"stargazers_count":11668,"watchers_count":11668,"language":"JavaScript","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9111,"mirror_url":null,"archived":false,"open_issues_count":1968,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":9111,"open_issues":1968,"watchers":11668,"default_branch":"12.0"}},"_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/28205"},"html":{"href":"https://github.com/odoo/odoo/pull/28205"},"issue":{"href":"https://api.github.com/repos/odoo/odoo/issues/28205"},"comments":{"href":"https://api.github.com/repos/odoo/odoo/issues/28205/comments"},"review_comments":{"href":"https://api.github.com/repos/odoo/odoo/pulls/28205/comments"},"review_comment":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/odoo/odoo/pulls/28205/commits"},"statuses":{"href":"https://api.github.com/repos/odoo/odoo/statuses/f39d113d7c14b116644976b0049f3170c328898f"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"dbeguin"}}