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)
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
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)
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()
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
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)