local-deep-research 0.6.1__py3-none-any.whl → 0.6.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. local_deep_research/__init__.py +6 -0
  2. local_deep_research/__version__.py +1 -1
  3. local_deep_research/setup_data_dir.py +3 -2
  4. local_deep_research/utilities/db_utils.py +11 -9
  5. local_deep_research/utilities/log_utils.py +1 -1
  6. local_deep_research/utilities/threading_utils.py +17 -4
  7. local_deep_research/web/api.py +5 -3
  8. local_deep_research/web/app.py +0 -74
  9. local_deep_research/web/app_factory.py +1 -11
  10. local_deep_research/web/database/migrations.py +699 -28
  11. local_deep_research/web/database/uuid_migration.py +2 -247
  12. local_deep_research/web/models/database.py +0 -79
  13. local_deep_research/web/routes/settings_routes.py +70 -73
  14. local_deep_research/web/services/settings_manager.py +13 -28
  15. local_deep_research/web/services/settings_service.py +6 -40
  16. local_deep_research/web/services/socket_service.py +1 -1
  17. local_deep_research/web_search_engines/rate_limiting/tracker.py +1 -3
  18. {local_deep_research-0.6.1.dist-info → local_deep_research-0.6.4.dist-info}/METADATA +19 -4
  19. {local_deep_research-0.6.1.dist-info → local_deep_research-0.6.4.dist-info}/RECORD +22 -25
  20. local_deep_research/migrate_db.py +0 -149
  21. local_deep_research/web/database/migrate_to_ldr_db.py +0 -297
  22. local_deep_research/web/database/schema_upgrade.py +0 -519
  23. {local_deep_research-0.6.1.dist-info → local_deep_research-0.6.4.dist-info}/WHEEL +0 -0
  24. {local_deep_research-0.6.1.dist-info → local_deep_research-0.6.4.dist-info}/entry_points.txt +0 -0
  25. {local_deep_research-0.6.1.dist-info → local_deep_research-0.6.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,297 +0,0 @@
1
- """
2
- Migration script to merge deep_research.db and research_history.db into ldr.db
3
- """
4
-
5
- # Standard library imports
6
- # import json # Remove unused imports
7
- import logging
8
- import os
9
- import sqlite3
10
- import sys
11
- import traceback
12
-
13
- # from pathlib import Path # Remove unused imports
14
-
15
- # Set up logging
16
- logging.basicConfig(level=logging.INFO)
17
- logger = logging.getLogger(__name__)
18
-
19
- # Add the parent directory to sys.path to allow relative imports
20
- sys.path.append(
21
- os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
22
- )
23
-
24
- # Import the database module after adding to sys path
25
- # pylint: disable=wrong-import-position
26
- from src.local_deep_research.web.models.database import ( # noqa: E402
27
- DB_PATH,
28
- LEGACY_DEEP_RESEARCH_DB,
29
- LEGACY_RESEARCH_HISTORY_DB,
30
- )
31
-
32
-
33
- def migrate_to_ldr_db():
34
- """
35
- Migrates data from deep_research.db and research_history.db to ldr.db
36
- """
37
- # Ensure data directory exists
38
- try:
39
- from src.local_deep_research.setup_data_dir import setup_data_dir
40
-
41
- setup_data_dir()
42
- except ImportError:
43
- # If we can't import directly, check the path manually
44
- logger.info("Creating data directory manually")
45
- data_dir = os.path.dirname(DB_PATH)
46
- os.makedirs(data_dir, exist_ok=True)
47
-
48
- logger.info(f"Using database path: {DB_PATH}")
49
-
50
- # Check if ldr.db already exists
51
- if os.path.exists(DB_PATH):
52
- logger.info(f"Target database {DB_PATH} already exists")
53
-
54
- # Ask for confirmation
55
- if (
56
- input(
57
- f"Target database {DB_PATH} already exists. Do you want to continue migration? (y/n): "
58
- ).lower()
59
- != "y"
60
- ):
61
- logger.info("Migration aborted by user")
62
- return False
63
-
64
- # Connect to the target database
65
- try:
66
- ldr_conn = sqlite3.connect(DB_PATH)
67
- ldr_cursor = ldr_conn.cursor()
68
- logger.info(f"Connected to target database: {DB_PATH}")
69
- except Exception as e:
70
- logger.error(f"Failed to connect to target database: {e}")
71
- return False
72
-
73
- # Enable foreign keys
74
- ldr_cursor.execute("PRAGMA foreign_keys = OFF")
75
-
76
- # Initialize the database schema
77
- try:
78
- from src.local_deep_research.web.models.database import init_db
79
-
80
- init_db()
81
- logger.info("Initialized database schema")
82
- except Exception as e:
83
- logger.error(f"Failed to initialize database schema: {e}")
84
- ldr_conn.close()
85
- return False
86
-
87
- # Migrate from research_history.db
88
- migrated_research = migrate_research_history_db(
89
- ldr_conn, LEGACY_RESEARCH_HISTORY_DB
90
- )
91
-
92
- # Migrate from deep_research.db
93
- migrated_deep_research = migrate_deep_research_db(
94
- ldr_conn, LEGACY_DEEP_RESEARCH_DB
95
- )
96
-
97
- # Re-enable foreign keys and commit
98
- ldr_cursor.execute("PRAGMA foreign_keys = ON")
99
- ldr_conn.commit()
100
- ldr_conn.close()
101
-
102
- logger.info(
103
- f"Migration completed - Research History: {migrated_research}, Deep Research: {migrated_deep_research}"
104
- )
105
- return True
106
-
107
-
108
- def migrate_research_history_db(ldr_conn, legacy_path):
109
- """
110
- Migrates data from research_history.db to ldr.db
111
-
112
- Args:
113
- ldr_conn: Connection to the target ldr.db
114
- legacy_path: Path to legacy research_history.db
115
-
116
- Returns:
117
- bool: True if migration was successful, False otherwise
118
- """
119
- if not os.path.exists(legacy_path):
120
- logger.warning(f"Legacy database not found: {legacy_path}")
121
- return False
122
-
123
- try:
124
- # Connect to legacy database
125
- legacy_conn = sqlite3.connect(legacy_path)
126
- legacy_cursor = legacy_conn.cursor()
127
- ldr_cursor = ldr_conn.cursor()
128
-
129
- logger.info(f"Connected to legacy database: {legacy_path}")
130
-
131
- # Get tables from legacy database
132
- legacy_cursor.execute(
133
- "SELECT name FROM sqlite_master WHERE type='table'"
134
- )
135
- tables = [row[0] for row in legacy_cursor.fetchall()]
136
-
137
- for table in tables:
138
- # Skip sqlite internal tables
139
- if table.startswith("sqlite_"):
140
- continue
141
-
142
- logger.info(f"Migrating table: {table}")
143
-
144
- # Check if table exists in target database
145
- ldr_cursor.execute(
146
- f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'"
147
- )
148
- if not ldr_cursor.fetchone():
149
- # Create the table in the target database
150
- legacy_cursor.execute(
151
- f"SELECT sql FROM sqlite_master WHERE type='table' AND name='{table}'"
152
- )
153
- create_sql = legacy_cursor.fetchone()[0]
154
- logger.info(f"Creating table {table} with SQL: {create_sql}")
155
- ldr_cursor.execute(create_sql)
156
- logger.info(f"Created table {table} in target database")
157
-
158
- # Get column names
159
- legacy_cursor.execute(f"PRAGMA table_info({table})")
160
- columns = [row[1] for row in legacy_cursor.fetchall()]
161
-
162
- # Get all data from legacy table
163
- legacy_cursor.execute(f"SELECT * FROM {table}")
164
- rows = legacy_cursor.fetchall()
165
-
166
- logger.info(f"Found {len(rows)} rows in {table}")
167
-
168
- if rows:
169
- # Create placeholders for the SQL query
170
- placeholders = ", ".join(["?" for _ in columns])
171
- columns_str = ", ".join(columns)
172
-
173
- # Insert data into target database
174
- for row in rows:
175
- try:
176
- ldr_cursor.execute(
177
- f"INSERT OR IGNORE INTO {table} ({columns_str}) VALUES ({placeholders})",
178
- row,
179
- )
180
- except sqlite3.Error as e:
181
- logger.error(f"Error inserting into {table}: {e}")
182
- logger.error(f"Row data: {row}")
183
- continue
184
-
185
- # Verify data was inserted
186
- ldr_cursor.execute(f"SELECT COUNT(*) FROM {table}")
187
- count = ldr_cursor.fetchone()[0]
188
- logger.info(
189
- f"Migrated {count} rows to {table} (expected {len(rows)})"
190
- )
191
- else:
192
- logger.info(f"No data to migrate from {table}")
193
-
194
- legacy_conn.close()
195
- return True
196
-
197
- except Exception as e:
198
- logger.error(f"Failed to migrate from {legacy_path}: {e}")
199
- logger.error(f"Exception details: {traceback.format_exc()}")
200
- return False
201
-
202
-
203
- def migrate_deep_research_db(ldr_conn, legacy_path):
204
- """
205
- Migrates data from deep_research.db to ldr.db
206
-
207
- Args:
208
- ldr_conn: Connection to the target ldr.db
209
- legacy_path: Path to legacy deep_research.db
210
-
211
- Returns:
212
- bool: True if migration was successful, False otherwise
213
- """
214
- if not os.path.exists(legacy_path):
215
- logger.warning(f"Legacy database not found: {legacy_path}")
216
- return False
217
-
218
- try:
219
- # Connect to legacy database
220
- legacy_conn = sqlite3.connect(legacy_path)
221
- legacy_cursor = legacy_conn.cursor()
222
- ldr_cursor = ldr_conn.cursor()
223
-
224
- logger.info(f"Connected to legacy database: {legacy_path}")
225
-
226
- # Get tables from legacy database
227
- legacy_cursor.execute(
228
- "SELECT name FROM sqlite_master WHERE type='table'"
229
- )
230
- tables = [row[0] for row in legacy_cursor.fetchall()]
231
-
232
- # Migrate each table
233
- for table in tables:
234
- # Skip sqlite internal tables
235
- if table.startswith("sqlite_"):
236
- continue
237
-
238
- # Skip the research_log table as it's redundant with research_logs
239
- if table == "research_log":
240
- logger.info(
241
- "Skipping redundant table 'research_log', using 'research_logs' instead"
242
- )
243
- continue
244
-
245
- logger.info(f"Migrating table: {table}")
246
-
247
- # Check if table exists in target database
248
- ldr_cursor.execute(
249
- f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'"
250
- )
251
- if not ldr_cursor.fetchone():
252
- # Create the table in the target database
253
- legacy_cursor.execute(
254
- f"SELECT sql FROM sqlite_master WHERE type='table' AND name='{table}'"
255
- )
256
- create_sql = legacy_cursor.fetchone()[0]
257
- ldr_cursor.execute(create_sql)
258
- logger.info(f"Created table {table} in target database")
259
-
260
- # Get column names
261
- legacy_cursor.execute(f"PRAGMA table_info({table})")
262
- columns = [row[1] for row in legacy_cursor.fetchall()]
263
-
264
- # Get all data from legacy table
265
- legacy_cursor.execute(f"SELECT * FROM {table}")
266
- rows = legacy_cursor.fetchall()
267
-
268
- if rows:
269
- # Create placeholders for the SQL query
270
- placeholders = ", ".join(["?" for _ in columns])
271
- columns_str = ", ".join(columns)
272
-
273
- # Insert data into target database
274
- for row in rows:
275
- try:
276
- ldr_cursor.execute(
277
- f"INSERT OR IGNORE INTO {table} ({columns_str}) VALUES ({placeholders})",
278
- row,
279
- )
280
- except sqlite3.Error as e:
281
- logger.error(f"Error inserting into {table}: {e}")
282
- continue
283
-
284
- logger.info(f"Migrated {len(rows)} rows from {table}")
285
- else:
286
- logger.info(f"No data to migrate from {table}")
287
-
288
- legacy_conn.close()
289
- return True
290
-
291
- except Exception as e:
292
- logger.error(f"Failed to migrate from {legacy_path}: {e}")
293
- return False
294
-
295
-
296
- if __name__ == "__main__":
297
- migrate_to_ldr_db()