Esempio n. 1
0
    def widget(self, resource, values):
        """
            Render this widget as HTML helper object(s)

            @param resource: the resource
            @param values: the search values from the URL query
        """

        attr = self.attr

        # CSS class and element ID
        _class = self._class
        if "_class" in attr and attr["_class"]:
            _class = "%s %s" % (attr["_class"], _class)
        else:
            _class = _class
        _id = attr["_id"]

        # Determine the field type
        rfield = S3ResourceField(resource, self.field)
        field = rfield.field
        if rfield.virtual:
            # S3DateTimeWidget doesn't support virtual fields
            dtformat = current.deployment_settings.get_L10n_date_format()
            field = Field(rfield.fname,
                          "datetime",
                          requires=IS_DATE_IN_RANGE(format=dtformat))
            field._tablename = rfield.tname
        elif not rfield.field:
            # Unresolvable selector
            return ""

        # Options
        hide_time = self.opts.get("hide_time", False)

        # Generate the input elements
        selector = self.selector
        _variable = self._variable
        input_class = self._input_class
        input_labels = self.input_labels
        input_elements = DIV(_id=_id, _class=_class)
        append = input_elements.append
        for operator in self.operator:

            input_id = "%s-%s" % (_id, operator)

            # Determine the widget class
            if rfield.ftype == "date":
                widget = S3DateWidget()
            else:
                opts = {}
                if operator == "ge":
                    opts["set_min"] = "%s-%s" % (_id, "le")
                elif operator == "le":
                    opts["set_max"] = "%s-%s" % (_id, "ge")
                widget = S3DateTimeWidget(hide_time=hide_time, **opts)

            # Populate with the value, if given
            # if user has not set any of the limits, we get [] in values.
            variable = _variable(selector, operator)
            value = values.get(variable, None)
            if value not in [None, []]:
                if type(value) is list:
                    value = value[0]
            else:
                value = None

            # Render the widget
            picker = widget(field,
                            value,
                            _name=input_id,
                            _id=input_id,
                            _class=input_class)

            # Append label and widget
            append(current.T(input_labels[operator]) + ":")
            append(picker)

        return input_elements
Esempio n. 2
0
    def configure_tasktable_crud(self,
                                 task=None,
                                 function=None,
                                 args=[],
                                 vars={},
                                 period = 3600, # seconds, so 1 hour
                                 ):
        """
            Configure the task table for interactive CRUD,
            setting defaults, widgets and hiding unnecessary fields

            @param task: the task name (will use a UUID if omitted)
            @param function: the function name (won't hide if omitted)
            @param args: the function position arguments
            @param vars: the function named arguments
        """

        T = current.T
        NONE = current.messages["NONE"]
        UNLIMITED = T("unlimited")

        tablename = self.TASK_TABLENAME
        table = current.db[tablename]

        table.uuid.readable = table.uuid.writable = False

        table.sync_output.readable = table.sync_output.writable = False

        table.times_failed.readable = False

        field = table.start_time
        field.represent = lambda dt: S3DateTime.datetime_represent(dt, utc=True)
        field.widget = S3DateTimeWidget(past=0)
        field.requires = IS_UTC_DATETIME(
                    format=current.deployment_settings.get_L10n_datetime_format()
                )

        field = table.stop_time
        field.represent = lambda dt: S3DateTime.datetime_represent(dt, utc=True)
        field.widget = S3DateTimeWidget(past=0)
        field.requires = IS_EMPTY_OR(
                            IS_UTC_DATETIME(
                    format=current.deployment_settings.get_L10n_datetime_format()
                ))

        if not task:
            import uuid
            task = str(uuid.uuid4())
        field = table.task_name
        field.default = task
        field.readable = False
        field.writable = False

        if function:
            field = table.function_name
            field.default = function
            field.readable = False
            field.writable = False

        field = table.args
        field.default = json.dumps(args)
        field.readable = False
        field.writable = False

        field = table.repeats
        field.label = T("Repeat")
        field.comment = T("times (0 = unlimited)")
        field.default = 0
        field.represent = lambda opt: \
            opt and "%s %s" % (opt, T("times")) or \
            opt == 0 and UNLIMITED or \
            NONE

        field = table.period
        field.label = T("Run every")
        field.default = period
        field.widget = S3TimeIntervalWidget.widget
        field.requires = IS_TIME_INTERVAL_WIDGET(table.period)
        field.represent = S3TimeIntervalWidget.represent
        field.comment = None

        table.timeout.default = 600
        table.timeout.represent = lambda opt: \
            opt and "%s %s" % (opt, T("seconds")) or \
            opt == 0 and UNLIMITED or \
            NONE

        field = table.vars
        field.default = json.dumps(vars)
        field.readable = field.writable = False

        # Always use "default" controller (web2py uses current controller),
        # otherwise the anonymous worker does not pass the controller
        # permission check and gets redirected to login before it reaches
        # the task function which does the s3_impersonate
        field = table.application_name
        field.default = "%s/default" % current.request.application
        field.readable = field.writable = False
        table.group_name.readable = table.group_name.writable = False
        table.status.readable = table.status.writable = False
        table.next_run_time.readable = table.next_run_time.writable = False
        table.times_run.readable = table.times_run.writable = False
        table.assigned_worker_name.readable = table.assigned_worker_name.writable = False

        current.s3db.configure(tablename,
                               list_fields=["id",
                                            "enabled",
                                            "start_time",
                                            "repeats",
                                            "period",
                                            (T("Last run"), "last_run_time"),
                                            (T("Last status"), "status"),
                                            (T("Next run"), "next_run_time"),
                                            "stop_time"
                                            ])

        response = current.response
        if response:
            response.s3.crud_strings[tablename] = Storage(
                title_create = T("Add Job"),
                title_display = T("Scheduled Jobs"),
                title_list = T("Job Schedule"),
                title_update = T("Edit Job"),
                #title_search = T("Search for Job"),
                subtitle_create = T("Add Job"),
                label_list_button = T("List Jobs"),
                label_create_button = T("Add Job"),
                msg_record_created = T("Job added"),
                msg_record_modified = T("Job updated"),
                msg_record_deleted = T("Job deleted"),
                msg_list_empty = T("No jobs configured yet"),
                msg_no_match = T("No jobs configured"))

        return
Esempio n. 3
0
def s3_datetime(name="date", **attr):
    """
        Return a standard Datetime field

        Additional options to normal S3ResuableField:
            default = "now" (in addition to usual meanings)
            represent = "date" (in addition to usual meanings)
            widget = "date" (in addition to usual meanings)
            past = x hours
            future = x hours
    """

    if "past" in attr:
        past = attr["past"]
        del attr["past"]
    else:
        past = None
    if "future" in attr:
        future = attr["future"]
        del attr["future"]
    else:
        future = None

    if "default" in attr and attr["default"] == "now":
        attr["default"] = current.request.utcnow
    if "label" not in attr:
        attr["label"] = current.T("Date")
    if "represent" not in attr:
        attr["represent"] = lambda dt: S3DateTime.datetime_represent(dt,
                                                                     utc=True)
    elif attr["represent"] == "date":
        attr["represent"] = lambda dt: S3DateTime.date_represent(dt, utc=True)

    if "widget" not in attr:
        if past is None and future is None:
            attr["widget"] = S3DateTimeWidget()
        elif past is None:
            attr["widget"] = S3DateTimeWidget(future=future)
        elif future is None:
            attr["widget"] = S3DateTimeWidget(past=past)
        else:
            attr["widget"] = S3DateTimeWidget(past=past, future=future)
    elif attr["widget"] == "date":
        if past is None and future is None:
            attr["widget"] = S3DateWidget()
            requires = IS_DATE(
                format=current.deployment_settings.get_L10n_date_format())
        else:
            now = current.request.utcnow.date()
            current_month = now.month
            if past is None:
                future = int(round(future / 744.0, 0))
                attr["widget"] = S3DateWidget(future=future)
                future_month = now.month + future
                if future_month <= 12:
                    max = now.replace(month=future_month)
                else:
                    current_year = now.year
                    years = int(future_month / 12)
                    future_year = current_year + years
                    future_month = future_month - (years * 12)
                    max = now.replace(year=future_year, month=future_month)
                requires = IS_DATE_IN_RANGE(
                    format=current.deployment_settings.get_L10n_date_format(),
                    maximum=max,
                    error_message=current.T(
                        "Date must be %(max)s or earlier!"))
            elif future is None:
                past = int(round(past / 744.0, 0))
                attr["widget"] = S3DateWidget(past=past)
                if past < current_month:
                    min = now.replace(month=current_month - past)
                else:
                    current_year = now.year
                    past_years = int(past / 12)
                    past_months = past - (past_years * 12)
                    min = now.replace(year=current_year - past_years,
                                      month=current_month - past_months)
                requires = IS_DATE_IN_RANGE(
                    format=current.deployment_settings.get_L10n_date_format(),
                    minimum=min,
                    error_message=current.T("Date must be %(min)s or later!"))
            else:
                future = int(round(future / 744.0, 0))
                past = int(round(past / 744.0, 0))
                attr["widget"] = S3DateWidget(past=past, future=future)
                future_month = now.month + future
                if future_month < 13:
                    max = now.replace(month=future_month)
                else:
                    current_year = now.year
                    years = int(future_month / 12)
                    future_year = now.year + years
                    future_month = future_month - (years * 12)
                    max = now.replace(year=future_year, month=future_month)
                if past < current_month:
                    min = now.replace(month=current_month - past)
                else:
                    current_year = now.year
                    past_years = int(past / 12)
                    past_months = past - (past_years * 12)
                    min = now.replace(year=current_year - past_years,
                                      month=current_month - past_months)
                requires = IS_DATE_IN_RANGE(
                    format=current.deployment_settings.get_L10n_date_format(),
                    maximum=max,
                    minimum=min,
                    error_message=current.T(
                        "Date must be between %(min)s and %(max)s!"))
        if "empty" in attr:
            if attr["empty"] is False:
                attr["requires"] = requires
            else:
                attr["requires"] = IS_EMPTY_OR(requires)
            del attr["empty"]
        else:
            # Default
            attr["requires"] = IS_EMPTY_OR(requires)

    if "requires" not in attr:
        if past is None and future is None:
            requires = IS_UTC_DATETIME(
                format=current.deployment_settings.get_L10n_datetime_format())
        else:
            now = current.request.utcnow
            if past is None:
                max = now + datetime.timedelta(hours=future)
                requires = IS_UTC_DATETIME(
                    format=current.deployment_settings.
                    get_L10n_datetime_format(),
                    maximum=max,
                    error_message=current.T(
                        "Date must be %(max)s or earlier!"))
            elif future is None:
                min = now - datetime.timedelta(hours=past)
                requires = IS_UTC_DATETIME(
                    format=current.deployment_settings.
                    get_L10n_datetime_format(),
                    minimum=min,
                    error_message=current.T("Date must be %(min)s or later!"))
            else:
                min = now - datetime.timedelta(hours=past)
                max = now + datetime.timedelta(hours=future)
                requires = IS_UTC_DATETIME(
                    format=current.deployment_settings.
                    get_L10n_datetime_format(),
                    maximum=max,
                    minimum=min,
                    error_message=current.T(
                        "Date must be between %(min)s and %(max)s!"))
        if "empty" in attr:
            if attr["empty"] is False:
                attr["requires"] = requires
            else:
                attr["requires"] = IS_EMPTY_OR(requires)
            del attr["empty"]
        else:
            # Default
            attr["requires"] = IS_EMPTY_OR(requires)

    f = S3ReusableField(name, "datetime", **attr)
    return f()