#!/usr/bin/env python3
"""
TickTick CLI - Unified command-line interface for importing and exporting tasks
"""
import os
from dotenv import load_dotenv
from src.exporters.notes_exporter import NotesManager, MarkdownExporter, JSONExporter
from src.importers.task_importer import TaskImporter
load_dotenv()
def main():
"""Main interactive CLI"""
print("="*60)
print("TickTick CLI - Import & Export Tasks")
print("="*60)
# Check authentication first
token = os.getenv('TICKTICK_ACCESS_TOKEN')
if not token:
print("\nNo access token found!")
print("Please run 'python get_token.py' to authenticate first.")
return
# Initialize managers
exporter = NotesManager()
importer = TaskImporter()
# Authenticate
print("\nAuthenticating...")
if not exporter.authenticate():
print("Authentication failed")
return
# Show projects
print("\n" + "="*60)
print("Your Projects")
print("="*60)
exporter.list_projects()
# Interactive menu
while True:
print("\n" + "="*60)
print("What would you like to do?")
print("="*60)
print("1. Import tasks from Markdown")
print("2. Export notes by tag")
print("3. Export entire project")
print("4. List tags")
print("5. Exit")
try:
choice = input("\nEnter choice (1-5): ").strip()
except (KeyboardInterrupt, EOFError):
print("\n\nDone!")
break
if choice == "1":
# Import tasks from Markdown
print("\n" + "="*60)
print("Import Tasks from Markdown")
print("="*60)
file_path = input("\nEnter markdown file path: ").strip()
if not os.path.exists(file_path):
print(f"File not found: {file_path}")
continue
default_project = input("Default project (leave empty for Inbox): ").strip() or None
dry_run_choice = input("Preview only (dry run)? (y/n, default=n): ").strip().lower()
dry_run = (dry_run_choice == 'y')
if not dry_run:
print("\nThis will create tasks in your TickTick account!")
confirm = input("Continue? (y/n): ").strip().lower()
if confirm != 'y':
print("Import cancelled")
continue
importer.import_from_file(file_path, default_project, dry_run)
elif choice == "2":
# Export by tag
print("\n" + "="*60)
print("Export Notes by Tag")
print("="*60)
tag_name = input("\nEnter tag name: ").strip()
project_name = input("Enter project name (leave empty to search ALL projects): ").strip() or None
output_file = input("Enter output filename (default: notes.md): ").strip() or "notes.md"
# Choose format
format_choice = input("Export format (1=Markdown, 2=JSON, default=1): ").strip() or "1"
if format_choice == "2":
export_format = JSONExporter()
if not output_file.endswith('.json'):
output_file = output_file.rsplit('.', 1)[0] + '.json'
else:
export_format = MarkdownExporter()
if not output_file.endswith('.md'):
output_file = output_file.rsplit('.', 1)[0] + '.md'
exporter.export_by_tag(tag_name, output_file, project_name, export_format)
elif choice == "3":
# Export entire project
print("\n" + "="*60)
print("Export Entire Project")
print("="*60)
project_name = input("\nEnter project name: ").strip()
output_file = input("Enter output filename (default: notes.md): ").strip() or "notes.md"
# Choose format
format_choice = input("Export format (1=Markdown, 2=JSON, default=1): ").strip() or "1"
if format_choice == "2":
export_format = JSONExporter()
if not output_file.endswith('.json'):
output_file = output_file.rsplit('.', 1)[0] + '.json'
else:
export_format = MarkdownExporter()
if not output_file.endswith('.md'):
output_file = output_file.rsplit('.', 1)[0] + '.md'
exporter.export_project(project_name, output_file, export_format)
elif choice == "4":
# List tags
print("\n" + "="*60)
print("List Tags")
print("="*60)
project_name = input("\nEnter project name (leave empty to list ALL tags): ").strip() or None
exporter.list_tags(project_name)
elif choice == "5":
print("\nDone!")
break
else:
print("Invalid choice, please try again")
if __name__ == "__main__":
main()