Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
b3bc4023
Commit
b3bc4023
authored
Aug 22, 2013
by
Sarina Canelake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor html->plaintext conversion (for bulk email) into separate library
parent
f98d6764
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
53 additions
and
10 deletions
+53
-10
common/lib/html_to_text.py
+23
-0
lms/djangoapps/bulk_email/models.py
+1
-0
lms/djangoapps/bulk_email/tasks.py
+3
-9
lms/djangoapps/bulk_email/tests/test_course_optout.py
+8
-0
lms/djangoapps/bulk_email/tests/test_email.py
+7
-1
lms/djangoapps/bulk_email/tests/test_err_handling.py
+2
-0
lms/djangoapps/bulk_email/tests/tests.py
+6
-0
lms/djangoapps/instructor/views/legacy.py
+3
-0
No files found.
common/lib/html_to_text.py
0 → 100644
View file @
b3bc4023
"""Provides a function to convert html to plaintext."""
from
subprocess
import
Popen
,
PIPE
def
html_to_text
(
html_message
):
"""
Converts an html message to plaintext.
Currently uses lynx in a subprocess; should be refactored to
use something more pythonic.
"""
process
=
Popen
(
[
'lynx'
,
'-stdin'
,
'-display_charset=UTF-8'
,
'-assume_charset=UTF-8'
,
'-dump'
],
stdin
=
PIPE
,
stdout
=
PIPE
)
# use lynx to get plaintext
(
plaintext
,
err_from_stderr
)
=
process
.
communicate
(
input
=
html_message
.
encode
(
'utf-8'
)
)
if
err_from_stderr
:
log
.
info
(
err_from_stderr
)
return
plaintext
lms/djangoapps/bulk_email/models.py
View file @
b3bc4023
...
...
@@ -14,6 +14,7 @@ class Email(models.Model):
hash
=
models
.
CharField
(
max_length
=
128
,
db_index
=
True
)
subject
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
)
html_message
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
text_message
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
modified
=
models
.
DateTimeField
(
auto_now
=
True
)
...
...
lms/djangoapps/bulk_email/tasks.py
View file @
b3bc4023
...
...
@@ -8,7 +8,6 @@ import re
import
time
from
smtplib
import
SMTPServerDisconnected
,
SMTPDataError
,
SMTPConnectError
from
subprocess
import
Popen
,
PIPE
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
,
Group
...
...
@@ -98,15 +97,9 @@ def course_email(hash_for_msg, to_list, course_title, course_url, throttle=False
subject
=
"["
+
course_title
+
"] "
+
msg
.
subject
process
=
Popen
([
'lynx'
,
'-stdin'
,
'-display_charset=UTF-8'
,
'-assume_charset=UTF-8'
,
'-dump'
],
stdin
=
PIPE
,
stdout
=
PIPE
)
(
plaintext
,
err_from_stderr
)
=
process
.
communicate
(
input
=
msg
.
html_message
.
encode
(
'utf-8'
))
# use lynx to get plaintext
course_title_no_quotes
=
re
.
sub
(
r'"'
,
''
,
course_title
)
from_addr
=
'"{0}" Course Staff <{1}>'
.
format
(
course_title_no_quotes
,
settings
.
DEFAULT_BULK_FROM_EMAIL
)
if
err_from_stderr
:
log
.
info
(
err_from_stderr
)
try
:
connection
=
get_connection
()
connection
.
open
()
...
...
@@ -136,14 +129,15 @@ def course_email(hash_for_msg, to_list, course_title, course_url, throttle=False
email_msg
=
EmailMultiAlternatives
(
subject
,
plaintext
+
plain_footer
.
encode
(
'utf-8'
),
msg
.
text_message
+
plain_footer
.
encode
(
'utf-8'
),
from_addr
,
[
email
],
connection
=
connection
)
email_msg
.
attach_alternative
(
msg
.
html_message
+
html_footer
.
encode
(
'utf-8'
),
'text/html'
)
if
throttle
or
current_task
.
request
.
retries
>
0
:
# throttle if we tried a few times and got the rate limiter
# Throttle if we tried a few times and got the rate limiter
if
throttle
or
current_task
.
request
.
retries
>
0
:
time
.
sleep
(
0.2
)
try
:
...
...
lms/djangoapps/bulk_email/tests/test_course_optout.py
View file @
b3bc4023
...
...
@@ -31,6 +31,12 @@ class TestOptoutCourseEmails(ModuleStoreTestCase):
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
"test"
)
def
tearDown
(
self
):
"""
Undo all patches.
"""
patch
.
stopall
()
def
navigate_to_email_view
(
self
):
"""Navigate to the instructor dash's email view"""
# Pull up email view on instructor dashboard
...
...
@@ -54,6 +60,8 @@ class TestOptoutCourseEmails(ModuleStoreTestCase):
Make sure student does not receive course email after opting out.
"""
url
=
reverse
(
'change_email_settings'
)
# This is a checkbox, so on the post of opting out (that is, an Un-check of the box),
# the Post that is sent will not contain 'receive_emails'
response
=
self
.
client
.
post
(
url
,
{
'course_id'
:
self
.
course
.
id
})
self
.
assertEquals
(
json
.
loads
(
response
.
content
),
{
'success'
:
True
})
...
...
lms/djangoapps/bulk_email/tests/test_email.py
View file @
b3bc4023
...
...
@@ -64,6 +64,12 @@ class TestEmailSendFromDashboard(ModuleStoreTestCase):
selected_email_link
=
'<a href="#" onclick="goto(
\'
Email
\'
)" class="selectedmode">Email</a>'
self
.
assertTrue
(
selected_email_link
in
response
.
content
)
def
tearDown
(
self
):
"""
Undo all patches.
"""
patch
.
stopall
()
def
test_send_to_self
(
self
):
"""
Make sure email send to myself goes to myself.
...
...
@@ -185,7 +191,7 @@ class TestEmailSendFromDashboard(ModuleStoreTestCase):
self
.
assertIn
(
u'ẗëṡẗ ṁëṡṡäġë ḟöṛ äḷḷ イ乇丂イ ᄊ乇丂丂ムg乇 キo尺 ムレレ тэѕт мэѕѕаБэ fоѓ аll'
,
mail
.
outbox
[
0
]
.
body
.
decode
(
'utf-8'
)
mail
.
outbox
[
0
]
.
body
)
def
test_unicode_students_send_to_all
(
self
):
...
...
lms/djangoapps/bulk_email/tests/test_err_handling.py
View file @
b3bc4023
...
...
@@ -40,8 +40,10 @@ class TestEmailErrors(ModuleStoreTestCase):
self
.
url
=
reverse
(
'instructor_dashboard'
,
kwargs
=
{
'course_id'
:
self
.
course
.
id
})
def
tearDown
(
self
):
self
.
smtp_server_thread
.
stop
()
patch
.
stopall
()
@patch
(
'bulk_email.tasks.course_email.retry'
)
def
test_data_err_retry
(
self
,
retry
):
...
...
lms/djangoapps/bulk_email/tests/tests.py
View file @
b3bc4023
...
...
@@ -32,6 +32,12 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase):
# URL for email view
self
.
email_link
=
'<a href="#" onclick="goto(
\'
Email
\'
)" class="None">Email</a>'
def
tearDown
(
self
):
"""
Undo all patches.
"""
patch
.
stopall
()
@patch.dict
(
settings
.
MITX_FEATURES
,
{
'ENABLE_INSTRUCTOR_EMAIL'
:
True
})
def
test_email_flag_true
(
self
):
# Assert that the URL for the email view is in the response
...
...
lms/djangoapps/instructor/views/legacy.py
View file @
b3bc4023
...
...
@@ -55,6 +55,7 @@ from mitxmako.shortcuts import render_to_string
from
bulk_email.models
import
CourseEmail
from
html_to_text
import
html_to_text
import
datetime
from
hashlib
import
md5
from
bulk_email
import
tasks
...
...
@@ -706,12 +707,14 @@ def instructor_dashboard(request, course_id):
to_option
=
request
.
POST
.
get
(
"to_option"
)
subject
=
request
.
POST
.
get
(
"subject"
)
html_message
=
request
.
POST
.
get
(
"message"
)
text_message
=
html_to_text
(
html_message
)
email
=
CourseEmail
(
course_id
=
course_id
,
sender
=
request
.
user
,
to
=
to_option
,
subject
=
subject
,
html_message
=
html_message
,
text_message
=
text_message
,
hash
=
md5
((
html_message
+
subject
+
datetime
.
datetime
.
isoformat
(
datetime
.
datetime
.
now
()))
.
encode
(
'utf-8'
))
.
hexdigest
())
email
.
save
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment