~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

__metaclass__ = type

from datetime import datetime

import pytz
from zope.app.form import CustomWidgetFactory
from zope.app.form.browser.widget import (
    ISimpleInputWidget,
    SimpleInputWidget,
    )
from zope.app.form.interfaces import (
    ConversionError,
    WidgetInputError,
    )
from zope.formlib import form
from zope.interface import implements
from zope.schema import (
    Choice,
    Datetime,
    )
from zope.schema.vocabulary import (
    SimpleTerm,
    SimpleVocabulary,
    )

from canonical.launchpad import _
from canonical.launchpad.webapp.interfaces import IAlwaysSubmittedWidget
from lp.app.validators import LaunchpadValidationError
from lp.app.widgets.date import DateTimeWidget
from lp.app.widgets.itemswidgets import LaunchpadRadioWidget
from lp.registry.interfaces.announcement import IAnnouncement


class IAnnouncementDateWidget(ISimpleInputWidget):
    """A widget for selecting the date of a news item."""


class AnnouncementDateWidget(SimpleInputWidget):
    """See IAnnouncementDateWidget."""

    implements(IAlwaysSubmittedWidget)

    def __init__(self, context, request):
        SimpleInputWidget.__init__(self, context, request)
        fields = form.Fields(
            Choice(__name__='action', source=self._getActionsVocabulary(),
                   title=_('Action')),
            Datetime(__name__='announcement_date', title=_('Date'),
                     required=False, default=None))
        fields['action'].custom_widget = CustomWidgetFactory(
            LaunchpadRadioWidget)
        fields['announcement_date'].custom_widget = CustomWidgetFactory(
            DateTimeWidget)
        if IAnnouncement.providedBy(self.context.context):
            # we are editing an existing announcement
            data = {}
            date_announced = self.context.context.date_announced
            data['announcement_date'] = date_announced
            if date_announced is None:
                data['action'] = 'sometime'
            else:
                data['action'] = 'specific'
        else:
            data = {'action': 'immediately'}
        widgets = form.setUpWidgets(
            fields, self.name, context, request, ignore_request=False,
            data=data)
        self.action_widget = widgets['action']
        self.announcement_date_widget = widgets['announcement_date']

    def __call__(self):
        html = '<div>Publish this announcement:</div>\n'
        html += "<p>%s</p><p>%s</p>" % (
            self.action_widget(), self.announcement_date_widget())
        return html

    def hasInput(self):
        return self.action_widget.hasInput()

    def _getActionsVocabulary(self):
        action_names = [
            ('immediately', 'Immediately'),
            ('sometime', 'At some time in the future when I come back to '
                         'authorize it'),
            ('specific', 'At this specific date and time:')]
        terms = [
            SimpleTerm(name, name, label) for name, label in action_names]
        return SimpleVocabulary(terms)

    # pylint: disable-msg=W0706
    def getInputValue(self):
        self._error = None
        action = self.action_widget.getInputValue()
        try:
            announcement_date = self.announcement_date_widget.getInputValue()
        except ConversionError:
            self._error = WidgetInputError(
                self.name, self.label,
                LaunchpadValidationError(
                    _('Please provide a valid date and time.')))
            raise self._error
        if action == 'immediately' and announcement_date is not None:
            self._error = WidgetInputError(
                self.name, self.label,
                LaunchpadValidationError(
                    _('Please do not provide a date if you want to publish '
                      'immediately.')))
            raise self._error
        if action == 'specific' and announcement_date is None:
            self._error = WidgetInputError(
                self.name, self.label,
                LaunchpadValidationError(
                    _('Please provide a publication date.')))
            raise self._error
        if action == 'immediately':
            return datetime.now(pytz.utc)
        elif action == "sometime":
            return None
        elif action == "specific":
            return announcement_date
        else:
            raise AssertionError, 'Unknown action in AnnouncementDateWidget'