Commits

tehfink committed ff06084

readme, screenshot, pip install, etc.

Comments (0)

Files changed (16)

+syntax: regexp
+\.pyc$
+^media/
+^fabfile
+^nbproject/
+^ref/
+^virtualenvs/
+
+syntax: glob
+*.textClipping
+.DS_Store
+project.xml
+*.db
+*.psd
+~*
+*backup
+*svn
+http://bitbucket.org/tehfink/
+include AUTHORS
+include README.txt
+recursive-include cmsplugin_googlesearch/templates *
+recursive-include cmsplugin_googlesearch/fixtures *
+ALPHA
+
+Name: cmsplugin-googlesearch
+Description: for django-cms. provides a plugin inteerface for google's search ajax api & custom site search, for cms plugins and page apphook attachmentDownload: http://bitbucket.org/tehfink/cmsplugin-googlesearch/
+
+Requirements:
+- django-photologue: trunk
+- django-cms-2: 2.0.2
+- django: 1.1.1
+- modified django-pipes: http://github.com/tehfink/django-pipes
+
+Setup:
+- make sure requirements are installed and properly working
+- add cmsplugin_googlesearch to python path
+- add 'cmsplugin_googlesearch' to settings.INSTALLED_APPS
+- add ('cmsplugin_googlesearch.urls', 'Google Search plugin app') to settings.CMS_APPLICATIONS_URLS
+- run `python manage.py syncdb`
+- add plugins to pages, AND attach 'Google Search plugin app' to a page (you may have to restart server process for urls to an attached page to work, something with how django-cms caches urls). this is important, as the search plugin redirects to the apphooked page
+- edit settings for the plugin in django administration interface. these settings are cached as well
+
+Versioning:
+we're only tracking django-cms releases at this time.
+- branches are named based on django-cms; eg: cms-2.X
+- releases are tagged based on django-cms; eg: cms-2.0.2
+
+Optional:
+- define in settings.py:
+    CMSPLUGIN_GOOGLESEARCH_CSS_CHOICES - define multiple css classes to apply to plugins
+    CMSPLUGIN_GOOGLESEARCH_TEMPLATES_CHOICES - define multiple custom templates for plugins
+- copy cmsplugin_googlesearch/templates/plugins/ to your project's template directory
+- make sure you are in accord with google's requirements for using their services:
+ - http://www.google.com/cse/
+ - http://code.google.com/apis/ajaxsearch/web.html
+
+Todo:
+- implement paging and result counting
+
+Example Projects:
+- are stripped down, slightly modified versions of django-cms' example project for each relevant version
+- require a virtualenv with the requirements above installed
+- should work out of the box
+- username/password: admin/password

cmsplugin_googlesearch/__init__.py

+VERSION = (0, 0, 1, 'alpha')
+__version__ = '.'.join(map(str, VERSION))

cmsplugin_googlesearch/admin.py

+from django.contrib import admin
+from cmsplugin_googlesearch.models import GoogleSearchSettings
+
+
+class GoogleSearchSettingsAdmin(admin.ModelAdmin):
+    list_display = ('site', 'uri', 'user_agent',  'referrer', 'search_engine_id', 'result_size', )
+
+admin.site.register(GoogleSearchSettings, GoogleSearchSettingsAdmin)

cmsplugin_googlesearch/cms_plugins.py

+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+#from cms.models import CMSPlugin
+from cmsplugin_googlesearch.models import GoogleSearchPlugin
+from cmsplugin_googlesearch.forms import GoogleSearchForm
+from django.utils.translation import ugettext as _
+from cms.models.titlemodels import Title
+
+class CMSGoogleSearchPlugin(CMSPluginBase):
+    model = GoogleSearchPlugin
+    name = _("Google Search")
+    render_template = "plugins/cmsplugin_googlesearch/"
+
+    def render(self, context, instance, placeholder):
+
+        #set plugin template from plugin model
+        self.render_template = "plugins/cmsplugin_googlesearch/%s" % instance.get_template_display()
+
+        #get the first page that has an apphook to cmsplugin_googlesearch; use it as the form redirect value
+        redirect = Title.objects.filter(application_urls='cmsplugin_googlesearch.urls').filter(publisher_is_draft=False)[0].page.get_absolute_url()
+
+#        import ipdb; ipdb.set_trace()
+
+        form = GoogleSearchForm()
+
+        #if a query is defined in the plugin
+        if instance.query:
+            form.initial.update({'query': instance.query.strip(), })
+
+        context.update({
+            'object':       instance,
+            'placeholder':  placeholder,
+            'css':          instance.get_css_display(),
+            'form':         form,
+            'redirect':     redirect,
+        })
+        return context
+
+plugin_pool.register_plugin(CMSGoogleSearchPlugin)

cmsplugin_googlesearch/fixtures/initial_data.json

+[
+    {
+        "pk": 0,
+        "model": "cmsplugin_googlesearch.GoogleSearchSettings",
+        "fields": {
+            "site": "1",
+            "api_version": "1.0",
+            "uri": "http://ajax.googleapis.com/ajax/services/search/web"
+        }
+    }
+]

cmsplugin_googlesearch/forms.py

+from django import forms
+
+class GoogleSearchForm(forms.Form):
+	query = forms.CharField(max_length=200, required=True, label='Search This Site')

cmsplugin_googlesearch/models.py

+from django.db import models
+from cms.models import CMSPlugin
+from django.conf import settings
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.sites.models import Site
+from django.contrib.sites.managers import CurrentSiteManager
+
+
+class GoogleSearchSettings(models.Model):
+    """ Per site settings for Google Search """
+    site = models.OneToOneField(Site, primary_key=True)
+    api_version = models.CharField(_('API version'), max_length=5, blank=False, help_text=_('Google Search API version'))
+    uri = models.URLField(_('URI'), verify_exists=True, max_length=255, blank=False, help_text=_('Google Search API URI'))
+    user_agent = models.CharField(_('User-Agent header'), max_length=255, blank=True, help_text=_('Not required for Google API; eg: "User-Agent: Softphone Beta1.5"'))
+    referrer = models.URLField(_('Referrer header'), verify_exists=True, max_length=255, blank=True, help_text=_('"Referer"[sic]; Leave blank for current site\'s domain; eg: "http://www.w3.org/hypertext/DataSources/Overview.html"'))
+    search_engine_id = models.CharField(_('CSE id'), max_length=255, blank=True, help_text=_('Google Custom Search Engine (CSE) id'))
+    result_size = models.CharField(_('Result set size'), max_length=50, blank=True, help_text=_('Size of Google API result set; leave blank for default'))
+    objects = models.Manager()
+    on_site = CurrentSiteManager()
+
+    def __unicode__(self):
+        return self.__doc__
+
+    class Meta:
+        verbose_name_plural = _('settings')
+
+
+#get custom templates from settings or use default
+CMSPLUGIN_GOOGLESEARCH_TEMPLATES_CHOICES = getattr(settings,"CMSPLUGIN_GOOGLESEARCH_TEMPLATES", (('default', 'googlesearch_plugin.html'),) )
+
+#get custom css from settings or use default
+CMSPLUGIN_GOOGLESEARCH_CSS_CHOICES = getattr(settings,"CMSPLUGIN_GOOGLESEARCH_CSS", (('0', ''),('1', 'left'),('2', 'right'),('3', 'center'),) )
+
+class GoogleSearchPlugin(CMSPlugin):
+    query = models.CharField(_('Query string'), max_length=255, blank=True, help_text=_('Custom query'))
+    css = models.CharField(_('CSS class'), max_length=1, choices=CMSPLUGIN_GOOGLESEARCH_CSS_CHOICES, default='0', help_text=_('Additional CSS class to apply'))
+    template = models.CharField(_('Plugin template'), max_length=255, choices=CMSPLUGIN_GOOGLESEARCH_TEMPLATES_CHOICES, default=CMSPLUGIN_GOOGLESEARCH_TEMPLATES_CHOICES[0][0], help_text=_('Template used to render plugin'))

cmsplugin_googlesearch/templates/plugins/cmsplugin_googlesearch/googlesearch.html

+{% extends "index.html" %}
+{% load cache cms_tags i18n %}
+
+{% block title %}
+     Search results for {{ q }}
+{% endblock title %}
+
+{% block page-title %}{% endblock page-title %}
+
+<div class="content-main">
+{% block content %}
+    {% placeholder content-main %}
+    {% spaceless %}
+
+    {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
+
+    <form action="." method="post">
+        <style type="text/css">
+            @import url(http://www.google.com/cse/api/branding.css);
+        </style>
+        <div class="cse-branding-logo">
+            <img src="http://www.google.com/images/poweredby_transparent/poweredby_FFFFFF.gif" alt="Google" />
+        </div>
+        <div class="cse-branding-text">
+            Custom Search
+        </div>
+        {% for field in form %}
+                <div class="form-error">{{ field.errors }}</div>
+                <div class="form-left">
+                    {{ field.label_tag }}{% if field.field.required %}<span class="form-required">*</span>{% endif %}
+                </div>
+                <div class="form-right">
+                    {{ field }}
+                </div>
+                <div class="help_text">{{ field.help_text }}</div>
+        {% endfor %}
+        <div class="gsc-branding-text">powered by</div>
+        <div class="gsc-branding-img-noclear"><img src="http://www.google.com/uds/css/small-logo.png" class="gsc-branding-img-noclear"></div>
+
+        <input type="submit" name="submit" class="button" value="{% trans "Search" %}">
+    </form>
+
+    {% if results %}
+    <h2>Search Results for {{ q|safe }}</h2>
+    <ul>
+        {% for result in results %}
+        <li><a href="{{ result.unescapedUrl }}">{{ result.title|safe }}</a>
+        <ul>
+            <li>{{ result.content|safe }}
+        </ul>
+        {% endfor %}
+    </ul>
+    {% endif %}
+
+    {% endspaceless %}
+{% endblock content %}
+</div>

cmsplugin_googlesearch/templates/plugins/cmsplugin_googlesearch/googlesearch_plugin.html

+{% load cache cms_tags i18n %}
+    <div class="googlesearch-plugin{% if css %} {{ css }}{% endif %}">
+        <form action="{{ redirect }}" method="post">
+            <style type="text/css">
+                @import url(http://www.google.com/cse/api/branding.css);
+            </style>
+            <div class="cse-branding-logo">
+                <img src="http://www.google.com/images/poweredby_transparent/poweredby_FFFFFF.gif" alt="Google" />
+            </div>
+            <div class="cse-branding-text">
+                Custom Search
+            </div>
+            {% comment %} very basic django form here, sine we are redirecting anyway {% endcomment %}
+            {% for field in form %}
+                <div class="form-left">
+                    {{ field.label_tag }}{% if field.field.required %}<span class="form-required">*</span>{% endif %}
+                </div>
+                <div class="form-right">
+                    {{ field }}
+                </div>
+                <div class="help_text">{{ field.help_text }}</div>
+            {% endfor %}
+            <div class="gsc-branding-text">powered by</div>
+            <div class="gsc-branding-img-noclear"><img src="http://www.google.com/uds/css/small-logo.png" class="gsc-branding-img-noclear"></div>
+            <input type="submit" class="button" value="{% trans "Search" %}">
+        </form>
+    </div>

cmsplugin_googlesearch/urls.py

+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('cmsplugin_googlesearch.views',
+    (r'^$', 'search'),
+)

cmsplugin_googlesearch/views.py

+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from cmsplugin_googlesearch.models import GoogleSearchSettings
+from cmsplugin_googlesearch.forms import GoogleSearchForm
+import django_pipes
+from django.contrib.sites.models import Site
+
+
+class GoogleSearch(django_pipes.Pipe):
+    """ Formats and executes Google API searches """
+
+    #get settings for cmsplugin_googlesearch
+    g = GoogleSearchSettings.on_site.all().select_related()[0]
+
+#    import ipdb; ipdb.set_trace()
+    uri = g.uri
+
+    #if referrer is not in settings, get it from current site
+    if not g.referrer:
+        g.referrer = 'http://%s' % Site.objects.get_current().domain
+
+    headers = {}
+    if g.user_agent:
+        headers.update({'User-Agent' : g.user_agent})
+    if g.referrer:
+        headers.update({'User-Referer' : g.referrer})
+
+#    import ipdb; ipdb.set_trace()
+
+#    @staticmethod
+    @classmethod
+    def fetch(self, query):
+#        import ipdb; ipdb.set_trace()
+
+        g = self.g
+
+        GET_args = {
+            'q': query,                                     #query string, eg: 'q=Paris%20Hilton'
+        }
+
+        GET_args.update({'v': g.api_version })              #google api version is required
+
+        if g.search_engine_id:
+            GET_args.update({'cx': g.search_engine_id })
+        if g.result_size:
+            GET_args.update({'rsz': g.result_size })
+
+        resp = GoogleSearch.objects.get(GET_args)           #execute the search
+
+        if resp and hasattr(resp, "responseData") and hasattr(resp.responseData, "results"):
+            return resp.responseData.results
+
+
+def search(request, form_class=GoogleSearchForm, template_name='plugins/cmsplugin_googlesearch/googlesearch.html'):
+    """ Renders a search form, validates its input, returns results """
+
+    #initial values
+    query = ''
+    results = ''
+    form = form_class()
+
+    #if the form has been sent, get results; otherwise send the empty form
+    if request.method == 'POST':
+        form = form_class(request.POST)
+#        import pdb; pdb.set_trace()
+        if form.is_valid():
+            cd = form.cleaned_data
+            query = request.GET.get('q', cd['query'])
+            results = GoogleSearch.fetch(query)
+
+#    import pdb; pdb.set_trace()
+
+    #django-cms requires RequestContext
+    return render_to_response(template_name, {'form': form, 'results': results, 'q': query, }, context_instance=RequestContext(request))
Added
New image
+#!/usr/bin/env python
+from setuptools import setup, find_packages
+import os
+import cmsplugin_googlesearch
+media_files = []
+
+for dirpath, dirnames, filenames in os.walk('cmsplugin_googlesearch'):
+    media_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
+
+setup(
+    author="tehfink",
+    name='cmsplugin-googlesearch',
+    version=cmsplugin_googlesearch.__version__,
+    description='plugin bridge between django-cms & google search api',
+    long_description=open(os.path.join(os.path.dirname(__file__), 'README.txt')).read(),
+    url='http://bitbucket.org/tehfink/cmsplugin-googlesearch/',
+    license='BSD License',
+    platforms=['OS Independent'],
+    requires=[
+        'django (>=1.1.1)',
+        'cms (=2.0.2)',
+    ],
+    
+    packages=find_packages(),
+    package_dir={
+        'cmsplugin_googlesearch': 'cmsplugin_googlesearch',
+    },
+    data_files = media_files,
+    package_data = {
+        'cmsplugin_googlesearch': [
+            'fixtures/*.json',
+            'templates/plugins/cmsplugin_googlesearch/*.html',
+        ],
+    },
+    include_package_data=True,
+    install_requires=['setuptools'],
+    zip_safe = False,
+    classifiers = [
+        'Development Status :: 4 - Beta',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: BSD License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Framework :: Django',
+    ],
+
+)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.