#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Copyright 2009-2011 Olemis Lang <olemis at gmail.com>
#
#   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.

r"""Data sources used to share data generated by Trac search engine. 
This includes search filters and results.

Note: It relies on Trac XML-RPC plugin.

Copyright 2009-2011 Olemis Lang <olemis at gmail.com>
Licensed under the Apache License, Version 2.0 
"""

__all__ = 'GVizSearchFiltersProvider', 'GVizSearchProvider'

from util import GVizXMLRPCAdapter
from api import gviz_col, gviz_param, GVizBadRequestError
import types

class GVizSearchFiltersProvider(GVizXMLRPCAdapter):
    r"""Returns all the search filters installed in the environment.
    
    This component depends on tracrpc.ticket.SearchRPC. The later 
    must be enabled. Please read 
    https://opensvn.csie.org/traccgi/swlcu/wiki/En/Devel/TracGViz/DataSources#Preconditions
    for further details.
    """
    # IGVizDataProvider methods
    def get_data_schema(self):
        return [('name', 'string'), ('desc', 'string', 'description')]
    
    @gviz_col('name', "The name of the search filter")
    @gviz_col('desc', "Search filter description")
    def get_data(self, req, tq, **tqx):
        r"""Get search filters' data.
        
        @return a list of search filters with each element in the 
                form (name, description).
        """
        return (fi[:2] for fi in self._rpc_obj.getSearchFilters(req))
    
    def xmlrpc_namespace(self):
        r"""Use Search XML-RPC.
        """
        return ('search',)
    def gviz_namespace(self):
        r"""Access the data at `search/filters`.
        """
        return ('search', 'filters')

class GVizSearchProvider(GVizXMLRPCAdapter):
    r"""Provides the data retrieved by Trac built-in search engine. It 
    consists of the occurrences of keywords and substrings in wiki 
    pages, tickets, changeset descriptions and other specific 
    extensions.
    
    This component depends on tracrpc.ticket.SearchRPC. The later 
    must be enabled. Please read 
    https://opensvn.csie.org/traccgi/swlcu/wiki/En/Devel/TracGViz/DataSources#Preconditions
    for further details.
    """
    # IGVizDataProvider methods
    def get_data_schema(self):
        return [('url', 'string'), ('title', 'string'), \
                ('date', 'datetime'), ('author', 'string'), \
                ('excerpt', 'string')]
    
    @gviz_col('url', "URL to the resource where a match was found.")
    @gviz_col('title', "Result title.")
    @gviz_col('date', "Timestamp. It's usually the date and time "
                "of the last modification made to the resource.")
    @gviz_col('author', "The name of the author of the last change.")
    @gviz_col('excerpt', "Brief text illustrating the contents found.")
    @gviz_param('q', "The query string.")
    @gviz_param('filter', "Restricts the search to specific filters. "
                "Specify this parameter multiple times in order to "
                "select multiple search filters. Defaults to all if "
                "not provided.")
    def get_data(self, req, tq, q=None, filter=None, **tqx):
        r"""Retrieve search results.
        """
        if not q:
            raise GVizBadRequestError("No query was specified")
        if isinstance(filter, types.StringTypes):
            filter = [filter]
        self.log.debug("IG: Filter : %s", filter)
        result = self._rpc_obj.performSearch(req, q, filter)
        self.log.debug("IG: Search result : %s", result)
        return result
    
    def gviz_namespace(self):
        return ('search',)
        
