Merge pull request #1162 from aws-lumberyard-dev/Prism/gem-db

Adding python bindings for modifying project properties
main
amzn-mgwynn 5 years ago committed by GitHub
commit 38865c95e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,10 +15,13 @@
namespace O3DE::ProjectManager
{
ProjectInfo::ProjectInfo(const QString& path, const QString& projectName, const QString& displayName,
const QString& imagePath, const QString& backgroundImagePath, bool needsBuild)
const QString& origin, const QString& summary, const QString& imagePath, const QString& backgroundImagePath,
bool needsBuild)
: m_path(path)
, m_projectName(projectName)
, m_displayName(displayName)
, m_origin(origin)
, m_summary(summary)
, m_imagePath(imagePath)
, m_backgroundImagePath(backgroundImagePath)
, m_needsBuild(needsBuild)

@ -15,6 +15,7 @@
#if !defined(Q_MOC_RUN)
#include <AzCore/Math/Uuid.h>
#include <QString>
#include <QStringList>
#endif
namespace O3DE::ProjectManager
@ -23,8 +24,17 @@ namespace O3DE::ProjectManager
{
public:
ProjectInfo() = default;
ProjectInfo(const QString& path, const QString& projectName, const QString& displayName,
const QString& imagePath, const QString& backgroundImagePath, bool needsBuild);
ProjectInfo(
const QString& path,
const QString& projectName,
const QString& displayName,
const QString& origin,
const QString& summary,
const QString& imagePath,
const QString& backgroundImagePath,
bool needsBuild);
bool operator==(const ProjectInfo& rhs);
bool operator!=(const ProjectInfo& rhs);
@ -36,12 +46,16 @@ namespace O3DE::ProjectManager
// From project.json
QString m_projectName;
QString m_displayName;
QString m_origin;
QString m_summary;
QStringList m_userTags;
// Used on projects home screen
QString m_imagePath;
QString m_backgroundImagePath;
// Used in project creation
bool m_needsBuild = false; //! Does this project need to be built
};
} // namespace O3DE::ProjectManager

@ -19,6 +19,7 @@
#include <pybind11/functional.h>
#include <pybind11/embed.h>
#include <pybind11/eval.h>
#include <pybind11/stl.h>
#pragma pop_macro("slots")
#include <AzCore/IO/FileIO.h>
@ -289,6 +290,7 @@ namespace O3DE::ProjectManager
m_engineTemplate = pybind11::module::import("o3de.engine_template");
m_enableGemProject = pybind11::module::import("o3de.enable_gem");
m_disableGemProject = pybind11::module::import("o3de.disable_gem");
m_editProjectProperties = pybind11::module::import("o3de.project_properties");
// make sure the engine is registered
RegisterThisEngine();
@ -678,6 +680,12 @@ namespace O3DE::ProjectManager
{
projectInfo.m_projectName = Py_To_String(projectData["project_name"]);
projectInfo.m_displayName = Py_To_String_Optional(projectData, "display_name", projectInfo.m_projectName);
projectInfo.m_origin = Py_To_String_Optional(projectData, "origin", projectInfo.m_origin);
projectInfo.m_summary = Py_To_String_Optional(projectData, "summary", projectInfo.m_summary);
for (auto tag : projectData["user_tags"])
{
projectInfo.m_userTags.append(Py_To_String(tag));
}
}
catch ([[maybe_unused]] const std::exception& e)
{
@ -748,9 +756,27 @@ namespace O3DE::ProjectManager
});
}
bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo)
AZ::Outcome<void, AZStd::string> PythonBindings::UpdateProject(const ProjectInfo& projectInfo)
{
return false;
return ExecuteWithLockErrorHandling([&]
{
std::list<std::string> newTags;
for (const auto& i : projectInfo.m_userTags)
{
newTags.push_back(i.toStdString());
}
m_editProjectProperties.attr("edit_project_props")(
pybind11::str(projectInfo.m_path.toStdString()), // proj_path
pybind11::none(), // proj_name not used
pybind11::str(projectInfo.m_origin.toStdString()), // new_origin
pybind11::str(projectInfo.m_displayName.toStdString()), // new_display
pybind11::str(projectInfo.m_summary.toStdString()), // new_summary
pybind11::str(projectInfo.m_imagePath.toStdString()), // new_icon
pybind11::none(), // add_tags not used
pybind11::none(), // remove_tags not used
pybind11::list(pybind11::cast(newTags))); // replace_tags
});
}
ProjectTemplateInfo PythonBindings::ProjectTemplateInfoFromPath(pybind11::handle path)

@ -50,7 +50,7 @@ namespace O3DE::ProjectManager
AZ::Outcome<QVector<ProjectInfo>> GetProjects() override;
bool AddProject(const QString& path) override;
bool RemoveProject(const QString& path) override;
bool UpdateProject(const ProjectInfo& projectInfo) override;
AZ::Outcome<void, AZStd::string> UpdateProject(const ProjectInfo& projectInfo) override;
AZ::Outcome<void, AZStd::string> AddGemToProject(const QString& gemPath, const QString& projectPath) override;
AZ::Outcome<void, AZStd::string> RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override;
@ -78,5 +78,6 @@ namespace O3DE::ProjectManager
pybind11::handle m_manifest;
pybind11::handle m_enableGemProject;
pybind11::handle m_disableGemProject;
pybind11::handle m_editProjectProperties;
};
}

@ -122,7 +122,7 @@ namespace O3DE::ProjectManager
* @param projectInfo the info to use to update the project
* @return true on success, false on failure
*/
virtual bool UpdateProject(const ProjectInfo& projectInfo) = 0;
virtual AZ::Outcome<void, AZStd::string> UpdateProject(const ProjectInfo& projectInfo) = 0;
/**
* Add a gem to a project

@ -136,10 +136,10 @@ namespace O3DE::ProjectManager
// Update project if settings changed
if (m_projectInfo != newProjectSettings)
{
bool result = PythonBindingsInterface::Get()->UpdateProject(newProjectSettings);
if (!result)
auto result = PythonBindingsInterface::Get()->UpdateProject(newProjectSettings);
if (!result.IsSuccess())
{
QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project."));
QMessageBox::critical(this, tr("Project update failed"), tr(result.GetError().c_str()));
return;
}
}

@ -30,7 +30,7 @@ def get_project_props(name: str = None, path: pathlib.Path = None) -> dict:
return proj_json
def edit_project_props(proj_path, proj_name, new_origin, new_display,
new_summary, new_icon, new_tag, remove_tag) -> int:
new_summary, new_icon, new_tags, delete_tags, replace_tags) -> int:
proj_json = get_project_props(proj_name, proj_path)
if not proj_json:
@ -44,16 +44,22 @@ def edit_project_props(proj_path, proj_name, new_origin, new_display,
proj_json['summary'] = new_summary
if new_icon:
proj_json['icon_path'] = new_icon
if new_tag:
proj_json.setdefault('user_tags', []).append(new_tag)
if remove_tag:
if new_tags:
tag_list = [new_tags] if isinstance(new_tags, str) else new_tags
proj_json.setdefault('user_tags', []).extend(tag_list)
if delete_tags:
removal_list = [delete_tags] if isinstance(delete_tags, str) else delete_tags
if 'user_tags' in proj_json:
if remove_tag in proj_json['user_tags']:
proj_json['user_tags'].remove(remove_tag)
else:
logger.warn(f'{remove_tag} not found in user_tags for removal.')
for tag in removal_list:
if tag in proj_json['user_tags']:
proj_json['user_tags'].remove(tag)
else:
logger.warn(f'{tag} not found in user_tags for removal.')
else:
logger.warn(f'user_tags property not found for removal of tag {remove_tag}.')
logger.warn(f'user_tags property not found for removal of {remove_tags}.')
if replace_tags:
tag_list = [replace_tags] if isinstance(replace_tags, str) else replace_tags
proj_json['user_tags'] = tag_list
manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json')
return 0
@ -65,8 +71,9 @@ def _edit_project_props(args: argparse) -> int:
args.project_display,
args.project_summary,
args.project_icon,
args.project_tag,
args.remove_tag)
args.add_tags,
args.delete_tags,
args.replace_tags)
def add_parser_args(parser):
group = parser.add_mutually_exclusive_group(required=True)
@ -83,10 +90,13 @@ def add_parser_args(parser):
help='Sets the summary description of the project.')
group.add_argument('-pi', '--project-icon', type=str, required=False,
help='Sets the path to the projects icon resource.')
group.add_argument('-pt', '--project-tag', type=str, required=False,
help='Adds a tag to user_tags property. These tags are intended for documentation and filtering.')
group.add_argument('-rt', '--remove-tag', type=str, required=False,
help='Removes a tag from the user_tags property.')
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('-at', '--add-tags', type=str, nargs='*', required=False,
help='Adds tag(s) to user_tags property. Space delimited list (ex. -at A B C)')
group.add_argument('-dt', '--delete-tags', type=str, nargs ='*', required=False,
help='Removes tag(s) from the user_tags property. Space delimited list (ex. -dt A B C')
group.add_argument('-rt', '--replace-tags', type=str, nargs ='*', required=False,
help='Replace entirety of user_tags property with space delimited list of values')
parser.set_defaults(func=_edit_project_props)
def add_args(subparsers) -> None:

Loading…
Cancel
Save