EventAggregator

Annotated EventAggregatorSupport.py

46:8337b0b6177d
2009-06-06 Paul Boddie Added an action which adds new events, displaying a form for the event parameters, then copies an event template and makes a new page containing substituted values for each of the specified parameters. Added day number links from the HTML produced by the macro in order to invoke the action.
paul@10 1
# -*- coding: iso-8859-1 -*-
paul@10 2
"""
paul@10 3
    MoinMoin - EventAggregator library
paul@10 4
paul@10 5
    @copyright: 2008, 2009 by Paul Boddie <paul@boddie.org.uk>
paul@10 6
    @copyright: 2000-2004 Juergen Hermann <jh@web.de>,
paul@10 7
                2005-2008 MoinMoin:ThomasWaldmann.
paul@10 8
    @license: GNU GPL (v2 or later), see COPYING.txt for details.
paul@10 9
"""
paul@10 10
paul@10 11
from MoinMoin.Page import Page
paul@10 12
from MoinMoin import search, version
paul@24 13
from MoinMoin import wikiutil
paul@10 14
import calendar
paul@11 15
import datetime
paul@24 16
import time
paul@10 17
import re
paul@10 18
paul@45 19
__version__ = "0.3"
paul@10 20
paul@22 21
# Date labels.
paul@22 22
paul@22 23
month_labels = ["January", "February", "March", "April", "May", "June",
paul@22 24
    "July", "August", "September", "October", "November", "December"]
paul@22 25
weekday_labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
paul@22 26
paul@10 27
# Regular expressions where MoinMoin does not provide the required support.
paul@10 28
paul@10 29
category_regexp = None
paul@10 30
definition_list_regexp = re.compile(ur'^\s+(?P<term>.*?)::\s(?P<desc>.*?)$', re.UNICODE | re.MULTILINE)
paul@10 31
date_regexp = re.compile(ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})-(?P<day>[0-9]{2})', re.UNICODE)
paul@10 32
month_regexp = re.compile(ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})', re.UNICODE)
paul@19 33
verbatim_regexp = re.compile(ur'(?:'
paul@19 34
    ur'<<Verbatim\((?P<verbatim>.*?)\)>>'
paul@19 35
    ur'|'
paul@19 36
    ur'\[\[Verbatim\((?P<verbatim2>.*?)\)\]\]'
paul@19 37
    ur'|'
paul@19 38
    ur'`(?P<monospace>.*?)`'
paul@19 39
    ur'|'
paul@19 40
    ur'{{{(?P<preformatted>.*?)}}}'
paul@19 41
    ur')', re.UNICODE)
paul@10 42
paul@10 43
# Utility functions.
paul@10 44
paul@10 45
def isMoin15():
paul@10 46
    return version.release.startswith("1.5.")
paul@10 47
paul@10 48
def getCategoryPattern(request):
paul@10 49
    global category_regexp
paul@10 50
paul@10 51
    try:
paul@10 52
        return request.cfg.cache.page_category_regexact
paul@10 53
    except AttributeError:
paul@10 54
paul@10 55
        # Use regular expression from MoinMoin 1.7.1 otherwise.
paul@10 56
paul@10 57
        if category_regexp is None:
paul@10 58
            category_regexp = re.compile(u'^%s$' % ur'(?P<all>Category(?P<key>(?!Template)\S+))', re.UNICODE)
paul@10 59
        return category_regexp
paul@10 60
paul@19 61
# Action support functions.
paul@19 62
paul@19 63
def getCategories(request):
paul@19 64
paul@19 65
    """
paul@19 66
    From the AdvancedSearch macro, return a list of category page names using
paul@19 67
    the given 'request'.
paul@19 68
    """
paul@19 69
paul@19 70
    # This will return all pages with "Category" in the title.
paul@19 71
paul@19 72
    cat_filter = getCategoryPattern(request).search
paul@19 73
    return request.rootpage.getPageList(filter=cat_filter)
paul@19 74
paul@19 75
def getCategoryMapping(category_pagenames, request):
paul@19 76
paul@19 77
    """
paul@19 78
    For the given 'category_pagenames' return a list of tuples of the form
paul@19 79
    (category name, category page name) using the given 'request'.
paul@19 80
    """
paul@19 81
paul@19 82
    cat_pattern = getCategoryPattern(request)
paul@19 83
    mapping = []
paul@19 84
    for pagename in category_pagenames:
paul@19 85
        name = cat_pattern.match(pagename).group("key")
paul@19 86
        if name != "Category":
paul@19 87
            mapping.append((name, pagename))
paul@19 88
    mapping.sort()
paul@19 89
    return mapping
paul@19 90
paul@30 91
def getPageRevision(page):
paul@24 92
paul@30 93
    # From Page.edit_info...
paul@24 94
paul@30 95
    if hasattr(page, "editlog_entry"):
paul@30 96
        line = page.editlog_entry()
paul@27 97
    else:
paul@30 98
        line = page._last_edited(page.request) # MoinMoin 1.5.x and 1.6.x
paul@27 99
paul@30 100
    timestamp = line.ed_time_usecs
paul@30 101
    mtime = wikiutil.version2timestamp(long(timestamp)) # must be long for py 2.2.x
paul@30 102
    return {"timestamp" : time.gmtime(mtime), "comment" : line.comment}
paul@29 103
paul@29 104
def getHTTPTimeString(tmtuple):
paul@29 105
    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
paul@29 106
        weekday_labels[tmtuple.tm_wday],
paul@29 107
        tmtuple.tm_mday,
paul@29 108
        month_labels[tmtuple.tm_mon -1], # zero-based labels
paul@29 109
        tmtuple.tm_year,
paul@29 110
        tmtuple.tm_hour,
paul@29 111
        tmtuple.tm_min,
paul@29 112
        tmtuple.tm_sec
paul@29 113
        )
paul@24 114
paul@10 115
# The main activity functions.
paul@10 116
paul@10 117
def getPages(pagename, request):
paul@10 118
paul@10 119
    "Return the links minus category links for 'pagename' using the 'request'."
paul@10 120
paul@10 121
    query = search.QueryParser().parse_query('category:%s' % pagename)
paul@10 122
    if isMoin15():
paul@10 123
        results = search.searchPages(request, query)
paul@10 124
        results.sortByPagename()
paul@10 125
    else:
paul@10 126
        results = search.searchPages(request, query, "page_name")
paul@10 127
paul@10 128
    cat_pattern = getCategoryPattern(request)
paul@10 129
    pages = []
paul@10 130
    for page in results.hits:
paul@10 131
        if not cat_pattern.match(page.page_name):
paul@10 132
            pages.append(page)
paul@10 133
    return pages
paul@10 134
paul@24 135
def getSimpleWikiText(text):
paul@24 136
paul@24 137
    """
paul@24 138
    Return the plain text representation of the given 'text' which may employ
paul@24 139
    certain Wiki syntax features, such as those providing verbatim or monospaced
paul@24 140
    text.
paul@24 141
    """
paul@24 142
paul@24 143
    # NOTE: Re-implementing support for verbatim text and linking avoidance.
paul@24 144
paul@24 145
    return "".join([s for s in verbatim_regexp.split(text) if s is not None])
paul@24 146
paul@27 147
def getFormat(page):
paul@27 148
paul@27 149
    "Get the format used on 'page'."
paul@27 150
paul@27 151
    if isMoin15():
paul@27 152
        return "wiki" # page.pi_format
paul@27 153
    else:
paul@27 154
        return page.pi["format"]
paul@27 155
paul@10 156
def getEventDetails(page):
paul@10 157
paul@10 158
    "Return a dictionary of event details from the given 'page'."
paul@10 159
paul@10 160
    event_details = {}
paul@10 161
paul@27 162
    if getFormat(page) == "wiki":
paul@27 163
        for match in definition_list_regexp.finditer(page.get_raw_body()):
paul@10 164
paul@10 165
            # Permit case-insensitive list terms.
paul@10 166
paul@10 167
            term = match.group("term").lower()
paul@10 168
            desc = match.group("desc")
paul@10 169
paul@10 170
            # Special value type handling.
paul@10 171
paul@19 172
            # Dates.
paul@19 173
paul@10 174
            if term in ("start", "end"):
paul@10 175
                desc = getDate(desc)
paul@19 176
paul@24 177
            # Lists (whose elements may be quoted).
paul@19 178
paul@24 179
            elif term in ("topics", "categories"):
paul@24 180
                desc = [getSimpleWikiText(value.strip()) for value in desc.split(",")]
paul@10 181
paul@19 182
            # Labels which may well be quoted.
paul@19 183
paul@45 184
            elif term in ("title", "summary", "description"):
paul@24 185
                desc = getSimpleWikiText(desc)
paul@19 186
paul@10 187
            if desc is not None:
paul@10 188
                event_details[term] = desc
paul@10 189
paul@10 190
    return event_details
paul@10 191
paul@19 192
def getEventSummary(event_page, event_details):
paul@19 193
paul@19 194
    """
paul@19 195
    Return either the given title or summary of the event described by the given
paul@19 196
    'event_page', according to the given 'event_details', or return the pretty
paul@19 197
    version of the page name.
paul@19 198
    """
paul@19 199
paul@19 200
    if event_details.has_key("title"):
paul@19 201
        return event_details["title"]
paul@19 202
    elif event_details.has_key("summary"):
paul@19 203
        return event_details["summary"]
paul@19 204
    else:
paul@19 205
        return getPrettyPageName(event_page)
paul@19 206
paul@10 207
def getDate(s):
paul@10 208
paul@10 209
    "Parse the string 's', extracting and returning a date string."
paul@10 210
paul@10 211
    m = date_regexp.search(s)
paul@10 212
    if m:
paul@10 213
        return tuple(map(int, m.groups()))
paul@10 214
    else:
paul@10 215
        return None
paul@10 216
paul@10 217
def getMonth(s):
paul@10 218
paul@10 219
    "Parse the string 's', extracting and returning a month string."
paul@10 220
paul@10 221
    m = month_regexp.search(s)
paul@10 222
    if m:
paul@10 223
        return tuple(map(int, m.groups()))
paul@10 224
    else:
paul@10 225
        return None
paul@10 226
paul@11 227
def getCurrentMonth():
paul@11 228
paul@11 229
    "Return the current month as a (year, month) tuple."
paul@11 230
paul@11 231
    today = datetime.date.today()
paul@11 232
    return (today.year, today.month)
paul@11 233
paul@17 234
def getCurrentYear():
paul@17 235
paul@17 236
    "Return the current year."
paul@17 237
paul@17 238
    today = datetime.date.today()
paul@17 239
    return today.year
paul@17 240
paul@11 241
def monthupdate(date, n):
paul@11 242
paul@11 243
    "Return 'date' updated by 'n' months."
paul@11 244
paul@11 245
    if n < 0:
paul@11 246
        fn = prevmonth
paul@11 247
    else:
paul@11 248
        fn = nextmonth
paul@11 249
paul@11 250
    i = 0
paul@11 251
    while i < abs(n):
paul@11 252
        date = fn(date)
paul@11 253
        i += 1
paul@11 254
        
paul@11 255
    return date
paul@11 256
paul@13 257
def daterange(first, last, step=1):
paul@11 258
paul@13 259
    """
paul@13 260
    Get the range of dates starting at 'first' and ending on 'last', using the
paul@13 261
    specified 'step'.
paul@13 262
    """
paul@11 263
paul@10 264
    results = []
paul@10 265
paul@10 266
    months_only = len(first) == 2
paul@10 267
    start_year = first[0]
paul@10 268
    end_year = last[0]
paul@10 269
paul@11 270
    for year in range(start_year, end_year + step, step):
paul@11 271
        if step == 1 and year < end_year:
paul@10 272
            end_month = 12
paul@11 273
        elif step == -1 and year > end_year:
paul@11 274
            end_month = 1
paul@10 275
        else:
paul@10 276
            end_month = last[1]
paul@10 277
paul@11 278
        if step == 1 and year > start_year:
paul@10 279
            start_month = 1
paul@11 280
        elif step == -1 and year < start_year:
paul@11 281
            start_month = 12
paul@10 282
        else:
paul@10 283
            start_month = first[1]
paul@10 284
paul@11 285
        for month in range(start_month, end_month + step, step):
paul@10 286
            if months_only:
paul@10 287
                results.append((year, month))
paul@10 288
            else:
paul@11 289
                if step == 1 and month < end_month:
paul@10 290
                    _wd, end_day = calendar.monthrange(year, month)
paul@11 291
                elif step == -1 and month > end_month:
paul@11 292
                    end_day = 1
paul@10 293
                else:
paul@10 294
                    end_day = last[2]
paul@10 295
paul@11 296
                if step == 1 and month > start_month:
paul@10 297
                    start_day = 1
paul@11 298
                elif step == -1 and month < start_month:
paul@11 299
                    _wd, start_day = calendar.monthrange(year, month)
paul@10 300
                else:
paul@10 301
                    start_day = first[2]
paul@10 302
paul@11 303
                for day in range(start_day, end_day + step, step):
paul@10 304
                    results.append((year, month, day))
paul@10 305
paul@10 306
    return results
paul@10 307
paul@10 308
def nextdate(date):
paul@11 309
paul@11 310
    "Return the date following the given 'date'."
paul@11 311
paul@10 312
    year, month, day = date
paul@10 313
    _wd, end_day = calendar.monthrange(year, month)
paul@10 314
    if day == end_day:
paul@10 315
        if month == 12:
paul@10 316
            return (year + 1, 1, 1)
paul@10 317
        else:
paul@10 318
            return (year, month + 1, 1)
paul@10 319
    else:
paul@10 320
        return (year, month, day + 1)
paul@10 321
paul@11 322
def prevdate(date):
paul@11 323
paul@11 324
    "Return the date preceding the given 'date'."
paul@11 325
paul@11 326
    year, month, day = date
paul@11 327
    if day == 1:
paul@11 328
        if month == 1:
paul@11 329
            return (year - 1, 12, 31)
paul@11 330
        else:
paul@11 331
            _wd, end_day = calendar.monthrange(year, month - 1)
paul@11 332
            return (year, month - 1, end_day)
paul@11 333
    else:
paul@11 334
        return (year, month, day - 1)
paul@11 335
paul@11 336
def nextmonth(date):
paul@11 337
paul@11 338
    "Return the (year, month) tuple following 'date'."
paul@11 339
paul@11 340
    year, month = date
paul@11 341
    if month == 12:
paul@11 342
        return (year + 1, 1)
paul@11 343
    else:
paul@11 344
        return year, month + 1
paul@11 345
paul@11 346
def prevmonth(date):
paul@11 347
paul@11 348
    "Return the (year, month) tuple preceding 'date'."
paul@11 349
paul@11 350
    year, month = date
paul@11 351
    if month == 1:
paul@11 352
        return (year - 1, 12)
paul@11 353
    else:
paul@11 354
        return year, month - 1
paul@11 355
paul@13 356
def span(start, end):
paul@13 357
paul@13 358
    "Return the difference between 'start' and 'end'."
paul@13 359
paul@13 360
    return end[0] - start[0], end[1] - start[1]
paul@13 361
paul@10 362
def getEvents(request, category_names, calendar_start=None, calendar_end=None):
paul@10 363
paul@10 364
    """
paul@10 365
    Using the 'request', generate a list of events found on pages belonging to
paul@10 366
    the specified 'category_names', using the optional 'calendar_start' and
paul@10 367
    'calendar_end' month tuples of the form (year, month) to indicate a window
paul@10 368
    of interest.
paul@10 369
paul@10 370
    Return a list of events, a dictionary mapping months to event lists (within
paul@10 371
    the window of interest), a list of all events within the window of interest,
paul@10 372
    the earliest month of an event within the window of interest, and the latest
paul@10 373
    month of an event within the window of interest.
paul@10 374
    """
paul@10 375
paul@12 376
    # Re-order the window, if appropriate.
paul@12 377
paul@12 378
    if calendar_start is not None and calendar_end is not None and calendar_start > calendar_end:
paul@12 379
        calendar_start, calendar_end = calendar_end, calendar_start
paul@12 380
paul@10 381
    events = []
paul@10 382
    shown_events = {}
paul@10 383
    all_shown_events = []
paul@17 384
    processed_pages = set()
paul@10 385
paul@10 386
    earliest = None
paul@10 387
    latest = None
paul@10 388
paul@10 389
    for category_name in category_names:
paul@10 390
paul@10 391
        # Get the pages and page names in the category.
paul@10 392
paul@10 393
        pages_in_category = getPages(category_name, request)
paul@10 394
paul@10 395
        # Visit each page in the category.
paul@10 396
paul@10 397
        for page_in_category in pages_in_category:
paul@10 398
            pagename = page_in_category.page_name
paul@10 399
paul@17 400
            # Only process each page once.
paul@17 401
paul@17 402
            if pagename in processed_pages:
paul@17 403
                continue
paul@17 404
            else:
paul@17 405
                processed_pages.add(pagename)
paul@17 406
paul@10 407
            # Get a real page, not a result page.
paul@10 408
paul@10 409
            real_page_in_category = Page(request, pagename)
paul@10 410
            event_details = getEventDetails(real_page_in_category)
paul@10 411
paul@10 412
            # Define the event as the page together with its details.
paul@10 413
paul@10 414
            event = (real_page_in_category, event_details)
paul@10 415
            events.append(event)
paul@10 416
paul@10 417
            # Test for the suitability of the event.
paul@10 418
paul@10 419
            if event_details.has_key("start") and event_details.has_key("end"):
paul@10 420
paul@10 421
                start_month = event_details["start"][:2]
paul@10 422
                end_month = event_details["end"][:2]
paul@10 423
paul@10 424
                # Compare the months of the dates to the requested calendar
paul@10 425
                # window, if any.
paul@10 426
paul@10 427
                if (calendar_start is None or end_month >= calendar_start) and \
paul@10 428
                    (calendar_end is None or start_month <= calendar_end):
paul@10 429
paul@10 430
                    all_shown_events.append(event)
paul@10 431
paul@10 432
                    if earliest is None or start_month < earliest:
paul@10 433
                        earliest = start_month
paul@10 434
                    if latest is None or end_month > latest:
paul@10 435
                        latest = end_month
paul@10 436
paul@10 437
                    # Store the event in the month-specific dictionary.
paul@10 438
paul@10 439
                    first = max(start_month, calendar_start or start_month)
paul@10 440
                    last = min(end_month, calendar_end or end_month)
paul@10 441
paul@10 442
                    for event_month in daterange(first, last):
paul@10 443
                        if not shown_events.has_key(event_month):
paul@10 444
                            shown_events[event_month] = []
paul@10 445
                        shown_events[event_month].append(event)
paul@10 446
paul@10 447
    return events, shown_events, all_shown_events, earliest, latest
paul@10 448
paul@29 449
def setEventTimestamps(request, events):
paul@29 450
paul@29 451
    """
paul@29 452
    Using 'request', set timestamp details in the details dictionary of each of
paul@29 453
    the 'events': a list of the form (event_page, event_details).
paul@29 454
paul@29 455
    Retutn the latest timestamp found.
paul@29 456
    """
paul@29 457
paul@29 458
    latest = None
paul@29 459
paul@29 460
    for event_page, event_details in events:
paul@29 461
paul@29 462
        # Get the initial revision of the page.
paul@29 463
paul@29 464
        revisions = event_page.getRevList()
paul@29 465
        event_page_initial = Page(request, event_page.page_name, rev=revisions[-1])
paul@29 466
paul@29 467
        # Get the created and last modified times.
paul@29 468
paul@30 469
        initial_revision = getPageRevision(event_page_initial)
paul@30 470
        event_details["created"] = initial_revision["timestamp"]
paul@30 471
        latest_revision = getPageRevision(event_page)
paul@30 472
        event_details["last-modified"] = latest_revision["timestamp"]
paul@29 473
        event_details["sequence"] = len(revisions) - 1
paul@30 474
        event_details["last-comment"] = latest_revision["comment"]
paul@29 475
paul@29 476
        if latest is None or latest < event_details["last-modified"]:
paul@29 477
            latest = event_details["last-modified"]
paul@29 478
paul@29 479
    return latest
paul@29 480
paul@26 481
def compareEvents(event1, event2):
paul@26 482
paul@26 483
    """
paul@26 484
    Compare 'event1' and 'event2' by start and end date, where both parameters
paul@26 485
    are of the following form:
paul@26 486
paul@26 487
    (event_page, event_details)
paul@26 488
    """
paul@26 489
paul@26 490
    event_page1, event_details1 = event1
paul@26 491
    event_page2, event_details2 = event2
paul@26 492
    return cmp(
paul@26 493
        (event_details1["start"], event_details1["end"]),
paul@26 494
        (event_details2["start"], event_details2["end"])
paul@26 495
        )
paul@26 496
paul@26 497
def getOrderedEvents(events):
paul@26 498
paul@26 499
    """
paul@26 500
    Return a list with the given 'events' ordered according to their start and
paul@26 501
    end dates. Each list element must be of the following form:
paul@26 502
paul@26 503
    (event_page, event_details)
paul@26 504
    """
paul@26 505
paul@26 506
    ordered_events = events[:]
paul@26 507
    ordered_events.sort(compareEvents)
paul@26 508
    return ordered_events
paul@26 509
paul@13 510
def getConcretePeriod(calendar_start, calendar_end, earliest, latest):
paul@13 511
paul@13 512
    """
paul@13 513
    From the requested 'calendar_start' and 'calendar_end', which may be None,
paul@13 514
    indicating that no restriction is imposed on the period for each of the
paul@13 515
    boundaries, use the 'earliest' and 'latest' event months to define a
paul@13 516
    specific period of interest.
paul@13 517
    """
paul@13 518
paul@13 519
    # Define the period as starting with any specified start month or the
paul@13 520
    # earliest event known, ending with any specified end month or the latest
paul@13 521
    # event known.
paul@13 522
paul@13 523
    first = calendar_start or earliest
paul@13 524
    last = calendar_end or latest
paul@13 525
paul@13 526
    # If there is no range of months to show, perhaps because there are no
paul@13 527
    # events in the requested period, and there was no start or end month
paul@13 528
    # specified, show only the month indicated by the start or end of the
paul@13 529
    # requested period. If all events were to be shown but none were found show
paul@13 530
    # the current month.
paul@13 531
paul@13 532
    if first is None:
paul@13 533
        first = last or getCurrentMonth()
paul@13 534
    if last is None:
paul@13 535
        last = first or getCurrentMonth()
paul@13 536
paul@13 537
    # Permit "expiring" periods (where the start date approaches the end date).
paul@13 538
paul@13 539
    return min(first, last), last
paul@13 540
paul@15 541
def getCoverage(start, end, events):
paul@15 542
paul@15 543
    """
paul@15 544
    Within the period defined by the 'start' and 'end' dates, determine the
paul@15 545
    coverage of the days in the period by the given 'events', returning a set of
paul@15 546
    covered days, along with a list of slots, where each slot contains a tuple
paul@15 547
    of the form (set of covered days, events).
paul@15 548
    """
paul@15 549
paul@15 550
    all_events = []
paul@15 551
    full_coverage = set()
paul@15 552
paul@15 553
    # Get event details.
paul@15 554
paul@15 555
    for event in events:
paul@15 556
        event_page, event_details = event
paul@15 557
paul@15 558
        # Test for the event in the period.
paul@15 559
paul@15 560
        if event_details["start"] <= end and event_details["end"] >= start:
paul@15 561
paul@15 562
            # Find the coverage of this period for the event.
paul@15 563
paul@15 564
            event_start = max(event_details["start"], start)
paul@15 565
            event_end = min(event_details["end"], end)
paul@15 566
            event_coverage = set(daterange(event_start, event_end))
paul@15 567
paul@15 568
            # Update the overall coverage.
paul@15 569
paul@15 570
            full_coverage.update(event_coverage)
paul@15 571
paul@15 572
            # Try and fit the event into the events list.
paul@15 573
paul@15 574
            for i, (coverage, covered_events) in enumerate(all_events):
paul@15 575
paul@15 576
                # Where the event does not overlap with the current
paul@15 577
                # element, add it alongside existing events.
paul@15 578
paul@15 579
                if not coverage.intersection(event_coverage):
paul@15 580
                    covered_events.append(event)
paul@15 581
                    all_events[i] = coverage.union(event_coverage), covered_events
paul@15 582
                    break
paul@15 583
paul@15 584
            # Make a new element in the list if the event cannot be
paul@15 585
            # marked alongside existing events.
paul@15 586
paul@15 587
            else:
paul@15 588
                all_events.append((event_coverage, [event]))
paul@15 589
paul@15 590
    return full_coverage, all_events
paul@15 591
paul@19 592
# User interface functions.
paul@19 593
paul@23 594
def getParameter(request, name):
paul@23 595
    return request.form.get(name, [None])[0]
paul@23 596
paul@19 597
def getParameterMonth(arg):
paul@19 598
    n = None
paul@19 599
paul@19 600
    if arg.startswith("current"):
paul@19 601
        date = getCurrentMonth()
paul@19 602
        if len(arg) > 8:
paul@19 603
            n = int(arg[7:])
paul@19 604
paul@19 605
    elif arg.startswith("yearstart"):
paul@19 606
        date = (getCurrentYear(), 1)
paul@19 607
        if len(arg) > 10:
paul@19 608
            n = int(arg[9:])
paul@19 609
paul@19 610
    elif arg.startswith("yearend"):
paul@19 611
        date = (getCurrentYear(), 12)
paul@19 612
        if len(arg) > 8:
paul@19 613
            n = int(arg[7:])
paul@19 614
paul@19 615
    else:
paul@19 616
        date = getMonth(arg)
paul@19 617
paul@19 618
    if n is not None:
paul@19 619
        date = monthupdate(date, n)
paul@19 620
paul@19 621
    return date
paul@19 622
paul@19 623
def getFormMonth(request, calendar_name, argname):
paul@19 624
    if calendar_name is None:
paul@19 625
        calendar_prefix = argname
paul@19 626
    else:
paul@19 627
        calendar_prefix = "%s-%s" % (calendar_name, argname)
paul@19 628
paul@23 629
    arg = getParameter(request, calendar_prefix)
paul@19 630
    if arg is not None:
paul@19 631
        return getParameterMonth(arg)
paul@19 632
    else:
paul@19 633
        return None
paul@19 634
paul@23 635
def getFormMonthPair(request, yeararg, montharg):
paul@23 636
    year = getParameter(request, yeararg)
paul@23 637
    month = getParameter(request, montharg)
paul@23 638
    if year and month:
paul@23 639
        return (int(year), int(month))
paul@23 640
    else:
paul@23 641
        return None
paul@23 642
paul@19 643
def getPrettyPageName(page):
paul@19 644
paul@19 645
    "Return a nicely formatted title/name for the given 'page'."
paul@19 646
paul@27 647
    if isMoin15():
paul@27 648
        title = page.split_title(page.request, force=1)
paul@27 649
    else:
paul@27 650
        title = page.split_title(force=1)
paul@27 651
paul@27 652
    return title.replace("_", " ").replace("/", u" ? ")
paul@19 653
paul@22 654
def getMonthLabel(month):
paul@22 655
paul@22 656
    "Return an unlocalised label for the given 'month'."
paul@22 657
paul@22 658
    return month_labels[month - 1] # zero-based labels
paul@22 659
paul@22 660
def getDayLabel(weekday):
paul@22 661
paul@22 662
    "Return an unlocalised label for the given 'weekday'."
paul@22 663
paul@22 664
    return weekday_labels[weekday]
paul@22 665
paul@27 666
def linkToPage(request, page, text, query_string=None):
paul@27 667
paul@27 668
    """
paul@27 669
    Using 'request', return a link to 'page' with the given link 'text' and
paul@27 670
    optional 'query_string'.
paul@27 671
    """
paul@27 672
paul@27 673
    text = wikiutil.escape(text)
paul@27 674
paul@27 675
    if isMoin15():
paul@27 676
        url = wikiutil.quoteWikinameURL(page.page_name)
paul@27 677
        if query_string is not None:
paul@27 678
            url = "%s?%s" % (url, query_string)
paul@27 679
        return wikiutil.link_tag(request, url, text, getattr(page, "formatter", None))
paul@27 680
    else:
paul@27 681
        return page.link_to_raw(request, text, query_string)
paul@27 682
paul@38 683
def getPageURL(request, page):
paul@38 684
paul@38 685
    "Using 'request', return the URL of 'page'."
paul@38 686
paul@38 687
    if isMoin15():
paul@38 688
        return request.getQualifiedURL(page.url(request))
paul@38 689
    else:
paul@38 690
        return request.getQualifiedURL(page.url(request, relative=0))
paul@38 691
paul@10 692
# vim: tabstop=4 expandtab shiftwidth=4