Script parrafos_dinamicos_forma_pago.py ajustado para cuenta de servicio.

This commit is contained in:
mabejoyb
2026-05-13 11:33:58 -03:00
parent 7ffc9a74e8
commit 79a61bbc92

View File

@@ -9,23 +9,41 @@ import unicodedata
import datetime as dt import datetime as dt
from decimal import Decimal, InvalidOperation from decimal import Decimal, InvalidOperation
def _rb_set_early(name, value):
try:
SetVar(name, value)
except Exception:
pass
# -------------------- # --------------------
# Boot libs (Rocketbot portable) # Boot libs (Rocketbot portable)
# -------------------- # --------------------
base_dir = os.path.dirname(sys.executable) _rb_set_early("gdoc_textos_status", "BOOTING")
libs_dir = os.path.join(base_dir, "py_libs", "py310")
sys.path.insert(0, libs_dir)
for k in list(sys.modules.keys()): try:
if k == "pyparsing" or k.startswith("pyparsing."): base_dir = os.path.dirname(sys.executable)
del sys.modules[k] libs_candidates = [
os.path.join(base_dir, "py_libs", "py310"),
os.path.join(base_dir, "librerias", "py_libs", "py310"),
os.path.join(os.getcwd(), "librerias", "py_libs", "py310"),
]
for libs_dir in libs_candidates:
if os.path.isdir(libs_dir) and libs_dir not in sys.path:
sys.path.insert(0, libs_dir)
from googleapiclient.discovery import build for k in list(sys.modules.keys()):
from googleapiclient.errors import HttpError if k == "pyparsing" or k.startswith("pyparsing."):
from google.oauth2 import service_account del sys.modules[k]
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build
from google.auth.transport.requests import Request as GRequest from googleapiclient.errors import HttpError
from google.oauth2 import service_account
except Exception as e:
_rb_set_early("gdoc_textos_status", "ERROR")
_rb_set_early("gdoc_textos_error", "BOOT_IMPORT: " + repr(e))
print("BOOT_IMPORT error:", repr(e))
raise
# ----------------------------------------------------------- # -----------------------------------------------------------
@@ -474,46 +492,70 @@ def _build_refuerzos_post_paragraphs(refuerzos_post, sep_line="-----------------
# ----------------------------------------------------------- # -----------------------------------------------------------
# GOOGLE AUTH # GOOGLE AUTH
# ----------------------------------------------------------- # -----------------------------------------------------------
SCOPES = {scopes_api_google} def _resolve_google_scopes():
default_scopes = [
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/drive",
]
try:
raw = scopes_api_google
except NameError:
raw = _gv("scopes_api_google", None)
if _missing(raw):
return default_scopes
if isinstance(raw, (list, tuple, set)):
scopes = [str(x).strip() for x in raw if str(x).strip()]
return scopes or default_scopes
s = str(raw).strip()
if not s:
return default_scopes
try:
parsed = json.loads(s)
except Exception:
try:
parsed = ast.literal_eval(s)
except Exception:
parsed = None
if isinstance(parsed, (list, tuple, set)):
scopes = [str(x).strip() for x in parsed if str(x).strip()]
return scopes or default_scopes
if "," in s:
scopes = [x.strip().strip("'\"") for x in s.split(",") if x.strip()]
return scopes or default_scopes
return [s.strip("'\"")]
SCOPES = _resolve_google_scopes()
def _load_json(path): def _load_json(path):
with open(path, "r", encoding="utf-8") as f: with open(path, "r", encoding="utf-8") as f:
return json.load(f) return json.load(f)
def get_services(credentials_json_path, token_json_path): def get_services(credentials_json_path, impersonated_user):
info = _load_json(credentials_json_path) info = _load_json(credentials_json_path)
if not isinstance(info, dict) or info.get("type") != "service_account":
raise RuntimeError("gdoc_sa_json2 debe apuntar a un JSON de cuenta de servicio.")
if isinstance(info, dict) and info.get("type") == "service_account": impersonated_user = (impersonated_user or "").strip()
creds = service_account.Credentials.from_service_account_file( if not impersonated_user:
credentials_json_path, raise RuntimeError("Falta la variable gdoc_impersonated_user.")
scopes=SCOPES
)
docs = build("docs", "v1", credentials=creds, cache_discovery=False)
drive = build("drive", "v3", credentials=creds, cache_discovery=False)
return docs, drive, "service_account"
creds = None
if os.path.exists(token_json_path):
creds = Credentials.from_authorized_user_file(token_json_path, SCOPES)
if (not creds) or (not creds.valid):
if creds and creds.expired and creds.refresh_token:
creds.refresh(GRequest())
else:
flow = InstalledAppFlow.from_client_secrets_file(credentials_json_path, SCOPES)
try:
creds = flow.run_local_server(port=0)
except Exception:
creds = flow.run_console()
os.makedirs(os.path.dirname(token_json_path), exist_ok=True)
with open(token_json_path, "w", encoding="utf-8") as f:
f.write(creds.to_json())
creds = service_account.Credentials.from_service_account_file(
credentials_json_path,
scopes=SCOPES,
subject=impersonated_user,
)
docs = build("docs", "v1", credentials=creds, cache_discovery=False) docs = build("docs", "v1", credentials=creds, cache_discovery=False)
drive = build("drive", "v3", credentials=creds, cache_discovery=False) drive = build("drive", "v3", credentials=creds, cache_discovery=False)
return docs, drive, "oauth" return docs, drive, "service_account_impersonated"
# ----------------------------------------------------------- # -----------------------------------------------------------
# DRIVE / DOC HELPERS # DRIVE / DOC HELPERS
@@ -892,6 +934,10 @@ globals().update(locals())
# MAIN # MAIN
# ----------------------------------------------------------- # -----------------------------------------------------------
try: try:
_sv("gdoc_textos_status", "STARTED")
_sv("gdoc_textos_error", "")
print("parrafos_dinamicos_forma_pago.py STARTED")
NL = "\n" NL = "\n"
# usar SOLO current_url # usar SOLO current_url
@@ -909,23 +955,20 @@ try:
_sv("gdoc_original_id", raw_id) _sv("gdoc_original_id", raw_id)
cred_path = _gvs("gdoc_sa_json", "") cred_path = _gvs("gdoc_sa_json2", "")
if cred_path == "": if cred_path == "":
raise RuntimeError("Falta la variable gdoc_sa_json.") raise RuntimeError("Falta la variable gdoc_sa_json2.")
if not os.path.isabs(cred_path): if not os.path.isabs(cred_path):
cred_path = os.path.join(base_dir, cred_path) cred_path = os.path.join(base_dir, cred_path)
if not os.path.exists(cred_path): if not os.path.exists(cred_path):
raise RuntimeError("No existe credentials.json: " + cred_path) raise RuntimeError("No existe JSON de cuenta de servicio: " + cred_path)
token_path = _gvs("gdoc_token_json", "") impersonated_user = _gvs("gdoc_impersonated_user", "")
if token_path == "":
token_path = os.path.join(base_dir, "credentials", "token_gdocs_drive.json")
if not os.path.isabs(token_path):
token_path = os.path.join(base_dir, token_path)
docs_service, drive_service, auth_mode = get_services(cred_path, token_path) docs_service, drive_service, auth_mode = get_services(cred_path, impersonated_user)
_sv("gdoc_impersonated_user_used", impersonated_user)
_sv("gdoc_auth_mode", auth_mode) _sv("gdoc_auth_mode", auth_mode)
doc_id, meta_file, converted = ensure_docs_api_compatible(drive_service, raw_id) doc_id, meta_file, converted = ensure_docs_api_compatible(drive_service, raw_id)
@@ -1790,9 +1833,12 @@ try:
except HttpError as e: except HttpError as e:
_sv("gdoc_textos_status", "ERROR") _sv("gdoc_textos_status", "ERROR")
_sv("gdoc_textos_error", "HttpError: " + str(e)) _sv("gdoc_textos_error", "HttpError: " + str(e))
_sv("gdoc_textos_traceback", "HttpError: " + str(e))
raise raise
except Exception as e: except Exception as e:
import traceback
_sv("gdoc_textos_status", "ERROR") _sv("gdoc_textos_status", "ERROR")
_sv("gdoc_textos_error", str(e)) _sv("gdoc_textos_error", str(e))
_sv("gdoc_textos_traceback", traceback.format_exc())
raise raise