Spaces:
Running
Running
Update src/services/journal_engine.py
Browse files
src/services/journal_engine.py
CHANGED
|
@@ -3,6 +3,7 @@ import io
|
|
| 3 |
import os
|
| 4 |
import re
|
| 5 |
import uuid
|
|
|
|
| 6 |
from google_auth_oauthlib.flow import Flow
|
| 7 |
from googleapiclient.discovery import build
|
| 8 |
from googleapiclient.http import MediaIoBaseUpload, MediaIoBaseDownload
|
|
@@ -39,6 +40,7 @@ class JournalEngine:
|
|
| 39 |
except Exception as e:
|
| 40 |
print(f"⚠️ Token Load Error: {e}")
|
| 41 |
return None
|
|
|
|
| 42 |
@staticmethod
|
| 43 |
def get_drive_service(creds):
|
| 44 |
return build('drive', 'v3', credentials=creds)
|
|
@@ -70,7 +72,6 @@ class JournalEngine:
|
|
| 70 |
@staticmethod
|
| 71 |
def initialize_journal(service):
|
| 72 |
try:
|
| 73 |
-
# Check if file exists specifically in appDataFolder
|
| 74 |
response = service.files().list(
|
| 75 |
q="name='journal.json' and 'appDataFolder' in parents",
|
| 76 |
spaces='appDataFolder',
|
|
@@ -96,18 +97,26 @@ class JournalEngine:
|
|
| 96 |
|
| 97 |
@classmethod
|
| 98 |
def save_trade(cls, service, file_id, trade_data):
|
| 99 |
-
"""Smart Update: Edits existing ID or Appends new UUID."""
|
| 100 |
journal = cls.load_journal(service, file_id)
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
trade_id = trade_data.get('id')
|
| 103 |
updated = False
|
| 104 |
|
| 105 |
-
# Ensure ID exists for new trades
|
| 106 |
if not trade_id:
|
| 107 |
trade_data['id'] = str(uuid.uuid4())
|
| 108 |
journal.append(trade_data)
|
| 109 |
else:
|
| 110 |
-
# Try to find and update
|
| 111 |
for i, existing in enumerate(journal):
|
| 112 |
if existing.get('id') == trade_id:
|
| 113 |
journal[i] = trade_data
|
|
@@ -119,6 +128,19 @@ class JournalEngine:
|
|
| 119 |
cls.save_to_drive(service, file_id, journal)
|
| 120 |
return True
|
| 121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
@staticmethod
|
| 123 |
def parse_pnl(pnl_str):
|
| 124 |
try:
|
|
|
|
| 3 |
import os
|
| 4 |
import re
|
| 5 |
import uuid
|
| 6 |
+
import datetime # <--- NEW IMPORT
|
| 7 |
from google_auth_oauthlib.flow import Flow
|
| 8 |
from googleapiclient.discovery import build
|
| 9 |
from googleapiclient.http import MediaIoBaseUpload, MediaIoBaseDownload
|
|
|
|
| 40 |
except Exception as e:
|
| 41 |
print(f"⚠️ Token Load Error: {e}")
|
| 42 |
return None
|
| 43 |
+
|
| 44 |
@staticmethod
|
| 45 |
def get_drive_service(creds):
|
| 46 |
return build('drive', 'v3', credentials=creds)
|
|
|
|
| 72 |
@staticmethod
|
| 73 |
def initialize_journal(service):
|
| 74 |
try:
|
|
|
|
| 75 |
response = service.files().list(
|
| 76 |
q="name='journal.json' and 'appDataFolder' in parents",
|
| 77 |
spaces='appDataFolder',
|
|
|
|
| 97 |
|
| 98 |
@classmethod
|
| 99 |
def save_trade(cls, service, file_id, trade_data):
|
| 100 |
+
"""Smart Update: Edits existing ID or Appends new UUID + Auto-Tags Date."""
|
| 101 |
journal = cls.load_journal(service, file_id)
|
| 102 |
|
| 103 |
+
# --- PHASE 1 UPGRADE: Temporal Injection ---
|
| 104 |
+
if 'trade_date' in trade_data:
|
| 105 |
+
try:
|
| 106 |
+
dt = datetime.datetime.strptime(trade_data['trade_date'], "%Y-%m-%d")
|
| 107 |
+
trade_data['week'] = dt.strftime("%Y-W%W") # e.g. 2026-W05
|
| 108 |
+
trade_data['month'] = dt.strftime("%Y-%m") # e.g. 2026-02
|
| 109 |
+
except ValueError:
|
| 110 |
+
pass # Keep going even if date parse fails
|
| 111 |
+
# -------------------------------------------
|
| 112 |
+
|
| 113 |
trade_id = trade_data.get('id')
|
| 114 |
updated = False
|
| 115 |
|
|
|
|
| 116 |
if not trade_id:
|
| 117 |
trade_data['id'] = str(uuid.uuid4())
|
| 118 |
journal.append(trade_data)
|
| 119 |
else:
|
|
|
|
| 120 |
for i, existing in enumerate(journal):
|
| 121 |
if existing.get('id') == trade_id:
|
| 122 |
journal[i] = trade_data
|
|
|
|
| 128 |
cls.save_to_drive(service, file_id, journal)
|
| 129 |
return True
|
| 130 |
|
| 131 |
+
@classmethod
|
| 132 |
+
def delete_trade(cls, service, file_id, trade_id):
|
| 133 |
+
"""Removes a trade by UUID and saves the list."""
|
| 134 |
+
journal = cls.load_journal(service, file_id)
|
| 135 |
+
|
| 136 |
+
# Filter out the trade with matching ID
|
| 137 |
+
new_journal = [t for t in journal if t.get('id') != trade_id]
|
| 138 |
+
|
| 139 |
+
if len(new_journal) < len(journal):
|
| 140 |
+
cls.save_to_drive(service, file_id, new_journal)
|
| 141 |
+
return True
|
| 142 |
+
return False
|
| 143 |
+
|
| 144 |
@staticmethod
|
| 145 |
def parse_pnl(pnl_str):
|
| 146 |
try:
|