scottquach / canvas-assignments-transfer-for-todoist Goto Github PK
View Code? Open in Web Editor NEWTransfer your school assignments from Canvas to Todoist
License: MIT License
Transfer your school assignments from Canvas to Todoist
License: MIT License
Some teachers in my classes have created 0 point unsubmittable assignments, which of course sync every time because they're not completed. Sometimes these even have a "due date" listed on them, even though you can't do anything.
I've tried to get the teacher to fix these, but sometimes they're not interested/unable/too busy/etc to do so.
After investigation, these all have a "grading_type" of "not_graded" - I think it would make sense to ignore any assignment with a grading_type of "not_graded" - has anyone else seen or run into this?
As of Nov 2022, Todoist has shut off the todoist-python (https://github.com/Doist/todoist-python) so this no longer works
They suggest you migrate to https://github.com/Doist/todoist-api-python
I will work on migrating my branch to that.
To start, im a novice with python and custom scripts in general and im wondering if there's a way customize this code to fit my purposes. First, is there a way to not import overdue assignments? Second, how could i get this program to run regularly, say once a day? Thanks.
After PR#15 (#15) several assignments which didn't sync before synced, which are all completed.
Investigating these showed that they are all assignments which are submitted external to Canvas using third party systems, so the status does not show submitted, as submitting shows "An external tool".
I'm wondering the best way to handle these - One possibility could be to not sync assignments where the grade is 100% (in this case they all have 10/10), but that wouldn't work if they aren't 100%. Or add an option to use score recorded instead of submitted status.
It looks like while I was updating everything, something broke with updating assignments and checking if they match - I'm getting duplicates in some places, and then the update_task function is not working correctly.
Remove or archive unneeded files
canvas_to_todoist.py
config.json (auto generated on first script run)
Right now, the tool pulls all assignments from Canvas, and all tasks in Todoist. This results in a lot of overhead and impact (for example, I have 1800+ Todoist Tasks) and retrieving data that isn't needed.
It think architecturally it would be preferable if instead it iterated and submitted tasks on a per-course basis, pulling only the matching tasks for the project. This would significantly cut down on the amount of return, though it would require that we iterate through the process times for each class.
Thoughts on changing the logic flow? It would be more API calls, but significantly less data returned. I think it would help with performance and efficiency.
The Canvas API has pagination when calling items/assignments. This is shown by the return of the "link" item in the header, which informs the next page to query. (see https://canvas.instructure.com/doc/api/file.pagination.html)
However, this script doesn't handle that, meaning we only process the first 100 items.
Need to add logic to handle pagination (one option may be this link https://community.canvaslms.com/t5/Canvas-Developers-Group/Handling-Pagination/td-p/51450/page/2)
Is there someone who might be able to help with this?
Canvas now has a "TODO" API. This is separate from assignments, though assignments are automatically added as Todos (however, the URL would be the same, so we could easily deduplicate them).
I would like to investigate adding the capability of syncing that, as often important coursework and content (that is not an assignment) is added that way.
When you make a creative work (which includes code), the work is under exclusive copyright by default. Unless you include a license that specifies otherwise, nobody else can copy, distribute, or modify your work without being at risk of take-downs, shake-downs, or litigation. Once the work has other contributors (each a copyright holder), “nobody” starts including you.
Even in the absence of a license file, you may grant some rights in cases where you publish your source code to a site that requires accepting terms of service. For example, if you publish your source code in a public repository on GitHub, you have accepted the Terms of Service, by which you allow others to view and fork your repository. Others may not need your permission if limitations and exceptions to copyright apply to their particular situation. Neither site terms nor jurisdiction-specific copyright limitations are sufficient for the kinds of collaboration that people usually seek on a public code host, such as experimentation, modification, and sharing as fostered by an open source license.
See https://choosealicense.com/no-permission/
As each contributor holds copyright for the portions of the program they wrote, their consent would be needed to add a license for that portion, but it could be done piecemeal for each person's contributions.
Rather than just creating a task with the assignment title, include the assignment URL, i.e
[Assignment
Title](https://canvas.instructure.com/courses/10544/assignments/633167)
The value is included in the returned response but can also be generated based on the course and assignment ID.
I have a significant number of teachers who use the "lock" function within Canvas to prevent you from submitting or editing old assignments (often don't accept late work) and/or to keep you from working too far ahead.
This creates the problem of assignments you can't do because they are locked, or can't submit.
The problem is that we probably don't want to just not sync all locked assignments, because if they are due in the future, they will become unlocked and you want to work on them.
So, I'm thinking the best logic would probably be
locked_for_user": true" AND "unlock_at" is in the PAST
(If it's locked but will unlock in the future OR if it is unlocked but will lock in the future we will still want to sync it)
Has anyone else run into this? My school/teachers seem to do a lot of weird stuff in Canvas... :)
I have added labels and priority to my latest branch , as well as reworked the initial config (with a single config variable and a separate initial configuration loop), so if users want to configure those parameters they can (otherwise they'll be set to defaults). I'd love it if you'd take a look and let me know any thoughts before I submit a PR.
However, I have one issue I'd love some help on since you tackled a similar problem elsewhere in the code.
I added the "todoist_task_labels" dict with which you can submit the task with the appropriate labels (or none; it will still submit successfully). However, you need to submit with label ids, which most end users likely don't know.
So, while it works if I manually add the label IDs to the config.json, most users are going to want to enter the label names as part of the initial config setup, which we then would need to either a) query and match up with existing labels, and/or b) create them or throw an error if they don't exist. (This is basically the same process as you do in the code for the initial projects).
They're easy to pull with "labels = todoist_api.state['labels']", but not sure about how best to match them up.
This is an important feature for me and others who use custom filters, because otherwise I have to create filters for each and every project, whereas I group them all under common labels (such as "school").
I've discovered that if an assignment due date is updated by a professor in Canvas, the tool will not sync the updated due date, since it already sees that the task has been synced.
This isn't frequent but is a problem when it occurs.
Is it possible to add all to one list on Todo so free users can add all of there classes. Right now its limited to just 5
Todoist Projects don't allow most special characters (see https://todoist.com/help/articles/create-a-project)
When creating a project, you can’t use # " ( ) | & ! or , in the project name. The only special characters allowed in project names are . _ and -.
However, I have a canvas class which contains an "&" character in the title, resulting in a KeyError when it attempts to create the associated tasks. It appears the script initially creates the project within todoist (with an underscore _ instead of &), and then each subsequent run simply creates yet another project with the same name within Todoist.
I'm not sure the best way to handle this - it seems the easiest would be to just do a simple replace and substitute for any of those special characters prior to execution.
As Canvas has updated their API and added several new features, I have found that not everything is under the "/api/v1/courses/[course id]" / assignments anymore - for example, I just found several new courses are using quizzes and they are under the /quizzes API seperately
My goal is to rewrite the script to use the Todo API (/api/v1/users/self/todo) which has two great advantages - 1, it includes all items added as Todos (including announcements, quizzes, etc) and 2, it syncs to Canvas so when items are removed in Canvas (for whatever reason). Unfortunately, it looks like Canvas doesn't automatically add everything to the todo list however, so it seems to have limits. So I'm still investigating. I may need to set it up to query all three APIs separately in iterations.
The response "Assignment Already Synced" is printed twice for assignments already synced/
Working... the key was in dict, don't create project Assignment already synced: Training for Students assignment already synced Done!
Looks to be an issue with the if/else closes in the def transfer_assingments_to_todoist.
What is the scenario being accounted for with the second "Assignment already synced?"? Shouldn't everything fall into already submitted or already synced?
Probably need to rework the logic with some "else/if" instead of setting the is_synced parameter to false and then starting new logic for it? Or we could add a second variable for is_submitted and then if the second print to only print submitted?
Some teachers set the due dates of their assignments to 11:59pm, which doesn't translate well when Todoist is integrated with a calendar.
I plan to implement this and submit a pull request.
Would like to add logging, statistics, and automation
For example, "For Course x, there are 15 assignments in canvas, 12 submitted, 4 unsubmitted, 2 null, 1 locked", with a summary printed at the end. IThis would also be extrememly helpful in identifying bugs)
Adding logging to file and automation would help so that I can add the ability to automatically run it on schedule.
Hello!
I found this project and was very excited to be able to pull in my existing Canvas tasks to todoist. Unfortunately, it doesn't seem to work, and I'd love some help.
Executing it returns the error "AttributeError: 'str' object has no attribute 'get'"
`
user@macbookf Canvas-Assignments-Transfer-For-Todoist-master-1 % python easy_run.py
###################################################
###################################################
Traceback (most recent call last):
File "/Canvas-Assignments-Transfer-For-Todoist-master-1/easy_run.py", line 162, in
main()
File "/Canvas-Assignments-Transfer-For-Todoist-master-1/easy_run.py", line 22, in main
select_courses(keys)
File “/Canvas-Assignments-Transfer-For-Todoist-master-1/easy_run.py", line 73, in select_courses
courses_id_name_dict[course.get('id', None)] = course.get('name', None)
AttributeError: 'str' object has no attribute 'get'`
I also found and identified a few additional notes/problems:
The courses displayed is capped at 100 and courses after the 100th are omitted and cannot be selected
When Todoist added durations, we didn't add any code, so tasks now sync with a "15m" duration.
Easy fix: Add a "0m" duration to remove the duration from the assignments.
More complex fix: Add a longer task duration and sync backwards from that (the problem is that durations start at due time, which is when they need to be turned in..)
I beleive this is a problem with the API version it's requesting. We may need to replace the calls from https://api.todoist.com/rest/v1/projects to https://api.todoist.com/rest/v2/projects
It would be nice to have the option to be able to set the due date of all assignments x days before it is actually due.
I would imagine there could be two ways of having the actual due date incorporated either as a sub task or within the task name itself.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.