-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy paththings_sync.py
More file actions
129 lines (107 loc) · 4.55 KB
/
things_sync.py
File metadata and controls
129 lines (107 loc) · 4.55 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import logging
import os
import sys
import argparse
# Add the libraries folder to Python path - more robust path resolution
current_dir = os.path.dirname(os.path.abspath(__file__))
libraries_path = os.path.join(current_dir, 'libraries')
if libraries_path not in sys.path:
sys.path.insert(0, libraries_path)
#from pyThings.json import Json
from dotenv import load_dotenv
from database import DatabaseManager
from config import DatabaseConfig
class ThingsSyncer:
def __init__(self, db_manager: DatabaseManager):
self.db_manager = db_manager
def update_things_id(self, ticket_id: str, things_id: str):
"""Update the Things ID for a given ticket"""
with self.db_manager.get_connection() as conn:
cursor = conn.cursor()
cursor.execute('''
UPDATE jira_tickets
SET things_id = ?
WHERE ticket_id = ?
''', (things_id, ticket_id))
conn.commit()
logging.info(f"Updated Things ID for ticket {ticket_id}")
def get_unsynced_tickets(self):
"""Get all tickets that haven't been synced to Things yet"""
with self.db_manager.get_connection() as conn:
cursor = conn.cursor()
cursor.execute('''
SELECT ticket_id, summary, description, has_subtasks
FROM jira_tickets
WHERE things_id IS NULL
''')
return cursor.fetchall()
def create_things_todo(self, ticket_id: str, summary: str, description: str):
"""Create a new todo in Things and return its ID"""
# Create the todo with JIRA ticket reference in notes
jira_url = f"{self.db_manager.jira_base_url}/browse/{ticket_id}"
notes = f"{jira_url}\n\n{description}"
# Create the task data
task_data = [{
"type": "to-do",
"attributes": {
"title": f"[{ticket_id}] {summary}",
"notes": notes,
"tags": ["jira"],
"list": "inbox"
}
}]
# Use pyThings Json class to create the todo
logging.debug(f"Creating Things todo: {task_data[0]['attributes']['title']}")
task = Json(data=task_data)
# Get the Things ID from the response
things_id = task.response.get('x-things-ids')
if things_id:
logging.debug(f"Received Things ID: {things_id}")
return things_id
else:
logging.warning("No Things ID received from Things 3")
return None
def sync_tickets(self):
"""Sync all unsynced tickets to Things"""
logging.info("Starting Things sync...")
unsynced_tickets = self.get_unsynced_tickets()
for ticket in unsynced_tickets:
ticket_id, summary, description, has_subtasks = ticket
logging.info(f"Syncing ticket {ticket_id} to Things...")
try:
# Create the todo in Things
sync_status = self.create_things_todo(ticket_id, summary, description)
# Update the database with sync status
self.update_things_id(ticket_id, sync_status)
logging.info(f"Successfully synced ticket {ticket_id} to Things")
except Exception as e:
logging.error(f"Error syncing ticket {ticket_id}: {str(e)}")
def parse_args():
parser = argparse.ArgumentParser(description='Sync JIRA tickets from SQLite to Things 3')
parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging')
return parser.parse_args()
def main():
args = parse_args()
# Set up logging
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
try:
# Load configuration
load_dotenv()
jira_base_url = os.getenv("JIRA_BASE_URL")
if not jira_base_url:
raise ValueError("JIRA_BASE_URL environment variable is required")
# Initialize database with jira_base_url
db_config = DatabaseConfig()
db_manager = DatabaseManager(db_config.db_path, jira_base_url)
# Initialize and run syncer
syncer = ThingsSyncer(db_manager)
syncer.sync_tickets()
logging.info("Things sync completed successfully")
except Exception as e:
logging.error(f"Error during Things sync: {str(e)}")
if __name__ == "__main__":
main()