forked from GNHua/Project-Wiki
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmanage.py
More file actions
executable file
·113 lines (93 loc) · 4.13 KB
/
manage.py
File metadata and controls
executable file
·113 lines (93 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from app import create_app, db, wiki_pwd, mail
from app.models import WikiUser, WikiPage, WikiGroup, WikiPageTree
from flask_script import Manager, Shell, Option
from mongoengine.context_managers import switch_db
app = create_app()
manager = Manager(app)
def make_shell_context():
return dict(app=app, db=db, WikiUser=WikiUser, WikiPage=WikiPage, mail=mail)
manager.add_command('shell', Shell(make_context=make_shell_context))
@manager.option('--force', action='store_true', dest='force', default=False,
help='Re-seed the tree even if one already exists')
def migrate_page_tree(force):
"""Seed WikiPageTree for each group from the Home page link graph."""
groups = WikiGroup.objects.all()
if not groups:
print('No groups found.')
return
for group in groups:
gname = group.name_no_whitespace
print(f'Processing group: {gname}')
with switch_db(WikiPageTree, gname) as _WikiPageTree, \
switch_db(WikiPage, gname) as _WikiPage:
existing = _WikiPageTree.objects.first()
if existing and not force:
print(f' Skipping — tree already exists (use --force to re-seed)')
continue
# Find Home page
home = _WikiPage.objects(title='Home').first()
if home is None:
print(f' WARNING: No Home page found, skipping.')
continue
# BFS from Home's refs
tree = []
orphan_ids = set()
# Pre-seed visited with Home so it never appears as a tree node
visited = {str(home.id)}
def collect_ids(nodes):
"""Walk a nested tree list and collect all ids."""
for node in nodes:
yield node['id']
yield from collect_ids(node.get('children', []))
def build_children(page):
children = []
refs = [r for r in (page.refs or []) if r is not None]
for ref in refs:
ref_id = str(ref.id)
if ref_id in visited:
continue
visited.add(ref_id)
# Skip dangling refs (target page was deleted)
ref_page = _WikiPage.objects(id=ref_id)\
.only('id', 'refs').first()
if ref_page is None:
continue
children.append({'id': ref_id,
'children': build_children(ref_page)})
return children
# Seed top-level from Home's refs
home_refs = [r for r in (home.refs or []) if r is not None]
for ref in home_refs:
ref_id = str(ref.id)
if ref_id in visited:
continue
visited.add(ref_id)
ref_page = _WikiPage.objects(id=ref_id)\
.only('id', 'refs').first()
if ref_page is None:
continue
tree.append({'id': ref_id,
'children': build_children(ref_page)})
# All remaining pages (not Home, not visited) go to orphans
all_pages = _WikiPage.objects.only('id', 'title').all()
for page in all_pages:
pid = str(page.id)
if pid not in visited and page.title != 'Home':
orphan_ids.add(pid)
orphans = list(orphan_ids)
if existing and force:
existing.tree = tree
existing.orphans = orphans
existing.save()
else:
_WikiPageTree(tree=tree, orphans=orphans).save()
tree_count = len(list(collect_ids(tree)))
print(f' Done — {tree_count} pages in tree, {len(orphans)} orphans')
@manager.command
def create_admin():
WikiUser(name=app.config['ADMIN_USERNAME'],
email=app.config['ADMIN_EMAIL'],
password_hash=wiki_pwd.hash(app.config['ADMIN_PASSWORD']),
permissions={'super': 0xff}).save()
if __name__ == '__main__':
manager.run()