##// END OF EJS Templates
codingstyle: replace upper-case variable names with lower-case ones...
codingstyle: replace upper-case variable names with lower-case ones PEP8 issues reported by flake8.

File last commit:

r6789:76912908 default
r6790:94bbb7eb default
Show More
journal.py
319 lines | 11.6 KiB | text/x-python | PythonLexer
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 # -*- coding: utf-8 -*-
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
kallithea.controllers.journal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thomas De Schampheleire
Turbogears2 migration: remove some references to Pylons in comments...
r6178 Journal controller
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Bradley M. Kuhn
RhodeCode GmbH is not the sole author of this work
r4211 This file was forked by the Kallithea project in July 2014.
Original author and date, and relevant copyright and licensing information is below:
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 :created_on: Nov 21, 2010
:author: marcink
Bradley M. Kuhn
RhodeCode GmbH is not the sole author of this work
r4211 :copyright: (c) 2013 RhodeCode GmbH, and others.
Bradley M. Kuhn
Correct licensing information in individual files....
r4208 :license: GPLv3, see LICENSE.md for more details.
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
"""
import logging
Mads Kiilerich
cleanup: avoid some 'except Exception' catching - catch specific exceptions or log it and show what happened...
r4733 import traceback
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 from itertools import groupby
from sqlalchemy import or_
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
from webob.exc import HTTPBadRequest
Mads Kiilerich
tg: minimize future diff by some mocking and replacing some pylons imports with tg...
r6508 from tg import request, tmpl_context as c, response
from tg.i18n import ugettext as _
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Thomas De Schampheleire
Turbogears2 migration: replace pylons.url by kallithea.config.routing.url...
r6182 from kallithea.config.routing import url
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 from kallithea.controllers.admin.admin import _journal_filter
from kallithea.model.db import UserLog, UserFollowing, Repository, User
from kallithea.model.meta import Session
from kallithea.model.repo import RepoModel
import kallithea.lib.helpers as h
from kallithea.lib.auth import LoginRequired, NotAnonymous
from kallithea.lib.base import BaseController, render
Thomas De Schampheleire
helpers: move Page/RepoPage to a separate file page.py...
r6215 from kallithea.lib.page import Page
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 from kallithea.lib.utils2 import safe_int, AttributeDict
log = logging.getLogger(__name__)
Mads Kiilerich
controllers: avoid setting constants as controller instance variables in __before__...
r6411 language = 'en-us'
ttl = "5"
feed_nr = 20
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 class JournalController(BaseController):
Thomas De Schampheleire
controllers: rename __before__ to _before in preparation of TurboGears2...
r6513 def _before(self, *args, **kwargs):
super(JournalController, self)._before(*args, **kwargs)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 c.search_term = request.GET.get('filter')
def _get_daily_aggregate(self, journal):
groups = []
for k, g in groupby(journal, lambda x: x.action_as_day):
user_group = []
Lars Kruse
codingstyle: trivial whitespace fixes...
r6789 # groupby username if it's a present value, else fallback to journal username
Mads Kiilerich
cleanup: various fixes, issues found with pyflakes
r4424 for _unused, g2 in groupby(list(g), lambda x: x.user.username if x.user else x.username):
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 l = list(g2)
user_group.append((l[0].user, l))
groups.append((k, user_group,))
return groups
def _get_journal_data(self, following_repos):
Søren Løvborg
db: rename UserFollowing.follows_repo_id to follows_repository_id...
r6281 repo_ids = [x.follows_repository_id for x in following_repos
if x.follows_repository_id is not None]
Søren Løvborg
cleanup: use obj.foo_id instead of obj.foo.foo_id...
r6197 user_ids = [x.follows_user_id for x in following_repos
if x.follows_user_id is not None]
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
filtering_criterion = None
if repo_ids and user_ids:
filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
UserLog.user_id.in_(user_ids))
if repo_ids and not user_ids:
filtering_criterion = UserLog.repository_id.in_(repo_ids)
if not repo_ids and user_ids:
filtering_criterion = UserLog.user_id.in_(user_ids)
if filtering_criterion is not None:
Søren Løvborg
model: remove BaseModel class...
r6483 journal = UserLog.query() \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserLog.user)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .options(joinedload(UserLog.repository))
Lars Kruse
codingstyle: trivial whitespace fixes...
r6789 # filter
Mads Kiilerich
cleanup: avoid some 'except Exception' catching - catch specific exceptions or log it and show what happened...
r4733 journal = _journal_filter(journal, c.search_term)
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 journal = journal.filter(filtering_criterion) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .order_by(UserLog.action_date.desc())
else:
journal = []
return journal
def _atom_feed(self, repos, public=True):
journal = self._get_journal_data(repos)
if public:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _link = h.canonical_url('public_journal_atom')
Mads Kiilerich
spelling: fix title casing on various translated strings...
r5127 _desc = '%s %s %s' % (c.site_name, _('Public Journal'),
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 'atom feed')
else:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _link = h.canonical_url('journal_atom')
Mads Kiilerich
spelling: fix title casing on various translated strings...
r5127 _desc = '%s %s %s' % (c.site_name, _('Journal'), 'atom feed')
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
feed = Atom1Feed(title=_desc,
link=_link,
description=_desc,
Mads Kiilerich
controllers: avoid setting constants as controller instance variables in __before__...
r6411 language=language,
ttl=ttl)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Mads Kiilerich
controllers: avoid setting constants as controller instance variables in __before__...
r6411 for entry in journal[:feed_nr]:
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 user = entry.user
if user is None:
Lars Kruse
codingstyle: trivial whitespace fixes...
r6789 # fix deleted users
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 user = AttributeDict({'short_contact': entry.username,
'email': '',
'full_contact': ''})
action, action_extra, ico = h.action_parser(entry, feed=True)
title = "%s - %s %s" % (user.short_contact, action(),
entry.repository.repo_name)
desc = action_extra()
_url = None
if entry.repository is not None:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _url = h.canonical_url('changelog_home',
repo_name=entry.repository.repo_name)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
feed.add_item(title=title,
pubdate=entry.action_date,
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 link=_url or h.canonical_url(''),
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 author_email=user.email,
author_name=user.full_contact,
description=desc)
response.content_type = feed.mime_type
return feed.writeString('utf-8')
def _rss_feed(self, repos, public=True):
journal = self._get_journal_data(repos)
if public:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _link = h.canonical_url('public_journal_atom')
Mads Kiilerich
spelling: fix title casing on various translated strings...
r5127 _desc = '%s %s %s' % (c.site_name, _('Public Journal'),
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 'rss feed')
else:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _link = h.canonical_url('journal_atom')
Mads Kiilerich
spelling: fix title casing on various translated strings...
r5127 _desc = '%s %s %s' % (c.site_name, _('Journal'), 'rss feed')
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
feed = Rss201rev2Feed(title=_desc,
link=_link,
description=_desc,
Mads Kiilerich
controllers: avoid setting constants as controller instance variables in __before__...
r6411 language=language,
ttl=ttl)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Mads Kiilerich
controllers: avoid setting constants as controller instance variables in __before__...
r6411 for entry in journal[:feed_nr]:
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 user = entry.user
if user is None:
Lars Kruse
codingstyle: trivial whitespace fixes...
r6789 # fix deleted users
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 user = AttributeDict({'short_contact': entry.username,
'email': '',
'full_contact': ''})
action, action_extra, ico = h.action_parser(entry, feed=True)
title = "%s - %s %s" % (user.short_contact, action(),
entry.repository.repo_name)
desc = action_extra()
_url = None
if entry.repository is not None:
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 _url = h.canonical_url('changelog_home',
repo_name=entry.repository.repo_name)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
feed.add_item(title=title,
pubdate=entry.action_date,
Mads Kiilerich
urls: introduce canonical_url config setting...
r4445 link=_url or h.canonical_url(''),
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 author_email=user.email,
author_name=user.full_contact,
description=desc)
response.content_type = feed.mime_type
return feed.writeString('utf-8')
@LoginRequired()
@NotAnonymous()
def index(self):
# Return a rendered template
Mads Kiilerich
controllers: simplify request.GET.get for safe_int...
r5992 p = safe_int(request.GET.get('page'), 1)
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 c.user = User.get(request.authuser.user_id)
Søren Løvborg
model: remove BaseModel class...
r6483 c.following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
journal = self._get_journal_data(c.following)
def url_generator(**kw):
return url.current(filter=c.search_term, **kw)
c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
timeless@gmail.com
spelling: aggregate
r5783 c.journal_day_aggregate = self._get_daily_aggregate(c.journal_pager)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
if request.environ.get('HTTP_X_PARTIAL_XHR'):
Thomas De Schampheleire
controllers: don't pass rendered templates in context variables...
r4850 return render('journal/journal_data.html')
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Søren Løvborg
db: add a Repository.query() shortcut
r6186 repos_list = Repository.query(sorted=True) \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter_by(owner_id=request.authuser.user_id).all()
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
admin=True)
Lars Kruse
codingstyle: trivial whitespace fixes...
r6789 # data used to render the grid
Søren Løvborg
templates: properly escape inline JavaScript values...
r6492 c.data = repos_data
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
return render('journal/journal.html')
@LoginRequired(api_access=True)
@NotAnonymous()
def journal_atom(self):
"""
Produce an atom-1.0 feed via feedgenerator module
"""
Søren Løvborg
model: remove BaseModel class...
r6483 following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
return self._atom_feed(following, public=False)
@LoginRequired(api_access=True)
@NotAnonymous()
def journal_rss(self):
"""
Produce an rss feed via feedgenerator module
"""
Søren Løvborg
model: remove BaseModel class...
r6483 following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
return self._rss_feed(following, public=False)
@LoginRequired()
@NotAnonymous()
def toggle_following(self):
Mads Kiilerich
controllers: remove old auth_token checks - it was only partial CSRF protection
r4990 user_id = request.POST.get('follows_user_id')
if user_id:
try:
self.scm_model.toggle_following_user(user_id,
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 request.authuser.user_id)
domruf
sqlalchemy: be consistent, always use Session() instead of just Session
r6578 Session().commit()
Mads Kiilerich
controllers: remove old auth_token checks - it was only partial CSRF protection
r4990 return 'ok'
except Exception:
log.error(traceback.format_exc())
raise HTTPBadRequest()
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Søren Løvborg
db: rename UserFollowing.follows_repo_id to follows_repository_id...
r6281 repo_id = request.POST.get('follows_repository_id')
Mads Kiilerich
controllers: remove old auth_token checks - it was only partial CSRF protection
r4990 if repo_id:
try:
self.scm_model.toggle_following_repo(repo_id,
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 request.authuser.user_id)
domruf
sqlalchemy: be consistent, always use Session() instead of just Session
r6578 Session().commit()
Mads Kiilerich
controllers: remove old auth_token checks - it was only partial CSRF protection
r4990 return 'ok'
except Exception:
log.error(traceback.format_exc())
raise HTTPBadRequest()
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
raise HTTPBadRequest()
@LoginRequired()
def public_journal(self):
# Return a rendered template
Mads Kiilerich
controllers: simplify request.GET.get for safe_int...
r5992 p = safe_int(request.GET.get('page'), 1)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Søren Løvborg
model: remove BaseModel class...
r6483 c.following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
journal = self._get_journal_data(c.following)
c.journal_pager = Page(journal, page=p, items_per_page=20)
timeless@gmail.com
spelling: aggregate
r5783 c.journal_day_aggregate = self._get_daily_aggregate(c.journal_pager)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
if request.environ.get('HTTP_X_PARTIAL_XHR'):
Thomas De Schampheleire
controllers: don't pass rendered templates in context variables...
r4850 return render('journal/journal_data.html')
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 return render('journal/public_journal.html')
@LoginRequired(api_access=True)
def public_journal_atom(self):
"""
Produce an atom-1.0 feed via feedgenerator module
"""
Søren Løvborg
model: remove BaseModel class...
r6483 c.following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
return self._atom_feed(c.following)
@LoginRequired(api_access=True)
def public_journal_rss(self):
"""
Produce an rss2 feed via feedgenerator module
"""
Søren Løvborg
model: remove BaseModel class...
r6483 c.following = UserFollowing.query() \
Mads Kiilerich
controllers: avoid setting request state in controller instances - set it in the thread global request variable...
r6412 .filter(UserFollowing.user_id == request.authuser.user_id) \
Mads Kiilerich
cleanup: consistent space before line continuation backslash
r5585 .options(joinedload(UserFollowing.follows_repository)) \
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 .all()
return self._rss_feed(c.following)