Skip to content

Commit 54c777d

Browse files
committed
add discussion selection to the profile, also record if users post a message in a discussion
1 parent 74cd8ee commit 54c777d

File tree

10 files changed

+140
-34
lines changed

10 files changed

+140
-34
lines changed

pyhackers/controllers/ajax.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from flask.ext.login import login_required, current_user
44
from pyhackers.helpers import current_user_id
55
from pyhackers.service.channel import follow_channel
6-
from pyhackers.service.discuss import new_discussion_message, discussion_messages
6+
from pyhackers.service.discuss import new_discussion_message, discussion_messages, get_user_discussion_by_nick
77
from pyhackers.service.project import project_follow
88
from pyhackers.service.user import follow_user, get_user_timeline_by_nick, get_user_projects_by_nick
99

@@ -75,7 +75,7 @@ def discussion_messages_ctrl(discussion_id):
7575
def user_projects(nick):
7676
_ = get_user_projects_by_nick(nick)
7777
if _ is None:
78-
return jsonify({'user': None})
78+
return jsonify({'user': None, 'projects': None})
7979

8080
user, projects = _
8181
start = 0
@@ -92,4 +92,17 @@ def user_timeline(nick):
9292

9393
user, timeline = _
9494

95-
return jsonify({'user': user.to_dict(), 'timeline': [t.to_dict() for t in timeline]})
95+
return jsonify({'user': user.to_dict(), 'timeline': [t.to_dict() for t in timeline]})
96+
97+
98+
@ajax_app.route('user/<regex(".+"):nick>/discussions')
99+
def user_discussion(nick):
100+
after_id = request.args.get("after_id", -1)
101+
102+
_ = get_user_discussion_by_nick(nick)
103+
if _ is None:
104+
return jsonify({'user': None})
105+
106+
user, discussions = _
107+
108+
return jsonify({'user': user.to_dict(), 'discussions': [t.to_dict() for t in discussions]})

pyhackers/controllers/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ def profile():
283283
"""Returns profile of the current logged in user"""
284284
user_data = load_user(current_user.id, current_user)
285285
if user_data is not None:
286-
user, followers, following, os_projects = user_data
286+
user, followers, following = user_data
287287

288288
return render_base_template("profile.html", profile=user, followers=followers,
289289
following=following,
290-
os_projects=os_projects)
290+
os_projects=[])
291291

292292
return abort(404)
293293

pyhackers/model/cassandra/hierachy.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ def to_dict(self):
146146
}
147147

148148

149+
class UserDiscussion(MBase):
150+
user_id = columns.Integer(primary_key=True)
151+
discussion_id = columns.BigInt(primary_key=True)
152+
153+
149154
class DiscussionCounter(MBase):
150155
id = columns.BigInt(primary_key=True)
151156
message_count = columns.Counter()
@@ -157,30 +162,30 @@ def to_dict(self):
157162
'message_count': self.message_count,
158163
'user_count': self.user_count,
159164
'view_count': self.view_count,
160-
161165
}
162166

163167

164168
class Discussion(MBase):
165169
id = columns.BigInt(primary_key=True)
166170
title = columns.Text(required=True)
167171
slug = columns.Text(required=True, index=True)
168-
user_id = columns.Integer()
172+
user_id = columns.Integer(index=True)
169173
users = columns.Set(value_type=columns.Integer)
170174
post_id = columns.BigInt()
171175
last_message = columns.BigInt()
172176
published_at = columns.DateTime(default=dt.utcnow())
173177
topic_id = columns.Integer(required=False)
174178

175179
def to_dict(self):
176-
return {'id': self.id,
180+
return {'id': unicode(self.id),
177181
'title': self.title,
182+
'slug': self.slug,
178183
'user_id': self.user_id,
179-
'post_id': self.post_id,
184+
'post_id': unicode(self.post_id),
180185
'last_message': unicode(self.last_message),
181186
'published_at': self.published_at,
182-
'topic_id': self.topic_id,
183-
}
187+
'topic_id': unicode(self.topic_id) if self.topic_id is not None else None,
188+
}
184189

185190

186191
class DiscussionPost(MBase):

pyhackers/model/cassandra/management.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def create(cassa_key_space='pyhackers'):
2323
sync_table(UserFollowing)
2424
sync_table(UserPost)
2525
sync_table(UserProject)
26+
sync_table(UserDiscussion)
2627
sync_table(UserCounter)
2728

2829
# Post related Tables

pyhackers/service/discuss.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,27 @@
22
from cqlengine.query import DoesNotExist
33
from pyhackers.events import Event
44
from pyhackers.idgen import idgen_client
5-
from pyhackers.model.cassandra.hierachy import Post, Discussion, DiscussionPost, DiscussionCounter
5+
from pyhackers.model.cassandra.hierachy import Post, Discussion, DiscussionPost, DiscussionCounter, UserDiscussion, \
6+
User as CsUser
67
from pyhackers.service.post import new_post, load_posts
7-
from pyhackers.service.user import load_user, load_user_profiles
8+
from pyhackers.service.user import load_user_profiles
89
from pyhackers.utils import markdown_to_html
910

1011
from slugify import slugify
1112

1213
from datetime import datetime as dt
1314

15+
1416
def load_discussions():
1517
discussions = Discussion.objects.all().limit(50)
1618

1719
return discussions
1820

1921

22+
def load_discussions_by_id(ids):
23+
return Discussion.objects.filter(id__in=ids).limit(50)
24+
25+
2026
def load_discussion(slug, discussion_id):
2127
discussion, disc_posts, users, counters = discussion_messages(discussion_id)
2228

@@ -29,7 +35,6 @@ def load_discussion(slug, discussion_id):
2935

3036

3137
def discussion_messages(discussion_id, after_message_id=None, limit=100):
32-
3338
discussion = Discussion.objects.get(id=discussion_id)
3439
if after_message_id:
3540
post_filter = DiscussionPost.objects.filter(disc_id=discussion_id,
@@ -48,10 +53,11 @@ def discussion_messages(discussion_id, after_message_id=None, limit=100):
4853
u = filter(lambda x: x.id == post.user_id, users)
4954

5055
post.user = u[0] if u is not None else None
56+
5157
try:
5258
counters = DiscussionCounter.get(id=discussion_id)
5359
except DoesNotExist:
54-
counters = { 'message_count': 1, 'user_count': 1, 'view_count': 0 }
60+
counters = {'message_count': 1, 'user_count': 1, 'view_count': 0}
5561

5662
return discussion, disc_posts, users, counters
5763

@@ -74,12 +80,14 @@ def new_discussion(title, text, current_user_id=None):
7480

7581
d.save()
7682

77-
disc_counter = DiscussionCounter.create(id=disc_id)
83+
disc_counter = DiscussionCounter(id=disc_id)
7884
disc_counter.message_count = 1
7985
disc_counter.user_count = 1
8086
disc_counter.view_count = 1
8187
disc_counter.save()
8288

89+
UserDiscussion.create(user_id=current_user_id, discussion_id=d.id)
90+
8391
new_post(text, code='', current_user_id=current_user_id, post_id=post_id)
8492

8593
return disc_id, slug
@@ -89,8 +97,6 @@ def new_discussion_message(discussion_id, text, current_user_id):
8997
logging.warn("DSCSS:[{}]USER:[{}]".format(discussion_id, current_user_id))
9098
discussion = Discussion.objects.get(id=discussion_id)
9199

92-
93-
94100
p = Post()
95101
p.id = idgen_client.get()
96102
p.discussion_id = discussion_id
@@ -110,11 +116,26 @@ def new_discussion_message(discussion_id, text, current_user_id):
110116
discussion.users.union({current_user_id})
111117
discussion.save()
112118

119+
UserDiscussion.create(user_id=current_user_id, discussion_id=discussion_id)
120+
113121
DiscussionPost.create(disc_id=discussion_id, post_id=p.id, user_id=current_user_id)
114-
disc_counter = DiscussionCounter.create(id=discussion_id )
122+
123+
disc_counter = DiscussionCounter(id=discussion_id)
115124
disc_counter.message_count += 1
116125
disc_counter.save()
117126

127+
return p.id
118128

119129

120-
return p.id
130+
def get_user_discussion_by_nick(nick):
131+
try:
132+
user = CsUser.filter(nick=nick).first()
133+
except DoesNotExist, dne:
134+
user = None
135+
136+
if user is None:
137+
return
138+
139+
discussions = list([d.discussion_id for d in UserDiscussion.objects.filter(user_id=user.id)])
140+
141+
return user, load_discussions_by_id(discussions)

pyhackers/service/user.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pyhackers.model.os_project import OpenSourceProject
77
from pyhackers.model.action import Action, ActionType
88
from pyhackers.db import DB as db
9-
from pyhackers.model.cassandra.hierachy import User as CsUser, UserFollower, UserFollowing, UserProject, Project, UserPost
9+
from pyhackers.model.cassandra.hierachy import User as CsUser, UserFollower, UserFollowing, UserProject, Project, UserPost, UserDiscussion
1010
from pyhackers.apps.idgen import idgen_client
1111
from pyhackers.sentry import sentry_client
1212
import simplejson as json
@@ -207,6 +207,8 @@ def get_user_projects_by_nick(nick):
207207

208208
return user, os_projects
209209

210+
211+
210212
def get_user_timeline_by_nick(nick):
211213
try:
212214
user = CsUser.filter(nick=nick).first()

pyhackers/static/coffee/app/user.coffee

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
class User
33
postTemplate : window.Handlebars.compile($.trim($("#message-template").html()))
44
projectTemplate: window.Handlebars.compile($.trim($("#project-template").html()))
5+
discussionTemplate: window.Handlebars.compile($.trim($("#discussion-template").html()))
56

67
constructor : (@user_nick, @activeModule) ->
78
console.log "Initialized"
@@ -26,12 +27,11 @@ class User
2627
$tab.find('a[href="#projects"]').parent().addClass("active").siblings().removeClass("active")
2728
do @loadProjects
2829
when "#timeline-container", "timeline"
29-
3030
do @loadTimeline
31-
when "#discussions", "discussions"
31+
when "#discussions-container", "discussions"
3232
if !evt?
33-
$('#discussions').addClass("active").siblings().removeClass("active")
34-
$tab.find('a[href="#discussions"]').parent().addClass("active").siblings().removeClass("active")
33+
$('#discussions-container').addClass("active").siblings().removeClass("active")
34+
$tab.find('a[href="#discussions-container"]').parent().addClass("active").siblings().removeClass("active")
3535
do @loadDiscussions
3636
else
3737
console.log "#{target} not found"
@@ -60,9 +60,18 @@ class User
6060
))
6161
)
6262
loadDiscussions: () ->
63-
console.log("Load discussions")
64-
65-
63+
$discussions= $("#discussions")
64+
$.getJSON("/ajax/user/#{@user_nick}/discussions",
65+
{_: new Date().getTime(), after_id: @lastMessage or -1},
66+
(data) =>
67+
console.log(data)
68+
_.each(data.discussions, (dd) ->
69+
dd.user = data.user
70+
)
71+
$discussions.html(@discussionTemplate(
72+
discussions: data.discussions
73+
))
74+
)
6675
$ ->
6776
user_nick = $("#user_nick").val()
6877
activeModule = $("#active_module").val()

pyhackers/static/js/app/user.js

Lines changed: 20 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyhackers/templates/js_templates.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,37 @@ <h4 class="modal-title" id="myModalLabel">Modal title</h4>
107107
{{/each}}
108108
</script>
109109

110+
<script type="text/x-handlebars-template" id="discussion-template">
111+
{{#each discussions }}
112+
<div class='row message-container'>
113+
<div class='front-action col-lg-2'>
114+
<i class='fa fa-arrow-up fa-2x'></i>
115+
<span class="label"> 1 </span>
116+
</div>
117+
<div class='col-lg-10 link-box' style="padding-left:0;">
118+
<div class='clear link-container row'>
119+
<div class='col-lg-12'>
120+
<div class="message">
121+
<a class='link' href='/user/{{ user.nick }}'>{{ user.nick }}</a>
122+
wrote a message&nbsp;
123+
<a class="link" href="/discuss/{{ slug }}/{{ id }}">
124+
{{{ title }}}
125+
</a>
126+
</div>
127+
</div>
128+
</div>
129+
<div class='row'>
130+
<div class='col-lg-5'>
131+
<a href="#post" class="link-discuss">{{ ago }}</a>
132+
<a href="/user/{{ user.nick }}"> by @{{ user.nick }}</a>
133+
</div>
134+
135+
<div class="col-6" style="text-align: right">
136+
</div>
137+
</div>
138+
</div>
139+
</div>
140+
{{/each}}
141+
</script>
142+
110143
{% endraw %}

pyhackers/templates/user_profile.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h5>@{{ profile.nick }}</h5>
3737
<ul id="user-tab" class="nav nav-tabs">
3838
<li class="active"><a href="#timeline-container" data-toggle="tab">Timeline</a></li>
3939
<li><a href="#projects" data-toggle="tab">Projects</a></li>
40-
<li><a href="#discussions" data-toggle="tab">Discussions</a></li>
40+
<li><a href="#discussions-container" data-toggle="tab">Discussions</a></li>
4141
</ul>
4242

4343
<div class="tab-content">
@@ -51,7 +51,13 @@ <h5>@{{ profile.nick }}</h5>
5151
<div class="tab-pane frame" id="projects">
5252

5353
</div>
54-
<div class="tab-pane" id="discussions"></div>
54+
<div class="tab-pane" id="discussions-container">
55+
<div class="links container">
56+
<div id='discussions' class="linklist row">
57+
58+
</div>
59+
</div>
60+
</div>
5561
</div>
5662
</div>
5763
</div>

0 commit comments

Comments
 (0)