コード例 #1
0
def test_extract_header_with_additional_imgs():
    file_obj = os.path.join(
        settings.ROOT,
        'src/olympia/devhub/tests/addons/static_theme_tiled.zip')
    data = {
        'images': {
            'headerURL':
            'empty.png',
            'additional_backgrounds': [
                'transparent.gif', 'missing_&_ignored.png',
                'weta_for_tiling.png'
            ]
        }
    }
    dest_path = tempfile.mkdtemp()
    header_file = dest_path + '/empty.png'
    additional_file_1 = dest_path + '/transparent.gif'
    additional_file_2 = dest_path + '/weta_for_tiling.png'
    assert not default_storage.exists(header_file)
    assert not default_storage.exists(additional_file_1)
    assert not default_storage.exists(additional_file_2)

    utils.extract_header_img(file_obj, data, dest_path)
    assert default_storage.exists(header_file)
    assert default_storage.size(header_file) == 332
    assert default_storage.exists(additional_file_1)
    assert default_storage.size(additional_file_1) == 42
    assert default_storage.exists(additional_file_2)
    assert default_storage.size(additional_file_2) == 93371
コード例 #2
0
    def test_extract_header_img_missing(self):
        data = {'images': {'headerURL': 'missing_file.png'}}
        dest_path = tempfile.mkdtemp()
        header_file = dest_path + '/missing_file.png'
        assert not default_storage.exists(header_file)

        utils.extract_header_img(self.file_obj, data, dest_path)
        assert not default_storage.exists(header_file)
コード例 #3
0
    def test_extract_header_img(self):
        data = {'images': {'headerURL': 'weta.png'}}
        dest_path = tempfile.mkdtemp()
        header_file = dest_path + '/weta.png'
        assert not default_storage.exists(header_file)

        utils.extract_header_img(self.file_obj, data, dest_path)
        assert default_storage.exists(header_file)
        assert default_storage.size(header_file) == 126447
コード例 #4
0
def test_extract_header_img_missing():
    file_obj = os.path.join(
        settings.ROOT, 'src/olympia/devhub/tests/addons/static_theme.zip')
    data = {'images': {'headerURL': 'missing_file.png'}}
    dest_path = tempfile.mkdtemp()
    header_file = dest_path + '/missing_file.png'
    assert not default_storage.exists(header_file)

    utils.extract_header_img(file_obj, data, dest_path)
    assert not default_storage.exists(header_file)
コード例 #5
0
def test_extract_header_img_missing():
    file_obj = os.path.join(
        settings.ROOT, 'src/olympia/devhub/tests/addons/static_theme.zip')
    data = {'images': {'headerURL': 'missing_file.png'}}
    dest_path = tempfile.mkdtemp()
    header_file = dest_path + '/missing_file.png'
    assert not default_storage.exists(header_file)

    utils.extract_header_img(file_obj, data, dest_path)
    assert not default_storage.exists(header_file)
コード例 #6
0
    def test_extract_header_img_not_image(self):
        self.file_obj = os.path.join(
            settings.ROOT,
            'src/olympia/devhub/tests/addons/static_theme_non_image.zip')
        data = {'images': {'headerURL': 'not_an_image.js'}}
        dest_path = tempfile.mkdtemp()
        header_file = dest_path + '/not_an_image.js'
        assert not default_storage.exists(header_file)

        utils.extract_header_img(self.file_obj, data, dest_path)
        assert not default_storage.exists(header_file)
コード例 #7
0
def test_extract_header_with_additional_imgs():
    file_obj = os.path.join(
        settings.ROOT,
        'src/olympia/devhub/tests/addons/static_theme_tiled.zip')
    data = {'images': {
        'headerURL': 'empty.png',
        'additional_backgrounds': [
            'transparent.gif', 'missing_&_ignored.png', 'weta_for_tiling.png']
    }}
    dest_path = tempfile.mkdtemp()
    header_file = dest_path + '/empty.png'
    additional_file_1 = dest_path + '/transparent.gif'
    additional_file_2 = dest_path + '/weta_for_tiling.png'
    assert not default_storage.exists(header_file)
    assert not default_storage.exists(additional_file_1)
    assert not default_storage.exists(additional_file_2)

    utils.extract_header_img(file_obj, data, dest_path)
    assert default_storage.exists(header_file)
    assert default_storage.size(header_file) == 332
    assert default_storage.exists(additional_file_1)
    assert default_storage.size(additional_file_1) == 42
    assert default_storage.exists(additional_file_2)
    assert default_storage.size(additional_file_2) == 93371
コード例 #8
0
ファイル: models.py プロジェクト: phawit555/addons-server
    def from_upload(cls,
                    upload,
                    addon,
                    platforms,
                    channel,
                    send_signal=True,
                    source=None,
                    is_beta=False,
                    parsed_data=None):
        from olympia.addons.models import AddonFeatureCompatibility

        if addon.status == amo.STATUS_DISABLED:
            raise VersionCreateError(
                'Addon is Mozilla Disabled; no new versions are allowed.')

        if parsed_data is None:
            parsed_data = utils.parse_addon(upload, addon)
        license_id = None
        if channel == amo.RELEASE_CHANNEL_LISTED:
            previous_version = addon.find_latest_version(channel=channel,
                                                         exclude=())
            if previous_version and previous_version.license_id:
                license_id = previous_version.license_id
        version = cls.objects.create(
            addon=addon,
            version=parsed_data['version'],
            license_id=license_id,
            source=source,
            channel=channel,
        )
        log.info('New version: %r (%s) from %r' %
                 (version, version.id, upload))
        activity.log_create(amo.LOG.ADD_VERSION, version, addon)
        # Update the add-on e10s compatibility since we're creating a new
        # version that may change that.
        e10s_compatibility = parsed_data.get('e10s_compatibility')
        if e10s_compatibility is not None:
            feature_compatibility = (
                AddonFeatureCompatibility.objects.get_or_create(
                    addon=addon)[0])
            feature_compatibility.update(e10s=e10s_compatibility)

        compatible_apps = {}
        for app in parsed_data.get('apps', []):
            compatible_apps[app.appdata] = ApplicationsVersions(
                version=version, min=app.min, max=app.max, application=app.id)
            compatible_apps[app.appdata].save()

        # See #2828: sometimes when we generate the filename(s) below, in
        # File.from_upload(), cache-machine is confused and has trouble
        # fetching the ApplicationsVersions that were just created. To work
        # around this we pre-generate version.compatible_apps and avoid the
        # queries completely.
        version._compatible_apps = compatible_apps

        if addon.type in [amo.ADDON_SEARCH, amo.ADDON_STATICTHEME]:
            # Search extensions and static themes are always for all platforms.
            platforms = [amo.PLATFORM_ALL.id]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        for platform in platforms:
            File.from_upload(
                upload,
                version,
                platform,
                parsed_data=parsed_data,
                is_beta=(is_beta and waffle.switch_is_active('beta-versions')))

        version.inherit_nomination(from_statuses=[amo.STATUS_AWAITING_REVIEW])
        version.disable_old_files()
        # After the upload has been copied to all platforms, remove the upload.
        storage.delete(upload.path)
        if send_signal:
            version_uploaded.send(sender=version)

        # Generate a preview and icon for listed static themes
        if (addon.type == amo.ADDON_STATICTHEME
                and channel == amo.RELEASE_CHANNEL_LISTED):
            from olympia.addons.models import Preview  # Avoid circular ref.
            dst_root = os.path.join(user_media_path('addons'), str(addon.id))
            theme_data = parsed_data.get('theme', {})
            version_root = os.path.join(dst_root, unicode(version.id))

            utils.extract_header_img(version.all_files[0].file_path,
                                     theme_data, version_root)
            preview = Preview.objects.create(addon=addon,
                                             caption=unicode(version.version))
            generate_static_theme_preview.delay(theme_data, version_root,
                                                preview)

        # Track the time it took from first upload through validation
        # (and whatever else) until a version was created.
        upload_start = utc_millesecs_from_epoch(upload.created)
        now = datetime.datetime.now()
        now_ts = utc_millesecs_from_epoch(now)
        upload_time = now_ts - upload_start

        log.info('Time for version {version} creation from upload: {delta}; '
                 'created={created}; now={now}'.format(delta=upload_time,
                                                       version=version,
                                                       created=upload.created,
                                                       now=now))
        statsd.timing('devhub.version_created_from_upload', upload_time)

        return version
コード例 #9
0
    def from_upload(cls, upload, addon, selected_apps, channel,
                    parsed_data=None):
        """
        Create a Version instance and corresponding File(s) from a
        FileUpload, an Addon, a list of compatible app ids, a channel id and
        the parsed_data generated by parse_addon().

        Note that it's the caller's responsability to ensure the file is valid.
        We can't check for that here because an admin may have overridden the
        validation results.
        """
        assert parsed_data is not None

        from olympia.addons.models import AddonFeatureCompatibility

        if addon.status == amo.STATUS_DISABLED:
            raise VersionCreateError(
                'Addon is Mozilla Disabled; no new versions are allowed.')

        license_id = None
        if channel == amo.RELEASE_CHANNEL_LISTED:
            previous_version = addon.find_latest_version(
                channel=channel, exclude=())
            if previous_version and previous_version.license_id:
                license_id = previous_version.license_id
        version = cls.objects.create(
            addon=addon,
            version=parsed_data['version'],
            license_id=license_id,
            channel=channel,
        )
        log.info(
            'New version: %r (%s) from %r' % (version, version.id, upload))
        activity.log_create(amo.LOG.ADD_VERSION, version, addon)
        # Update the add-on e10s compatibility since we're creating a new
        # version that may change that.
        e10s_compatibility = parsed_data.get('e10s_compatibility')
        if e10s_compatibility is not None:
            feature_compatibility = (
                AddonFeatureCompatibility.objects.get_or_create(addon=addon)[0]
            )
            feature_compatibility.update(e10s=e10s_compatibility)

        compatible_apps = {}
        for app in parsed_data.get('apps', []):
            if app.id not in selected_apps:
                # If the user chose to explicitly deselect Firefox for Android
                # we're not creating the respective `ApplicationsVersions`
                # which will have this add-on then be listed only for
                # Firefox specifically.
                continue

            compatible_apps[app.appdata] = ApplicationsVersions(
                version=version, min=app.min, max=app.max, application=app.id)
            compatible_apps[app.appdata].save()

        # See #2828: sometimes when we generate the filename(s) below, in
        # File.from_upload(), cache-machine is confused and has trouble
        # fetching the ApplicationsVersions that were just created. To work
        # around this we pre-generate version.compatible_apps and avoid the
        # queries completely.
        version._compatible_apps = compatible_apps

        # For backwards compatibility. We removed specific platform
        # support during submission but we don't handle it any different
        # beyond that yet. That means, we're going to simply set it
        # to `PLATFORM_ALL` and also have the backend create separate
        # files for each platform. Cleaning that up is another step.
        # Given the timing on this, we don't care about updates to legacy
        # add-ons as well.
        platforms = [amo.PLATFORM_ALL.id]

        # Create as many files as we have platforms. Update the all_files
        # cached property on the Version while we're at it, because we might
        # need it afterwards.
        version.all_files = [
            File.from_upload(
                upload, version, platform, parsed_data=parsed_data)
            for platform in platforms]

        version.inherit_nomination(from_statuses=[amo.STATUS_AWAITING_REVIEW])
        version.disable_old_files()
        # After the upload has been copied to all platforms, remove the upload.
        storage.delete(upload.path)
        version_uploaded.send(sender=version)

        # Generate a preview and icon for listed static themes
        if (addon.type == amo.ADDON_STATICTHEME and
                channel == amo.RELEASE_CHANNEL_LISTED):
            dst_root = os.path.join(user_media_path('addons'), str(addon.id))
            theme_data = parsed_data.get('theme', {})
            version_root = os.path.join(dst_root, unicode(version.id))

            utils.extract_header_img(
                version.all_files[0].file_path, theme_data, version_root)
            generate_static_theme_preview(
                theme_data, version_root, version.pk)

        # Track the time it took from first upload through validation
        # (and whatever else) until a version was created.
        upload_start = utc_millesecs_from_epoch(upload.created)
        now = datetime.datetime.now()
        now_ts = utc_millesecs_from_epoch(now)
        upload_time = now_ts - upload_start

        log.info('Time for version {version} creation from upload: {delta}; '
                 'created={created}; now={now}'
                 .format(delta=upload_time, version=version,
                         created=upload.created, now=now))
        statsd.timing('devhub.version_created_from_upload', upload_time)

        return version
コード例 #10
0
    def from_upload(cls, upload, addon, platforms, channel,
                    source=None, parsed_data=None):
        """
        Create a Version instance and corresponding File(s) from a
        FileUpload, an Addon, a list of platform ids, a channel id and the
        parsed_data generated by parse_addon().

        Note that it's the caller's responsability to ensure the file is valid.
        We can't check for that here because an admin may have overridden the
        validation results.
        """
        assert parsed_data is not None

        from olympia.addons.models import AddonFeatureCompatibility

        if addon.status == amo.STATUS_DISABLED:
            raise VersionCreateError(
                'Addon is Mozilla Disabled; no new versions are allowed.')

        license_id = None
        if channel == amo.RELEASE_CHANNEL_LISTED:
            previous_version = addon.find_latest_version(
                channel=channel, exclude=())
            if previous_version and previous_version.license_id:
                license_id = previous_version.license_id
        version = cls.objects.create(
            addon=addon,
            version=parsed_data['version'],
            license_id=license_id,
            source=source,
            channel=channel,
        )
        log.info(
            'New version: %r (%s) from %r' % (version, version.id, upload))
        activity.log_create(amo.LOG.ADD_VERSION, version, addon)
        # Update the add-on e10s compatibility since we're creating a new
        # version that may change that.
        e10s_compatibility = parsed_data.get('e10s_compatibility')
        if e10s_compatibility is not None:
            feature_compatibility = (
                AddonFeatureCompatibility.objects.get_or_create(addon=addon)[0]
            )
            feature_compatibility.update(e10s=e10s_compatibility)

        compatible_apps = {}
        for app in parsed_data.get('apps', []):
            compatible_apps[app.appdata] = ApplicationsVersions(
                version=version, min=app.min, max=app.max, application=app.id)
            compatible_apps[app.appdata].save()

        # See #2828: sometimes when we generate the filename(s) below, in
        # File.from_upload(), cache-machine is confused and has trouble
        # fetching the ApplicationsVersions that were just created. To work
        # around this we pre-generate version.compatible_apps and avoid the
        # queries completely.
        version._compatible_apps = compatible_apps

        if addon.type in [amo.ADDON_SEARCH, amo.ADDON_STATICTHEME]:
            # Search extensions and static themes are always for all platforms.
            platforms = [amo.PLATFORM_ALL.id]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        # Create as many files as we have platforms. Update the all_files
        # cached property on the Version while we're at it, because we might
        # need it afterwards.
        version.all_files = [
            File.from_upload(
                upload, version, platform, parsed_data=parsed_data)
            for platform in platforms]

        version.inherit_nomination(from_statuses=[amo.STATUS_AWAITING_REVIEW])
        version.disable_old_files()
        # After the upload has been copied to all platforms, remove the upload.
        storage.delete(upload.path)
        version_uploaded.send(sender=version)

        # Generate a preview and icon for listed static themes
        if (addon.type == amo.ADDON_STATICTHEME and
                channel == amo.RELEASE_CHANNEL_LISTED):
            dst_root = os.path.join(user_media_path('addons'), str(addon.id))
            theme_data = parsed_data.get('theme', {})
            version_root = os.path.join(dst_root, unicode(version.id))

            utils.extract_header_img(
                version.all_files[0].file_path, theme_data, version_root)
            preview = VersionPreview.objects.create(version=version)
            generate_static_theme_preview(
                theme_data, version_root, preview.pk)

        # Track the time it took from first upload through validation
        # (and whatever else) until a version was created.
        upload_start = utc_millesecs_from_epoch(upload.created)
        now = datetime.datetime.now()
        now_ts = utc_millesecs_from_epoch(now)
        upload_time = now_ts - upload_start

        log.info('Time for version {version} creation from upload: {delta}; '
                 'created={created}; now={now}'
                 .format(delta=upload_time, version=version,
                         created=upload.created, now=now))
        statsd.timing('devhub.version_created_from_upload', upload_time)

        return version