Avatars are now obtained from Blender ID. They are downloaded from
Blender ID and stored in the users' home project storage.
Avatars can be synced via Celery and triggered from a webhook.
The avatar can be obtained from the current user object in Python, or
via pillar.api.users.avatar.url(user_dict).
Avatars can be shown in the web frontend by:
- an explicit image (like before but with a non-Gravatar URL)
- a Vue.js component `user-avatar`
- a Vue.js component `current-user-avatar`
The latter is the most efficient for the current user, as it uses user
info that's already injected into the webpage (so requires no extra
queries).
Commit 0f0a4be4 introduced using PATCH on users to set the username.
An old unit test failed, as it checks that PATCH is not allowed (e.g.
tests for 405 Method Not Allowed response).
The timestamps used by the 'last viewed' property of the video progress
feature were converted to strings when sending to the frontend, but never
changed back to timestamps when PUTting via the SDK. I solved it by not
PUTing the user at all, but using PATCH to set the username instead.
'valueschema' and 'keyschema' have been replaced by 'valuesrules' and
'keysrules'. Note the change from 2x singular ('value' and 'schema') to
2x plural ('values' and 'rules').
Eve doesn't have any counting methods on `current_app.data`, so there is
no one-to-one translation for `cursor.count()` in
`file_storage/__init__.py`. Since the call was only used in a debug log
entry, I just removed it altogether.
I removed `pillar.cli.operations.index_users_rebuild()`, as it was
importing `pillar.api.utils.algolia.algolia_index_user_save` which doesn't
exist any more, so the code was dead anyway.
This makes it possible to PUT a project after attach_project_pictures()
has been called on it (which embeds the picture file documents).
This will be used in SVNman.
Breadcrumbs are served as JSON at `/nodes/{node ID}/breadcrumbs`, with
the top-level parent listed first and the node itself listed last:
{breadcrumbs: [
...
{_id: "parentID",
name: "The Parent Node",
node_type: "group",
url: "/p/project/parentID"},
{_id: "deadbeefbeefbeefbeeffeee",
name: "The Node Itself",
node_type: "asset",
url: "/p/project/nodeID",
_self: true},
]}
When a parent node is missing, it has a breadcrumb like this:
{_id: "deadbeefbeefbeefbeeffeee",
_exists': false,
name': '-unknown-'}
Of course this will be the first in the breadcrumbs list, as we won't be
able to determine the parent of a deleted/non-existing node.
Breadcrumbs are rendered with Vue.js in Blender Cloud (not in Pillar);
see projects/view.pug.
Use this decorator on Flask endpoints that should respond with CORS
headers. These headers are sent in a reply when the browser sends an
`Origin` request header; for more info see [1].
This commit rolls back the previous commit (0ee1d0d3), as this new
approach with a separate decorator is both easier to use and less
error-prone.
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
This makes the `require_login` decorator always return a Flask response.
Previously it could also raise a `Forbidden` exception; now it returns a
403 Forbidden response in that case too.
Notifications for when someone posted a comment on your node
was not created.
Root cause was that default values defined in schema was not set,
resulting in activity subscriptions not being active.
There were 2 bugs preventing them to be set:
* The way the caching of markdown as html was implemented caused
default values not to be set.
* Eve/Cerberus regression causes nested default values to fail
https://github.com/pyeve/eve/issues/1174
Also, a 3rd bug caused nodes without a parent not to have a
subscription.
Migration scripts:
How markdown fields is cached has changed, and unused properties
of attachments has been removed.
./manage.py maintenance replace_pillar_node_type_schemas
Set the default values of activities-subscription
./manage.py maintenance fix_missing_activities_subscription_defaults
* Drag and drop files to comment editor to add a file attachment
* Using Vue to render comments
Since comments now has attachments we need to update the schemas
./manage.py maintenance replace_pillar_node_type_schemas
Changed how and what we store in elastic to unify it with how we store
things in mongodb so we can have more generic javascript code
to render the data.
Elastic changes:
Added:
Node.project.url
Altered to store id instead of url
Node.picture
Made Post searchable
./manage.py elastic reset_index
./manage.py elastic reindex
Thanks to Pablo and Sybren
project.
Javascript tutti.js and timeline.js is needed, and then the following to
init the timeline:
$('.timeline')
.timeline({
url: '/api/timeline'
});
# Javascript Notes:
## ES6 transpile:
* Files in src/scripts/js/es6/common will be transpiled from
modern es6 js to old es5 js, and then added to tutti.js
* Files in src/scripts/js/es6/individual will be transpiled from
modern es6 js to old es5 js to individual module files
## JS Testing
* Added the Jest test framework to write javascript tests.
* `npm test` will run all the javascript tests
Thanks to Sybren for reviewing
This adds a new Blinker signal `user_logged_in` that is only sent when
the user logs in via the web interface (and not on every token
authentication and every API call).
Asset nodes now have a new field called "properties.duration_seconds". This holds a copy of the duration stored on the referenced video file and stays in sync using eve hooks.
To migrate existing duration times from files to nodes you need to run the following:
./manage.py maintenance reconcile_node_video_duration -ag
There are 2 more maintenance commands to be used to determine if there are any missing durations in either files or nodes:
find_video_files_without_duration
find_video_nodes_without_duration
FFProbe is now used to detect what duration a video file has.
Reviewed by Sybren.
The previous implementation only supported rendering
attachments within the context of a node or project document.
Now it also supports node.properties. This is a temporary
solution, as noted in the TODO comments.
This function generates a list of selected links for important nodes such
as Pages and Blog. This list of links is used in the templates to provide
high level navigation of a Project.
Synchronisation is performed in the background by the Celery Beat, every
10 minutes. It has a time limit of 9 minutes to prevent multiple refresh
tasks from running at the same time.
Synchronisation is also possible with the `manage.py badges sync` CLI
command, which can sync either a single user or all users.
This also changes the way we treat Blender ID tokens. Before, the Blender ID
token was discarded and a random token was generated & stored. Now the
actual Blender ID token is stored.
The Facebook and Google OAuth code still uses the old approach of generating
a new token. Not sure what the added value is, though, because once the
Django session is gone there is nothing left to authenticate the user and
thus the random token is useless anyway.
This partially reverts commit c57aefd48b10ca3cabc9df162bc32efa62a6a21e.
The code to check against hashed tokens remains, because existing tokens
should still work.
The unhashed tokens are necessary for fetching badges from Blender ID.
We had an issue creating comments, so I wrote a test for it. The test
succeeds on a new project, so the problem lies with the older projects.
In the end it was the comment node type that still had
`{'coerce': 'markdown'}`.
Video progress updates:
- Mark as 'done' when 90% or more is watched.
- Keep 'done' flag when re-watching.
The video progress is stored on three events, whichever comes first:
- Every 30 seconds of video.
- Every 10% of the video.
- Every pause/stop/navigation to another page.
- When we detect the video is looping.
Apparently Eve is now stricter in checking against MONGO_QUERY_BLACKLIST,
and blocks our use of $regex when getting child nodes. See
`jstree.py::jstree_get_children()`
It looks like with the new Eve (or one of its dependencies) empty lists
aren't stored any more; rather than storing `{'org_roles': []}`, it skips
the `'org_roles'` key altogether. Not sure what caused this, as it was
mentioned in neither the Eve nor the PyMongo changelog.