diff --git a/alembic/versions/11fb55be6e62_added_campaign_model.py b/alembic/versions/11fb55be6e62_added_campaign_model.py new file mode 100644 index 0000000..fbdd7fa --- /dev/null +++ b/alembic/versions/11fb55be6e62_added_campaign_model.py @@ -0,0 +1,56 @@ +"""Added campaign model + +Revision ID: 11fb55be6e62 +Revises: 155bdd6d893d +Create Date: 2013-12-23 15:37:54.560976 + +""" + +# revision identifiers, used by Alembic. +revision = '11fb55be6e62' +down_revision = '155bdd6d893d' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.add_column('user', sa.Column('send_newsletter', sa.Boolean(), nullable=False, server_default=sa.text(u"'t'"))) + + op.alter_column('user', 'send_newsletter', server_default=None) + + # Create a new table for email_campaign + op.create_table('email_campaign', + sa.Column('id', sa.Integer, nullable=False, primary_key=True), + sa.Column('event_id', sa.Integer, nullable=False), + sa.Column('status', sa.Integer, nullable=False), + sa.Column('start_datetime', sa.DateTime, nullable=False), + sa.Column('end_datetime', sa.DateTime, nullable=True), + sa.Column('name', sa.Unicode(250), nullable=False, unique=True), + sa.Column('title', sa.Unicode(250), nullable=False), + sa.Column('created_at', sa.DateTime, nullable=False), + sa.Column('updated_at', sa.DateTime, nullable=False), + ) + op.create_foreign_key("fk_email_campaign_event_id", "email_campaign", "event", ["event_id"], ["id"], ondelete="CASCADE") + + # Create a new table for email_campaign_user + op.create_table('email_campaign_user', + sa.Column('id', sa.Integer, nullable=False, primary_key=True), + sa.Column('user_id', sa.Integer, nullable=False), + sa.Column('email_campaign_id', sa.Integer, nullable=False), + sa.Column('created_at', sa.DateTime, nullable=False), + sa.Column('updated_at', sa.DateTime, nullable=False), + ) + op.create_foreign_key("fk_email_campaign_user_user_id", "email_campaign_user", "user", ["user_id"], ["id"], ondelete="CASCADE") + op.create_foreign_key("fk_email_campaign_user_email_campaign_id", "email_campaign_user", "email_campaign", ["email_campaign_id"], ["id"], ondelete="CASCADE") + + ### end Alembic commands ### + + +def downgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'send_newsletter') + op.drop_table('email_campaign_user') + op.drop_table('email_campaign') + ### end Alembic commands ### diff --git a/hacknight/forms/profile.py b/hacknight/forms/profile.py index 7217874..10169aa 100644 --- a/hacknight/forms/profile.py +++ b/hacknight/forms/profile.py @@ -3,10 +3,14 @@ import wtforms from baseframe.forms import Form, RichTextField -__all__ = ['ProfileForm'] +__all__ = ['ProfileForm', 'NewsLetterForm'] class ProfileForm(Form): type = wtforms.SelectField(u"Profile type", coerce=int, validators=[wtforms.validators.Required()]) description = RichTextField(u"Description/Bio", content_css="/static/css/editor.css") + + +class NewsLetterForm(Form): + send_newsletter = wtforms.BooleanField("Receive NewsLetter", description="Do you like to receive notification about new hacknight?") diff --git a/hacknight/models/__init__.py b/hacknight/models/__init__.py index daebcb6..76f7aeb 100644 --- a/hacknight/models/__init__.py +++ b/hacknight/models/__init__.py @@ -12,3 +12,4 @@ from hacknight.models.project import * from hacknight.models.participant import * from hacknight.models.sponsor import * +from hacknight.models.campaign import * diff --git a/hacknight/models/campaign.py b/hacknight/models/campaign.py new file mode 100644 index 0000000..dc12095 --- /dev/null +++ b/hacknight/models/campaign.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +import datetime +from hacknight.models import db, BaseNameMixin, BaseMixin, Event, User + + +class EMAIL_CAMPAIGN_STATUS: + COMPLETED = 1 + PROGRESS = 2 + + +class EmailCampaign(BaseNameMixin, db.Model): + __tablename__ = "email_campaign" + + event_id = db.Column(None, db.ForeignKey('event.id'), nullable=False) + event = db.relationship(Event) + start_datetime = db.Column(db.DateTime, default=datetime.datetime.utcnow, nullable=False) + end_datetime = db.Column(db.DateTime, nullable=True) + status = db.Column(db.Integer, default=EMAIL_CAMPAIGN_STATUS.PROGRESS, nullable=False) + + @classmethod + def get(cls, event): + return cls.query.filter_by(event=event).first() + + @classmethod + def sent_for(cls, event): + email_campaign = cls.get(event=event) + if email_campaign: + if email_campaign.status == EMAIL_CAMPAIGN_STATUS.COMPLETED: + return True + return False + + def yet_to_send(self): + return set(User.subscribed_to_newsletter()) - set([user.user for user in self.users]) + + +class EmailCampaignUser(BaseMixin, db.Model): + __tablename__ = "email_campaign_user" + + user_id = db.Column(None, db.ForeignKey('user.id'), nullable=False) + user = db.relationship(User) + email_campaign_id = db.Column(None, db.ForeignKey('email_campaign.id'), nullable=False) + email_campaign = db.relationship(EmailCampaign, backref=db.backref('users', cascade='all, delete-orphan')) diff --git a/hacknight/models/event.py b/hacknight/models/event.py index 37093ff..0b6182c 100644 --- a/hacknight/models/event.py +++ b/hacknight/models/event.py @@ -64,6 +64,10 @@ def url_for(self, action='view', _external=True): return url_for('profile_view', profile=self.name, _external=_external) elif action == 'new-event': return url_for('event_new', profile=self.name, _external=_external) + elif action == 'settings': + return url_for('profile_settings', profile=self.name, _external=_external) + elif action == 'unsubscribe': + return url_for('profile_settings', action='unsubscribe', profile=self.name, _external=_external) class Event(BaseScopedNameMixin, db.Model): diff --git a/hacknight/models/user.py b/hacknight/models/user.py index b757a22..d8a6be5 100644 --- a/hacknight/models/user.py +++ b/hacknight/models/user.py @@ -14,6 +14,7 @@ class User(UserBase, db.Model): phone_no = db.Column(db.Unicode(15), default=u'', nullable=True) job_title = db.Column(db.Unicode(120), default=u'', nullable=True) company = db.Column(db.Unicode(1200), default=u'', nullable=True) + send_newsletter = db.Column(db.Boolean, default=True, nullable=False) @property def profile_url(self): @@ -28,6 +29,10 @@ def profiles(self): return [self.profile] + Profile.query.filter( Profile.userid.in_(self.organizations_owned_ids())).order_by('title').all() + @classmethod + def subscribed_to_newsletter(cls): + return cls.query.filter_by(send_newsletter=True).all() + def projects_in(self, event): return [member.project for member in self.project_memberships if member.project.event == event] diff --git a/hacknight/templates/send_newsletter.html b/hacknight/templates/send_newsletter.html new file mode 100644 index 0000000..544f4a8 --- /dev/null +++ b/hacknight/templates/send_newsletter.html @@ -0,0 +1,7 @@ +
+ You are receiving this mail because you registered for Hacknight newsletter.
+ Unsubscribe
+