@@ -385,12 +385,8 @@ def facebook_login(data): | |||||
"new_password": webnotes.generate_hash(data["email"]), | "new_password": webnotes.generate_hash(data["email"]), | ||||
"fb_username": data["username"], | "fb_username": data["username"], | ||||
"fb_userid": data["id"], | "fb_userid": data["id"], | ||||
"fb_location": data.get("location", {}).get("name"), | |||||
"fb_hometown": data.get("hometown", {}).get("name"), | |||||
"fb_age_range": data.get("age_range") and "{min}-{max}".format(**data.get("age_range")), | |||||
"location": data.get("location", {}).get("name"), | |||||
"birth_date": data.get("birthday"), | "birth_date": data.get("birthday"), | ||||
"fb_bio": data.get("bio"), | |||||
"fb_education": data.get("education") and data.get("education")[-1].get("type"), | |||||
"user_type": "Website User" | "user_type": "Website User" | ||||
}) | }) | ||||
profile.ignore_permissions = True | profile.ignore_permissions = True | ||||
@@ -20,10 +20,6 @@ web_include_css = style_settings.css | |||||
website_clear_cache = webnotes.templates.generators.website_group.clear_cache | website_clear_cache = webnotes.templates.generators.website_group.clear_cache | ||||
website_group_handler:Forum = webnotes.templates.website_group.forum | |||||
website_group_handler:Events = webnotes.templates.website_group.events | |||||
website_group_handler:Tasks = webnotes.templates.website_group.tasks | |||||
get_desktop_icons = webnotes.manage.get_desktop_icons | get_desktop_icons = webnotes.manage.get_desktop_icons | ||||
notification_config = webnotes.core.notifications.get_notification_config | notification_config = webnotes.core.notifications.get_notification_config | ||||
@@ -42,3 +38,8 @@ has_permission:Event = webnotes.core.doctype.event.event.has_permission | |||||
permission_query_conditions:ToDo = webnotes.core.doctype.todo.todo.get_permission_query_conditions | permission_query_conditions:ToDo = webnotes.core.doctype.todo.todo.get_permission_query_conditions | ||||
has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission | has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission | ||||
# bean | |||||
bean_event:User Vote:after_insert = webnotes.templates.generators.website_group.clear_cache_on_bean_event | |||||
bean_event:Website Sitemap Permission:on_update = webnotes.templates.generators.website_group.clear_cache_on_bean_event |
@@ -38,7 +38,7 @@ body { | |||||
.btn-primary{ | .btn-primary{ | ||||
text-decoration:none; | text-decoration:none; | ||||
color: #FFF; | |||||
color: #FFF !important; | |||||
background-color: #348eda; | background-color: #348eda; | ||||
border:solid #348eda; | border:solid #348eda; | ||||
border-width:10px 20px; | border-width:10px 20px; | ||||
@@ -53,7 +53,7 @@ body { | |||||
.btn-secondary { | .btn-secondary { | ||||
text-decoration:none; | text-decoration:none; | ||||
color: #FFF; | |||||
color: #FFF !important; | |||||
background-color: #aaa; | background-color: #aaa; | ||||
border:solid #aaa; | border:solid #aaa; | ||||
border-width:10px 20px; | border-width:10px 20px; | ||||
@@ -12,9 +12,10 @@ | |||||
{% block content %} | {% block content %} | ||||
<ul class="nav nav-tabs view-selector"> | <ul class="nav nav-tabs view-selector"> | ||||
{%- for t in views -%} | {%- for t in views -%} | ||||
{% set url = (pathname if t.default else "{}?view={}".format(pathname, t.name)) %} | |||||
<li class="{% if view.name==t.name -%} active {%- endif %} {% if t.hidden -%} hide {%- endif %}" | <li class="{% if view.name==t.name -%} active {%- endif %} {% if t.hidden -%} hide {%- endif %}" | ||||
data-view="{{ t.name }}"> | data-view="{{ t.name }}"> | ||||
<a href="{{ t.url or '' }}"><i class="{{ t.icon }}"></i> | |||||
<a href="{{ url or '' }}"><i class="{{ t.icon }}"></i> | |||||
<span class="nav-label">{{ t.label }}</span></a> | <span class="nav-label">{{ t.label }}</span></a> | ||||
</li> | </li> | ||||
{%- endfor -%} | {%- endfor -%} | ||||
@@ -26,11 +27,17 @@ | |||||
{%- endif -%} | {%- endif -%} | ||||
website.group = "{{ group.name }}"; | website.group = "{{ group.name }}"; | ||||
website.view = "{{ view.name }}"; | website.view = "{{ view.name }}"; | ||||
website.pathname = "{{ pathname }}"; | |||||
website.upvote = {{ 1 if view.upvote else 0 }}; | |||||
{% if view.upvote %} | |||||
website.setup_upvote(); | |||||
{% endif %} | |||||
</script> | </script> | ||||
{% include view.template_path %} | {% include view.template_path %} | ||||
<script>$(function() { website.toggle_upvote(); });</script> | |||||
{% endblock %} | {% endblock %} | ||||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} | {% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -3,23 +3,19 @@ | |||||
import webnotes | import webnotes | ||||
from webnotes.webutils import get_access, can_cache | from webnotes.webutils import get_access, can_cache | ||||
from webnotes.templates.website_group.post import clear_post_cache | |||||
from webnotes.templates.website_group.forum import get_post_list_html | |||||
doctype = "Website Group" | doctype = "Website Group" | ||||
no_cache = 1 | no_cache = 1 | ||||
def get_context(context): | def get_context(context): | ||||
bean = context.bean | |||||
group, view = guess_group_view(bean, context) | |||||
group, view = guess_group_view(context) | |||||
try: | try: | ||||
if not has_access(context.access, view): | if not has_access(context.access, view): | ||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
group_context = get_group_context(group, view, bean, context) | |||||
group_context.update(context) | |||||
return group_context | |||||
return get_group_context(group, view, context) | |||||
except webnotes.DoesNotExistError: | except webnotes.DoesNotExistError: | ||||
return { | return { | ||||
@@ -32,66 +28,85 @@ def get_context(context): | |||||
'You are not permitted to view this page.</div>' | 'You are not permitted to view this page.</div>' | ||||
} | } | ||||
def get_group_context(group, view, bean, context): | |||||
def get_group_context(group, view, context): | |||||
cache_key = "website_group_context:{}:{}".format(group, view) | cache_key = "website_group_context:{}:{}".format(group, view) | ||||
views = get_views(bean.doc.group_type) | |||||
views = get_views(context.bean.doc.group_type) | |||||
view = webnotes._dict(views.get(view)) | view = webnotes._dict(views.get(view)) | ||||
if can_cache(view.get("no_cache")): | |||||
if can_cache(view.no_cache): | |||||
group_context = webnotes.cache().get_value(cache_key) | group_context = webnotes.cache().get_value(cache_key) | ||||
if group_context: | if group_context: | ||||
return group_context | return group_context | ||||
group_context = build_group_context(group, view, bean, views, context) | |||||
group_context = build_group_context(group, view, views, context) | |||||
if can_cache(view.get("no_cache")): | if can_cache(view.get("no_cache")): | ||||
webnotes.cache().set_value(cache_key, group_context) | webnotes.cache().set_value(cache_key, group_context) | ||||
return group_context | return group_context | ||||
def build_group_context(group, view, bean, views, context): | |||||
title = "{} - {}".format(bean.doc.group_title, view.get("label")) | |||||
for name, opts in views.iteritems(): | |||||
opts["url"] = opts["url"].format(pathname=context.pathname, post="") | |||||
def build_group_context(group, view, views, context): | |||||
title = "{} - {}".format(context.bean.doc.group_title, view.get("label")) | |||||
group_context = webnotes._dict({ | group_context = webnotes._dict({ | ||||
"group": bean.doc.fields, | |||||
"group": context.bean.doc.fields, | |||||
"view": view, | "view": view, | ||||
"views": (v[1] for v in sorted(views.iteritems(), key=lambda (k, v): v.get("idx"))), | |||||
"title": title | |||||
"views": [v[1] for v in sorted(views.iteritems(), key=lambda (k, v): v.get("idx"))], | |||||
"title": title, | |||||
"pathname": context.pathname | |||||
}) | }) | ||||
handler = get_handler(bean.doc.group_type) | |||||
if handler: | |||||
group_context.update(handler.get_context(group_context)) | |||||
group_context.update(build_view_context(group_context)) | |||||
return group_context | return group_context | ||||
def guess_group_view(bean, context): | |||||
group = context.docname | |||||
view = webnotes.form_dict.view | |||||
if not view: | |||||
for v, opts in get_views(bean.doc.group_type).iteritems(): | |||||
if opts.get("default"): | |||||
view = v | |||||
break | |||||
def build_view_context(context): | |||||
from webnotes.templates.website_group.post import get_post_context | |||||
if context.view.name in ("popular", "feed", "open", "closed", "upcoming", "past"): | |||||
context.post_list_html = get_post_list_html(context.group.name, context.view.name) | |||||
elif context.view.name == "edit": | |||||
context.post = webnotes.doc("Post", webnotes.form_dict.name).fields | |||||
if context.post.assigned_to: | |||||
context.profile = webnotes.doc("Profile", context.post.assigned_to) | |||||
elif context.view.name == "settings": | |||||
context.profiles = webnotes.conn.sql("""select p.*, wsp.`read`, wsp.`write`, wsp.`admin` | |||||
from `tabProfile` p, `tabWebsite Sitemap Permission` wsp | |||||
where wsp.website_sitemap=%s and wsp.profile=p.name""", context.pathname, as_dict=True) | |||||
elif context.view.name == "post": | |||||
context.update(get_post_context(context)) | |||||
return context | |||||
def guess_group_view(context): | |||||
group = context.docname | |||||
view = webnotes.form_dict.view or get_default_view(context.bean.doc.group_type) | |||||
return group, view | return group, view | ||||
def get_handler(group_type): | |||||
handler = webnotes.get_hooks("website_group_handler:{}".format(group_type)) | |||||
if handler: | |||||
return webnotes.get_module(handler[0]) | |||||
def get_default_view(group_type): | |||||
for view, opts in get_views(group_type).iteritems(): | |||||
if opts.get("default"): | |||||
return view | |||||
def get_views(group_type=None): | |||||
if group_type: | |||||
group_views = webnotes._dict(views[group_type]) | |||||
else: | |||||
group_views = {} | |||||
for group_type in views: | |||||
group_views.update(views[group_type].copy()) | |||||
group_views.update(common_views) | |||||
def get_views(group_type): | |||||
from copy import deepcopy | |||||
handler = get_handler(group_type) | |||||
if handler and hasattr(handler, "get_views"): | |||||
return deepcopy(handler.get_views() or {}) | |||||
return {} | |||||
if group_type == "Forum": | |||||
group_views["post"]["upvote"] = True | |||||
return group_views | |||||
def has_access(access, view): | def has_access(access, view): | ||||
if view=="settings": | if view=="settings": | ||||
return access.get("admin") | return access.get("admin") | ||||
@@ -100,26 +115,123 @@ def has_access(access, view): | |||||
else: | else: | ||||
return access.get("read") | return access.get("read") | ||||
def clear_cache(page_name=None, website_group=None): | |||||
if page_name or website_group: | |||||
filters = {"page_name": page_name} if page_name else website_group | |||||
website_group = webnotes.conn.get_value("Website Group", filters, | |||||
["page_name", "group_type"], as_dict=True) | |||||
if not website_group: | |||||
return | |||||
def clear_cache(path=None, website_group=None): | |||||
from webnotes.templates.website_group.post import clear_post_cache | |||||
if path: | |||||
website_groups = [webnotes.conn.get_value("Website Sitemap", path, "docname")] | |||||
elif website_group: | |||||
website_groups = [website_group] | website_groups = [website_group] | ||||
else: | else: | ||||
clear_post_cache() | clear_post_cache() | ||||
website_groups = webnotes.conn.sql("""select page_name, group_type from `tabWebsite Group`""", as_dict=True) | |||||
website_groups = webnotes.conn.sql_list("""select name from `tabWebsite Group`""") | |||||
cache = webnotes.cache() | cache = webnotes.cache() | ||||
all_views = get_views() | |||||
for group in website_groups: | for group in website_groups: | ||||
for view in get_views(group.group_type): | |||||
cache.delete_value("website_group_context:{}:{}".format(group.page_name, view)) | |||||
for view in all_views: | |||||
cache.delete_value("website_group_context:{}:{}".format(group, view)) | |||||
def clear_event_cache(): | def clear_event_cache(): | ||||
for group in webnotes.conn.sql_list("""select name from `tabWebsite Group` where group_type='Event'"""): | for group in webnotes.conn.sql_list("""select name from `tabWebsite Group` where group_type='Event'"""): | ||||
clear_unit_views(website_group=group) | |||||
clear_unit_views(website_group=group) | |||||
def clear_cache_on_bean_event(bean, method, *args, **kwargs): | |||||
clear_cache(path=bean.doc.website_sitemap, website_group=bean.doc.website_group) | |||||
def get_pathname(group): | |||||
return webnotes.conn.get_value("Website Sitemap", {"ref_doctype": "Website Group", | |||||
"docname": group}) | |||||
views = { | |||||
"Forum": { | |||||
"popular": { | |||||
"name": "popular", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Popular", | |||||
"icon": "icon-heart", | |||||
"default": True, | |||||
"upvote": True, | |||||
"idx": 1 | |||||
}, | |||||
"feed": { | |||||
"name": "feed", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Feed", | |||||
"icon": "icon-rss", | |||||
"upvote": True, | |||||
"idx": 2 | |||||
} | |||||
}, | |||||
"Tasks": { | |||||
"open": { | |||||
"name": "open", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Open", | |||||
"icon": "icon-inbox", | |||||
"default": True, | |||||
"upvote": True, | |||||
"idx": 1 | |||||
}, | |||||
"closed": { | |||||
"name": "closed", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Closed", | |||||
"icon": "icon-smile", | |||||
"idx": 2 | |||||
} | |||||
}, | |||||
"Events": { | |||||
"upcoming": { | |||||
"name": "upcoming", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Upcoming", | |||||
"icon": "icon-calendar", | |||||
"default": True, | |||||
"idx": 1 | |||||
}, | |||||
"past": { | |||||
"name": "past", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"label": "Past", | |||||
"icon": "icon-time", | |||||
"idx": 2 | |||||
} | |||||
} | |||||
} | |||||
common_views = { | |||||
"post": { | |||||
"name": "post", | |||||
"template_path": "templates/website_group/post.html", | |||||
"label": "Post", | |||||
"icon": "icon-comments", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 3 | |||||
}, | |||||
"edit": { | |||||
"name": "edit", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"label": "Edit Post", | |||||
"icon": "icon-pencil", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 4 | |||||
}, | |||||
"add": { | |||||
"name": "add", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"label": "Add Post", | |||||
"icon": "icon-plus", | |||||
"hidden": True, | |||||
"idx": 5 | |||||
}, | |||||
"settings": { | |||||
"name": "settings", | |||||
"template_path": "templates/website_group/settings.html", | |||||
"label": "Settings", | |||||
"icon": "icon-cog", | |||||
"hidden": True, | |||||
"idx": 6 | |||||
} | |||||
} |
@@ -20,7 +20,7 @@ | |||||
</h4> | </h4> | ||||
{%- endif -%} | {%- endif -%} | ||||
<ul class="list-inline small text-muted post-options"> | <ul class="list-inline small text-muted post-options"> | ||||
{% if view and view.upvote %}<li class="upvote"> | |||||
{% if view and view.upvote and not post.parent_post %}<li class="upvote"> | |||||
<a><span class="upvote-count {% if not post.upvotes %}hide{% endif %}">{{ post.upvotes }}</span> | <a><span class="upvote-count {% if not post.upvotes %}hide{% endif %}">{{ post.upvotes }}</span> | ||||
<i class="icon-thumbs-up"></i></a></li>{% endif %} | <i class="icon-thumbs-up"></i></a></li>{% endif %} | ||||
{%- if not post.parent_post and view.name != "post" -%} | {%- if not post.parent_post and view.name != "post" -%} | ||||
@@ -32,7 +32,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group task-status {% if not (post and post.assigned_to) %}hide{% endif %}"> | |||||
<div class="form-group task-status {% if not post %}hide{% endif %}"> | |||||
<label>Status</label> | <label>Status</label> | ||||
<select class="form-control" data-fieldname="status"> | <select class="form-control" data-fieldname="status"> | ||||
{% for opt in ("Open", "Closed") %} | {% for opt in ("Open", "Closed") %} | ||||
@@ -4,6 +4,6 @@ | |||||
</div> | </div> | ||||
<div class="media-body"> | <div class="media-body"> | ||||
<div>{{ profile.first_name or "" }} {{ profile.last_name or "" }}</div> | <div>{{ profile.first_name or "" }} {{ profile.last_name or "" }}</div> | ||||
<div class="text-muted"><small>{{ profile.fb_location or profile.fb_hometown or "" }}</small></div> | |||||
<div class="text-muted"><small>{{ profile.location or "" }}</small></div> | |||||
</div> | </div> | ||||
</div> | </div> |
@@ -0,0 +1,10 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
from __future__ import unicode_literals | |||||
import webnotes | |||||
def get_context(context): | |||||
# get settings from site config | |||||
if webnotes.conf.get("fb_app_id"): | |||||
return { "fb_app_id": webnotes.conf.fb_app_id } |
@@ -1,7 +1,7 @@ | |||||
{% include "templates/includes/post_editor.html" %} | {% include "templates/includes/post_editor.html" %} | ||||
<script type="text/javascript" src="/assets/js/canvasResize.min.js"></script> | |||||
<script> | <script> | ||||
wn.require("/assets/js/canvasResize.min.js"); | |||||
$(function() { | $(function() { | ||||
website.bind_add_post(); | website.bind_add_post(); | ||||
@@ -1,29 +0,0 @@ | |||||
<div class="small text-muted post-list-help"></div> | |||||
<div class="post-list"> | |||||
{{ post_list_html }} | |||||
</div> | |||||
<div class="text-center"> | |||||
<button class="btn btn-default btn-more hide">More</button> | |||||
</div> | |||||
<script> | |||||
$(function() { | |||||
if($(".post").length===20) { | |||||
wn.setup_pagination($(".btn-more"), { | |||||
args: { | |||||
cmd: "webnotes.templates.website_group.events.get_post_list_html", | |||||
limit_start: $(".post").length, | |||||
limit_length: 20, | |||||
group: website.group, | |||||
view: website.view | |||||
}, | |||||
$wrapper: $(".post-list") | |||||
}); | |||||
} | |||||
website.toggle_edit(); | |||||
website.setup_upvote(); | |||||
website.toggle_upvote(); | |||||
website.format_event_timestamps(); | |||||
}); | |||||
</script> |
@@ -1,125 +0,0 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
from __future__ import unicode_literals | |||||
import webnotes | |||||
from webnotes.utils import now_datetime, get_datetime_str | |||||
from webnotes.webutils import get_access | |||||
from webnotes.templates.website_group.settings import get_settings_context | |||||
from webnotes.templates.website_group.post import get_post_context | |||||
def get_views(): | |||||
return views | |||||
def get_context(group_context): | |||||
events_context = {} | |||||
if group_context.view.name in ("upcoming", "past"): | |||||
events_context["post_list_html"] = get_post_list_html(group_context["group"]["name"], group_context["view"]) | |||||
elif group_context.view.name == "edit": | |||||
events_context["session_user"] = webnotes.session.user | |||||
events_context["post"] = webnotes.doc("Post", webnotes.form_dict.name).fields | |||||
elif group_context.view.name == "settings": | |||||
events_context.update(get_settings_context(group_context)) | |||||
elif group_context.view.name == "post": | |||||
events_context.update(get_post_context(group_context)) | |||||
return events_context | |||||
@webnotes.whitelist(allow_guest=True) | |||||
def get_post_list_html(group, view, limit_start=0, limit_length=20): | |||||
access = get_access(group) | |||||
if isinstance(view, basestring): | |||||
view = get_views()[view] | |||||
view = webnotes._dict(view) | |||||
# verify permission for paging | |||||
if webnotes.local.form_dict.cmd == "get_post_list_html": | |||||
if not access.get("read"): | |||||
return webnotes.PermissionError | |||||
if view.name=="upcoming": | |||||
condition = "and p.event_datetime >= %s" | |||||
order_by = "p.event_datetime asc" | |||||
else: | |||||
condition = "and p.event_datetime < %s" | |||||
order_by = "p.event_datetime desc" | |||||
# should show based on time upto precision of hour | |||||
# because the current hour should also be in upcoming | |||||
now = now_datetime().replace(minute=0, second=0, microsecond=0) | |||||
posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name, | |||||
(select count(pc.name) from `tabPost` pc where pc.parent_post=p.name) as post_reply_count | |||||
from `tabPost` p, `tabProfile` pr | |||||
where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' | |||||
and p.is_event=1 {condition} | |||||
order by {order_by} limit %s, %s""".format(condition=condition, order_by=order_by), | |||||
(group, now, int(limit_start), int(limit_length)), as_dict=True) | |||||
context = {"posts": posts, "limit_start": limit_start, "view": view} | |||||
return webnotes.get_template("templates/includes/post_list.html").render(context) | |||||
views = { | |||||
"upcoming": { | |||||
"name": "upcoming", | |||||
"template_path": "templates/website_group/events.html", | |||||
"url": "/{group}", | |||||
"label": "Upcoming", | |||||
"icon": "icon-calendar", | |||||
"default": True, | |||||
"idx": 1 | |||||
}, | |||||
"past": { | |||||
"name": "past", | |||||
"template_path": "templates/website_group/events.html", | |||||
"url": "/{group}?view=past", | |||||
"label": "Past", | |||||
"icon": "icon-time", | |||||
"idx": 2 | |||||
}, | |||||
"post": { | |||||
"name": "post", | |||||
"template_path": "templates/website_group/post.html", | |||||
"url": "/{group}?view=post&name={post}", | |||||
"label": "Post", | |||||
"icon": "icon-comments", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 3 | |||||
}, | |||||
"edit": { | |||||
"name": "edit", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{group}?view=edit&name={post}", | |||||
"label": "Edit Post", | |||||
"icon": "icon-pencil", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 4 | |||||
}, | |||||
"add": { | |||||
"name": "add", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{group}?view=add", | |||||
"label": "Add Post", | |||||
"icon": "icon-plus", | |||||
"hidden": True, | |||||
"idx": 5 | |||||
}, | |||||
"settings": { | |||||
"name": "settings", | |||||
"template_path": "templates/website_group/settings.html", | |||||
"url": "/{group}?view=settings", | |||||
"label": "Settings", | |||||
"icon": "icon-cog", | |||||
"hidden": True, | |||||
"idx": 6 | |||||
} | |||||
} |
@@ -9,21 +9,19 @@ | |||||
<script> | <script> | ||||
$(function() { | $(function() { | ||||
if($(".post").length===20) { | if($(".post").length===20) { | ||||
wn.setup_pagination($(".btn-more"), { | |||||
args: { | |||||
cmd: "webnotes.templates.website_group.forum.get_post_list_html", | |||||
limit_start: $(".post").length, | |||||
limit_length: 20, | |||||
group: website.group, | |||||
view: website.view, | |||||
pathname: website.pathname | |||||
}, | |||||
$wrapper: $(".post-list") | |||||
}); | |||||
wn.setup_pagination(); | |||||
} | } | ||||
{% if group.group_type == "Forum" -%} | |||||
website.toggle_edit(true); | website.toggle_edit(true); | ||||
website.setup_upvote(); | |||||
website.toggle_upvote(); | |||||
{% elif group.group_type == "Tasks" %} | |||||
website.toggle_edit(); | |||||
{% elif group.group_type == "Events" %} | |||||
website.toggle_edit(); | |||||
website.format_event_timestamps(); | |||||
{%- endif %} | |||||
}); | }); | ||||
</script> | </script> |
@@ -5,120 +5,61 @@ from __future__ import unicode_literals | |||||
import webnotes | import webnotes | ||||
from webnotes.utils import now_datetime, get_datetime_str | from webnotes.utils import now_datetime, get_datetime_str | ||||
from webnotes.webutils import get_access | from webnotes.webutils import get_access | ||||
from webnotes.templates.website_group.settings import get_settings_context | |||||
from webnotes.templates.website_group.post import get_post_context | |||||
def get_views(): | |||||
return views | |||||
def get_context(group_context): | |||||
forum_context = {} | |||||
if group_context.view.name in ("popular", "feed"): | |||||
forum_context["post_list_html"] = get_post_list_html(group_context["group"]["name"], group_context["view"], group_context.pathname) | |||||
elif group_context.view.name == "edit": | |||||
forum_context["session_user"] = webnotes.session.user | |||||
forum_context["post"] = webnotes.doc("Post", webnotes.form_dict.name).fields | |||||
elif group_context.view.name == "settings": | |||||
forum_context.update(get_settings_context(group_context)) | |||||
elif group_context.view.name == "post": | |||||
forum_context.update(get_post_context(group_context)) | |||||
return forum_context | |||||
@webnotes.whitelist(allow_guest=True) | @webnotes.whitelist(allow_guest=True) | ||||
def get_post_list_html(group, view, pathname, limit_start=0, limit_length=20): | |||||
print pathname | |||||
access = get_access(pathname) | |||||
if isinstance(view, basestring): | |||||
view = get_views()[view] | |||||
view = webnotes._dict(view) | |||||
def get_post_list_html(group, view, limit_start=0, limit_length=20): | |||||
from webnotes.templates.generators.website_group import get_views | |||||
# verify permission for paging | # verify permission for paging | ||||
if webnotes.local.form_dict.cmd == "get_post_list_html": | if webnotes.local.form_dict.cmd == "get_post_list_html": | ||||
pathname = webnotes.conn.get_value("Website Sitemap", | |||||
{"ref_doctype": "Website Group", "docname": group}) | |||||
access = get_access(pathname) | |||||
if not access.get("read"): | if not access.get("read"): | ||||
return webnotes.PermissionError | return webnotes.PermissionError | ||||
if view.name == "feed": | |||||
conditions = "" | |||||
values = [group] | |||||
group_type = webnotes.conn.get_value("Website Group", group, "group_type") | |||||
if group_type == "Events": | |||||
# should show based on time upto precision of hour | |||||
# because the current hour should also be in upcoming | |||||
values.append(now_datetime().replace(minute=0, second=0, microsecond=0)) | |||||
if view in ("feed", "closed"): | |||||
order_by = "p.creation desc" | order_by = "p.creation desc" | ||||
else: | |||||
if view == "closed": | |||||
conditions += " and p.is_task=1 and p.status='Closed'" | |||||
elif view in ("popular", "open"): | |||||
now = get_datetime_str(now_datetime()) | now = get_datetime_str(now_datetime()) | ||||
order_by = """(p.upvotes + post_reply_count - (timestampdiff(hour, p.creation, \"{}\") / 2)) desc, | order_by = """(p.upvotes + post_reply_count - (timestampdiff(hour, p.creation, \"{}\") / 2)) desc, | ||||
p.creation desc""".format(now) | p.creation desc""".format(now) | ||||
if view == "open": | |||||
conditions += " and p.is_task=1 and p.status='Open'" | |||||
elif view == "upcoming": | |||||
conditions += " and p.is_event=1 and p.event_datetime >= %s" | |||||
order_by = "p.event_datetime asc" | |||||
elif view == "past": | |||||
conditions += " and p.is_event=1 and p.event_datetime < %s" | |||||
order_by = "p.event_datetime desc" | |||||
values += [int(limit_start), int(limit_length)] | |||||
posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name, | posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name, | ||||
(select count(pc.name) from `tabPost` pc where pc.parent_post=p.name) as post_reply_count | (select count(pc.name) from `tabPost` pc where pc.parent_post=p.name) as post_reply_count | ||||
from `tabPost` p, `tabProfile` pr | from `tabPost` p, `tabProfile` pr | ||||
where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' | |||||
order by {order_by} limit %s, %s""".format(order_by=order_by), | |||||
(group, int(limit_start), int(limit_length)), as_dict=True) | |||||
context = {"posts": posts, "limit_start": limit_start, "view": view} | |||||
where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' | |||||
{conditions} order by {order_by} limit %s, %s""".format(conditions=conditions, order_by=order_by), | |||||
tuple(values), as_dict=True, debug=True) | |||||
context = { "posts": posts, "limit_start": limit_start, "view": get_views(group_type)[view] } | |||||
return webnotes.get_template("templates/includes/post_list.html").render(context) | return webnotes.get_template("templates/includes/post_list.html").render(context) | ||||
views = { | |||||
"popular": { | |||||
"name": "popular", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"url": "{pathname}", | |||||
"label": "Popular", | |||||
"icon": "icon-heart", | |||||
"default": True, | |||||
"upvote": True, | |||||
"idx": 1 | |||||
}, | |||||
"feed": { | |||||
"name": "feed", | |||||
"template_path": "templates/website_group/forum.html", | |||||
"url": "/{pathname}?view=feed", | |||||
"label": "Feed", | |||||
"icon": "icon-rss", | |||||
"upvote": True, | |||||
"idx": 2 | |||||
}, | |||||
"post": { | |||||
"name": "post", | |||||
"template_path": "templates/website_group/post.html", | |||||
"url": "/{pathname}?view=post&name={post}", | |||||
"label": "Post", | |||||
"icon": "icon-comments", | |||||
"upvote": True, | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 3 | |||||
}, | |||||
"edit": { | |||||
"name": "edit", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{pathname}?view=edit&name={post}", | |||||
"label": "Edit Post", | |||||
"icon": "icon-pencil", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 4 | |||||
}, | |||||
"add": { | |||||
"name": "add", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{pathname}?view=add", | |||||
"label": "Add Post", | |||||
"icon": "icon-plus", | |||||
"hidden": True, | |||||
"idx": 5 | |||||
}, | |||||
"settings": { | |||||
"name": "settings", | |||||
"template_path": "templates/website_group/settings.html", | |||||
"url": "/{pathname}?view=settings", | |||||
"label": "Settings", | |||||
"icon": "icon-cog", | |||||
"hidden": True, | |||||
"idx": 6 | |||||
} | |||||
} |
@@ -12,11 +12,10 @@ | |||||
{% include "templates/includes/post_editor.html" %} | {% include "templates/includes/post_editor.html" %} | ||||
</div> | </div> | ||||
<script type="text/javascript" src="/assets/js/canvasResize.min.js"></script> | |||||
<script> | <script> | ||||
wn.require("/assets/js/canvasResize.min.js"); | |||||
$(function() { | $(function() { | ||||
website.toggle_edit(true); | website.toggle_edit(true); | ||||
website.setup_upvote(); | |||||
website.toggle_upvote(); | website.toggle_upvote(); | ||||
website.bind_add_post(); | website.bind_add_post(); | ||||
@@ -4,8 +4,11 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
from webnotes.utils import get_fullname | from webnotes.utils import get_fullname | ||||
from webnotes.webutils import get_access | |||||
from webnotes.utils.file_manager import save_file | |||||
from webnotes.templates.generators.website_group import get_pathname | |||||
def get_post_context(group_context): | |||||
def get_post_context(context): | |||||
post = webnotes.doc("Post", webnotes.form_dict.name) | post = webnotes.doc("Post", webnotes.form_dict.name) | ||||
if post.parent_post: | if post.parent_post: | ||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
@@ -14,24 +17,23 @@ def get_post_context(group_context): | |||||
fullname = get_fullname(post.owner) | fullname = get_fullname(post.owner) | ||||
return { | return { | ||||
"title": "{} by {}".format(post.title, fullname), | "title": "{} by {}".format(post.title, fullname), | ||||
# "group_title": group_context.get("unit_title") + " by {}".format(fullname), | |||||
"parent_post_html": get_parent_post_html(post, group_context.get("view")), | |||||
"post_list_html": get_child_posts_html(post, group_context.get("view")), | |||||
"parent_post_html": get_parent_post_html(post, context), | |||||
"post_list_html": get_child_posts_html(post, context), | |||||
"parent_post": post.name | "parent_post": post.name | ||||
} | } | ||||
cache_key = "website_group_post:{}".format(post.name) | cache_key = "website_group_post:{}".format(post.name) | ||||
return webnotes.cache().get_value(cache_key, lambda: _get_post_context()) | return webnotes.cache().get_value(cache_key, lambda: _get_post_context()) | ||||
def get_parent_post_html(post, view): | |||||
def get_parent_post_html(post, context): | |||||
profile = webnotes.bean("Profile", post.owner).doc | profile = webnotes.bean("Profile", post.owner).doc | ||||
for fieldname in ("first_name", "last_name", "user_image", "location"): | for fieldname in ("first_name", "last_name", "user_image", "location"): | ||||
post.fields[fieldname] = profile.fields[fieldname] | post.fields[fieldname] = profile.fields[fieldname] | ||||
return webnotes.get_template("templates/includes/inline_post.html")\ | return webnotes.get_template("templates/includes/inline_post.html")\ | ||||
.render({"post": post.fields, "view": view}) | |||||
.render({"post": post.fields, "view": context.view}) | |||||
def get_child_posts_html(post, view): | |||||
def get_child_posts_html(post, context): | |||||
posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name | posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name | ||||
from tabPost p, tabProfile pr | from tabPost p, tabProfile pr | ||||
where p.parent_post=%s and pr.name = p.owner | where p.parent_post=%s and pr.name = p.owner | ||||
@@ -41,7 +43,7 @@ def get_child_posts_html(post, view): | |||||
.render({ | .render({ | ||||
"posts": posts, | "posts": posts, | ||||
"parent_post": post.name, | "parent_post": post.name, | ||||
"view": view | |||||
"view": context.view | |||||
}) | }) | ||||
def clear_post_cache(post=None): | def clear_post_cache(post=None): | ||||
@@ -49,4 +51,105 @@ def clear_post_cache(post=None): | |||||
posts = [post] if post else webnotes.conn.sql_list("select name from `tabPost`") | posts = [post] if post else webnotes.conn.sql_list("select name from `tabPost`") | ||||
for post in posts: | for post in posts: | ||||
cache.delete_value("website_group_post:{}".format(post)) | |||||
cache.delete_value("website_group_post:{}".format(post)) | |||||
@webnotes.whitelist(allow_guest=True) | |||||
def add_post(group, content, picture, picture_name, title=None, parent_post=None, | |||||
assigned_to=None, status=None, event_datetime=None): | |||||
access = get_access(get_pathname(group)) | |||||
if not access.get("write"): | |||||
raise webnotes.PermissionError | |||||
if parent_post: | |||||
if webnotes.conn.get_value("Post", parent_post, "parent_post"): | |||||
webnotes.throw("Cannot reply to a reply") | |||||
group = webnotes.doc("Website Group", group) | |||||
post = webnotes.bean({ | |||||
"doctype":"Post", | |||||
"title": (title or "").title(), | |||||
"content": content, | |||||
"website_group": group.name, | |||||
"parent_post": parent_post or None | |||||
}) | |||||
if not parent_post: | |||||
if group.group_type == "Tasks": | |||||
post.doc.is_task = 1 | |||||
post.doc.assigned_to = assigned_to | |||||
elif group.group_type == "Events": | |||||
post.doc.is_event = 1 | |||||
post.doc.event_datetime = event_datetime | |||||
post.ignore_permissions = True | |||||
post.insert() | |||||
if picture_name and picture: | |||||
process_picture(post, picture_name, picture) | |||||
# send email | |||||
if parent_post: | |||||
post.run_method("send_email_on_reply") | |||||
return post.doc.parent_post or post.doc.name | |||||
@webnotes.whitelist(allow_guest=True) | |||||
def save_post(post, content, picture=None, picture_name=None, title=None, | |||||
assigned_to=None, status=None, event_datetime=None): | |||||
post = webnotes.bean("Post", post) | |||||
access = get_access(get_pathname(post.doc.website_group)) | |||||
if not access.get("write"): | |||||
raise webnotes.PermissionError | |||||
# TODO improve error message | |||||
if webnotes.session.user != post.doc.owner: | |||||
for fieldname in ("title", "content"): | |||||
if post.doc.fields.get(fieldname) != locals().get(fieldname): | |||||
webnotes.throw("You cannot change: {}".format(fieldname.title())) | |||||
if picture and picture_name: | |||||
webnotes.throw("You cannot change: Picture") | |||||
post.doc.fields.update({ | |||||
"title": (title or "").title(), | |||||
"content": content, | |||||
"assigned_to": assigned_to, | |||||
"status": status, | |||||
"event_datetime": event_datetime | |||||
}) | |||||
post.ignore_permissions = True | |||||
post.save() | |||||
if picture_name and picture: | |||||
process_picture(post, picture_name, picture) | |||||
return post.doc.parent_post or post.doc.name | |||||
def process_picture(post, picture_name, picture): | |||||
from webnotes.templates.generators.website_group import clear_cache | |||||
file_data = save_file(picture_name, picture, "Post", post.doc.name, decode=True) | |||||
post.doc.picture_url = file_data.file_name or file_data.file_url | |||||
webnotes.conn.set_value("Post", post.doc.name, "picture_url", post.doc.picture_url) | |||||
clear_cache(website_group=post.doc.website_group) | |||||
@webnotes.whitelist() | |||||
def suggest_user(group, term): | |||||
"""suggest a user that has read permission in this group tree""" | |||||
profiles = webnotes.conn.sql("""select | |||||
pr.name, pr.first_name, pr.last_name, | |||||
pr.user_image, pr.location | |||||
from `tabProfile` pr | |||||
where (pr.first_name like %(term)s or pr.last_name like %(term)s) | |||||
and pr.user_type = 'Website User' and pr.enabled=1""", | |||||
{"term": "%{}%".format(term), "group": group}, as_dict=True) | |||||
template = webnotes.get_template("templates/includes/profile_display.html") | |||||
return [{ | |||||
"value": "{} {}".format(pr.first_name or "", pr.last_name or "").strip(), | |||||
"profile_html": template.render({"profile": pr}), | |||||
"profile": pr.name | |||||
} for pr in profiles] |
@@ -3,46 +3,42 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
from webnotes.webutils import get_access | |||||
from webnotes.website.doctype.website_sitemap_permission.website_sitemap_permission import clear_permissions | |||||
from webnotes.webutils import get_access, clear_permissions | |||||
from webnotes.templates.generators.website_group import get_pathname | |||||
from webnotes.utils.email_lib.bulk import send | from webnotes.utils.email_lib.bulk import send | ||||
def get_settings_context(group_context): | |||||
if not get_access(group_context.group.name).get("admin"): | |||||
raise webnotes.PermissionError | |||||
return { | |||||
"profiles": webnotes.conn.sql("""select p.*, wsp.`read`, wsp.`write`, wsp.`admin` | |||||
from `tabProfile` p, `tabWebsite Sitemap Permission` wsp | |||||
where wsp.website_sitemap=%s and wsp.profile=p.name""", (group_context.group.name,), as_dict=True) | |||||
} | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def suggest_user(term, group): | def suggest_user(term, group): | ||||
pathname = get_pathname(group) | |||||
if not get_access(pathname).get("admin"): | |||||
raise webnotes.PermissionError | |||||
profiles = webnotes.conn.sql("""select pr.name, pr.first_name, pr.last_name, | profiles = webnotes.conn.sql("""select pr.name, pr.first_name, pr.last_name, | ||||
pr.user_image, pr.fb_location, pr.fb_hometown | |||||
pr.user_image, pr.location | |||||
from `tabProfile` pr | from `tabProfile` pr | ||||
where (pr.first_name like %(term)s or pr.last_name like %(term)s) | where (pr.first_name like %(term)s or pr.last_name like %(term)s) | ||||
and pr.user_type = "Website User" | |||||
and pr.user_image is not null and pr.enabled=1 | and pr.user_image is not null and pr.enabled=1 | ||||
and not exists(select wsp.name from `tabWebsite Sitemap Permission` wsp | and not exists(select wsp.name from `tabWebsite Sitemap Permission` wsp | ||||
where wsp.website_sitemap=%(group)s and wsp.profile=pr.name)""", | where wsp.website_sitemap=%(group)s and wsp.profile=pr.name)""", | ||||
{"term": "%{}%".format(term), "group": group}, as_dict=True) | |||||
{"term": "%{}%".format(term), "group": pathname}, as_dict=True) | |||||
template = webnotes.get_template("templates/includes/profile_display.html") | template = webnotes.get_template("templates/includes/profile_display.html") | ||||
return [{ | return [{ | ||||
"value": "{} {}".format(pr.first_name, pr.last_name), | |||||
"value": "{} {}".format(pr.first_name or "", pr.last_name or ""), | |||||
"profile_html": template.render({"profile": pr}), | "profile_html": template.render({"profile": pr}), | ||||
"profile": pr.name | "profile": pr.name | ||||
} for pr in profiles] | } for pr in profiles] | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def add_sitemap_permission(sitemap_page, profile): | |||||
if not get_access(sitemap_page).get("admin"): | |||||
def add_sitemap_permission(group, profile): | |||||
pathname = get_pathname(group) | |||||
if not get_access(pathname).get("admin"): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
permission = webnotes.bean({ | permission = webnotes.bean({ | ||||
"doctype": "Website Sitemap Permission", | "doctype": "Website Sitemap Permission", | ||||
"website_sitemap": sitemap_page, | |||||
"website_sitemap": pathname, | |||||
"profile": profile, | "profile": profile, | ||||
"read": 1 | "read": 1 | ||||
}) | }) | ||||
@@ -50,24 +46,25 @@ def add_sitemap_permission(sitemap_page, profile): | |||||
profile = permission.doc.fields | profile = permission.doc.fields | ||||
profile.update(webnotes.conn.get_value("Profile", profile.profile, | profile.update(webnotes.conn.get_value("Profile", profile.profile, | ||||
["name", "first_name", "last_name", "user_image", "fb_location", "fb_hometown"], as_dict=True)) | |||||
["name", "first_name", "last_name", "user_image", "location"], as_dict=True)) | |||||
return webnotes.get_template("templates/includes/sitemap_permission.html").render({ | return webnotes.get_template("templates/includes/sitemap_permission.html").render({ | ||||
"profile": profile | "profile": profile | ||||
}) | }) | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def update_permission(sitemap_page, profile, perm, value): | |||||
if not get_access(sitemap_page).get("admin"): | |||||
def update_permission(group, profile, perm, value): | |||||
pathname = get_pathname(group) | |||||
if not get_access(pathname).get("admin"): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
permission = webnotes.bean("Website Sitemap Permission", {"website_sitemap": sitemap_page, "profile": profile}) | |||||
permission = webnotes.bean("Website Sitemap Permission", {"website_sitemap": pathname, "profile": profile}) | |||||
permission.doc.fields[perm] = int(value) | permission.doc.fields[perm] = int(value) | ||||
permission.save(ignore_permissions=True) | permission.save(ignore_permissions=True) | ||||
# send email | # send email | ||||
if perm=="admin" and int(value): | if perm=="admin" and int(value): | ||||
group_title = webnotes.conn.get_value("Website Sitemap", sitemap_page, "page_title") | |||||
group_title = webnotes.conn.get_value("Website Sitemap", pathname, "page_title") | |||||
subject = "You have been made Administrator of Group " + group_title | subject = "You have been made Administrator of Group " + group_title | ||||
@@ -79,7 +76,7 @@ def update_permission(sitemap_page, profile, perm, value): | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def update_description(group, description): | def update_description(group, description): | ||||
if not get_access(group).get("admin"): | |||||
if not get_access(get_pathname(group)).get("admin"): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
group = webnotes.bean("Website Group", group) | group = webnotes.bean("Website Group", group) | ||||
@@ -88,7 +85,7 @@ def update_description(group, description): | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def add_website_group(group, new_group, public_read, public_write, group_type="Forum"): | def add_website_group(group, new_group, public_read, public_write, group_type="Forum"): | ||||
if not get_access(group).get("admin"): | |||||
if not get_access(get_pathname(group)).get("admin"): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
parent_website_sitemap = webnotes.conn.get_value("Website Sitemap", | parent_website_sitemap = webnotes.conn.get_value("Website Sitemap", | ||||
@@ -1,32 +0,0 @@ | |||||
<div class="small text-muted post-list-help"></div> | |||||
<div class="post-list"> | |||||
{{ post_list_html }} | |||||
</div> | |||||
<div class="text-center"> | |||||
<button class="btn btn-default btn-more hide">More</button> | |||||
</div> | |||||
<script> | |||||
$(function() { | |||||
if($(".post").length===20) { | |||||
wn.setup_pagination($(".btn-more"), { | |||||
args: { | |||||
cmd: "webnotes.templates.website_group.tasks.get_post_list_html", | |||||
limit_start: $(".post").length, | |||||
limit_length: 20, | |||||
group: website.group, | |||||
view: website.view, | |||||
status: "Closed" ? view=="closed" : undefined | |||||
}, | |||||
$wrapper: $(".post-list") | |||||
}); | |||||
} | |||||
{%- if view.name == "open" -%} | |||||
website.setup_upvote(); | |||||
website.toggle_upvote(); | |||||
{%- endif -%} | |||||
website.toggle_edit(); | |||||
}); | |||||
</script> |
@@ -1,126 +0,0 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
from __future__ import unicode_literals | |||||
import webnotes | |||||
from webnotes.utils import now_datetime, get_datetime_str | |||||
from webnotes.webutils import get_access | |||||
from webnotes.templates.website_group.settings import get_settings_context | |||||
from webnotes.templates.website_group.post import get_post_context | |||||
def get_views(): | |||||
return views | |||||
def get_context(group_context): | |||||
tasks_context = {} | |||||
if group_context.view.name in ("open", "closed"): | |||||
tasks_context["post_list_html"] = get_post_list_html(group_context["group"]["name"], group_context["view"]) | |||||
elif group_context.view.name == "edit": | |||||
post = webnotes.doc("Post", webnotes.form_dict.name).fields | |||||
tasks_context["session_user"] = webnotes.session.user | |||||
tasks_context["post"] = post | |||||
if post.assigned_to: | |||||
tasks_context["profile"] = webnotes.doc("Profile", post.assigned_to) | |||||
elif group_context.view.name == "settings": | |||||
tasks_context.update(get_settings_context(group_context)) | |||||
elif group_context.view.name == "post": | |||||
tasks_context.update(get_post_context(group_context)) | |||||
return tasks_context | |||||
@webnotes.whitelist(allow_guest=True) | |||||
def get_post_list_html(group, view, limit_start=0, limit_length=20, status="Open"): | |||||
access = get_access(group) | |||||
if isinstance(view, basestring): | |||||
view = get_views()[view] | |||||
view = webnotes._dict(view) | |||||
# verify permission for paging | |||||
if webnotes.local.form_dict.cmd == "get_post_list_html": | |||||
if not access.get("read"): | |||||
return webnotes.PermissionError | |||||
if view.name=="open": | |||||
now = get_datetime_str(now_datetime()) | |||||
order_by = "(p.upvotes + post_reply_count - (timestampdiff(hour, p.creation, \"{}\") / 2)) desc, p.creation desc".format(now) | |||||
else: | |||||
status = "Closed" | |||||
order_by = "p.creation desc" | |||||
posts = webnotes.conn.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name, | |||||
(select count(pc.name) from `tabPost` pc where pc.parent_post=p.name) as post_reply_count | |||||
from `tabPost` p, `tabProfile` pr | |||||
where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' | |||||
and p.is_task=1 and p.status=%s | |||||
order by {order_by} limit %s, %s""".format(order_by=order_by), | |||||
(group, status, int(limit_start), int(limit_length)), as_dict=True) | |||||
context = {"posts": posts, "limit_start": limit_start, "view": view} | |||||
return webnotes.get_template("templates/includes/post_list.html").render(context) | |||||
views = { | |||||
"open": { | |||||
"name": "open", | |||||
"template_path": "templates/website_group/tasks.html", | |||||
"url": "/{group}", | |||||
"label": "Open", | |||||
"icon": "icon-inbox", | |||||
"default": True, | |||||
"upvote": True, | |||||
"idx": 1 | |||||
}, | |||||
"closed": { | |||||
"name": "closed", | |||||
"template_path": "templates/website_group/tasks.html", | |||||
"url": "/{group}?view=closed", | |||||
"label": "Closed", | |||||
"icon": "icon-smile", | |||||
"idx": 2 | |||||
}, | |||||
"post": { | |||||
"name": "post", | |||||
"template_path": "templates/website_group/post.html", | |||||
"url": "/{group}?view=post&name={post}", | |||||
"label": "Post", | |||||
"icon": "icon-comments", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"upvote": True, | |||||
"idx": 3 | |||||
}, | |||||
"edit": { | |||||
"name": "edit", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{group}?view=edit&name={post}", | |||||
"label": "Edit Post", | |||||
"icon": "icon-pencil", | |||||
"hidden": True, | |||||
"no_cache": True, | |||||
"idx": 4 | |||||
}, | |||||
"add": { | |||||
"name": "add", | |||||
"template_path": "templates/website_group/edit_post.html", | |||||
"url": "/{group}?view=add", | |||||
"label": "Add Post", | |||||
"icon": "icon-plus", | |||||
"hidden": True, | |||||
"idx": 5 | |||||
}, | |||||
"settings": { | |||||
"name": "settings", | |||||
"template_path": "templates/website_group/settings.html", | |||||
"url": "/{group}?view=settings", | |||||
"label": "Settings", | |||||
"icon": "icon-cog", | |||||
"hidden": True, | |||||
"idx": 6 | |||||
} | |||||
} |
@@ -9,9 +9,6 @@ import webnotes | |||||
from webnotes.utils import get_fullname | from webnotes.utils import get_fullname | ||||
from webnotes.utils.email_lib.bulk import send | from webnotes.utils.email_lib.bulk import send | ||||
from webnotes.utils.email_lib import sendmail | from webnotes.utils.email_lib import sendmail | ||||
from webnotes.utils.file_manager import save_file | |||||
from webnotes.webutils import get_access | |||||
from webnotes.templates.generators.website_group import clear_cache | from webnotes.templates.generators.website_group import clear_cache | ||||
from webnotes.templates.website_group.post import clear_post_cache | from webnotes.templates.website_group.post import clear_post_cache | ||||
@@ -99,102 +96,3 @@ class DocType: | |||||
message += "<p><a href='/post/{post_name}'>Click here to view the post</a></p>".format(fullname=owner_fullname, | message += "<p><a href='/post/{post_name}'>Click here to view the post</a></p>".format(fullname=owner_fullname, | ||||
post_name=post_name) | post_name=post_name) | ||||
return message | return message | ||||
@webnotes.whitelist(allow_guest=True) | |||||
def add_post(group, content, picture, picture_name, title=None, parent_post=None, | |||||
assigned_to=None, status=None, event_datetime=None): | |||||
access = get_access(group) | |||||
if not access.get("write"): | |||||
raise webnotes.PermissionError | |||||
if parent_post: | |||||
if webnotes.conn.get_value("Post", parent_post, "parent_post"): | |||||
webnotes.throw("Cannot reply to a reply") | |||||
group = webnotes.doc("Website Group", group) | |||||
post = webnotes.bean({ | |||||
"doctype":"Post", | |||||
"title": (title or "").title(), | |||||
"content": content, | |||||
"website_group": group.name, | |||||
"parent_post": parent_post or None | |||||
}) | |||||
if not parent_post: | |||||
if group.group_type == "Tasks": | |||||
post.doc.is_task = 1 | |||||
post.doc.assigned_to = assigned_to | |||||
elif group.group_type == "Events": | |||||
post.doc.is_event = 1 | |||||
post.doc.event_datetime = event_datetime | |||||
post.ignore_permissions = True | |||||
post.insert() | |||||
if picture_name and picture: | |||||
process_picture(post, picture_name, picture) | |||||
# send email | |||||
if parent_post: | |||||
post.run_method("send_email_on_reply") | |||||
return post.doc.parent_post or post.doc.name | |||||
@webnotes.whitelist(allow_guest=True) | |||||
def save_post(post, content, picture=None, picture_name=None, title=None, | |||||
assigned_to=None, status=None, event_datetime=None): | |||||
post = webnotes.bean("Post", post) | |||||
access = get_access(post.doc.website_group) | |||||
if not access.get("write"): | |||||
raise webnotes.PermissionError | |||||
# TODO improve error message | |||||
if webnotes.session.user != post.doc.owner: | |||||
for fieldname in ("title", "content"): | |||||
if post.doc.fields.get(fieldname) != locals().get(fieldname): | |||||
webnotes.throw("You cannot change: {}".format(fieldname.title())) | |||||
if picture and picture_name: | |||||
webnotes.throw("You cannot change: Picture") | |||||
post.doc.fields.update({ | |||||
"title": (title or "").title(), | |||||
"content": content, | |||||
"assigned_to": assigned_to, | |||||
"status": status, | |||||
"event_datetime": event_datetime | |||||
}) | |||||
post.ignore_permissions = True | |||||
post.save() | |||||
if picture_name and picture: | |||||
process_picture(post, picture_name, picture) | |||||
return post.doc.parent_post or post.doc.name | |||||
def process_picture(post, picture_name, picture): | |||||
file_data = save_file(picture_name, picture, "Post", post.doc.name, decode=True) | |||||
post.doc.picture_url = file_data.file_name or file_data.file_url | |||||
webnotes.conn.set_value("Post", post.doc.name, "picture_url", post.doc.picture_url) | |||||
clear_cache(website_group=post.doc.website_group) | |||||
@webnotes.whitelist() | |||||
def suggest_user(group, term): | |||||
"""suggest a user that has read permission in this group tree""" | |||||
profiles = webnotes.conn.sql("""select | |||||
pr.name, pr.first_name, pr.last_name, | |||||
pr.user_image, pr.fb_location, pr.fb_hometown | |||||
from `tabProfile` pr | |||||
where (pr.first_name like %(term)s or pr.last_name like %(term)s) | |||||
and pr.name not in ("Guest", "Administrator") is not null and pr.enabled=1""", | |||||
{"term": "%{}%".format(term), "group": group}, as_dict=True) | |||||
template = webnotes.get_template("templates/includes/profile_display.html") | |||||
return [{ | |||||
"value": "{} {}".format(pr.first_name or "", pr.last_name or "").strip(), | |||||
"profile_html": template.render({"profile": pr}), | |||||
"profile": pr.name | |||||
} for pr in profiles] |
@@ -1,8 +1,6 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | # MIT License. See license.txt | ||||
# For license information, please see license.txt | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
from webnotes.webutils import get_access | from webnotes.webutils import get_access | ||||
@@ -37,7 +35,10 @@ def on_doctype_update(): | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def set_vote(ref_doctype, ref_name): | def set_vote(ref_doctype, ref_name): | ||||
website_group = webnotes.conn.get_value(ref_doctype, ref_name, "website_group") | website_group = webnotes.conn.get_value(ref_doctype, ref_name, "website_group") | ||||
if not get_access(website_group).get("read"): | |||||
pathname = webnotes.conn.get_value("Website Sitemap", {"ref_doctype": "Website Group", | |||||
"docname": website_group}) | |||||
if not get_access(pathname).get("read"): | |||||
raise webnotes.PermissionError | raise webnotes.PermissionError | ||||
try: | try: | ||||
@@ -3,8 +3,8 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
from webnotes.webutils import WebsiteGenerator, cleanup_page_name | |||||
from webnotes.templates.generators.website_group import get_context | |||||
from webnotes.webutils import WebsiteGenerator | |||||
from webnotes.templates.generators.website_group import clear_cache | |||||
from webnotes.model.doc import make_autoname | from webnotes.model.doc import make_autoname | ||||
class DocType(WebsiteGenerator): | class DocType(WebsiteGenerator): | ||||
@@ -15,4 +15,11 @@ class DocType(WebsiteGenerator): | |||||
self.doc.name = make_autoname("Website-Group-.######") | self.doc.name = make_autoname("Website-Group-.######") | ||||
def get_page_title(self): | def get_page_title(self): | ||||
return self.doc.group_title | |||||
return self.doc.group_title | |||||
def on_update(self): | |||||
WebsiteGenerator.on_update(self) | |||||
clear_cache(website_group=self.doc.name) | |||||
def after_insert(self): | |||||
clear_cache(path=self.doc.parent_website_sitemap) |
@@ -14,7 +14,7 @@ class DocType(DocListController): | |||||
def validate_home_page(self): | def validate_home_page(self): | ||||
if self.doc.home_page and \ | if self.doc.home_page and \ | ||||
not webnotes.conn.get_value("Website Sitemap", {"page_name": self.doc.home_page}): | |||||
not webnotes.conn.get_value("Website Sitemap", {"name": self.doc.home_page}): | |||||
webnotes.throw(_("Invalid Home Page") + " (Standard pages - index, login, products, blog, about, contact)") | webnotes.throw(_("Invalid Home Page") + " (Standard pages - index, login, products, blog, about, contact)") | ||||
def validate_top_bar_items(self): | def validate_top_bar_items(self): | ||||
@@ -2,13 +2,14 @@ | |||||
{ | { | ||||
"creation": "2014-01-29 17:56:29", | "creation": "2014-01-29 17:56:29", | ||||
"docstatus": 0, | "docstatus": 0, | ||||
"modified": "2014-01-29 18:05:29", | |||||
"modified": "2014-02-11 19:26:33", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"owner": "Administrator" | "owner": "Administrator" | ||||
}, | }, | ||||
{ | { | ||||
"autoname": "WSP.######", | "autoname": "WSP.######", | ||||
"doctype": "DocType", | "doctype": "DocType", | ||||
"icon": "icon-shield", | |||||
"module": "Website", | "module": "Website", | ||||
"name": "__common__" | "name": "__common__" | ||||
}, | }, | ||||
@@ -8,7 +8,7 @@ $.extend(wn, { | |||||
require: function(url) { | require: function(url) { | ||||
if(wn._assets_loaded.indexOf(url)!==-1) return; | if(wn._assets_loaded.indexOf(url)!==-1) return; | ||||
$.ajax({ | $.ajax({ | ||||
url: url, //+ "?q=" + Math.floor(Math.random() * 1000), | |||||
url: url, | |||||
async: false, | async: false, | ||||
dataType: "text", | dataType: "text", | ||||
success: function(data) { | success: function(data) { | ||||
@@ -14,24 +14,28 @@ $.extend(website, { | |||||
$(".post-list-help").html(!website.access.write ? "You do not have permission to post" : ""); | $(".post-list-help").html(!website.access.write ? "You do not have permission to post" : ""); | ||||
} | } | ||||
}, | }, | ||||
setup_pagination: function($btn, opts) { | |||||
$btn.removeClass("hide"); | |||||
$btn.on("click", function() { | |||||
wn.call($.extend({ | |||||
btn: $btn, | |||||
type: "GET", | |||||
callback: function(data) { | |||||
if(opts.prepend) { | |||||
opts.$wrapper.prepend(data.message); | |||||
} else { | |||||
opts.$wrapper.append(data.message); | |||||
setup_pagination: function() { | |||||
var $btn = $(".btn-more") | |||||
.removeClass("hide") | |||||
.on("click", function() { | |||||
wn.call({ | |||||
btn: $btn, | |||||
type: "GET", | |||||
args: { | |||||
cmd: "webnotes.templates.website_group.forum.get_post_list_html", | |||||
limit_start: $(".post").length, | |||||
limit_length: 20, | |||||
group: website.group, | |||||
view: website.view, | |||||
pathname: website.pathname | |||||
}, | |||||
callback: function(data) { | |||||
$(".post-list").append(data.message); | |||||
$btn.toggleClass("hide", !(data.message && data.message.length===opts.args.limit_length)); | |||||
website.toggle_upvote(); | |||||
} | } | ||||
$btn.toggleClass("hide", !(data.message && data.message.length===opts.args.limit_length)); | |||||
} | |||||
}, opts)) | |||||
}); | |||||
}) | |||||
}); | |||||
}, | }, | ||||
bind_add_post: function() { | bind_add_post: function() { | ||||
$(".btn-post-add").on("click", website.add_post); | $(".btn-post-add").on("click", website.add_post); | ||||
@@ -47,7 +51,7 @@ $.extend(website, { | |||||
return; | return; | ||||
} | } | ||||
website._update_post(this, "webnotes.website.doctype.post.post.add_post"); | |||||
website._update_post(this, "webnotes.templates.website_group.post.add_post"); | |||||
}, | }, | ||||
bind_save_post: function() { | bind_save_post: function() { | ||||
$(".btn-post-add").addClass("hide"); | $(".btn-post-add").addClass("hide"); | ||||
@@ -60,7 +64,7 @@ $.extend(website, { | |||||
return; | return; | ||||
} | } | ||||
website._update_post(this, "webnotes.website.doctype.post.post.save_post"); | |||||
website._update_post(this, "webnotes.templates.website_group.post.save_post"); | |||||
}, | }, | ||||
_update_post: function(btn, cmd) { | _update_post: function(btn, cmd) { | ||||
var values = website.get_editor_values(); | var values = website.get_editor_values(); | ||||
@@ -74,17 +78,11 @@ $.extend(website, { | |||||
args: $.extend({ | args: $.extend({ | ||||
cmd: cmd, | cmd: cmd, | ||||
group: website.group, | group: website.group, | ||||
post: website.post || undefined | |||||
post: website.post || undefined, | |||||
}, values), | }, values), | ||||
callback: function(data) { | callback: function(data) { | ||||
var url = window.location.pathname + "?view=post&name=" + data.message; | var url = window.location.pathname + "?view=post&name=" + data.message; | ||||
window.location.href = url; | window.location.href = url; | ||||
// if(history.pushState) { | |||||
// app.get_content(url); | |||||
// } else { | |||||
// window.location.href = url; | |||||
// } | |||||
} | } | ||||
}); | }); | ||||
}, | }, | ||||
@@ -175,7 +173,7 @@ $.extend(website, { | |||||
$post_editor.find('[data-fieldname="assigned_to"]').val(value); | $post_editor.find('[data-fieldname="assigned_to"]').val(value); | ||||
bind_close(); | bind_close(); | ||||
}, | }, | ||||
method: "webnotes.website.doctype.post.post.suggest_user" | |||||
method: "webnotes.templates.website_group.post.suggest_user" | |||||
}); | }); | ||||
bind_close(); | bind_close(); | ||||
} | } | ||||
@@ -271,7 +269,7 @@ $.extend(website, { | |||||
} | } | ||||
}, | }, | ||||
toggle_upvote: function() { | toggle_upvote: function() { | ||||
if(!website.access.read) { | |||||
if(!website.access.read || !website.upvote) { | |||||
$(".upvote").remove(); | $(".upvote").remove(); | ||||
} | } | ||||
}, | }, | ||||
@@ -279,7 +277,13 @@ $.extend(website, { | |||||
$(".post-editor").toggleClass("hide", !website.access.write); | $(".post-editor").toggleClass("hide", !website.access.write); | ||||
}, | }, | ||||
setup_upvote: function() { | setup_upvote: function() { | ||||
$(".post-list, .parent-post").on("click", ".upvote a", function() { | |||||
if(window.website.setup_upvote_done) return; | |||||
window.website.setup_upvote_done = true; | |||||
$(document).on("click", ".post-list .upvote a, .parent-post .upvote a", function() { | |||||
console.log("clicked"); | |||||
var sid = wn.get_cookie("sid"); | var sid = wn.get_cookie("sid"); | ||||
if(!sid || sid==="Guest") { | if(!sid || sid==="Guest") { | ||||
wn.msgprint("Please login to Upvote!"); | wn.msgprint("Please login to Upvote!"); | ||||
@@ -315,6 +319,8 @@ $.extend(website, { | |||||
}).always(function() { | }).always(function() { | ||||
$btn.prop("disabled", false); | $btn.prop("disabled", false); | ||||
}); | }); | ||||
return false; | |||||
}); | }); | ||||
}, | }, | ||||
setup_autosuggest: function(opts) { | setup_autosuggest: function(opts) { | ||||
@@ -490,7 +496,7 @@ $.extend(website, { | |||||
profile: $tr.attr("data-profile"), | profile: $tr.attr("data-profile"), | ||||
perm: $chk.attr("data-perm"), | perm: $chk.attr("data-perm"), | ||||
value: $chk.prop("checked") ? "1" : "0", | value: $chk.prop("checked") ? "1" : "0", | ||||
sitemap_page: website.group | |||||
group: website.group | |||||
}, | }, | ||||
statusCode: { | statusCode: { | ||||
403: function() { | 403: function() { | ||||
@@ -515,7 +521,7 @@ $.extend(website, { | |||||
data: { | data: { | ||||
cmd: "webnotes.templates.website_group.settings.add_sitemap_permission", | cmd: "webnotes.templates.website_group.settings.add_sitemap_permission", | ||||
profile: profile, | profile: profile, | ||||
sitemap_page: website.group | |||||
group: website.group | |||||
}, | }, | ||||
success: function(data) { | success: function(data) { | ||||
$(".add-user-control").val(""); | $(".add-user-control").val(""); | ||||
@@ -49,6 +49,11 @@ wn.module_page["Website"] = [ | |||||
doctype:"Blog Settings", | doctype:"Blog Settings", | ||||
route: "Form/Blog Settings" | route: "Form/Blog Settings" | ||||
}, | }, | ||||
{ | |||||
label: wn._("Website Page Permission"), | |||||
description: wn._("Define read, write, admin permissions for a Website Page."), | |||||
doctype:"Website Sitemap Permission", | |||||
}, | |||||
] | ] | ||||
}, | }, | ||||
@@ -245,10 +245,6 @@ def get_website_settings(): | |||||
context.web_include_js = hooks.web_include_js or [] | context.web_include_js = hooks.web_include_js or [] | ||||
context.web_include_css = hooks.web_include_css or [] | context.web_include_css = hooks.web_include_css or [] | ||||
# get settings from site config | |||||
if webnotes.conf.get("fb_app_id"): | |||||
context.fb_app_id = webnotes.conf.fb_app_id | |||||
return context | return context | ||||
def is_ajax(): | def is_ajax(): | ||||
@@ -330,8 +326,6 @@ class WebsiteGenerator(DocListController): | |||||
webnotes.conn.set(self.doc, self._website_config.page_name_field, page_name) | webnotes.conn.set(self.doc, self._website_config.page_name_field, page_name) | ||||
def setup_generator(self): | def setup_generator(self): | ||||
if webnotes.flags.in_install_app: | |||||
return | |||||
self._website_config = webnotes.conn.get_values("Website Sitemap Config", | self._website_config = webnotes.conn.get_values("Website Sitemap Config", | ||||
{"ref_doctype": self.doc.doctype}, "*")[0] | {"ref_doctype": self.doc.doctype}, "*")[0] | ||||
@@ -351,9 +345,6 @@ class WebsiteGenerator(DocListController): | |||||
remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name) | remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name) | ||||
def update_sitemap(self): | def update_sitemap(self): | ||||
if webnotes.flags.in_install_app: | |||||
return | |||||
self.setup_generator() | self.setup_generator() | ||||
if self._website_config.condition_field and \ | if self._website_config.condition_field and \ | ||||