Skip to content

Instantly share code, notes, and snippets.

@oscarnovasf
Created September 26, 2025 15:24
Show Gist options
  • Select an option

  • Save oscarnovasf/e2d663b9de989c086447e752ce8c9c91 to your computer and use it in GitHub Desktop.

Select an option

Save oscarnovasf/e2d663b9de989c086447e752ce8c9c91 to your computer and use it in GitHub Desktop.
OBS. Actualizar escena (título y body) con el contenido de una issue de Drupal.org (Drupaladas)
import requests
import obspython as obs
from bs4 import BeautifulSoup
import re
# Variables globales
issue_id = ""
title_source_name = ""
body_source_name = ""
def update_drupal_issue():
global issue_id
global title_source_name
global body_source_name
if not issue_id:
obs.script_log(obs.LOG_WARNING, "Issue ID no especificado")
return
# Construir la URL de la issue de Drupal
url = f"https://www.drupal.org/project/drupaladas/issues/{issue_id}"
try:
# Headers para simular un navegador real y evitar el error 403
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
}
# Realizar la solicitud HTTP con headers
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
# Parsear el HTML
soup = BeautifulSoup(response.content, 'html.parser')
# Extraer el título (eliminar la parte después del pipe)
title_element = soup.find('title')
if title_element:
full_title = title_element.get_text().strip()
# Eliminar la parte después del pipe
title = full_title.split('|')[0].strip()
else:
title = "Título no encontrado"
# Extraer el contenido del body
body_element = soup.find('div', class_=['field-name-body', 'field-type-text-with-summary'])
if body_element:
# Buscar el elemento h3 con "TODOs" y eliminar todo desde ahí
todos_header = body_element.find('h3', string=re.compile(r'TODOs?', re.IGNORECASE))
if todos_header:
# Eliminar el h3 y todo lo que viene después
current = todos_header
while current:
next_sibling = current.next_sibling
current.decompose()
current = next_sibling
# Obtener el texto limpio del body
body_content = body_element.get_text().strip()
# Limpiar espacios en blanco excesivos
body_content = re.sub(r'\n\s*\n', '\n\n', body_content)
else:
body_content = "Contenido no encontrado"
# Actualizar la fuente de texto del título
if title_source_name:
title_source = obs.obs_get_source_by_name(title_source_name)
if title_source is not None:
settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", title)
obs.obs_source_update(title_source, settings)
obs.obs_data_release(settings)
obs.obs_source_release(title_source)
# Actualizar la fuente de texto del body
if body_source_name:
body_source = obs.obs_get_source_by_name(body_source_name)
if body_source is not None:
settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", body_content)
obs.obs_source_update(body_source, settings)
obs.obs_data_release(settings)
obs.obs_source_release(body_source)
obs.script_log(obs.LOG_INFO, f"Issue actualizada: {title}")
else:
obs.script_log(obs.LOG_WARNING, f"Error al acceder a la URL: {response.status_code}")
except Exception as e:
obs.script_log(obs.LOG_WARNING, f"Error al procesar la issue: {str(e)}")
def refresh_pressed(props, prop):
update_drupal_issue()
# ------------------------------------------------------------
def script_description():
return "Extrae título y contenido de issues de Drupal.org.\n\nPor ONovasDev"
def script_update(settings):
global issue_id
global title_source_name
global body_source_name
issue_id = obs.obs_data_get_string(settings, "issue_id")
title_source_name = obs.obs_data_get_string(settings, "title_source")
body_source_name = obs.obs_data_get_string(settings, "body_source")
def script_defaults(settings):
obs.obs_data_set_default_string(settings, "issue_id", "3532728")
def script_properties():
props = obs.obs_properties_create()
obs.obs_properties_add_text(props, "issue_id", "Issue ID de Drupal", obs.OBS_TEXT_DEFAULT)
# Lista de fuentes para el título
p_title = obs.obs_properties_add_list(props, "title_source", "Fuente de Texto - Título", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
# Lista de fuentes para el body
p_body = obs.obs_properties_add_list(props, "body_source", "Fuente de Texto - Contenido", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
sources = obs.obs_enum_sources()
if sources is not None:
for source in sources:
source_id = obs.obs_source_get_unversioned_id(source)
if source_id == "text_gdiplus" or source_id == "text_ft2_source":
name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p_title, name, name)
obs.obs_property_list_add_string(p_body, name, name)
obs.source_list_release(sources)
obs.obs_properties_add_button(props, "button", "Actualizar", refresh_pressed)
return props
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment