<commit_before>#-*- python -*-
import logging
from mimetypes import guess_type
import json, urllib, re
import Image

# Non-stdlib imports
import pkg_resources
from tg import tmpl_context
from tg import expose, validate, redirect, flash
from tg import request, response
from tg.decorators import with_trailing_slash, without_trailing_slash
from pylons import g, c, request
from formencode import validators
from pymongo.bson import ObjectId

from ming.orm.base import session
from ming.orm.ormsession import ThreadLocalORMSession

# Pyforge-specific imports
from pyforge.app import Application, ConfigOption, SitemapEntry, DefaultAdminController
from pyforge.lib.helpers import push_config, tag_artifact, DateTimeConverter, square_image
from pyforge.lib.search import search_artifact
from pyforge.lib.decorators import audit, react
from pyforge.lib.security import require, has_artifact_access
from pyforge.model import ProjectRole, TagEvent, UserTags, ArtifactReference, Feed
from pyforge.lib import widgets as w
from pyforge.lib.widgets import form_fields as ffw
from pyforge.controllers import AppDiscussionController

# Local imports
from forgetracker import model
from forgetracker import version

from forgetracker.widgets.ticket_form import ticket_form
from forgetracker.widgets.bin_form import bin_form

log = logging.getLogger(__name__)

class W:
    thread=w.Thread(
        offset=None, limit=None, page_size=None, total=None,
        style='linear')
    markdown_editor = ffw.MarkdownEdit()
    user_tag_edit = ffw.UserTagEdit()
    attachment_list = ffw.AttachmentList()

class ForgeTrackerApp(Application):
    __version__ = version.__version__
    permissions = ['configure', 'read', 'write',
                    'unmoderated_post', 'post', 'moderate', 'admin']

    def __init__(self, project, config):
        Application.__init__(self, project, config)
        self.root = RootController()
        self.admin = TrackerAdminController(self)

    def has_access(self, user, topic):
        return has_artifact_access('post', user=user)

    @audit('Tickets.msg.#')
    def message_auditor(self, routing_key, data):
        log.info('Auditing data from %s (%s)',
                 routing_key, self.config.options.mount_point)
        log.info('Headers are: %s', data['headers'])
        try:
            ticket_num = routing_key.split('.')[-1]
            t = model.Ticket.query.get(ticket_num=int(ticket_num))
        except:
            log.exception('Unexpected error routing tkt msg: %s', routing_key)
            return
        if t is None:
            log.error("Can't find ticket %s (routing key was %s)",
                      ticket_num, routing_key)
        super(ForgeTrackerApp, self).message_auditor(routing_key, data, t)

    @react('Tickets.#')
    def reactor(self, routing_key, data):
        log.info('Reacting to data from %s (%s)',
                 routing_key, self.config.options.mount_point)

    @property
    def sitemap(self):
        menu_id = self.config.options.mount_point.title()
        with push_config(c, app=self):
            return [
                SitemapEntry(menu_id, '.')[self.sidebar_menu()] ]

    def sidebar_menu(self):
        related_artifacts = []
        search_bins = []
        related_urls = []
        ticket = request.path_info.split(self.url)[-1].split('/')[0]
        for bin in model.Bin.query.find():
            search_bins.append(SitemapEntry(bin.shorthand_id(), bin.url(), className='nav_child'))
        if ticket.isdigit():
            ticket = model.Ticket.query.find(dict(app_config_id=self.config._id,ticket_num=int(ticket))).first()
        else:
            ticket = None
        links = [
            SitemapEntry('Home', self.config.url()),
            SitemapEntry('Discuss', c.app.url + '_discuss/'),
            SitemapEntry('Create New Ticket', self.config.url() + 'new/')]
        if ticket:
            links.append(SitemapEntry('Update this Ticket',ticket.url() + 'edit/'))
            for aref in ticket.references+ticket.backreferences.values():
                artifact = ArtifactReference(aref).to_artifact()
                if artifact.url() not in related_urls:
                    related_urls.append(artifact.url())
                    related_artifacts.append(SitemapEntry(artifact.shorthand_id(), artifact.url(), className='nav_child'))
        if len(related_artifacts):
            links.append(SitemapEntry('Related Artifacts'))
            links = links + related_artifacts
        links.append(SitemapEntry('Search', self.config.url() + 'search/'))
        links.append(SitemapEntry('Saved Searches'))
        links.append(SitemapEntry('All', self.config.url() + 'bins', className='nav_child'))
        if len(search_bins):
            links = links + search_bins
        if ticket:
            if ticket.super_id:
                links.append(SitemapEntry('Supertask'))
                super = model.Ticket.query.get(_id=ticket.super_id, app_config_id=c.app.config._id)
                links.append(SitemapEntry('Ticket {0}'.format(super.ticket_num), super.url(), className='nav_child'))
            links.append(SitemapEntry('Subtasks'))
            for sub_id in ticket.sub_ids or []:
                sub = model.Ticket.query.get(_id=sub_id, app_config_id=c.app.config._id)
                links.append(SitemapEntry('Ticket {0}'.format(sub.ticket_num), sub.url(), className='nav_child'))
            links.append(SitemapEntry('Create New Subtask', '{0}new/?super_id={1}'.format(self.config.url(), ticket._id), className='nav_child'))
        links.append(SitemapEntry('Help'))
        links.append(SitemapEntry('Ticket Help', self.config.url() + 'help', className='nav_child'))
        links.append(SitemapEntry('Markdown Syntax', self.config.url() + 'markdown_syntax', className='nav_child'))
        return links

    @property
    def templates(self):
         return pkg_resources.resource_filename('forgetracker', 'templates')

    def install(self, project):
        'Set up any default permissions and roles here'

        self.uninstall(project)
        super(ForgeTrackerApp, self).install(project)
        # Give the installing user all the permissions
        pr = c.user.project_role()
        for perm in self.permissions:
              self.config.acl[perm] = [ pr._id ]
        self.config.acl['read'].append(
            ProjectRole.query.get(name='*anonymous')._id)
        self.config.acl['post'].append(
            ProjectRole.query.get(name='*authenticated')._id)
        model.Globals(app_config_id=c.app.config._id,
            last_ticket_num=0,
            status_names='open unread accepted pending closed',
            custom_fields=[])

    def uninstall(self, project):
        "Remove all the plugin's artifacts from the database"
        model.Attachment.query.remove({'metadata.app_config_id':c.app.config._id})
        app_config_id = {'app_config_id':c.app.config._id}
        model.Ticket.query.remove(app_config_id)
        # model.Comment.query.remove(app_config_id)
        model.Globals.query.remove(app_config_id)

class RootController(object):

    def __init__(self):
        setattr(self, 'feed.atom', self.feed)
        setattr(self, 'feed.rss', self.feed)
        self._discuss = AppDiscussionController()

    def ordered_history(self, limit=None):
        q = []
        tickets = model.Ticket.query.find(dict(app_config_id=c.app.config._id)).sort('ticket_num')
        for ticket in tickets:
            q.append(dict(change_type='ticket',change_date=ticket.created_date,
                          ticket_num=ticket.ticket_num,change_text=ticket.summary))
            for comment in ticket.discussion_thread().find_posts(limit=limit, style='linear'):
                # for comment in ticket.ordered_comments(limit):
                q.append(dict(change_type='comment',
                              change_date=comment.timestamp,
                              ticket_num=ticket.ticket_num,
                              change_text=comment.text))
        q.sort(reverse=True)
        if limit:
            n = len(q)
            if n > limit:
                z = []
                for i in range(0, limit):
                    z.append(q[i])
                q = z
        return q

    @with_trailing_slash
    @expose('forgetracker.templates.index')
    def index(self):
        tickets = model.Ticket.query.find(dict(app_config_id=c.app.config._id)).sort('ticket_num')
        changes = self.ordered_history(5)
        return dict(tickets=tickets,changes=changes)
<commit_msg>[#25]: Initialize new (sub) BinController in RootController<commit_after>#-*- python -*-
import logging
from mimetypes import guess_type
import json, urllib, re
import Image

# Non-stdlib imports
import pkg_resources
from tg import tmpl_context
from tg import expose, validate, redirect, flash
from tg import request, response
from tg.decorators import with_trailing_slash, without_trailing_slash
from pylons import g, c, request
from formencode import validators
from pymongo.bson import ObjectId

from ming.orm.base import session
from ming.orm.ormsession import ThreadLocalORMSession

# Pyforge-specific imports
from pyforge.app import Application, ConfigOption, SitemapEntry, DefaultAdminController
from pyforge.lib.helpers import push_config, tag_artifact, DateTimeConverter, square_image
from pyforge.lib.search import search_artifact
from pyforge.lib.decorators import audit, react
from pyforge.lib.security import require, has_artifact_access
from pyforge.model import ProjectRole, TagEvent, UserTags, ArtifactReference, Feed
from pyforge.lib import widgets as w
from pyforge.lib.widgets import form_fields as ffw
from pyforge.controllers import AppDiscussionController

# Local imports
from forgetracker import model
from forgetracker import version

from forgetracker.widgets.ticket_form import ticket_form
from forgetracker.widgets.bin_form import bin_form

log = logging.getLogger(__name__)

class W:
    thread=w.Thread(
        offset=None, limit=None, page_size=None, total=None,
        style='linear')
    markdown_editor = ffw.MarkdownEdit()
    user_tag_edit = ffw.UserTagEdit()
    attachment_list = ffw.AttachmentList()

class ForgeTrackerApp(Application):
    __version__ = version.__version__
    permissions = ['configure', 'read', 'write',
                    'unmoderated_post', 'post', 'moderate', 'admin']

    def __init__(self, project, config):
        Application.__init__(self, project, config)
        self.root = RootController()
        self.admin = TrackerAdminController(self)

    def has_access(self, user, topic):
        return has_artifact_access('post', user=user)

    @audit('Tickets.msg.#')
    def message_auditor(self, routing_key, data):
        log.info('Auditing data from %s (%s)',
                 routing_key, self.config.options.mount_point)
        log.info('Headers are: %s', data['headers'])
        try:
            ticket_num = routing_key.split('.')[-1]
            t = model.Ticket.query.get(ticket_num=int(ticket_num))
        except:
            log.exception('Unexpected error routing tkt msg: %s', routing_key)
            return
        if t is None:
            log.error("Can't find ticket %s (routing key was %s)",
                      ticket_num, routing_key)
        super(ForgeTrackerApp, self).message_auditor(routing_key, data, t)

    @react('Tickets.#')
    def reactor(self, routing_key, data):
        log.info('Reacting to data from %s (%s)',
                 routing_key, self.config.options.mount_point)

    @property
    def sitemap(self):
        menu_id = self.config.options.mount_point.title()
        with push_config(c, app=self):
            return [
                SitemapEntry(menu_id, '.')[self.sidebar_menu()] ]

    def sidebar_menu(self):
        related_artifacts = []
        search_bins = []
        related_urls = []
        ticket = request.path_info.split(self.url)[-1].split('/')[0]
        for bin in model.Bin.query.find():
            search_bins.append(SitemapEntry(bin.shorthand_id(), bin.url(), className='nav_child'))
        if ticket.isdigit():
            ticket = model.Ticket.query.find(dict(app_config_id=self.config._id,ticket_num=int(ticket))).first()
        else:
            ticket = None
        links = [
            SitemapEntry('Home', self.config.url()),
            SitemapEntry('Discuss', c.app.url + '_discuss/'),
            SitemapEntry('Create New Ticket', self.config.url() + 'new/')]
        if ticket:
            links.append(SitemapEntry('Update this Ticket',ticket.url() + 'edit/'))
            for aref in ticket.references+ticket.backreferences.values():
                artifact = ArtifactReference(aref).to_artifact()
                if artifact.url() not in related_urls:
                    related_urls.append(artifact.url())
                    related_artifacts.append(SitemapEntry(artifact.shorthand_id(), artifact.url(), className='nav_child'))
        if len(related_artifacts):
            links.append(SitemapEntry('Related Artifacts'))
            links = links + related_artifacts
        links.append(SitemapEntry('Search', self.config.url() + 'search/'))
        links.append(SitemapEntry('Saved Searches'))
        links.append(SitemapEntry('All', self.config.url() + 'bins', className='nav_child'))
        if len(search_bins):
            links = links + search_bins
        if ticket:
            if ticket.super_id:
                links.append(SitemapEntry('Supertask'))
                super = model.Ticket.query.get(_id=ticket.super_id, app_config_id=c.app.config._id)
                links.append(SitemapEntry('Ticket {0}'.format(super.ticket_num), super.url(), className='nav_child'))
            links.append(SitemapEntry('Subtasks'))
            for sub_id in ticket.sub_ids or []:
                sub = model.Ticket.query.get(_id=sub_id, app_config_id=c.app.config._id)
                links.append(SitemapEntry('Ticket {0}'.format(sub.ticket_num), sub.url(), className='nav_child'))
            links.append(SitemapEntry('Create New Subtask', '{0}new/?super_id={1}'.format(self.config.url(), ticket._id), className='nav_child'))
        links.append(SitemapEntry('Help'))
        links.append(SitemapEntry('Ticket Help', self.config.url() + 'help', className='nav_child'))
        links.append(SitemapEntry('Markdown Syntax', self.config.url() + 'markdown_syntax', className='nav_child'))
        return links

    @property
    def templates(self):
         return pkg_resources.resource_filename('forgetracker', 'templates')

    def install(self, project):
        'Set up any default permissions and roles here'

        self.uninstall(project)
        super(ForgeTrackerApp, self).install(project)
        # Give the installing user all the permissions
        pr = c.user.project_role()
        for perm in self.permissions:
              self.config.acl[perm] = [ pr._id ]
        self.config.acl['read'].append(
            ProjectRole.query.get(name='*anonymous')._id)
        self.config.acl['post'].append(
            ProjectRole.query.get(name='*authenticated')._id)
        model.Globals(app_config_id=c.app.config._id,
            last_ticket_num=0,
            status_names='open unread accepted pending closed',
            custom_fields=[])

    def uninstall(self, project):
        "Remove all the plugin's artifacts from the database"
        model.Attachment.query.remove({'metadata.app_config_id':c.app.config._id})
        app_config_id = {'app_config_id':c.app.config._id}
        model.Ticket.query.remove(app_config_id)
        # model.Comment.query.remove(app_config_id)
        model.Globals.query.remove(app_config_id)

class RootController(object):

    def __init__(self):
        setattr(self, 'feed.atom', self.feed)
        setattr(self, 'feed.rss', self.feed)
        self._discuss = AppDiscussionController()
        self.bins = BinController()

    def ordered_history(self, limit=None):
        q = []
        tickets = model.Ticket.query.find(dict(app_config_id=c.app.config._id)).sort('ticket_num')
        for ticket in tickets:
            q.append(dict(change_type='ticket',change_date=ticket.created_date,
                          ticket_num=ticket.ticket_num,change_text=ticket.summary))
            for comment in ticket.discussion_thread().find_posts(limit=limit, style='linear'):
                # for comment in ticket.ordered_comments(limit):
                q.append(dict(change_type='comment',
                              change_date=comment.timestamp,
                              ticket_num=ticket.ticket_num,
                              change_text=comment.text))
        q.sort(reverse=True)
        if limit:
            n = len(q)
            if n > limit:
                z = []
                for i in range(0, limit):
                    z.append(q[i])
                q = z
        return q

    @with_trailing_slash
    @expose('forgetracker.templates.index')
    def index(self):
        tickets = model.Ticket.query.find(dict(app_config_id=c.app.config._id)).sort('ticket_num')
        changes = self.ordered_history(5)
        return dict(tickets=tickets,changes=changes)

{'fraction_non_alphanumeric': 0.11574775614873528, 'fraction_numerical': 0.0012822007226949528, 'mean_word_length': 2.8105707306240286, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5312429', 'n_tokens_mistral': 5157, 'n_tokens_neox': 4951, 'n_words': 1006}