From patchwork Tue Oct 16 03:18:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Panteleev X-Patchwork-Id: 809 Return-Path: Delivered-To: patchwork@archlinux.org Received: from apollo.archlinux.org (localhost [127.0.0.1]) by apollo.archlinux.org (Postfix) with ESMTP id 352A27933321 for ; Tue, 16 Oct 2018 03:19:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on apollo X-Spam-Level: X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00=-1, MAILING_LIST_MULTI=-1,RCVD_IN_DNSWL_MED=-2.3 autolearn=ham autolearn_force=no version=3.4.2 X-Spam-BL-Results: [127.0.9.2] Received: from orion.archlinux.org (orion.archlinux.org [IPv6:2a01:4f8:160:6087::1]) by apollo.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:09 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id B8E3FE264212E; Tue, 16 Oct 2018 03:19:07 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [5.9.250.164]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS; Tue, 16 Oct 2018 03:19:07 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 774C9260AC; Tue, 16 Oct 2018 03:19:07 +0000 (UTC) Authentication-Results: luna.archlinux.org; dkim=none Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id EFE152503B for ; Tue, 16 Oct 2018 03:19:03 +0000 (UTC) Received: from orion.archlinux.org (orion.archlinux.org [88.198.91.70]) by luna.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:03 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 9B7D8E2642126 for ; Tue, 16 Oct 2018 03:19:02 +0000 (UTC) Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:02 +0000 (UTC) Received: by mail-wr1-f67.google.com with SMTP id 61-v6so23609605wrb.6 for ; Mon, 15 Oct 2018 20:19:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Xjn0Z86vMaJ38GzddgQ0nahNqYdpbVRl3d29ApQy65g=; b=pGyvAwaul/rrkiH8usLzWnRGHrBHe4KFX+ZEOfVDe23i/az7G+S1z3dasV31FnoLy3 2A9vHQWmcsGcyPhSwTcWlWVcP32/29LERaiIqdPw/OcsP7yXmeFx8D1eR/Cqn6t5YDVI kN1MwjzDaOM+H5pD0Q10RHfsJLfyAi0h+rOhRkoYc2ijjTCJY+Ds7AQaTAhTSM+DXKd7 FqyL8A23IfNZWy/Rouz72Qo+f+NfRWrtHS1JD5LeqLL1GO7TuROBNssp7JPhgQVbEZsa 0MZFPa1g4AgyJjDfH/1H/YtBn/feBo61SbAkbTL37AWla07iKmrD4GOsHsjygZsqhkBk A0Dg== X-Gm-Message-State: ABuFfohgUhKFmdTy2Yq7db4NzKVUzYisxOJarvUFUx6UUjLBAbW2bJAf M6/XLUJUIaYh94tDYUoaUMq42OMFdLc= X-Google-Smtp-Source: ACcGV61a6pj2X1VDNW92dswVMADzFN+6E4U0koaUkZun/sCnZLbaAXlW1Ph9qRgYZCBwToOlFMVBcw== X-Received: by 2002:a5d:4b50:: with SMTP id w16-v6mr13706701wrs.173.1539659941637; Mon, 15 Oct 2018 20:19:01 -0700 (PDT) Received: from home.thecybershadow.net ([89.28.117.31]) by smtp.gmail.com with ESMTPSA id 140-v6sm14723704wmx.34.2018.10.15.20.19.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Oct 2018 20:19:00 -0700 (PDT) From: Vladimir Panteleev To: aur-dev@archlinux.org Subject: [PATCH 1/2] notify.py: Encapsulate individual message recipient into a new class Date: Tue, 16 Oct 2018 03:18:43 +0000 Message-Id: <20181016031844.30857-2-archlinux@thecybershadow.net> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181016031844.30857-1-archlinux@thecybershadow.net> References: <20181016031844.30857-1-archlinux@thecybershadow.net> MIME-Version: 1.0 X-BeenThere: aur-dev@archlinux.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Arch User Repository \(AUR\) Development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: aur-dev-bounces@archlinux.org Sender: "aur-dev" Allow Notification implementations to add additional fields to their returned Recipient objects, so as to allow customizing the message body/subject per recipient. --- aurweb/scripts/notify.py | 156 ++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 69 deletions(-) diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py index 44eec84..c463823 100755 --- a/aurweb/scripts/notify.py +++ b/aurweb/scripts/notify.py @@ -41,6 +41,14 @@ def pkgbase_from_pkgreq(conn, reqid): return cur.fetchone()[0] +class Recipient: + def __init__(self, to, lang): + self._to, self._lang = to, lang + + def get_to(self): + return self._to + + class Notification: def __init__(self): self._l10n = aurweb.l10n.Translator() @@ -51,9 +59,9 @@ class Notification: def get_headers(self): return {} - def get_body_fmt(self, lang): + def get_body_fmt(self, recipient): body = '' - for line in self.get_body(lang).splitlines(): + for line in self.get_body(recipient).splitlines(): body += textwrap.fill(line, break_long_words=False) + '\n' for i, ref in enumerate(self.get_refs()): body += '\n' + '[%d] %s' % (i + 1, ref) @@ -65,10 +73,10 @@ class Notification: reply_to = aurweb.config.get('notifications', 'reply-to') for recipient in self.get_recipients(): - to, lang = recipient - msg = email.mime.text.MIMEText(self.get_body_fmt(lang), + to = recipient.get_to() + msg = email.mime.text.MIMEText(self.get_body_fmt(recipient), 'plain', 'utf-8') - msg['Subject'] = self.get_subject(lang) + msg['Subject'] = self.get_subject(recipient) msg['From'] = sender msg['Reply-to'] = reply_to msg['To'] = to @@ -89,34 +97,34 @@ class ResetKeyNotification(Notification): super().__init__() def get_recipients(self): - return [(self._to, self._lang)] + return [Recipient(self._to, self._lang)] - def get_subject(self, lang): - return self._l10n.translate('AUR Password Reset', lang) + def get_subject(self, recipient): + return self._l10n.translate('AUR Password Reset', recipient._lang) - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'A password reset request was submitted for the account ' '{user} associated with your email address. If you wish to ' 'reset your password follow the link [1] below, otherwise ' 'ignore this message and nothing will happen.', - lang).format(user=self._username) + recipient._lang).format(user=self._username) def get_refs(self): return (aur_location + '/passreset/?resetkey=' + self._resetkey,) class WelcomeNotification(ResetKeyNotification): - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('Welcome to the Arch User Repository', - lang) + recipient._lang) - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'Welcome to the Arch User Repository! In order to set an ' 'initial password for your new account, please click the ' 'link [1] below. If the link does not work, try copying and ' - 'pasting it into your browser.', lang) + 'pasting it into your browser.', recipient._lang) class CommentNotification(Notification): @@ -130,7 +138,7 @@ class CommentNotification(Notification): 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID = ?', [comment_id]) self._text = cur.fetchone()[0] @@ -139,20 +147,22 @@ class CommentNotification(Notification): def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Comment for {pkgbase}', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format( + pkgbase=self._pkgbase) - def get_body(self, lang): + def get_body(self, recipient): body = self._l10n.translate( '{user} [1] added the following comment to {pkgbase} [2]:', - lang).format(user=self._user, pkgbase=self._pkgbase) + recipient._lang).format(user=self._user, pkgbase=self._pkgbase) body += '\n\n' + self._text + '\n\n' - dnlabel = self._l10n.translate('Disable notifications', lang) + dnlabel = self._l10n.translate('Disable notifications', + recipient._lang) body += self._l10n.translate( 'If you no longer wish to receive notifications about this ' 'package, please go to the package page [2] and select ' - '"{label}".', lang).format(label=dnlabel) + '"{label}".', recipient._lang).format(label=dnlabel) return body def get_refs(self): @@ -177,27 +187,29 @@ class UpdateNotification(Notification): 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] super().__init__() def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Package Update: {pkgbase}', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format( + pkgbase=self._pkgbase) - def get_body(self, lang): + def get_body(self, recipient): body = self._l10n.translate('{user} [1] pushed a new commit to ' - '{pkgbase} [2].', lang).format( + '{pkgbase} [2].', recipient._lang).format( user=self._user, pkgbase=self._pkgbase) body += '\n\n' - dnlabel = self._l10n.translate('Disable notifications', lang) + dnlabel = self._l10n.translate('Disable notifications', + recipient._lang) body += self._l10n.translate( 'If you no longer wish to receive notifications about this ' 'package, please go to the package page [2] and select ' - '"{label}".', lang).format(label=dnlabel) + '"{label}".', recipient._lang).format(label=dnlabel) return body def get_refs(self): @@ -222,7 +234,7 @@ class FlagNotification(Notification): 'ON PackageBases.MaintainerUID = Users.ID OR ' + 'PackageBases.ID = PackageComaintainers.PackageBaseID ' + 'WHERE PackageBases.ID = ?', [pkgbase_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + 'ID = ?', [pkgbase_id]) self._text = cur.fetchone()[0] @@ -231,16 +243,17 @@ class FlagNotification(Notification): def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Out-of-date Notification for ' '{pkgbase}', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format( + pkgbase=self._pkgbase) - def get_body(self, lang): + def get_body(self, recipient): body = self._l10n.translate( 'Your package {pkgbase} [1] has been flagged out-of-date by ' - '{user} [2]:', lang).format(pkgbase=self._pkgbase, - user=self._user) + '{user} [2]:', recipient._lang).format(pkgbase=self._pkgbase, + user=self._user) body += '\n\n' + self._text return body @@ -261,7 +274,7 @@ class OwnershipEventNotification(Notification): 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + 'ID = ?', [pkgbase_id]) self._text = cur.fetchone()[0] @@ -270,9 +283,10 @@ class OwnershipEventNotification(Notification): def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Ownership Notification for {pkgbase}', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format( + pkgbase=self._pkgbase) def get_refs(self): return (aur_location + '/pkgbase/' + self._pkgbase + '/', @@ -280,18 +294,18 @@ class OwnershipEventNotification(Notification): class AdoptNotification(OwnershipEventNotification): - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'The package {pkgbase} [1] was adopted by {user} [2].', - lang).format(pkgbase=self._pkgbase, user=self._user) + recipient._lang).format(pkgbase=self._pkgbase, user=self._user) class DisownNotification(OwnershipEventNotification): - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'The package {pkgbase} [1] was disowned by {user} ' - '[2].', lang).format(pkgbase=self._pkgbase, - user=self._user) + '[2].', recipient._lang).format(pkgbase=self._pkgbase, + user=self._user) class ComaintainershipEventNotification(Notification): @@ -303,29 +317,30 @@ class ComaintainershipEventNotification(Notification): super().__init__() def get_recipients(self): - return [(self._to, self._lang)] + return [Recipient(self._to, self._lang)] - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Co-Maintainer Notification for ' '{pkgbase}', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format( + pkgbase=self._pkgbase) def get_refs(self): return (aur_location + '/pkgbase/' + self._pkgbase + '/',) class ComaintainerAddNotification(ComaintainershipEventNotification): - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'You were added to the co-maintainer list of {pkgbase} [1].', - lang).format(pkgbase=self._pkgbase) + recipient._lang).format(pkgbase=self._pkgbase) class ComaintainerRemoveNotification(ComaintainershipEventNotification): - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'You were removed from the co-maintainer list of {pkgbase} ' - '[1].', lang).format(pkgbase=self._pkgbase) + '[1].', recipient._lang).format(pkgbase=self._pkgbase) class DeleteNotification(Notification): @@ -343,31 +358,34 @@ class DeleteNotification(Notification): 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, old_pkgbase_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] super().__init__() def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('AUR Package deleted: {pkgbase}', - lang).format(pkgbase=self._old_pkgbase) + recipient._lang).format( + pkgbase=self._old_pkgbase) - def get_body(self, lang): + def get_body(self, recipient): if self._new_pkgbase: - dnlabel = self._l10n.translate('Disable notifications', lang) + dnlabel = self._l10n.translate('Disable notifications', + recipient._lang) return self._l10n.translate( '{user} [1] merged {old} [2] into {new} [3].\n\n' 'If you no longer wish receive notifications about the ' 'new package, please go to [3] and click "{label}".', - lang).format(user=self._user, old=self._old_pkgbase, - new=self._new_pkgbase, label=dnlabel) + recipient._lang).format( + user=self._user, old=self._old_pkgbase, + new=self._new_pkgbase, label=dnlabel) else: return self._l10n.translate( '{user} [1] deleted {pkgbase} [2].\n\n' 'You will no longer receive notifications about this ' - 'package.', lang).format(user=self._user, - pkgbase=self._old_pkgbase) + 'package.', recipient._lang).format( + user=self._user, pkgbase=self._old_pkgbase) def get_refs(self): refs = (aur_location + '/account/' + self._user + '/', @@ -398,13 +416,13 @@ class RequestOpenNotification(Notification): self._merge_into = merge_into def get_recipients(self): - return [(self._to, 'en')] + return [Recipient(self._to, 'en')] - def get_subject(self, lang): + def get_subject(self, recipient): return '[PRQ#%d] %s Request for %s' % \ (self._reqid, self._reqtype.title(), self._pkgbase) - def get_body(self, lang): + def get_body(self, recipient): if self._merge_into: body = '%s [1] filed a request to merge %s [2] into %s [3]:' % \ (self._user, self._pkgbase, self._merge_into) @@ -455,15 +473,15 @@ class RequestCloseNotification(Notification): self._reason = reason def get_recipients(self): - return [(self._to, 'en')] + return [Recipient(self._to, 'en')] - def get_subject(self, lang): + def get_subject(self, recipient): return '[PRQ#%d] %s Request for %s %s' % (self._reqid, self._reqtype.title(), self._pkgbase, self._reason.title()) - def get_body(self, lang): + def get_body(self, recipient): if self._user: body = 'Request #%d has been %s by %s [1]' % \ (self._reqid, self._reason, self._user) @@ -497,21 +515,21 @@ class TUVoteReminderNotification(Notification): 'WHERE AccountTypeID IN (2, 4) AND ID NOT IN ' + '(SELECT UserID FROM TU_Votes ' + 'WHERE TU_Votes.VoteID = ?)', [vote_id]) - self._recipients = cur.fetchall() + self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] super().__init__() def get_recipients(self): return self._recipients - def get_subject(self, lang): + def get_subject(self, recipient): return self._l10n.translate('TU Vote Reminder: Proposal {id}', - lang).format(id=self._vote_id) + recipient._lang).format(id=self._vote_id) - def get_body(self, lang): + def get_body(self, recipient): return self._l10n.translate( 'Please remember to cast your vote on proposal {id} [1]. ' 'The voting period ends in less than 48 hours.', - lang).format(id=self._vote_id) + recipient._lang).format(id=self._vote_id) def get_refs(self): return (aur_location + '/tu/?id=' + str(self._vote_id),) From patchwork Tue Oct 16 03:18:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Panteleev X-Patchwork-Id: 810 Return-Path: Delivered-To: patchwork@archlinux.org Received: from apollo.archlinux.org (localhost [127.0.0.1]) by apollo.archlinux.org (Postfix) with ESMTP id 2EE70793333F for ; Tue, 16 Oct 2018 03:19:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on apollo X-Spam-Level: X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00=-1, MAILING_LIST_MULTI=-1,RCVD_IN_DNSWL_MED=-2.3 autolearn=ham autolearn_force=no version=3.4.2 X-Spam-BL-Results: [127.0.0.6] [127.0.9.2] Received: from orion.archlinux.org (orion.archlinux.org [IPv6:2a01:4f8:160:6087::1]) by apollo.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:14 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id C401AE2642147; Tue, 16 Oct 2018 03:19:12 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [IPv6:2a01:4f8:160:3033::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS; Tue, 16 Oct 2018 03:19:12 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id E2B9E282F9; Tue, 16 Oct 2018 03:19:08 +0000 (UTC) Authentication-Results: luna.archlinux.org; dkim=none Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 0BAC828068 for ; Tue, 16 Oct 2018 03:19:06 +0000 (UTC) Received: from orion.archlinux.org (orion.archlinux.org [IPv6:2a01:4f8:160:6087::1]) by luna.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:06 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 8952AE2642129 for ; Tue, 16 Oct 2018 03:19:04 +0000 (UTC) Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS for ; Tue, 16 Oct 2018 03:19:04 +0000 (UTC) Received: by mail-wr1-f41.google.com with SMTP id 63-v6so23572791wra.11 for ; Mon, 15 Oct 2018 20:19:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VLAgP4NyPopnfMEss/HKgl8u5d17oE6IxuO+OMdwSNg=; b=KUFFLrUszqwntQ+X+TpnBadO8AGicmf6X6dWNaFMdEBjK9EMrHnoDLq4WGqQe65zzN nBlP6lKSwssf28K6oc10dPexoEGWzjyPlbZBIljYKBb3XkYcFcAwWFzqsQbGNV6VI5p/ KCt7BXp+O5og6ViuFTmWPfx6sJPiWRaI4A9Mo3VfYB8u3BNmhI4u9VQyybsct4PR4EwY 5xrVB+75o4PTHJwfmw24+f0z9dUH3BUz9JFXoV68dy9y2haRAN67TB9g3vpQwWVODV/G KRvJPoZiazMoQG2kyBMpUDvCP4aRY4Ov+RHr3qLe9tqsPAPi+kxYHMFN/kZmtHNbn0EI os1w== X-Gm-Message-State: ABuFfogCbaj99J/j+fI1WLxvHTAxgMsb6BYOn4hkogTZ3C/ESiLBkyIA 6q3IOL71Nqt7fYH4dhr6ncPlDYQ+tlI= X-Google-Smtp-Source: ACcGV61X47pbZio+crJbUhOvZm5Cp3x3oNy3wJUl4BJh4mJ/9OLm66F44F86Uu3IWWlxBtoU/TgqMA== X-Received: by 2002:a05:6000:111:: with SMTP id o17mr17585325wrx.279.1539659943659; Mon, 15 Oct 2018 20:19:03 -0700 (PDT) Received: from home.thecybershadow.net ([89.28.117.31]) by smtp.gmail.com with ESMTPSA id 140-v6sm14723704wmx.34.2018.10.15.20.19.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Oct 2018 20:19:02 -0700 (PDT) From: Vladimir Panteleev To: aur-dev@archlinux.org Subject: [PATCH 2/2] notify.py: Mention users' relationship to packages in comment notifications Date: Tue, 16 Oct 2018 03:18:44 +0000 Message-Id: <20181016031844.30857-3-archlinux@thecybershadow.net> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181016031844.30857-1-archlinux@thecybershadow.net> References: <20181016031844.30857-1-archlinux@thecybershadow.net> MIME-Version: 1.0 X-BeenThere: aur-dev@archlinux.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Arch User Repository \(AUR\) Development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: aur-dev-bounces@archlinux.org Sender: "aur-dev" Generally, it's useful to distinguish actionable vs. non-actionable notifications. When receiving a comment notification on a package a user maintains, it can be easy to miss it in a flood of comment notifications for packages the user merely follows. To this end, mention the user's relationship to the package when sending a comment notification email. --- aurweb/scripts/notify.py | 66 +++++++++++++++-- test/t2500-notify.sh | 150 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 7 deletions(-) diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py index c463823..30eb0c3 100755 --- a/aurweb/scripts/notify.py +++ b/aurweb/scripts/notify.py @@ -127,18 +127,65 @@ class WelcomeNotification(ResetKeyNotification): 'pasting it into your browser.', recipient._lang) +class CommentRecipient(Recipient): + def __init__(self, to, lang, role_short, role_long): + self._role_short = role_short + self._role_long = role_long + super().__init__(to, lang) + + class CommentNotification(Notification): def __init__(self, conn, uid, pkgbase_id, comment_id): self._user = username_from_id(conn, uid) - self._pkgbase = pkgbase_from_id(conn, pkgbase_id) - cur = conn.execute('SELECT DISTINCT Users.Email, Users.LangPreference ' + cur = conn.execute('SELECT Name, FlaggerUID, SubmitterUID, ' + + 'MaintainerUID, PackagerUID FROM PackageBases ' + + 'WHERE ID = ?', [pkgbase_id]) + (self._pkgbase, + flagger_id, submitter_id, maintainer_id, packager_id) = cur.fetchone() + + cur = conn.execute('SELECT DISTINCT Users.ID, Users.Email, ' + + 'Users.LangPreference, ' + + 'COUNT(PackageComaintainers.UsersID) ' + 'FROM Users INNER JOIN PackageNotifications ' + - 'ON PackageNotifications.UserID = Users.ID WHERE ' + + 'ON PackageNotifications.UserID = Users.ID ' + + 'LEFT JOIN PackageComaintainers ' + + 'ON PackageComaintainers.UsersID = Users.ID ' + + 'AND PackageComaintainers.PackageBaseID = ' + + 'PackageNotifications.PackageBaseID WHERE ' + 'Users.CommentNotify = 1 AND ' + 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) - self._recipients = [Recipient(to, lang) for to, lang in cur.fetchall()] + recipients = [] + for (user_id, to, lang, is_comaintainer) in cur: + if user_id == maintainer_id: + role_short = self._l10n.translate(' (maintained by you)', lang) + role_long = self._l10n.translate( + 'You are currently maintaining this package.', lang) + elif is_comaintainer > 0: + role_short = self._l10n.translate( + ' (co-maintained by you)', lang) + role_long = self._l10n.translate( + 'You are currently co-maintaining this package.', lang) + elif user_id == packager_id: + role_short = self._l10n.translate(' (packaged by you)', lang) + role_long = self._l10n.translate( + 'You are this package\'s last packager.', lang) + elif user_id == submitter_id: + role_short = self._l10n.translate(' (submitted by you)', lang) + role_long = self._l10n.translate( + 'You are this package\'s submitter.', lang) + elif user_id == flagger_id: + role_short = self._l10n.translate(' (flagged by you)', lang) + role_long = self._l10n.translate( + 'You have last flagged this package.', lang) + else: + role_short = None + role_long = None + recipients.append(CommentRecipient(to, lang, + role_short, role_long)) + self._recipients = recipients + cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID = ?', [comment_id]) self._text = cur.fetchone()[0] @@ -148,15 +195,20 @@ class CommentNotification(Notification): return self._recipients def get_subject(self, recipient): - return self._l10n.translate('AUR Comment for {pkgbase}', - recipient._lang).format( - pkgbase=self._pkgbase) + subject = self._l10n.translate('AUR Comment for {pkgbase}', + recipient._lang).format( + pkgbase=self._pkgbase) + if recipient._role_short: + subject += recipient._role_short + return subject def get_body(self, recipient): body = self._l10n.translate( '{user} [1] added the following comment to {pkgbase} [2]:', recipient._lang).format(user=self._user, pkgbase=self._pkgbase) body += '\n\n' + self._text + '\n\n' + if recipient._role_long: + body += recipient._role_long + '\n\n' dnlabel = self._l10n.translate('Disable notifications', recipient._lang) body += self._l10n.translate( diff --git a/test/t2500-notify.sh b/test/t2500-notify.sh index c9c7208..c8936e0 100755 --- a/test/t2500-notify.sh +++ b/test/t2500-notify.sh @@ -110,6 +110,156 @@ test_expect_success 'Test subject and body of comment notifications.' ' test_cmp actual expected ' +test_expect_success 'Test subject and body of comment notifications for flaggers.' ' + cat <<-EOD | sqlite3 aur.db && + UPDATE PackageBases SET FlaggerUID = 2 WHERE ID == 1001; + EOD + >sendmail.out && + "$NOTIFY" comment 1 1001 2001 && + grep ^Subject: sendmail.out >actual && + cat <<-EOD >expected && + Subject: AUR Comment for foobar (flagged by you) + EOD + test_cmp actual expected && + sed -n "/^\$/,\$p" sendmail.out | base64 -d >actual && + echo >>actual && + cat <<-EOD >expected && + user [1] added the following comment to foobar [2]: + + This is a test comment. + + You have last flagged this package. + + If you no longer wish to receive notifications about this package, + please go to the package page [2] and select "Disable notifications". + + [1] https://aur.archlinux.org/account/user/ + [2] https://aur.archlinux.org/pkgbase/foobar/ + EOD + test_cmp actual expected +' + +test_expect_success 'Test subject and body of comment notifications for submitters.' ' + cat <<-EOD | sqlite3 aur.db && + /* Keep and accumulate FlaggerUID and other properties from preceding tests. */ + /* Only the most "important" relationship should be mentioned. */ + UPDATE PackageBases SET SubmitterUID = 2 WHERE ID == 1001; + EOD + >sendmail.out && + "$NOTIFY" comment 1 1001 2001 && + grep ^Subject: sendmail.out >actual && + cat <<-EOD >expected && + Subject: AUR Comment for foobar (submitted by you) + EOD + test_cmp actual expected && + sed -n "/^\$/,\$p" sendmail.out | base64 -d >actual && + echo >>actual && + cat <<-EOD >expected && + user [1] added the following comment to foobar [2]: + + This is a test comment. + + You are this package'\''s submitter. + + If you no longer wish to receive notifications about this package, + please go to the package page [2] and select "Disable notifications". + + [1] https://aur.archlinux.org/account/user/ + [2] https://aur.archlinux.org/pkgbase/foobar/ + EOD + test_cmp actual expected +' + +test_expect_success 'Test subject and body of comment notifications for packagers.' ' + cat <<-EOD | sqlite3 aur.db && + UPDATE PackageBases SET PackagerUID = 2 WHERE ID == 1001; + EOD + >sendmail.out && + "$NOTIFY" comment 1 1001 2001 && + grep ^Subject: sendmail.out >actual && + cat <<-EOD >expected && + Subject: AUR Comment for foobar (packaged by you) + EOD + test_cmp actual expected && + sed -n "/^\$/,\$p" sendmail.out | base64 -d >actual && + echo >>actual && + cat <<-EOD >expected && + user [1] added the following comment to foobar [2]: + + This is a test comment. + + You are this package'\''s last packager. + + If you no longer wish to receive notifications about this package, + please go to the package page [2] and select "Disable notifications". + + [1] https://aur.archlinux.org/account/user/ + [2] https://aur.archlinux.org/pkgbase/foobar/ + EOD + test_cmp actual expected +' + +test_expect_success 'Test subject and body of comment notifications for co-maintainers.' ' + cat <<-EOD | sqlite3 aur.db && + INSERT INTO PackageComaintainers (PackageBaseID, UsersID, Priority) VALUES (1001, 2, 1); + EOD + >sendmail.out && + "$NOTIFY" comment 1 1001 2001 && + grep ^Subject: sendmail.out >actual && + cat <<-EOD >expected && + Subject: AUR Comment for foobar (co-maintained by you) + EOD + test_cmp actual expected && + sed -n "/^\$/,\$p" sendmail.out | base64 -d >actual && + echo >>actual && + cat <<-EOD >expected && + user [1] added the following comment to foobar [2]: + + This is a test comment. + + You are currently co-maintaining this package. + + If you no longer wish to receive notifications about this package, + please go to the package page [2] and select "Disable notifications". + + [1] https://aur.archlinux.org/account/user/ + [2] https://aur.archlinux.org/pkgbase/foobar/ + EOD + test_cmp actual expected +' + +test_expect_success 'Test subject and body of comment notifications for maintainers.' ' + cat <<-EOD | sqlite3 aur.db && + UPDATE PackageBases SET MaintainerUID = 2 WHERE ID == 1001; + EOD + >sendmail.out && + "$NOTIFY" comment 1 1001 2001 && + grep ^Subject: sendmail.out >actual && + cat <<-EOD >expected && + Subject: AUR Comment for foobar (maintained by you) + EOD + test_cmp actual expected && + sed -n "/^\$/,\$p" sendmail.out | base64 -d >actual && + echo >>actual && + cat <<-EOD >expected && + user [1] added the following comment to foobar [2]: + + This is a test comment. + + You are currently maintaining this package. + + If you no longer wish to receive notifications about this package, + please go to the package page [2] and select "Disable notifications". + + [1] https://aur.archlinux.org/account/user/ + [2] https://aur.archlinux.org/pkgbase/foobar/ + EOD + test_cmp actual expected + cat <<-EOD | sqlite3 aur.db + DELETE FROM PackageComaintainers; + EOD +' + test_expect_success 'Test subject and body of update notifications.' ' cat <<-EOD | sqlite3 aur.db && UPDATE Users SET UpdateNotify = 1 WHERE ID = 2;