def test_project_fs_instance_bad(english): # needs a Project with pytest.raises(TypeError): FSPlugin() project = ProjectDBFactory(source_language=english) # project is not configured with pytest.raises(NotConfiguredError): FSPlugin(project) with pytest.raises(ValidationError): project.config["pootle_fs.fs_type"] = "foo" project.config["pootle_fs.fs_type"] = "localfs" with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_url"] = "/bar" default_receivers = fs_plugins.receivers[:] default_cache = fs_plugins.sender_receivers_cache.copy() @provider(fs_plugins, sender=Project) def provide_fs_plugin(**kwargs): return dict(dummyfs=DummyFSPlugin) project.config["pootle_fs.fs_type"] = "dummyfs" fs_plugins.receivers = default_receivers fs_plugins.sender_receivers_cache = default_cache with pytest.raises(MissingPluginError): FSPlugin(project)
def test_project_fs_instance(): @provider(fs_plugins, sender=Project) def provide_fs_plugin(**kwargs): return dict(dummyfs=DummyFSPlugin) project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummyfs" project.config["pootle_fs.fs_url"] = "/foo/bar" plugin = FSPlugin(project) assert str(plugin) == "<DummyFSPlugin(Project 0)>" assert plugin.project == project assert plugin.plugin_property == "Plugin property" assert plugin.plugin_method("bar") == "Plugin method called with: bar" assert plugin == FSPlugin(project)
def test_init_fs_project_cmd_nosync(settings, test_fs, tmpdir): settings.POOTLE_FS_WORKING_PATH = str(tmpdir) fs_path = test_fs.path("data/fs/example_fs/non_gnu_style_minimal/") tr_path = "<language_code>/<filename>.<ext>" call_command( "init_fs_project", "foo", fs_path, tr_path, "--nosync", "--checkstyle=standard", "--filetypes=po", "--source-language=en", "--name=Foo" ) project = Project.objects.get(code='foo') assert project is not None assert project.code == "foo" assert project.fullname == "Foo" assert "po" in project.filetypes.values_list("name", flat=True) assert project.checkstyle == "standard" assert project.source_language.code == "en" assert project.treestyle == 'pootle_fs' assert project.config.get('pootle_fs.fs_type') == 'localfs' assert project.config.get('pootle_fs.fs_url') == fs_path assert project.config.get('pootle_fs.translation_paths')['default'] == tr_path assert project.translationproject_set.all().count() == 0 state = FSPlugin(project).state() assert "fs_untracked: 1" in str(state)
def project0_dummy_plugin_fs_changed(settings, request, no_fs_plugins, no_fs_files): from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project class FSChangedFile(FSFile): @property def fs_changed(self): return True class PootleConflictDummyPlugin(DummyPlugin): pass @provider(fs_plugins, weak=False, sender=Project) def plugin_provider(**kwargs): return dict(dummyfs=PootleConflictDummyPlugin) @getter(fs_file, weak=False, sender=PootleConflictDummyPlugin) def fs_files_getter(**kwargs): return FSChangedFile project = Project.objects.get(code="project0") settings.POOTLE_FS_PATH = "/tmp/foo/" project.config["pootle_fs.fs_type"] = "dummyfs" project.config["pootle_fs.fs_url"] = "/foo/bar" return FSPlugin(project)
def project0_dummy_plugin_no_files(settings, request, no_fs_plugins, no_fs_files): from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project settings.POOTLE_FS_PATH = "/tmp/foo/" class NoFilesDummyPlugin(DummyPlugin): def find_translations(self, fs_path=None, pootle_path=None): return [] @provider(fs_plugins, weak=False, sender=Project) def plugin_provider(**kwargs): return dict(dummyfs=NoFilesDummyPlugin) @getter(fs_file, weak=False, sender=NoFilesDummyPlugin) def fs_files_getter(**kwargs): return FSFile project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummyfs" project.config["pootle_fs.fs_url"] = "/foo/bar" return FSPlugin(project)
def __test_plugin_commit_message(hg_project): hg_plugin = FSPlugin(hg_project) NEW_COMMIT_MSG = "New commit message" hg_plugin.pull() assert not hg_plugin.config.get("pootle_fs.commit_message") # make some updates hg_plugin.push_translations() # check that commit message uses default when not set in config with tmp_hg(hg_plugin.fs_url) as (tmp_repo_path, tmp_repo): last_commit = tmp_repo.hg.log('-1', '--pretty=%s') assert last_commit == DEFAULT_COMMIT_MSG # update the config hg_plugin.config["pootle_fs.commit_message"] = NEW_COMMIT_MSG # make further updates hg_plugin.add_translations() hg_plugin.sync_translations() # test that sync_translations committed with new commit message with tmp_hg(hg_plugin.fs_url) as (tmp_repo_path, tmp_repo): last_commit = tmp_repo.hg.log('-1', '--pretty=%s') assert last_commit == NEW_COMMIT_MSG
def dummyfs_plugin_fs_changed(settings, no_fs_plugins, no_fs_files): from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project class FSChangedFile(FSFile): @property def fs_changed(self): return True class PootleConflictDummyPlugin(DummyPlugin): pass @provider(fs_plugins, weak=False, sender=Project) def plugin_provider_(**kwargs_): return dict(dummyfs=PootleConflictDummyPlugin) @getter(fs_file, weak=False, sender=PootleConflictDummyPlugin) def fs_files_getter_(**kwargs_): return FSChangedFile project = Project.objects.get(code="project0") settings.POOTLE_FS_WORKING_PATH = os.sep.join(['', 'tmp', 'foo']) project.config["pootle_fs.fs_type"] = "dummyfs" return FSPlugin(project)
def dummyfs_plugin_no_stores(settings, no_complex_po_, no_fs_plugins, no_fs_files): from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project from pootle_store.models import Store settings.POOTLE_FS_WORKING_PATH = os.sep.join(['', 'tmp', 'foo']) project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummyfs" stores = Store.objects.filter(translation_project__project=project) pootle_paths = list(stores.values_list("pootle_path", flat=True)) class NoStoresDummyPlugin(DummyPlugin): def find_translations(self, fs_path=None, pootle_path=None): for pp in pootle_paths: if pootle_path and not fnmatch(pp, pootle_path): continue fp = self.get_fs_path(pp) if fs_path and not fnmatch(fp, fs_path): continue yield pp, fp @provider(fs_plugins, weak=False, sender=Project) def plugin_provider_(**kwargs_): return dict(dummyfs=NoStoresDummyPlugin) @getter(fs_file, weak=False, sender=NoStoresDummyPlugin) def fs_files_getter_(**kwargs_): return FSFile plugin = FSPlugin(project) return plugin
def test_plugin_instance(english): project = ProjectDBFactory(source_language=english) project.config["pootle_fs.fs_type"] = "hg" project.config["pootle_fs.fs_url"] = "bar" project.config["pootle_fs.translation_paths"] = DEFAULT_TRANSLATION_PATHS hg_plugin = FSPlugin(project) assert hg_plugin.project == hg_plugin.plugin.project == project assert hg_plugin.is_cloned is False
def test_plugin_instance_bad_args(hg_project): hg_plugin = FSPlugin(hg_project) with pytest.raises(TypeError): hg_plugin.plugin.__class__() with pytest.raises(TypeError): hg_plugin.plugin.__class__("FOO")
def handle_translation_project(self, translation_project, **options): """ """ path_glob = "%s*" % translation_project.pootle_path plugin = FSPlugin(translation_project.project) plugin.add(pootle_path=path_glob, update="pootle") plugin.rm(pootle_path=path_glob, update="pootle") plugin.resolve(pootle_path=path_glob, merge=not options["overwrite"]) plugin.sync(pootle_path=path_glob, update="pootle")
def handle(self, *args, **kwargs): any_configured = False for project in Project.objects.order_by("pk"): try: plugin = FSPlugin(project) self.stdout.write("%s\t%s" % (project.code, plugin.fs_url)) any_configured = True except (MissingPluginError, NotConfiguredError): pass if not any_configured: self.stdout.write("No projects configured")
def project_fs(tmpdir, settings): from pootle_project.models import Project from pootle_fs.utils import FSPlugin project = Project.objects.get(code="project0") new_url = os.path.join(str(tmpdir), "__src__") project.config["pootle_fs.fs_url"] = new_url plugin = FSPlugin(project) os.makedirs(new_url) settings.POOTLE_FS_PATH = str(tmpdir) return plugin
def _sync_translations(db_unit): store = db_unit.store tp = store.translation_project project = tp.project language = tp.language plugin = FSPlugin(project) plugin.fetch() plugin.sync() file_store = db_unit.store.deserialize( open(os.path.join(plugin.fs_url, language.code, store.name)).read()) file_unit = file_store.findid(db_unit.getid()) return file_store, file_unit
def _parse_tps_to_create(self, project): plugin = FSPlugin(project) plugin.fetch() untracked_languages = set( fs.pootle_path.split("/")[1] for fs in plugin.state()["fs_untracked"]) new_langs = ([ lang for lang in untracked_languages if lang in self.languages ] if self.languages else untracked_languages) return Language.objects.filter(code__in=new_langs).exclude( code__in=project.translationproject_set.values_list( "language__code", flat=True))
def test_fs_cmd(project_fs, capsys): call_command("fs") out, err = capsys.readouterr() expected = [] for project in Project.objects.order_by("pk"): try: plugin = FSPlugin(project) expected.append("%s\t%s" % (project.code, plugin.fs_url)) except (MissingPluginError, NotConfiguredError): pass expected = ("%s\n" % '\n'.join(expected)) assert out == expected
def test_project_fs_instance_bad(): # needs a Project with pytest.raises(TypeError): FSPlugin() project = Project.objects.get(code="project0") # project is not configured with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = "foo" with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = None project.config["pootle_fs.fs_url"] = "bar" with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = "foo" with pytest.raises(MissingPluginError): FSPlugin(project) @provider(fs_plugins, sender=Project) def provide_fs_plugin(**kwargs): return dict(dummyfs=DummyFSPlugin) with pytest.raises(MissingPluginError): FSPlugin(project)
def test_project_fs_instance_bad(english): # needs a Project with pytest.raises(TypeError): FSPlugin() project = ProjectDBFactory(source_language=english) # project is not configured with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = "foo" with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = None project.config["pootle_fs.fs_url"] = "bar" with pytest.raises(NotConfiguredError): FSPlugin(project) project.config["pootle_fs.fs_type"] = "foo" with pytest.raises(MissingPluginError): FSPlugin(project) @provider(fs_plugins, sender=Project) def provide_fs_plugin(**kwargs): return dict(dummyfs=DummyFSPlugin) with pytest.raises(MissingPluginError): FSPlugin(project)
def test_plugin_instance(project_fs_empty): project_fs = project_fs_empty assert project_fs.project == project_fs.plugin.project assert project_fs.project.local_fs_path.endswith(project_fs.project.code) assert project_fs.is_cloned is False assert project_fs.resources.stores.exists() is False assert project_fs.resources.tracked.exists() is False # any instance of the same plugin is equal new_plugin = FSPlugin(project_fs.project) assert project_fs == new_plugin assert project_fs is not new_plugin # but the plugin doesnt equate to a cabbage 8) assert not project_fs == "a cabbage"
def _setup_project_fs(self, project): from pootle_fs.utils import FSPlugin from pytest_pootle.utils import add_store_fs project.config["pootle_fs.fs_type"] = "localfs" project.config["pootle_fs.translation_mappings"] = { "default": "/<language_code>/<dir_path>/<filename>.<ext>" } project.config["pootle_fs.fs_url"] = "/tmp/path/for/setup" plugin = FSPlugin(project) for store in plugin.resources.stores: add_store_fs(store=store, fs_path=plugin.get_fs_path(store.pootle_path), synced=True)
def dummy_cmd_state(): from pootle.core.plugin import provider from pootle_fs.delegate import fs_plugins from pootle_fs.utils import FSPlugin from pootle_project.models import Project DummyState, DummyCommandPlugin = _get_dummy_state_plugin() @provider(fs_plugins, sender=Project, weak=False) def plugins_provider_(**kwargs_): return dict(dummy_state_cmd=DummyCommandPlugin) project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummy_state_cmd" return FSPlugin(project), DummyState
def dummyfs(settings, dummy_fs_getters): from pootle.core.plugin import provider from pootle_fs.delegate import fs_plugins from pootle_fs.utils import FSPlugin from pootle_project.models import Project @provider(fs_plugins, weak=False) def plugin_provider_(**kwargs_): return dict(dummyfs=DummyPlugin) project = Project.objects.get(code="project0") settings.POOTLE_FS_WORKING_PATH = os.sep.join(['', 'tmp', 'foo']) project.config["pootle_fs.fs_type"] = "dummyfs" return FSPlugin(project)
def handle_all_stores(self, translation_project, **options): path_glob = "%s*" % translation_project.pootle_path plugin = FSPlugin(translation_project.project) plugin.fetch() if translation_project.project.pk not in self.warn_on_conflict: state = plugin.state() if any(k in state for k in ["conflict", "conflict_untracked"]): logger.warn( "The project '%s' has conflicting changes in the database " "and translation files. Use `pootle fs resolve` to tell " "pootle how to merge", translation_project.project.code) self.warn_on_conflict.append(translation_project.project.pk) if not options["skip_missing"]: plugin.add(pootle_path=path_glob, update="fs") plugin.sync(pootle_path=path_glob, update="fs")
def tutorial(english, settings): """Require `tutorial` test project.""" import pytest_pootle from pootle_fs.utils import FSPlugin shutil.copytree( os.path.join(os.path.dirname(pytest_pootle.__file__), "data", "po", "tutorial"), os.path.join(settings.POOTLE_TRANSLATION_DIRECTORY, "tutorial")) project = _require_project('tutorial', 'Tutorial', english, settings) plugin = FSPlugin(project) plugin.fetch() plugin.add() plugin.sync() return project
def test_init_fs_project_cmd(capsys, settings, test_fs, tmpdir): settings.POOTLE_FS_WORKING_PATH = str(tmpdir) fs_path = test_fs.path("data/fs/example_fs/non_gnu_style_minimal/") tr_path = "<language_code>/<filename>.<ext>" call_command("init_fs_project", "foo", fs_path, tr_path) project = Project.objects.get(code='foo') assert project is not None assert project.config.get('pootle_fs.fs_type') == 'localfs' assert project.config.get('pootle_fs.fs_url') == fs_path assert project.config.get('pootle_fs.translation_paths')['default'] == tr_path assert project.translationproject_set.all().count() > 0 state = FSPlugin(project).state() assert "Nothing to report" in str(state)
def project_fs_empty(english, tmpdir, settings): from pytest_pootle.factories import ProjectDBFactory from pootle_fs.utils import FSPlugin project = ProjectDBFactory(source_language=english, code="project_fs_empty") settings.POOTLE_FS_WORKING_PATH = str(tmpdir) repo_path = os.path.join(str(tmpdir), "__src__") if not os.path.exists(repo_path): os.mkdir(repo_path) project.config["pootle_fs.fs_type"] = "localfs" project.config["pootle_fs.fs_url"] = repo_path project.config["pootle_fs.translation_mappings"] = { "default": "/<language_code>/<dir_path>/<filename>.<ext>" } return FSPlugin(project)
def project0_dummy_plugin_no_stores(settings, request, no_fs_plugins, no_fs_files): from pytest_pootle.utils import add_store_fs from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project from pootle_store.models import Store settings.POOTLE_FS_PATH = "/tmp/foo/" project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummyfs" project.config["pootle_fs.fs_url"] = "/foo/bar" stores = Store.objects.filter( translation_project__project=project) pootle_paths = list(stores.values_list("pootle_path", flat=True)) class NoStoresDummyPlugin(DummyPlugin): def find_translations(self, fs_path=None, pootle_path=None): for pp in pootle_paths: if pootle_path and not fnmatch(pp, pootle_path): continue fp = self.get_fs_path(pp) if fs_path and not fnmatch(fp, fs_path): continue yield pp, fp @provider(fs_plugins, weak=False, sender=Project) def plugin_provider(**kwargs): return dict(dummyfs=NoStoresDummyPlugin) @getter(fs_file, weak=False, sender=NoStoresDummyPlugin) def fs_files_getter(**kwargs): return FSFile plugin = FSPlugin(project) for store in stores: add_store_fs( store=store, fs_path=plugin.get_fs_path(store.pootle_path), synced=True) return plugin
def dummy_cmd_response(): from pootle.core.plugin import provider from pootle.core.state import State from pootle_fs.delegate import fs_plugins from pootle_fs.utils import FSPlugin from pootle_project.models import Project DummyResponse, DummyCommandPlugin = _get_dummy_api_plugin() @provider(fs_plugins, sender=Project, weak=False) def plugins_provider_(**kwargs_): return dict(dummy_cmd=DummyCommandPlugin) project = Project.objects.get(code="project0") project.config["pootle_fs.fs_type"] = "dummy_cmd" plugin = FSPlugin(project) dummy_response = DummyResponse(State(plugin)) return dummy_response, add_dummy_api_call
def handle(self, **options): source_language_code = options['source_language'] try: source_language = Language.objects.get(code=source_language_code) except Language.DoesNotExist as e: self.stdout.write('%s: Unknown language code.' % source_language_code) raise CommandError(e) fs_type, fs_url = parse_fs_url(options['fs']) code = options['code'] name = options['name'] or code.capitalize() try: project = Project.objects.create( code=code, fullname=name, treestyle='pootle_fs', checkstyle=options['checkstyle'], source_language=source_language) except ValidationError as e: raise CommandError(e) for filetype in options["filetypes"] or ["po"]: try: filetype = Format.objects.get(name=filetype) project.filetypes.add(filetype) except Format.DoesNotExist as e: raise CommandError(e) project.config['pootle_fs.fs_type'] = fs_type project.config['pootle_fs.fs_url'] = fs_url project.config['pootle_fs.translation_mappings'] = { 'default': options['translation_mapping'] } if options['sync']: try: plugin = FSPlugin(project) plugin.fetch() plugin.add() plugin.sync() except FSFetchError as e: project.delete() raise CommandError(e)
def dummyfs(settings, no_fs_plugins, no_fs_files): from pootle.core.plugin import getter, provider from pootle_fs.delegate import fs_file, fs_plugins from pootle_fs.files import FSFile from pootle_fs.utils import FSPlugin from pootle_project.models import Project @provider(fs_plugins, weak=False) def plugin_provider_(**kwargs_): return dict(dummyfs=DummyPlugin) @getter(fs_file, weak=False, sender=DummyPlugin) def fs_files_getter_(**kwargs_): return FSFile project = Project.objects.get(code="project0") settings.POOTLE_FS_WORKING_PATH = "/tmp/foo/" project.config["pootle_fs.fs_type"] = "dummyfs" return FSPlugin(project)