Ana2012 commited on
Commit
bee13be
·
verified ·
1 Parent(s): 7bee5b1

Update app/feedback.py

Browse files
Files changed (1) hide show
  1. app/feedback.py +140 -171
app/feedback.py CHANGED
@@ -1,171 +1,140 @@
1
- import csv
2
- import os
3
- from datetime import datetime, timezone
4
-
5
- from .google_oauth import GoogleAuthRequiredError, append_feedback_to_sheet, load_credentials
6
- from .memory import salvar_memoria_negativa
7
-
8
-
9
- BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
10
- LOGS_DIR = os.getenv("LOGS_DIR", "/data/logs")
11
- FEEDBACK_FILE = os.path.join(LOGS_DIR, "feedback.csv")
12
- FEEDBACK_HEADERS = [
13
- "timestamp",
14
- "query",
15
- "product_id",
16
- "product_name",
17
- "rating",
18
- "is_helpful",
19
- "note",
20
- "categoria_inferida",
21
- "feedback",
22
- "motivo",
23
- "score_final",
24
- "score_semantico",
25
- "bonus_lexical",
26
- "penalidade_feedback",
27
- "user_message",
28
- ]
29
-
30
-
31
- def garantir_pasta_logs():
32
- os.makedirs(LOGS_DIR, exist_ok=True)
33
-
34
-
35
- def inicializar_arquivo_feedback():
36
- garantir_pasta_logs()
37
-
38
- if not os.path.exists(FEEDBACK_FILE):
39
- with open(FEEDBACK_FILE, mode="w", newline="", encoding="utf-8") as f:
40
- writer = csv.writer(f)
41
- writer.writerow(FEEDBACK_HEADERS)
42
-
43
-
44
- def google_sheets_habilitado():
45
- try:
46
- return load_credentials() is not None and bool(os.getenv("GOOGLE_SPREADSHEET_ID", "").strip())
47
- except Exception:
48
- return False
49
-
50
-
51
- def _append_feedback_csv(row):
52
- inicializar_arquivo_feedback()
53
-
54
- with open(FEEDBACK_FILE, mode="a", newline="", encoding="utf-8") as f:
55
- writer = csv.writer(f)
56
- writer.writerow([row.get(header, "") for header in FEEDBACK_HEADERS])
57
-
58
-
59
- def _build_feedback_payload(
60
- query,
61
- product_id,
62
- product_name,
63
- rating=None,
64
- is_helpful=None,
65
- note=None,
66
- categoria_inferida=None,
67
- feedback=None,
68
- motivo=None,
69
- score_final=None,
70
- score_semantico=None,
71
- bonus_lexical=None,
72
- penalidade_feedback=None,
73
- user_message=None,
74
- ):
75
- return {
76
- "timestamp": datetime.now(timezone.utc).isoformat(),
77
- "query": query,
78
- "product_id": product_id,
79
- "product_name": product_name,
80
- "rating": rating if rating is not None else "",
81
- "is_helpful": is_helpful if is_helpful is not None else "",
82
- "note": note or "",
83
- "categoria_inferida": categoria_inferida or "",
84
- "feedback": feedback or "",
85
- "motivo": motivo or "",
86
- "score_final": score_final if score_final is not None else "",
87
- "score_semantico": score_semantico if score_semantico is not None else "",
88
- "bonus_lexical": bonus_lexical if bonus_lexical is not None else "",
89
- "penalidade_feedback": penalidade_feedback if penalidade_feedback is not None else "",
90
- "user_message": user_message or "",
91
- }
92
-
93
-
94
- def salvar_feedback(
95
- query,
96
- product_id,
97
- product_name,
98
- rating=None,
99
- is_helpful=None,
100
- note=None,
101
- categoria_inferida=None,
102
- feedback=None,
103
- motivo=None,
104
- score_final=None,
105
- score_semantico=None,
106
- bonus_lexical=None,
107
- penalidade_feedback=None,
108
- user_message=None,
109
- ):
110
- row = _build_feedback_payload(
111
- query=query,
112
- product_id=product_id,
113
- product_name=product_name,
114
- rating=rating,
115
- is_helpful=is_helpful,
116
- note=note,
117
- categoria_inferida=categoria_inferida,
118
- feedback=feedback,
119
- motivo=motivo,
120
- score_final=score_final,
121
- score_semantico=score_semantico,
122
- bonus_lexical=bonus_lexical,
123
- penalidade_feedback=penalidade_feedback,
124
- user_message=user_message,
125
- )
126
-
127
- _append_feedback_csv(row)
128
- saved_google_sheets = False
129
- warning = None
130
-
131
- try:
132
- append_feedback_to_sheet(row)
133
- saved_google_sheets = True
134
- except GoogleAuthRequiredError:
135
- warning = "Feedback salvo localmente, mas nao enviado ao Google Sheets. Acesse /auth/google para autorizar."
136
- except Exception as exc:
137
- warning = (
138
- "Feedback salvo localmente, mas nao enviado ao Google Sheets. "
139
- f"Erro de sincronizacao: {exc}"
140
- )
141
-
142
- if rating is not None and rating <= 2:
143
- salvar_memoria_negativa(
144
- query=query,
145
- product_id=product_id,
146
- product_name=product_name,
147
- rating=rating,
148
- motivo="rating_baixo",
149
- )
150
-
151
- if is_helpful is False:
152
- salvar_memoria_negativa(
153
- query=query,
154
- product_id=product_id,
155
- product_name=product_name,
156
- rating=rating if rating is not None else "",
157
- motivo="nao_foi_util",
158
- )
159
-
160
- response = {
161
- "ok": True,
162
- "saved_local": True,
163
- "saved_google_sheets": saved_google_sheets,
164
- }
165
- if warning:
166
- response["warning"] = warning
167
- return response
168
-
169
-
170
- def caminho_feedback():
171
- return FEEDBACK_FILE
 
1
+ import csv
2
+ import os
3
+ import tempfile
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+
7
+ from .google_oauth import GoogleAuthRequiredError, append_feedback_to_sheet, load_credentials
8
+ from .memory import salvar_memoria_negativa
9
+
10
+
11
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
12
+ DEFAULT_LOGS_DIR = Path(os.getenv("LOGS_DIR", "/data/logs"))
13
+ FALLBACK_LOGS_DIR = Path(tempfile.gettempdir()) / "tcc2_agent" / "logs"
14
+ FEEDBACK_HEADERS = [
15
+ "timestamp",
16
+ "query",
17
+ "product_id",
18
+ "product_name",
19
+ "rating",
20
+ "is_helpful",
21
+ "note",
22
+ "categoria_inferida",
23
+ "feedback",
24
+ "motivo",
25
+ "score_final",
26
+ "score_semantico",
27
+ "bonus_lexical",
28
+ "penalidade_feedback",
29
+ "user_message",
30
+ ]
31
+
32
+
33
+ def _resolve_logs_dir():
34
+ preferred_dir = os.environ.get("LOGS_DIR", "").strip()
35
+ candidates = [Path(preferred_dir)] if preferred_dir else []
36
+ candidates.extend([DEFAULT_LOGS_DIR, FALLBACK_LOGS_DIR])
37
+
38
+ for directory in candidates:
39
+ try:
40
+ directory.mkdir(parents=True, exist_ok=True)
41
+ return directory
42
+ except OSError:
43
+ continue
44
+
45
+ raise OSError(
46
+ "Nao foi possivel criar um diretorio para armazenar os logs de feedback. "
47
+ "Defina LOGS_DIR para um caminho gravavel."
48
+ )
49
+
50
+
51
+ def caminho_feedback():
52
+ return str(_resolve_logs_dir() / "feedback.csv")
53
+
54
+
55
+ def inicializar_arquivo_feedback():
56
+ feedback_file = caminho_feedback()
57
+
58
+ if not os.path.exists(feedback_file):
59
+ with open(feedback_file, mode="w", newline="", encoding="utf-8") as f:
60
+ writer = csv.writer(f)
61
+ writer.writerow(FEEDBACK_HEADERS)
62
+
63
+
64
+ def google_sheets_habilitado():
65
+ try:
66
+ return load_credentials() is not None and bool(os.getenv("GOOGLE_SPREADSHEET_ID", "").strip())
67
+ except Exception:
68
+ return False
69
+
70
+
71
+ def _append_feedback_csv(row):
72
+ inicializar_arquivo_feedback()
73
+ feedback_file = caminho_feedback()
74
+
75
+ with open(feedback_file, mode="a", newline="", encoding="utf-8") as f:
76
+ writer = csv.writer(f)
77
+ writer.writerow([row.get(header, "") for header in FEEDBACK_HEADERS])
78
+
79
+
80
+ def _build_feedback_payload(
81
+ query,
82
+ product_id,
83
+ product_name,
84
+ rating=None,
85
+ is_helpful=None,
86
+ note=None,
87
+ categoria_inferida=None,
88
+ feedback=None,
89
+ motivo=None,
90
+ score_final=None,
91
+ score_semantico=None,
92
+ bonus_lexical=None,
93
+ penalidade_feedback=None,
94
+ user_message=None,
95
+ ):
96
+ return {
97
+ "timestamp": datetime.now(timezone.utc).isoformat(),
98
+ "query": query,
99
+ "product_id": product_id,
100
+ "product_name": product_name,
101
+ "rating": rating if rating is not None else "",
102
+ "is_helpful": is_helpful if is_helpful is not None else "",
103
+ "note": note or "",
104
+ "categoria_inferida": categoria_inferida or "",
105
+ "feedback": feedback or "",
106
+ "motivo": motivo or "",
107
+ "score_final": score_final if score_final is not None else "",
108
+ "score_semantico": score_semantico if score_semantico is not None else "",
109
+ "bonus_lexical": bonus_lexical if bonus_lexical is not None else "",
110
+ "penalidade_feedback": penalidade_feedback if penalidade_feedback is not None else "",
111
+ "user_message": user_message or "",
112
+ }
113
+
114
+
115
+ def salvar_feedback(
116
+ query,
117
+ product_id,
118
+ product_name,
119
+ rating=None,
120
+ is_helpful=None,
121
+ note=None,
122
+ categoria_inferida=None,
123
+ feedback=None,
124
+ motivo=None,
125
+ score_final=None,
126
+ score_semantico=None,
127
+ bonus_lexical=None,
128
+ penalidade_feedback=None,
129
+ user_message=None,
130
+ ):
131
+ row = _build_feedback_payload(
132
+ query=query,
133
+ product_id=product_id,
134
+ product_name=product_name,
135
+ rating=rating,
136
+ is_helpful=is_helpful,
137
+ note=note,
138
+ categoria_inferida=categoria_inferida,
139
+ feedback=feedback,
140
+