def test_populate(self):
     msg = ProjectMessage(self.env)
     msg.populate(self.default_data)
     self.assertEqual('Test Term', msg['name'])
     self.assertEqual('Hello World!', msg['message'])
     self.assertEqual('Agree', msg['button'])
     self.assertEqual(['project_managers'], msg['groups'])
     self.assertEqual(self.start_date, msg['start'])
     self.assertEqual(self.end_date, msg['end'])
     self.assertEqual("milsomd", msg['author'])
     self.assertEqual("1396975221114382", msg['created_at'])
     self.assertRaises(AttributeError, lambda: msg.foo)
     msg.insert()
 def test_filtered_message_dates_3(self):
     # start date is tomorrow and end date is next week
     msg = self._create_new_message()
     msg['start'] = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
     msg['end ']= (datetime.now() + timedelta(days=7)).strftime("%Y-%m-%d")
     msg.insert()
     filtered_msgs = ProjectMessage.get_filtered_messages(self.env)
     self.assertEqual(0, len(filtered_msgs))
 def test_filtered_message_dates_2(self):
     # start date is today and end date is tomorrow
     msg = self._create_new_message()
     msg.start = datetime.now().strftime("%Y-%m-%d")
     msg.end = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
     msg.insert()
     filtered_msgs = ProjectMessage.get_filtered_messages(self.env)
     self.assertEqual(1, len(filtered_msgs))
 def test_filtered_message_dates(self):
     # start date is before and end date is after today
     msg = self._create_new_message()
     msg['start'] = (datetime.now() - timedelta(days=5)).strftime("%Y-%m-%d")
     msg['end'] = (datetime.now() + timedelta(days=5)).strftime("%Y-%m-%d")
     msg.insert()
     filtered_msgs = ProjectMessage.get_filtered_messages(self.env)
     self.assertEqual(1, len(filtered_msgs))
    def createMessage(self, req, name, message, button, 
                            mode, groups, start, end):
        """Create a new project message.

        :param string: name
        :param string: text (supports wiki formatting)
        :param string: button text
        :param string: mode ('Alert' or 'Full Screen')
        :param list: groups who can see the message (['groupA', 'groupB'])
        :param string: start date (ISO-8601 26-07-2014)
        :param string: end date (ISO-8601 30-07-2014)
        """

        try:
            ProjectMessage(self.env, name)
        except ResourceNotFound:
            self.log.debug("Name %s is unique - creating new project message.", name)
        else:
            return ("Unable to create a new project message. Please choose a "
                    "different name, %s is already in use." % (name))

        msg = ProjectMessage(self.env)
        msg['name'] = name
        msg['message'] = message
        msg['button'] = button
        msg['mode'] = mode
        msg['groups'] = groups
        msg['start'] = start
        msg['end'] = end
        msg['author'] = req.authname
        msg['created_at'] = to_utimestamp(datetime.now(pytz.utc))

        if not msg.validate():
            return "Could not create a new message. Some attributes are invalid."

        try:
            msg.insert()
        except DatabaseError:
            self.log.info("Database error when creating a new project message via XMLRPC.")
            return "Unable to create a new project message."
        else:
            self.log.info("Successfully created new project message via XMLRPC.")
            return "Successfully created new project message."
    def _insert_message(self, name, message, button, mode, start, end, *args):
        """
        Inserts a new project message into the project_message table, 
        validating each argument passed prior to the transaction 
        being completed.

        This code is intended to be used only by IAdminCommandProvider.
        """

        try:
            ProjectMessage(self.env, name)
        except ResourceNotFound:
            self.log.debug("Name is unique - creating message.")
        else:
            raise AdminCommandError("There is already a project message "
                                    "with the name %s. Please choose "
                                    "a different name." % name)

        new_msg = ProjectMessage(self.env)
        new_msg['name'] = name
        new_msg['message'] = message
        new_msg['button'] = button
        new_msg['mode'] = mode
        new_msg['groups'] = [group for group in args]
        new_msg['start'] = start
        new_msg['end'] = end
        new_msg['author'] = "system" # anyone could lie about who they are
        new_msg['created_at'] = to_utimestamp(datetime.now(pytz.utc))

        if not new_msg.validate():
            raise AdminCommandError("Could not create a new message. Some "
                                    "attributes are invalid.")

        try:
            new_msg.insert()
        except:
            AdminCommandError("We were unable to save that "
                             "message. Please try again.")
        else:
            AdminCommandError("You created a new project message.")
            self.log.info("Created a new project message - %s", name)
    def render_preference_panel(self, req, panel):

        agreed = ProjectMessageRecord.get_user_records(self.env, req.authname)
        for m in agreed:
            m['agreed_at'] = m['agreed_at'].strftime("%Y-%m-%d %H:%M")
        disagreed = ProjectMessage.get_unagreed_messages(self.env, req.authname)

        data = {
            'agreed': agreed,
            'unagreed': disagreed,
        }

        return 'project_message_prefs.html', data
    def render_admin_panel(self, req, cat, page, path_info):

        if 'LOGIN_ADMIN' in req.perm:

            if (page == 'project-message' and 
                'PROJECTMESSAGE_CREATE' in req.perm):

                groups = (sid for sid in Group.groupsBy(self.env))
                previous_msgs = ProjectMessage.get_all_messages(self.env)
                for m in previous_msgs:
                    for k in ('created_at', 'start', 'end'):
                        m[k] = m[k].strftime('%Y-%m-%d')

                data = {
                        'mode_options': ProjectMessageSystem(self.env).mode_options,
                        'group_options': itertools.chain(groups, ['*']),
                        'msgs': previous_msgs,
                        'start_date': datetime.now().strftime("%Y-%m-%d"),
                        'end_date': (datetime.now() + 
                                     timedelta(days=7)).strftime("%Y-%m-%d"),
                }

                # the message can be wiki mark-up
                Chrome(self.env).add_wiki_toolbars(req)
                add_script(req, 'projectmessage/js/project_message_admin.js')
                add_stylesheet(req, 'projectmessage/css/project_message_admin.css')

                if req.method == 'POST':
                    name = req.args.get('name')
                    message = req.args.get('message')
                    button = req.args.get('button')
                    mode = req.args.get('mode')
                    groups = req.args.get('groups', [])
                    start = req.args.get('start')
                    end = req.args.get('end')

                    if not all((name, message, button, mode, groups, start, end)):
                        add_notice(req, "Please complete the form - some "
                                        "fields were left blank.")
                        data.update(req.args)
                        return 'project_message_admin.html', data

                    new_msg = ProjectMessage(self.env)
                    msg_args = copy.deepcopy(req.args)
                    msg_args['author'] = req.authname
                    msg_args['created_at'] = to_utimestamp(datetime.now(pytz.utc))
                    if isinstance(groups, basestring):
                        msg_args['groups'] = [groups]
                    new_msg.populate(msg_args)

                    error = None
                    if not new_msg.unique_name:
                        add_warning(req, "There is already a project message "
                                        "with the name %s. Please choose "
                                        "a different name." % name)
                        error = True
                    elif not new_msg.valid_date_format:
                        add_warning(req, "Incorrect format for date. "
                                        "Should be YYYY-MM-DD" )
                        error = True
                    elif not new_msg.valid_date_range:
                        add_warning(req, "The date difference between start date and "
                                        "end date should be of atleast 1 day.")
                        error = True

                    if error:
                        data.update(req.args)
                        return 'project_message_admin.html', data

                    new_msg.insert()
                    try:
                        ProjectMessage(self.env, name)
                    except ResourceNotFound:
                        add_warning(req, "Unable to save project message. "
                            "Please try again.")
                        data.update(req.args)
                    else:
                        add_notice(req, "New project message created.")
                        self.log.info("New project message '%s' created", name)
                        # don't show a timestamp to the user - bad UI
                        new_msg['created_at'] = from_utimestamp(new_msg['created_at']).strftime('%Y-%m-%d')
                        data['msgs'].append(new_msg)

                return 'project_message_admin.html', data

            elif (page == 'project-message-records' and 
                'PROJECTMESSAGE_VIEW' in req.perm):

                records = ProjectMessageRecord.get_all_records(self.env)
                for r in records:
                    r['agreed_at'] = r['agreed_at'].strftime("%Y-%m-%d %H:%M")

                data = {
                        'records': records,
                }

                return 'project_message_records.html', data
    def filter_stream(self, req, method, filename, stream, data):
        """
        Check for alert messages to show authenticated user.

        If there are any project messages that the authenticated user has not 
        seen, which are selected to be viewed as alert based notifications, 
        we add the necessary mark-up and javscript.
        """

        if req.authname != 'anonymous':

            timeout_exceeded = self._timeout_limit_exceeded(req)
            if timeout_exceeded or timeout_exceeded is None:

                # we can check for alert notifications
                unagreed = ProjectMessage.get_unagreed_messages(self.env, 
                            req.authname, 'Alert')
                if unagreed:
                    # we only shown one notification at a time currently
                    msg = unagreed[0]
                    msg['message'] = format_to_html(self.env, 
                                        Context.from_request(req), msg['message'])
                    alert_markup = tag(
                                    tag.div(
                                        tag.i(
                                            class_="alert-icon fa fa-info-circle"
                                        ),
                                        tag.ul(
                                            tag.li(msg['message'],
                                                class_="alert-message"
                                            ),
                                        ),
                                        tag.button(msg['button'],
                                            class_="close btn btn-mini",
                                            type="button",
                                            data_dismiss="alert"
                                        ),
                                        class_="project-message cf alert alert-info alert-dismissable individual"
                                    ),
                                    tag.form(
                                        tag.input(
                                            name="name",
                                            value=msg['name'],
                                            type="text",
                                        ),
                                        tag.input(
                                            name="agree",
                                            value=True,
                                            type="text",
                                        ),
                                        class_="hidden",
                                        method="post",
                                        action="",
                                    ),
                                  )

                    stream |= Transformer("//*[@id='main']/*[1]").before(alert_markup)
                    add_script(req, 'projectmessage/js/project_message.js')

                # if the timeout has been exceeded or does not exist yet, 
                # and there are no notifications to show, we update the 
                # session attribute table
                if not ProjectMessage.get_unagreed_messages(self.env, req.authname):
                    stamp = str(to_utimestamp(datetime.now(pytz.utc)))
                    req.session['project_message_timeout'] = stamp
                    req.session.save()

        return stream