Commit graph

663 commits

Author SHA1 Message Date
Stephane Bisson 5ffbc4db97 Fix foreign bundle count
Use foreign source reported notifications count
instead of counting the actual objects.

Counting objects is wrong because of bundles
that are 1 object but represent multiple notifications.

Bug: T138888
Change-Id: Ib63efc1e33af8f4364a7ba11a0dc3ff820f0a03c
2016-06-29 09:09:55 -04:00
Stephane Bisson f8a8d392d6 Expandable bundle
Support bundles being expandable
to show their sub-notifications.

Bug: T114356
Change-Id: I1507cae360f45cc87f2d60e966b4d047abfa202d
2016-06-28 15:37:54 -04:00
jenkins-bot 731cde01b8 Merge "Dynamic bundles" 2016-06-28 19:34:42 +00:00
jenkins-bot 8ca3bbac5e Merge "Mention notification: don't repeat the section title at the begining of the excerpt" 2016-06-28 19:13:00 +00:00
Stephane Bisson 23691d73d1 Mention notification: don't repeat the section title at the begining of the excerpt
Bug: T134922
Change-Id: I731ed9a7fafa7964aca776c543a58f6c5692f89a
2016-06-28 09:48:38 -04:00
Stephane Bisson cf7bee76ee Don't send empty emails
If no notification can be rendered,
don't send an email at all.

Bug: T137012
Change-Id: I57944e7af275ddecdffc82de8c050d8baa357660
2016-06-28 09:19:01 -04:00
Stephane Bisson 24caf50ff6 Dynamic bundles
To allow individual notifications to be
marked as read/unread or moderated,
bundles are created by grouping associated
notifications when they are fetched for display
instead of when they are created.

From a product perspective, this change doesn't
introduce moderation or expandable bundles but
it counts each individual notifications.
For instance, the bundled notification
"3 new topics on PageA" now counts as 3
notifications.

Bug: T93673
Bug: T120153
Change-Id: Iacd098573efd92bb1e3fcd7da4cd40cea9522f15
2016-06-27 09:49:13 -04:00
jenkins-bot 79aad8f479 Merge "Add support for querying notifications not associated with any page" 2016-06-27 13:35:02 +00:00
Roan Kattouw 7d97881344 Add support for querying notifications not associated with any page
Uses the magic value '[]' to mean 'no title'. This is a bit ugly,
but I think introducing an additional &notwithouttitle=1 parameter
is uglier and results in more code.

Change-Id: I83278182aeaf3905eb0f3e24c4c6c247720b1e76
2016-06-24 00:37:21 +02:00
jenkins-bot 2eabf079f8 Merge "Clean up and fix updateEchoSchemaForSuppression.php" 2016-06-23 20:38:04 +00:00
jenkins-bot c90176a2cb Merge "ApiUnreadNotificationPages: Output pages as an array rather than an object" 2016-06-23 19:35:37 +00:00
Roan Kattouw 6c4bf99da8 ApiUnreadNotificationPages: Output pages as an array rather than an object
Make the frontend code based on page titles rather than page IDs.

Change-Id: I79c6a0e3a7178acdb14039a0c5208e90a7341044
2016-06-23 17:00:51 +02:00
jenkins-bot 190994bab2 Merge "Use the actual total notification count in the special page sidebar" 2016-06-23 11:05:14 +00:00
Moriel Schottlender bbf2ba7e7b Change link to help page on Special:Notifications
Bug: T138395
Change-Id: I6b9476206c53925a9d63b41da4b2fde33c739584
2016-06-22 12:38:38 -07:00
Stephane Bisson c93800e17c Support for PlaceholderWidget with no link
Bug: T137490
Change-Id: Ia861b5aa3f100124418956a0e09603a9ba29215a
2016-06-22 12:54:13 -04:00
Roan Kattouw e4b79c1bc2 Use the actual total notification count in the special page sidebar
Adding up numbers in the front-end is not enough, because it could
be that not all pages are listed (it's a top 10). So get the
total count from the backend.

Change-Id: Ibbc76691ef88333b92132a514fdba3cde3797e10
2016-06-22 17:11:34 +01:00
addshore c1b4e4d5aa docs: Fix typo of 'begining' instead of 'beginning' in phpdoc
Change-Id: Ibc015f2133393788634d7e8b6119dcc305c6c534
2016-06-22 13:02:13 +00:00
Stephane Bisson b3273d23d7 Define global transition vars before using them
Bug: T132954
Change-Id: I9515f79285672aff10545502ba1558dc2443eaff
2016-06-21 08:00:27 -04:00
jenkins-bot 6b20e63b73 Merge "Clarify mention error log comment" 2016-06-20 16:14:54 +00:00
WMDE-Fisch 3e9b2055b2 Clarify mention error log comment
The case also logs non-existing users.

Change-Id: Id5a360b672df11d214459432c4ebbed5c03c1ba9
2016-06-20 18:01:51 +02:00
jenkins-bot 6d12122f9f Merge "Gracefully handle outdated echo_unread_wikis rows" 2016-06-20 15:51:18 +00:00
Roan Kattouw 792de35994 Gracefully handle outdated echo_unread_wikis rows
Adds $wgEchoSectionTransition and $wgEchoBundleTransition.
If either of these settings is enabled, we will disbelieve
the alert/message counts in the euw table and obtain them
using server-side cross-wiki API queries instead.

This affects both ApiEchoNotifications (for generating the cross-wiki
summary entry) and the count and timestamp computation in NotifUser.

In bundle transition mode, we trust that notifications are classified
correctly between alerts and messages, but we don't trust the
counts in the table. In section transition mode, we trust that
the sum of the alert and message counts is the correct count,
but we don't trust the alert and message counts individually.
If both modes are enabled, we mistrust anything that's mistrusted
by either mode and only trust what's trusted by both modes.
In any event, we do trust that only the wikis with rows in the
euw table have unread notifications.

Bug: T132954
Change-Id: Ibcc8ac102dac3cf06916d67427b42457fdb93db6
2016-06-20 16:21:03 +01:00
matejsuchanek 282ec08110 Add missing parameter to a message
This is already done in EditUserTalk-, Mention- and RevertedPresentationModel,
so PageLinked- should be consistent.

Change-Id: I4786406cabab778250d72c7ed92701b940a0a9f7
2016-06-20 17:14:45 +02:00
jenkins-bot 15dc477e04 Merge "Try to extract an excerpt from a revision" 2016-06-19 10:02:39 +00:00
Stephane Bisson d55396dee8 Try to extract an excerpt from a revision
Bug: T120152
Change-Id: I91abb2dded9ab7f124aaa798dd07c52576ee791b
2016-06-17 11:26:00 -04:00
Roan Kattouw 87e515e02b NotifUser: rename preloadKeys() to getPreloadKeys() and make it tolerate uncomputable keys
Change-Id: Id9a39a481533d39f99c9d7f43c573af81fe957cf
2016-06-17 15:49:31 +01:00
Catrope 2771b94af7 Revert "Implement backfillUnreadWikis.php in terms of resetNotificationCount()"
Better idea: invalidate caches in this script, and write
a separate script to recompute existing euw rows.

This reverts commit c83af257d2.

Change-Id: I57bccfb726eada646cb318206d9091a20d59dcf5
2016-06-17 13:43:29 +00:00
jenkins-bot 7a6d0f6aa3 Merge "ApiEchoNotificatons: Add nottitles parameter" 2016-06-16 12:09:46 +00:00
Roan Kattouw bbac9ff0c4 Follow-up 05e531c7b6: actually unset notcrosswikisummary
To prevent recursive cross-wiki notifications from appearing.

Change-Id: I63808e32561a350bf8b3286ebc9ec180958059c7
2016-06-15 23:48:54 +01:00
jenkins-bot e6c78fa09a Merge "Allow the primary link to set all bundled notifications as read" 2016-06-14 15:42:35 +00:00
Stephane Bisson b06b2294c9 Allow the primary link to set all bundled notifications as read
Bug: T136368
Change-Id: If07369cb168d1a085f297293e713d65e49997264
2016-06-14 08:49:23 -04:00
Roan Kattouw bcbb1763be PageLinkedPresentationModel: Use the correct title for the diff link
Also cache the from title, because Title::newFromId() doesn't cache
its results.

Bug: T137798
Change-Id: I5df444d3dacd55fbee09e53d82ac22c77ee9e246
2016-06-14 12:30:03 +01:00
Roan Kattouw 016e6dabda ApiEchoNotificatons: Add nottitles parameter
To only show notifications related to a certain title
(or set of titles).

Bug: T137139
Change-Id: I5c82e02bc8e8553c5b761a771b975f03d943d408
2016-06-13 20:19:32 +01:00
Roan Kattouw 00c5e5ae25 ApiEchoUnreadNotificationPages: Only count bundle bases
Change-Id: I6da4b72c7326dcf1354253aa98fdff8b82678ed8
2016-06-13 20:19:32 +01:00
jenkins-bot 954e83b0f8 Merge "Add ?markasread=NNN to primary links in emails too" 2016-06-13 11:52:03 +00:00
Roan Kattouw c09517492d Add ?markasread=NNN to primary links in emails too
This ensures that following the link in the email
marks the notification as read.

Bug: T137488
Change-Id: Id365650239c032f224a86c49691faef772cdc62d
2016-06-10 00:15:22 +02:00
Roan Kattouw 05e531c7b6 Factor out cross-wiki API request code
Change-Id: Id926a607b99103d4489d1b734e00d104b7e80233
2016-06-08 22:35:57 +02:00
Roan Kattouw c83af257d2 Implement backfillUnreadWikis.php in terms of resetNotificationCount()
This causes it to update the notification count cache as well.
Should we perhaps rename it to recacheNotificationCounts.php?

Bug: T132954
Change-Id: I540c4296f4fbadcf2267d77b53f71ee5c2eb8b52
2016-06-08 16:16:37 +02:00
Roan Kattouw 99377e5525 Clean up and fix updateEchoSchemaForSuppression.php
This script was supposed to be run in production in 2013, but that
never happened. It was also never added to update.php.

* Use makeTitleSafe instead of newFromText, for correctness
* Fetch the columns that the update generator needs
* Replace wrapper for private method with closure
* Make the maintenance script logged

Bug: T136427
Bug: T50059
Change-Id: I6c2972120189f035483b5ca49610c008c4ba2c88
2016-06-06 23:56:28 +02:00
Stephane Bisson aa578a44a1 Mark bundled notifications as read
In the current bundling system, only the
bundle base is mark as read. It leaves all
the non-base bundled notifications without
a read_timestamp. They would all appear
as read in the new bundling system.

With this change, all notifications in
a bundled are update with a read_timestamp
when the bundle is read.

The implementation of this change is
somewhat temporary as the new bundling
system brings changes to the models
and controller.

Bug: T136368
Change-Id: I70b71d722d8d62cbdd1adc004293030ef900ac94
2016-06-02 13:48:33 -04:00
jenkins-bot 45013bb676 Merge "Fix notification pager" 2016-06-01 22:23:31 +00:00
Matthew Flaschen f88c90efce Fix notification pager
Needs to use Echo-specific DB

Bug: T136759
Change-Id: Ibdd71a76e751b0b8d115e86cb7eefab79cc56510
2016-06-01 18:04:11 -04:00
jenkins-bot 7c89fc0fa2 Merge "No-JS special page: One-click mark as read" 2016-06-01 18:21:56 +00:00
jenkins-bot 8639c9c30a Merge "Cleanup DiscussionParser" 2016-06-01 00:19:26 +00:00
addshore 6ad1abc171 Cleanup DiscussionParser
Change-Id: Ic37fac50455ac63e5388c2307d8b36cb9249ed1c
2016-05-31 17:01:32 -07:00
jenkins-bot ec34b25758 Merge "Unread pages API" 2016-05-31 18:29:07 +00:00
Stephane Bisson 6564919c28 Don't fetch duplication notifications
Avoid joining on echo_taget_page to prevent fetching
duplicate notifications.

Change-Id: Ibcda67ce2fa387d8be0ffcb405bd0692965dddcb
2016-05-27 21:47:36 -07:00
Matthias Mullie f751e96839 Unread pages API
The query shouldn't be too expensive: it'll use an index to narrow
down the resultset for 1 user. After that, it'll be sorted based on
a grouped by value, but that should fit in memory: it'll never be
on more than 2000 entries, which is the max amount of notifications
per user.

Change-Id: I271ea7f7a6e010284739bfce02c4ec8a077148fc
2016-05-27 17:24:53 -07:00
Matthew Flaschen 188e8d7395 No-JS special page: One-click mark as read
Bug: T136361
Change-Id: I7896dbdf25d2c1624f97777f4c8d0af41b195ef0
Depends-On: Ic31f857c749d62a32cafae68dc3f1cbd86e1e382
2016-05-27 17:23:29 -07:00
Stephane Bisson 1bef12c3e7 Stop outputting $nextContinue in Special:Notifications
Bug: T129176
Change-Id: If0d05cb1df0b2e0f93c7367c0848fbcbb04fea8d
2016-05-27 16:46:20 -07:00
jenkins-bot 95bea57983 Merge "Initial version of Special:Notifications Javascript page" 2016-05-27 21:34:44 +00:00
Moriel Schottlender 9262614ded Initial version of Special:Notifications Javascript page
Bug: T129176
Change-Id: I2f55358c16f78e234ec19154b944a4edebfbe639
2016-05-27 13:42:25 -07:00
matejsuchanek 38adb78619 Use native MediaWiki linking to help pages
There was quite a small link under the main title in Special:Notifications
which pointed to a related help page. Now the OutputPage::addHelpLink()
method is used which moves this link to the upper right corner and allows
configuring this on-wiki (instead of LocalSettings.php or so).

Bug: T101057
Change-Id: Ib4aecee8006b8d71bb3cd86f1d4ebdfee9080870
2016-05-27 20:40:41 +02:00
jenkins-bot 5992e88f6e Merge "Rip general cross-wiki API request helpers out of ApiEchoNotifications" 2016-05-27 00:29:50 +00:00
jenkins-bot 2d3a031b47 Merge "Add diff link to page-linked notification" 2016-05-26 23:33:58 +00:00
Matthias Mullie 6b0081fd78 Rip general cross-wiki API request helpers out of ApiEchoNotifications
They'll come in useful for other APIs as well

Change-Id: I59e508d8c2d33c3868c13e28e4ac40441bc07d4e
2016-05-26 13:51:42 -07:00
Stephane Bisson 52525249e6 Adjust styling for "Mark group as read"
Bug: T134204
Change-Id: Ia0486fa400be7e96ffc4e1ad47f952c17f40042c
2016-05-26 13:30:49 -07:00
jenkins-bot cc9dfff167 Merge "Use Revision::RAW when checking whether the author of a revision mentioned themselves" 2016-05-26 17:09:17 +00:00
jenkins-bot 721391b979 Merge "Track why mentions didn't happen" 2016-05-26 17:09:13 +00:00
jenkins-bot cdbe707f4f Merge "Set doesWrites() for SpecialNotificationsMarkRead" 2016-05-25 19:58:34 +00:00
Aaron Schulz df5ee8ef8e Set doesWrites() for SpecialNotificationsMarkRead
Change-Id: I782e66a468a0d57ab8a5bb3b38c92f334635a3a7
2016-05-25 11:17:07 -07:00
Roan Kattouw efa8846731 Use Revision::RAW when checking whether the author of a revision mentioned themselves
It's probably not realistically possible for a revision to be oversighted
by the time generateMentionEvents() runs, but for consistency
we should be using RAW here.

Change-Id: If73b4abe5fbae5cadb75c5e09137299873f2a764
2016-05-24 15:51:17 -07:00
addshore f51256845c Track why mentions didn't happen
Right now we don't actually know how many times
each of these cases happen so add some basic tracking
so we can make some informed decisions.

Bug: T135719
Change-Id: Id4d519aefe96ecca2e3c51dd1c8128de70d0caac
2016-05-24 15:47:05 -07:00
Stephane Bisson c96bc7ec38 Pagination on no-js Special:Notifications
Bug: T129169
Change-Id: I48aff35352bbda7f8818d456284c5c7adb346bb1
2016-05-23 15:39:43 -07:00
Roan Kattouw 71eacf3fad Add diff link to page-linked notification
Will only show for new instances, because the information
will be unavailable for old ones.

Bug: T135959
Depends-On: I3d894acaf3d85b790e5034c7d9f76bf94672f445
Change-Id: I04620678dd0ebffb3b1a92a9a0587cb7557d77f4
2016-05-23 12:23:30 -07:00
addshore 5b2ad7617c Remove overwritten $notifyTypes array
Change-Id: I8ee6fab3285881f29e9484b1bdd0a52a1509a1e9
2016-05-20 11:43:48 +01:00
Stephane Bisson cb6e6e96cd Build lego message for HTML email footer
Change-Id: Ic750ff3eb4e97c0cd23dd39a998c60860a49cf45
2016-05-19 06:19:38 -04:00
Stephane Bisson 224caaf072 Expand URLs of icon and actions in HTML email formatter
The plain text email formatter already does this.

Bug: T135625
Change-Id: I630b49ef59988744fa0f89af62655f879e34a6fb
2016-05-18 11:23:53 -04:00
jenkins-bot 7d2d4f2c0a Merge "Get rid of email bundling" 2016-05-18 02:23:25 +00:00
Stephane Bisson bb7a15e8be Get rid of email bundling
Bug: T135446
Change-Id: I95dc3d70c82c19d89b7a32be0c36294350d5c30d
2016-05-17 16:24:16 -04:00
jenkins-bot d0f5e168cf Merge "HTML email footer shows raw HTML" 2016-05-17 20:08:06 +00:00
Stephane Bisson 08fdaa0d22 HTML email footer shows raw HTML
Change-Id: I45b8aa2b951c155a3f8c3c7be006604113cbc2ee
2016-05-17 13:00:29 -07:00
Stephane Bisson 46e69972c6 Bring back messages used by old email formatter system
Bug: T135446
Change-Id: I235db93c0f50424da8bc30bcafd717c50a6b0b62
2016-05-17 10:37:39 -04:00
Roan Kattouw 91dfdfcbd0 Attempt to fix unsubstituted message in Echo emails
Bug: T135446
Change-Id: Id5f2e6affc43c79f8b247362e4f501af3bd356f7
2016-05-16 15:43:56 -07:00
jenkins-bot 942f79d55d Merge "Link project labels in xwiki bundle to their Special:Notifications page" 2016-05-16 20:47:32 +00:00
Moriel Schottlender 28feb4bf82 Link project labels in xwiki bundle to their Special:Notifications page
Also, get rid of the feature where we hide the project name when there
is only one project available. The titles are always showing.

Bug: T127419
Change-Id: I1b1285d84b7fb4775d13067e6ae1c50602ed3baf
2016-05-16 13:33:18 -07:00
jenkins-bot 772666b4eb Merge "Follow-up f5e9d4e: log parsing failures and API errors too" 2016-05-16 17:03:56 +00:00
jenkins-bot 397d402a5b Merge "Avoid exceptions when event_extra can't be unserialized" 2016-05-14 00:45:56 +00:00
jenkins-bot 5a2faf26da Merge "HTML email formatter using presentation model" 2016-05-14 00:29:30 +00:00
jenkins-bot ae571b55dd Merge "Handle section-text being null" 2016-05-13 23:57:41 +00:00
jenkins-bot ff780827e2 Merge "Use JSON instead of PHP-serialized for internal cross-wiki API requests" 2016-05-13 23:41:09 +00:00
Roan Kattouw d2f899d9d3 Handle section-text being null
This was causing warnings in production:
Invalid parameter for message "notification-body-edit-user-talk-with-section": a:1:{s:9:"plaintext";N;}

Change-Id: Ibdea5d899caf446a8c7f811416fdabaa3dccccdd
2016-05-13 16:39:59 -07:00
Kunal Mehta 64127cd815 Avoid exceptions when event_extra can't be unserialized
Check for proper unserialization in EchoEvent::loadFromRow(), and return
false if not possible. Callers were updated to check for a false return.

Bug: T73489
Change-Id: I33867aa9bbbc5f0ecfe0d2a9e1b03eb1a937ae83
2016-05-13 16:39:17 -07:00
Roan Kattouw bc641732e5 Use JSON instead of PHP-serialized for internal cross-wiki API requests
Change-Id: I12e211b454366405e10b7a9706d4be12aab2849e
2016-05-13 16:28:30 -07:00
Roan Kattouw 62908b5cf9 Don't reuse CentralAuth tokens for multiple requests
CA tokens are single-use, and the fact that they even worked
for multiple requests was a race condition. Instead of getting
one CA token and using it for all requests, get a fresh token
for each request.

Bug: T135250
Change-Id: Ie1bbdefd3e265d009d0c42ff27da447b8da7f1fd
2016-05-13 16:13:36 -07:00
Roan Kattouw c7bdb879e6 Follow-up f5e9d4e: log parsing failures and API errors too
Change-Id: Ie00994008aab632a9b02d11b840457e91546b12a
2016-05-13 15:52:33 -07:00
jenkins-bot 712109fa5d Merge "Log warning on failure to fetch foreign notifications" 2016-05-13 21:42:20 +00:00
Roan Kattouw 0e2f1a9c18 Add $wgEchoCrossWikiNotifications flag to disable cross-wiki notifications
This is needed because global tables and cache keys will attempt to be used
even for users who don't have the preference enabled.

Bug: T135266
Change-Id: I6208a12d46c8cd0275a232663cd50ac2bd2fed1c
2016-05-13 13:52:54 -07:00
Stephane Bisson f5e9d4e372 Log warning on failure to fetch foreign notifications
Change-Id: I92bc0ea2aebc1992d43dc0cd560137090b4d5857
2016-05-13 16:42:15 -04:00
Roan Kattouw d6c2f1a82c Protect against some errors that apparently happen in production
Committing a live hack that I put in to silence errors and notices.

Bug: T135196
Bug: T135197
Change-Id: Ib1b049686f59d69192b33151eea27bc54519c379
2016-05-12 17:56:16 -07:00
Stephane Bisson 6f6e10084c HTML email formatter using presentation model
Bug: T121067
Change-Id: I77f466f0b507ffa49a9714ddba95bea8db1d8438
2016-05-12 09:29:24 -04:00
Moriel Schottlender 8f5c718a4f Add 'mark section as read' to Special:Notifications
Allow marking notifications as read per 'section' (days) in the
Special:Notifications page.

Bug: T115528
Bug: T134204
Change-Id: I7324a2c693aa92b9327cf8ff98f125293d5fba10
2016-05-11 20:00:24 +00:00
jenkins-bot 4331c30993 Merge "Add mark-as-read button to notifications in Special:Notifications" 2016-05-11 18:42:46 +00:00
jenkins-bot 69967ae13a Merge "Don't cache pages with outdated global notification counts" 2016-05-11 18:08:53 +00:00
Roan Kattouw d2d420a3c4 Don't cache pages with outdated global notification counts
When updating notification counts, we already called User::invalidateCache(),
which bumps the local user's touched timestamp, which is taken into
account by OutputPage when computing the last-modified timestamp of the response.

However, this only works for one wiki, while the changed global count
needs to be displayed on every wiki. To accomplish this, track the
timestamp of the last update in NotifUser, and hook it into
OutputPageCheckLastModified.

Change-Id: I22c88a017f18a28179906049ee423c2d7e81c939
2016-05-11 10:53:13 -07:00
Moriel Schottlender 15a44768f4 Add mark-as-read button to notifications in Special:Notifications
Bug: T115528
Change-Id: I54dba5f86d28a069659d66dede5b7ab9981213aa
2016-05-11 10:41:32 -07:00
Roan Kattouw cd4194bd40 Avoid invalid API response when server-side cross-wiki requests fail
If all server-side cross-wiki requests fail, we'd return an empty API response.
This is invalid, the frontend expects things like list:[] to still be there.

Change-Id: I72fc5a017647ca28abbc061992fa4868ca5737f4
2016-05-09 11:08:00 -07:00
Roan Kattouw ac85f28f3e Use global user ID in global cache keys
We were using the local user ID instead, which is not the
same on every wiki, which caused strange cache staleness
and pollution behavior.

Run sets through a wrapper function (gets were already wrapped)
so we can update the instance cache and deal with uncomputable
cache keys in one place. A global cache key may be uncomputable
if we fail to obtain the user's global user ID (users aren't
supposed to be unattached, but some are).

Also bump the cache version to get rid of polluted cache entries.
Bumping this version number was probably a good idea anyway,
with all the recent changes.

Bug: T134533
Change-Id: I1c4f0c2f2eded480c80f8ec7a49a04feb7c5ecfb
2016-05-05 17:21:32 -07:00
Roan Kattouw e57dbfc86b Follow-up 73ec3a331: fix fatal when no cross-wiki results are found
If we don't initialize $results, getForeignNotifications() will return
null, and this will cause a fatal when trying to += it into an array.

Change-Id: Ibb868cbf0b52ff2de41c5be82c9605801e51ffae
2016-05-05 12:58:28 -07:00
Kunal Mehta b6f742bc46 Add plain text email formatter
Formatters based on presentation models for
individual event emails and digest (daily, weekly)
plain text emails.

Bug: T121067
Change-Id: I4eceaf521315adab7429a8a73ffca70ebcddab86
2016-05-04 13:35:37 -04:00