def show_user(request, uid, post_type=''): "Displays posts by a user" user = models.User.objects.filter( id=uid).select_related('profile').all()[0] params = html.Params(nav='', tab='user', sort='', title="Activity for user %s" % user.profile.display_name) # notification messages.info(request, 'Filtering by user: %s' % user.profile.display_name) post_type = POST_REV_MAP.get(post_type.lower()) if post_type: posts = get_post_manager(request).filter( type=post_type, author=user).order_by('-creation_date') else: posts = get_post_manager(request).filter( type__in=POST_TOPLEVEL, author=user).order_by('-creation_date') posts = posts.select_related('author', 'author__profile', 'root') page = get_page(request, posts, per_page=20) return html.template(request, name='index.html', page=page, params=params)
def decorate(res): "Decorates search results with highlights" content = res.highlights('content') return html.Params(title=res['title'], pid=res['pid'], content=content, type=res['type'])
def new_post(request, pid=0, post_type=POST_QUESTION): "Handles the creation of a new post" user = request.user name = "post.edit.html" parent = models.Post.objects.get(pk=pid) if pid else None root = parent.root if parent else None toplevel = (pid == 0) factory = formdef.ChildContent if pid else formdef.TopLevelContent params = html.Params(tab='new', title="New post", toplevel=toplevel) if request.method == 'GET': # no incoming data, render form form = factory() return html.template(request, name=name, form=form, params=params) # process the incoming data assert request.method == 'POST', "Method=%s" % request.method form = factory(request.POST) if not form.is_valid(): # returns with an error message return html.template(request, name=name, form=form, params=params) # form is valid at this point, create the post params = dict(author=user, type=post_type, parent=parent, root=root) params.update(form.cleaned_data) with transaction.commit_on_success(): post = models.Post.objects.create(**params) post.set_tags() #post.save() return redirect(post)
def main(request): "Main search" counts = request.session.get(SESSION_POST_COUNT, {}) q = request.GET.get('q', '') # query t = request.GET.get('t', 'all') # type params = html.Params(tab='search', q=q, sort='') subset = get_subset(t) if params.q: form = SearchForm(request.GET) res = search_results(request=request, text=params.q, subset=subset) size = len(res) messages.info( request, 'Searched results for: %s found %d results' % (params.q, size)) else: form = SearchForm() res = [] page = get_page(request, res, per_page=10) return html.template(request, name='search.html', page=page, params=params, counts=counts, form=form)
def post_show(request, pid): """ Displays a post and its children """ user = request.user # populate the session data sess = middleware.Session(request) tab = "posts" pill = sess.get_tab() auth = user.is_authenticated() layout = settings.USER_PILL_BAR if auth else settings.ANON_PILL_BAR params = html.Params(tab=tab, pill=pill, layout=layout) query = get_post_manager(request) try: root = query.get(id=pid) # update the views for the question models.update_post_views(post=root, request=request, minutes=const.POST_VIEW_UPDATE) counts = sess.get_counts() except models.Post.DoesNotExist, exc: messages.warning(request, 'The post that you are looking for does not exists. Perhaps it was deleted!') return html.redirect("/")
def show_tag(request, tag_name=''): "Display posts by a certain tag" user = request.user # populate the session data sess = middleware.Session(request) # get the sort order sort_type = sess.sort_order() # parse the date request since = request.GET.get('since', DATE_FILTER[0]).lower() # select based on history tab, pill = "posts", sess.get_tab() params = html.Params(nav='', tab=tab, sort='') # the params object will carry layout = settings.USER_PILL_BAR if auth else settings.ANON_PILL_BAR # wether to show the type of the post params = html.Params(tab=tab, pill=pill, sort=sort_type, sort_choices=SORT_CHOICES, date_filter=DATE_FILTER, since=since, layout=layout, title="Tagged as %s" % tag_name) msg = 'Filtering by tag: <b>%s</b>. Subscribe to an <a href="/feeds/tag/%s/">RSS feed</a> to this tag.' % ( tag_name, tag_name) messages.info(request, msg) posts = models.query_by_tags(user=user, text=tag_name) # apply date filtering posts = filter_by_date(request=request, posts=posts, since=since) # order may change if it is invalid search posts = apply_sort(request=request, posts=posts, order=sort_type, sticky=False) page = get_page(request, posts, per_page=20) return html.template(request, name='index.html', page=page, params=params)
def google(request): "Renders the rss feed page" user = request.user params = html.Params(nav='google') return html.template(request, name='pages/google.html', params=params, user=user)
def rss(request): "Renders the rss feed page" user = request.user params = html.Params(nav='rss') return html.template(request, name='pages/rss.html', params=params, user=user)
def show_tag(request, tag_name=None): "Display posts by a certain tag" user = request.user params = html.Params(nav='', tab='tags', sort='') msg = 'Filtering by tag: <b>%s</b>. Subscribe to an <a href="/feeds/tag/%s/">RSS feed</a> to this tag.' % (tag_name,tag_name) messages.info(request, msg) posts = models.query_by_tags(user=user, text=tag_name).order_by('-rank') page = get_page(request, posts, per_page=20) return html.template( request, name='index.html', page=page, params=params)
def user_profile(request, uid, tab='activity'): "User's profile page" if not models.User.objects.filter(id=uid): messages.error(request, "This user does not exist. It has perhaps been deleted.") return html.redirect("/") user = request.user target = models.User.objects.get(id=uid) awards = [] page = None # some information is only visible to the user target.writeable = auth.authorize_user_edit(target=target, user=user, strict=False) target.showall = (target == user) params = html.Params(tab=tab, sort='') # these do not actually get executed unless explicitly rendered in the page bookmarks = models.Vote.objects.filter(author=target, type=VOTE_BOOKMARK).select_related('post', 'post__author__profile').order_by('id') awards = models.Award.objects.filter(user=target).select_related('badge').order_by('-date') # we need to collate and count the awards answer_count = models.Post.objects.filter(author=target, type=POST_ANSWER).count() question_count = models.Post.objects.filter(author=target, type=POST_QUESTION).count() comment_count = models.Post.objects.filter(author=target, type=POST_COMMENT).count() post_count = models.Post.objects.filter(author=target).count() vote_count = models.Vote.objects.filter(author=target).count() award_count = models.Award.objects.filter(user=target).count() note_count = models.Note.objects.filter(target=target, unread=True).count() bookmarks_count = models.Vote.objects.filter(author=target, type=VOTE_BOOKMARK).count() if tab == 'activity': notes = models.Note.objects.filter(target=target, type=NOTE_USER).select_related('author', 'author__profile', 'root').order_by('-date') page = get_page(request, notes, per_page=15) # we evalute it here so that subsequent status updates won't interfere page.object_list = list(page.object_list) if user==target: models.Note.objects.filter(target=target).update(unread=False) models.UserProfile.objects.filter(user=target).update(new_messages=0) note_count = 0 elif tab == 'bookmarks': bookmarks = models.Vote.objects.filter(author=target, type=VOTE_BOOKMARK).select_related('post', 'post__author__profile').order_by('-date') page = get_page(request, bookmarks, per_page=15) elif tab =="moderator": notes = models.Note.objects.filter(target=target, type=NOTE_MODERATOR).select_related('author', 'author__profile').order_by('-date') page = get_page(request, notes, per_page=15) params.update(dict(question_count=question_count, answer_count=answer_count, note_count=note_count, bookmarks_count=bookmarks_count, comment_count=comment_count, post_count=post_count, vote_count=vote_count, award_count=award_count)) return html.template(request, name='user.profile.html', awards=awards, user=request.user,target=target, params=params, page=page)
def user_list(request): search = request.GET.get('m','')[:80] # trim for sanity params = html.Params(nav='users', sort='') if search: query = Q(profile__display_name__icontains=search) else: query = Q(id__gt=0) users = models.User.objects.filter(query).select_related('profile').order_by("-profile__score") page = get_page(request, users, per_page=24) return html.template(request, name='user.list.html', page=page, params=params)
def more(request, pid): counts = request.session.get(SESSION_POST_COUNT, {}) form = SearchForm() params = html.Params(tab='search', q="", sort='') res = more_like_this(request=request, pid=pid) page = get_page(request, res, per_page=10) return html.template(request, name='search.html', page=page, params=params, counts=counts, form=form)
def badge_list(request): user = request.user badges = models.Badge.objects.filter(secret=False).order_by('-count', '-type') # set a flag for badges that a user has if user.is_authenticated(): earned = set( models.Award.objects.filter(user=user).values_list('badge__name', flat=True).distinct() ) else: earned = [] for badge in badges: badge.earned = badge.name in earned params = html.Params(nav='badges', sort='') return html.template(request, name='badge.list.html', badges=badges, params=params)
def get_context_data(self, target="", **kwargs): context = super(AdView, self).get_context_data(**kwargs) user = self.request.user layout = settings.USER_PILL_BAR params = html.Params(tab="", pill="ads", sort='', since='', layout=layout, title="Ad List") context['params'] = params context['search'] = self.get_search() return context
def more(request, pid): counts = request.session.get(SESSION_POST_COUNT, {}) form = SearchForm() params = html.Params(tab='search', q="", sort='') results = more_like_this(request=request, pid=pid) posts = Post.objects.filter( id__in=[row['pid'] for row in results]).exclude(status=POST_DELETED) for post, row in zip(posts, results): post.context = row['content'] page = get_page(request, posts, per_page=10) return html.template(request, name='search.html', page=page, params=params, counts=counts, form=form)
def tag_list(request): # remove null tags models.Tag.objects.all().filter(count=0).delete() search = request.GET.get('m','')[:80] # trim for sanity if search: query = Q(name__icontains=search) else: query = Q(id__gt=0) tags = models.Tag.objects.filter(query).order_by('name') page = get_page(request, tags, per_page=152) params = html.Params(nav='tags', sort='') return html.template(request, name='tag.list.html', page=page, params=params)
def help_external(request, word='main'): "Renders a test page" user = request.user # create a test key/value pair name = "GALAXY" pair = settings.EXTERNAL_AUTHENICATION.get(name) if pair: messages.info(request, "The <b>%s</b> key is active!" % name) key, patt = pair else: key, patt = "abcd", "" # prepare the data data = dict(display_name="Jane Doe", username="******", email="*****@*****.**", tags="galaxy bwa", title="How do I run bwa?", tool_name="Uber Convert", tool_id=1, tool_version="0.0.1.alpha", ) # encode the data and get the digest enc, digest = formdef.encode(data, key=key) # encode into url parameters store = dict(name=name, data=enc, digest=digest) # encoding the parameters into the url to be loaded params = urllib.urlencode(store.items()) login_url = "/x/?%s" % params store['action'] = 'new' params = urllib.urlencode(store.items()) post_url = "/x/?%s" % params # override login_url = "http://test.biostars.org" + login_url post_url = "http://test.biostars.org" + post_url # this is used inside the templates params = html.Params(post_url=post_url, login_url=login_url, key=key, data=data, enc=enc, digest=digest) return html.template(request, name='help/help.external.html', params=params, user=user)
def post_edit(request, pid=0): "Handles the editing of an existing post" user = request.user name = "post.edit.html" post = models.Post.objects.get(pk=pid) if not post.open and not user.can_moderate: messages.error(request, 'Post is closed. It may not be edited.') return redirect(post.root) # verify that this user may indeed modify the post if not auth.authorize_post_edit(post=post, user=request.user, strict=False): messages.error(request, 'User may not edit the post.') return redirect(post.root) toplevel = post.top_level factory = formdef.TopLevelContent if toplevel else formdef.ChildContent params = html.Params(tab='edit', title="Edit post", toplevel=toplevel) if request.method == 'GET': # no incoming data, render prefilled form form = factory(initial=dict(title=post.title, content=post.content, tag_val=post.tag_val, type=post.type, context=post.context)) return html.template(request, name=name, form=form, params=params) # process the incoming data assert request.method == 'POST', "Method=%s" % request.method form = factory(request.POST) if not form.is_valid(): # returns with an error message return html.template(request, name=name, form=form, params=params) # form is valid now set the attributes for key, value in form.cleaned_data.items(): setattr(post, key, value) post.lastedit_user = user post.lastedit_date = datetime.now() post.set_tags() # this saves the post return redirect(post)
def testpage(request): "Renders a test page" user = request.user params = html.Params(nav='rss') posts = models.Post.objects posts = posts.exclude(type=POST_BLOG).select_related( 'author', 'author__profile') posts = posts.order_by('-rank')[:10] posts = list(posts) rows = connection.queries return html.template(request, name='pages/testpage.html', params=params, user=user, rows=rows)
def get_context_data(self, **kwargs): context = super(MessageView, self).get_context_data(**kwargs) user = self.request.user note_types = [NOTE_USER, NOTE_PRIVATE] q = Q(target=user, type__in=note_types) e = Q(sender=user, type=NOTE_USER) notes = models.Note.objects.filter(q).exclude(e) notes = notes.select_related('author', 'author__profile').order_by('-date') page = html.get_page(request=self.request, obj_list=notes, per_page=25) # evaluate the query here so that the unread status is kept page.object_list = list(page.object_list) # reset the counts models.Note.objects.filter(target=user, unread=True).update(unread=False) models.UserProfile.objects.filter(user=user).update(new_messages=0) sess = middleware.Session(self.request) counts = sess.get_counts("message_count") sess.save() # the params object will carry layout = settings.USER_PILL_BAR params = html.Params(tab="", pill="messages", sort='', since='', layout=layout, title="Your Messages") context['page'] = page context['params'] = params context['counts'] = counts return context
def request_info(request, pid): "Requests information from a source" user = request.user post = models.Post.objects.get(id=pid) params = html.Params(site_domain=settings.SITE_DOMAIN, user=user, post=post) params.subject = "Your expert advice is needed at Biostar" if user.is_authenticated(): params.display_name, score = user.profile.display_name, user.profile.score else: params.display_name, score = "Anonymous", 0 params.body = html.fill(name='pages/request-info.txt', params=params) LIMIT = 5 disabled = score < LIMIT if disabled: messages.error( request, "Note: users with fewer than %s reputation points may not send messages via Biostar. You have %s points" % (LIMIT, score)) elif 'submit' in request.POST: form = formdef.RequestInfo(request.POST) if form.is_valid(): send_mail(params.subject, params.body, settings.DEFAULT_FROM_EMAIL, [form.cleaned_data['email']], fail_silently=False) messages.info(request, "Your message has been sent.") return html.redirect(post.get_absolute_url()) else: messages.error(request, "%s" % form.errors) return html.template(request, name='pages/request-info.html', params=params)
def new_post(request, pid=0, post_type=POST_QUESTION, data=None): "Handles the creation of a new post" user = request.user name = "post.edit.html" parent = models.Post.objects.get(pk=pid) if pid else None root = parent.root if parent else None toplevel = (pid == 0) factory = formdef.ChildContent if pid else formdef.TopLevelContent params = html.Params(tab='new', title="New post", toplevel=toplevel, data=data) extern = formdef.ExternalLogin(request.GET) if extern.is_valid(): e = extern.cleaned_data['data'] context = safe_context(extern.cleaned_data['name'], e) tag_val = e.get("tags", "") title = e.get("title", "") form = factory( initial=dict(tag_val=tag_val, context=context, title=title)) return html.template(request, name=name, form=form, params=params) if request.method == 'GET': # no incoming data, render form form = factory() return html.template(request, name=name, form=form, params=params) # polls can only have comments associated with the root is_poll = root and root.type == POST_POLL is_author = root and root.author == user is_root_comment = (post_type == POST_COMMENT) and (parent == root) if is_poll and not is_author and not is_root_comment: messages.error( request, "Polls are special content. Users other than the author of the poll may only create comments directly associated with the top post." ) return redirect(root) # process the incoming data assert request.method == 'POST', "Method=%s" % request.method form = factory(request.POST) # applying some throttles here now = datetime.now() # minimum age trust_range = timedelta(hours=settings.TRUST_INTERVAL) # a user that joined six hours ago new_user = (now - user.date_joined) < trust_range # posts within a trust interval post_count = models.Post.objects.filter(author=user, creation_date__gt=now - trust_range).count() # how many posts are too many too_many = (post_count >= settings.TRUST_NEW_USER_MAX_POST ) if new_user else post_count >= settings.TRUST_USER_MAX_POST # different error messages for different type of users if new_user and too_many: messages.error( request, """ Brand new users (accounts less than %s hours old) may not create more than %s posts.<br> Apologies if that interferes with your usage, it is an anti-spam measure.<br> Gives us a chance to ban the spam bots before too long. This limitation is lifted later. """ % (settings.TRUST_INTERVAL, settings.TRUST_NEW_USER_MAX_POST)) return html.template(request, name=name, form=form, params=params) # this is main user throttling if too_many: messages.error( request, """ A user may only create %s posts within a six hour period.<br> This is to protect against runaway bots.<br> Sorry for any inconvenience this may cause. """ % settings.TRUST_USER_MAX_POST) return html.template(request, name=name, form=form, params=params) if not form.is_valid(): # returns with an error message return html.template(request, name=name, form=form, params=params) # form is valid at this point, create the post params = dict(author=user, type=post_type, parent=parent, root=root) # form may contain a variable number of elements for attr in "title content tag_val type context".split(): if attr in form.cleaned_data: params[attr] = form.cleaned_data[attr] with transaction.commit_on_success(): post = models.Post.objects.create(**params) post.set_tags() return redirect(post)
def process_exception(self, request, exc): path = request.path params = html.Params(exc=exc, path=path) return html.template(request, name='500.html', params=params)
def beta(request): "Renders the beta test information page" params = html.Params(nav='') return html.template(request, name='pages/beta.html', params=params)
def index(request, tab='all'): user = request.user auth = user.is_authenticated() # asking for an invalid tab if tab not in VALID_TABS: msg = html.sanitize('Unknown content type "%s"' % tab) messages.error(request, msg) return html.redirect("/") # populate the session data sess = middleware.Session(request) # get the sort order sort_type = sess.sort_order() # set the last active tab sess.set_tab(tab) # get the numerical value for these posts post_type = POST_TYPE_MAP.get(tab, tab) # override the sort order if the content so requires sort_type = 'creation' if tab == 'recent' else sort_type # the params object will carry layout = settings.USER_PILL_BAR if auth else settings.ANON_PILL_BAR # wether to show the type of the post show_type = post_type in ('all', 'recent') if tab in VALID_PILLS: tab, pill = "posts", tab else: tab, pill = tab, "" params = html.Params(tab=tab, pill=pill, sort=sort_type, sort_choices=SORT_CHOICES, layout=layout, show_type=show_type, title="Bioinformatics Answers") # this will fill in the query (q) and the match (m)parameters params.parse(request) # returns the object manager that contains all or only visible posts posts = get_post_manager(request) # filter posts by type posts = filter_by_type(request=request, posts=posts, post_type=post_type) # sticky is not active on recent and all pages sticky = (tab != 'recent') and (pill != 'all') # order may change if it is invalid search posts = apply_sort(request=request, posts=posts, order=sort_type, sticky=sticky) # this is necessary because the planet posts require more attributes if tab == 'planet': models.decorate_posts(posts, request.user) # get the counts for the session counts = sess.get_counts(post_type) page = get_page(request, posts, per_page=POSTS_PER_PAGE) # save the session sess.save() # try to set a more informative title title_map = dict(questions="Bioinformatics Questions", unanswered="Unanswered Questions", tutorials="Bioinformatics Tutorials", jobs="Bioinformatics Jobs", videos="Bioinformatics Videos", news='Bioinformatics News', tools="Bioinformatics Tools", recent="Recent bioinformatics posts", planet="Bioinformatics Planet") params.title = title_map.get(tab, params.title) return html.template(request, name='index.html', page=page, params=params, counts=counts)
def faq(request): "Renders the faq page" best = models.User.objects.all().select_related("profile").order_by( '-profile__score')[:3] params = html.Params(nav='faq', best=best) return html.template(request, name='pages/faq.html', params=params)
def testpage(request): "Renders a test page" user = request.user params = html.Params() return html.template(request, name='pages/testpage.html', params=params, user=user)
mods = models.User.objects.filter( profile__type=USER_MODERATOR).select_related("profile").order_by( '-profile__score').all() admins = models.User.objects.filter( profile__type=USER_ADMIN).select_related("profile").order_by( '-profile__score').all() managers = models.User.objects.filter( email=settings.ADMINS[0][1]).select_related("profile").order_by( '-profile__score').all() navloc = dict(about="active") params = html.Params(nav='about', post_count=post_count, user_count=user_count, question_count=question_count, answer_count=answer_count, comment_count=comment_count, admins=admins, mods=mods, navloc=navloc, managers=managers, visitors=visitors) return html.template(request, name='pages/about.html', params=params) def rss(request): "Renders the rss feed page" user = request.user params = html.Params(nav='rss') return html.template(request, name='pages/rss.html',
fill = dict( domain=settings.SITE_DOMAIN, master_id=master.id, remove_id=remove.id, master_name = master.profile.display_name, remove_name=remove.profile.display_name, master_email = master.email, remove_email=remove.email, request_id = request.user.id, request_name = user.profile.display_name, ) body = ACCOUNT_MERGE_EMAIL % fill logger.info('sending email to %s' % settings.SERVER_EMAIL) send_mail(subject='BioStar: account merge request', message=body, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=[ settings.DEFAULT_FROM_EMAIL ], fail_silently=False) messages.info(request, "Your request for account merge has been submitted for review.") return html.redirect( user.profile.get_absolute_url() ) except Exception, exc: messages.error(request, 'Submission error %s' % exc) else: form = MergeForm() params = html.Params(nav='') return html.template(request, name='pages/merge.html', params=params, form=form) def migrate(master, remove): "Migrates user data" UserOpenID.objects.filter(user=remove).update(user=master) models.Vote.objects.filter(author=remove).update(author=master) models.Note.objects.filter(sender=remove).update(sender=master) models.Note.objects.filter(target=remove).update(target=master) models.Post.objects.filter(author=remove).update(author=master) models.Post.objects.filter(lastedit_user=remove).update(lastedit_user=master) models.PostRevision.objects.filter(author=remove).update(author=master) models.Award.objects.filter(user=remove).update(user=master) master.profile.score += remove.profile.score
def index(request, tab=""): "Main page" user = request.user if not tab: # if the user has a mytags then switch to that if user.is_authenticated() and user.profile.my_tags: tab = 'mytags' else: tab = 'questions' if tab not in VALID_TABS: messages.error(request, 'Unknown content type requested') params = html.Params(tab=tab) # this will fill in the query (q) and the match (m)parameters params.parse(request) # update with counts counts = request.session.get(SESSION_POST_COUNT, {}) # returns the object manager that contains all or only visible posts posts = get_post_manager(request) # filter posts by type posts = filter_by_type(posts=posts, value=tab) # sort selected in the dropdown. by default lists cannot be sorted sort = request.GET.get('sort', '').lower() # attempts to remeber the last sorting sort = get_last_sort(request, sort) # override sort in the recent tab if tab == 'recent': sort = 'creation' posts = posts.order_by('-creation_date') else: posts = apply_sort(posts, value=sort, request=request) if tab == 'planet': models.decorate_posts(posts, user) if tab == 'mytags': if user.is_authenticated(): text = user.profile.my_tags if not text: messages.warning(request, "This Tab will show posts matching the My Tags fields in your user profile.") else: messages.info(request, "Filtering by %s" % text) posts = models.query_by_tags(user,text=text) posts = apply_sort(posts, value=sort, request=request) else: messages.warning(request, "This Tab is populated only for registered users based on the My Tags field in their user profile") posts = [] sort_choices = "rank,views,votes,answers,bookmarks,creation,edit".split(',') # put sort options in params so they can be displayed params.update(dict(sort=sort, sort_choices=sort_choices)) # reset the counts update_counts(request, tab, 0) page = get_page(request, posts, per_page=POSTS_PER_PAGE) return html.template(request, name='index.html', page=page, params=params, counts=counts)