def test_add_to_config(self):
        # add storage mirrors to config
        config = self.repo.get_config()
        StorageManager.add_to_config(self.repo, config)

        # assert that we now have storage mirror in the config
        self.assertTrue(len(config['mirrors']) == 1)
        url = 'https://example.com/repos/WRK98dKjNKjR5XJy5sjH_Ptuxrs4QgNK/repo'
        self.assertEqual(url, config['mirrors'][0])
    def test_add_to_config(self):
        # get config from repo and assert that it doesn't contain storage mirrors
        config = self.repo.get_config()
        self.assertFalse('mirrors' in config)

        # add existing storage mirrors to config
        StorageManager.add_to_config(self.repo, config)

        # assert that we now have all the storage mirrors in the config
        self.assertTrue('mirrors' in config)
        self.assertTrue(len(config['mirrors']) == 3)
        self.assertTrue('https://s3.amazonaws.com/s3_bucket/fdroid/repo' in
                        config['mirrors'])
        self.assertTrue('ssh_url' in config['mirrors'])
        self.assertTrue('git_url/repo' in config['mirrors'])
 def test_publish(self, update_serverwebroot):
     storage = StorageManager.get_storage(self.repo)[0]
     storage.publish()
     local = self.repo.get_repo_path()
     remote = os.path.join(settings.DEFAULT_REPO_STORAGE[0][0],
                           storage.get_identifier())
     update_serverwebroot.assert_called_once_with(remote, local)
Example #4
0
    def get_context_data(self, **kwargs):
        context = super(RepositoryView, self).get_context_data(**kwargs)
        repo = self.get_repo()
        context['repo'] = repo
        if repo.fingerprint is None or repo.fingerprint == '':
            raise RuntimeError("Repository has not been created properly.")

        context['storage'] = StorageManager.get_storage(repo)
        from .apk import ApkForm
        context['form'] = ApkForm()
        if 'search' in self.request.GET and self.request.GET['search'] != '':
            context['search_params'] = 'search=%s' % self.request.GET['search']
        return context
Example #5
0
 def delete(self, request, *args, **kwargs):
     storage = self.get_object()
     # if this was the main storage, unset the repo URL or promote a different storage
     storage_url = storage.get_repo_url()
     if storage_url == storage.repo.url:
         for s in StorageManager.get_storage(storage.repo):
             # fallback to this storage if it isn't the same
             if s.get_repo_url() != storage_url:
                 storage.repo.set_url(s.get_repo_url())
                 return super().delete(request, *args, **kwargs)
         # we did not find another storage to use, so unset the main repo URL
         storage.repo.set_url(None)
     return super().delete(request, *args, **kwargs)
Example #6
0
    def publish(self):
        """
        Publishes the repository to the available storage locations

        You normally don't need to call this manually
        as it is intended to be called automatically after each update.
        """
        from repomaker.models.storage import StorageManager
        remote_storage = StorageManager.get_storage(self, onlyEnabled=True)
        if len(remote_storage) == 0:
            return  # bail out if there is no remote storage to publish to

        # Publish to remote storage
        self.chdir()  # expected by server.update_awsbucket()
        for storage in remote_storage:
            storage.publish()

        # Update the publication date
        self.last_publication_date = timezone.now()
Example #7
0
    def form_valid(self, form):
        form.instance.user = self.request.user
        result = super(RepositoryCreateView,
                       self).form_valid(form)  # saves new repo

        try:
            # generate repo, QR Code, etc. on disk
            form.instance.create()

            # set main repo URL to that of first default storage, if any exists
            storage = StorageManager.get_default_storage(form.instance)
            if len(storage) > 0:
                # requires repo fingerprint to exist
                form.instance.set_url(
                    storage[0].get_repo_url())  # saves form.instance
        except Exception as e:
            logging.error('Creating repo failed: %s', e)
            form.instance.delete()
            error = _(
                'There was an error creating the repository. Please try again!'
            )
            return ErrorView().dispatch(self.request,
                                        error=error + ' ' + str(e))
        return result
Example #8
0
    def update(self):
        """
        Updates the repository on disk, generates index, categories, etc.

        You normally don't need to call this directly
        as it is meant to be run in a background task scheduled by update_async().
        """
        from repomaker.models import App, ApkPointer
        from repomaker.models.storage import StorageManager
        self.chdir()
        config = self.get_config()
        StorageManager.add_to_config(self, config)

        # ensure that this repo's main URL is set prior to updating
        if not self.url and len(config['mirrors']) > 0:
            self.set_url(config['mirrors'][0])

        # Gather information about all the apk files in the repo directory, using
        # cached data if possible.
        apkcache = update.get_cache()

        # Process all apks in the main repo
        knownapks = common.KnownApks()
        apks, cache_changed = update.process_apks(apkcache, REPO_DIR,
                                                  knownapks, False)

        # Apply app metadata from database
        apps = {}
        categories = set()
        for apk in apks:
            try:
                app = App.objects.get(
                    repo=self,
                    package_id=apk['packageName']).to_metadata_app()
                apps[app.id] = app
                categories.update(app.Categories)
            except ObjectDoesNotExist:
                logging.warning("App '%s' not found in database",
                                apk['packageName'])

        # Scan non-apk files in the repo
        files, file_cache_changed = update.scan_repo_files(
            apkcache, REPO_DIR, knownapks, False)

        # Apply metadata from database
        for file in files:
            pointers = ApkPointer.objects.filter(repo=self,
                                                 apk__hash=file['hash'])
            if not pointers.exists():
                logging.warning("App with hash '%s' not found in database",
                                file['hash'])
            elif pointers.count() > 1:
                logging.error("Repo %d has more than one app with hash '%s'",
                              self.pk, file['hash'])
            else:
                # add app to list of apps to be included in index
                pointer = pointers[0]
                app = pointer.app.to_metadata_app()
                apps[pointer.app.package_id] = app
                categories.update(app.Categories)

                # update package data and add to repo files
                file['name'] = pointer.app.name
                file['versionCode'] = pointer.apk.version_code
                file['versionName'] = pointer.apk.version_name
                file['packageName'] = pointer.apk.package_id
                apks.append(file)

        update.apply_info_from_latest_apk(apps, apks)

        # Sort the app list by name
        sortedids = sorted(apps.keys(),
                           key=lambda app_id: apps[app_id].Name.upper())

        # Make the index for the repo
        index.make(apps, sortedids, apks, REPO_DIR, False)
        update.make_categories_txt(REPO_DIR, categories)

        # Update cache if it changed
        if cache_changed or file_cache_changed:
            update.write_cache(apkcache)

        # Update repo page
        self._generate_page()
 def test_get_identifier(self):
     storage = StorageManager.get_storage(self.repo)[0]
     self.assertEqual('WRK98dKjNKjR5XJy5sjH_Ptuxrs4QgNK',
                      storage.get_identifier())
 def test_get_storage_only_enabled(self):
     # assert that only two storage locations are returned by the StorageManager
     self.assertTrue(
         len(StorageManager.get_storage(self.repo, onlyEnabled=True)) == 2)
 def test_get_storage(self):
     # assert that all three storage locations are returned by the StorageManager
     self.assertTrue(len(StorageManager.get_storage(self.repo)) == 3)
 def test_get_repo_url_without_schema(self):
     storage = StorageManager.get_storage(self.repo)[0]
     self.assertTrue(
         storage.get_repo_url().startswith('https://example.com' +
                                           storage.url))
 def test_get_default_storage(self):
     self.assertTrue(
         len(StorageManager.get_default_storage(self.repo)) == 1)
 def test_get_identifier_changes_with_repo_fingerprint(self):
     self.repo.fingerprint = 'different_fingerprint'
     storage = StorageManager.get_storage(self.repo)[0]
     self.assertEqual('Jhvw3A7Jcu3U_d8Ixq9JkQkJDjXdahLA',
                      storage.get_identifier())
 def test_get_repo_url_without_trailing_slash(self):
     storage = StorageManager.get_storage(self.repo)[0]
     expected_url = 'test/' + storage.get_identifier() + '/' + REPO_DIR
     self.assertEqual(expected_url, storage.get_repo_url())
 def test_get_identifier_changes_with_secret_key(self):
     storage = StorageManager.get_storage(self.repo)[0]
     self.assertEqual('pOzUwCWqrdFLXmOFHTFmEeReLhNEqiy1',
                      storage.get_identifier())
 def test_get_default_storage_without_any_defined(self):
     self.assertTrue(
         len(StorageManager.get_default_storage(self.repo)) == 0)
 def test_default_flag(self):
     self.assertTrue(StorageManager.get_storage(self.repo)[0].is_default)
 def test_returned_by_storage_manager(self):
     self.assertTrue(len(StorageManager.get_storage(self.repo)) == 1)
 def test_undefined_default_storage(self):
     self.assertTrue(len(StorageManager.get_storage(self.repo)) == 0)