Commit 605130ae authored by Matthieu Boileau's avatar Matthieu Boileau

A much simpler implementation of rubrique tree exporting

parent 4e9c137a
......@@ -296,6 +296,7 @@ class Article:
self.type = spip_type = website
self.rubrique = spip_article['id_rubrique']
self.category =[spip_article['id_rubrique']]
id_tag = 'id_' + self.type
self.short_id = spip_article[id_tag]
......@@ -375,49 +376,6 @@ summary: {self.summary}
return self.skip_reason
class Tree(dict):
Simple Tree data structure from
Stores data in the form:
"a": {
"b": {},
"c": {},
"d": {
"e": {},
And can be nested to any depth.
def __missing__(self, key):
value = self[key] = type(self)()
return value
def insert(self, node, ancestors):
"""Insert the supplied node, creating all ancestors as required.
This expects a list (possibly empty) containing the ancestors,
and a value for the node.
if not ancestors:
self[ancestors[0]].insert(node, ancestors[1:])
def label(self, labels, sort_key=lambda x: x[0]):
"""Return a nested 2-tuple with just the supplied labels.
Realistically, the labels could be any type of object.
return sorted([
value.label(labels, sort_key)
) for key, value in self.items()
], key=sort_key)
class Website:
"""Define a website from Spip data"""
......@@ -445,6 +403,8 @@ class Website:
self.nullified_urls = 0
self.articles = []
self.rubrique_tree = {}
config_filename = "config.yml"
with open(config_filename, 'r') as ymlfile:
cfg = yaml.load(ymlfile)
......@@ -501,7 +461,7 @@ class Website:
rubriques = yaml.load(
self.parents = {rubrique['id_rubrique']: rubrique['id_parent'] for rubrique in rubriques}
self.labels = {rubrique['id_rubrique']: rubrique['titre'] for rubrique in rubriques}
self.labels = {rubrique['id_rubrique']: rubrique['titre'].strip() for rubrique in rubriques}
self.category_index = {rubrique['id_rubrique']: get_category(rubrique['id_rubrique'])
for rubrique in rubriques}
......@@ -512,51 +472,40 @@ class Website:
"""Render node label from node id"""
return f"{node_id}: {self.labels[node_id]}"
def walk(node, parent=None):
A recursive function to walk a Tree object in order to build an anytree.Node tree
node: a Tree object
parent: a Tree object
if len(node):
# node is a real Tree, not a leaf
name = list(node.keys())[0]
anytree_nodes[name] = anytree.Node(name, parent=parent)
children = list(node.values())[0]
for k, v in children.items():
walk({k: v}, anytree_nodes[name])
data = [] # a list of Tree nodes
tree = Tree() # a Tree object to store rubrique structure as a nested dict
def insert_node(node_id):
"""A recursive function to insert a node in the anytree.Node tree"""
node_name = get_label(node_id)
if node_id == 0:
self.rubrique_tree[node_name] = anytree.Node(node_name)
parent_id = self.parents[node_id]
parent_name = get_label(parent_id)
parent = self.rubrique_tree.get(parent_name)
if not parent:
# insert parent if it does not exist
self.rubrique_tree[node_name] = anytree.Node(node_name, parent=parent)
self.labels[0] = "root" # Root node label
# Build ancestors list
for node_id in self.parents:
node = {}
label = get_label(node_id)
node['node'] = label
node['label'] = self.labels[node_id]
node['ancestors'] = []
current_id = node_id
while current_id != 0:
# Insert node if it is not the tree root
current_id = self.parents[current_id]
label = get_label(current_id)
node['ancestors'].insert(0, label)
for node in data:
tree.insert(node['node'], node['ancestors'])
# Create a dictionary of anytree.Node objects
anytree_nodes = {get_label(0): anytree.Node(get_label(0))} # create root node
walk(tree) # walk tree to insert other nodes
# Render the anytree.Node object like the bash "tree" command would do
for pre, fill, anytree_node in anytree.RenderTree(anytree_nodes['0: root']):
return anytree_nodes['0: root']
# Count the number of articles for each rubriques
for article in self.articles:
if article.type != 'rubrique': # Do not rubriques themselves
#rubrique_node =, article.rubrique, name="id")
#rubrique_node.count += 1
# Render the AnyNode object like the bash "tree" command would do
for pre, fill, rubrique_node in anytree.RenderTree(self.rubrique_tree['0: root']):
def _build_doc_index(self):
"""Build the index dictionary: {id_doc: file_path}"""
......@@ -646,6 +595,6 @@ if __name__ == '__main__':
if args.rubriques:
# Show only Spip rubrique structure
tree = website.print_rubrique_tree()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment