##// END OF EJS Templates
setup: change url to github
setup: change url to github

File last commit:

r153:32f4b641
r196:472d1df0 master
Show More
user.py
166 lines | 6.0 KiB | text/x-python | PythonLexer
# -*- coding: utf-8 -*-
# Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import pyramid_mailer
import pyramid.renderers
import sqlalchemy as sa
from collections import namedtuple
from datetime import datetime
from ziggurat_foundations.models.services.user import UserService
from appenlight.lib.rule import Rule
from appenlight.models import get_db_session
from appenlight.models.integrations import IntegrationException
from appenlight.models.report import REPORT_TYPE_MATRIX
from appenlight.models.user import User
from paginate_sqlalchemy import SqlalchemyOrmPage
from pyramid.threadlocal import get_current_registry
log = logging.getLogger(__name__)
GroupOccurence = namedtuple("GroupOccurence", ["occurences", "group"])
class UserService(UserService):
@classmethod
def all(cls, db_session=None):
return get_db_session(db_session).query(User).order_by(User.user_name)
@classmethod
def send_email(
cls, request, recipients, variables, template, immediately=False, silent=False
):
html = pyramid.renderers.render(template, variables, request)
title = variables.get("email_title", variables.get("title", "No Title"))
title = title.replace("\r", "").replace("\n", "")
sender = "{} <{}>".format(
request.registry.settings["mailing.from_name"],
request.registry.settings["mailing.from_email"],
)
message = pyramid_mailer.message.Message(
subject=title, sender=sender, recipients=recipients, html=html
)
if immediately:
try:
request.registry.mailer.send_immediately(message)
except Exception as e:
log.warning("Exception %s" % e)
if not silent:
raise
else:
request.registry.mailer.send(message)
@classmethod
def get_paginator(
cls,
page=1,
item_count=None,
items_per_page=50,
order_by=None,
filter_settings=None,
exclude_columns=None,
db_session=None,
):
registry = get_current_registry()
if not exclude_columns:
exclude_columns = []
if not filter_settings:
filter_settings = {}
db_session = get_db_session(db_session)
q = db_session.query(User)
if filter_settings.get("order_col"):
order_col = filter_settings.get("order_col")
if filter_settings.get("order_dir") == "dsc":
sort_on = "desc"
else:
sort_on = "asc"
q = q.order_by(getattr(sa, sort_on)(getattr(User, order_col)))
else:
q = q.order_by(sa.desc(User.registered_date))
# remove urlgen or it never caches count
cache_params = dict(filter_settings)
cache_params.pop("url", None)
cache_params.pop("url_maker", None)
@registry.cache_regions.redis_min_5.cache_on_arguments()
def estimate_users(cache_key):
o_q = q.order_by(False)
return o_q.count()
item_count = estimate_users(cache_params)
# if the number of pages is low we may want to invalidate the count to
# provide 'real time' update - use case -
# errors just started to flow in
if item_count < 1000:
item_count = estimate_users.refresh(cache_params)
paginator = SqlalchemyOrmPage(
q,
page=page,
item_count=item_count,
items_per_page=items_per_page,
**filter_settings
)
return paginator
@classmethod
def get_valid_channels(cls, user):
return [channel for channel in user.alert_channels if channel.channel_validated]
@classmethod
def report_notify(
cls, user, request, application, report_groups, occurence_dict, db_session=None
):
db_session = get_db_session(db_session)
if not report_groups:
return True
since_when = datetime.utcnow()
for channel in cls.get_valid_channels(user):
confirmed_groups = []
for group in report_groups:
occurences = occurence_dict.get(group.id, 1)
for action in channel.channel_actions:
not_matched = (
action.resource_id
and action.resource_id != application.resource_id
)
if action.type != "report" or not_matched:
continue
should_notify = action.action == "always" or not group.notified
rule_obj = Rule(action.rule, REPORT_TYPE_MATRIX)
report_dict = group.get_report().get_dict(request)
if rule_obj.match(report_dict) and should_notify:
item = GroupOccurence(occurences, group)
if item not in confirmed_groups:
confirmed_groups.append(item)
# send individual reports
total_confirmed = len(confirmed_groups)
if not total_confirmed:
continue
try:
channel.notify_reports(
resource=application,
user=user,
request=request,
since_when=since_when,
reports=confirmed_groups,
)
except IntegrationException as e:
log.warning("%s" % e)