Esempio n. 1
0
    def from_upload(cls, upload, addon, platforms, send_signal=True):
        data = utils.parse_addon(upload, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        max_len = cls._meta.get_field_by_name('_developer_name')[0].max_length
        developer = data.get('developer_name', '')[:max_len]
        v = cls.objects.create(addon=addon, version=data['version'],
                               license_id=license, _developer_name=developer)
        log.info('New version: %r (%s) from %r' % (v, v.id, upload))

        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application_id=app.id).save()
        if addon.type == amo.ADDON_SEARCH:
            # Search extensions are always for all platforms.
            platforms = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        for platform in platforms:
            File.from_upload(upload, v, platform, parse_data=data)

        v.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=v)

        return v
Esempio n. 2
0
    def from_upload(cls, upload, addon, platforms):
        data = utils.parse_addon(upload.path, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        v = cls.objects.create(addon=addon, version=data['version'],
                               license_id=license)
        log.info('New version: %r (%s) from %r' % (v, v.id, upload))
        # appversions
        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application_id=app.id).save()
        if addon.type == amo.ADDON_SEARCH:
            # Search extensions are always for all platforms.
            platforms = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        for platform in platforms:
            File.from_upload(upload, v, platform, parse_data=data)

        v.disable_old_files()
        # After the upload has been copied to all
        # platforms, remove the upload.
        upload.path.unlink()
        version_uploaded.send(sender=v)
        return v
Esempio n. 3
0
    def from_upload(cls, upload, addon, platforms, send_signal=True):
        data = utils.parse_addon(upload, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        max_len = cls._meta.get_field_by_name('_developer_name')[0].max_length
        developer = data.get('developer_name', '')[:max_len]
        v = cls.objects.create(addon=addon, version=data['version'],
                               license_id=license, _developer_name=developer)
        log.info('New version: %r (%s) from %r' % (v, v.id, upload))

        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application_id=app.id).save()
        if addon.type in [amo.ADDON_SEARCH, amo.ADDON_WEBAPP]:
            # Search extensions and webapps are always for all platforms.
            platforms = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        if addon.is_webapp():
            from mkt.webapps.models import AppManifest

            # Create AppManifest if we're a Webapp.
            # Note: This must happen before we call `File.from_upload`.
            manifest = utils.WebAppParser().get_json_data(upload)
            AppManifest.objects.create(
                version=v, manifest=json.dumps(manifest))

        for platform in platforms:
            File.from_upload(upload, v, platform, parse_data=data)

        if addon.is_webapp():
            # Update supported locales from manifest.
            # Note: This needs to happen after we call `File.from_upload`.
            update_supported_locales_single.apply_async(
                args=[addon.id], kwargs={'latest': True},
                eta=datetime.datetime.now() +
                    datetime.timedelta(seconds=settings.NFS_LAG_DELAY))

        v.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=v)

        # If packaged app and app is blocked, put in escalation queue.
        if (addon.is_webapp() and addon.is_packaged and
            addon.status == amo.STATUS_BLOCKED):
            # To avoid circular import.
            from editors.models import EscalationQueue
            EscalationQueue.objects.create(addon=addon)

        return v
Esempio n. 4
0
    def from_upload(cls, upload, addon, platforms, send_signal=True,
                    source=None, is_beta=False):
        data = utils.parse_addon(upload, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        max_len = cls._meta.get_field_by_name('_developer_name')[0].max_length
        developer = data.get('developer_name', '')[:max_len]
        v = cls.objects.create(
            addon=addon,
            version=data['version'],
            license_id=license,
            _developer_name=developer,
            source=source
        )
        log.info('New version: %r (%s) from %r' % (v, v.id, upload))

        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application=app.id).save()
        if addon.type == amo.ADDON_SEARCH:
            # Search extensions 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, v, platform, parse_data=data,
                             is_beta=is_beta)

        v.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=v)

        # 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=v,
                         created=upload.created, now=now))
        statsd.timing('devhub.version_created_from_upload', upload_time)

        return v
Esempio n. 5
0
 def test_beta_version_non_public(self):
     # Only public add-ons can get beta versions.
     upload = self.upload('beta-extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_LITE)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_UNREVIEWED)
Esempio n. 6
0
 def test_jetpack_version(self):
     upload = self.upload('jetpack')
     f = File.from_upload(upload, self.version, self.platform)
     file_ = File.objects.get(id=f.id)
     eq_(file_.jetpack_version, '1.0b4')
     eq_(file_.builder_version, None)
     eq_(['jetpack'], [t.tag_text for t in self.addon.tags.all()])
Esempio n. 7
0
 def test_jetpack_with_invalid_json(self):
     upload = self.upload('jetpack_invalid')
     f = File.from_upload(upload, self.version, self.platform)
     file_ = File.objects.get(id=f.id)
     eq_(file_.jetpack_version, None)
     eq_(file_.builder_version, None)
     assert not self.addon.tags.exists()
Esempio n. 8
0
 def test_lite_to_unreviewed(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_LITE)
     eq_(self.addon.status, amo.STATUS_LITE)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_UNREVIEWED)
Esempio n. 9
0
 def test_trusted_lite_to_lite(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_LITE, trusted=True)
     eq_(self.addon.status, amo.STATUS_LITE)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_LITE)
Esempio n. 10
0
 def test_public_to_beta(self):
     upload = self.upload('beta-extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_PUBLIC)
     eq_(self.addon.status, amo.STATUS_PUBLIC)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_BETA)
Esempio n. 11
0
 def test_public_to_unreviewed(self):
     upload = self.upload('extension')
     d = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_PUBLIC)
     eq_(self.addon.status, amo.STATUS_PUBLIC)
     f = File.from_upload(upload, self.version, self.platform, parse_data=d)
     eq_(f.status, amo.STATUS_UNREVIEWED)
Esempio n. 12
0
 def test_trusted_public_to_public(self):
     upload = self.upload('extension')
     d = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_PUBLIC, trusted=True)
     eq_(self.addon.status, amo.STATUS_PUBLIC)
     f = File.from_upload(upload, self.version, self.platform, parse_data=d)
     eq_(f.status, amo.STATUS_PUBLIC)
Esempio n. 13
0
 def test_trusted_litenominated_to_litenominated(self):
     upload = self.upload("extension")
     data = parse_addon(upload.path)
     with mock.patch("addons.models.Addon.update_status"):
         # mock update_status because it doesn't like Addons without files.
         self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED, trusted=True)
     eq_(self.addon.status, amo.STATUS_LITE_AND_NOMINATED)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_LITE_AND_NOMINATED)
Esempio n. 14
0
 def test_litenominated_to_unreviewed(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     with mock.patch('addons.models.Addon.update_status'):
         # mock update_status because it doesn't like Addons without files.
         self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
     eq_(self.addon.status, amo.STATUS_LITE_AND_NOMINATED)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_UNREVIEWED)
Esempio n. 15
0
 def test_file_validation(self):
     upload = self.upload('jetpack')
     file = File.from_upload(upload, self.version, self.platform)
     fv = FileValidation.objects.get(file=file)
     eq_(fv.validation, upload.validation)
     eq_(fv.valid, True)
     eq_(fv.errors, 0)
     eq_(fv.warnings, 1)
     eq_(fv.notices, 2)
Esempio n. 16
0
    def from_upload(cls, upload, addon, platforms, send_signal=True):
        data = utils.parse_addon(upload, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        v = cls.objects.create(addon=addon, version=data['version'],
                               license_id=license)
        log.info('New version: %r (%s) from %r' % (v, v.id, upload))
        # appversions
        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application_id=app.id).save()
        if addon.type in [amo.ADDON_SEARCH, amo.ADDON_WEBAPP]:
            # Search extensions and webapps are always for all platforms.
            platforms = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]
        else:
            platforms = cls._make_safe_platform_files(platforms)

        for platform in platforms:
            File.from_upload(upload, v, platform, parse_data=data)

        if addon.type == amo.ADDON_WEBAPP:
            update_supported_locales_single.apply_async(
                args=[addon.id], kwargs={'latest': True},
                eta=datetime.datetime.now() +
                    datetime.timedelta(seconds=settings.NFS_LAG_DELAY))

        v.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=v)

        # If packaged app and app is blocked, put in escalation queue.
        if (addon.is_webapp() and addon.is_packaged and
            addon.status == amo.STATUS_BLOCKED):
            # To avoid circular import.
            from editors.models import EscalationQueue
            EscalationQueue.objects.create(addon=addon)

        return v
Esempio n. 17
0
    def test_trusted_litenominated_to_litenominated(self):
        upload = self.upload('extension')
        d = parse_addon(upload.path)
        with mock.patch('addons.models.Addon.update_status'):
            # mock update_status because it doesn't like Addons without files.
            self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED,
                              trusted=True)

        assert self.addon.status == amo.STATUS_LITE_AND_NOMINATED
        f = File.from_upload(upload, self.version, self.platform, parse_data=d)
        assert f.status == amo.STATUS_LITE
Esempio n. 18
0
def version_add_file(request, addon_id, addon, version_id):
    version = get_object_or_404(Version, pk=version_id, addon=addon)
    form = forms.NewFileForm(request.POST, addon=addon, version=version)
    if not form.is_valid():
        return json_view.error(form.errors)
    upload = form.cleaned_data['upload']
    new_file = File.from_upload(upload, version, form.cleaned_data['platform'])
    upload.path.unlink()
    file_form = forms.FileFormSet(prefix='files', queryset=version.files.all())
    form = [f for f in file_form.forms if f.instance == new_file]
    return jingo.render(request, 'devhub/includes/version_file.html',
                        {'form': form[0], 'addon': addon})
Esempio n. 19
0
    def from_upload(cls, upload, addon, platforms):
        data = utils.parse_addon(upload.path, addon)
        try:
            license = addon.versions.latest().license_id
        except Version.DoesNotExist:
            license = None
        v = cls.objects.create(addon=addon, version=data['version'],
                               license_id=license)
        log.debug('New version: %r (%s) from %r' % (v, v.id, upload))
        # appversions
        AV = ApplicationsVersions
        for app in data.get('apps', []):
            AV(version=v, min=app.min, max=app.max,
               application_id=app.id).save()
        if addon.type == amo.ADDON_SEARCH:
            # Search extensions are always for all platforms.
            platforms = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]
        else:
            new_plats = []
            # Transform PLATFORM_ALL_MOBILE into specific mobile platform
            # files (e.g. Android, Maemo).
            # TODO(Kumar) Stop doing this when allmobile is supported
            # for downloads. See bug 646268.
            for p in platforms:
                if p.id == amo.PLATFORM_ALL_MOBILE.id:
                    for mobi_p in (set(amo.MOBILE_PLATFORMS.keys()) -
                                   set([amo.PLATFORM_ALL_MOBILE.id])):
                        new_plats.append(Platform.objects.get(id=mobi_p))
                else:
                    new_plats.append(p)
            platforms = new_plats

        for platform in platforms:
            File.from_upload(upload, v, platform, parse_data=data)

        v.disable_old_files()
        # After the upload has been copied to all
        # platforms, remove the upload.
        upload.path.unlink()
        return v
Esempio n. 20
0
 def test_validator_sets_require_chrome(self):
     validation = json.dumps(
         {
             "errors": 0,
             "success": True,
             "warnings": 0,
             "notices": 0,
             "message_tree": {},
             "messages": [],
             "metadata": {"version": "1.0", "name": "gK0Bes Bot", "id": "gkobes@gkobes", "requires_chrome": True},
         }
     )
     upload = self.get_upload(filename="extension.xpi", validation=validation)
     version = Version.objects.filter(addon__pk=3615)[0]
     file_ = File.from_upload(upload, version, amo.PLATFORM_LINUX.id)
     eq_(file_.requires_chrome, True)
Esempio n. 21
0
 def test_validator_sets_binary_via_content(self):
     validation = json.dumps({
         "errors": 0,
         "success": True,
         "warnings": 0,
         "notices": 0,
         "message_tree": {},
         "messages": [],
         "metadata": {
             "contains_binary_content": True,
             "version": "1.0",
             "name": "gK0Bes Bot",
             "id": "gkobes@gkobes",
         }
     })
     upload = self.get_upload(filename='extension.xpi',
                              validation=validation)
     version = Version.objects.filter(addon__pk=3615)[0]
     file_ = File.from_upload(upload, version, amo.PLATFORM_LINUX.id)
     eq_(file_.binary, True)
Esempio n. 22
0
 def test_file_hash_paranoia(self):
     upload = self.upload('extension')
     f = File.from_upload(upload, self.version, self.platform)
     assert f.hash.startswith('sha256:035ae07b4988711')
Esempio n. 23
0
 def test_trusted_litenominated_to_litenominated(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED, trusted=True)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_LITE_AND_NOMINATED)
Esempio n. 24
0
 def test_size_small(self):
     upload = self.upload('alt-rdf')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.size, 675)
Esempio n. 25
0
 def test_utf8(self):
     upload = self.upload(u'jétpack')
     self.version.addon.name = u'jéts!'
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename, u'jets-0.1-mac.xpi')
Esempio n. 26
0
 def test_jetpack_builder_version(self):
     upload = self.upload('jetpack_builder')
     f = File.from_upload(upload, self.version, self.platform)
     file_ = File.objects.get(id=f.id)
     eq_(file_.builder_version, '1.1.1.1')
Esempio n. 27
0
 def test_no_restart_dictionary(self):
     upload = self.upload('dictionary-explicit-type-test')
     d = parse_addon(upload.path)
     f = File.from_upload(upload, self.version, self.platform, parse_data=d)
     assert f.no_restart
Esempio n. 28
0
 def test_trusted_public_to_public(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_PUBLIC, trusted=True)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_PUBLIC)
Esempio n. 29
0
 def test_langpack_extension(self):
     upload = self.upload('langpack.xpi')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
Esempio n. 30
0
 def test_extension_extension(self):
     upload = self.upload('extension.xpi')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
     assert not self.addon.tags.exists()
Esempio n. 31
0
 def test_theme_extension(self):
     upload = self.upload('theme.jar')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
Esempio n. 32
0
 def test_strict_compat(self):
     upload = self.upload('strict-compat')
     data = parse_addon(upload.path)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.strict_compatibility, True)
Esempio n. 33
0
 def test_beta_version(self):
     upload = self.upload('beta-extension')
     data = parse_addon(upload.path)
     self.addon.status = amo.STATUS_PUBLIC
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_BETA)
Esempio n. 34
0
 def test_theme_extension(self):
     upload = self.upload('theme.jar')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
Esempio n. 35
0
 def test_utf8(self):
     upload = self.upload(u'jétpack')
     self.version.addon.name = u'jéts!'
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename, u'jets-0.1-mac.xpi')
Esempio n. 36
0
 def test_size_small(self):
     upload = self.upload('alt-rdf')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.size, 1)
Esempio n. 37
0
 def test_no_restart_false(self):
     upload = self.upload('extension')
     d = parse_addon(upload.path)
     f = File.from_upload(upload, self.version, self.platform, parse_data=d)
     assert not f.no_restart
Esempio n. 38
0
 def test_file_hash(self):
     upload = self.upload('jetpack')
     f = File.from_upload(upload, self.version, self.platform)
     assert f.hash.startswith('sha256:')
     assert len(f.hash) == 64 + 7  # 64 for hash, 7 for 'sha256:'
Esempio n. 39
0
 def test_no_restart_true(self):
     upload = self.upload('jetpack')
     d = parse_addon(upload.path)
     f = File.from_upload(upload, self.version, self.platform, parse_data=d)
     assert f.no_restart
Esempio n. 40
0
 def test_filename_no_extension(self):
     upload = self.upload('jetpack')
     # Remove the exension.
     upload.name = upload.name.rsplit('.', 1)[0]
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename, 'xxx-0.1-mac.xpi')
Esempio n. 41
0
 def test_file_hash(self):
     upload = self.upload('jetpack')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.hash, upload.hash)
Esempio n. 42
0
 def test_not_multi_package(self):
     upload = self.upload('extension')
     file_ = File.from_upload(upload, self.version, self.platform)
     assert not file_.is_multi_package
Esempio n. 43
0
 def test_filename(self):
     upload = self.upload('jetpack')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename, 'xxx-0.1-mac.xpi')
Esempio n. 44
0
 def test_size(self):
     upload = self.upload('extension')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.size, 2264)
Esempio n. 45
0
 def test_is_jetpack(self):
     upload = self.upload('jetpack')
     f = File.from_upload(upload, self.version, self.platform)
     assert File.objects.get(id=f.id).jetpack
Esempio n. 46
0
 def test_file_hash_no_paranoia(self):
     upload = self.upload('extension')
     upload.hash = 'oops'
     f = File.from_upload(upload, self.version, self.platform)
     assert f.hash.startswith('oops')
Esempio n. 47
0
 def test_search_extension(self):
     upload = self.upload('search.xml')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xml'), True)
Esempio n. 48
0
 def test_lite_to_unreviewed(self):
     upload = self.upload('extension')
     data = parse_addon(upload.path)
     self.addon.update(status=amo.STATUS_LITE)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.status, amo.STATUS_UNREVIEWED)
Esempio n. 49
0
 def test_langpack_extension(self):
     upload = self.upload('langpack.xpi')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
Esempio n. 50
0
 def test_strict_compat(self):
     upload = self.upload('strict-compat')
     data = parse_addon(upload.path)
     f = File.from_upload(upload, self.version, self.platform, data)
     eq_(f.strict_compatibility, True)
Esempio n. 51
0
 def test_file_hash_paranoia(self):
     upload = self.upload('extension')
     f = File.from_upload(upload, self.version, self.platform)
     assert f.hash.startswith('sha256:035ae07b4988711')
Esempio n. 52
0
 def test_extension_extension(self):
     upload = self.upload('extension.xpi')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xpi'), True)
     assert not self.addon.tags.exists()
Esempio n. 53
0
 def test_size(self):
     upload = self.upload('extension')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.size, 2)
Esempio n. 54
0
 def test_search_extension(self):
     upload = self.upload('search.xml')
     f = File.from_upload(upload, self.version, self.platform)
     eq_(f.filename.endswith('.xml'), True)
Esempio n. 55
0
 def test_jetpack_with_invalid_json(self):
     upload = self.upload('jetpack_invalid')
     f = File.from_upload(upload, self.version, self.platform)
     file_ = File.objects.get(id=f.id)
     eq_(file_.jetpack_version, None)
     eq_(file_.builder_version, None)