Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Method to Merge Entries and Databases #413

Open
nicholasf-at-schultztechnology opened this issue Feb 3, 2025 · 0 comments
Open

Add Method to Merge Entries and Databases #413

nicholasf-at-schultztechnology opened this issue Feb 3, 2025 · 0 comments

Comments

@nicholasf-at-schultztechnology

Summary

Request for a method to merge entries and databases in the pykeepass library. This feature would be highly beneficial for the ability to consolidate multiple KeePass databases or resolve conflicts between entries.


Proposed Feature

Introduce a method to merge the contents of one KeePass database into another, including groups and entries, with conflict resolution.

Suggested Method

pykeepass.merge_databases(src_db, trgt_db)

Description:
This method would allow users to merge the contents of a source KeePass database (src_db) into a target database (trgt_db), handling groups, entries, and conflicts in a structured manner.


Example Implementation

Below is a possible implementation of the merge_databases function:

def merge_databases(source_db, target_db):
    """
    Merge the contents of the source KeePass database into the target KeePass database.

    Args:
        source_db (PyKeePass): The source database to merge from.
        target_db (PyKeePass): The target database to merge into.
    """
    def merge_groups(source_group, target_group):
        # Merge subgroups
        for source_subgroup in source_group.subgroups:
            target_subgroup = target_db.find_groups(
                name=source_subgroup.name,
                group=target_group,
                first=True,
                recursive=False
            )
            if not target_subgroup:
                target_subgroup = target_db.add_group(
                    target_group,
                    source_subgroup.name,
                    icon=source_subgroup.icon,
                    notes=source_subgroup.notes
                )
            merge_groups(source_subgroup, target_subgroup)

        # Merge entries
        for source_entry in source_group.entries:
            target_entry = target_db.find_entries(
                uuid=source_entry.uuid,
                group=target_group,
                first=True,
                recursive=False
            )
            if target_entry:
                # Handle conflicts
                print(f"Conflict detected for entry: {source_entry.title}")
                target_entry.title = source_entry.title or ""
                target_entry.username = source_entry.username or ""
                target_entry.password = source_entry.password or ""
                target_entry.url = source_entry.url or ""
                target_entry.notes = source_entry.notes or ""
                target_entry.icon = source_entry.icon or ""
                target_entry.tags = source_entry.tags or ""
                target_entry.otp = source_entry.otp or ""
                try: 
                    target_entry.autotype_enabled = source_entry.autotype_enabled 
                except Exception:
                    pass
                try:
                    target_entry.autotype_sequence = source_entry.autotype_sequence
                except Exception:
                    pass
                try:
                    target_entry.autotype_window = source_entry.autotype_window
                except Exception:
                    pass
                target_entry.history.extend(source_entry.history)
            else:
                # Add new entry
                target_db.add_entry(
                    target_group,
                    title=source_entry.title,
                    username=source_entry.username,
                    password=source_entry.password,
                    url=source_entry.url,
                    notes=source_entry.notes,
                    icon=source_entry.icon,
                    tags=source_entry.tags,
                    otp=source_entry.otp,
                    force_creation=True
                )

    merge_groups(source_db.root_group, target_db.root_group)

Benefits

  1. Simplifies Database Management:
    Users can easily consolidate multiple KeePass databases into one.

  2. Conflict Resolution:
    Provides a clear and structured way to handle conflicts between entries.

  3. Enhanced Functionality:
    Expands the capabilities of the pykeepass library, making it more versatile for advanced use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant