Table of contents

DONE

Move in-subtree archive to separate archive file

%3 cluster_02ff79f0_00a8_4859_a2ed_a06f92fd0fff Move in-subtree archive to separate archive file _659d6c4e_b75d_444e_b71a_1b545974bbe9 Reverse: Combine new files and archive into a single output _0873a209_b9df_4bf3_b65e_2f425c5a2adc Librarian / Personal Library __0:cluster_02ff79f0_00a8_4859_a2ed_a06f92fd0fff->_0873a209_b9df_4bf3_b65e_2f425c5a2adc
import org_rw
import os

def recursively_raise_depth_to(hl: org_rw.Headline, new_depth: int):
    assert hl.depth >= new_depth
    depth_change = hl.depth - new_depth
    recursively_raise_depth(hl, depth_change)

def recursively_raise_depth(hl, depth_change):
    for child in hl.children:
        recursively_raise_depth(child, depth_change)
    hl.depth -= depth_change

def move_in_subtree_archive_to_separate_archive_file(from_doc: org_rw.OrgDoc, to_doc: org_rw.OrgDoc):
    # Get all archives
    archives = []
    for hl in from_doc.getAllHeadlines():
        if hl.title.get_text().strip() == 'Archive' and 'ARCHIVE' in hl.tags:
            archives.append(hl)

    print("Found {} archives".format(len(archives)))
    change_count = 0
    for archive in archives:
        if archive.parent.id is None:
            print("Skipping archive as parent ({}; title={}) has no ID".format(archive.parent, archive.parent.title if isinstance(archive.parent, org_rw.Headline) else '(doc)'))
            continue

        parid = archive.parent.id
        while len(archive.children) > 0:
            change_count += 1
            hl = archive.children.pop(0)
            hl.set_property('ARCHIVE_PARENT_ID', parid)

            recursively_raise_depth_to(hl, 1)
            to_doc.headlines.append(hl)

    print("{} changes applied".format(change_count))

with open(os.path.expanduser('~/.logs/logs.org.txt_archive'), 'rt') as farc:
    with open(os.path.expanduser('~/.logs/logs.org.txt'), 'rt') as f:
        from_doc = org_rw.load(f)
        to_doc = org_rw.load(farc)

move_in_subtree_archive_to_separate_archive_file(from_doc, to_doc)

# Save archives first
with open(os.path.expanduser('~/.logs/logs.org.txt_archive'), 'wt') as farc:
    org_rw.dump(to_doc, farc)
with open(os.path.expanduser('~/.logs/logs.org.txt'), 'wt') as f:
    org_rw.dump(from_doc, f)

DONE

Reverse: Combine new files and archive into a single output

Used this to combine all the notes to send them to coworkers when leaving a project.

import org_rw
import os

def recursively_raise_depth_to(hl: org_rw.Headline, new_depth: int):
    assert hl.depth >= new_depth
    depth_change = hl.depth - new_depth
    recursively_raise_depth(hl, depth_change)

def recursively_raise_depth(hl, depth_change):
    for child in hl.children:
        recursively_raise_depth(child, depth_change)

    new_depth = hl.depth - depth_change
    assert new_depth > 0, f"Trying to move to depth to {new_depth} (raising by {depth_change})"
    hl.depth = new_depth

def combine_main_file_and_archive(main_doc: org_rw.OrgDoc, archive_doc: org_rw.OrgDoc):
    archive_trees = list(archive_doc.getTopHeadlines())
    print("Found {} archive trees".format(len(archive_trees)))
    while len(archive_trees) > 0:
        some_inserted = False

        skipped = []
        while len(archive_trees) > 0:
            next_tree = archive_trees.pop()
            archive_parent_id = next_tree.get_property("ARCHIVE_PARENT_ID")
            this_was_inserted = False

            if archive_parent_id is not None:
                # Find appropriate headline
                match_headline = None
                for headline in main_doc.getAllHeadlines():
                    if headline.id == archive_parent_id:
                        match_headline = headline
                        break

                if match_headline is not None:
                    print("Inserting '{}' (id:{}) in '{}' (id:{})".format(
                        next_tree.title.get_text(),
                        next_tree.id,
                        match_headline.title.get_text(),
                        match_headline.id,
                    ))

                    match_headline.children.append(next_tree)
                    recursively_raise_depth(next_tree, next_tree.depth - (match_headline.depth + 1))

                    some_inserted = True
                    this_was_inserted = True

            if not this_was_inserted:
                skipped.append(next_tree)

        archive_trees = skipped
        if not some_inserted:
            break

    if len(archive_trees) == 0:
        print("All archive trees inserted")
    else:
        print("{} archive trees cannot be inserted".format(len(archive_trees)))
        print("next 10:")
        for t in archive_trees[:10]:
            print(f"  title: {t.title.get_text()} ; id: {t.id} ; parent: {t.get_property('ARCHIVE_PARENT_ID')}")

with open(os.path.expanduser('~/.logs/logs.org.txt_archive'), 'rt') as farc:
    with open(os.path.expanduser('~/.logs/logs.org.txt'), 'rt') as f:
        main_doc = org_rw.load(f)
        archive_doc = org_rw.load(farc)

combine_main_file_and_archive(main_doc, archive_doc)
remove_logbooks(main_doc)

# Save archives first
with open(os.path.expanduser('~/.logs/logs-all.org.txt'), 'wt') as fnew:
    org_rw.dump(main_doc, fnew)