Skip to content

Instantly share code, notes, and snippets.

@zolople

zolople/BoinColaBHG.py

Last active Aug 16, 2020
Embed
What would you like to do?
Boinc en Google Colab con conexión a Google Drive
#@title ver/ocultar codigo
# ---------------------------------------------------------------------
App1= "BoinColaBHG v.20.08.16.014"
App2= "Globularia alypum"
Separador="--------------------------------------------------------------------"
#
# Autor: Bartomeu Homar Graxell
# Web: http://www.zolople.com
# Web descarga: https://gist.github.com/zolople/c96d9759d2b10c0ed126dd0a61901e2d
# Licencia: Atribución-NoComercial-CompartirIgual 4.0 Internacional
# https://creativecommons.org/licenses/by-nc-sa/4.0/deed.es
#
# ---------------------------------------------------------------------
# ** C O N F I G U R A C I O N **
# ---------------------------------------------------------------------
Servidor = 'U01'
# Cambiar el nombre del servidor en cada maquina virtual (por ejemplo, U01,
# U02, U03, U04 y U05)
Idioma = 'es' # idiomas posibles: 'ca', 'es', 'en'
Altura = 500 # altura del panel de salida de información
Proyectos={'URLs':['https://boinc.ibercivis.es/ibercivis/',
'http://www.worldcommunitygrid.org',
'https://www.gpugrid.net/',
'http://einstein.phys.uwm.edu/',
'https://boinc.bakerlab.org/rosetta/'],
'AUTH':['clave_ibercivis',
'clave_wcg',
'clave_gpugrid',
'clave_einstein',
'clave_rosetta'],
'PATH':['boinc.ibercivis.es_ibercivis',
'www.worldcommunitygrid.org',
'www.gpugrid.net',
'einstein.phys.uwm.edu',
'boinc.bakerlab.org_rosetta'],
'NOMs':['Ibercivis',
'WCG',
'Gpugrid',
'EinsteinAtHome',
'Rosetta']}
# La clave 'AUTH' se obtiene del campo 'authenticator' en
# account_boinc.ibercivis.es_ibercivis.xml y similares. El Path es el nombre
# de carpeta que crea BOINC al dar de alta el proyecto. Para un nuevo
# proyecto, si no se sabe cual es el nombre de carpeta, se puede poner
# cualquier cosa, por ejemplo 'nolose' y, una vez el programa cree dicha
# carpeta, cambiarlo aqui para que no intente volver a dar de alta el
# proyecto.
# * FIN DE LA CONFIGURACIÓN *
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# I N F O R M A C I Ó N I M P O R T A N T E :
# ------------------------------------------------------------------------------
#
# - Google Colab, actualmente está limitado a usar hasta 5 máquinas virtuales,
# con un límite de 12h. Una vez llegado a ese limite, si perdemos la conexión
# con una máquina virtual, no nos dejará reconectar hasta pasadas esas 12h,
# si bien, a veces, puede dar error hasta pasadas 24h o, al menos, hasta
# pasadas unas horas desde que acabó la última máquina virtual conectada en
# la cuenta. El uso de GPU está aún más restringido.
#
# - No intente vincular dos cuentas distintas de google, compartiendo la
# carpeta Boinc. Las carpetas compartidas en Google funcionan 'raras', solo
# conseguirá llenar de archivos compartidos el directorio principal de ambas
# cuentas.
#
# - Para no tener que generar una clave de autorización para Google Drive cada
# vez que nos conectemos, basta con: a la izquierda del cuaderno, desplegar
# la carpeta de archivos y luego en el tercer ícono "Activar Drive".
# A partir de este momento, cada vez que conectemos el cuaderno a una sesión,
# automáticamente nos conectará con Drive.
#
# - Tal como Boinc va funcionando, va borrando los archivos que de tareas
# acabadas. Google Drive mantiene los archivos borrados en la papelera de
# reciclaje y eso hace que nos vayamos quedando sin espacio disponible.
# Si de algún proyecto vemos que no se descargan tareas a pesar de haber
# disponibles, hay que vigilar que no esté dando error de falta de espacio.
# El programa está preparado para avisar al llegar al 66% de espacio ocupado,
# para que vayamos a vaciar la papelera.
# ------------------------------------------------------------------------------
# L I B R E R I A
# ------------------------------------------------------------------------------
from IPython.display import HTML
#-------------------------------
# FUNCION: Linea_ValorY
#-------------------------------
def Linea_ValorY(X=50, X0=0, Y0=0, X1=100, Y1=100, MaxMin=True):
"""Función Linea_ValorY(X=50, X0=0, Y0=0, X1=100, Y1=100, MaxMin=True).
Calcula el valor Y para un X dado, dentro de la linea que une los puntos
(X0,Y0) y (X1,Y1).
Si MaxMin=true, Y nunca podrá salir de los valores [Y0..Y1]
"""
m = (Y1-Y0)/(X1-X0) # Pendiente
b = Y0-m*X0 # intersección
Y = m*X+b
if MaxMin: #aplica márgenes de forma que siempre {Y in [Y0..Y1]}
MaxY = max(Y0, Y1)
MinY = min(Y0, Y1)
Y = max(Y, MinY)
Y = min(Y, MaxY)
return Y
#-------------------------------
# FUNCION: titulo
#-------------------------------
def titulo(texto="", alineacion="center"):
"""Función titulo(texto="", alineacion="center").
Muestra un título de nivel 3 en formato HTML.
texto: titulo a mostrar
alineacion: tipo de alineación deseada (left, center, right, justify)
"""
display(HTML('<h3 style="text-align:'+alineacion+'">'+texto+'</h3>'))
#-------------------------------
# FUNCION: progreso
#-------------------------------
def progreso(Cuenta, Pasos=100, Ancho=100, SegDesde=0, SegHasta=1):
"""Función progreso(Cuenta, Pasos=100, Ancho=100, SegHasta=1).
Muestra una barra de progreso de tiempo, posicionada en el valor "Cuenta".
Cuenta: posición del cursor de progreso
Pasos: Cantidad de divisiones de tiempo empleadas, normalmente 100
Ancho: porcentaje de anchura de la barra de progreso, normalmente 100%
SegDesde, SegHasta: segundos de inicio y final
"""
return HTML("""
{SegDesde}s
<progress
value='{Cuenta}'
max='{Pasos}',
style='width: {Ancho}%'
>
{Cuenta}
</progress> {Segundos}s / {SegHasta}s
""".format(Segundos=(SegHasta-SegDesde)*Cuenta/Pasos+SegDesde, Cuenta=Cuenta,
Pasos=Pasos, SegDesde=SegDesde, SegHasta=SegHasta, Ancho=Ancho))
#-------------------------------
# FUNCION: espera
#-------------------------------
def espera(SegDesde=0, SegHasta=1, ancho=100, TicsPorSegundo = 2,
Acumulado=False): #contador de segundos con barra de progreso
"""Función espera(SegDesde=0, SegHasta=1, ancho=100, TicsPorSegundo = 2,
Acumulado=False):
Detiene la ejecución un determinado número de segundos, mostrando una barra
de progreso.
SegDesde, SegHasta: segundos de inicio y final
Ancho: porcentaje de anchura de la barra de progreso, normalmente 100%
TicsPorSegundo: divisiones de tiempo que hace en cada segundo
Acumulado:
Si True, saca la barra empezando desde 0, pero con la posición inicial
en SegDesde.
Si False, saca la barra empezando en SegDesde
"""
Segundos = SegHasta - SegDesde
Pasos = Segundos * TicsPorSegundo
PasosPrevios = TicsPorSegundo*SegDesde
if Acumulado:
out= display(progreso(PasosPrevios, Pasos+PasosPrevios, ancho, 0, SegHasta),
display_id=True)
else:
out= display(progreso(0, Pasos, ancho, SegDesde, SegHasta), display_id=True)
for ii in range(1,Pasos+1):
time.sleep((SegHasta-SegDesde)/Pasos)
if Acumulado:
out.update(progreso(ii+PasosPrevios,Pasos+PasosPrevios,ancho,0,SegHasta))
else:
out.update(progreso(ii, Pasos, ancho, SegDesde, SegHasta))
# ------------------------------------------------------------------------------
# I N I C I L I A C I O N C O N S T A N T E S Y V A R I A B L E S
# ------------------------------------------------------------------------------
titulo(Separador)
titulo(App1)
titulo('"'+App2+'"')
titulo(Separador)
InfoInicio = {
'ca':['definint constants','Instal·lant','Preparant entorn Python',
'Muntar Google Drive?','Accedint al directori del servidor',
'Donant permisos d\'accés','Copiant els executables de Boinc',
'Aturar execucions prèvies?','Netejant el log de la darrera execució',
'Iniciant el servei','Associant els projectes','Associant a ',
'Un moment que acabi de començar...'],
'es':['Definiendo constantes','Instalando','Preparando entorno Python',
'¿Montando Google Drive?','Accediendo al directorio del servidor',
'Dando permisos de acceso','Copiando los ejecutables de Boinc',
'¿Detener ejecuciones previas?',
'Limpiando el log de la última ejecución','Iniciando el servicio',
'asociando los proyectos','Conectando a ',
'Un momento que termine de arrancar...'],
'en':['Declaring constants','Installing','Import Python functions',
'Moun Google Drive?','Accessing the server directory',
'Changing access permissions','Copying the Boinc executables',
'Stop previous executions?','Cleaning the last run log',
'Starting the service','Linking projects','Connect to ',
'Finishing starting...'],
}
titulo(InfoInicio[Idioma][0])# * Definiendo constantes *
menu = {
'ca':[
'=============================================================================',
'| 0-ATURAR | 1-LÍNIA DE COMANDES | 2-Obtenir Estat | 3-Actualitzar Projectes|',
'| 4-NO més tasques | 5-SI més tasques |',
'=============================================================================',
'Seleccionar Opció:',
'Opció Desconeguda!'],
'es':[
'=============================================================================',
'| 0-DETENER | 1-LINEA DE COMANDOS | 2-Releer Estado | 3-Refrescar Proyectos |',
'| 4-NO mas tareas | 5-SI mas tareas |',
'=============================================================================',
'Seleccionar Opción:',
'Opcion Desconocida!'],
'en':[
'=============================================================================',
'| 0-STOP | 1-COMMAND LINE | 2-Get State | 3-Update Projects | 4-no more work|',
'| 5-allow more work |',
'=============================================================================',
'Select Option:',
'Unknown Option!']
}
tabuladoTXT = {
'ca':['Missatges','Projectes','Apps','Versión Apps','Unitats','Tasques',
'estadístiques de temps'],
'es':['Mensajes','Proyectos','Apps','Version Apps','Unidades','Tareas',
'Estadisticas de tiempo'],
'en':['Messages','Projects', 'Apps', 'App versions', 'Workunits', 'Tasks',
'Time Stats']}
Estados = {'cadena':['state: upload','state: compute error','state: aborted',
'active_task_state: EXECUTING'],
'ca':['-penjar','-error','-abortat' ,'-[__%]'],
'es':['-enviar','-error','-abortado','-[__%]'],
'en':['-upload','-error','-aborted' ,'-[__%]']
}
OtrosMensajes = {'ca':{
'Papelera':'Si us plau, buideu la '+
'<a href="https://drive.google.com/drive/u/0/trash"'+
' target="_blank">paperera</a> de ',
},
'es':{
'Papelera':'Por favor, vacie la '+
'<a href="https://drive.google.com/drive/u/0/trash"'+
' target="_blank">papelera</a> de ',
},
'en':{
'Papelera':'Please, empty the '+
'<a href="https://drive.google.com/drive/u/0/trash"'+
' target="_blank">trash</a> of ',
},
}
# ------------------------------------------------------------------------------
# I M P O R T A C I O N E S
# ------------------------------------------------------------------------------
titulo(InfoInicio[Idioma][2])# * Preparando entorno Python *
import os #rutas directorios
import re #regex
import time #funciones de tiempo
from google.colab import widgets #elementos de pantalla (tabuladores...)
from google.colab import output #salida avanzada
from IPython.display import clear_output #borrar pantalla
from google.colab import drive #Google Drive
import shutil
# ------------------------------------------------------------------------------
# F U N C I O N E S
# ------------------------------------------------------------------------------
#-------------------------------
# FUNCION: EspacioGoogleDrive
#-------------------------------
def EspacioGoogleDrive():
"""EspacioGoogleDrive().
Muestra el estado de la memoria de disco en Google Drive.
Cuando el disco está muy lleno (66%), solicita que se vacie la papelera de
reciclaje.
"""
Ancho=13 # anchura en porcentaje
CambioInicio = 1/3 # Color verde en X=[0..1/3]
CambioMedio = 1/2 # Ir de verde a hacia amarillo para X =[1/3..1/2]
CambioFin = 2/3 # Ir de amarilla hacia rojo para X=[1/2..2/3]
# Color rojo en X=[2/3..1]
# ver memoria disco Google Drive
!df . -h -BM > stdoutdrive.txt
f = open('stdoutdrive.txt','r')
EspacioDisco=f.read().splitlines()
f.close()
Espacios=EspacioDisco[1][15:].split('M')
Total = float(Espacios[0])/1024
Ocupado = float(Espacios[1])/1024
X = Ocupado/Total
Rojo = int(Linea_ValorY(X, CambioInicio, 0, CambioMedio, 255))
Verde = int(Linea_ValorY(X, CambioMedio, 255, CambioFin, 0))
Color = '#' + format(Rojo*65536+Verde*256,'06x')
if (X>CambioFin):#si Google Drive está ocupado en más del 66%, vaciar papelera
Mensaje = "<b style='color:red'>"+OtrosMensajes[Idioma]['Papelera']
else:
Mensaje = "<b>"
display(HTML("""
<div style="display: block; text-align:right">
{Mensaje} Google Drive</b>: {Cuenta}%
<progress
value='{Cuenta}'
max='100',
style='background-color: {Color}; width: {Ancho}%'
>
{Cuenta}
</progress>{Ocupado}GB / {Total}GB </div>
""".format(Ocupado = '{0:.2f}'.format(Ocupado),
Total = '{0:.2f}'.format(Total),
Cuenta = int(100*Ocupado/Total),
Ancho = Ancho,
Color = Color,
Mensaje = Mensaje
)
))
#-------------------------------
# FUNCION: LogArranque
#-------------------------------
def LogArranque():
"""Función LogArranque(). Nos muestra los mensajes que va generando Boinc
hasta el momento que ya ha calculado el Benchmark de la CPU, esperando un
máximo de 1 minuto
"""
OkBenchmark = False #para comprobar si ya ha acabado el Benchmark
tespera = 0 #para esperar máximo 60s (normalmente acaba antes de 30s)
InfoCPU = ''
InfoGPU = ''
while not(OkBenchmark) and (tespera<60):
clear_output(wait=False)
# Leer información
f = open('stdoutdae.txt','r')
Mensajes=f.read().splitlines()
f.close()
salida = widgets.Grid(2,1)
# Mostrar log (mensajes) en orden inverso
Mensajestxt=''
LenMensajes= len(Mensajes)
for j in range(LenMensajes):
Mensajestxt = Mensajestxt+str(LenMensajes-j).zfill(3)+": "\
+Mensajes[LenMensajes-j-1]+'<br>'
OkBenchmark|=(Mensajes[LenMensajes-j-1].find('integer MIPS (Dhrystone)')\
>-1)
if (Mensajes[LenMensajes-j-1].find('[---] No usable GPUs found')>-1):
InfoGPU = "GPU: NO"
desde = Mensajes[LenMensajes-j-1].find('[---] OpenCL:')
if (desde>-1):
hasta = Mensajes[LenMensajes-j-1].find('(driver')
InfoGPU = "GPU: "+Mensajes[LenMensajes-j-1][desde+14:hasta]
desde = Mensajes[LenMensajes-j-1].find('[---] Processor:')
if (desde>-1):
hasta = Mensajes[LenMensajes-j-1].find('[Family')
InfoCPU = "CPU: "+Mensajes[LenMensajes-j-1][desde+17:hasta]
with salida.output_to(1, 0):
display(HTML('<div style="height: '+str(Altura)+'px;overflow: auto;">'\
+Mensajestxt+'</div>'))
with salida.output_to(0, 0):
titulo(InfoInicio[Idioma][12]) # Un momento que termine de arrancar...
espera(tespera, tespera+10, tespera+10, 2, True)
tespera +=10
return InfoCPU, InfoGPU
#-------------------------------
# FUNCION: SalidaDatos
#-------------------------------
def SalidaDatos(Altura = 500, InfoCPU = '', InfoGPU = ''):
"""Función SalidaDatos(Altura = 500, InfoCPU = '', InfoGPU = '').
Nos muestra la información del programa, con un encabezado y un panel con
pestañas informativas.
Altura: Altura en pixeles del panel informativo
InfoCPU, InfoGPU: Información relativa a dichos componentes, obtenida
durante el arranque
"""
clear_output(wait=False)
# LEER LOG PROGRAMA
f = open('stdoutdae.txt','r')
Mensajes=f.read().splitlines()
f.close()
# PEDIR ESTADO PROGRAMA
!boinccmd --get_state > stdoutstate.txt
f = open('stdoutstate.txt','r')
Estado = f.read().split("======== ")
f.close()
# PROCESAR INFORMACION
for i in range(len(Estado)):
if Estado[i].startswith("Projects ========"):
# Procesar proyectos, separándolos para mostrar en pestañas
LogProyectos=re.split('[0-9]+\) -----------\n',Estado[i])
del LogProyectos[0]
ProyectosNombre=[]
for j in range(len(LogProyectos)):
ProyectosNombre.append(LogProyectos[j][9:LogProyectos[j].index("\n")])
elif Estado[i].startswith("Tasks ========"):
# Procesar tareas, separándolas para mostrar en pestañas
LogTareas=re.split('[0-9]+\) -----------\n',Estado[i])
del LogTareas[0]
TareasNombre=[]
for j in range(len(LogTareas)):
NombreTarea = str(j+1).zfill(3)+':'
for k in range(len(Proyectos['URLs'])):
if (LogTareas[j].find(Proyectos['URLs'][k]) != -1):
NombreTarea = NombreTarea + Proyectos['NOMs'][k]
for k in range(len(Estados['cadena'])):
if (LogTareas[j].find(Estados['cadena'][k]) != -1):
if (k==3):
Porcentajetarea=''
DondePorcentaje=LogTareas[j].find('fraction done: ')
if (DondePorcentaje != -1):
Porcentajetarea =int(round(float(LogTareas[j]\
[DondePorcentaje+15:\
DondePorcentaje+19])*100))
NombreTarea = NombreTarea + '-['+str(Porcentajetarea)+'%]'
else:
NombreTarea = NombreTarea + Estados[Idioma][k]
TareasNombre.append(NombreTarea)
# MOSTRAR CABECERA
clear_output(wait=False)
display(HTML('<div style="float:left">'+InfoCPU+'<br>'+InfoGPU+'</div>'))
titulo(App1+' "'+App2+'"', "right")
EspacioGoogleDrive()
# MOSTRAR DATOS EN PESTAÑAS
Tabulado = widgets.TabBar(tabuladoTXT[Idioma],location='top')
for i in range(len(Estado)):
with Tabulado.output_to(i,select=(i==5)):
if i==0:
# Mostrar log (mensajes) en orden inverso
Mensajestxt=''
LenMensajes= len(Mensajes)
for j in range(LenMensajes):
Mensajestxt = Mensajestxt+str(LenMensajes-j).zfill(3)+": "\
+Mensajes[LenMensajes-j-1]+'<br>'
display(HTML('<div style="height: '+str(Altura)+'px;overflow: auto;">'\
+Mensajestxt+'</div>'))
elif i==1:
# Mostrar proyectos, separados en pestañas horizontales
TabProyectos = widgets.TabBar(ProyectosNombre,location='top')
for j in range(len(LogProyectos)):
with TabProyectos.output_to(j,select=(j==0)):
display(HTML('<div style="height: '+str(Altura-50)\
+'px;overflow: auto;">'\
+LogProyectos[j].replace("\n", "<br>")+'</div>'))
elif i==5:
# Mostrar tareas, separadas en pestañas verticales
nTareas=len(LogTareas)
bloques=1+(nTareas-1)//17
if bloques>1:
TareasNombreBloque=[]
for Bl in range(bloques):
TareasNombreBloque.append(str(Bl*17+1)+"-"\
+str(min(nTareas,(Bl+1)*17)))
TabTareasbloque = widgets.TabBar(TareasNombreBloque,location='start')
for Bl in range(bloques):
with TabTareasbloque.output_to(Bl,select=(Bl==0)):
TabTareas = widgets.TabBar(TareasNombre[Bl*17:min((Bl+1)*17\
,nTareas)]\
,location='start')
for j in range(Bl*17,min((Bl+1)*17,nTareas)):
with TabTareas.output_to(j-Bl*17,select=(j==0)):
display(HTML('<div style="height: '+str(Altura)\
+'px;overflow: auto;">'\
+LogTareas[j].replace("\n", "<br>")+'</div>'))
else:
TabTareas = widgets.TabBar(TareasNombre,location='start')
for j in range(len(LogTareas)):
with TabTareas.output_to(j,select=(j==0)):
display(HTML('<div style="height: '+str(Altura)\
+'px;overflow: auto;">'\
+LogTareas[j].replace("\n", "<br>")+'</div>'))
else:
# mostrar resto de datos
display(HTML('<div style="height: '+str(Altura)+'px;overflow: auto;">'\
+Estado[i].replace("\n", "<br>")+'</div>'))
# ------------------------------------------------------------------------------
# P R O G R A M A P R I N C I P A L ( A R R A N Q U E )
# ------------------------------------------------------------------------------
try:
InfoCPU, InfoGPU
except:
InfoCPU = ''
InfoGPU = ''
try:
yaenmarcha
except:
yaenmarcha = False
if yaenmarcha==False:
titulo(InfoInicio[Idioma][1])# * Instalando *
!apt-get update
!apt-get install boinc boinc-client
titulo(InfoInicio[Idioma][3])# * ¿Montando Google Drive? *
# Google Drive no es necesario enlazarlo aqui si enlazamos directamente el
# cuaderno, lo que nos ahorrará tener que entrar con una clave de autorización
# cada vez que ejecutemos el cuaderno.
if not os.path.exists('/content/drive/My Drive'):
drive.mount('/content/drive')
titulo(InfoInicio[Idioma][4])# *Accediendo al directorio del servidor*
os.chdir('/content/drive/My Drive')
if not os.path.exists('Boinc/'+Servidor):
os.makedirs('Boinc/'+Servidor)
os.chdir('Boinc/'+Servidor)
DirDatos=repr(os.getcwd())
print(DirDatos)
titulo(InfoInicio[Idioma][6])# * Copiando los ejecutables de Boinc *
shutil.copy('/usr/bin/boinc','.')
shutil.copy('/usr/bin/boinccmd','.')
titulo(InfoInicio[Idioma][5])# * Dando permisos *
!chmod -R 777 * # (Cada vez que conectamos a Drive, los permisos han
# desaparecido y hay que volver a darlos).
# -->ESTO DE PYTHON NO FUNCIONA BIEN!:
# for root, dirs, files in os.walk("path"):
# for d in dirs:
# os.chmod(os.path.join(root, d), 0o777)
# for f in files:
# os.chmod(os.path.join(root, f), 0o777)
titulo(InfoInicio[Idioma][7])# * Deteniendo posibles ejecuciones previas *
servicioactivo=True
while servicioactivo:
servicio = get_ipython().getoutput('boinccmd --quit').nlstr
servicioactivo = (servicio !="can't connect to local host")
if servicioactivo:
print('...')
espera(0, 10, 30, 2, False) #esperando que la detención sea efectiva
titulo(InfoInicio[Idioma][8])# * Limpiando el log de la última ejecución *
try:
os.remove('stdoutdae9.txt')
except:
pass
for i in range(9,1,-1):
try:
os.rename('stdoutdae'+str(i-1)+'.txt', 'stdoutdae'+str(i)+'.txt')
except:
pass
try:
os.rename('stdoutdae.txt', 'stdoutdae1.txt')
except:
pass
titulo(InfoInicio[Idioma][9])# * Iniciando el servicio *
!boinc --daemon --redirectio --run_cpu_benchmarks --start_delay 30 \
--dir $DirDatos
titulo(InfoInicio[Idioma][10])# * asociando los proyectos *
if not os.path.exists('projects'):
os.makedirs('projects')
for i in range(len(Proyectos['URLs'])):
ProyectoURL = repr(Proyectos['URLs'][i])
ProyectoAUTH = repr(Proyectos['AUTH'][i])
ProyectoPATH = 'projects/'+Proyectos['PATH'][i]
if not os.path.exists(ProyectoPATH):
espera(0, 10, 30, 2, False)
print(InfoInicio[Idioma][11]+Proyectos['URLs'][i])
!boinccmd --project_attach $ProyectoURL $ProyectoAUTH
titulo(InfoInicio[Idioma][12])# * Un momento que termine de arrancar... *
while not os.path.exists('stdoutdae.txt'):
espera(0, 10, 30, 2, False)
InfoCPU, InfoGPU = LogArranque()
clear_output(wait=False)
yaenmarcha = True
# ------------------------------------------------------------------------------
# P R O G R A M A P R I N C I P A L ( M E N Ú )
# ------------------------------------------------------------------------------
while True:
SalidaDatos(Altura, InfoCPU, InfoGPU)
for i in range(len(menu[Idioma])-2):
print(menu[Idioma][i])
selection=input(menu[Idioma][len(menu[Idioma])-2])
if selection =='0':
!boinccmd --quit
yaenmarcha = False
break
elif selection =='1':
break
elif selection == '2':
pass
elif selection == '3':
clear_output(wait=True)
for i in range(len(Proyectos['URLs'])):
ProyectoURL = repr(Proyectos['URLs'][i])
ProyectoAUTH = repr(Proyectos['AUTH'][i])
!boinccmd --project $ProyectoURL update
espera(0, 10, 30, 2, False)
elif selection == '4':
for i in range(len(Proyectos['URLs'])):
ProyectoURL = repr(Proyectos['URLs'][i])
!boinccmd --project $ProyectoURL nomorework
elif selection == '5':
for i in range(len(Proyectos['URLs'])):
ProyectoURL = repr(Proyectos['URLs'][i])
!boinccmd --project $ProyectoURL allowmorework
else:
titulo(menu[Idioma][len(menu[Idioma])-1])
espera(0, 3, 30, 2, False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.