<commit_before>#!/usr/bin/env python
# Copyright 2015 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import difflib
import fnmatch
import logging
import os
import re
import shlex
import subprocess
import sys
import time

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT_DIR = os.path.dirname(SCRIPT_DIR)
DEFAULT_PNACL_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'pnacl-opt-assert')
logger = logging.getLogger(__name__)

class Error(Exception):
  pass

def AsList(value):
  if value is None:
    return []
  elif type(value) is list:
    return value
  else:
    return [value]

def Indent(s, spaces):
  return ''.join(' '*spaces + l for l in s.splitlines(1))

def DiffLines(expected, actual):
  expected_lines = expected.splitlines(1)
  actual_lines = actual.splitlines(1)
  return list(difflib.unified_diff(expected_lines, actual_lines,
                                   fromfile='expected', tofile='actual'))

def FindTestFiles(directory, ext, filter_pattern_re):
  tests = []
  for root, dirs, files in os.walk(directory):
    for f in files:
      path = os.path.join(root, f)
      if os.path.splitext(f)[1] == ext:
        tests.append(os.path.relpath(path, SCRIPT_DIR))
  tests.sort()
  return [test for test in tests if re.match(filter_pattern_re, test)]

class TestInfo(object):
  def __init__(self):
    self.name = ''
    self.header_lines = []
    self.stdout_file = None
    self.expected_stdout = ''
    self.expected_stderr = ''
    self.exe = ''
    self.pexe = ''
    self.flags = []
    self.args = []
    self.expected_error = 0
    self.cmd = []
    self.slow = False

  def Parse(self, filename):
    self.name = filename

    with open(filename) as f:
      seen_keys = set()
      state = 'header'
      empty = True
      header_lines = []
      stdout_lines = []
      stderr_lines = []
      for line in f.readlines():
        empty = False
        m = re.match(r'\s*#(.*)$', line)
        if m:
          if state == 'stdout':
            raise Error('unexpected directive in STDOUT block: %s' % line)

          directive = m.group(1).strip()
          if directive.lower() == 'stdout:':
            if 'stdout_file' in seen_keys:
              raise Error('can\'t have stdout section and stdout file')
            state = 'stdout'
            continue

          if state != 'header':
            raise Error('unexpected directive: %s' % line)

          key, value = directive.split(':')
          key = key.strip().lower()
          value = value.strip()
          if key in seen_keys:
            raise Error('%s already set' % key)
          seen_keys.add(key)
          if key == 'exe':
            self.exe = value
          elif key == 'flags':
            self.flags = shlex.split(value)
          elif key == 'file':
            self.pexe = value
          elif key == 'error':
            self.expected_error = int(value)
          elif key == 'args':
            self.args = shlex.split(value)
          elif key == 'stdout_file':
            self.stdout_file = value
            with open(self.stdout_file) as s:
              self.expected_stdout = s.read()
          elif key == 'slow':
            self.slow = True
          else:
            raise Error('Unknown directive: %s' % key)
        elif state == 'header':
          state = 'stderr'

        if state == 'header':
          header_lines.append(line)
        elif state == 'stderr':
          stderr_lines.append(line)
        elif state == 'stdout':
          stdout_lines.append(line)
    if empty:
      raise Error('empty test file')

    self.header = ''.join(header_lines)
    if not self.stdout_file:
      self.expected_stdout = ''.join(stdout_lines)
    self.expected_stderr = ''.join(stderr_lines)

  def GetWithOverride(self, name, override, default=None):
    value = default
    if name in override:
      value = override[name]
    elif getattr(self, name):
      value = getattr(self, name)
    return value

  def Run(self, override):
    cmd = ['pnacl']
    cmd += self.GetWithOverride('flags', override)
    cmd += AsList(self.GetWithOverride('pexe', override))
    cmd += ['--'] + AsList(self.GetWithOverride('args', override))
    exe = self.GetWithOverride('exe', override, self.exe)

    # self.cmd is displayed to the user as a command that can reproduce the
    # bug. So it should display the executable that was actually run.
    self.cmd = [exe] + cmd[1:]
    try:
      start_time = time.time()
      process = subprocess.Popen(cmd, executable=exe, stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE)
      stdout, stderr = process.communicate()
      duration = time.time() - start_time
    except OSError as e:
      raise Error(str(e))

    return stdout, stderr, process.returncode, duration

  def Rebase(self, stdout, stderr):
    with open(self.name, 'w') as f:
      f.write(self.header)
      f.write(stderr)
      if self.stdout_file:
        with open(self.stdout_file, 'w') as s:
          s.write(stdout)
      elif stdout:
        f.write('# STDOUT:\n')
        f.write(stdout)

  def Diff(self, stdout, stderr):
    if self.expected_stderr != stderr:
      diff_lines = DiffLines(self.expected_stderr, stderr)
      raise Error('stderr mismatch:\n' + ''.join(diff_lines))

    if self.expected_stdout != stdout:
      if self.stdout_file:
        raise Error('stdout binary mismatch')
      else:
        diff_lines = DiffLines(self.expected_stdout, stdout)
        raise Error('stdout mismatch:\n' + ''.join(diff_lines))

def PrintStatus(passed, failed, start_time, incremental):
  total_duration = time.time() - start_time
  if incremental:
    sys.stderr.write('\r')
  status = '[+%d|-%d] (%.2fs)' % (passed, failed, total_duration)
  PrintStatus.last_status_length = len(status)
  sys.stderr.write(status)
  if not incremental:
    sys.stderr.write('\n')
  sys.stderr.flush()

PrintStatus.last_status_length = 0

def ClearStatus():
  sys.stderr.write('\r%s\r' % (' ' * PrintStatus.last_status_length))

def main(args):
  parser = argparse.ArgumentParser()
  parser.add_argument('-e', '--executable', help='override executable.',
                      default=DEFAULT_PNACL_EXE)
  parser.add_argument('-v', '--verbose', help='print more diagnotic messages. '
                      'Use more than once for more info.', action='count')
  parser.add_argument('-l', '--list', help='list all tests.',
                      action='store_true')
  parser.add_argument('-r', '--rebase',
                      help='rebase a test to its current output.',
                      action='store_true')
  parser.add_argument('-s', '--slow', help='run slow tests.',
                      action='store_true')
  parser.add_argument('patterns', metavar='pattern', nargs='*',
                      help='test patterns.')
  options = parser.parse_args(args)

  if options.patterns:
    pattern_re = '|'.join(fnmatch.translate('*%s*' % p)
                          for p in options.patterns)
  else:
    pattern_re = '.*'

  if options.verbose >= 2:
    level=logging.DEBUG
  elif options.verbose:
    level=logging.INFO
  else:
    level=logging.WARNING
  logging.basicConfig(level=level, format='%(message)s')

  tests = FindTestFiles(SCRIPT_DIR, '.txt', pattern_re)
  if options.list:
    for test in tests:
      print test
    return 0

  override = {}
  if options.executable:
    if not os.path.exists(options.executable):
      parser.error('executable %s does not exist' % options.executable)
    # We always run from SCRIPT_DIR, but allow the user to pass in executables
    # with a relative path from where they ran run-tests.py
    override['exe'] = os.path.relpath(
        os.path.join(os.getcwd(), options.executable), SCRIPT_DIR)

  os.chdir(SCRIPT_DIR)

  isatty = os.isatty(1)
  short_display = not logger.isEnabledFor(logging.INFO)

  passed = 0
  failed = 0
  start_time = time.time()
  for test in tests:
    info = TestInfo()
    try:
      info.Parse(test)
      if not options.slow and info.slow:
        logger.info('. %s (skipped)' % info.name)
        continue

      stdout, stderr, returncode, duration = info.Run(override)
      if returncode != info.expected_error:
        # This test has already failed, but diff it anyway.
        msg = 'expected error code %d, got %d.' % (info.expected_error,
                                                   returncode)
        try:
          info.Diff(stdout, stderr)
        except Error as e:
          msg += '\n' + str(e)

        raise Error(msg)

      if options.rebase:
        info.Rebase(stdout, stderr)
      else:
        info.Diff(stdout, stderr)

      passed += 1
      logger.info('+ %s (%.3fs)' % (info.name, duration))
    except Error as e:
      failed += 1
      msg = ''
      if logger.isEnabledFor(logging.DEBUG) and info.cmd:
        msg += Indent('cmd = %s\n' % ' '.join(info.cmd), 2)
      msg += Indent(str(e), 2)
      if short_display:
        ClearStatus()
      logger.error('- %s\n%s' % (info.name, msg))

    if short_display:
      PrintStatus(passed, failed, start_time, True)

  if not short_display:
    PrintStatus(passed, failed, start_time, False)
  else:
    sys.stderr.write('\n')

  if failed:
    return 1
  return 0

if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except Error as e:
    sys.stderr.write(str(e) + '\n')
    sys.exit(1)
<commit_msg>Slightly nicer output from run-tests<commit_after>#!/usr/bin/env python
# Copyright 2015 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import difflib
import fnmatch
import logging
import os
import re
import shlex
import subprocess
import sys
import time

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT_DIR = os.path.dirname(SCRIPT_DIR)
DEFAULT_PNACL_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'pnacl-opt-assert')
logger = logging.getLogger(__name__)

class Error(Exception):
  pass

def AsList(value):
  if value is None:
    return []
  elif type(value) is list:
    return value
  else:
    return [value]

def Indent(s, spaces):
  return ''.join(' '*spaces + l for l in s.splitlines(1))

def DiffLines(expected, actual):
  expected_lines = expected.splitlines(1)
  actual_lines = actual.splitlines(1)
  return list(difflib.unified_diff(expected_lines, actual_lines,
                                   fromfile='expected', tofile='actual'))

def FindTestFiles(directory, ext, filter_pattern_re):
  tests = []
  for root, dirs, files in os.walk(directory):
    for f in files:
      path = os.path.join(root, f)
      if os.path.splitext(f)[1] == ext:
        tests.append(os.path.relpath(path, SCRIPT_DIR))
  tests.sort()
  return [test for test in tests if re.match(filter_pattern_re, test)]

class TestInfo(object):
  def __init__(self):
    self.name = ''
    self.header_lines = []
    self.stdout_file = None
    self.expected_stdout = ''
    self.expected_stderr = ''
    self.exe = ''
    self.pexe = ''
    self.flags = []
    self.args = []
    self.expected_error = 0
    self.slow = False

  def Parse(self, filename):
    self.name = filename

    with open(filename) as f:
      seen_keys = set()
      state = 'header'
      empty = True
      header_lines = []
      stdout_lines = []
      stderr_lines = []
      for line in f.readlines():
        empty = False
        m = re.match(r'\s*#(.*)$', line)
        if m:
          if state == 'stdout':
            raise Error('unexpected directive in STDOUT block: %s' % line)

          directive = m.group(1).strip()
          if directive.lower() == 'stdout:':
            if 'stdout_file' in seen_keys:
              raise Error('can\'t have stdout section and stdout file')
            state = 'stdout'
            continue

          if state != 'header':
            raise Error('unexpected directive: %s' % line)

          key, value = directive.split(':')
          key = key.strip().lower()
          value = value.strip()
          if key in seen_keys:
            raise Error('%s already set' % key)
          seen_keys.add(key)
          if key == 'exe':
            self.exe = value
          elif key == 'flags':
            self.flags = shlex.split(value)
          elif key == 'file':
            self.pexe = value
          elif key == 'error':
            self.expected_error = int(value)
          elif key == 'args':
            self.args = shlex.split(value)
          elif key == 'stdout_file':
            self.stdout_file = value
            with open(self.stdout_file) as s:
              self.expected_stdout = s.read()
          elif key == 'slow':
            self.slow = True
          else:
            raise Error('Unknown directive: %s' % key)
        elif state == 'header':
          state = 'stderr'

        if state == 'header':
          header_lines.append(line)
        elif state == 'stderr':
          stderr_lines.append(line)
        elif state == 'stdout':
          stdout_lines.append(line)
    if empty:
      raise Error('empty test file')

    self.header = ''.join(header_lines)
    if not self.stdout_file:
      self.expected_stdout = ''.join(stdout_lines)
    self.expected_stderr = ''.join(stderr_lines)

  def GetWithOverride(self, name, override, default=None):
    value = default
    if name in override:
      value = override[name]
    elif getattr(self, name):
      value = getattr(self, name)
    return value

  def GetExecutable(self, override):
    return self.GetWithOverride('exe', override, self.exe)

  def GetCommand(self, override, exe=None):
    if exe is None:
      exe = self.GetExecutable(override)
    cmd = [exe]
    cmd += self.GetWithOverride('flags', override)
    cmd += AsList(self.GetWithOverride('pexe', override))
    cmd += ['--'] + AsList(self.GetWithOverride('args', override))
    return cmd

  def Run(self, override):
    # Pass 'pnacl' as the executable name so the output is consistent
    cmd = self.GetCommand(override, 'pnacl')
    exe = self.GetExecutable(override)
    try:
      start_time = time.time()
      process = subprocess.Popen(cmd, executable=exe, stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE)
      stdout, stderr = process.communicate()
      duration = time.time() - start_time
    except OSError as e:
      raise Error(str(e))

    return stdout, stderr, process.returncode, duration

  def Rebase(self, stdout, stderr):
    with open(self.name, 'w') as f:
      f.write(self.header)
      f.write(stderr)
      if self.stdout_file:
        with open(self.stdout_file, 'w') as s:
          s.write(stdout)
      elif stdout:
        f.write('# STDOUT:\n')
        f.write(stdout)

  def Diff(self, stdout, stderr):
    if self.expected_stderr != stderr:
      diff_lines = DiffLines(self.expected_stderr, stderr)
      raise Error('stderr mismatch:\n' + ''.join(diff_lines))

    if self.expected_stdout != stdout:
      if self.stdout_file:
        raise Error('stdout binary mismatch')
      else:
        diff_lines = DiffLines(self.expected_stdout, stdout)
        raise Error('stdout mismatch:\n' + ''.join(diff_lines))

def PrintStatus(passed, failed, start_time, incremental):
  total_duration = time.time() - start_time
  if incremental:
    sys.stderr.write('\r')
  status = '[+%d|-%d] (%.2fs)' % (passed, failed, total_duration)
  PrintStatus.last_status_length = len(status)
  sys.stderr.write(status)
  if not incremental:
    sys.stderr.write('\n')
  sys.stderr.flush()

PrintStatus.last_status_length = 0

def ClearStatus():
  sys.stderr.write('\r%s\r' % (' ' * PrintStatus.last_status_length))

def main(args):
  parser = argparse.ArgumentParser()
  parser.add_argument('-e', '--executable', help='override executable.',
                      default=DEFAULT_PNACL_EXE)
  parser.add_argument('-v', '--verbose', help='print more diagnotic messages. '
                      'Use more than once for more info.', action='count')
  parser.add_argument('-l', '--list', help='list all tests.',
                      action='store_true')
  parser.add_argument('-r', '--rebase',
                      help='rebase a test to its current output.',
                      action='store_true')
  parser.add_argument('-s', '--slow', help='run slow tests.',
                      action='store_true')
  parser.add_argument('patterns', metavar='pattern', nargs='*',
                      help='test patterns.')
  options = parser.parse_args(args)

  if options.patterns:
    pattern_re = '|'.join(fnmatch.translate('*%s*' % p)
                          for p in options.patterns)
  else:
    pattern_re = '.*'

  if options.verbose >= 2:
    level=logging.DEBUG
  elif options.verbose:
    level=logging.INFO
  else:
    level=logging.WARNING
  logging.basicConfig(level=level, format='%(message)s')

  tests = FindTestFiles(SCRIPT_DIR, '.txt', pattern_re)
  if options.list:
    for test in tests:
      print test
    return 0

  override = {}
  if options.executable:
    if not os.path.exists(options.executable):
      parser.error('executable %s does not exist' % options.executable)
    # We  allow the user to pass in executables with a relative path from where
    # they ran run-tests.py
    override['exe'] = os.path.relpath(options.executable, SCRIPT_DIR)

  run_cwd = os.getcwd()
  os.chdir(SCRIPT_DIR)

  isatty = os.isatty(1)
  short_display = not logger.isEnabledFor(logging.INFO)

  passed = 0
  failed = 0
  failed_tests = []
  start_time = time.time()
  for test in tests:
    info = TestInfo()
    try:
      info.Parse(test)
      if not options.slow and info.slow:
        logger.info('. %s (skipped)' % info.name)
        continue

      stdout, stderr, returncode, duration = info.Run(override)
      if returncode != info.expected_error:
        # This test has already failed, but diff it anyway.
        msg = 'expected error code %d, got %d.' % (info.expected_error,
                                                   returncode)
        try:
          info.Diff(stdout, stderr)
        except Error as e:
          msg += '\n' + str(e)

        raise Error(msg)

      if options.rebase:
        info.Rebase(stdout, stderr)
      else:
        info.Diff(stdout, stderr)

      passed += 1
      logger.info('+ %s (%.3fs)' % (info.name, duration))
    except Error as e:
      failed_tests.append(test)
      failed += 1
      msg = ''
      cmd = info.GetCommand(override)
      msg += Indent(str(e), 2)
      if short_display:
        ClearStatus()
      logger.error('- %s\n%s' % (info.name, msg))

    if short_display:
      PrintStatus(passed, failed, start_time, True)

  if short_display:
    ClearStatus()

  ret = 0

  if failed:
    logging.error('**** FAILED %s' % ('*' * (80 - 14)))
    for test in failed_tests:
      msg = Indent('cmd = (cd %s && %s)\n' % (
          os.path.relpath(SCRIPT_DIR, run_cwd), ' '.join(cmd)), 2)
      msg += Indent('rerun = %s\n' % ' '.join(
          [sys.executable, sys.argv[0], '-e', options.executable, test]), 2)
      logger.error('- %s\n%s' % (test, msg))
    ret = 1

  PrintStatus(passed, failed, start_time, False)
  return ret

if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except Error as e:
    sys.stderr.write(str(e) + '\n')
    sys.exit(1)
<|endoftext|>


<commit_before>import numpy as np
from skge.base import Model, PairwiseStochasticTrainer
from skge.util import grad_sum_matrix, unzip_triples
from skge.param import ParamInit, normalize

class TransE(Model):

    def __init__(self, *args, **kwargs):
        super(TransE, self).__init__(*args, **kwargs)
        self.sz = args[0]
        self.ncomp = args[1]
        self.l1 = kwargs.pop('l1', True)

    def __getstate__(self):
        st = super(TransE, self).__getstate__()
        st.update({
            'sz': self.sz,
            'ncomp': self.ncomp,
            'E': self.E,
            'R': self.R,
            'l1': self.l1
        })
        return st

    def _scores(self, ss, ps, os):
        if self.l1:
            score = np.abs(self.E[ss] + self.R[ps] - self.E[os])
        else:
            score = (self.E[ss] + self.R[ps] - self.E[os]) ** 2
        return -np.sum(score, axis=1)

    def _init_factors(self, xs, ys):
        pinit = ParamInit(self.init)
        self.E = pinit((self.sz[0], self.ncomp))
        self.R = pinit((self.sz[2], self.ncomp))
        self.E = normalize(self.E)
        self.R = normalize(self.R)

        self.ups = [
            self.param_updater(self.E, self.learning_rate, normalize),
            self.param_updater(self.R, self.learning_rate)
        ]

    def _batch_step(self, res):
        ge, gr, eidx, ridx = res
        self.ups[0](ge, eidx)
        self.ups[1](gr, ridx)

class PairwiseStochasticTransE(TransE, PairwiseStochasticTrainer):

    def _batch_gradients(self, pxs, nxs):
        # indices of positive triples
        sp, pp, op = unzip_triples(pxs)
        # indices of negative triples
        sn, pn, on = unzip_triples(nxs)

        pscores = self._scores(sp, pp, op)
        nscores = self._scores(sn, pn, on)
        ind = np.where(nscores + self.margin > pscores)[0]

        # all examples in batch satify margin criterion
        self.nviolations += len(ind)
        if len(ind) == 0:
            return

        sp = list(sp[ind])
        sn = list(sn[ind])
        pp = list(pp[ind])
        pn = list(pn[ind])
        op = list(op[ind])
        on = list(on[ind])

        #pg = self.E[sp] + self.R[pp] - self.E[op]
        #ng = self.E[sn] + self.R[pn] - self.E[on]
        pg = self.E[op] - self.R[pp] - self.E[sp]
        ng = self.E[on] - self.R[pn] - self.E[sn]

        if self.l1:
            pg = np.sign(-pg)
            ng = -np.sign(-ng)
        else:
            raise NotImplementedError()

        # role gradients
        eidx, Sm, n = grad_sum_matrix(sp + op + sn + on)
        ge = Sm.dot(np.vstack((
            pg, -pg, ng, -ng
        ))) / n

        ridx, Sm, n = grad_sum_matrix(pp + pn)
        gr = Sm.dot(np.vstack((pg, ng))) / n
        return ge, gr, eidx, ridx
<commit_msg>refactor transe to new model structure<commit_after>import numpy as np
from skge.base import Model
from skge.util import grad_sum_matrix, unzip_triples
from skge.param import normalize

class TransE(Model):
    """
    Translational Embeddings of Knowledge Graphs
    """

    def __init__(self, *args, **kwargs):
        super(TransE, self).__init__(*args, **kwargs)
        self.add_hyperparam('sz', args[0])
        self.add_hyperparam('ncomp', args[1])
        self.add_hyperparam('l1', kwargs.pop('l1', True))
        self.add_param('E', (self.sz[0], self.ncomp), post=normalize)
        self.add_param('R', (self.sz[2], self.ncomp))

    def scores(self, ss, ps, os):
        score = self.E[ss] + self.R[ps] - self.E[os]
        if self.l1:
            score = np.abs(score)
        else:
            score = score ** 2
        return -np.sum(score, axis=1)

    def _pairwise_gradients(self, pxs, nxs):
        # indices of positive triples
        sp, pp, op = unzip_triples(pxs)
        # indices of negative triples
        sn, pn, on = unzip_triples(nxs)

        pscores = self.scores(sp, pp, op)
        nscores = self.scores(sn, pn, on)
        ind = np.where(nscores + self.margin > pscores)[0]

        # all examples in batch satify margin criterion
        self.nviolations = len(ind)
        if len(ind) == 0:
            return

        sp = list(sp[ind])
        sn = list(sn[ind])
        pp = list(pp[ind])
        pn = list(pn[ind])
        op = list(op[ind])
        on = list(on[ind])

        #pg = self.E[sp] + self.R[pp] - self.E[op]
        #ng = self.E[sn] + self.R[pn] - self.E[on]
        pg = self.E[op] - self.R[pp] - self.E[sp]
        ng = self.E[on] - self.R[pn] - self.E[sn]

        if self.l1:
            pg = np.sign(-pg)
            ng = -np.sign(-ng)
        else:
            raise NotImplementedError()

        # entity gradients
        eidx, Sm, n = grad_sum_matrix(sp + op + sn + on)
        ge = Sm.dot(np.vstack((pg, -pg, ng, -ng))) / n

        # relation gradients
        ridx, Sm, n = grad_sum_matrix(pp + pn)
        gr = Sm.dot(np.vstack((pg, ng))) / n
        return {'E': (ge, eidx), 'R': (gr, ridx)}
<|endoftext|>


<commit_before># Copyright 2015 datawire. All rights reserved.
#
# 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.

from __future__ import absolute_import

from collections import OrderedDict
from textwrap import dedent

from .compiler import BUILTIN
from .helpers import doc_helper, indent, Code

not_implemented_template = """\
throw TypeError, '`{clazz}.{name}` is an abstract method';""".format

## Packaging

def package(name, version, packages, srcs, deps):
    files = OrderedDict()
    files.update(srcs)

    dependencies = ",\n        ".join(['"%s": "%s"' % d[1:] for d in deps])

    for path, readme in packages.items():
        files["%s/README.md" % "/".join(path)] = readme

    files["index.js"] = str(Code(comment, "%s\n" % "\n".join([import_(path, (), None) for path in packages])))

    files["package.json"] = """
{
    "name": "%s",
    "version": "%s",
    "main": "index.js",
    "dependencies": {
        %s
    }
}
        """ % (name, version, dependencies)
    return files

def class_file(path, name, fname):
    if path:
        return "/".join(path + ["index.js"])
    else:
        return "%s.js" % fname

def function_file(path, name, fname):
    return class_file(path, name, fname)

def package_file(path, name, fname):
    return "/".join(path + [name, "index.js"])

def make_class_file(path, name, rtloc=BUILTIN, why="class"):
    what = "/".join(list(path) + [name])
    head=dedent('''\
        // %s
        var _qrt = require("%s/quark_runtime.js");
        _qrt.plugImports("%s");
    ''' % (why, rtloc, what))
    tail=dedent('''\
        _qrt.pumpImports("%s");
    ''' % (what))
    return Code(comment, head=head, tail=tail)

def make_function_file(path, name, mdpkg, rtloc=BUILTIN):
    return make_class_file(path, name, rtloc=rtloc, why="function")

def make_package_file(path, name, rtloc=BUILTIN):
    return make_class_file(path, name, rtloc=rtloc, why="package")

def main_file(name):
    return "%s.js" % name

def make_main_file(name):
    return Code(comment)

def main_prolog():
    return "exports.call_main = function () { main(process.argv.slice(1)); }"

def main(path, name):
    return invoke_function(path, name, ()) + ";"

## Naming and imports

SUBS = {"self": "this", "super": "super_"}
def name(n):
    return SUBS.get(n, n)

def type(path, name, parameters):
    return ".".join(path + [name])

def import_(path, origin, dep, seen=None, lazy=False):
    qual = qualify(path, origin)
    if seen is not None:
        if qual[0] in seen:
            return ""
        seen.add(qual[0])
    extra = ""
    if dep:
        req = dep
        extra = ".%s" % qual[0]
    else:
        if tuple(origin) + tuple(qual) == tuple(path):
            prefix = "./"
        else:
            prefix = "../"*len(origin)
        req = prefix + qual[0] + "/index.js"
    if lazy:
        return "var %s;\nquark_runtime.lazyImport('%s', function(){%s = require('%s')%s;\n  exports.%s = %s;}, 0);" % (qual[0], req, qual[0], req, extra, qual[0], qual[0])
    return "var %s = require('%s')%s;\nexports.%s = %s; // %s" % (qual[0], req, extra, qual[0], qual[0], dep)

def qualify(package, origin):
    if package == origin: return []
    if not package: return []
    if not origin:
        return package
    elif package[:len(origin)] == origin:
        return package[len(origin):]
    else:
        return package

def native_include(path, du_name):
    assert path.endswith(".js"), path
    assert "/" not in path, (path, "Subpackage native inclusion not implemented for JS")
    return """var %s = require("%s/%s");\n""" % (path[:-3], du_name, path)

## Documentation

def doc(lines):
    return doc_helper(lines, "/**", " * ", " */")

def add_doc(doc, lines):
    if doc:
        docl = doc.splitlines()
    else:
        #docl = ["/**", " */"]  # Use this if we want to output for undocumented items
        return ""               # Using this because we don't want that noise

    # Allow calling with a (presumably one-line) string instead of a list
    if str(lines) == lines:
        lines = [lines]

    for line in lines:
        docl[-1:-1] = [" * " + line]

    return "\n".join(docl) + "\n"

def add_param_doc(doc, params):
    return add_doc(doc, ["@param {*} %s" % param for param in params])

## Comments

def comment(stuff):
    return "/* %s */\n" % stuff

## Class definition

def clazz(doc, abstract, clazz, parameters, base, interfaces, static_fields, fields, constructors, methods):
    if base: fields = [base + ".prototype.__init_fields__.call(this);"] + fields

    doc = add_doc(doc, "@class %s" % clazz)
    result = "\n// CLASS %s\n" % clazz + doc
    result += "\n".join(constructors)
    if base:
        result += "_qrt.util.inherits(%s, %s);\n" % (clazz, base)

    result += "\nfunction %s__init_fields__() {" % clazz + indent("\n".join(fields)) + "}\n"
    result += "%s.prototype.__init_fields__ = %s__init_fields__;\n" % (clazz, clazz)

    result += "\n".join("_qrt.lazyStatic(function(){%s});" % x for x in static_fields)

    result += "\n".join(methods)

    return result

def static_field(doc, clazz, type, name, value):
    doc = add_doc(doc, "@static")
    return "%s%s.%s = %s;" % (doc, clazz, name, value or "null")

def field(doc, clazz, type, name, value):
    return "%sthis.%s = %s;" % (doc, name, value or "null")

def field_init():
    return "this.__init_fields__();"

def default_constructor(clazz):
    return "function %s() {\n    this.__init_fields__();\n}\nexports.%s = %s;\n" % \
        (clazz, clazz, clazz)

def constructor(doc, name, parameters, body):
    return "\n%sfunction %s(%s)%s\nexports.%s = %s;\n" % \
        (doc, name, ", ".join(parameters), body, name, name)

def method(doc, clazz, type, name, parameters, body):
    doc = add_doc(doc, ["@method %s" % name, "@memberof %s" % clazz, "@instance"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.prototype.%s = %s;" % (clazz, name, full_name)
    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

def static_method(doc, clazz, type, name, parameters, body):
    doc = add_doc(doc, ["@memberof %s" % clazz, "@static"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.%s = %s;" % (clazz, name, full_name)
    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

def abstract_method(doc, clazz, type, name, parameters):
    doc = add_doc(doc, ["@abstract", "@memberof %s" % clazz, "@instance"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.prototype.%s = %s;" % (clazz, name, full_name)
    body = not_implemented_template(clazz=clazz, name=name)
    return "\n%sfunction %s(%s) { %s }\n" % (doc, full_name, params, body) + trailer

## Interface definition

def interface(doc, iface, parameters, bases, static_fields, methods):
    doc = add_doc(doc, "@interface")
    return clazz(doc, False, iface, parameters, None, [], static_fields, [], [default_constructor(iface)], methods)

def interface_method(doc, iface, type, name, parameters, body):
    params = ", ".join(parameters)
    full_name = "%s_%s" % (iface, name)
    trailer = "%s.prototype.%s = %s;" % (iface, name, full_name)
    doc = add_doc(doc, ["@method %s" % name, "@memberof %s" % iface, "@instance"])
    if body is None:
        body = " { %s }" % not_implemented_template(clazz=iface, name=name)
        add_doc(doc, "@abstract")
    doc = add_param_doc(doc, parameters)

    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

## Function definition

def function(doc, type, name, parameters, body):
    trailer = "exports.%s = %s;" % (name, name)
    doc = add_doc(doc, "@function")
    doc = add_param_doc(doc, parameters)
    return "\n%sfunction %s(%s)%s\n" % (doc, name, ", ".join(parameters), body) + trailer

## Parameters for methods and functions

def param(type, name, value):
    if value is None:
        return "%s" % name
    else:
        return "%s = %s" % (name, value)

## Blocks

def block(statements):
    return " {%s}" % indent("\n".join(statements))

## Statements

def local(type, name, value):
    return "var %s = %s;" % (name, value or "null")

def expr_stmt(e):
    return "%s;" % e

def assign(lhs, rhs):
    return "%s = %s;" % (lhs, rhs)

def if_(pred, cons, alt):
    result = "if (%s)%s" % (pred, cons)
    if alt:
        result += " else%s" % alt
    return result

def while_(cond, body):
    return "while (%s)%s" % (cond, body)

def break_():
    return "break;"

def continue_():
    return "continue;"

def return_(expr):
    if expr:
        return "return %s;" % expr
    else:
        return "return;"

## Expressions

def class_ref(v):
    return v

def method_ref(v):
    return "this.%s" % v

def field_ref(v):
    return "this.%s" % v

def local_ref(v):
    return v

def invoke_function(path, name, args):
    return "%s(%s)" % (".".join(path + [name]), ", ".join(args))

def construct(clazz, args):
    return "new %s(%s)" % (clazz, ", ".join(args))

def invoke_super(clazz, base, args):
    return "%s.super_.call(%s)" % (clazz, ", ".join(["this"] + args))

def invoke_method(expr, method, args):
    return "(%s).%s(%s)" % (expr, method, ", ".join(args))

def invoke_method_implicit(method, args):
    return "this.%s(%s)" % (method, ", ".join(args))

def invoke_super_method(clazz, base, method, args):
    return "this.constructor.super_.prototype.%s.call(%s)" % (method, ", ".join(["this"] + args))

def invoke_static_method(path, clazz, method, args):
    return "%s.%s(%s)" % (".".join(path + [clazz]), method, ", ".join(args))

def get_static_field(path, clazz, field):
    return "%s.%s" % (".".join(path + [clazz]), field)

def get_field(expr, field):
    return "(%s).%s" % (expr, field)

def cast(type, expr):
    if type == '':  # TODO why does this happen?
        return expr
    assert expr
    template = '_qrt.cast({expr}, function () {{ return {type}; }})'.format
    return template(expr=expr, type=type)

## Literals

def null():
    return "null"

def bool_(b):
    return b.text

def number(n):
    assert n.text
    if n.text[-1:] == "L":
        return n.text[:-1]
    else:
        return n.text

def string(s):
    result = s.text[0]
    idx = 1
    while idx < len(s.text) - 1:
        c = s.text[idx]
        next = s.text[idx + 1]
        if c == "\\" and next == "x":
            result += "\\u00"
            idx += 1
        else:
            result += c
        idx += 1
    result += s.text[-1]
    return result

def list_(elements):
    return "[%s]" % ", ".join(elements)

def map(entries):
    return "new Map([%s])" % (", ".join(["[%s, %s]" % e for e in entries]))
<commit_msg>Typo in javascript lazy import<commit_after># Copyright 2015 datawire. All rights reserved.
#
# 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.

from __future__ import absolute_import

from collections import OrderedDict
from textwrap import dedent

from .compiler import BUILTIN
from .helpers import doc_helper, indent, Code

not_implemented_template = """\
throw TypeError, '`{clazz}.{name}` is an abstract method';""".format

## Packaging

def package(name, version, packages, srcs, deps):
    files = OrderedDict()
    files.update(srcs)

    dependencies = ",\n        ".join(['"%s": "%s"' % d[1:] for d in deps])

    for path, readme in packages.items():
        files["%s/README.md" % "/".join(path)] = readme

    files["index.js"] = str(Code(comment, "%s\n" % "\n".join([import_(path, (), None) for path in packages])))

    files["package.json"] = """
{
    "name": "%s",
    "version": "%s",
    "main": "index.js",
    "dependencies": {
        %s
    }
}
        """ % (name, version, dependencies)
    return files

def class_file(path, name, fname):
    if path:
        return "/".join(path + ["index.js"])
    else:
        return "%s.js" % fname

def function_file(path, name, fname):
    return class_file(path, name, fname)

def package_file(path, name, fname):
    return "/".join(path + [name, "index.js"])

def make_class_file(path, name, rtloc=BUILTIN, why="class"):
    what = "/".join(list(path) + [name])
    head=dedent('''\
        // %s
        var _qrt = require("%s/quark_runtime.js");
        _qrt.plugImports("%s");
    ''' % (why, rtloc, what))
    tail=dedent('''\
        _qrt.pumpImports("%s");
    ''' % (what))
    return Code(comment, head=head, tail=tail)

def make_function_file(path, name, mdpkg, rtloc=BUILTIN):
    return make_class_file(path, name, rtloc=rtloc, why="function")

def make_package_file(path, name, rtloc=BUILTIN):
    return make_class_file(path, name, rtloc=rtloc, why="package")

def main_file(name):
    return "%s.js" % name

def make_main_file(name):
    return Code(comment)

def main_prolog():
    return "exports.call_main = function () { main(process.argv.slice(1)); }"

def main(path, name):
    return invoke_function(path, name, ()) + ";"

## Naming and imports

SUBS = {"self": "this", "super": "super_"}
def name(n):
    return SUBS.get(n, n)

def type(path, name, parameters):
    return ".".join(path + [name])

def import_(path, origin, dep, seen=None, lazy=False):
    qual = qualify(path, origin)
    if seen is not None:
        if qual[0] in seen:
            return ""
        seen.add(qual[0])
    extra = ""
    if dep:
        req = dep
        extra = ".%s" % qual[0]
    else:
        if tuple(origin) + tuple(qual) == tuple(path):
            prefix = "./"
        else:
            prefix = "../"*len(origin)
        req = prefix + qual[0] + "/index.js"
    if lazy:
        return "var %s;\n_qrt.lazyImport('%s', function(){%s = require('%s')%s;\n  exports.%s = %s;}, 0);" % (qual[0], req, qual[0], req, extra, qual[0], qual[0])
    return "var %s = require('%s')%s;\nexports.%s = %s; // %s" % (qual[0], req, extra, qual[0], qual[0], dep)

def qualify(package, origin):
    if package == origin: return []
    if not package: return []
    if not origin:
        return package
    elif package[:len(origin)] == origin:
        return package[len(origin):]
    else:
        return package

def native_include(path, du_name):
    assert path.endswith(".js"), path
    assert "/" not in path, (path, "Subpackage native inclusion not implemented for JS")
    return """var %s = require("%s/%s");\n""" % (path[:-3], du_name, path)

## Documentation

def doc(lines):
    return doc_helper(lines, "/**", " * ", " */")

def add_doc(doc, lines):
    if doc:
        docl = doc.splitlines()
    else:
        #docl = ["/**", " */"]  # Use this if we want to output for undocumented items
        return ""               # Using this because we don't want that noise

    # Allow calling with a (presumably one-line) string instead of a list
    if str(lines) == lines:
        lines = [lines]

    for line in lines:
        docl[-1:-1] = [" * " + line]

    return "\n".join(docl) + "\n"

def add_param_doc(doc, params):
    return add_doc(doc, ["@param {*} %s" % param for param in params])

## Comments

def comment(stuff):
    return "/* %s */\n" % stuff

## Class definition

def clazz(doc, abstract, clazz, parameters, base, interfaces, static_fields, fields, constructors, methods):
    if base: fields = [base + ".prototype.__init_fields__.call(this);"] + fields

    doc = add_doc(doc, "@class %s" % clazz)
    result = "\n// CLASS %s\n" % clazz + doc
    result += "\n".join(constructors)
    if base:
        result += "_qrt.util.inherits(%s, %s);\n" % (clazz, base)

    result += "\nfunction %s__init_fields__() {" % clazz + indent("\n".join(fields)) + "}\n"
    result += "%s.prototype.__init_fields__ = %s__init_fields__;\n" % (clazz, clazz)

    result += "\n".join("_qrt.lazyStatic(function(){%s});" % x for x in static_fields)

    result += "\n".join(methods)

    return result

def static_field(doc, clazz, type, name, value):
    doc = add_doc(doc, "@static")
    return "%s%s.%s = %s;" % (doc, clazz, name, value or "null")

def field(doc, clazz, type, name, value):
    return "%sthis.%s = %s;" % (doc, name, value or "null")

def field_init():
    return "this.__init_fields__();"

def default_constructor(clazz):
    return "function %s() {\n    this.__init_fields__();\n}\nexports.%s = %s;\n" % \
        (clazz, clazz, clazz)

def constructor(doc, name, parameters, body):
    return "\n%sfunction %s(%s)%s\nexports.%s = %s;\n" % \
        (doc, name, ", ".join(parameters), body, name, name)

def method(doc, clazz, type, name, parameters, body):
    doc = add_doc(doc, ["@method %s" % name, "@memberof %s" % clazz, "@instance"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.prototype.%s = %s;" % (clazz, name, full_name)
    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

def static_method(doc, clazz, type, name, parameters, body):
    doc = add_doc(doc, ["@memberof %s" % clazz, "@static"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.%s = %s;" % (clazz, name, full_name)
    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

def abstract_method(doc, clazz, type, name, parameters):
    doc = add_doc(doc, ["@abstract", "@memberof %s" % clazz, "@instance"])
    doc = add_param_doc(doc, parameters)
    params = ", ".join(parameters)
    full_name = "%s_%s" % (clazz, name)
    trailer = "%s.prototype.%s = %s;" % (clazz, name, full_name)
    body = not_implemented_template(clazz=clazz, name=name)
    return "\n%sfunction %s(%s) { %s }\n" % (doc, full_name, params, body) + trailer

## Interface definition

def interface(doc, iface, parameters, bases, static_fields, methods):
    doc = add_doc(doc, "@interface")
    return clazz(doc, False, iface, parameters, None, [], static_fields, [], [default_constructor(iface)], methods)

def interface_method(doc, iface, type, name, parameters, body):
    params = ", ".join(parameters)
    full_name = "%s_%s" % (iface, name)
    trailer = "%s.prototype.%s = %s;" % (iface, name, full_name)
    doc = add_doc(doc, ["@method %s" % name, "@memberof %s" % iface, "@instance"])
    if body is None:
        body = " { %s }" % not_implemented_template(clazz=iface, name=name)
        add_doc(doc, "@abstract")
    doc = add_param_doc(doc, parameters)

    return "\n%sfunction %s(%s)%s\n" % (doc, full_name, params, body) + trailer

## Function definition

def function(doc, type, name, parameters, body):
    trailer = "exports.%s = %s;" % (name, name)
    doc = add_doc(doc, "@function")
    doc = add_param_doc(doc, parameters)
    return "\n%sfunction %s(%s)%s\n" % (doc, name, ", ".join(parameters), body) + trailer

## Parameters for methods and functions

def param(type, name, value):
    if value is None:
        return "%s" % name
    else:
        return "%s = %s" % (name, value)

## Blocks

def block(statements):
    return " {%s}" % indent("\n".join(statements))

## Statements

def local(type, name, value):
    return "var %s = %s;" % (name, value or "null")

def expr_stmt(e):
    return "%s;" % e

def assign(lhs, rhs):
    return "%s = %s;" % (lhs, rhs)

def if_(pred, cons, alt):
    result = "if (%s)%s" % (pred, cons)
    if alt:
        result += " else%s" % alt
    return result

def while_(cond, body):
    return "while (%s)%s" % (cond, body)

def break_():
    return "break;"

def continue_():
    return "continue;"

def return_(expr):
    if expr:
        return "return %s;" % expr
    else:
        return "return;"

## Expressions

def class_ref(v):
    return v

def method_ref(v):
    return "this.%s" % v

def field_ref(v):
    return "this.%s" % v

def local_ref(v):
    return v

def invoke_function(path, name, args):
    return "%s(%s)" % (".".join(path + [name]), ", ".join(args))

def construct(clazz, args):
    return "new %s(%s)" % (clazz, ", ".join(args))

def invoke_super(clazz, base, args):
    return "%s.super_.call(%s)" % (clazz, ", ".join(["this"] + args))

def invoke_method(expr, method, args):
    return "(%s).%s(%s)" % (expr, method, ", ".join(args))

def invoke_method_implicit(method, args):
    return "this.%s(%s)" % (method, ", ".join(args))

def invoke_super_method(clazz, base, method, args):
    return "this.constructor.super_.prototype.%s.call(%s)" % (method, ", ".join(["this"] + args))

def invoke_static_method(path, clazz, method, args):
    return "%s.%s(%s)" % (".".join(path + [clazz]), method, ", ".join(args))

def get_static_field(path, clazz, field):
    return "%s.%s" % (".".join(path + [clazz]), field)

def get_field(expr, field):
    return "(%s).%s" % (expr, field)

def cast(type, expr):
    if type == '':  # TODO why does this happen?
        return expr
    assert expr
    template = '_qrt.cast({expr}, function () {{ return {type}; }})'.format
    return template(expr=expr, type=type)

## Literals

def null():
    return "null"

def bool_(b):
    return b.text

def number(n):
    assert n.text
    if n.text[-1:] == "L":
        return n.text[:-1]
    else:
        return n.text

def string(s):
    result = s.text[0]
    idx = 1
    while idx < len(s.text) - 1:
        c = s.text[idx]
        next = s.text[idx + 1]
        if c == "\\" and next == "x":
            result += "\\u00"
            idx += 1
        else:
            result += c
        idx += 1
    result += s.text[-1]
    return result

def list_(elements):
    return "[%s]" % ", ".join(elements)

def map(entries):
    return "new Map([%s])" % (", ".join(["[%s, %s]" % e for e in entries]))
<|endoftext|>


<commit_before>import json
import logging
import re

from django.http import JsonResponse
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.db.models import Count
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View

from config.utils import get_active_event
from events.models import Ticket

def escape(text):
    """Escape slack control characters"""
    return text.replace('&', '&').replace('<', '<').replace('>', '>')

class SlackView(View):
    def log_request(self, request):
        logger = logging.getLogger('slack.requests')
        logger.info("\n{} {}".format(request.method, request.path))
        logger.info("GET:" + json.dumps(request.GET))
        logger.info("POST:" + json.dumps(request.POST))

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        self.log_request(request)

        expected_token = settings.SLACK_TOKEN
        if not expected_token:
            raise ImproperlyConfigured("SLACK_TOKEN setting not set.")

        token = request.GET.get("token")
        if token != expected_token:
            raise PermissionDenied("Invalid token")

        return super().dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return JsonResponse({
            "text": self.get_text(request),
            "attachments": self.get_attachments(request),
            "mrkdwn": True,
        })

    def get_text(self, request):
        return None

    def get_attachments(self, request):
        raise None

class TicketsView(SlackView):
    def get_attachments(self, request):
        categories = self.get_categories()
        lines = ["{} `{}`".format(*t) for t in categories]
        text = "\n".join(lines)

        return [{
            "fallback": "Ticket sale overview:\n{}".format(text),
            "title": "Ticket sale overview",
            "text": text,
            "color": "#9013FD"
        }]

    def get_categories(self):
        categories = (Ticket.objects
            .filter(event=get_active_event())
            .values('category')
            .annotate(count=Count('*'))
            .order_by('-count'))

        for category in categories:
            name = re.sub("\[.+\]", "", category['category']).strip()
            yield (escape(name), category['count'])
<commit_msg>Use slack verification token to authorize<commit_after>import json
import logging
import re

from django.http import JsonResponse
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.db.models import Count
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View

from config.utils import get_active_event
from events.models import Ticket

def escape(text):
    """Escape slack control characters"""
    return text.replace('&', '&').replace('<', '<').replace('>', '>')

class SlackView(View):
    def log_request(self, request):
        logger = logging.getLogger('slack.requests')
        logger.info("\n{} {}".format(request.method, request.path))
        logger.info("GET:" + json.dumps(request.GET))
        logger.info("POST:" + json.dumps(request.POST))

    def authorize(self, request):
        """Checks the request contains a vaild slack authentication token"""
        if not hasattr(settings, 'SLACK_VERIFICATION_TOKEN'):
            raise ImproperlyConfigured("SLACK_VERIFICATION_TOKEN setting not set.")

        expected_token = settings.SLACK_VERIFICATION_TOKEN
        if not expected_token:
            raise ImproperlyConfigured("SLACK_VERIFICATION_TOKEN setting is empty.")

        token = request.POST.get("token")
        if token != expected_token:
            raise PermissionDenied("Invalid token")

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        self.log_request(request)
        self.authorize(request)

        return super().dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return JsonResponse({
            "text": self.get_text(request),
            "attachments": self.get_attachments(request),
            "mrkdwn": True,
        })

    def get_text(self, request):
        return None

    def get_attachments(self, request):
        raise None

class TicketsView(SlackView):
    def get_attachments(self, request):
        categories = self.get_categories()
        lines = ["{} `{}`".format(*t) for t in categories]
        text = "\n".join(lines)

        return [{
            "fallback": "Ticket sale overview:\n{}".format(text),
            "title": "Ticket sale overview",
            "text": text,
            "color": "#9013FD"
        }]

    def get_categories(self):
        categories = (Ticket.objects
            .filter(event=get_active_event())
            .values('category')
            .annotate(count=Count('*'))
            .order_by('-count'))

        for category in categories:
            name = re.sub("\[.+\]", "", category['category']).strip()
            yield (escape(name), category['count'])
<|endoftext|>


<commit_before>import unittest

class StveTest(unittest.TestCase):

    def setUp(self):
        print('setUp')

    def test_first(self):
        print('stve test first')
        self.assertTrue(True)

def suite():
    suite = unittest.TestSuite()
    suite.addTests(unittest.makeSuite(StveTest))
    return suite
<commit_msg>Update.<commit_after>import unittest

class StveTest(unittest.TestCase):

    def setUp(self):
        print('setUp')

    def test_1(self):
        print('stve test first')
        self.assertTrue(True)

    def test_2(self):
        self.assertTrue(True)

def suite():
    suite = unittest.TestSuite()
    suite.addTests(unittest.makeSuite(StveTest))
    return suite
<|endoftext|>


<commit_before># coding: utf-8

import logging
import collections
import hashlib
import PyRSS2Gen as pyrss
import sys

# python3 support
if sys.version_info.major == 3:
    from urllib.parse import urljoin
    # from io import StringIO
else:
    from urlparse import urljoin
    # import StringIO

from datetime import datetime, timedelta
from flask import request, redirect, url_for, abort, current_app
from flask.views import MethodView
from quokka.utils.atom import AtomFeed
from quokka.core.models import Channel, Content, Config
from quokka.core.templates import render_template
from quokka.utils import get_current_user

logger = logging.getLogger()

class ContentList(MethodView):
    object_name = "content"
    template_suffix = "list"
    template_ext = "html"

    def get_template_names(self):

        if self.channel.channel_type:
            type_suffix = self.channel.channel_type.template_suffix
        else:
            type_suffix = 'default'

        self.template_suffix = "{0}_{1}".format(type_suffix,
                                                self.template_suffix)

        common_data = dict(
            object_name=self.object_name,
            suffix=self.template_suffix,
            ext=self.template_ext
        )

        channel_list = self.channel.get_ancestors_slugs()
        names = [
            u"{object_name}/{channel}/{suffix}.{ext}".format(
                channel=channel, **common_data
            )
            for channel in channel_list
        ]

        names.append(u"{object_name}/{suffix}.{ext}".format(**common_data))
        return names

    def get(self, long_slug):
        now = datetime.now()
        path = long_slug.split('/')
        mpath = ",".join(path)
        mpath = ",{0},".format(mpath)

        channel = Channel.objects.get_or_404(mpath=mpath, published=True)

        user = get_current_user()

        if channel.roles:
            forbidden = next(
                (True for role in user.roles if role in user.roles), False)
        else:
            forbidden = False

        if forbidden:
            return abort('Access Denied')  # or redirect

        # if channel.is_homepage and request.path != "/":
        #     return redirect("/")

        if channel.redirect_url:
            return redirect(channel.redirect_url)

        if channel.render_content:
            return ContentDetail().get(
                channel.render_content.content.long_slug, True)

        self.channel = channel

        base_filters = {}

        filters = {
            'published': True,
            'available_at__lte': now,
            'show_on_channel': True
        }

        if not channel.is_homepage:
            base_filters['__raw__'] = {
                'mpath': {'$regex': "^{0}".format(mpath)}}

        filters.update(channel.get_content_filters())
        contents = Content.objects(**base_filters).filter(**filters)

        sort = request.args.get('sort')
        if sort:
            contents = contents.order_by(sort)
        elif channel.sort_by:
            contents = contents.order_by(*channel.sort_by)

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = (
                request.args.get('per_page') or
                channel.per_page or
                current_app.config.get("PAGINATION_PER_PAGE", 10)
            )
            contents = contents.paginate(page=int(page),
                                         per_page=int(per_page))

        # this can be overkill! try another solution
        # to filter out content in unpublished channels
        # when homepage and also in blocks
        # contents = [content for content in contents
        #             if content.channel.published]

        themes = channel.get_themes()
        return render_template(self.get_template_names(),
                               theme=themes,
                               contents=contents,
                               channel=channel)

class ContentDetail(MethodView):
    object_name = "content"
    template_suffix = "detail"
    template_ext = "html"

    def get_template_names(self):

        if self.content.template_type:
            type_suffix = self.content.template_type.template_suffix
        else:
            type_suffix = 'default'

        self.template_suffix = "{0}_{1}".format(type_suffix,
                                                self.template_suffix)

        module_name = self.content.module_name
        model_name = self.content.model_name

        common_data = dict(
            object_name=self.object_name,
            module_name=module_name,
            model_name=model_name,
            suffix=self.template_suffix,
            ext=self.template_ext
        )

        names = [
            u"{object_name}/{content_slug}.{ext}".format(
                content_slug=self.content.long_slug, **common_data),
            u"{object_name}/{content_slug}_{suffix}.{ext}".format(
                content_slug=self.content.long_slug, **common_data),
            u"{object_name}/{content_slug}.{ext}".format(
                content_slug=self.content.slug, **common_data),
            u"{object_name}/{content_slug}_{suffix}.{ext}".format(
                content_slug=self.content.slug, **common_data)
        ]

        channel_list = self.content.channel.get_ancestors_slugs()
        for channel in channel_list:
            path = ("{object_name}/_{module_name}/{channel}/"
                    "{model_name}_{suffix}.{ext}")
            names.append(path.format(channel=channel, **common_data))

        for channel in channel_list:
            path = "{object_name}/_{module_name}/{channel}/{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        names.append(
            "{object_name}/_{module_name}/{model_name}_{suffix}.{ext}".format(
                **common_data
            )
        )

        names.append(
            "{object_name}/_{module_name}/{suffix}.{ext}".format(**common_data)
        )

        for channel in channel_list:
            path = "{object_name}/{channel}/{model_name}_{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        for channel in channel_list:
            path = "{object_name}/{channel}/{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        names.append(
            "{object_name}/{model_name}_{suffix}.{ext}".format(**common_data)
        )

        names.append("{object_name}/{suffix}.{ext}".format(**common_data))

        return names

    def get_context(self, long_slug, render_content=False):
        now = datetime.now()
        homepage = Channel.objects.get(is_homepage=True)

        if long_slug.startswith(homepage.slug) and \
                len(long_slug.split('/')) < 3 and \
                not render_content:
            slug = long_slug.split('/')[-1]
            return redirect(url_for('detail', long_slug=slug))

        filters = {
            'published': True,
            'available_at__lte': now
        }

        try:
            content = Content.objects.get(
                long_slug=long_slug,
                **filters
            )
        except Content.DoesNotExist:
            content = Content.objects.get_or_404(
                channel=homepage,
                slug=long_slug,
                **filters
            )

        if not content.channel.published:
            return abort(404)

        self.content = content

        context = {
            "content": content,
            "channel": content.channel
        }

        return context

    def get(self, long_slug, render_content=False):
        context = self.get_context(long_slug, render_content)
        if not render_content and isinstance(context, collections.Callable):
            return context
        return render_template(
            self.get_template_names(),
            theme=self.content.get_themes(),
            **context
        )

class BaseTagView(MethodView):
    def get_contents(self, tag):
        now = datetime.now()
        filters = {
            'published': True,
            'available_at__lte': now
        }
        contents = Content.objects(**filters).filter(tags=tag)

        # instantiate tag like channel for a list feed
        self.tag = tag

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = current_app.config.get(
                "PAGINATION_PER_PAGE", 10
            )
            contents = contents.paginate(page=int(page), per_page=per_page)

        return contents

class TagList(BaseTagView):
    object_name = "content"
    template_suffix = "list"
    template_ext = "html"

    def get_template_names(self):
        self.template_suffix = "{0}_{1}".format('tag',
                                                self.template_suffix)

        names = [
            u"{0}/{1}.{2}".format(
                self.object_name, self.template_suffix, self.template_ext
            )
        ]

        return names

    def get(self, tag):
        contents = self.get_contents(tag)
        return render_template(self.get_template_names(),
                               contents=contents)

def cdata(data):
    if not data:
        return u""
    return u"<![CDATA[\n{0}\n]]>".format(data)

class BaseFeed(MethodView):

    def make_external_url(self, url):
        return urljoin(request.url_root, url)

    def make_atom(self, feed_name, contents):
        feed = AtomFeed(
            feed_name,
            feed_url=request.url,
            url=request.url_root
        )
        for content in contents:
            if not content.channel.include_in_rss:
                continue

            if content.created_by:
                author = content.created_by.name
            else:
                author = Config.get('site', 'site_author', '')

            feed.add(
                content.title,
                cdata(content.get_text()),
                content_type="html",
                author=author,
                url=self.make_external_url(content.get_absolute_url()),
                updated=content.updated_at,
                published=content.created_at
            )
        return feed

    def make_rss(self, feed_name, contents):
        conf = current_app.config

        if not self.channel:  # Feed view
            description = 'Articles with tag: ' + self.tag
            categories = [self.tag]

        else:  # Tag View
            description = self.channel.get_text()
            categories = self.channel.tags

        rss = pyrss.RSS2(
            title=feed_name,
            link=request.url_root,
            # channel description after markdown processing
            description=description,
            language=conf.get('RSS_LANGUAGE', 'en-us'),
            copyright=conf.get('RSS_COPYRIGHT', 'All rights reserved.'),
            lastBuildDate=datetime.now(),
            categories=categories,
        )

        # set rss.pubDate to the newest post in the collection
        rss_pubDate =\
            datetime.today() - timedelta(days=365 * 10)  # 10 years in the past

        for content in contents:
            if not content.channel.include_in_rss:
                continue

            if content.created_at > rss_pubDate:
                rss_pubDate = content.created_at
            if content.created_by:
                author = content.created_by.name
            else:
                author = Config.get('site', 'site_author', '')

            rss.items.append(
                pyrss.RSSItem(
                    title=content.title,
                    link=content.get_absolute_url(),
                    description=content.get_text(),
                    author=author,
                    categories=content.tags,
                    guid=hashlib.sha1(content.title +
                                      content.get_absolute_url()).hexdigest(),
                    pubDate=content.created_at,
                )
            )

        # set the new published date after iterating the contents
        rss.pubDate = rss_pubDate

        return rss.to_xml(encoding=conf.get('RSS_ENCODING', 'utf-8'))

class ContentFeed(BaseFeed):

    def get_contents(self, long_slug):
        now = datetime.now()
        path = long_slug.split('/')
        mpath = ",".join(path)
        mpath = ",{0},".format(mpath)

        channel = Channel.objects.get_or_404(mpath=mpath, published=True)
        if not channel.include_in_rss:
            abort(404)

        self.channel = channel

        base_filters = {}

        filters = {
            'published': True,
            'available_at__lte': now,
        }

        if not channel.is_homepage:
            base_filters['__raw__'] = {
                'mpath': {'$regex': "^{0}".format(mpath)}}

        filters.update(channel.get_content_filters())
        contents = Content.objects(**base_filters).filter(**filters)

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = channel.per_page or current_app.config.get(
                "PAGINATION_PER_PAGE", 10
            )
            contents = contents.paginate(page=int(page), per_page=per_page)

        return contents

class FeedAtom(ContentFeed):

    def get(self, long_slug):
        contents = self.get_contents(long_slug)
        if current_app.config.get("PAGINATION_ENABLED", True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            self.channel.title
        )
        feed = self.make_atom(feed_name, contents)

        return feed.get_response()

class TagAtom(BaseFeed, BaseTagView):
    def get(self, tag):
        contents = self.get_contents(tag)
        if current_app.config.get("PAGINATION_ENABLED", True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            "Tag {0}".format(tag)
        )
        feed = self.make_atom(feed_name, contents)

        return feed.get_response()
<commit_msg>added manually because git was trolling me<commit_after># coding: utf-8

import logging
import collections
import hashlib
import PyRSS2Gen as pyrss
import sys

# python3 support
if sys.version_info.major == 3:
    from urllib.parse import urljoin
    # from io import StringIO
else:
    from urlparse import urljoin
    # import StringIO

from datetime import datetime, timedelta
from flask import request, redirect, url_for, abort, current_app
from flask.views import MethodView
from quokka.utils.atom import AtomFeed
from quokka.core.models import Channel, Content, Config
from quokka.core.templates import render_template
from quokka.utils import get_current_user

logger = logging.getLogger()

class ContentList(MethodView):
    object_name = "content"
    template_suffix = "list"
    template_ext = "html"

    def get_template_names(self):

        if self.channel.channel_type:
            type_suffix = self.channel.channel_type.template_suffix
        else:
            type_suffix = 'default'

        self.template_suffix = "{0}_{1}".format(type_suffix,
                                                self.template_suffix)

        common_data = dict(
            object_name=self.object_name,
            suffix=self.template_suffix,
            ext=self.template_ext
        )

        channel_list = self.channel.get_ancestors_slugs()
        names = [
            u"{object_name}/{channel}/{suffix}.{ext}".format(
                channel=channel, **common_data
            )
            for channel in channel_list
        ]

        names.append(u"{object_name}/{suffix}.{ext}".format(**common_data))
        return names

    def get(self, long_slug):
        now = datetime.now()
        path = long_slug.split('/')
        mpath = ",".join(path)
        mpath = ",{0},".format(mpath)

        channel = Channel.objects.get_or_404(mpath=mpath, published=True)

        user = get_current_user()

        if channel.roles:
            forbidden = next(
                (True for role in user.roles if role in user.roles), False)
        else:
            forbidden = False

        if forbidden:
            return abort('Access Denied')  # or redirect

        # if channel.is_homepage and request.path != "/":
        #     return redirect("/")

        if channel.redirect_url:
            return redirect(channel.redirect_url)

        if channel.render_content:
            return ContentDetail().get(
                channel.render_content.content.long_slug, True)

        self.channel = channel

        base_filters = {}

        filters = {
            'published': True,
            'available_at__lte': now,
            'show_on_channel': True
        }

        if not channel.is_homepage:
            base_filters['__raw__'] = {
                'mpath': {'$regex': "^{0}".format(mpath)}}

        filters.update(channel.get_content_filters())
        contents = Content.objects(**base_filters).filter(**filters)

        sort = request.args.get('sort')
        if sort:
            contents = contents.order_by(sort)
        elif channel.sort_by:
            contents = contents.order_by(*channel.sort_by)

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = (
                request.args.get('per_page') or
                channel.per_page or
                current_app.config.get("PAGINATION_PER_PAGE", 10)
            )
            contents = contents.paginate(page=int(page),
                                         per_page=int(per_page))

        # this can be overkill! try another solution
        # to filter out content in unpublished channels
        # when homepage and also in blocks
        # contents = [content for content in contents
        #             if content.channel.published]

        themes = channel.get_themes()
        return render_template(self.get_template_names(),
                               theme=themes,
                               contents=contents,
                               channel=channel)

class ContentDetail(MethodView):
    object_name = "content"
    template_suffix = "detail"
    template_ext = "html"

    def get_template_names(self):

        if self.content.template_type:
            type_suffix = self.content.template_type.template_suffix
        else:
            type_suffix = 'default'

        self.template_suffix = "{0}_{1}".format(type_suffix,
                                                self.template_suffix)

        module_name = self.content.module_name
        model_name = self.content.model_name

        common_data = dict(
            object_name=self.object_name,
            module_name=module_name,
            model_name=model_name,
            suffix=self.template_suffix,
            ext=self.template_ext
        )

        names = [
            u"{object_name}/{content_slug}.{ext}".format(
                content_slug=self.content.long_slug, **common_data),
            u"{object_name}/{content_slug}_{suffix}.{ext}".format(
                content_slug=self.content.long_slug, **common_data),
            u"{object_name}/{content_slug}.{ext}".format(
                content_slug=self.content.slug, **common_data),
            u"{object_name}/{content_slug}_{suffix}.{ext}".format(
                content_slug=self.content.slug, **common_data)
        ]

        channel_list = self.content.channel.get_ancestors_slugs()
        for channel in channel_list:
            path = ("{object_name}/_{module_name}/{channel}/"
                    "{model_name}_{suffix}.{ext}")
            names.append(path.format(channel=channel, **common_data))

        for channel in channel_list:
            path = "{object_name}/_{module_name}/{channel}/{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        names.append(
            "{object_name}/_{module_name}/{model_name}_{suffix}.{ext}".format(
                **common_data
            )
        )

        names.append(
            "{object_name}/_{module_name}/{suffix}.{ext}".format(**common_data)
        )

        for channel in channel_list:
            path = "{object_name}/{channel}/{model_name}_{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        for channel in channel_list:
            path = "{object_name}/{channel}/{suffix}.{ext}"
            names.append(path.format(channel=channel, **common_data))

        names.append(
            "{object_name}/{model_name}_{suffix}.{ext}".format(**common_data)
        )

        names.append("{object_name}/{suffix}.{ext}".format(**common_data))

        return names

    def get_context(self, long_slug, render_content=False):
        now = datetime.now()
        homepage = Channel.objects.get(is_homepage=True)

        if long_slug.startswith(homepage.slug) and \
                len(long_slug.split('/')) < 3 and \
                not render_content:
            slug = long_slug.split('/')[-1]
            return redirect(url_for('detail', long_slug=slug))

        filters = {
            'published': True,
            'available_at__lte': now
        }

        try:
            content = Content.objects.get(
                long_slug=long_slug,
                **filters
            )
        except Content.DoesNotExist:
            content = Content.objects.get_or_404(
                channel=homepage,
                slug=long_slug,
                **filters
            )

        if not content.channel.published:
            return abort(404)

        self.content = content

        context = {
            "content": content,
            "channel": content.channel
        }

        return context

    def get(self, long_slug, render_content=False):
        context = self.get_context(long_slug, render_content)
        if not render_content and isinstance(context, collections.Callable):
            return context
        return render_template(
            self.get_template_names(),
            theme=self.content.get_themes(),
            **context
        )

class BaseTagView(MethodView):
    def get_contents(self, tag):
        now = datetime.now()
        filters = {
            'published': True,
            'available_at__lte': now
        }
        contents = Content.objects(**filters).filter(tags=tag)

        # instantiate tag like channel for a list feed
        self.tag = tag

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = current_app.config.get(
                "PAGINATION_PER_PAGE", 10
            )
            contents = contents.paginate(page=int(page), per_page=per_page)

        return contents

class TagList(BaseTagView):
    object_name = "content"
    template_suffix = "list"
    template_ext = "html"

    def get_template_names(self):
        self.template_suffix = "{0}_{1}".format('tag',
                                                self.template_suffix)

        names = [
            u"{0}/{1}.{2}".format(
                self.object_name, self.template_suffix, self.template_ext
            )
        ]

        return names

    def get(self, tag):
        contents = self.get_contents(tag)
        return render_template(self.get_template_names(),
                               contents=contents)

def cdata(data):
    if not data:
        return u""
    return u"<![CDATA[\n{0}\n]]>".format(data)

class BaseFeed(MethodView):

    def make_external_url(self, url):
        return urljoin(request.url_root, url)

    def make_atom(self, feed_name, contents):
        feed = AtomFeed(
            feed_name,
            feed_url=request.url,
            url=request.url_root
        )
        for content in contents:
            if not content.channel.include_in_rss:
                continue

            if content.created_by:
                author = content.created_by.name
            else:
                author = Config.get('site', 'site_author', '')

            feed.add(
                content.title,
                cdata(content.get_text()),
                content_type="html",
                author=author,
                url=self.make_external_url(content.get_absolute_url()),
                updated=content.updated_at,
                published=content.created_at
            )
        return feed

    def make_rss(self, feed_name, contents):
        conf = current_app.config

        if not self.channel:  # Feed view
            description = 'Articles with tag: ' + self.tag
            categories = [self.tag]

        else:  # Tag View
            description = self.channel.get_text()
            categories = self.channel.tags

        rss = pyrss.RSS2(
            title=feed_name,
            link=request.url_root,
            # channel description after markdown processing
            description=description,
            language=conf.get('RSS_LANGUAGE', 'en-us'),
            copyright=conf.get('RSS_COPYRIGHT', 'All rights reserved.'),
            lastBuildDate=datetime.now(),
            categories=categories,
        )

        # set rss.pubDate to the newest post in the collection
        rss_pubDate =\
            datetime.today() - timedelta(days=365 * 10)  # 10 years in the past

        for content in contents:
            if not content.channel.include_in_rss:
                continue

            if content.created_at > rss_pubDate:
                rss_pubDate = content.created_at
            if content.created_by:
                author = content.created_by.name
            else:
                author = Config.get('site', 'site_author', '')

            rss.items.append(
                pyrss.RSSItem(
                    title=content.title,
                    link=content.get_absolute_url(),
                    description=content.get_text(),
                    author=author,
                    categories=content.tags,
                    guid=hashlib.sha1(content.title +
                                      content.get_absolute_url()).hexdigest(),
                    pubDate=content.created_at,
                )
            )

        # set the new published date after iterating the contents
        rss.pubDate = rss_pubDate

        return rss.to_xml(encoding=conf.get('RSS_ENCODING', 'utf-8'))

class ContentFeed(BaseFeed):

    def get_contents(self, long_slug):
        now = datetime.now()
        path = long_slug.split('/')
        mpath = ",".join(path)
        mpath = ",{0},".format(mpath)

        channel = Channel.objects.get_or_404(mpath=mpath, published=True)
        if not channel.include_in_rss:
            abort(404)

        self.channel = channel

        base_filters = {}

        filters = {
            'published': True,
            'available_at__lte': now,
        }

        if not channel.is_homepage:
            base_filters['__raw__'] = {
                'mpath': {'$regex': "^{0}".format(mpath)}}

        filters.update(channel.get_content_filters())
        contents = Content.objects(**base_filters).filter(**filters)

        if current_app.config.get("PAGINATION_ENABLED", True):
            pagination_arg = current_app.config.get("PAGINATION_ARG", "page")
            page = request.args.get(pagination_arg, 1)
            per_page = channel.per_page or current_app.config.get(
                "PAGINATION_PER_PAGE", 10
            )
            contents = contents.paginate(page=int(page), per_page=per_page)

        return contents

class FeedAtom(ContentFeed):

    def get(self, long_slug):
        contents = self.get_contents(long_slug)
        if current_app.config.get("PAGINATION_ENABLED", True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            self.channel.title
        )
        feed = self.make_atom(feed_name, contents)

        return feed.get_response()

class TagAtom(BaseFeed, BaseTagView):
    def get(self, tag):
        contents = self.get_contents(tag)
        if current_app.config.get("PAGINATION_ENABLED", True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            "Tag {0}".format(tag)
        )
        feed = self.make_atom(feed_name, contents)

        return feed.get_response()

class FeedRss(ContentFeed):
    def get(self, long_slug):
        # instantiates the self.channel property
        contents = self.get_contents(long_slug)
        self.tag = None

        if current_app.config.get("PAGINATION_ENABLED", True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            self.channel.title
        )

        return self.make_rss(feed_name, contents)

class TagRss(BaseFeed, BaseTagView):
    def get(self, tag):
        contents = self.get_contents(tag)
        self.channel = None

        if current_app.config.get('PAGINATION_ENABLED', True):
            contents = contents.items

        feed_name = u"{0} | {1} | feed".format(
            Config.get('site', 'site_name', ''),
            "Tag {0}".format(tag)
        )

        return self.make_rss(feed_name, contents)
<|endoftext|>