def detect_webapp_string(err, data):
    """Parse and validate a webapp based on the string version of the provided
    manifest.

    """

    try:
        u_data = unicodehelper.decode(data)
        webapp = json.loads(u_data)

    except ValueError as exc:
        err.error(err_id=("webapp", "detect_webapp", "parse_error"),
                  error="JSON Parse Error",
                  description=[
                      "The webapp extension could not be parsed due to a "
                      "syntax error in the JSON.",
                      unicode(exc)
                  ])

    else:
        ws = WebappSpec(webapp, err)
        ws.validate()

        def long_name_warning(appendix=None):
            if appendix:
                appendix = [appendix]
            else:
                appendix = []
            err.warning(
                err_id=("webapp", "b2g", "name_truncated"),
                warning="App name may be truncated on Firefox OS devices.",
                description=[
                    "Your app's name is long enough to possibly be "
                    "truncated on Firefox OS devices. Consider using a "
                    "shorter name for your app.",
                    "App names may be truncated after 12 "
                    "characters."
                ] + appendix)

        def test_name(locale, appendix=None):
            if not isinstance(locale, dict):
                return
            name = locale.get("name")
            # This magic number brought to you by @cvan (see bug 770755)
            # Updated 11/21/12: Bumped to 12 because Gaia is different.
            if name and isinstance(name, (str, unicode)) and len(name) > 12:
                long_name_warning(appendix)

        test_name(webapp)
        locales = webapp.get("locales")
        if locales and isinstance(locales, dict):
            for locale in locales:
                test_name(locales[locale], 'Seen in the "%s" locale.' % locale)

        # If the manifest is still good, save it
        if not err.failed(fail_on_warnings=False):
            err.save_resource("manifest", webapp)

        return webapp
def detect_webapp_string(err, data):
    """Parse and validate a webapp based on the string version of the provided
    manifest.

    """

    try:
        u_data = unicodehelper.decode(data)
        webapp = json.loads(u_data)

    except ValueError as exc:
        err.error(
            err_id=("webapp", "detect_webapp", "parse_error"),
            error="JSON Parse Error",
            description=["The webapp extension could not be parsed due to a "
                         "syntax error in the JSON.",
                         unicode(exc)])

    else:
        ws = WebappSpec(webapp, err)
        ws.validate()

        def long_name_warning(appendix=None):
            if appendix:
                appendix = [appendix]
            else:
                appendix = []
            err.warning(
                err_id=("webapp", "b2g", "name_truncated"),
                warning="App name may be truncated on Firefox OS devices.",
                description=["Your app's name is long enough to possibly be "
                             "truncated on Firefox OS devices. Consider using a "
                             "shorter name for your app.",
                             "App names may be truncated after 12 "
                             "characters."] + appendix)

        def test_name(locale, appendix=None):
            if not isinstance(locale, dict):
                return
            name = locale.get("name")
            # This magic number brought to you by @cvan (see bug 770755)
            # Updated 11/21/12: Bumped to 12 because Gaia is different.
            if name and isinstance(name, (str, unicode)) and len(name) > 12:
                long_name_warning(appendix)

        test_name(webapp)
        locales = webapp.get("locales")
        if locales and isinstance(locales, dict):
            for locale in locales:
                test_name(locales[locale], 'Seen in the "%s" locale.' % locale)

        # If the manifest is still good, save it
        if not err.failed(fail_on_warnings=False):
            err.save_resource("manifest", webapp)

        return webapp
Example #3
0
def detect_webapp(err, package):
    """Detect, parse, and validate a webapp manifest."""

    # Parse the file.
    try:
        with open(package, mode="r") as f:
            data = f.read()
            u_data = decode(data)
            webapp = json.loads(u_data)
    except ValueError:
        return err.error(
            err_id=("webapp", "detect_webapp", "parse_error"),
            error="JSON Parse Error",
            description="The webapp extension could not be parsed due to a " "syntax error in the JSON.",
        )

    return test_webapp(err, webapp, VALID_KEYS)
Example #4
0
def detect_webapp_string(err, data):
    """
    Parse and validate a webapp based on the string version of the provided
    manifest.
    """
    try:
        u_data = decode(data)
        webapp = json.loads(u_data)
    except ValueError:
        return err.error(
            err_id=("webapp", "detect_webapp", "parse_error"),
            error="JSON Parse Error",
            description="The webapp extension could not be parsed due to a "
                        "syntax error in the JSON.")
    else:
        detect_webapp_raw(err, webapp)
        return webapp
Example #5
0
def detect_webapp_string(err, data):
    """Parse and validate a webapp based on the string version of the provided
    manifest.

    """

    try:
        u_data = unicodehelper.decode(data)
        webapp = json.loads(u_data)

    except ValueError:
        err.error(
            err_id=("webapp", "detect_webapp", "parse_error"),
            error="JSON Parse Error",
            description="The webapp extension could not be parsed due to a "
            "syntax error in the JSON.")

    else:
        ws = WebappSpec(webapp, err)
        ws.validate()

        # This magic number brought to you by @cvan (see bug 770755)
        # Updated 11/21/12: Bumped to 12 because Gaia is different.
        if ("name" in webapp and isinstance(webapp["name"], (str, unicode))
                and len(webapp["name"]) > 12):
            err.warning(
                err_id=("webapp", "b2g", "name_truncated"),
                warning="App name may be truncated on Firefox OS devices.",
                description=[
                    "Your app's name is long enough to possibly be "
                    "truncated on Firefox OS devices. Consider using a "
                    "shorter name for your app.",
                    "App names may be truncated after 12 characters."
                ])

        # If the manifest is still good, save it
        if not err.failed(fail_on_warnings=False):
            err.save_resource("manifest", webapp)

        return webapp
Example #6
0
    def _format_line(self, data, column=0, rel_line=1):
        """Formats a line from the data to be the appropriate length."""
        line_length = len(data)

        if line_length > 140:
            if rel_line == 0:
                # Trim from the beginning
                data = "... %s" % data[-140:]
            elif rel_line == 1:
                # Trim surrounding the error position
                if column < 70:
                    data = "%s ..." % data[:140]
                elif column > line_length - 70:
                    data = "... %s" % data[-140:]
                else:
                    data = "... %s ..." % data[column - 70:column + 70]

            elif rel_line == 2:
                # Trim from the end
                data = "%s ..." % data[:140]

        return unicodehelper.decode(data)
    def _format_line(self, data, column=0, rel_line=1):
        """Formats a line from the data to be the appropriate length."""
        line_length = len(data)

        if line_length > 140:
            if rel_line == 0:
                # Trim from the beginning
                data = "... %s" % data[-140:]
            elif rel_line == 1:
                # Trim surrounding the error position
                if column < 70:
                    data = "%s ..." % data[:140]
                elif column > line_length - 70:
                    data = "... %s" % data[-140:]
                else:
                    data = "... %s ..." % data[column - 70:column + 70]

            elif rel_line == 2:
                # Trim from the end
                data = "%s ..." % data[:140]

        return unicodehelper.decode(data)
Example #8
0
def detect_webapp_string(err, data):
    """Parse and validate a webapp based on the string version of the provided
    manifest.

    """

    try:
        u_data = unicodehelper.decode(data)
        webapp = json.loads(u_data)

    except ValueError:
        err.error(
            err_id=("webapp", "detect_webapp", "parse_error"),
            error="JSON Parse Error",
            description="The webapp extension could not be parsed due to a "
                        "syntax error in the JSON.")

    else:
        ws = WebappSpec(webapp, err)
        ws.validate()

        # This magic number brought to you by @cvan (see bug 770755)
        # Updated 11/21/12: Bumped to 12 because Gaia is different.
        if ("name" in webapp and isinstance(webapp["name"], (str, unicode)) and
                len(webapp["name"]) > 12):
            err.warning(
                err_id=("webapp", "b2g", "name_truncated"),
                warning="App name may be truncated on Firefox OS devices.",
                description=["Your app's name is long enough to possibly be "
                             "truncated on Firefox OS devices. Consider using a "
                             "shorter name for your app.",
                             "App names may be truncated after 12 characters."])

        # If the manifest is still good, save it
        if not err.failed(fail_on_warnings=False):
            err.save_resource("manifest", webapp)

        return webapp
Example #9
0
    def _save_message(self, stack, type_, message, context=None):
        "Stores a message in the appropriate message stack."

        uid = uuid.uuid4().hex
        message["uid"] = uid

        # Get the context for the message (if there's a context available)
        if context is not None:
            if isinstance(context, tuple):
                message["context"] = context
            else:
                message["context"] = (
                    context.get_context(line=message["line"],
                                        column=message["column"]))
        else:
            message["context"] = None

        message["message"] = unicodehelper.decode(message["message"])
        message["description"] = unicodehelper.decode(message["description"])

        # Test that if for_appversions is set that we're only applying to
        # supported add-ons. THIS IS THE LAST FILTER BEFORE THE MESSAGE IS
        # ADDED TO THE STACK!
        if message["for_appversions"]:
            if not self.supports_version(message["for_appversions"]):
                if self.instant:
                    print "(Instant error discarded)"
                    self._print_message(type_, message, verbose=True)
                return
        elif self.version_requirements:
            # If there was no for_appversions but there were version
            # requirements detailed in the decorator, use the ones from the
            # decorator.
            message["for_appversions"] = self.version_requirements

        # Save the message to the stack.
        stack.append(message)

        # Mark the tier that the error occurred at.
        if message["tier"] is None:
            message["tier"] = self.tier

        # Build out the compatibility summary if possible.
        if message["compatibility_type"]:
            self.compat_summary["%ss" % message["compatibility_type"]] += 1

        # Build out the message tree entry.
        if message["id"]:
            tree = self.message_tree
            last_id = None
            for eid in message["id"]:
                if last_id is not None:
                    tree = tree[last_id]
                if eid not in tree:
                    tree[eid] = {"__errors": 0,
                                 "__warnings": 0,
                                 "__notices": 0,
                                 "__messages": []}
                tree[eid]["__%s" % type_] += 1
                last_id = eid

            tree[last_id]['__messages'].append(uid)

        # If instant mode is turned on, output the message immediately.
        if self.instant:
            self._print_message(type_, message, verbose=True)
Example #10
0
    def _save_message(self, stack, type_, message, context=None):
        "Stores a message in the appropriate message stack."

        uid = uuid.uuid4().hex
        message["uid"] = uid

        # Get the context for the message (if there's a context available)
        if context is not None:
            if isinstance(context, tuple):
                message["context"] = context
            else:
                message["context"] = (context.get_context(
                    line=message["line"], column=message["column"]))
        else:
            message["context"] = None

        message["message"] = unicodehelper.decode(message["message"])
        message["description"] = unicodehelper.decode(message["description"])

        # Test that if for_appversions is set that we're only applying to
        # supported add-ons. THIS IS THE LAST FILTER BEFORE THE MESSAGE IS
        # ADDED TO THE STACK!
        if message["for_appversions"]:
            if not self.supports_version(message["for_appversions"]):
                if self.instant:
                    print "(Instant error discarded)"
                    self._print_message(type_, message, verbose=True)
                return
        elif self.version_requirements:
            # If there was no for_appversions but there were version
            # requirements detailed in the decorator, use the ones from the
            # decorator.
            message["for_appversions"] = self.version_requirements

        # Save the message to the stack.
        stack.append(message)

        # Mark the tier that the error occurred at.
        if message["tier"] is None:
            message["tier"] = self.tier

        # Build out the compatibility summary if possible.
        if message["compatibility_type"]:
            self.compat_summary["%ss" % message["compatibility_type"]] += 1

        # Build out the message tree entry.
        if message["id"]:
            tree = self.message_tree
            last_id = None
            for eid in message["id"]:
                if last_id is not None:
                    tree = tree[last_id]
                if eid not in tree:
                    tree[eid] = {
                        "__errors": 0,
                        "__warnings": 0,
                        "__notices": 0,
                        "__messages": []
                    }
                tree[eid]["__%s" % type_] += 1
                last_id = eid

            tree[last_id]['__messages'].append(uid)

        # If instant mode is turned on, output the message immediately.
        if self.instant:
            self._print_message(type_, message, verbose=True)