Coder Social home page Coder Social logo

edgeryders / dynalist_companion Goto Github PK

View Code? Open in Web Editor NEW
13.0 13.0 2.0 184 KB

Unofficial utilities for the dynalist.io list management application. Provides: e-mail notifications (and that's it right now).

License: GNU Affero General Public License v3.0

Python 60.05% CSS 5.47% HTML 34.48%

dynalist_companion's People

Contributors

anuzement avatar debendraoli avatar tanius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

dynalist_companion's Issues

Make the sync interval configurable via conf.json

The current interval for checking the Dynalist file for new changes is 10 minutes. To allow to adapt this to the requirements of an installation, this should be transformed into a parameter in conf.json with a default value of 10 minutes. (Or maybe better, 30 minutes. Better we keep defaults very easy on the servers.)

This way, people can adapt the setting to prevent unnecessary load on the Dynalist API.

Fix the crash when a tag does not conform to a username

There is an issue in the current version in notify/helper.py line 32: if no username is found that conforms to the currently processed tag, the software exists with the exception "sqlalchemy.orm.exc.NoResultFound: No row was found for one()". A stacktrace is provided below.

This can happen for example for a #username tag of a user who did not yet register a Dynalist Companion account, or for a misspelled #username tag, or for one of the tags not related to usernames that we use: #discarded, #important and so on.


Traceback (most recent call last):
  File "notify.py", line 1, in <module> import
      notify
  File "…/dynalist_companion/notify/__init__.py", line 29, in <module>
      helper.parse(save[0], save[1])
  File "…/dynalist_companion/notify/helper.py", line 61, in parse
      email = get_email(assign)
  File "…/dynalist_companion/notify/helper.py", line 32, in get_email
      req = Users.query.filter_by(username=username).one()
  File "…/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2953, in one
      raise orm_exc.NoResultFound("No row was found for one()")
sqlalchemy.orm.exc.NoResultFound: No row was found for one()

Fix the newline characters in the notification e-mails

Currently, notification e-mails are rendered like this:

Hi username,

You have been assigned a new task:

"Test task for #username
"
https://dynalist.io/d/123abc#z=456def
Good luck :)

So there's one newline character too much after the task quote, causing the " to be in the line below. And one newline character missing after the task's URL, which should be right below the task but vertically separated from the complimentary greeting formula as is usual practice. So it should look like this:

Hi username,

You have been assigned a new task:

"Test task for #username"
https://dynalist.io/d/123abc#z=456def

Good luck :)

Remove the Dynalist API secret token from the signup and settings forms

These form fields seem to be remnants of a previous version and can safely be removed.

The current version seems to only use the Dynalist API secret token configured in conf.json. That's the right solution, as it is not safe to force users to enter their own Dynalist API secret tokens into the software – it would give the software read and write access to all their personal Dynalist files 😲

Provide a button to check for changes immediately

When testing the application and also when wanting to gather information about the most recent changes to the monitored Dynalist file, a sync button on the "Home" screen of the software would help a lot.

This way, there is no need to wait 10 minutes for the next round of notifications (or whatever time is configured for that in an installation). Also, the software will stay usable even if the permanent process or cron job to generate notifications automatically stopped to work orderly.

Provide a mindmap-style user interface to Dynalist lists

Some users are more visually inclined and want to see their lists as mindmaps. Dynalist has that in their roadmap somewhere, but it's still some time off. We're not so sure how, but we can add this feature ourselves. Options include:

  1. Freemind integration. Freemind is a mature cross-platform mindmapping software. Copy & paste from Freemind almost works, as both Freemind and Dynalist use text with two-space indentation to indicate item levels. However, some stuff gets lost or formatted in a weird way, so we'd have to fix that. Also, syncing between Freemind editing and Dynalist editing would have to be smooth. Freemind has a "remote editing" mode that could be used for that. Ideally in such a way that changes are auto-saved to the Freemind server when exiting node editing mode and from there to Dynalist. This would provide the same granularity of concurrent editing as Dynalist itself, avoiding most race conditions when editing the same node. The problem when everything is in Dynalist is, of course, that most graphical information added to Freemind mindmaps (such as icons, node colors etc.) cannot be saved to Dynalist and would be lost …

  2. Web based mindmaps. In addition or in alternative to Freemind integration, we could have add a web based, open source mindmap editor to this software, allowing to edit some small sub-parts as mindmaps with syncing to Dynalist.

To be discussed!

Polish the code formatting and documentation

This is of course a task that never ends, but this issue refers to simply doing one "cleanup" campaign in the existing source code.

Among others, things to clean up are:

  • commented parts of prior implementations that are no longer needed
  • the OPML syntax example at the end of notify.py; it can be kept somewhere, but should then go into its own file or into the README.md documentation file
  • parts and methods that are not completely obvious should get a code comment explaining it; it's good to have 10% or more of the lines being comments

Rename the repo to dynalist_notify

The difference to the current name is to use an underscore _ instead of a dash -.

Reason: dashes are not permitted in regular Python package names, but underscores are. A normal git clone will place the software into a directory carrying the repo name. While that name can be changed at will without issues, it will be good if that directory name is immediately a proper Python package name because then the directory containing the source code is already a proper Python package. And that is needed when writing a .wsgi file in order to install the software using Apace mod_wsgi (see here).

Best solution will be to rename the repository on Github first and then to adapt the name also in .git/config on the local computer accordingly.

Move the database.db file one directory up and access it with an absolute path

Currently, the location of the SQLite3 database is determined by the following entry in the config.py file:

SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db'

This looks for the database in the app's source code directory, i.e. ./app/. In contrast, all other dynamically generated files such as old.txt, new.txt and events.log are located one directory level above that. Since it makes sense to not mix code and data and to keep user-generated data in one place, the database file should also be moved to that directory.

This will require accessing it in a different way. Proposal: access it with an absolute path in exactly the same way as implemented in #47.

Add a backup function for Dynalist files

The backup function should be triggered by cron, just like the function to check for new notifications. To not create any avoidable load for the Dynalist server, the backup job should simply save the data fetched during the regular notifications job.

The Dynalist API allows access to the list data in JSON only, not in OPML as created by the current manual backup / file download function. This is ok though – we'll create the backup in JSON format then. Later (at latest when there is a need to restore a backup …) we'll have to write our own JSON to OPML converter.

By adding this feature here and no longer in its own script, we bundle all our Dynalist extensions into one software. So only one thing to install on our server :-)

Add an explanatory text to the "User tag" field on the signup form

A small text below the form field (or in another useful location) should say something like:

The #tag and @tag by which you are assigned to items and mentioned in Dynalist, according to the conventions used in your team. Enter without the # or @ character.

Also on this occasion, the "User tag" field could be renamed to "Your tag". Sounds more direct and friendly.

Fix the syntax error in notify.py

Currently, trying to start the notify.py script with python notify.py will result in the following error message:

File "notify.py", line 102
self.sendmail('[Dynalist Notification New Task]', email, f'Hi {res1.group(1)},\nYou have been assigned with new task.\n\n{line}\nGood luck.:)')
                                                                                                                                             ^
SyntaxError: invalid syntax

Should be fixed :) See how it pinpoints the error location with the ^ in the line below it.

Document how to install the software on a server so that changes to files take immediate effect

Right now, after changing and saving a file, the version executed on next page load is still the previous one due to Python's opcode caching.

There are ways around this. Should be documented for mod_wsgi based installations in README.md, and deployed on the server.

Currently, as a workaround you can simply restart the whole webserver after changing a Python file:

service apache2 restart

Allow monitoring multiple Dynalist files

Instead of supplying the file ID of one Dynalist file to monitor for changes, the software should simply monitor all files that are in the file list of the Dynalist account for which the Dynalist API secret token is supplied to the software.

Right now, monitoring only one file is fine though. This is for later.

Document the DEBUG configuration parameter

I noticed there is a debug mode somehow:

In config.py there is a parameter DEBUG, which is False by default. When setting it to True and running python run.py (means, using its internal webserver), the output changes to include:

* Debug mode: on
[…]
* Debugger is active!
* Debugger PIN: 312-289-679

But not sure how to proceed from there. Would be great to have that documented in the README. Not urgent of course.

Provide users with a list of others who will be notified

Automatic notification e-mails make only sense when a user can trust that a notification e-mail will be sent when creating a new task. For that, the Dynalist Companion software should show a list or table of all #tags that can be used, and what notifications they will trigger.

The current homepage of the Dynalist Companion software seems a good place for this.

Fix that notify.py sends notifications much too late

From a quick check it seems that notify.py is either receiving outdated content from Dynalist, or in some way writes old / outdated content to the new.txt file. This way, no changes are detected, and no notifications are sent.

Tested on our installation at tasks.edgeryders.eu as follows:

  1. Create a test task and assign it to yourself.

  2. Run the notify.py script as usually done by the cron job:

    sudo -H -u web15 bash -c "source /var/www/tasks.edgeryders.eu/web/venv/bin/activate && cd /var/www/tasks.edgeryders.eu/web/dynalist_companion && python notify.py"
    
  3. Check if you get a notification e-mail, and if not if the test task made it into the old.txt file on the server. (Both is not the case currently.)

The expected notification arrived finally, caused by the cron job run on 2018-10-01 00:00:22,129 CET. We have to test if this is a pattern, by leaving test tasks in place for more than 24 hours. If it now happens all the time that notifications arrive several hours later, it could be due to a change in the Dynalist API (so that document versions are made accessible by API only every several hours). If so, this is probably a bug and not a change to lower the server load, since Dynalist still allows access to the v1/doc/read API at a rate of 50 times per minute (see) and that would be the first thing to change if they want to reduce the server load.

Clean up the code control flow in notify.py

It is not intuitively understandable how the source code in notify.py works:

In Notifier#__init__, the software fetches a version of the monitored Dynalist file (so far so good).

Then, in Notifier#__init__ in line 52 it calles Notifier#save. The naming of that method and / or the source code structure is not adequate here, because the file Dynalist file content has already been saved (line 50) and it's not clear anyway what saving a Notifier singleton object would do?

Also, that "save" method will not just save two more files but also parse the files and send notification e-mails based on them. That's also not clear when reading the method name "save".

On a more general note, using a singleton object like here in notify.py is a kind of "pretty shell" for procedural programming, which still happens in Notifier#__init__. It only looks like object-oriented programming :-) However, it is ok to have some procedural programming elements in a simple script like this.

So, proposal: pull up what Notifier#__init__ does into the top-level of the notify.py script. Then define the class Notifier (with a different name) as something that can be used to create useful objects in this context rather than being a collection of procedures. For example, these objects might each represent one timestamped file from Dynalist with the corresponding JSON content, and would provide methods to compare themselves to a different object of the same class and to create notifications for the changes detected during that comparison. These notifications might be implemented using another class, with functions that can provide the notification in various ways (as part of an e-mail, as a push notification, maybe later others).

Make the settings form functional

Currently, the /settings form does not yet work properly. Not a big deal right now, as all relevant settings have been made on the signup form. But it would be better if the user is also able to see and change them here, of course.

All the settings made on the signup form should be possible to see and change here.

Also, the "Save" function of the form has to be fixed. Currently when pressing the "Save" button, the following error message will appear (and no form values will be saved):

Method Not Allowed
The method is not allowed for the requested URL.

In addition, right now the settings form (via the /settings URL path) is also visible to logged-out users. This will probably fix itself once the form has the right handler in the application.

Require one Dynalist Pro account

While not technically a requirement, it seems a nice gesture to support Dynalist. Because then every installation of this software that is managed by a non-coder will utilize one Dynalist Pro account and support Dynalist this way. When managed by a coder, he or she can of course easily remove this requirement. They'll still have a moment to think if they want to do that, or just keep it as it is and also support Dynalist, given they are a heavy Dynalist user going as far as installing our third-party companion app.

Our documentation should also be updated to say something to this effect: "This software needs its own Dynalist account by which it can access the document you want to manage with it (don't use a personal account or it can also access all your personal Dynalist documents). This has to be a Pro account, but you can remove this requirement quite simply from the code. However, we hope you take a moment and consider that paying for the products you love is the best way to support their future development, even if you don't have to pay because they are nice. By installing this software you prove to be a big Dynalist fan, which probably means you like it enough to support it with some hard-earned cash."

This "feature" should be technically enforced as a requirement if possible, by checking the type of Dynalist account via the API in some way (maybe by testing if the API supports some Pro-only feature).

Provide a way to sync to open source calendar software

For project management, calendar integration is a must. Indirectly, this also provides a calendar view on all time-associated data in Dynalist (so there would be no need to add a calendar view directly for just Dynalist data itself).

Currently, a Dynalist Pro account includes a feature to have items with dates appear in Google Calendar. However, not everyone likes Google Calendar, or Google. So we'd like to add a way to sync Dynalist items to other calendar systems, ideally relying on an open standard like iCalendar.

The synchronization should include inviting the task assignee(s) to the calendar item. For that, the software has to know which account ID of the calendar software belongs to which #username task assignment tag in Dynalist. This feature enables the user to better interact with the calendar item. For example, the calendar software can send reminders to the user when the calendar item approaches.

Implementing this as proposed also solves three other issues that currently exist with Dynalist and calendar synchronization:

  • It makes calendar synchronization possible without needing a Dynalist Pro account.

  • It fixes that Dynalist Pro's feature of syncing to Google Calendar does not invite the Google Calendar users according to the task assignment in Dynalist (obviously, as task assignment is just our own convention).

  • It fixes that Dynalist Pro's feature of syncing to Google Calendar only syncs activity by the Dynalist Pro user instead of the whole content of the to-be-synced document (details).

Do not notify about whitespace diffs

Due to a quirk in Dynalist, it often happens that a change is made to a list item that consists solely of appending a space character " ": the user positions the cursor at the end of a line and presses "Return" to create a new list item. However if the line ends with a tag, the "Return" key confirms inserting that same tag (as proposed in the autocomplete popup). Inserting means adding a space character after that tag so that the autocomplete popup disappears. Then, the user will press "Return" again to get her new list item. The result is an unintended whitespace change to an existing list item.

With the current code, unimportant changes like these also trigger notifications. By comparing lines and detecting what changed between them, it should be possible to avoid notifications in these cases. To implement that cleanly, it will be necessary to have IDs for list items, though, to detect what are changes to an existing item and what is a deletion of a list item and the creation of a (potentially similar) list item in its place. IDs are hopefully / probably available in the JSON provided by the Dynalist API, but to store them a different format than the current text format should be chosen (OPML if possible – see also #37 and #30 for this).

Note that when transitioning to OPML, detecting new list items from new IDs is the only possible way, as items will no longer be sorted by creation date as (seemingly) in the current list output, making a side-by-side diff comparison impossible.

Prioritize "new task" notifications

When a Dynalist item contains both a mention @username and a task assignment #username, then a notification for the @mention is sent out and none for the task assignment.

Since task assignments are the more relevant events, it should be the other way around: only send a notification for the task assignment.

Switch the notification system to using cron

Currently, notify.py is meant to run continuously. This is possible and usually done for server software ("daemon mode"). However, it is more difficult to control since we would need mechanisms that (1) restart the process in the case of errors or crashes, for example using Monit and (2) start the process automatically after a reboot of the server.

And it is not really necessary to keep the process running, since it does not listen to asynchronous requests that can come in at any time like a usual server. It has to take action regularly, in a predictable way.

It is simpler to use cron for such a case. For that, modify notify.py to be a command line tool that, when started as python3 notify.py will look for changes in the document and process notifications once, then exiting the process.

After that is done, @tanius will modify the installation on the server, now using a crontab entry.

Make the database file location configurable in conf.json

Currently, the database file is hardcoded as users.db in the source code.

Better, both the pathname and filename should be configurable by having a configuration variable pointing to the file (using an absolute path) in conf.json.

An absolute path is needed because some ways to install the software (such as this using Apache mod_wsgi) redefine what is the "current working directory", which means that a relative path such as just users.db will not find the right file anymore.

Open files with absolute paths

Currently, here in models.py, function Deadlines(), a file is opened like this:

  read_file = open('old.txt', 'r', encoding='utf-8').read()

This (opening files with a path relative to the current working directory) works in notify/*.py because the cron script notify.py is started after properly defining the current working directory of the python interpreter. It does not work here however because models.py is included when visiting the web interface, and it is not clear (or rather, depends on the installation environment) what the "working directory" will be in that case.

So currently, the line has been temporarily replaced with an absolute path to make the script functional on our server:

read_file = open('/var/www/…/dynalist_companion/old.txt', 'r', encoding='utf-8').read()

Proposal: Use absolute paths everywhere to access files, to solve this issue once and for all (and also to make the software more understandable, because it's not intuitively clear "relative to what" these paths are evaluated except in small command line scripts). By taking the base path of the directory containing these files out of the configuration file, it also solves the issue of having to cd into the working directory before being able to execute the cron job (see instructions cd /path/to/your/project/dynalist_companion/ && python notify.py in the README).

To solve this, the base directory for all these file paths should be contained in the config.py file. That base path would then be used when opening any file, by combining it with the filename into an absolute path.

Create notifications when monitored Dynalist searches change

Unlike the simple notifications for task assignments and @mentions, this could be a really powerful feature. However, it can also easily become complex so that nearly nobody uses it …

The basic idea is to let users monitor changes in the results of searches that can use all the usual Dynalist search operators. Just that filtering the document according to these searched would be done in our own software to not put unnecessary load on the Dynalist server through lots of API based searches.

The user would be able to define monitored search expressions in the settings of this software, and give a name for each expression. This system can also be used for all the notifications the software creates right now and in the near future – by means of predefined search expressions that are created when a user signs up, but can be edited and adapted lateron.

A list of monitored search expressions in a user's settings might then look as follows, starting from the usual ones for task assignments and mentions and then showcasing what a user could achieve by adding some custom ones after that:

  • task assignment: #matthias
  • mention: @matthias
  • everyone's important tasks: #important
  • own open tasks with upcoming deadline (due in the next week or overdue): #matthias until:7d -is:completed
  • own due and overdue tasks: #matthias until:now -is:completed

In addition to the usual Dynalist searcch operators, we'd have to define pseudo operators that allow to search within a certain document and to further restrict the search to below a certain item in a document. This is possible in Dynalist as well, since the search by default works within the context of the current file and zoomed item, as represented in the URL.

Provide a dry-run mode for notiy.py

When testing the notify.py script, esp. to find error conditions where it would send out too many notification e-mails, it would be very helpful to have a "dry run" mode of that script. Means, the script will tell on the console what e-mails it would send, but send nothing.

This would be activated with a command-line option --dry-run.

Fix that get_email() fails for some usernames

Refers to this function.

From the cron log, it appears that the script could not determine an e-mail address corresponding to username anique.yael, even though we have such a record in the users table.

The only difference to cases where this works seems to be the special character . in the username?

However, maybe this issue was just a timing coincidence. So it has to be tested more thoroughly.

Implement the rendering of the "Home" screen

It seems that content rendering for this screen has been prepared, but is not finished yet.

The screen should basically consist of a list of notifications, with the newest on top and using the same notification texts as in the e-mails.

The extended notification page in Discourse is a good inspiration how this could look like. It is available at https://edgeryders.eu/u/{username}/notifications, for example here for @anuzement.

The home screen does (at first) not require a mechanism to mark individual notifications as "read".

Fix duplicate notifications

Please re-apply the changes I made in 9eae71b.

They have been overwritten in recent commit, but I think that's by mistake as it introduces an issue of sending lots of notifications to all kinds of users, not just those mentioned in the current task. Effectively, everyone is notified about the currently processed item who got mentioned or assigned in any item the script processed before the current one.

(@anuzement maybe you have an issue with your git development process that caused this change to be lost? git forces you to merge upstream ("online") changes before you can commit yours. You should do that carefully if there is a merge conflict, which means that the software can't mix the changes together and you have to do it manually.)

Implement a changing favicon to indicate new notifications

For this, a webpage that can show the list of the actual notifications to the user is required. Whenever it changes, the favicon (the small icon in the page's browser tab) will be changed to include a red dot or other hint that the tab needs attention. When the user read through the new notifications, the favicon would be reset to one that does not visually demand attention.

This technique is used by several webpages and is a simple replacement for the more sophisticated "browser push notifications". Because instead of accepting push notifications, it is enough if the webpage reloads itself periodically, for example once every 5 minutes.

Implement e-mail notifications

That's by far the most important type of notifications. Browser based push notifications can wait, in comparison. That's good because e-mail notifications are simpler to implement than browser based push notifications.

Fix that comparisons to detect changes are done the wrong way around

It seems that currently, comparisons are done this way:

  • new content is fetched from Dynalist, saved somewhere and treated as the original version (which is wrong, obviously)
  • the old Dynalist content available from prior runs of the software in dynalist-a.txt is treated as the new version (also wrong, obviously, as this is the original version)

The comparison is then done "original to new version". In effect, notifications are created when manually adding something to the end of dynalist-a.txt before running notify.py. But not, as they should, when adding items inside Dynalist and then running notify.py. This is also the test proving that this issue exists.

Provide a LICENSE file

I'd propose we license this software under AGPL – it's open source and forces people to contribute their modifications back in all cases.

Use the Github license chooser to make this change. This way, the license will also appear in the overview information about the project as generated by Github.

Let notify.py tell what it does in console messages

The notify.py script is called via a cron job or manually in a console. To be able to notice future bugs etc. in both cases it would be helpful if the script would tell what it does using informational messages on stdout and error messages on stderr.

Then, we can track the success of the cron jobs (incl. e-mail sending and where that might fail), from the logs created by these cron jobs. The same can be used for bug hunting when testing the script manually, seeing its output on the console.

Python provides nice logging features that should be used for this.

INFO level messages should be created for all key events: downloading the data from Dynalist, finding a new item for which a notification has to be created, sending the notification e-mail.

Dynamically create Gantt charts from tasks in monitored Dynalist files

As discussed in the "Extending Dynalist" topic, another tool that would make Dynalist useful for task and project management would be Gantt charts.

Originally, we proposed there to generate these diagrams with scripts and publishing them every now and then as content in a CMS system or similar (in our case, as topics in Discourse). However, it seems much better to generate these diagrams frequently and to present them in an interactive fashion. For that, a custom software like this one is ideal.

Technically, we would have to introduce conventions for Dynalist usage to express dependencies between tasks, such as #depends {dynalist-task-url} which renders nicely into linked tasks in Dynalist. If necessary, also a convention for the typical constraints "earliest start date", "latest start date", earliest end date" and "latest end date" syntax has to be defined. (Using the existing !(yyyy-mm-dd) date syntax together with tags like #earliest-start seems to make the most sense, as it allows to enter all dates with the Dynalist date chooser widget. There is no issue having multiple such dates in one item.)

Note that there are good open source JavaScript based solutions to present Gantt charts interactively, and also interesting solutions to define Gantt charts in a Markdown-like language. (Ask @tanius for details of his research.)

But all this is for later :)

Fix the detection of Dynalist tags

Currently, @mentions and #name tags for task assignment are detected here with a regex \s@([a-z]{3,15}) and \s#([a-z]{3,15}), respectively.

However, some usernames on edgeryders.eu and thus tag names in our Dynalist documents contains special characters, for example: #anique.yael. It's a valid tag in Dynalist, as can be seen from the gray background formatting for the whole thing (not stopping before the dot) when entering it in Dynalist. Likewise, the restriction to 3-15 characters in length is arbitrary.

The clean solution here will be to detect all tags that are valid in Dynalist. For that, find out first what special characters can be contained in Dynalist tags, and adapt the regex accordingly. We should not try to apply any stricter rules on "what is a tag" than Dynalist, as others will use our software without these same conventions (that might come from Discourse usernames in our case, but others won't have Discourse).

(Then, as it is already happening, the application will try to look up an associated e-mail for each tag appearance, and send an e-mail for those where it succeeds. No changes needed in that part.)

Make the server port configurable via conf.json

Currently, the port on which the software can be accessed when running in the development environment is hardcoded as 8080 here.

However, this port might be in use on some systems. So it is better to let users choose it via a configuration parameter in conf.json. The value 8080 can be kept as a good default, of course.

Rename the repository (again!), to dynalist_companion

I think we should rename things again :) Because we'll also add a backup function here, and it appears we will add other functionality in the future (Gantt charts are already discussed in #21, also we are pondering a sync functionality with mindmapping software, specifically Freemind).

Naming proposals are being accepted. My first idea would be "Dynalist Companion" for the software (to be updated in the documentation), and as a repository name "dynalist_companion".

Implement a mechanism that prevents public signup

Right now, "everyone" from the Internet can sign up. Of course spam users will use that once they find out 😆 Also, everyone who signs up can get content snippets from an access protected Dynalist document, as they are e-mailed notifications with new items containing the tag they subscribed to (which they could also set to #important or a similar educated guess). So it's important to prevent the "general public" from signing up.

The right solution for this still has to be discussed (talk to @tanius). Options include:

  1. A form field for a "shared secret" in the signup form, in addition to the password. The field would have an explanation with a link pointing to a specific Dynalist list item in the monitored Dynalist file. This way, the link and the shared secret in that list item is only accessible to users with access to the Dynalist file – and only these users can sign up successfully. This is quite simple and elegant, but it is not clear yet how this mechanism could work when starting to monitor multiple files for changes.

  2. Requiring the signup e-mail address to appear among the e-mail addresses to which the monitored Dynalist file is shared. However, this reduces the user's flexibility compared with the current solution where the user can choose different e-mail addresses for the Dynalist and Dynalist Notify accounts. And again, it is not clear yet how this mechanism could work when starting to monitor multiple files for changes. Also, the e-mail addresses would have to be confirmed by letting the users click on a confirmation link.

Integrate a group decision making feature

For some uses of Dynalist in a group setting (for example for a commune of the type we are creating in Edgeryders in Kathmandu and Brussels), integrating a way how the group can decide about which tasks to do and in which order will be really helpful. However, this is only an idea so far, for later.

There are already tools for this, such as Loomio. But we'd like a simpler tool, and one that does not need "yet another platform".

One idea how it could look like follows: Dynalist task lists could be structured with a "project → section → tasks" hierarchy. Sections include "Done", "Current", "Undecided". People vote by adding tags to the notes section of a task in the "Undecided" section, for example: #matthias-votes-no, #matthias-votes-yes and #matthias-votes-nothing to abstain. When this Dynalist companion software detects a qualified majority, it marks and moves the task: either #decided-yes and moving it to the end of the "Current" section, or #decided-no and #discarded and moving it to the end of the "Done" section. People can then move it around according to when they plan to do it.

Send only one e-mail per user in notify.py

If one run of the notify.py script detects that a user should get multiple notifications, these should all be aggregated into one e-mail. No need for multiple ones, they would all arrive at the same time anyway.

This solution is less of a strain on user attention, and it also ameliorates issues where the script erroneously sends too many notifications (as in, hundreds). Currently, users have to deal with a deluge of e-mails in such cases rather than one per cron run (currently 20 minutes) with the new solution. Also, e-mail deluges can result in penalizing for the sending server due to anti-spam measures, so such issues should be avoided.

Replace the Edgeryders branding with application branding

We want to make this an independent software, nothing that is tightly coupled to Edgeryders itself. Only that will make it simple for other users to not just download but also productively use the software (without having to adapt lots of things first).

The branding to replace:

  • "Edgeryders" lettering in the top left corner of the main screen, to be replaced with "Dynalist Notify"
  • Edgeryders logo on the login and signup pages, to be replaced with a to-be-designed application logo

Right now, the Edgeryders logo refers to an image hosted on another domain, namely to https://edgeryders.eu/images/logo-small.png. While that is technically possible, it's not "clean": when creating a software, always try to make it as independent from outward changes as possible. Otherwise it can break at any time during use when something outside of ones own control breaks or simply changes.

The new application logo should be created in SVG format using Inkscape, and then exported to PNG in a suitable size. Both the SVG and PNG formats should be included in the repository. That allows others to adapt / change the file most easily, as the editing software (Inkscape) is also open source.

Implement browser push notifications

There will be more important features than this, and this feature could be quite complex to implement. So better to be done in a "version 2.0".

For a detailed description of how push notifications work and how to implement it using open source libraries, see topic "Extending Dynalist" in chapter "2.2. Browser push notifications". We should not use a commercial / third party web service to send these push notifications, as that is an annoyance when others want to install this software on their own server.

Allow sending via any SMTP account, not just via GMail

Currently, the config file conf.json asks for a GMail address and the associated password, and the source code has the GMail e-mail server hardcoded (here).

It will be better to not just allow one company's e-mail server, but any SMTP server for outgoing e-mail. (After all, the Internet is open infrastructure, and open source enthusiasts do not like being in a walled garden such as Google's … .)

This is a relatively simple change:

  1. Make the SMTP server (currently smtp.gmail.com) configurable via conf.json.

  2. Make the SMTP server post (currently 587) configurable via conf.json.

  3. Create a new configuration parameter smtp_login in conf.json and use it here. Because the login name is not in all cases identical to the e-mail address.

  4. Rename the existing configuration parameter in conf.json and the related content in source code and README.md to not mention GMail.

Include direct links to the Dynalist tasks in notifications

It will be really helpful if the notification e-mail includes a direct link to the list item that triggered it. Can be a URL in a pure-text e-mail like now – no need to transition to HTML e-mails for that.

This will be a bit difficult to implement, as it may need transitioning the file format how Dynalist documents are saved to something like OPML (which will be useful for the planned backup feature as well). Because the OPML format may be able to hold links to the individual dynalist list items (or maybe not; to be checked before).

As a stopgap measure / first step, a link to the Dynalist document should be included.

Implement notifications for task reassignments, deadline changes and upcoming deadlines

These are further events where it is useful to generate notifications for users of this software. As discussed in the "Extending Dynalist" topic in chapter 2, these cases mean the following:

  • Task reassignment. "Your task {name and link} has been transferred to {username}."
  • Deadline added. "Your task {name and link} has been assigned a deadline: {date}."
  • Deadline changed. "The deadline of your task {name and link} has been changed to {date}."
  • Upcoming deadline. "The deadline {date} for your task {name and link} is coming up in {days}." Derived from the !(yyyy-mm-dd) Dynalist dates, and (optionally) a setting in the Dynalist Notify software where the user can configure how much before a deadline she wants to receive the notification. (This could also be made configurable per task using custom tags in Dynalist such as #notify-1w for "start one week before". But that is just overkill, and nobody will use it … .)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.