Skip to content
This repository has been archived by the owner on Jan 8, 2021. It is now read-only.

Notifications - issue #165 #240

Merged
merged 31 commits into from Sep 24, 2012
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9ac8daf
Done basic logic in javascript and add some lines in css.
zupan May 30, 2012
c71b0c5
Added some css and new subscribers fiels in Post (api/models.py).
zupan Jun 8, 2012
93755bf
When post is created author is added to the list of subscribers.
zupan Jun 11, 2012
c240e5c
Merging...
zupan Jul 24, 2012
48303ef
Made some changes, fixed subscribers list.
zupan Jul 30, 2012
63e9e79
New comments are appending to user's notification list.
zupan Jul 30, 2012
feb6dbc
Updated from main repository. Minor changes in resources.py
zupan Aug 1, 2012
04ecad0
Changed model's structure and move notifications from user to new mod…
zupan Aug 9, 2012
b63ad70
Created notification api so that fields in api are the same as fields…
zupan Aug 9, 2012
dd130f9
Add javascript code which displays simple notification list.
zupan Aug 10, 2012
dc52c17
Fixed resources.py so that resource_uri is also pushed with other not…
zupan Aug 12, 2012
70cbcd2
Merge upstream...
Aug 16, 2012
3713e99
Merge remote-tracking branch 'upstream/master' into notifications_#165
Aug 16, 2012
dcba65b
Fixed css and html for notifications, changed fields in Notification …
Aug 16, 2012
f6bb9c8
Changed channel_id, fixed bugs in notification.js, resources.py, mode…
zupan Sep 7, 2012
41c32ca
Upstream merge.
zupan Sep 7, 2012
0f66119
Fixed harcoded notification api url.
zupan Sep 7, 2012
e5909e1
Fixed push for notifications using signals, changing channel_id on di…
zupan Sep 7, 2012
fecf0b6
Merge remote-tracking branch 'upstream/master' into notifications_#165
zupan Sep 7, 2012
2268613
Fixes user_chanell_id, mongoengine signals, javascript notification o…
zupan Sep 10, 2012
98ca54a
Fixed some minor issues, added translation for notifications.
zupan Sep 10, 2012
8c34061
Removed django.po~.
zupan Sep 10, 2012
b1059a0
Fixed imports, settings.py and generate_channel_id in models.py.
zupan Sep 11, 2012
8d9b496
Fixed signals for pushing notifications.
zupan Sep 12, 2012
750cde1
Changed html parsing, translation in js fixed code style...
zupan Sep 19, 2012
c59df26
Fixed authorization.py and resources.py.
zupan Sep 20, 2012
db6555a
Fixed all known issues/errors.
zupan Sep 20, 2012
d799a04
Fixed js in home.js added some comments and TODO.
zupan Sep 23, 2012
a7f203d
Changed addComment and fixed some issues with variable names.
zupan Sep 23, 2012
8b134bd
Added TODO in frontend/views.py.
zupan Sep 23, 2012
2bc2865
Updated translations.
zupan Sep 23, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions piplmesh/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class Connection(mongoengine.EmbeddedDocument):
http_if_modified_since = mongoengine.StringField()
channel_id = mongoengine.StringField()

class Notification(mongoengine.EmbeddedDocument):
read = mongoengine.BooleanField()
comment = mongoengine.IntField()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Int field? What will be stored here?


class User(auth.User):
username = mongoengine.StringField(
max_length=30,
Expand All @@ -48,6 +52,8 @@ class User(auth.User):
connections = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Connection))
connection_last_unsubscribe = mongoengine.DateTimeField()
is_online = mongoengine.BooleanField(default=False)

notifications = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Notification), default=lambda: [], required=False)

def get_image_url(self, request):
if self.twitter_id:
Expand Down
2 changes: 1 addition & 1 deletion piplmesh/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ class AuthoredDocument(mongoengine.Document):

meta = {
'abstract': True,
}
}
5 changes: 4 additions & 1 deletion piplmesh/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import mongoengine

from piplmesh.account import models as account_models
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import with relative import as you can see bellow.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need, because they are all part of the same package.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No empty line here. Those two are same package (PiplMesh).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use relative import also for above.

from . import base

POST_MESSAGE_MAX_LENGTH = 500
Expand Down Expand Up @@ -33,6 +35,7 @@ class Post(base.AuthoredDocument):
comments = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Comment), default=lambda: [], required=False)
attachments = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Attachment), default=lambda: [], required=False)

subscribers = mongoengine.ListField(mongoengine.ReferenceField(account_models.User), default=lambda: [], required=False)
# TODO: Prevent posting comments if post is not published
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line between subscribers and TODOs.

# TODO: Prevent adding attachments if post is published
# TODO: Prevent marking post as unpublished once it was published
Expand Down Expand Up @@ -65,4 +68,4 @@ class LinkAttachment(Attachment):

link_url = mongoengine.URLField(required=True)
link_caption = mongoengine.StringField(default='', required=True)
link_description = mongoengine.StringField(default='', required=True)
link_description = mongoengine.StringField(default='', required=True)
16 changes: 15 additions & 1 deletion piplmesh/api/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ def hydrate(self, bundle):
return bundle

class CommentResource(AuthoredResource):
def obj_create(self, bundle, request=None, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please read my comments here:

https://github.com/wlanslovenija/PiplMesh/pull/199/files#r1366928

So the main point is that you should decouple API from frontend. So in the API you just deal with storing data (so storing to list of subscribers is OK). But to send something for frontend (send_update) is no go.

So please define and use Django signals. And move the code for frontend to frontend.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And same as for discussion above, be careful where you put those signals. So adding subscribers is a part of creating an object. But sending notifications should come later, when we are really sure everything was done properly and we are just about to return the response.

obj = super(CommentResource, self).obj_create(bundle, request=request, **kwargs)

print obj.obj.author
#self.parent.fields['subscribers'].append(obj.obj.author)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.instance is what you search for (post object).


#obj.obj.save()
#print list((name, obj, " \n\n") for name, obj in self.parent.fields.iteritems())
return obj
class Meta:
object_class = api_models.Comment
allowed_methods = ('get', 'post', 'put', 'patch', 'delete')
Expand Down Expand Up @@ -63,9 +72,14 @@ class PostResource(AuthoredResource):

comments = fields.EmbeddedListField(of='piplmesh.api.resources.CommentResource', attribute='comments', default=lambda: [], null=True, full=False)
attachments = fields.EmbeddedListField(of='piplmesh.api.resources.AttachmentResource', attribute='attachments', default=lambda: [], null=True, full=True)

def obj_create(self, bundle, request=None, **kwargs):
obj = super(PostResource, self).obj_create(bundle, request=request, **kwargs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, obj_create returns bundle, not obj. Code would be clearer if you would do it like that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better place for all this would be in hydrate, not obj_create:

http://django-tastypie.readthedocs.org/en/latest/resources.html#hydrate

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See how we are populating fields in AuthoredResource.

obj.obj.subscribers.append(bundle.request.user)
obj.obj.save()
return obj
class Meta:
queryset = api_models.Post.objects.all()
#print queryset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be removed. :-)

allowed_methods = ('get', 'post', 'put', 'patch', 'delete')
# TODO: Make proper authorization, current implementation is for development use only
authorization = tastypie_authorization.Authorization()
28 changes: 28 additions & 0 deletions piplmesh/frontend/static/piplmesh/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,34 @@ form input[type="submit"], form input[type="reset"] {
white-space: nowrap;
}

.notifications {
padding: 5px;
border: 1px solid #999;
cursor: pointer;
}

.close_notif_box {
background: #eee;
clear: both;
cursor: pointer;
}

#notif_box {
background: #ffffff;
display: none;
position: absolute;
border: 1px solid #999;
}

#notif_content {
padding: 5px;
}

.close_notif_box {
text-align: right;
padding-right: 5px;
}

#header .user li.last {
border-right: none;
}
Expand Down
57 changes: 57 additions & 0 deletions piplmesh/frontend/static/piplmesh/js/notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
$(document).ready(function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space before () in anonymous functions.

$(".notifications").click(function (){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after (). Use ' for constant strings.

if ($("#notif_box").hasClass('show')) {
$("#notif_box").slideUp('fast');
$("#notif_box").toggleClass('show');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They beautify of jQuery is that you can chain this together:

$('#notif_box').slideUp('fast').toggleClass('show');

But I am not sure why you are setting and clearing this class?

} else {
$("#notif_box").slideDown('fast');
$("#notif_box").toggleClass('show');
}
});
$(".close_notif_box").click(function (){
if ($("#notif_box").hasClass('show')) {
$("#notif_box").slideUp('fast');
$("#notif_box").toggleClass('show');
}
});
$("#addPost").click(function (){
addPost("Bla bla bla bla Post...");
});
$("#addCom").click(function (){
addComment("Bla bla bla bla");
});
});

function addPost(message) {
$.ajax({
type: 'POST',
url: '/api/v1/post/',
data: JSON.stringify({'message': message, 'is_published': true}),
contentType: 'application/json',
dataType: "json",
success: function () {
alert("Post napisan.");
},
error: function (error) {
console.log(error);
alert("Oops, something went wrong... ");
}
});
}

function addComment(comment) {
$.ajax({
type: 'POST',
url: '/api/v1/post/4fd23f8cc91da109b8000001/comments/',
data: JSON.stringify({'message': comment}),
contentType: 'application/json',
dataType: "json",
success: function () {
alert("Komentar napisan.");
},
error: function (error) {
console.log(error);
alert("Oops, something went wrong... ");
}
});
}
1 change: 1 addition & 0 deletions piplmesh/frontend/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<script src="{% url django.views.i18n.javascript_catalog %}" type="text/javascript"></script>
<script src="{% static "pushserver/updates.js" %}" type="text/javascript"></script>
<script src="{% static "piplmesh/js/home.js" %}" type="text/javascript"></script>
<script src="{% static "piplmesh/js/notifications.js" %}" type="text/javascript"></script>
<script type="text/javascript">
$.updates.subscribe({
'home_channel': '{% filter escapejs %}{% channel_url HOME_CHANNEL_ID %}{% endfilter %}'
Expand Down
15 changes: 15 additions & 0 deletions piplmesh/frontend/templates/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@
If user is already logged in, logout link is shown instead.
{% endcomment %}
{% if user.is_authenticated %}
<li>
<div class="notifications">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only if authenticated? All users can get notifications, no? We are using lazy users now, remember. authenticated means that user is registered. But all users can post content.

1
</div>
<div id="notif_box" class="hide">
<div id="notif_content">
Bla bla bla.<br />
Bla bla bla.<br />
</div>
<div class='close_notif_box'>
<div id="addPost">Add p</div>
<div id="addCom">Add c</div> Close
</div>
</div>
</li>
<li class="image">
{% user_image %}
</li>
Expand Down
1 change: 1 addition & 0 deletions src/mongodbforms
Submodule mongodbforms added at 01201c
1 change: 1 addition & 0 deletions src/mongogeneric
Submodule mongogeneric added at 0d9d32
5 changes: 5 additions & 0 deletions src/pip-delete-this-directory.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This file is placed here by pip to indicate the source was put
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WHAT IS THIS?

here by pip.

Once this package is successfully installed this source code will be
deleted (unless you remove this file).