Skip to content

Course email for instructors - #555

Merged
sarina merged 11 commits into
masterfrom
feature/kluo/bulk-email-squashed
Aug 29, 2013
Merged

Course email for instructors#555
sarina merged 11 commits into
masterfrom
feature/kluo/bulk-email-squashed

Conversation

@kluo

@kluo kluo commented Aug 1, 2013

Copy link
Copy Markdown
Contributor

Updated from PR #437 with squashed commits for cleaner history and continued work.

Adds HTML editor for the email ported from CMS, which has raised some concerns that are still being discussed.
Unicode workaround for known issue Stanford-Online#3

@pmitros

pmitros commented Aug 2, 2013

Copy link
Copy Markdown
Contributor

Nice! We used SES for 6.002x, and the issues we ran into were:

  1. Performance. We needed many threads. The code does this, which is nice.
  2. Errors. We got a lot of errors, many specific to individual e-mail addresses (e.g. people who had an abuse complaint before -- which is automated for some e-mail services when users hit a 'spam' button), and some obscure. If a task handles many e-mails, and retries the rest of the task per failure (as opposed to just queuing up failed users and retrying those, so we have per-user retries), we may run into several issues, the key being awkward config. The desired number of retries will be coupled to expect number of users per task, and if we get a statistical variation in bad users, we may run out of retries. We may also run out of retries if the same individual user fails with the same error multiple times, and lose the rest of the users.

With regards to error handling, it's also be nice to know if there is some gross issue (e.g. a quarter of the e-mails are not delivered)

Analytics/tracking: It would be good if we could log when/if e-mails were sent to students in some way (e.g. log user, time, subject of e-mail, and hash of body/e-mail). This is a one-liner change.

Comment thread lms/djangoapps/bulk_email/tasks.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small style issue: we prefer to have docstrings surrounded by three double quotes, not single quotes.

@sarina

sarina commented Aug 5, 2013

Copy link
Copy Markdown
Contributor
  • I made some comments regarding Python styling in our codebase. Please check out https://github.com/edx/edx-platform/wiki/Python-Guidelines if you haven't already.
  • Your PR adds a bunch of Pylint violations. Please see the Diff-Quality report, http://jenkins.edx.org:8080/job/edx-feature-branch-tests/10089/Diff_Quality_Report/?, and address as much as you can. I also recommend rebasing to master today.
  • I notice you've made some changes to the instructor dash. @mlsteele made some instructor dashboard changes on Friday that may conflict with your changes, and/or he may need to update his beta version with your changes. Tagging him here so he can review what you've done.
  • What is the ETA on getting this merged in, and who on the edX side is shepherding this through? The work that @brianhw and I are starting today is going to be based off of this branch, and it seems foolish to start work if this branch is still going to be undergoing major revisions.

@brianhw

brianhw commented Aug 5, 2013

Copy link
Copy Markdown
Contributor

A more specific comment: the terminology for the "to" option is inconsistent. In the model, it is called "to" (too short), but the choices are "TO_OPTIONS". In the delegating task, it is called "recipients" (which sounds like a list of emails). It would be good to standardize on something, and I suggest "to_option".

I would also suggest a name change of the "hash" field to something indicating its purpose -- like index_key.

Optout contains email and course_id. Is there a reason for using email instead of user_id? In particular, a user can change an email address. Do we want to store created/modified times on this model, or are we relying on logging to track changes? (I think Piotr pointed out the lack of tracking logs -- maybe that is enough.)

@sarina

sarina commented Aug 6, 2013

Copy link
Copy Markdown
Contributor

The fixes look great! However I suspect the rebase will be challenging - between instructor dash, i18n, and various other changes that have landed recently. I recommend you do rebase sooner than later, to avoid the headache.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internationalize all your user-visible strings. https://edx-wiki.atlassian.net/wiki/pages/viewpage.action?pageId=12517501

@cahrens

cahrens commented Aug 8, 2013

Copy link
Copy Markdown

@talbs is there any place shared between LMS and CMS where things like problem-editor-icons.png can go?

Comment thread common/djangoapps/student/views.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use @require_POST ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, will update. Several other functions in this file should use decorators as well.

@talbs

talbs commented Aug 19, 2013

Copy link
Copy Markdown
Contributor

@cahrens, sorry for the delay.

RE: your question around storing common bits, we do have a /common/static/images/ directory. It looks like it has some things (green problem checkmark icon) that are meant to be shared across apps that render our courseware, but there is a lot of junk/old files there as well.

If I'm putting 2 and 2 together correctly, you're looking for a place to store templates. There's /common/templates.

Hope that helps. If you're looking for help/recommendations on something specific let me know.

Comment thread lms/djangoapps/bulk_email/tasks.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This .count() might do another query. The previous line materialized the entire recipient list, just use len(recipient_list).

Comment thread lms/djangoapps/bulk_email/tasks.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If optouts is a set because of duplicates, should num_optout be calculated on the size of the set? Actually it looks like it's only used to return a value at the end. If we want it to be an accurate number, it should be calculated as the change in the to_list before and after being filtered in the next line. If people opt out and then unenroll, there's no point in counting their optouts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not because of duplicates (see querying using pk). it's just there to speed up the filtering of to_list.
optouts is already a subset of the emails in to_list, and won't have duplicates since we're using pk to query also User.email and (Optout.user, Optout.course) have to be unique. So num_optout is accurate since each of its members will be stricken from to_list.

but we can change it to use len(set) just to be consistent.

@jbau

jbau commented Aug 28, 2013

Copy link
Copy Markdown

thx for all the comments @brianhw , I'll take a pass at addressing them tomorrow morning

@jbau

jbau commented Aug 28, 2013

Copy link
Copy Markdown

@brianhw @sarina I'm made the changes driven by comments, except for ones in code places I'm unfamiliar with. These are the db-based template, the get_analytics_result thing in legacy.py, and the 0006 migration.
I'd like to see that migration cleaned up before merge.

kluo and others added 11 commits August 29, 2013 12:40
Adds a new Email link to the instructor dashboard for frontend interface to send
email to course members. Adds a feature flag ENABLE_INSTRUCTOR_EMAIL to toggle this.
Creates a new djangoapp bulk_email that handles this action by getting the recipient
list and batching the emails to different celery tasks to do the actual sending.
Requires lynx package to convert HTML email to plaintext. Handles SMTP errors by
retrying or falling through to the next email. Adds the option to opt out of course
specific emails in the user dashboard with an Email Settings link for each course.
Uses severable configurable settings with defaults. DEFAULT_BULK_FROM_EMAIL
specifies the from address for email. EMAILS_PER_TASK specifies the number of emails
each celery task takes on. EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER,
EMAIL_HOST_PASSWORD, and EMAIL_USE_TLS for the SMTP email backend settings.

Co-authored-by: Akshay Jagadeesh <akjags@gmail.com>
 Delay for possible race condition with fetching course email object.
 Use settings.SITE_NAME for host name to generate email footer url.
Switch to using decorators; refactor and cleanup tests.
Includes Data + Schema migrations for optout email -> user.id change.
Note that migrations should be reversible.
Adds the edX Marketing-approved template as html default.
sarina added a commit that referenced this pull request Aug 29, 2013
@sarina
sarina merged commit 0142faf into master Aug 29, 2013
@sarina
sarina deleted the feature/kluo/bulk-email-squashed branch August 29, 2013 17:44
chrisrossi pushed a commit to jazkarta/edx-platform that referenced this pull request Mar 31, 2014
…ents-params

empty default for comments_service_key and comments_url because it was b...
hachiyanagi-ks added a commit to nttks/edx-platform that referenced this pull request Dec 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants