Changeset 193

Show
Ignore:
Timestamp:
08/18/08 22:16:35 (3 months ago)
Author:
rgrp
Message:

[shakespeare/stats][m]: add charting to support to text stats page using pygooglechart.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/setup.py

    Revision 155 Revision 193
    1try: 1try: 
    2    from setuptools import setup, find_packages 2    from setuptools import setup, find_packages 
    3except ImportError: 3except ImportError: 
    4    from ez_setup import use_setuptools 4    from ez_setup import use_setuptools 
    5    use_setuptools() 5    use_setuptools() 
    6    from setuptools import setup, find_packages 6    from setuptools import setup, find_packages 
    7 7 
    8import sys 8import sys 
    9sys.path.insert(0, '.') 9sys.path.insert(0, '.') 
    10from shakespeare import __version__, __application_name__ 10from shakespeare import __version__, __application_name__ 
    11from shakespeare import __doc__ as __long_description__ 11from shakespeare import __doc__ as __long_description__ 
    12 12 
    13setup( 13setup( 
    14    name = __application_name__, 14    name = __application_name__, 
    15    version = __version__, 15    version = __version__, 
    16    packages=find_packages(exclude=['ez_setup']), 16    packages=find_packages(exclude=['ez_setup']), 
    17    include_package_data=True, 17    include_package_data=True, 
    18 18 
    19    install_requires=[ 19    install_requires=[ 
    20        'Pylons>=0.9.6.1', 20        'Pylons>=0.9.6.1', 
    21        'SQLObject>=0.6', 21        'SQLObject>=0.6', 
    22        'Genshi>=0.3', 22        'Genshi>=0.3', 
    23        'annotater>=0.1',  23         'pygooglechart>=0.2,<0.3', 
       24         # 'annotater>=0.1', 
    24        ], 25        ], 
    25    test_suite='nose.collector', 26    test_suite='nose.collector', 
    26    package_data={'shakespeare': ['i18n/*/LC_MESSAGES/*.mo']}, 27    package_data={'shakespeare': ['i18n/*/LC_MESSAGES/*.mo']}, 
    27    #message_extractors = {'shakespeare': [ 28    #message_extractors = {'shakespeare': [ 
    28    #        ('**.py', 'python', None), 29    #        ('**.py', 'python', None), 
    29    #        ('public/**', 'ignore', None)]}, 30    #        ('public/**', 'ignore', None)]}, 
    30    entry_points=''' 31    entry_points=''' 
    31    [paste.app_factory] 32    [paste.app_factory] 
    32    main = shakespeare.config.middleware:make_app 33    main = shakespeare.config.middleware:make_app 
    33 34 
    34    [paste.app_install] 35    [paste.app_install] 
    35    main = pylons.util:PylonsInstaller 36    main = pylons.util:PylonsInstaller 
    36 37 
    37    [console_scripts] 38    [console_scripts] 
    38    shakespeare-admin=shakespeare.cli:main 39    shakespeare-admin=shakespeare.cli:main 
    39    ''', 40    ''', 
    40 41 
    41    # metadata for upload to PyPI 42    # metadata for upload to PyPI 
    42    author = "Open Knowledge Foundation", 43    author = "Open Knowledge Foundation", 
    43    author_email = 'info@okfn.org', 44    author_email = 'info@okfn.org', 
    44    description = \ 45    description = \ 
    45"A full open set of Shakespeare's works along with anciallary material, a variety of tools and a python api", 46"A full open set of Shakespeare's works along with anciallary material, a variety of tools and a python api", 
    46    long_description = __long_description__, 47    long_description = __long_description__, 
    47    license = "MIT", 48    license = "MIT", 
    48    keywords = "open shakespeare search view", 49    keywords = "open shakespeare search view", 
    49    url = "http://www.openshakespeare.org/",  50    url = "http://www.openshakespeare.org/",  
    50    download_url = "http://www.openshakespeare.org/code/", 51    download_url = "http://www.openshakespeare.org/code/", 
    51    classifiers = [ 52    classifiers = [ 
    52        'Development Status :: 4 - Beta', 53        'Development Status :: 4 - Beta', 
    53        'Environment :: Console', 54        'Environment :: Console', 
    54        'Environment :: Web Environment', 55        'Environment :: Web Environment', 
    55        'Intended Audience :: Developers', 56        'Intended Audience :: Developers', 
    56        'License :: OSI Approved :: MIT License', 57        'License :: OSI Approved :: MIT License', 
    57        'Operating System :: OS Independent', 58        'Operating System :: OS Independent', 
    58        'Programming Language :: Python', 59        'Programming Language :: Python', 
    59        'Topic :: Software Development :: Libraries :: Python Modules'], 60        'Topic :: Software Development :: Libraries :: Python Modules'], 
    60) 61) 
  • trunk/shakespeare/controllers/stats.py

    Revision 187 Revision 193
    1import logging 1import logging 
    2 2 
      3import pygooglechart 
      4 
    3from shakespeare.lib.base import * 5from shakespeare.lib.base import * 
    4   
    5log = logging.getLogger(__name__) 6log = logging.getLogger(__name__) 
    6   
    7import shakespeare.stats 7import shakespeare.stats 
    8 8 
    9class StatsController(BaseController): 9class StatsController(BaseController): 
    10 10 
    11    def index(self): 11    def index(self): 
    12        return render('stats/index') 12        return render('stats/index') 
    13     13     
    14    def text(self, id): 14    def text(self, id): 
    15        text_name = id 15        text_name = id 
    16        text = model.Material.byName(text_name) 16        text = model.Material.byName(text_name) 
    17        stats = shakespeare.stats.Stats() 17        stats = shakespeare.stats.Stats() 
    18        c.text = text 18        c.text = text 
    19        c.stats = stats.text_stats(text) 19        c.stats = stats.text_stats(text) 
      20        # 40 seems limit for google 
      21        data = [ (s.word, s.freq) for s in c.stats[:40] ] 
      22        c.img_url = self.vertical_bar_chart(data) 
    20        return render('stats/text') 23        return render('stats/text') 
    21 24 
      25    # TODO: factor this out to its module (?) 
      26    def vertical_bar_chart(self, data, width=500): 
      27        # tranpose 
      28        tdata = zip(*data) 
      29        labels = list(tdata[0]) 
      30        values = tdata[1] 
      31        bar_width = 10 
      32        # add 5 for space between bars 
      33        height = (bar_width + 5) * len(values) 
      34        # was setting x_range but automatic behaviour seems better 
      35        # x_range = (min(values), max(values)) 
      36        chart = pygooglechart.StackedHorizontalBarChart(width, height) 
      37        chart.set_bar_width(bar_width) 
      38        chart.set_colours(['cc0033']) 
      39        chart.add_data(values) 
      40        # have to reverse the labels for vertical 
      41        labels.reverse() 
      42        chart.set_axis_labels(pygooglechart.Axis.LEFT, labels) 
      43        chart.set_axis_range(pygooglechart.Axis.BOTTOM, 0, max(values)) 
      44        chart.set_axis_range(pygooglechart.Axis.TOP, 0, max(values)) 
      45        url = chart.get_url() 
      46        return url 
      47 
  • trunk/shakespeare/templates/layout.html

    Revision 181 Revision 193
    1<html xmlns="http://www.w3.org/1999/xhtml" 1<html xmlns="http://www.w3.org/1999/xhtml" 
    2  xmlns:py="http://genshi.edgewall.org/"  2  xmlns:py="http://genshi.edgewall.org/"  
    3  xmlns:xi="http://www.w3.org/2001/XInclude"> 3  xmlns:xi="http://www.w3.org/2001/XInclude"> 
    4 4 
    5<head> 5<head> 
    6  <title>Open Shakespeare - ${page_title()}</title> 6  <title>Open Shakespeare - ${page_title()}</title> 
    7 7 
    8  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    9  <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen, print" title="Master stylesheet" charset="utf-8" /> 9  <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen, print" title="Master stylesheet" charset="utf-8" /> 
    10  <script type="text/javascript" src="/scripts/prototype.js"></script> 10  <script type="text/javascript" src="/scripts/prototype.js"></script> 
    11  <script type="text/javascript" src="/scripts/behaviour.js"></script> 11  <script type="text/javascript" src="/scripts/behaviour.js"></script> 
    12  <script type="text/javascript" src="/scripts/master.js"></script> 12  <script type="text/javascript" src="/scripts/master.js"></script> 
    13  <style type="text/css"> 13  <style type="text/css"> 
    14    /* remove login info at top-right */ 14    /* remove login info at top-right */ 
    15    #top-bar { display: none; } 15    #top-bar { display: none; } 
    16    /* mess with standard ckan theme to remove second submenu for time being */ 16    /* mess with standard ckan theme to remove second submenu for time being */ 
    17    #subnav { background: transparent; height: 1px; } 17    #subnav { background: transparent; height: 1px; } 
    18    #subnav * { display: none; } 18    #subnav * { display: none; } 
    19  </style> 19  </style> 
    20 20 
    21  <py:if test="page_specific_css"> 21  <py:if test="page_specific_css"> 
    22    ${page_specific_css()} 22    ${page_specific_css()} 
    23  </py:if> 23  </py:if> 
    24</head> 24</head> 
    25 25 
    26<body> 26<body> 
    27<div id="airlock"> 27<div id="airlock"> 
    28  <!--[if IE]> 28  <!--[if IE]> 
    29    <hr class="holder" /> 29    <hr class="holder" /> 
    30  <![endif]--> 30  <![endif]--> 
    31  <div id="top"> 31  <div id="top"> 
    32    <div id="top-inner"> 32    <div id="top-inner"> 
    33      <div id="top-bar"> 33      <div id="top-bar"> 
    34        <topbar> 34        <topbar> 
    35         35         
    36        <py:choose> 36        <py:choose> 
    37        <py:when test="c.user"> 37        <py:when test="c.user"> 
    38        <p> 38        <p> 
    39          Logged in as <strong>${c.user}</strong>  39          Logged in as <strong>${c.user}</strong>  
    40          | <a href="/account/logout/">Logout</a> 40          | <a href="/account/logout/">Logout</a> 
    41        </p> 41        </p> 
    42        </py:when> 42        </py:when> 
    43        <py:otherwise> 43        <py:otherwise> 
    44          <p> 44          <p> 
    45          <a href="/account/">Register</a> or 45          <a href="/account/">Register</a> or 
    46          <a href="/account/login/">Login</a> 46          <a href="/account/login/">Login</a> 
    47          </p> 47          </p> 
    48        </py:otherwise> 48        </py:otherwise> 
    49        </py:choose> 49        </py:choose> 
    50        </topbar> 50        </topbar> 
    51      </div><!-- /top-bar --> 51      </div><!-- /top-bar --> 
    52    <h1><a href="${h.url_for(controller='site', action='home')}" title="Open Shakespeare Home">Open Shakespeare</a></h1> 52    <h1><a href="${h.url_for(controller='site', action='home')}" title="Open Shakespeare Home">Open Shakespeare</a></h1> 
    53     53     
    54    </div><!-- /top-inner --> 54    </div><!-- /top-inner --> 
    55      55      
    56    <h3 class="hidden">Sections:</h3> 56    <h3 class="hidden">Sections:</h3> 
    57    <ul id="navigation"> 57    <ul id="navigation"> 
    58      <li><a href="${h.url_for('/')}">Home</a></li> 58      <li><a href="${h.url_for('/')}">Home</a></li> 
    59      <li><a href="${h.url_for(controller='text', action='index')}">Texts</a></li> 59      <li><a href="${h.url_for(controller='text', action='index')}">Texts</a></li> 
    60      <li><a href="${h.url_for(controller='search', action='index')}">Search</a></li> 60      <li><a href="${h.url_for(controller='search', action='index')}">Search</a></li> 
      61      <li><a href="${h.url_for(controller='stats', action='index')}">Stats</a></li> 
    61      <li><a href="${h.url_for(controller='site', action='guide')}">Guide</a></li> 62      <li><a href="${h.url_for(controller='site', action='guide')}">Guide</a></li> 
    62    </ul> 63    </ul> 
    63    <h3 class="hidden">In this section:</h3> 64    <h3 class="hidden">In this section:</h3> 
    64    <ul id="subnav"> 65    <ul id="subnav"> 
    65      <minornavigation> 66      <minornavigation> 
    66      <li><a href="${h.url_for(controller='site', action='index')}">Home</a></li> 67      <li><a href="${h.url_for(controller='site', action='index')}">Home</a></li> 
    67      <py:choose> 68      <py:choose> 
    68      <py:when test="c.user"> 69      <py:when test="c.user"> 
    69      <li><a href="/account/logout/">Logout</a></li> 70      <li><a href="/account/logout/">Logout</a></li> 
    70      </py:when> 71      </py:when> 
    71      <py:otherwise> 72      <py:otherwise> 
    72      <li><a href="/account/">Register</a></li> 73      <li><a href="/account/">Register</a></li> 
    73      <li><a href="/account/login/">Login</a></li> 74      <li><a href="/account/login/">Login</a></li> 
    74      </py:otherwise> 75      </py:otherwise> 
    75      </py:choose> 76      </py:choose> 
    76      <li><a href="/package/new/">New Package</a></li> 77      <li><a href="/package/new/">New Package</a></li> 
    77      </minornavigation> 78      </minornavigation> 
    78    </ul> 79    </ul> 
    79        80        
    80    <!--[if IE]> 81    <!--[if IE]> 
    81    <hr class="holder" /> 82    <hr class="holder" /> 
    82    <![endif]--> 83    <![endif]--> 
    83     84     
    84  </div><!-- /top --> 85  </div><!-- /top --> 
    85   86   
    86  <p class="hidden"><a href="#main" title="Skip to page content">[ Skip to main content ]</a></p>  87  <p class="hidden"><a href="#main" title="Skip to page content">[ Skip to main content ]</a></p>  
    87   88   
    88  <div id="primary" class="sidebar"> 89  <div id="primary" class="sidebar"> 
    89    <div class="box"> 90    <div class="box"> 
    90      <h2>Further Assistance</h2> 91      <h2>Further Assistance</h2> 
    91      <p>For information on using Open Shakespeare check out the 92      <p>For information on using Open Shakespeare check out the 
    92      <a href="${h.url_for(action='guide')}">Guide</a>. 93      <a href="${h.url_for(action='guide')}">Guide</a>. 
    93      If you have a question or have found a bug please post to the <a href="http://lists.okfn.org/mailman/listinfo/okfn-help">okfn-help</a> mailing list. 94      If you have a question or have found a bug please post to the <a href="http://lists.okfn.org/mailman/listinfo/okfn-help">okfn-help</a> mailing list. 
    94      </p> 95      </p> 
    95    </div> 96    </div> 
    96    <primarysidebar> 97    <primarysidebar> 
    97    <!-- Primary Side Bar Goes Here --> 98    <!-- Primary Side Bar Goes Here --> 
    98    </primarysidebar> 99    </primarysidebar> 
    99     100     
    100    <!--[if IE]> 101    <!--[if IE]> 
    101    <hr class="primary" /> 102    <hr class="primary" /> 
    102    <![endif]--> 103    <![endif]--> 
    103     104     
    104  </div><!-- /primary --> 105  </div><!-- /primary --> 
    105 106 
    106  <div id="main"> 107  <div id="main"> 
    107    <h2>${page_title()}</h2> 108    <h2>${page_title()}</h2> 
    108    <content> 109    <content> 
    109      <p>Master content template placeholder &hellip; please replace me.</p> 110      <p>Master content template placeholder &hellip; please replace me.</p> 
    110    </content> 111    </content> 
    111     112     
    112    <div id="footer"> 113    <div id="footer"> 
    113      <p> 114      <p> 
    114        <a href="http://validator.w3.org/check/referer" title="Valid XHTML 1.1">XHTML</a> 115        <a href="http://validator.w3.org/check/referer" title="Valid XHTML 1.1">XHTML</a> 
    115        | <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> 116        | <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> 
    116        | <a href="http://www.okfn.org/shakespeare/">Project Home Page</a> 117        | <a href="http://www.okfn.org/shakespeare/">Project Home Page</a> 
    117        | <a href="mailto:info@okfn.org">Contact Us</a> 118        | <a href="mailto:info@okfn.org">Contact Us</a> 
    118      </p> 119      </p> 
    119      <p> 120      <p> 
    120        <img style="margin-bottom: -5px;" src="http://m.okfn.org/images/logo/okf_logo_white_and_green_tiny.png" /> An <a href="http://www.okfn.org/">Open Knowledge Foundation</a> Project 121        <img style="margin-bottom: -5px;" src="http://m.okfn.org/images/logo/okf_logo_white_and_green_tiny.png" /> An <a href="http://www.okfn.org/">Open Knowledge Foundation</a> Project 
    121      </p> 122      </p> 
    122      <p> 123      <p> 
    123        (c) Open Knowledge Foundation 124        (c) Open Knowledge Foundation 
    124        | All material available under an <a href="/license/">open license</a> 125        | All material available under an <a href="/license/">open license</a> 
    125        | <a href="http://www.opendefinition.org/1.0/"><img 126        | <a href="http://www.opendefinition.org/1.0/"><img 
    126            style="border: none; margin-bottom: -4px;" 127            style="border: none; margin-bottom: -4px;" 
    127            src="http://m.okfn.org/images/ok_buttons/ok_90x15_blue.png" 128            src="http://m.okfn.org/images/ok_buttons/ok_90x15_blue.png" 
    128            alt="This Content and Data is Open" /></a> 129            alt="This Content and Data is Open" /></a> 
    129      </p> 130      </p> 
    130    </div><!-- /footer --> 131    </div><!-- /footer --> 
    131     132     
    132    <!--[if IE]> 133    <!--[if IE]> 
    133    <hr class="main" /> 134    <hr class="main" /> 
    134    <![endif]--> 135    <![endif]--> 
    135     136     
    136  </div><!-- /main --> 137  </div><!-- /main --> 
    137 138 
    138</div><!-- /airlock --> 139</div><!-- /airlock --> 
    139</body> 140</body> 
    140</html> 141</html> 
  • trunk/shakespeare/templates/stats/text.html

    Revision 187 Revision 193
    1<html xmlns:py="http://genshi.edgewall.org/" 1<html xmlns:py="http://genshi.edgewall.org/" 
    2  xmlns:xi="http://www.w3.org/2001/XInclude"> 2  xmlns:xi="http://www.w3.org/2001/XInclude"> 
    3   3   
    4  <py:def function="page_title">Stats for ${c.text.name}</py:def> 4  <py:def function="page_title">Stats for ${c.text.title}</py:def> 
    5 5 
    6  <div py:match="content"> 6  <div py:match="content"> 
    7    <table border="1">  7     <img style="float: left;" 
       8       src="${c.img_url}" 
       9       alt="Word Statistics Bar Chart" /> 
       10  
       11     <table border="1" style="margin-left: 550px;"> 
    8    <thead> 12    <thead> 
    9      <tr> 13      <tr> 
      14        <th>Index</th> 
    10        <th> 15        <th> 
    11          Word   16          Word   
    12        </th> 17        </th> 
    13        <th> 18        <th> 
    14          Frequency 19          Frequency 
    15        </th> 20        </th> 
    16      </tr> 21      </tr> 
    17    </thead> 22    </thead> 
    18    <tbody> 23    <tbody> 
    19      <tr py:for="stat in c.stats">  24       <tr py:for="index, stat in enumerate(c.stats)"> 
       25         <td> 
       26           ${index + 1} 
       27         </td> 
    20        <td> 28        <td> 
    21          ${stat.word} 29          ${stat.word} 
    22        </td> 30        </td> 
    23        <td> 31        <td> 
    24          ${stat.freq} 32          ${stat.freq} 
    25        </td> 33        </td> 
    26      </tr> 34      </tr> 
    27    </tbody> 35    </tbody> 
    28    </table> 36    </table> 
    29  </div> 37  </div> 
    30 38 
    31  <xi:include href="../layout.html" /> 39  <xi:include href="../layout.html" /> 
    32</html> 40</html>