Ejemplo n.º 1
0
    def get_update(self):
        self.get_beta()
        data = self.data

        sql = ["""
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """]
        if data.get('appOS'):
            sql.append(' OR files.platform_id = %(appOS)s')

        if self.flags['use_version']:
            sql.append(') WHERE files.status > %(status)s AND '
                    'versions.version = %(version)s ')
        else:
            if self.flags['multiple_status']:
                # Note that getting this properly escaped is a pain.
                # Suggestions for improvement welcome.
                sql.append(') WHERE files.status in (%(STATUS_PUBLIC)s,'
                        '%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s) ')
            else:
                sql.append(') WHERE files.status = %(status)s ')

        sql.append('AND appmin.version_int <= %(version_int)s ')

        if self.compat_mode == 'ignore':
            pass  # no further SQL modification required.

        elif self.compat_mode == 'normal':
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append("""AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """)
            # Filter out versions that don't have the minimum maxVersion
            # requirement to qualify for default-to-compatible.
            d2c_max = applications.D2C_MAX_VERSIONS.get(data['app_id'])
            if d2c_max:
                data['d2c_max_version'] = version_int(d2c_max)
                sql.append("AND appmax.version_int >= %(d2c_max_version)s ")

            # Filter out versions found in compat overrides
            sql.append("""AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """)

        else:  # Not defined or 'strict'.
            sql.append('AND appmax.version_int >= %(version_int)s ')

        sql.append('ORDER BY versions.id DESC LIMIT 1;')

        self.cursor.execute(''.join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(zip([
                'guid', 'type', 'disabled_by_user', 'appguid', 'min', 'max',
                'file_id', 'file_status', 'hash', 'filename', 'version_id',
                'datestatuschanged', 'strict_compat', 'releasenotes',
                'version', 'premium_type'],
                list(result)))
            row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
            row['url'] = get_mirror(self.data['addon_status'],
                                    self.data['id'], row)
            data['row'] = row
            return True

        return False
Ejemplo n.º 2
0
    def get_update(self):
        self.get_beta()
        data = self.data

        sql = """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        if data.get('appOS'):
            sql += ' OR files.platform_id = %(appOS)s'

        if self.flags['use_version']:
            sql += (') WHERE files.status > %(status)s AND '
                    'versions.version = %(version)s ')
        else:
            if self.flags['multiple_status']:
                # Note that getting this properly escaped is a pain.
                # Suggestions for improvement welcome.
                sql += (') WHERE files.status in (%(STATUS_PUBLIC)s,'
                        '%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s)')
            else:
                sql += ') WHERE files.status = %(status)s '

        sql += """
            AND (appmin.version_int <= %(version_int)s
            AND appmax.version_int >= %(version_int)s)
            ORDER BY versions.id DESC LIMIT 1;
            """

        self.cursor.execute(sql, data)
        result = self.cursor.fetchone()
        if result:
            row = dict(zip([
                'guid', 'type', 'disabled_by_user', 'appguid', 'min', 'max',
                'file_id', 'file_status', 'hash', 'filename', 'version_id',
                'datestatuschanged', 'releasenotes', 'version',
                'premium_type'],
                list(result)))
            row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
            if row['premium_type'] == base.ADDON_PREMIUM:
                qs = urlencode(dict((k, data.get(k, ''))
                               for k in base.WATERMARK_KEYS))
                row['url'] = (u'%s/downloads/watermarked/%s?%s' %
                              (settings.SITE_URL, row['file_id'], qs))
            else:
                row['url'] = get_mirror(self.data['addon_status'],
                                        self.data['id'], row)
            data['row'] = row
            return True

        return False
Ejemplo n.º 3
0
    def get_update(self):
        data = self.data

        data['STATUS_PUBLIC'] = base.STATUS_PUBLIC
        data['STATUS_BETA'] = base.STATUS_BETA
        data['STATUS_DISABLED'] = base.STATUS_DISABLED
        data['RELEASE_CHANNEL_LISTED'] = base.RELEASE_CHANNEL_LISTED

        sql = [
            """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
                AND appmin.application_id = %(app_id)s
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
                AND appmax.application_id = %(app_id)s
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        ]
        if data.get('appOS'):
            sql.append(' OR files.platform_id = %(appOS)s')

        sql.append("""
            )
            -- Find a reference to the user's current version, if it exists.
            -- These should never be inner joins. We need results even if we
            -- can't find the current version.
            LEFT JOIN versions curver
                ON curver.addon_id = addons.id AND curver.version = %(version)s
            LEFT JOIN files curfile
                ON curfile.version_id = curver.id
            WHERE
                versions.deleted = 0 AND
                versions.channel = %(RELEASE_CHANNEL_LISTED)s AND
                -- Note that the WHEN clauses here will evaluate to the same
                -- thing for each row we examine. The JOINs above narrow the
                -- rows matched by the WHERE clause to versions of a specific
                -- add-on, and the ORDER BY and LIMIT 1 clauses below make it
                -- unlikely that we'll be examining a large number of rows,
                -- so this is fairly cheap.
                CASE
                WHEN curfile.status = %(STATUS_BETA)s
                THEN
                    -- User's current version is a known beta version.
                    --
                    -- Serve only beta updates. Serving a full version here
                    -- will forever kick users out of the beta update channel.
                    --
                    -- If the add-on does not have full review, serve no
                    -- updates.

                    addons.status = %(STATUS_PUBLIC)s AND
                    files.status = %(STATUS_BETA)s

                ELSE
                   -- Anything else, including:
                   --
                   --  * Add-on has full review
                   --  * User's current version has full review, regardless
                   --    of add-on status
                   --
                   -- Serve only full-reviewed updates.
                   files.status = %(STATUS_PUBLIC)s
                END
        """)

        sql.append('AND appmin.version_int <= %(version_int)s ')

        if self.compat_mode == 'ignore':
            pass  # no further SQL modification required.

        elif self.compat_mode == 'normal':
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append("""AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """)
            # Filter out versions that don't have the minimum maxVersion
            # requirement to qualify for default-to-compatible.
            d2c_max = applications.D2C_MAX_VERSIONS.get(data['app_id'])
            if d2c_max:
                data['d2c_max_version'] = version_int(d2c_max)
                sql.append("AND appmax.version_int >= %(d2c_max_version)s ")

            # Filter out versions found in compat overrides
            sql.append("""AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """)

        else:  # Not defined or 'strict'.
            sql.append('AND appmax.version_int >= %(version_int)s ')

        # Special case for bug 1031516.
        if data['guid'] == '*****@*****.**':
            app_version = data['version_int']
            hotfix_version = data['version']
            if version_int('10') <= app_version <= version_int('16.0.1'):
                if hotfix_version < '20121019.01':
                    sql.append("AND versions.version = '20121019.01' ")
                elif hotfix_version < '20130826.01':
                    sql.append("AND versions.version = '20130826.01' ")
            elif version_int('16.0.2') <= app_version <= version_int('24.*'):
                if hotfix_version < '20130826.01':
                    sql.append("AND versions.version = '20130826.01' ")

        sql.append('ORDER BY versions.id DESC LIMIT 1;')

        self.cursor.execute(''.join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(
                zip([
                    'guid', 'type', 'disabled_by_user', 'min', 'max',
                    'file_id', 'file_status', 'hash', 'filename', 'version_id',
                    'datestatuschanged', 'strict_compat', 'releasenotes',
                    'version'
                ], list(result)))
            row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
            row['url'] = get_mirror(data['addon_status'], data['id'], row)
            row['appguid'] = applications.APPS_ALL[data['app_id']].guid
            data['row'] = row
            return True

        return False
Ejemplo n.º 4
0
    def get_update(self):
        self.get_beta()
        data = self.data

        sql = [
            """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        ]
        if data.get("appOS"):
            sql.append(" OR files.platform_id = %(appOS)s")

        if self.flags["use_version"]:
            sql.append(") WHERE files.status > %(status)s AND " "versions.version = %(version)s ")
        else:
            if self.flags["multiple_status"]:
                # Note that getting this properly escaped is a pain.
                # Suggestions for improvement welcome.
                sql.append(
                    ") WHERE files.status in (%(STATUS_PUBLIC)s," "%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s) "
                )
            else:
                sql.append(") WHERE files.status = %(status)s ")

        sql.append("AND appmin.version_int <= %(version_int)s ")

        if self.compat_mode == "ignore":
            pass  # no further SQL modification required.

        elif self.compat_mode == "normal":
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append(
                """AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """
            )
            # Filter out versions found in compat overrides
            sql.append(
                """AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """
            )

        else:  # Not defined or 'strict'.
            sql.append("AND appmax.version_int >= %(version_int)s ")

        sql.append("ORDER BY versions.id DESC LIMIT 1;")

        self.cursor.execute("".join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(
                zip(
                    [
                        "guid",
                        "type",
                        "disabled_by_user",
                        "appguid",
                        "min",
                        "max",
                        "file_id",
                        "file_status",
                        "hash",
                        "filename",
                        "version_id",
                        "datestatuschanged",
                        "strict_compat",
                        "releasenotes",
                        "version",
                        "premium_type",
                    ],
                    list(result),
                )
            )
            row["type"] = base.ADDON_SLUGS_UPDATE[row["type"]]
            if row["premium_type"] in base.ADDON_PREMIUMS:
                qs = urlencode(dict((k, data.get(k, "")) for k in base.WATERMARK_KEYS))
                row["url"] = u"%s/downloads/watermarked/%s?%s" % (settings.SITE_URL, row["file_id"], qs)
            else:
                row["url"] = get_mirror(self.data["addon_status"], self.data["id"], row)
            data["row"] = row
            return True

        return False
Ejemplo n.º 5
0
    def get_update(self):
        data = self.data

        data.update(STATUSES_PUBLIC)
        data['STATUS_BETA'] = base.STATUS_BETA
        data['STATUS_DISABLED'] = base.STATUS_DISABLED

        sql = ["""
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
                AND appmin.application_id = %(app_id)s
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
                AND appmax.application_id = %(app_id)s
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """]
        if data.get('appOS'):
            sql.append(' OR files.platform_id = %(appOS)s')

        sql.append("""
            )
            -- Find a reference to the user's current version, if it exists.
            -- These should never be inner joins. We need results even if we
            -- can't find the current version.
            LEFT JOIN versions curver
                ON curver.addon_id = addons.id AND curver.version = %(version)s
            LEFT JOIN files curfile
                ON curfile.version_id = curver.id
            WHERE
                -- Note that the WHEN clauses here will evaluate to the same
                -- thing for each row we examine. The JOINs above narrow the
                -- rows matched by the WHERE clause to versions of a specific
                -- add-on, and the ORDER BY and LIMIT 1 clauses below make it
                -- unlikely that we'll be examining a large number of rows,
                -- so this is fairly cheap.
                CASE
                WHEN curfile.status = %(STATUS_BETA)s
                THEN
                    -- User's current version is a known beta version.
                    --
                    -- Serve only beta updates. Serving a full version here
                    -- will forever kick users out of the beta update channel.
                    --
                    -- If the add-on does not have full review, serve no
                    -- updates.

                    addons.status = %(STATUS_PUBLIC)s AND
                    files.status = %(STATUS_BETA)s

                WHEN addons.status IN (%(STATUS_LITE)s,
                                       %(STATUS_LITE_AND_NOMINATED)s)
                   AND (curfile.id IS NULL OR
                        curfile.status IN (%(STATUS_LITE)s,
                                           %(STATUS_DISABLED)s))
                THEN
                   -- Add-on is prelim, and user's current version is either a
                   -- known prelim, or an unknown version.
                   --
                   -- Serve only prelim versions. Serving a full version here
                   -- will prevent users from receiving further updates until
                   -- the add-on achieves full review.

                   files.status = %(STATUS_LITE)s

                ELSE
                   -- Anything else, including:
                   --
                   --  * Add-on has full review
                   --  * User's current version has full review, regardless
                   --    of add-on status
                   --
                   -- Serve only full-reviewed updates.
                   files.status = %(STATUS_PUBLIC)s
                END
        """)

        sql.append('AND appmin.version_int <= %(version_int)s ')

        if self.compat_mode == 'ignore':
            pass  # no further SQL modification required.

        elif self.compat_mode == 'normal':
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append("""AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """)
            # Filter out versions that don't have the minimum maxVersion
            # requirement to qualify for default-to-compatible.
            d2c_max = applications.D2C_MAX_VERSIONS.get(data['app_id'])
            if d2c_max:
                data['d2c_max_version'] = version_int(d2c_max)
                sql.append("AND appmax.version_int >= %(d2c_max_version)s ")

            # Filter out versions found in compat overrides
            sql.append("""AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """)

        else:  # Not defined or 'strict'.
            sql.append('AND appmax.version_int >= %(version_int)s ')

        # Special case for bug 1031516.
        if data['guid'] == '*****@*****.**':
            app_version = data['version_int']
            hotfix_version = data['version']
            if version_int('10') <= app_version <= version_int('16.0.1'):
                if hotfix_version < '20121019.01':
                    sql.append("AND versions.version = '20121019.01' ")
                elif hotfix_version < '20130826.01':
                    sql.append("AND versions.version = '20130826.01' ")
            elif version_int('16.0.2') <= app_version <= version_int('24.*'):
                if hotfix_version < '20130826.01':
                    sql.append("AND versions.version = '20130826.01' ")

        sql.append('ORDER BY versions.id DESC LIMIT 1;')

        self.cursor.execute(''.join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(zip([
                'guid', 'type', 'disabled_by_user', 'min', 'max',
                'file_id', 'file_status', 'hash', 'filename', 'version_id',
                'datestatuschanged', 'strict_compat', 'releasenotes',
                'version', 'premium_type'],
                list(result)))
            row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
            row['url'] = get_mirror(data['addon_status'],
                                    data['id'], row)
            row['appguid'] = applications.APPS_ALL[data['app_id']].guid
            data['row'] = row
            return True

        return False
Ejemplo n.º 6
0
    def get_update(self):
        self.get_beta()
        data = self.data

        sql = """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                versions.releasenotes, versions.version as version
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        if data.get('appOS'):
            sql += ' OR files.platform_id = %(appOS)s'

        if self.flags['use_version']:
            sql += (') WHERE files.status > %(status)s AND '
                    'versions.version = %(version)s ')
        else:
            if self.flags['multiple_status']:
                # Note that getting this properly escaped is a pain.
                # Suggestions for improvement welcome.
                sql += (') WHERE files.status in (%(STATUS_PUBLIC)s,'
                        '%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s)')
            else:
                sql += ') WHERE files.status = %(status)s '

        sql += """
            AND (appmin.version_int <= %(version_int)s
            AND appmax.version_int >= %(version_int)s)
            ORDER BY versions.id DESC LIMIT 1;
            """

        self.cursor.execute(sql, data)
        result = self.cursor.fetchone()
        if result:
            row = dict(
                zip([
                    'guid', 'type', 'disabled_by_user', 'appguid', 'min',
                    'max', 'file_id', 'file_status', 'hash', 'filename',
                    'version_id', 'datestatuschanged', 'releasenotes',
                    'version'
                ], list(result)))
            row['type'] = ADDON_SLUGS_UPDATE[row['type']]
            row['url'] = get_mirror(self.data['addon_status'], self.data['id'],
                                    row)
            data['row'] = row
            return True

        return False
Ejemplo n.º 7
0
    def get_update(self):
        self.get_beta()
        data = self.data

        sql = [
            """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        ]
        if data.get('appOS'):
            sql.append(' OR files.platform_id = %(appOS)s')

        if self.flags['use_version']:
            sql.append(') WHERE files.status > %(status)s AND '
                       'versions.version = %(version)s ')
        else:
            if self.flags['multiple_status']:
                # Note that getting this properly escaped is a pain.
                # Suggestions for improvement welcome.
                sql.append(') WHERE files.status in (%(STATUS_PUBLIC)s,'
                           '%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s) ')
            else:
                sql.append(') WHERE files.status = %(status)s ')

        sql.append('AND appmin.version_int <= %(version_int)s ')

        if self.compat_mode == 'ignore':
            pass  # no further SQL modification required.

        elif self.compat_mode == 'normal':
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append("""AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """)
            # Filter out versions that don't have the minimum maxVersion
            # requirement to qualify for default-to-compatible.
            d2c_max = applications.D2C_MAX_VERSIONS.get(data['app_id'])
            if d2c_max:
                data['d2c_max_version'] = version_int(d2c_max)
                sql.append("AND appmax.version_int >= %(d2c_max_version)s ")

            # Filter out versions found in compat overrides
            sql.append("""AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """)

        else:  # Not defined or 'strict'.
            sql.append('AND appmax.version_int >= %(version_int)s ')

        sql.append('ORDER BY versions.id DESC LIMIT 1;')

        self.cursor.execute(''.join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(
                zip([
                    'guid', 'type', 'disabled_by_user', 'appguid', 'min',
                    'max', 'file_id', 'file_status', 'hash', 'filename',
                    'version_id', 'datestatuschanged', 'strict_compat',
                    'releasenotes', 'version', 'premium_type'
                ], list(result)))
            row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
            row['url'] = get_mirror(self.data['addon_status'], self.data['id'],
                                    row)
            data['row'] = row
            return True

        return False
Ejemplo n.º 8
0
    def get_update(self):
        data = self.data

        data.update(STATUSES_PUBLIC)
        data["STATUS_BETA"] = base.STATUS_BETA

        sql = [
            """
            SELECT
                addons.guid as guid, addons.addontype_id as type,
                addons.inactive as disabled_by_user,
                applications.guid as appguid, appmin.version as min,
                appmax.version as max, files.id as file_id,
                files.status as file_status, files.hash,
                files.filename, versions.id as version_id,
                files.datestatuschanged as datestatuschanged,
                files.strict_compatibility as strict_compat,
                versions.releasenotes, versions.version as version,
                addons.premium_type
            FROM versions
            INNER JOIN addons
                ON addons.id = versions.addon_id AND addons.id = %(id)s
            INNER JOIN applications_versions
                ON applications_versions.version_id = versions.id
            INNER JOIN applications
                ON applications_versions.application_id = applications.id
                AND applications.id = %(app_id)s
            INNER JOIN appversions appmin
                ON appmin.id = applications_versions.min
            INNER JOIN appversions appmax
                ON appmax.id = applications_versions.max
            INNER JOIN files
                ON files.version_id = versions.id AND (files.platform_id = 1
            """
        ]
        if data.get("appOS"):
            sql.append(" OR files.platform_id = %(appOS)s")

        sql.append(
            """
            )
            -- Find a reference to the user's current version, if it exists.
            -- These should never be inner joins. We need results even if we
            -- can't find the current version.
            LEFT JOIN versions curver
                ON curver.addon_id = addons.id AND curver.version = %(version)s
            LEFT JOIN files curfile
                ON curfile.version_id = curver.id
            WHERE
                -- Note that the WHEN clauses here will evaluate to the same
                -- thing for each row we examine. The JOINs above narrow the
                -- rows matched by the WHERE clause to versions of a specific
                -- add-on, and the ORDER BY and LIMIT 1 clauses below make it
                -- unlikely that we'll be examining a large number of rows,
                -- so this is fairly cheap.
                CASE
                WHEN curfile.status = %(STATUS_BETA)s
                THEN
                    -- User's current version is a known beta version.
                    --
                    -- Serve only beta updates. Serving a full version here
                    -- will forever kick users out of the beta update channel.
                    --
                    -- If the add-on does not have full review, serve no
                    -- updates.

                    addons.status = %(STATUS_PUBLIC)s AND
                    files.status = %(STATUS_BETA)s

                WHEN addons.status IN (%(STATUS_LITE)s,
                                       %(STATUS_LITE_AND_NOMINATED)s)
                   AND (curfile.id IS NULL OR curfile.status = %(STATUS_LITE)s)
                THEN
                   -- Add-on is prelim, and user's current version is either a
                   -- known prelim, or an unknown version.
                   --
                   -- Serve only prelim versions. Serving a full version here
                   -- will prevent users from receiving further updates until
                   -- the add-on achieves full review.

                   files.status = %(STATUS_LITE)s

                ELSE
                   -- Anything else, including:
                   --
                   --  * Add-on has full review
                   --  * User's current version has full review, regardless
                   --    of add-on status
                   --
                   -- Serve only full-reviewed updates.
                   files.status = %(STATUS_PUBLIC)s
                END
        """
        )

        sql.append("AND appmin.version_int <= %(version_int)s ")

        if self.compat_mode == "ignore":
            pass  # no further SQL modification required.

        elif self.compat_mode == "normal":
            # When file has strict_compatibility enabled, or file has binary
            # components, default to compatible is disabled.
            sql.append(
                """AND
                CASE WHEN files.strict_compatibility = 1 OR
                          files.binary_components = 1
                THEN appmax.version_int >= %(version_int)s ELSE 1 END
            """
            )
            # Filter out versions that don't have the minimum maxVersion
            # requirement to qualify for default-to-compatible.
            d2c_max = applications.D2C_MAX_VERSIONS.get(data["app_id"])
            if d2c_max:
                data["d2c_max_version"] = version_int(d2c_max)
                sql.append("AND appmax.version_int >= %(d2c_max_version)s ")

            # Filter out versions found in compat overrides
            sql.append(
                """AND
                NOT versions.id IN (
                SELECT version_id FROM incompatible_versions
                WHERE app_id=%(app_id)s AND
                  (min_app_version='0' AND
                       max_app_version_int >= %(version_int)s) OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version='*') OR
                  (min_app_version_int <= %(version_int)s AND
                       max_app_version_int >= %(version_int)s)) """
            )

        else:  # Not defined or 'strict'.
            sql.append("AND appmax.version_int >= %(version_int)s ")

        sql.append("ORDER BY versions.id DESC LIMIT 1;")

        self.cursor.execute("".join(sql), data)
        result = self.cursor.fetchone()

        if result:
            row = dict(
                zip(
                    [
                        "guid",
                        "type",
                        "disabled_by_user",
                        "appguid",
                        "min",
                        "max",
                        "file_id",
                        "file_status",
                        "hash",
                        "filename",
                        "version_id",
                        "datestatuschanged",
                        "strict_compat",
                        "releasenotes",
                        "version",
                        "premium_type",
                    ],
                    list(result),
                )
            )
            row["type"] = base.ADDON_SLUGS_UPDATE[row["type"]]
            row["url"] = get_mirror(data["addon_status"], data["id"], row)
            data["row"] = row
            return True

        return False