#!/usr/bin/env python3 """ Content management examples for the Wiki.js Python SDK. This script demonstrates advanced content management operations like bulk operations, content migration, and template usage. """ import os import time from datetime import datetime from wikijs import WikiJSClient from wikijs.models import PageCreate, PageUpdate from wikijs.exceptions import APIError def create_page_template(template_type, **kwargs): """Create page content from templates.""" templates = { "meeting_notes": """# {title} **Date:** {date} **Attendees:** {attendees} **Duration:** {duration} ## Agenda {agenda} ## Discussion Points {discussion} ## Decisions Made {decisions} ## Action Items {action_items} ## Next Meeting **Date:** {next_meeting_date} **Topics:** {next_meeting_topics} """, "project_doc": """# {project_name} ## Project Overview {overview} ## Objectives {objectives} ## Scope ### In Scope {in_scope} ### Out of Scope {out_of_scope} ## Timeline {timeline} ## Resources ### Team Members {team_members} ### Budget {budget} ## Risks and Mitigation {risks} ## Success Criteria {success_criteria} ## Status Updates *Last updated: {last_updated}* {status} """, "api_doc": """# {api_name} API ## Overview {overview} ## Base URL ``` {base_url} ``` ## Authentication {authentication} ## Endpoints ### {endpoint_name} ```http {http_method} {endpoint_path} ``` **Description:** {endpoint_description} **Parameters:** {parameters} **Example Request:** ```json {example_request} ``` **Example Response:** ```json {example_response} ``` ## Error Codes {error_codes} """, "troubleshooting": """# {title} - Troubleshooting Guide ## Common Issues ### Issue: {issue_1_title} **Symptoms:** {issue_1_symptoms} **Cause:** {issue_1_cause} **Solution:** {issue_1_solution} ### Issue: {issue_2_title} **Symptoms:** {issue_2_symptoms} **Cause:** {issue_2_cause} **Solution:** {issue_2_solution} ## FAQ {faq} ## Getting Help {help_info} ## Related Documentation {related_docs} """ } template = templates.get(template_type) if not template: raise ValueError(f"Unknown template type: {template_type}") return template.format(**kwargs) def bulk_create_pages(client, pages_data): """Create multiple pages with error handling and progress tracking.""" created_pages = [] failed_pages = [] print(f"๐Ÿ“ Creating {len(pages_data)} pages...") for i, page_data in enumerate(pages_data, 1): try: print(f" [{i}/{len(pages_data)}] Creating: {page_data.title}") created_page = client.pages.create(page_data) created_pages.append(created_page) # Be nice to the server time.sleep(0.2) except APIError as e: print(f" โŒ Failed: {e}") failed_pages.append((page_data.title, str(e))) print(f"โœ… Successfully created {len(created_pages)} pages") if failed_pages: print(f"โŒ Failed to create {len(failed_pages)} pages:") for title, error in failed_pages: print(f" โ€ข {title}: {error}") return created_pages, failed_pages def content_migration_example(client): """Demonstrate content migration and format conversion.""" print("๐Ÿ”„ Content Migration Example") print("-" * 40) # Find pages that need migration (example: old format markers) pages_to_migrate = client.pages.search("OLD_FORMAT", limit=5) if not pages_to_migrate: print("No pages found that need migration") return print(f"Found {len(pages_to_migrate)} pages to migrate") migration_count = 0 for page in pages_to_migrate: try: print(f" Migrating: {page.title}") # Example migration: Convert old-style headers new_content = page.content # Convert old format markers new_content = new_content.replace("OLD_FORMAT", "") new_content = new_content.replace("==Header==", "## Header") new_content = new_content.replace("===Subheader===", "### Subheader") # Add migration notice migration_notice = f"\n\n---\n*Migrated on {datetime.now().strftime('%Y-%m-%d')}*\n" new_content += migration_notice # Update the page update_data = PageUpdate( content=new_content, tags=page.tags + ["migrated"] if page.tags else ["migrated"] ) client.pages.update(page.id, update_data) migration_count += 1 except APIError as e: print(f" โŒ Migration failed: {e}") print(f"โœ… Successfully migrated {migration_count} pages") def content_audit_example(client): """Perform a content audit to analyze wiki structure.""" print("๐Ÿ“Š Content Audit Example") print("-" * 40) # Get all pages for analysis all_pages = client.pages.list() print(f"๐Ÿ“š Total pages: {len(all_pages)}") # Analyze by status published = [p for p in all_pages if p.is_published] private = [p for p in all_pages if p.is_private] print(f"๐Ÿ“– Published: {len(published)}") print(f"๐Ÿ”’ Private: {len(private)}") # Analyze by tags all_tags = set() for page in all_pages: if page.tags: all_tags.update(page.tags) print(f"๐Ÿท๏ธ Unique tags: {len(all_tags)}") # Find most common tags tag_counts = {} for page in all_pages: if page.tags: for tag in page.tags: tag_counts[tag] = tag_counts.get(tag, 0) + 1 if tag_counts: top_tags = sorted(tag_counts.items(), key=lambda x: x[1], reverse=True)[:5] print("๐Ÿ”ฅ Most common tags:") for tag, count in top_tags: print(f" โ€ข {tag}: {count} pages") # Analyze content length word_counts = [p.word_count for p in all_pages] if word_counts: avg_words = sum(word_counts) / len(word_counts) max_words = max(word_counts) min_words = min(word_counts) print(f"๐Ÿ“ Content analysis:") print(f" โ€ข Average words: {avg_words:.0f}") print(f" โ€ข Longest page: {max_words} words") print(f" โ€ข Shortest page: {min_words} words") # Find pages without tags untagged = [p for p in all_pages if not p.tags] if untagged: print(f"โš ๏ธ Pages without tags: {len(untagged)}") print(" Consider adding tags to improve organization") # Find very short pages (potential stubs) stubs = [p for p in all_pages if p.word_count < 50] if stubs: print(f"๐Ÿ“ Potential stubs (< 50 words): {len(stubs)}") for stub in stubs[:3]: print(f" โ€ข {stub.title} ({stub.word_count} words)") def main(): """Run content management examples.""" base_url = os.getenv("WIKIJS_URL", "https://wiki.example.com") api_key = os.getenv("WIKIJS_API_KEY", "your-api-key-here") print("๐Ÿ“š Wiki.js Python SDK - Content Management Examples") print("=" * 60) try: with WikiJSClient(base_url=base_url, auth=api_key) as client: # Test connection if not client.test_connection(): print("โŒ Connection failed!") return print("โœ… Connected successfully!") # Example 1: Template-based page creation print("\n๐Ÿ“ Example 1: Template-based Page Creation") print("-" * 50) # Create meeting notes from template meeting_content = create_page_template( "meeting_notes", title="Weekly Team Sync - Dec 15, 2023", date="December 15, 2023", attendees="Alice, Bob, Charlie, Diana", duration="1 hour", agenda="โ€ข Project updates\nโ€ข Q1 planning\nโ€ข Process improvements", discussion="โ€ข Discussed current sprint progress\nโ€ข Reviewed Q1 roadmap priorities", decisions="โ€ข Approved new deployment process\nโ€ข Selected project management tool", action_items="โ€ข Alice: Update documentation by Dec 20\nโ€ข Bob: Set up new CI pipeline", next_meeting_date="December 22, 2023", next_meeting_topics="Holiday schedule, Q1 kickoff planning" ) meeting_page = PageCreate( title="Weekly Team Sync - Dec 15, 2023", path="meetings/2023-12-15-team-sync", content=meeting_content, tags=["meeting", "team", "weekly"], description="Weekly team synchronization meeting notes" ) # Create project documentation from template project_content = create_page_template( "project_doc", project_name="Wiki.js Python SDK", overview="A comprehensive Python SDK for interacting with Wiki.js API", objectives="โ€ข Provide easy-to-use Python interface\nโ€ข Support all major Wiki.js features\nโ€ข Maintain high code quality", in_scope="Pages API, authentication, error handling, documentation", out_of_scope="Advanced admin features, custom plugins", timeline="โ€ข Phase 1: MVP (2 weeks)\nโ€ข Phase 2: Advanced features (4 weeks)", team_members="โ€ข Lead Developer: Alice\nโ€ข Contributors: Community", budget="Open source project - volunteer contributions", risks="โ€ข API changes in Wiki.js\nโ€ข Community adoption", success_criteria="โ€ข >85% test coverage\nโ€ข Complete documentation\nโ€ข Community feedback", last_updated=datetime.now().strftime('%Y-%m-%d'), status="โœ… Phase 1 completed\n๐Ÿ”„ Phase 2 in progress" ) project_page = PageCreate( title="Wiki.js Python SDK - Project Documentation", path="projects/wikijs-python-sdk", content=project_content, tags=["project", "sdk", "python", "documentation"], description="Project documentation for the Wiki.js Python SDK" ) # Bulk create pages template_pages = [meeting_page, project_page] created_pages, failed_pages = bulk_create_pages(client, template_pages) # Example 2: Content audit print("\n๐Ÿ“Š Example 2: Content Audit") print("-" * 50) content_audit_example(client) # Example 3: Batch operations print("\n๐Ÿ”„ Example 3: Batch Tag Updates") print("-" * 50) # Find pages without descriptions pages_without_desc = client.pages.list()[:5] # Sample for demo pages_to_update = [p for p in pages_without_desc if not p.description] if pages_to_update: print(f"Found {len(pages_to_update)} pages without descriptions") update_count = 0 for page in pages_to_update: try: # Generate a basic description description = f"Wiki page about {page.title.lower()}" update_data = PageUpdate( description=description, tags=page.tags + ["auto-description"] if page.tags else ["auto-description"] ) client.pages.update(page.id, update_data) update_count += 1 print(f" โœ… Updated: {page.title}") except APIError as e: print(f" โŒ Failed to update {page.title}: {e}") print(f"โœ… Updated {update_count} pages with descriptions") else: print("All pages already have descriptions!") # Cleanup created pages print("\n๐Ÿงน Cleaning up example pages...") for page in created_pages: try: client.pages.delete(page.id) print(f" ๐Ÿ—‘๏ธ Deleted: {page.title}") except APIError as e: print(f" โŒ Failed to delete {page.title}: {e}") print("\nโœจ Content management examples completed!") except Exception as e: print(f"โŒ Error: {e}") if __name__ == "__main__": print("๐Ÿ’ก Before running this example:") print(" export WIKIJS_URL='https://your-wiki.example.com'") print(" export WIKIJS_API_KEY='your-api-key'") print() main()