Add Immediate frequency option, reorder to None/Immediate/Daily/Weekly, default Daily
Subscription frequency was missing Immediate and defaulted to Weekly. Now offers four options in logical order with Daily as the default digest.
This commit is contained in:
parent
7f3b3e2fee
commit
df9270b3aa
5 changed files with 32 additions and 18 deletions
|
|
@ -2,12 +2,14 @@
|
|||
Console script to send email digests to shop subscribers.
|
||||
|
||||
Usage:
|
||||
digest_sender data/development.ini --frequency immediate
|
||||
digest_sender data/development.ini --frequency daily
|
||||
digest_sender data/development.ini --frequency weekly --dry-run
|
||||
|
||||
Cron setup:
|
||||
0 8 * * * /path/to/env/bin/digest_sender /path/to/production.ini --frequency daily
|
||||
0 8 * * 1 /path/to/env/bin/digest_sender /path/to/production.ini --frequency weekly
|
||||
*/5 * * * * /path/to/env/bin/digest_sender /path/to/production.ini --frequency immediate
|
||||
0 8 * * * /path/to/env/bin/digest_sender /path/to/production.ini --frequency daily
|
||||
0 8 * * 1 /path/to/env/bin/digest_sender /path/to/production.ini --frequency weekly
|
||||
"""
|
||||
|
||||
import argparse
|
||||
|
|
@ -22,6 +24,7 @@ from ..models.product import Product
|
|||
from ..models.shop_subscription import (
|
||||
FREQUENCY_DAILY,
|
||||
FREQUENCY_WEEKLY,
|
||||
FREQUENCY_IMMEDIATE,
|
||||
get_verified_subscriptions_for_shop,
|
||||
)
|
||||
from .mail import send_email
|
||||
|
|
@ -37,7 +40,7 @@ def parse_args(argv):
|
|||
p.add_argument("config_uri", help="Pyramid config file, e.g. development.ini")
|
||||
p.add_argument(
|
||||
"--frequency",
|
||||
choices=["daily", "weekly"],
|
||||
choices=["immediate", "daily", "weekly"],
|
||||
required=True,
|
||||
help="Which frequency of subscribers to process",
|
||||
)
|
||||
|
|
@ -95,7 +98,12 @@ def build_digest_html(shop_name, items, unsubscribe_url, get_endpoint=""):
|
|||
|
||||
def run(env, frequency_str, dry_run=False):
|
||||
"""Process all shops and send digests."""
|
||||
frequency = FREQUENCY_DAILY if frequency_str == "daily" else FREQUENCY_WEEKLY
|
||||
freq_map = {
|
||||
"immediate": FREQUENCY_IMMEDIATE,
|
||||
"daily": FREQUENCY_DAILY,
|
||||
"weekly": FREQUENCY_WEEKLY,
|
||||
}
|
||||
frequency = freq_map.get(frequency_str, FREQUENCY_DAILY)
|
||||
request = env["request"]
|
||||
dbsession = request.dbsession
|
||||
settings = request.registry.settings
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@ from .meta import (
|
|||
|
||||
FREQUENCY_DAILY = 0
|
||||
FREQUENCY_WEEKLY = 1
|
||||
FREQUENCY_IMMEDIATE = 2
|
||||
|
||||
FREQUENCY_HUMAN = {
|
||||
FREQUENCY_DAILY: "Daily",
|
||||
FREQUENCY_WEEKLY: "Weekly",
|
||||
FREQUENCY_IMMEDIATE: "Immediate",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -27,7 +29,7 @@ class ShopSubscription(RBase, Base):
|
|||
shop_id = Column(UUIDType, foreign_key("Shop", "id"), nullable=False, index=True)
|
||||
user_id = Column(UUIDType, foreign_key("User", "id"), nullable=True, index=True)
|
||||
email = Column(Unicode(64), nullable=False)
|
||||
frequency = Column(Integer, nullable=False, default=FREQUENCY_WEEKLY)
|
||||
frequency = Column(Integer, nullable=False, default=FREQUENCY_DAILY)
|
||||
verified = Column(Boolean, nullable=False, default=False)
|
||||
unsubscribe_token = Column(Unicode(64), nullable=False, unique=True)
|
||||
verify_token = Column(Unicode(64), nullable=True)
|
||||
|
|
@ -40,7 +42,7 @@ class ShopSubscription(RBase, Base):
|
|||
self.email = email
|
||||
self.shop_id = shop_id
|
||||
self.user_id = user_id
|
||||
self.frequency = FREQUENCY_WEEKLY
|
||||
self.frequency = FREQUENCY_DAILY
|
||||
self.disabled = False
|
||||
self.unsubscribe_token = secrets.token_urlsafe(32)
|
||||
self.created_timestamp = now_timestamp()
|
||||
|
|
@ -56,7 +58,7 @@ class ShopSubscription(RBase, Base):
|
|||
|
||||
@property
|
||||
def human_frequency(self):
|
||||
return FREQUENCY_HUMAN.get(self.frequency, "Weekly")
|
||||
return FREQUENCY_HUMAN.get(self.frequency, "Daily")
|
||||
|
||||
|
||||
def get_subscription_for_email_and_shop(dbsession, email, shop_id):
|
||||
|
|
|
|||
|
|
@ -111,12 +111,15 @@
|
|||
<input type="radio" name="frequency" value="-1" id="freq-none" />
|
||||
<label for="freq-none" class="freq-option freq-none">None</label>
|
||||
|
||||
<input type="radio" name="frequency" value="1" id="freq-weekly" checked />
|
||||
<label for="freq-weekly" class="freq-option">Weekly</label>
|
||||
<input type="radio" name="frequency" value="2" id="freq-immediate" />
|
||||
<label for="freq-immediate" class="freq-option">Immediate</label>
|
||||
|
||||
<input type="radio" name="frequency" value="0" id="freq-daily" />
|
||||
<input type="radio" name="frequency" value="0" id="freq-daily" checked />
|
||||
<label for="freq-daily" class="freq-option">Daily</label>
|
||||
|
||||
<input type="radio" name="frequency" value="1" id="freq-weekly" />
|
||||
<label for="freq-weekly" class="freq-option">Weekly</label>
|
||||
|
||||
<input type="submit" name="submit" class="subscribe-btn" value="Save Preferences" />
|
||||
</form>
|
||||
|
||||
|
|
|
|||
|
|
@ -2548,12 +2548,12 @@ class TestShopSubscription(unittest.TestCase):
|
|||
self.assertNotEqual(sub1.unsubscribe_token, sub2.unsubscribe_token)
|
||||
self.assertNotEqual(sub1.verify_token, sub2.verify_token)
|
||||
|
||||
def test_default_frequency_weekly(self):
|
||||
"""Test that default frequency is weekly."""
|
||||
from ..models.shop_subscription import ShopSubscription, FREQUENCY_WEEKLY
|
||||
def test_default_frequency_daily(self):
|
||||
"""Test that default frequency is daily."""
|
||||
from ..models.shop_subscription import ShopSubscription, FREQUENCY_DAILY
|
||||
|
||||
sub = ShopSubscription("test@example.com", self.shop.id)
|
||||
self.assertEqual(sub.frequency, FREQUENCY_WEEKLY)
|
||||
self.assertEqual(sub.frequency, FREQUENCY_DAILY)
|
||||
|
||||
def test_human_frequency(self):
|
||||
"""Test human_frequency property."""
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from ..models.shop_subscription import (
|
|||
ShopSubscription,
|
||||
FREQUENCY_DAILY,
|
||||
FREQUENCY_WEEKLY,
|
||||
FREQUENCY_IMMEDIATE,
|
||||
get_subscription_for_email_and_shop,
|
||||
get_subscription_by_unsubscribe_token,
|
||||
get_subscription_by_verify_token,
|
||||
|
|
@ -45,17 +46,17 @@ def subscribe(request):
|
|||
)
|
||||
|
||||
if request.method == "POST":
|
||||
frequency_str = request.params.get("frequency", "1")
|
||||
frequency_str = request.params.get("frequency", "0")
|
||||
try:
|
||||
frequency = int(frequency_str)
|
||||
except (ValueError, TypeError):
|
||||
frequency = FREQUENCY_WEEKLY
|
||||
frequency = FREQUENCY_DAILY
|
||||
|
||||
# frequency -1 means "None" — disable notifications
|
||||
wants_unsubscribe = frequency == -1
|
||||
|
||||
if frequency not in (FREQUENCY_DAILY, FREQUENCY_WEEKLY):
|
||||
frequency = FREQUENCY_WEEKLY
|
||||
if frequency not in (FREQUENCY_DAILY, FREQUENCY_WEEKLY, FREQUENCY_IMMEDIATE):
|
||||
frequency = FREQUENCY_DAILY
|
||||
|
||||
if request.user and request.user.authenticated:
|
||||
# Logged-in user: one-click subscribe
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue