nmlorg / metabot

Modularized, multi-account bot.
https://metabot.readthedocs.io/
5 stars 0 forks source link

Daily announcement UI improvements #74

Open nmlorg opened 5 years ago

nmlorg commented 5 years ago

For groups that don't use the bot's daily announcements, it's very common for their manual announcements to include only one event at a time, and include a large write-up about it, sometimes additionally including a picture (either some topical clipart or an actual flier).

It might be possible to have the daily announcement format changed to reference the next upcoming event primarily, and use its description as the write-up.

Probably only one event per announcement should be expanded, but all events that would currently be shown should still be included.

One approach would be to pick an interval (say, 5-6 days), then pick one event that starts during that interval (either arbitrarily—like the first/last/longest/shortest—or at random), and render it in long form at the stop (in place of the preamble), then the rest of the list (with or without the selected event (in its natural position)) beneath it.

Current:

There are a few events coming up:

*Alpha Summary*
Alpha Time @ Alpha Location
*Bravo Summary*
Bravo Time @ Bravo Location
*Charlie Summary*
Charlie Time @ Charlie Location

possibility (assuming Alpha is in 4.5 days, Bravo is happening in 5.5 days, Charlie is in 6.5 days):

*Bravo Summary*
This is the description for Bravo. Come join us, it'll be fun!

This is a second paragraph in the description. Should I be folded into the first line?

Can't wait to see you!
Bravo Time @ Bravo Location

Also keep in mind these other events:

*Alpha Summary*
Alpha Time @ Alpha Location
*Charlie Summary*
Charlie Time @ Charlie Location

Regardless of if/how this main change is made, it might be useful to restore the behavior of adding a line to the very end saying:

            "there's an event coming up:\n\n%s\n\nClick the date for more details or to set a "
            'reminder, or the location to pop open a map!') % events[0]
            " events coming up:\n\n%s\n\nClick an event's date for more details or to set "
            'reminders, or its location to pop open a map!') % '\n'.join(events)

For images, the announcement could be changed from a sendMessage to a sendPhoto, though the text of the message will become a "caption" instead—and will be limited to 1024 characters. Theoretically I can get manually set event images from Google Calendar API in the form of attachments, though I'll have to experiment further, and even if possible it might be the case that nobody is actually attaching relevant images to their events.

nmlorg commented 5 years ago

New announcement settings:

Showcasing an event is just formatting it with full=True. However, selection for showcasing might be complicated.

If one event is happening before the next scheduled announcement (typically, if it is "today" in the local time zone, but events that begin after midnight still count, as do events that begin in more than 24 hours when dow would prevent another announcement within 24 hours of its start).

If two start within that window, we have three choices:

  1. Pick the first one to showcase.
  2. Showcase both (all).
  3. Use day-of-year-based round robin among just those two (or however many) events.

If no events begin before the next announcement, we'll pick one from the upcoming set based on the day of the year (as is used to round robin preambles).

Ideally, we might want to try to only showcase an event twice per week. (Twice per /events period?) This might suggest using something like, if the period is set to 6 days (the default), and there is only one event coming up, it'll be showcased on the first day, then no showcases until the day of. If there are two events coming up, the first one will be showcased on the first day, the second will be showcased on the third day. If there events, one will be showcased every other day; etc.

Since the number of events in the current period can change every day as the period's begin/end advances (dropping past events and adding further-away upcoming ones), the geometry of the showcase schedule could constantly change too, leading to one event possibly ending up being showcased every day for a week. This might further suggest we should actually record when an event was last showcased (per-bot and per-group, rather than in the calendar itself). The geometry of the showcase schedule could therefore change every day without risking repeating the same event (or otherwise showing them out of order). This could even be used to showcase events outside the defined /events period, for example showcasing a one-off event that's months away (but might need substantial lead time to plan for—because of travel, purchasing tickets, signing up to volunteer, etc.); however, right now one-off events and instances of repeating events aren't differentiated in the calendar, so we'd need to be careful about not just iterating through the next 50 years worth of repeated event instances (either exposing repeatedness through the calendar or doing some kind of fuzzy duplicate elision while searching for something to showcase).

An alternative to the self-configuring, probablistic approach would be to add a third new option, showcasedow (possibly using it in place of hideshowcase, though some groups might want to control if/when future events are showcased independently from if today's events are showcased) to define specific days of the week to showcase on. The selection algorithm could be as simple as scanning through the entire calendar (through the next 50 years; or maybe arbitrarily cut off at one year, or X * (/events period), etc.) for the first event summary it has never showcased or, if they're all listed, the one closest to the head of its list. The summary will be removed from the list (if present) and appended in last place, then the event will be showcased.

nmlorg commented 5 years ago

For images, the announcement could be changed from a sendMessage to a sendPhoto, though the text of the message will become a "caption" instead—and will be limited to 1024 characters. Theoretically I can get manually set event images from Google Calendar API in the form of attachments, though I'll have to experiment further, and even if possible it might be the case that nobody is actually attaching relevant images to their events.

So far all I've actually come up with are "flair" banners provided (and automatically used) by Google. I haven't found any official documentation so far, but several lists include:

Not a list, but official acknowledgment:

  A complete-looking list can be retrieved from the Android Google Calendar app somewhat easily (though it's stored as a set of protobufs, and I couldn't find a .proto definition so I hacked a quick parser together):

  1. Find a Google Calendar .apk. There's again no officially supported process, but we're just looking for data, so using a third-party service like https://www.apkmirror.com/apk/google-inc/calendar/ should be fine.
  2. .apk files are just .zip files, so unzip it into a temporary directory:
    ~$ mkdir caltmp
    ~$ cd caltmp
    ~/caltmp$ unzip ../com.google.android.calendar_6.0.46-264203736-release-2016285840_minAPI21\(nodpi\)_apkmirror.com.apk 
     extracting: META-INF/services/com.fasterxml.jackson.core.JsonFactory  
     extracting: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader  
     extracting: build-data.properties   
      ...
  3. Extract the information from assets/flairs/flairdata_en.pb:
    ~/caltmp$ strings assets/flairs/flairdata_en.pb 
    genericnewyear
    New Year
    new year's
        new years
    babyshower
    babyshower
        maternity
    baby shower
    running
      ...

    (If I go ahead with this, I'll check my hacky parser in too.)

The flair is defined as an identifier followed by one or more phrases, which presumably are checked along the lines of converting spaces to \W+ and checking for matches like new years/\Wnew\W+years\W/i ("new years", "new  years", "new: years", and "new. years" all match new years, but "newx years", "xnew years", etc. don't; and curiously "gay lesbian" does match gay lesbian, but "gay & lesbian" does not actually match gay & lesbian).

The images are hosted at https://ssl.gstatic.com/calendar/images/eventillustrations/v1/img_IDENTIFIER_1x.jpg and _2x.jpg, and look like: genericnewyear pride