Changeset 3920

Show
Ignore:
Timestamp:
06/29/08 17:07:23 (6 months ago)
Author:
doki_pen
Message:

merged changes from optaros oforge project

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • irclogsplugin/0.11/irclogs/htdocs/style.css

    r1875 r3920  
    9494    font-size: 0.8em; 
    9595} 
     96 
     97a.dp-choose-date { 
     98        width: 16px; 
     99        height: 16px; 
     100        padding: 0; 
     101        margin: 5px 0px; 
     102        text-indent: -2000px; 
     103        overflow: hidden; 
     104        background: url(calendar.png) no-repeat;  
     105} 
     106a.dp-choose-date.dp-disabled { 
     107        background-position: 0 -20px; 
     108        cursor: default; 
     109        text-size: 10px; 
     110} 
     111input.dp-applied { 
     112        display: none; 
     113} 
     114 
     115div.irclogs div.navcal { 
     116        position: relative; 
     117        float: right; 
     118        top: -15px; 
     119} 
     120 
     121div.navcal a.previous { 
     122        margin-right: 20px; 
     123} 
     124 
     125div.navcal a.next { 
     126        margin-left: 20px; 
     127} 
     128 
     129div.navcal a.link-datepicker { 
     130        margin-right: 4px; 
     131} 
     132 
     133div.irclogs input#showactions { 
     134        float: left; 
     135} 
     136div#irclog-controls { 
     137  display: none; 
     138  padding-left: 10px;  
     139  padding-right: 10px; 
     140  margin-bottom: -15px; 
     141} 
     142.irclogs tr.server, .irclogs tr.hidden_user { 
     143  display:none; 
     144} 
     145 
  • irclogsplugin/0.11/irclogs/__init__.py

    r2591 r3920  
    1 # -*- coding: utf-8 -*- 
    2 import os 
    3 import re 
    4 import calendar 
    5 from datetime import datetime 
    6 from trac.core import * 
    7 from trac.perm import IPermissionRequestor 
    8 from trac.config import Option 
    9 from trac.web.chrome import INavigationContributor, ITemplateProvider, \ 
    10                             add_stylesheet 
    11 from trac.web.main import IRequestHandler 
    12 from trac.util.html import escape, html, Markup 
    13 from trac.util.text import to_unicode 
    14  
    15  
    16 class IrclogsPlugin(Component): 
    17     implements(INavigationContributor, ITemplateProvider, IRequestHandler, \ 
    18                IPermissionRequestor) 
    19     _url_re = re.compile(r'^/irclogs(/(?P<year>\d{4})(/(?P<month>\d{2})' 
    20                          r'(/(?P<day>\d{2}))?)?)?/?$') 
    21 # TODO: make the line format somewhat configurable 
    22 # Uncomment the following line if using a pipe as a divider and a space 
    23 # between the date adn time.  Make sure to comment out the existing 
    24 # _line_re. 
    25 #    _line_re = re.compile('%s %s \|  (%s)$' % ( 
    26     _line_re = re.compile('%sT%s  (%s)$' % ( 
    27         r'(?P<date>\d{4}-\d{2}-\d{2})', 
    28         r'(?P<time>\d{2}:\d{2}:\d{2})', 
    29         '|'.join([ 
    30             r'(<(?P<c_nickname>.*?)> (?P<c_text>.*?))', 
    31             r'(\* (?P<a_nickname>.*?) (?P<a_text>.*?))', 
    32             r'(\*\*\* (?P<s_nickname>.*?) (?P<s_text>.*?))' 
    33         ])) 
    34     ) 
    35     charset = Option('irclogs', 'charset', 'utf-8', 
    36                      doc='Channel charset') 
    37     file_format = Option('irclogs', 'file_format', '#channel.%Y-%m-%d.log', 
    38                          doc='Format of a logfile for a given day. Must ' 
    39                              'include %Y, %m and %d. Example: ' 
    40                              '#channel.%Y-%m-%d.log') 
    41     path = Option('irclogs', 'path', '', 
    42                   doc='The path where the irc logfiles are') 
    43     navbutton = Option('irclogs', 'navigation_button', '', 
    44                        doc='If not empty an button with this value as caption ' 
    45                            'is added to the navigation bar, pointing to the ' 
    46                            'irc plugin') 
    47  
    48     def _to_unicode(self, iterable): 
    49         for line in iterable: 
    50             yield to_unicode(line, self.charset) 
    51  
    52     def _get_file_re(self): 
    53         return re.compile(r'^%s$' % re.escape(self.file_format) 
    54               .replace('\\%Y', '(?P<year>\d{4})') 
    55               .replace('\\%m', '(?P<month>\d{2})') 
    56               .replace('\\%d', '(?P<day>\d{2})') 
    57         ) 
    58  
    59     def _get_filename(self, year, month, day): 
    60         return os.path.join(self.path, self.file_format 
    61                 .replace('%Y', str(year)) 
    62                 .replace('%m', str(month)) 
    63                 .replace('%d', str(day)) 
    64         ) 
    65  
    66     def _render_lines(self, iterable): 
    67         dummy = lambda: {} 
    68         result = [] 
    69         for line in iterable: 
    70             d = getattr(self._line_re.search(line), 'groupdict', dummy)() 
    71             for mode in ('channel', 'action', 'server'): 
    72                 prefix = mode[0] 
    73                 text = d.get('%s_text' % prefix) 
    74                 if not text is None: 
    75                     nick = d['%s_nickname' % prefix] 
    76                     break 
    77             else: 
    78                 continue 
    79             result.append({ 
    80                 'date':         d['date'], 
    81                 'time':         d['time'], 
    82                 'mode':         mode, 
    83                 'text':         text, 
    84                 'nickname':     nick, 
    85                 'nickcls':      'nick-%d' % (sum(ord(c) for c in nick) % 8) 
    86             }) 
    87         return result 
    88  
    89     def _generate_calendar(self, req, entries): 
    90         if not req.args['year'] is None: 
    91             year = int(req.args['year']) 
    92         else: 
    93             year = datetime.now().year 
    94         if not req.args['month'] is None: 
    95             month = int(req.args['month']) 
    96         else: 
    97             month = datetime.now().month 
    98         if not req.args['day'] is None: 
    99             today = int(req.args['day']) 
    100         else: 
    101             today = -1 
    102         this_month_entries = entries.get(year, {}).get(month, {}) 
    103  
    104         weeks = [] 
    105         for week in calendar.monthcalendar(year, month): 
    106             w = [] 
    107             for day in week: 
    108                 if not day: 
    109                     w.append({ 
    110                         'empty':    True 
    111                     }) 
    112                 else: 
    113                     w.append({ 
    114                         'caption':  day, 
    115                         'href':     req.href('irclogs', year, 
    116                                              '%02d' % month, '%02d' % day), 
    117                         'today':    day == today, 
    118                         'has_log':  day in this_month_entries 
    119                     }) 
    120             weeks.append(w) 
    121  
    122         next_month_year = year 
    123         next_month = int(month) + 1 
    124         if next_month > 12: 
    125             next_month_year += 1 
    126             next_month = 1 
    127         if today > -1: 
    128             next_month_href = req.href('irclogs', next_month_year, 
    129                                        '%02d' % next_month, '%02d' % today) 
    130         else: 
    131             next_month_href = req.href('irclogs', next_month_year, 
    132                                        '%02d' % next_month) 
    133  
    134         prev_month_year = year 
    135         prev_month = int(month) - 1 
    136         if prev_month < 1: 
    137             prev_month_year -= 1 
    138             prev_month = 12 
    139         if today > -1: 
    140             prev_month_href = req.href('irclogs', prev_month_year, 
    141                                        '%02d' % prev_month, '%02d' % today) 
    142         else: 
    143             prev_month_href = req.href('irclogs', prev_month_year, 
    144                                        '%02d' % prev_month) 
    145  
    146         return { 
    147             'year':         year, 
    148             'month':        month, 
    149             'weeks':        weeks, 
    150             'next_year':    { 
    151                 'caption':      str(year + 1), 
    152                 'href':         req.href('irclogs', year + 1) 
    153             }, 
    154             'prev_year':    { 
    155                 'caption':      str(year - 1), 
    156                 'href':         req.href('irclogs', year - 1) 
    157             }, 
    158             'next_month':   { 
    159                 'caption':      '%02d' % next_month, 
    160                 'href':         next_month_href 
    161             }, 
    162             'prev_month':   { 
    163                 'caption':      '%02d' % prev_month, 
    164                 'href':         prev_month_href 
    165             }, 
    166         } 
    167  
    168     # INavigationContributor methods 
    169     def get_active_navigation_item(self, req): 
    170         if self.navbutton.strip(): 
    171             return 'irclogs' 
    172  
    173     def get_navigation_items(self, req): 
    174         if req.perm.has_permission('IRCLOGS_VIEW'): 
    175             title = self.navbutton.strip() 
    176             if title: 
    177                 yield 'mainnav', 'irclogs', html.A(title, href=req.href.irclogs()) 
    178  
    179     # IPermissionHandler methods 
    180     def get_permission_actions(self): 
    181         return ['IRCLOGS_VIEW'] 
    182  
    183     # IRequestHandler methods 
    184     def match_request(self, req): 
    185         m = self._url_re.search(req.path_info) 
    186         if m is None: 
    187             return False 
    188         req.args.update(m.groupdict()) 
    189         return True 
    190  
    191     def process_request(self, req): 
    192         req.perm.assert_permission('IRCLOGS_VIEW') 
    193         add_stylesheet(req, 'irclogs/style.css') 
    194  
    195         file_re = self._get_file_re() 
    196  
    197         context = {} 
    198         entries = {} 
    199         files = os.listdir(self.path) 
    200         files.sort() 
    201         for fn in files: 
    202             m = file_re.search(fn) 
    203             if m is None: 
    204                 continue 
    205             d = m.groupdict() 
    206             y = entries.setdefault(int(d['year']), {}) 
    207             m = y.setdefault(int(d['month']), {}) 
    208             m[int(d['day'])] = True 
    209  
    210         if req.args['year'] is None: 
    211             years = entries.keys() 
    212             years.sort() 
    213             context['years'] = [{ 
    214                 'caption':      y, 
    215                 'href':         req.href('irclogs', y) 
    216             } for y in years] 
    217             context['viewmode'] = 'years' 
    218         elif req.args['month'] is None: 
    219             months = entries.get(int(req.args['year']), {}).keys() 
    220             months.sort() 
    221             context['months'] = [{ 
    222                 'caption':      m, 
    223                 'href':         req.href('irclogs', req.args['year'], 
    224                                          '%02d' % m) 
    225             } for m in months] 
    226             context['year'] = req.args['year'] 
    227             context['viewmode'] = 'months' 
    228         elif req.args['day'] is None: 
    229             year = entries.get(int(req.args['year']), {}) 
    230             days = year.get(int(req.args['month']), {}).keys() 
    231             days.sort() 
    232             context['days'] = [{ 
    233                 'caption':      d, 
    234                 'href':         req.href('irclogs', req.args['year'], 
    235                                          req.args['month'], '%02d' % d) 
    236             } for d in days] 
    237             context['year'] = req.args['year'] 
    238             context['month'] = req.args['month'] 
    239             context['viewmode'] = 'days' 
    240  
    241         context['cal'] = self._generate_calendar(req, entries) 
    242  
    243         if req.args['day'] is not None: 
    244             logfile = self._get_filename(req.args['year'], req.args['month'], 
    245                                          req.args['day']) 
    246             context['day'] = req.args['day'] 
    247             context['month'] = req.args['month'] 
    248             context['year'] = req.args['year'] 
    249             context['viewmode'] = 'day' 
    250  
    251             if not os.path.exists(logfile): 
    252                 context['missing'] = True 
    253             else: 
    254                 context['missing'] = False 
    255                 f = file(logfile) 
    256                 try: 
    257                     context['lines'] = self._render_lines(self._to_unicode(f)) 
    258                 finally: 
    259                     f.close() 
    260  
    261         return 'irclogs.html', context, None 
    262  
    263     # ITemplateProvider methods 
    264     def get_templates_dirs(self): 
    265         from pkg_resources import resource_filename 
    266         return [resource_filename(__name__, 'templates')] 
    267  
    268     def get_htdocs_dirs(self): 
    269         from pkg_resources import resource_filename 
    270         return [('irclogs', resource_filename(__name__, 'htdocs'))] 
     1import web_ui 
     2import macros 
     3import search 
     4import wiki 
     5from console import update_irc_search 
  • irclogsplugin/0.11/irclogs/templates/irclogs.html

    r1875 r3920  
    55      xmlns:xi="http://www.w3.org/2001/XInclude"> 
    66  <xi:include href="layout.html" /> 
    7   <head> 
    8     <title>IRC Logs</title> 
    9   </head> 
    10   <body> 
    11     <div id="content" class="irclogs"> 
    12       <h1>IRC Logs</h1> 
    13       <table class="minical"> 
    14         <tr class="head"> 
    15           <th colspan="7">${cal.year} ${cal.month}</th> 
    16         </tr> 
    17         <tr class="days"> 
    18           <th>Mo</th> 
    19           <th>Tu</th> 
    20           <th>We</th> 
    21           <th>Th</th> 
    22           <th>Fr</th> 
    23           <th>Sa</th> 
    24           <th>So</th> 
    25         </tr> 
    26         <tr class="week" py:for="week in cal.weeks"> 
    27           <py:for each="day in week"> 
    28             <td py:if="day.empty" class="empty">&nbsp;</td> 
    29             <td py:if="not day.empty" class="${day.has_log and 'has' or 'no'}_log"> 
    30               <a href="${day.href}">${day.caption}</a> 
    31             </td> 
    32           </py:for> 
    33         </tr> 
    34         <tr class="nav"> 
    35          <td><a href="${cal.prev_year.href}">◀</a></td> 
    36          <td><a href="${cal.prev_month.href}">◂</a></td> 
    37          <td colspan="3">&nbsp;</td> 
    38          <td><a href="${cal.next_month.href}">▾</a></td> 
    39          <td><a href="${cal.next_year.href}">▶</a></td> 
    40         </tr> 
    41       </table> 
    42  
     7  <xi:include href="irclogs_macros.html" /> 
     8   
     9 <head> 
     10 <title>Team Chat Logs</title> 
     11</head> 
     12  <body>  
     13  <div id="content" class="irclogs"> 
     14      <h1>Team Chat Logs</h1> 
     15      <div id="content" class="error" py:if="error"> 
     16        <div class="message">${message}</div> 
     17      </div> 
     18      <div id="nojscal" style="display: block;"> 
     19        <table class="minical"> 
     20          <tr class="head"> 
     21            <th colspan="7">${year} ${int_month}</th> 
     22          </tr> 
     23          <tr class="days"> 
     24            <th>Mo</th> 
     25            <th>Tu</th> 
     26            <th>We</th> 
     27            <th>Th</th> 
     28            <th>Fr</th> 
     29            <th>Sa</th> 
     30            <th>Su</th> 
     31          </tr> 
     32          <tr class="week" py:for="week in cal.weeks"> 
     33            <py:for each="day in week"> 
     34              <td py:if="day.empty" class="empty">&nbsp;</td> 
     35              <td py:if="not day.empty" class="${day.has_log and 'has' or 'non'}_log"> 
     36                <a href="${day.href}">${day.caption}</a> 
     37              </td> 
     38            </py:for> 
     39          </tr> 
     40          <tr class="nav"> 
     41            <td><a href="${cal.prev_year.href}">&lt;&lt;</a></td> 
     42            <td><a href="${cal.prev_month.href}">&lt;</a></td> 
     43            <td colspan="3">&nbsp;</td> 
     44            <td><a href="${cal.next_month.href}">&gt;</a></td> 
     45            <td><a href="${cal.next_year.href}">&gt;&gt;</a></td> 
     46          </tr> 
     47        </table> 
     48      </div> 
    4349      <py:choose test="viewmode"> 
    4450        <py:when test="'years'"> 
     
    5763          <h2>Logs for ${month} ${year}</h2> 
    5864          <ul class="days"> 
    59             <li py:for="day in days"><a href="${day.href}">${day.caption}. ${month} ${year}</a></li> 
     65            <li py:for="day in days"><a href="${day.href}">${month} ${day.caption}, ${year}</a></li> 
    6066          </ul> 
    6167        </py:when> 
    62         <py:when test="'day'"> 
    63           <h2>${day}. ${month} ${year}</h2> 
     68        <py:when test="'day'">  
     69          <h2>${month_name} ${day}, ${year}</h2> 
     70          <div id="irclog-controls"> 
     71            <input type="checkbox" id="showactions" py:if="not missing" style="display: none;"></input> 
     72            <div id="jscal" style="display: none;"> 
     73              <div class="navcal"> 
     74                <a href="#" class="previous">&lt;&lt;</a>  
     75                <a class="link-datepicker" href="#">Select Date</a><input class="date-pick" value="${current_date}"/> 
     76                <a href="#" class="next">&gt;&gt;</a> 
     77              </div> 
     78            </div> 
     79          <br style="clear:both"/> 
     80          </div> 
    6481          <div py:if="missing"> 
    6582            No logfile for this day. 
    6683          </div> 
    67           <table class="irclog" py:if="not missing"> 
    68             <tr py:for="line in lines" class="${line.mode}"> 
    69               <td class="time">[<a href="#T${line.time}" id="${line.time}">${line.time}</a>]</td> 
    70               <td class="left" py:if="line.mode in ('action', 'server')">*</td> 
    71               <td class="left" py:if="line.mode == 'channel'">&lt;<span class="${line.nickcls}">${line.nickname}</span>&gt;</td> 
    72               <td class="right">${line.mode != 'channel' and line.nickname + ' ' or '' }${line.text}</td> 
    73             </tr> 
    74           </table> 
     84          ${irclog_table(lines,'searchable')} 
    7585        </py:when> 
    7686      </py:choose> 
     87      <script type="text/javascript"> 
     88        jQuery(document).ready(function($) { 
     89            irclogs_setup('${current_date}','${start_date}','${int_month}','${req.base_path}'); 
     90            $('#jscal')[0].style.display = 'block'; 
     91            $('#nojscal')[0].style.display = 'none'; 
     92            $('#showactions')[0].style.display = 'block'; 
     93        }); 
     94      </script>         
    7795      <br style="clear:both" /> 
    7896    </div> 
    7997  </body> 
    8098</html> 
    81  
  • irclogsplugin/0.11/setup.py

    r1887 r3920  
    1818    ], 
    1919    package_data={ 
    20         'irclogs' : ['templates/*.html', 'htdocs/*.css'] 
     20        'irclogs' : ['templates/*.html', 'htdocs/*.css',  
     21                     'htdocs/*.js', 'htdocs/*.png'] 
    2122    }, 
    2223    entry_points = { 
    23         'trac.plugins': ['irclogs = irclogs'] 
    24     } 
     24        'trac.plugins': ['irclogs = irclogs'], 
     25        'console_scripts': ['update-irc-search = irclogs.update_irc_search',], 
     26    }, 
     27    install_requires = ['pyndexter>=0.2'], 
    2528)