-
-
Save ElGuillermo/6b2588ef05a64809e3d5e4525b4e17f1 to your computer and use it in GitHub Desktop.
#@title Menu "Affichage" -> "Afficher/masquer le code" | |
# ----------------------------------------------------------------- | |
App1 = "BoinColaBHG++ for AF" | |
App2 = "v.22.02.05.wip (see inner code for details)" | |
Separator = "-----------------------------------------------------------------" | |
# By : https://github.com/ElGuillermo | |
# Based on : BoinColaBHG v.21.02.26.015 "Ononis minutissima" | |
# Author : Bartomeu Homar Graxell | |
# Web : http://www.zolople.com | |
# Download : https://gist.github.com/zolople/c96d9759d2b10c0ed126dd0a61901e2d | |
# Licence : Attribution-NonCommercial-ShareAlike 4.0 International | |
# https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en | |
# ----------------------------------------------------------------------------- | |
# Configuration | |
# ----------------------------------------------------------------------------- | |
# Change the Server's name for each Colab notebook you'll use. | |
Server = 'Colab01' | |
# Available languages : 'en', 'fr' | |
Language = 'fr' | |
# Interface height (pixels). Default : 500 | |
InterfaceHeight = 400 | |
# Project URL | |
Projects = {'URLs':['https://wuprop.boinc-af.org/', | |
'https://sech.me/boinc/Amicable/', | |
'https://rake.boincfast.ru/rakesearch/', | |
'https://boinc.progger.info/odlk/', | |
'http://boincvm.proxyma.ru:30080/test4vm/', | |
'http://gene.disi.unitn.it/test/', | |
'https://www.gpugrid.net/', | |
'https://escatter11.fullerton.edu/nfs/', | |
'http://numberfields.asu.edu/NumberFields/', | |
'https://boinc.multi-pool.info/latinsquares/', | |
'http://milkyway.cs.rpi.edu/milkyway/', | |
'https://boinc.thesonntags.com/collatz/', | |
'http://www.worldcommunitygrid.org/', | |
'http://boincvm.proxyma.ru:30080/test4vm/', | |
'http://einstein.phys.uwm.edu/' | |
], | |
# Your *personal* account keys - give access to your accounts - DO NOT SHARE ! | |
'AUTH':['xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx', | |
'xxx' | |
], | |
# Attach this project ? | |
'Attach':[True, # wuprop@home | |
False, # Amicable | |
False, # Rakeserach | |
False, # Odlk | |
False, # PrivateGFN | |
False, # TNGrid | |
False, # GPUGrid | |
False, # NFS | |
False, # NumberFields | |
False, # Odlk1 | |
False, # Milkyway | |
False, # Collatz | |
False, # World community grid | |
False, # Private GFN Server | |
True # Einstein@home | |
]} | |
# Default RPC password (leave blank if you do not intend remote controlling) | |
RPC_Password = '' | |
# Default cc_config.xml | |
# Will be stored on your Google drive (but won't overwrite any existent one) | |
# doc : https://boinc.berkeley.edu/wiki/Client_configuration | |
UserCCConfig = ("<cc_config>\n\ | |
\t<log_flags>\n\ | |
\t\t<task>0</task>\n\ | |
\t\t<file_xfer>0</file_xfer>\n\ | |
\t\t<sched_ops>1</sched_ops>\n\ | |
\t\t<rr_simulation>0</rr_simulation>\n\ | |
\t\t<unparsed_xml>1</unparsed_xml>\n\ | |
\t</log_flags>\n\ | |
\t<options>\n\ | |
\t\t<abort_jobs_on_exit>0</abort_jobs_on_exit>\n\ | |
\t\t<allow_multiple_clients>0</allow_multiple_clients>\n\ | |
\t\t<max_file_xfers_per_project>20</max_file_xfers_per_project>\n\ | |
\t\t<max_file_xfers>30</max_file_xfers>\n\ | |
\t\t<max_tasks_reported>1000</max_tasks_reported>\n\ | |
\t\t<ncpus>-1</ncpus>\n\ | |
\t\t<process_priority>5</process_priority>\n\ | |
\t\t<process_priority_special>5</process_priority_special>\n\ | |
\t\t<report_results_immediately>1</report_results_immediately>\n\ | |
\t\t<use_all_gpus>1</use_all_gpus>\n\ | |
\t</options>\n\ | |
</cc_config>") | |
# Default global_prefs_override.xml | |
# Will be stored on your Google drive (but won't overwrite any existent one) | |
# doc : https://boinc.berkeley.edu/wiki/Global_prefs_override.xml | |
UserGlobalPrefsOverride = ("<global_preferences>\n\ | |
\t<cpu_scheduling_period_minutes>5.000000</cpu_scheduling_period_minutes>\n\ | |
\t<cpu_usage_limit>100</cpu_usage_limit>\n\ | |
\t<disk_max_used_pct>95</disk_max_used_pct>\n\ | |
\t<ram_max_used_busy_pct>95</ram_max_used_busy_pct>\n\ | |
\t<ram_max_used_idle_pct>95</ram_max_used_idle_pct>\n\ | |
\t<run_if_user_active/>\n\ | |
\t<run_on_batteries/>\n\ | |
\t<suspend_cpu_usage>100</suspend_cpu_usage>\n\ | |
\t<vm_max_used_pct>95</vm_max_used_pct>\n\ | |
\t<work_buf_min_days>0.02</work_buf_min_days>\n\ | |
\t<work_buf_additional_days>0</work_buf_additional_days>\n\ | |
</global_preferences>") | |
# Configuration : end | |
# ----------------------------------------------------------------------------- | |
# Information FR | |
# ----------------------------------------------------------------------------- | |
# | |
# - N'essayez pas d'utiliser deux comptes Google différents | |
# sur le même Google Drive : les drives liés aux deux comptes seraient | |
# utilisés et leurs fichiers partagés entre les comptes. | |
# | |
# - Pour éviter d'avoir à confirmer l'accès à Google Drive | |
# lors de chaque démarrage : cliquez sur l'icône "Activer Drive" | |
# dans le volet de gauche, dans la partie "dossiers". | |
# | |
# - Lors de l'ajout d'un projet, il est recommandé d'arrêter le notebook | |
# (option 0) et de le redémarrer. Ceci est nécessaire pour accorder la | |
# permission de s'exécuter aux nouveaux programmes. | |
# | |
# - Les UTs terminées et renvoyées sont supprimées de Google Drive. | |
# Elles sont envoyées dans la corbeille, dont le volume compte | |
# pour le quota. Si un projet semble ne plus télécharger d'UTs, | |
# vérifiez qu'il reste de l'espace disque disponible sur Google Drive. | |
# Le script vous alertera lorsque 66% d'espace disque seront occupés, | |
# afin que vous vidiez la corbeille. | |
# Notez que le vidage peut prendre un certain temps. | |
# ----------------------------------------------------------------------------- | |
# Python libraries import | |
# ----------------------------------------------------------------------------- | |
import os | |
import re | |
import time | |
import shutil | |
from google.colab import widgets | |
from google.colab import output | |
from google.colab import drive | |
from IPython.display import clear_output | |
from IPython.display import HTML | |
from IPython import get_ipython | |
import ipywidgets | |
# ----------------------------------------------------------------------------- | |
# Constants | |
# ----------------------------------------------------------------------------- | |
InitialInfo = { | |
'en':{ | |
'Installing':'Updating Notebook, installing Boinc', | |
'KillPreviousBoinc':'Kill previous Boinc clients (if any)', | |
'LaunchBoinc':'Launch and set Boinc client', | |
'AutoAttachProjects':'Attach projects', | |
'AutoDetachProjects':'Detach projects', | |
'StartSequenceEnd':'Waiting for Boinc start sequence\'s end', | |
}, | |
'fr':{ | |
'Installing':'Mise à jour du Notebook et installation de Boinc', | |
'KillPreviousBoinc':'Arrêt des précédents clients Boinc (s\'il y en a)', | |
'LaunchBoinc':'Lancement et configuration du client Boinc', | |
'AutoAttachProjects':'Rattachement aux projets', | |
'AutoDetachProjects':'Détachement des projets', | |
'StartSequenceEnd':'Attente de la fin du démarrage de Boinc', | |
} | |
} | |
menu_buttons = { | |
'en':{ | |
'MenuBoinc':'Boinc Client', | |
'MenuProjects':'Projects', | |
'MenuTasks':'Tasks', | |
'MenuSystem':'System infos', | |
'SubBoinc_messages':'Messages', | |
'SubBoinc_getccstatus':'CPU/GPU/Net usage policies', | |
'SubBoinc_filetransfers':'File transfers', | |
'SubBoinc_timestats':'Time stats', | |
'SubBoinc_readcfg':'Re-read cfg', | |
'SubBoinc_quit':'Stop Boinc', | |
'SubBoinc_start':'Start Boinc', | |
'SubProjects_attached':'Attached', | |
'SubProjects_apps':'Apps', | |
'SubProjects_appversions':'Apps versions', | |
'SubProjects_workunits':'Workunits', | |
'SubProjects_updateall':'Update all projects', | |
'SubProjects_operations':'Operations', | |
'SubProjects_suspend':'Suspend', | |
'SubProjects_resume':'Resume', | |
'SubProjects_nomorewus':'No more WUs', | |
'SubProjects_morewus':'Send WUs', | |
'SubProjects_update':'Update', | |
'SubProjects_reset':'Reset', | |
'SubTasks_running':'Running', | |
'SubTasks_upload':'Upload', | |
'SubTasks_error':'Error', | |
'SubTasks_aborted':'Aborted', | |
'SubSystem_hostinfo':'Boinc host_info', | |
'SubSystem_CPU':'CPU : \"top\"', | |
'SubSystem_GPU':'GPU : \"nvidia-smi\"' | |
}, | |
'fr':{ | |
'MenuBoinc':'Client Boinc', | |
'MenuProjects':'Projets', | |
'MenuTasks':'Tâches', | |
'MenuSystem':'Infos système', | |
'SubBoinc_messages':'Messages', | |
'SubBoinc_getccstatus':'Règles d\'usage CPU/GPU/Net', | |
'SubBoinc_filetransfers':'Transferts', | |
'SubBoinc_timestats':'Time stats', | |
'SubBoinc_readcfg':'Relire cfg', | |
'SubBoinc_quit':'Arrêter Boinc', | |
'SubBoinc_start':'Démarrer Boinc', | |
'SubProjects_attached':'Attachés', | |
'SubProjects_apps':'Apps', | |
'SubProjects_appversions':'Apps versions', | |
'SubProjects_workunits':'UTs', | |
'SubProjects_updateall':'Màj des projets', | |
'SubProjects_operations':'Opérations', | |
'SubProjects_suspend':'Suspendre', | |
'SubProjects_resume':'Reprendre', | |
'SubProjects_nomorewus':'Ne plus demander d\'UTs', | |
'SubProjects_morewus':'Redemander des UTs', | |
'SubProjects_update':'Mise à jour', | |
'SubProjects_reset':'Réinitialiser', | |
'SubTasks_running':'En cours', | |
'SubTasks_upload':'Envoi', | |
'SubTasks_error':'Erreur', | |
'SubTasks_aborted':'Abandonnées', | |
'SubSystem_hostinfo':'Boinc host_info', | |
'SubSystem_CPU':'CPU : \"top\"', | |
'SubSystem_GPU':'GPU : \"nvidia-smi\"' | |
} | |
} | |
WUStates = {'SearchString':['state: upload', 'state: compute error', | |
'state: aborted', 'active_task_state: EXECUTING'], | |
'en':[' [upload]', ' [error]', ' [aborted]', ' [__%]'], | |
'fr':[' [envoi]', ' [erreur]', ' [interrompu]', ' [__%]'] | |
} | |
OtherMsgs = {'en':{ | |
'TrashBin':'Please, empty the ' | |
+ '<a href="https://drive.google.com/drive/u/0/trash"' | |
+ ' target="_blank">trashbin</a> of ' | |
}, | |
'fr':{ | |
'TrashBin':'Veuillez vider la ' | |
+ '<a href="https://drive.google.com/drive/u/0/trash"' | |
+ ' target="_blank">corbeille</a> de ' | |
} | |
} | |
# ----------------------------------------------------------------------------- | |
# Functions | |
# ----------------------------------------------------------------------------- | |
#------------------------------ | |
# Function: title | |
#------------------------------ | |
def Title(text = "", alignment = "left"): | |
display(HTML( | |
'<h3 style="text-align: ' + alignment + ';">' + text + '</h3>')) | |
#------------------------------ | |
# Function: progress | |
#------------------------------ | |
def progress(Cuenta, Pasos = 100, Ancho = 100, SegDesde = 0, SegHasta = 1): | |
"""Shows a time progress bar | |
Cuenta : posición del cursor de progreso | |
Pasos : Cantidad de divisiones de tiempo empleadas, normalmente 100 | |
Ancho : pixels de anchura de la barra de progreso | |
SegDesde, SegHasta: segundos de inicio y final | |
""" | |
return HTML(""" | |
{SegDesde}s | |
<progress | |
value = '{Cuenta}' | |
max = '{Pasos}', | |
style = 'width: {Ancho}px' | |
> | |
{Cuenta} | |
</progress> {Segundos}s / {SegHasta}s | |
""".format(Segundos = (SegHasta - SegDesde) | |
* Cuenta/Pasos | |
+ SegDesde, | |
Cuenta = Cuenta, | |
Pasos = Pasos, | |
SegDesde = SegDesde, | |
SegHasta = SegHasta, | |
Ancho = Ancho)) | |
#------------------------------ | |
# Function: wait | |
#------------------------------ | |
# Wait for a given number of seconds, displaying a progress bar | |
# depends : function progress() | |
def wait(InitialSec = 0, | |
EndSec = 10, | |
BarWidthpx = 250, | |
TicksPerSec = 1, | |
Cumulate = False): | |
Segundos = EndSec - InitialSec | |
Pasos = Segundos * TicksPerSec | |
PasosPrevios = TicksPerSec * InitialSec | |
if Cumulate: | |
out = display( | |
progress( | |
PasosPrevios, | |
Pasos + PasosPrevios, | |
BarWidthpx, | |
0, | |
EndSec | |
), | |
display_id = True | |
) | |
else: | |
out = display( | |
progress( | |
0, | |
Pasos, | |
BarWidthpx, | |
InitialSec, | |
EndSec | |
), | |
display_id = True | |
) | |
for ii in range(1, Pasos + 1): | |
time.sleep((EndSec - InitialSec) / Pasos) | |
if Cumulate: | |
out.update( | |
progress( | |
ii + PasosPrevios, | |
Pasos + PasosPrevios, | |
BarWidthpx, | |
0, | |
EndSec | |
) | |
) | |
else: | |
out.update( | |
progress( | |
ii, | |
Pasos, | |
BarWidthpx, | |
InitialSec, | |
EndSec | |
) | |
) | |
#------------------------------ | |
# Function: Line_ValueY | |
#------------------------------ | |
def Line_ValueY(X = 50, X0 = 0, Y0 = 0, X1 = 100, Y1 = 100, MaxMin = True): | |
""" Appelée par la fonction GoogleDriveSpace | |
Calcule la valeur de Y selon X (X0,Y0) y (X1,Y1). | |
Si MaxMin == true, Y ne peut sortir des limites [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 | |
#------------------------------ | |
# Fonction: GoogleDriveSpace | |
#------------------------------ | |
def GoogleDriveSpace(): | |
"""GoogleDriveSpace(). | |
Affiche le taux de remplissage de Google Drive. | |
Demande que la corbeille soit vidée à partir de 66%. | |
""" | |
GD_Largeur = 100 # width px | |
GD_debut = 1/3 # green X < 0.33 | |
GD_milieu = 1/2 # yellow 0.33 < X < 0.5 | |
GD_fin = 2/3 # red 0.5 < X < 0.66 | |
# Evaluate free space on Google drive | |
!df . -h -BM > stdoutdrive.txt | |
f = open('stdoutdrive.txt','r') | |
DiskSpace = f.read().splitlines() | |
f.close() | |
Spaces = DiskSpace[1][15:].split('M') | |
Total = float(Spaces[0]) / 1024 | |
Occupied = float(Spaces[1]) / 1024 | |
X = Occupied / Total | |
# Define | |
Red = int(Line_ValueY(X, GD_debut, 0, GD_milieu, 255)) | |
Green = int(Line_ValueY(X, GD_milieu, 255, GD_fin, 0)) | |
Color = '#' + format(Red * 65536 + Green * 256, '06x') | |
if (X > GD_fin): # if occupied > 66%, ask user to empty the recycle bin. | |
GDMessage = "<b style='color:red;'>" + OtherMsgs[Language]['TrashBin'] | |
else: # if occupied < 66% | |
GDMessage = "<b>" | |
display(HTML(""" | |
<div style="display: block; margin: 16px 0 16px 0; text-align:left;"> | |
{GDMessage}Google Drive</b> : {Count}% | |
<progress | |
value = '{Count}' | |
max = '100', | |
style = 'background-color: {Color}; width: {GD_Largeur}px;' | |
> | |
{Count} | |
</progress> {Occupied} GB / {Total} GB</div> | |
""".format(Occupied = '{0:.2f}'.format(Occupied), | |
Total = '{0:.2f}'.format(Total), | |
Count = int(100 * Occupied / Total), | |
GD_Largeur = GD_Largeur, | |
Color = Color, | |
GDMessage = GDMessage) | |
) | |
) | |
#-------------------------------- | |
# Fonction: GetProjectNameFromURL | |
#-------------------------------- | |
# Used in stdoutstate_infos() function | |
def GetProjectNameFromURL(url): | |
# Using the url to forge an account_*.xml filename | |
# then opening this file to get <project_name> tag inner data | |
AccountFile = url.split('://')[1] # gets what's after http(s):// | |
AccountFile = AccountFile.strip("/") # removes ending slash | |
AccountFile = AccountFile.replace("/", "_") # replace / for _ | |
AccountFile = 'account_' + AccountFile + '.xml' | |
if os.path.isfile( | |
'/content/drive/MyDrive/Boinc/' | |
+ Server + '/' + AccountFile): | |
FullPathFilename = ('/content/drive/MyDrive/Boinc/' | |
+ Server + '/' + AccountFile) | |
AccountFile_desc = open(FullPathFilename, 'r') | |
AccountFileContent = AccountFile_desc.read() | |
AccountFile_desc.close() | |
ProjectName = ( | |
(AccountFileContent.split('<project_name>')[1]) | |
.split('</project_name>')[0]) | |
else: | |
ProjectName = '(unknown : no account file found)' | |
return ProjectName | |
#-------------------------------- | |
# Fonction: AccountFilesInfos | |
#-------------------------------- | |
# Gives Project's URL and name for each account_*.xml file found. | |
# Used in installation : auto attach/auto detach sequence | |
# Used in function button_action(button) | |
# Used in function ProjectOperations() | |
# returns : AccountsFilesInfos[[URL1, name1], [URL2, name2], ...] | |
# exemple : AccountsFilesInfos[0][0] : "URL1" | |
# exemple : AccountsFilesInfos[1][0] : "URL2" | |
# exemple : AccountsFilesInfos[0][1] : "name1" | |
def AccountFilesInfos(): | |
AccountsFilesInfos = [] | |
for filename in os.listdir('/content/drive/MyDrive/Boinc/' + Server): | |
if filename.startswith('account_') and filename.endswith('.xml'): | |
FullPathFilename = ('/content/drive/MyDrive/Boinc/' | |
+ Server + '/' + filename) | |
AccountFile_desc = open(FullPathFilename, 'r') | |
AccountFileContent = AccountFile_desc.read() | |
AccountFile_desc.close() | |
MasterURL = ( | |
(AccountFileContent.split('<master_url>')[1]) | |
.split('</master_url>')[0]) | |
ProjectName = ( | |
(AccountFileContent.split('<project_name>')[1]) | |
.split('</project_name>')[0]) | |
ThisAccountFileInfos = [MasterURL, ProjectName] | |
AccountsFilesInfos.append(ThisAccountFileInfos) | |
return AccountsFilesInfos | |
#-------------------------------- | |
# Fonction: button_action | |
#-------------------------------- | |
def button_action(button): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
AccountsFilesInfo = AccountFilesInfos() | |
# Display command in main interface's header | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;padding: 5px;">' | |
+ button.description | |
+ '</div>\n')) | |
# Main menu | |
if button.description == menu_buttons[Language]['MenuBoinc']: | |
with MenuOutput.output_to(1, 0): | |
MenuOutput.clear_cell() | |
MenuBoinc.style.button_color = '#808080' | |
MenuProjects.style.button_color = '#454545' | |
MenuTasks.style.button_color = '#454545' | |
MenuSystem.style.button_color = '#454545' | |
TestBoincRunning = get_ipython().\ | |
getoutput('boinccmd --get_file_transfers').nlstr | |
isBoincRunning = ( | |
TestBoincRunning != "can't connect to local host" | |
) | |
if isBoincRunning: | |
display(SubBoinc_menu_withquit) | |
else: | |
display(SubBoinc_menu_withstart) | |
# default : first submenu entry displayed | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;' | |
+ 'padding: 5px;">' | |
+ menu_buttons[Language]['SubBoinc_messages'] | |
+ '</div>\n')) | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Messages() | |
elif button.description == menu_buttons[Language]['MenuProjects']: | |
with MenuOutput.output_to(1, 0): | |
MenuOutput.clear_cell() | |
MenuBoinc.style.button_color = '#454545' | |
MenuProjects.style.button_color = '#808080' | |
MenuTasks.style.button_color = '#454545' | |
MenuSystem.style.button_color = '#454545' | |
display(SubProjects_menu) | |
# default : first submenu entry displayed | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;' | |
+ 'padding: 5px;">' | |
+ menu_buttons[Language]['SubProjects_attached'] | |
+ '</div>\n')) | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Attached_infos() | |
elif button.description == menu_buttons[Language]['MenuTasks']: | |
with MenuOutput.output_to(1, 0): | |
MenuOutput.clear_cell() | |
MenuBoinc.style.button_color = '#454545' | |
MenuProjects.style.button_color = '#454545' | |
MenuTasks.style.button_color = '#808080' | |
MenuSystem.style.button_color = '#454545' | |
display(SubTasks_menu) | |
# default : first submenu entry displayed | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;' | |
+ 'padding: 5px;">' | |
+ menu_buttons[Language]['SubTasks_running'] | |
+ '</div>\n')) | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Tasks_infos() | |
elif button.description == menu_buttons[Language]['MenuSystem']: | |
with MenuOutput.output_to(1, 0): | |
MenuOutput.clear_cell() | |
MenuBoinc.style.button_color = '#454545' | |
MenuProjects.style.button_color = '#454545' | |
MenuTasks.style.button_color = '#454545' | |
MenuSystem.style.button_color = '#808080' | |
display(SubSystem_menu) | |
# default : first submenu entry displayed | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;' | |
+ 'padding: 5px;">' | |
+ menu_buttons[Language]['SubSystem_hostinfo'] | |
+ '</div>\n')) | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --get_host_info | |
# Submenu Boinc | |
elif button.description == menu_buttons[Language]['SubBoinc_messages']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Messages() | |
elif button.description == menu_buttons[Language]['SubBoinc_getccstatus']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --get_cc_status | |
elif button.description == menu_buttons[Language]['SubBoinc_timestats']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
func_Timestats() | |
elif button.description == ( | |
menu_buttons[Language]['SubBoinc_filetransfers']): | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --get_file_transfers | |
elif button.description == menu_buttons[Language]['SubBoinc_readcfg']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('global_prefs_override') | |
!boinccmd --read_global_prefs_override > /dev/null | |
print('cc_config') | |
!boinccmd --read_cc_config > /dev/null | |
with RunningScreenOutput.output_to(1, 0): | |
RunningScreenOutput.clear_cell() | |
wait(0, 5, 250, 1, False) | |
RunningScreenOutput.clear_cell() | |
# Displays messages when done | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Messages() | |
elif button.description == menu_buttons[Language]['SubBoinc_quit']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('Bye !') | |
!boinccmd --quit | |
with RunningScreenOutput.output_to(1, 0): | |
RunningScreenOutput.clear_cell() | |
wait(0, 5, 250, 1, False) | |
RunningScreenOutput.clear_cell() | |
elif button.description == menu_buttons[Language]['SubBoinc_start']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('Let\'s go !') | |
!boinc --daemon --redirectio --run_cpu_benchmarks\ | |
--start_delay 30 --dir $DataDir | |
with RunningScreenOutput.output_to(1, 0): | |
RunningScreenOutput.clear_cell() | |
wait(0, 5, 250, 1, False) | |
RunningScreenOutput.clear_cell() | |
# Submenu Projects | |
elif button.description == menu_buttons[Language]['SubProjects_attached']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Attached_infos() | |
elif button.description == menu_buttons[Language]['SubProjects_apps']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Apps_infos() | |
elif button.description ==\ | |
menu_buttons[Language]['SubProjects_appversions']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Appversions_infos() | |
elif button.description == menu_buttons[Language]['SubProjects_workunits']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Workunits_infos() | |
elif button.description == menu_buttons[Language]['SubProjects_updateall']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
for i in range(len(Projects['URLs'])): | |
ProjectURL = repr(Projects['URLs'][i]) | |
if Projects['Attach'][i] == True: | |
print(ProjectURL) | |
!boinccmd --project $ProjectURL update > /dev/null | |
with RunningScreenOutput.output_to(1, 0): | |
RunningScreenOutput.clear_cell() | |
wait(0, 5, 250, 1, False) | |
RunningScreenOutput.clear_cell() | |
# Displays messages when done | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Messages() | |
elif button.description == menu_buttons[Language]\ | |
['SubProjects_operations']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
ProjectOperations() | |
# Projects : operations | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_suspend']) != -1 and\ | |
len(button.description) != ( | |
len(menu_buttons[Language]['SubProjects_suspend'])): | |
RequiredAction = 'suspend' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ProjectsNames[int(ProjectNumber)]: | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_resume']) != -1 and\ | |
len(button.description) != (len( | |
menu_buttons[Language]['SubProjects_resume'])): | |
RequiredAction = 'resume' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ProjectsNames[int(ProjectNumber)]: | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_nomorewus']) != -1 and\ | |
len(button.description) != ( | |
len(menu_buttons[Language]['SubProjects_nomorewus'])): | |
RequiredAction = 'nomorework' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ProjectsNames[int(ProjectNumber)]: | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_morewus']) != -1 and\ | |
len(button.description) != ( | |
len(menu_buttons[Language]['SubProjects_morewus'])): | |
RequiredAction = 'allowmorework' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ProjectsNames[int(ProjectNumber)]: | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_update']) != -1 and\ | |
len(button.description) != ( | |
len(menu_buttons[Language]['SubProjects_update'])): | |
RequiredAction = 'update' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ( | |
ProjectsNames[int(ProjectNumber)]): | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
elif button.description.find( | |
menu_buttons[Language]['SubProjects_reset']) != -1 and\ | |
len(button.description) != ( | |
len(menu_buttons[Language]['SubProjects_reset'])): | |
RequiredAction = 'reset' | |
ProjectNumber = button.description.rsplit(' ', 1)[1] | |
for i in range(len(ProjectsNames)): | |
if AccountsFilesInfo[i][1] == ( | |
ProjectsNames[int(ProjectNumber)]): | |
ProjectURL = AccountsFilesInfo[i][0] | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --project $ProjectURL $RequiredAction | |
print('(OK) !boinccmd --project ' | |
+ ProjectURL + ' ' + RequiredAction) | |
wait(0, 5, 250, 1, False) | |
# Submenu Tasks | |
elif button.description == menu_buttons[Language]['SubTasks_running']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Tasks_infos() | |
elif button.description == menu_buttons[Language]['SubTasks_upload']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('not done yet !') # todo | |
pass | |
elif button.description == menu_buttons[Language]['SubTasks_error']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('not done yet !') # todo | |
pass | |
elif button.description == menu_buttons[Language]['SubTasks_aborted']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
print('not done yet !') # todo | |
pass | |
# Submenu System info | |
elif button.description == menu_buttons[Language]['SubSystem_hostinfo']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!boinccmd --get_host_info | |
elif button.description == menu_buttons[Language]['SubSystem_CPU']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!top -b -n 1 -o TIME | |
elif button.description == menu_buttons[Language]['SubSystem_GPU']: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
!nvidia-smi | |
# Unknown button / no linked action | |
else: | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #903030;padding: 5px;">' | |
+ button.description + ' has no linked action' | |
+ '</div>\n')) | |
# Date/time of last command | |
with RunningScreenOutput.output_to(3, 0): | |
RunningScreenOutput.clear_cell() | |
print (time.strftime('%d/%m/%Y %H:%M:%S')) | |
#-------------------------------- | |
# Fonction: StartLog | |
#-------------------------------- | |
# Analyzes Boinc's startup, waiting for benchmark result (max : 60 secs) | |
# Gives CPU and GPU infos | |
def StartLog(): | |
OkBenchmark = False # Benchmark isn't done | |
tespera = 0 | |
InfoCPU = '' | |
InfoGPU = '' | |
while not(OkBenchmark) and (tespera < 60): | |
# clear_output(wait = True) | |
f = open('stdoutdae.txt','r') | |
ClientMessages = f.read().splitlines() | |
f.close() | |
# Show log (ClientMessages) most recent first | |
ClientMessagestxt = '' | |
LenClientMessages = len(ClientMessages) | |
for j in range(LenClientMessages): | |
ClientMessagestxt = (ClientMessagestxt | |
+ str(LenClientMessages - j).zfill(4) | |
+ ": " | |
+ ClientMessages[LenClientMessages - j - 1] | |
+ '<br>') | |
# benchmark terminé ? | |
OkBenchmark |= (ClientMessages[LenClientMessages - j - 1] | |
.find('integer MIPS (Dhrystone)') > -1) | |
# présence GPU ? | |
if (ClientMessages[LenClientMessages - j - 1] | |
.find('[---] No usable GPUs found') > -1): | |
InfoGPU = "GPU: NO" | |
desde = (ClientMessages[LenClientMessages - j - 1] | |
.find('[---] OpenCL:')) | |
if (desde > -1): | |
hasta = (ClientMessages[LenClientMessages - j - 1] | |
.find('(driver')) | |
InfoGPU = ("GPU: " | |
+ ClientMessages[LenClientMessages - j - 1]\ | |
[desde + 14:hasta]) | |
desde = (ClientMessages[LenClientMessages - j - 1] | |
.find('[---] Processor:')) | |
# Infos CPU | |
if (desde > -1): | |
hasta = (ClientMessages[LenClientMessages - j - 1] | |
.find('[Family')) | |
InfoCPU = ("CPU: " | |
+ ClientMessages[LenClientMessages - j - 1]\ | |
[desde + 17:hasta]) | |
with StartingScreenOutput.output_to(1, 0): | |
StartingScreenOutput.clear_cell() | |
display(HTML( | |
'<div style="height: ' | |
+ str(InterfaceHeight) | |
+ 'px;overflow: auto;">' | |
+ ClientMessagestxt | |
+ '</div>')) | |
# "Waiting for Boinc start sequence's end" | |
with StartingScreenOutput.output_to(0, 0): | |
StartingScreenOutput.clear_cell() | |
Title(InitialInfo[Language]['StartSequenceEnd']) | |
wait(tespera, tespera + 10, 250, 1, True) | |
tespera += 10 # boucle de 10 secondes * 6 max | |
return InfoCPU, InfoGPU | |
#------------------------------ | |
# Fonction: Messages | |
#------------------------------ | |
# Displays Boinc messages in inverted order (most recent first) | |
def Messages(): | |
f = open('stdoutdae.txt', 'r') | |
ClientMessages = f.read().splitlines() | |
f.close() | |
ClientMessagestxt = '' | |
LenClientMessages = len(ClientMessages) | |
for j in range(LenClientMessages): | |
# # Limit the line lenght to 158 chars | |
# new_input = "" | |
# for k, letter in enumerate( | |
# ClientMessages[LenClientMessages - j - 1]): | |
# if k % 158 == 0: | |
# new_input += '<br>\n' | |
# new_input += letter | |
# ClientMessages[LenClientMessages - j - 1] = ( | |
# new_input[5:]) | |
# Construct final message string | |
ClientMessagestxt = (ClientMessagestxt | |
+ str(LenClientMessages-j).zfill(4) | |
+ " : " | |
+ ClientMessages[LenClientMessages - j - 1] | |
+ '<br>') | |
display(HTML('<div style="height: ' | |
+ str(InterfaceHeight) | |
+ 'px;overflow: auto;">' | |
+ ClientMessagestxt + '</div>')) | |
#------------------------------ | |
# Fonction: stdoutstate_infos | |
#------------------------------ | |
def stdoutstate_infos(): | |
!boinccmd --get_state > stdoutstate.txt | |
f = open('stdoutstate.txt', 'r') | |
ClientStatus = f.read().split("======== ") | |
f.close() | |
for i in range(len(ClientStatus)): | |
# Projects | |
if ClientStatus[i].startswith("Projects ========"): | |
ProjectsLogsBlocs = re.split('[0-9]+\) -----------\n', | |
ClientStatus[i]) | |
del ProjectsLogsBlocs[0] | |
ProjectsNames = [] | |
for j in range(len(ProjectsLogsBlocs)): | |
ProjectsNames.append( | |
ProjectsLogsBlocs[j][9:ProjectsLogsBlocs[j].index("\n")]) | |
# Applications | |
if ClientStatus[i].startswith("Applications ========"): | |
AppsLogsBlocs = re.split('[0-9]+\) -----------\n', | |
ClientStatus[i]) | |
del AppsLogsBlocs[0] | |
AppsNames = [] | |
for j in range(len(AppsLogsBlocs)): | |
AppsNames.append( | |
AppsLogsBlocs[j][9:AppsLogsBlocs[j].index("\n")]) | |
# Application versions | |
if ClientStatus[i].startswith("Application versions ========"): | |
AppsversionsLogsBlocs = re.split('[0-9]+\) -----------\n', | |
ClientStatus[i]) | |
del AppsversionsLogsBlocs[0] | |
AppsversionsNames = [] | |
for j in range(len(AppsversionsLogsBlocs)): | |
AppsversionsNames.append( | |
AppsversionsLogsBlocs[j][12:AppsversionsLogsBlocs[j]\ | |
.index("\n")]) | |
# Workunits | |
if ClientStatus[i].startswith("Workunits ========"): | |
WorkunitsLogsBlocs = re.split('[0-9]+\) -----------\n', | |
ClientStatus[i]) | |
del WorkunitsLogsBlocs[0] | |
WorkunitsNames = [] | |
for j in range(len(WorkunitsLogsBlocs)): | |
WorkunitsNames.append( | |
WorkunitsLogsBlocs[j][9:WorkunitsLogsBlocs[j].index("\n")]) | |
# Tasks | |
if ClientStatus[i].startswith("Tasks ========"): | |
TasksLog = re.split('[0-9]+\) -----------\n', ClientStatus[i]) | |
del TasksLog[0] | |
TasksNames=[] | |
for j in range(len(TasksLog)): | |
# ThisTaskName = str(j + 1).zfill(4) + ' : ' # Task number | |
ThisTaskName = str(j + 1) + ' : ' | |
for k in range(len(Projects['URLs'])): | |
if (TasksLog[j].find(Projects['URLs'][k]) != -1): | |
ProjectNameFound = GetProjectNameFromURL( | |
Projects['URLs'][k]) | |
ThisTaskName = ThisTaskName + ProjectNameFound | |
for k in range(len(WUStates['SearchString'])): | |
if (TasksLog[j].find(WUStates['SearchString'][k]) != -1): | |
if (k == 3): # "active_task_state: EXECUTING" | |
TaskPercentComplete = '' | |
WherePercent = (TasksLog[j] | |
.find('fraction done: ')) | |
if (WherePercent != -1): | |
TaskPercentComplete = ( | |
int(round(float(TasksLog[j] | |
[WherePercent + 15: | |
WherePercent + 19]) * 100))) | |
ThisTaskName = (ThisTaskName | |
+ ' [' | |
+ str(TaskPercentComplete) | |
+ '%]') # Progression | |
else: # State != running | |
ThisTaskName = (ThisTaskName | |
+ WUStates[Language][k]) | |
TasksNames.append(ThisTaskName) | |
# Timestats | |
Timestats = ClientStatus[i].split('Time stats ========')[1] | |
return ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats | |
#------------------------------ | |
# Fonction: Timestats | |
#------------------------------ | |
# Displays Boinc client stats | |
def func_Timestats(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
display(HTML('<div style="overflow: auto;">' | |
+ Timestats.replace("\n", "<br>") | |
+ '</div>')) | |
#------------------------------ | |
# Fonction: Attached_infos | |
#------------------------------ | |
# List attached projects in tabs | |
def Attached_infos(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
SubTabProjects = ipywidgets.widgets.Tab() | |
children = [] | |
for k in range(len(ProjectsLogsBlocs)): | |
SubTabProjects.set_title(k, ProjectsNames[k]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight - 100) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ ProjectsLogsBlocs[k].replace("\n", "<br>") | |
+ '</div>' | |
) | |
children.append(ipywidgets.widgets.HTML( | |
# description = ProjectsNames[k], # (Useless) desc tag inside tab | |
value = content | |
) | |
) | |
SubTabProjects.children = children | |
display(SubTabProjects) | |
#------------------------------ | |
# Fonction: Apps_infos | |
#------------------------------ | |
# List projects apps in tabs | |
def Apps_infos(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
SubTabApps = ipywidgets.widgets.Tab() | |
children = [] | |
for k in range(len(AppsLogsBlocs)): | |
SubTabApps.set_title(k, AppsNames[k]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight - 100) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ AppsLogsBlocs[k].replace("\n", "<br>") | |
+ '</div>' | |
) | |
children.append(ipywidgets.widgets.HTML( | |
# description = AppssNames[k], # (Useless) desc tag inside tab | |
value = content | |
) | |
) | |
SubTabApps.children = children | |
display(SubTabApps) | |
#------------------------------ | |
# Fonction: Appversions_infos | |
#------------------------------ | |
# List workunits in tabs | |
def Appversions_infos(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
SubTabAppversions = ipywidgets.widgets.Tab() | |
children = [] | |
for k in range(len(AppsversionsLogsBlocs)): | |
SubTabAppversions.set_title(k, AppsversionsNames[k]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight - 100) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ AppsversionsLogsBlocs[k].replace("\n", "<br>") | |
+ '</div>' | |
) | |
children.append(ipywidgets.widgets.HTML( | |
# description = AppversionsNames[k], # (Useless) desc tag inside tab | |
value = content | |
) | |
) | |
SubTabAppversions.children = children | |
display(SubTabAppversions) | |
#------------------------------ | |
# Fonction: Workunits_infos | |
#------------------------------ | |
# List workunits in tabs | |
def Workunits_infos(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
SubTabWorkunits = ipywidgets.widgets.Tab() | |
children = [] | |
for k in range(len(WorkunitsLogsBlocs)): | |
SubTabWorkunits.set_title(k, WorkunitsNames[k]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight - 100) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ WorkunitsLogsBlocs[k].replace("\n", "<br>") | |
+ '</div>' | |
) | |
children.append(ipywidgets.widgets.HTML( | |
# description = ProjectsNames[k], # (Useless) desc tag inside tab | |
value = content | |
) | |
) | |
SubTabWorkunits.children = children | |
display(SubTabWorkunits) | |
#------------------------------ | |
# Fonction: Tasks_infos | |
#------------------------------ | |
# List running tasks in tabs | |
def Tasks_infos(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
TasksLogLength = len(TasksLog) | |
TasksLogBlocs = 1 + (TasksLogLength - 1) // 17 | |
if TasksLogBlocs > 1: # More than 17 tasks | |
SubTabTasksNames = [] | |
for Bl in range(TasksLogBlocs): | |
SubTabTasksNames.append(str(Bl * 17 + 1) | |
+ "-" | |
+ str(min(TasksLogLength, (Bl + 1) * 17))) | |
TabTasks = ipywidgets.widgets.Tab(layout="width='50px'") | |
grandchildren = [] | |
for Bl in range(TasksLogBlocs): | |
# TasksNames[Bl * 17:min((Bl + 1) * 17, TasksLogLength)] | |
TabTasks.set_title(B1, SubTabTasksNames[B1]) | |
SubSubTabTasks = ipywidgets.widgets.Tab(location = 'start') | |
grandchildren = [] | |
for j in range(Bl * 17, min((Bl + 1) * 17, TasksLogLength)): | |
TabTasks.set_title(j, TasksNames[j]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ TasksLog[j].replace("\n", "<br>") | |
+ '</div>' | |
) | |
grandchildren.append(ipywidgets.widgets.HTML( | |
# description = TasksNames[k], # (Useless) desc tag in tab | |
value = content | |
) | |
) | |
TabTasks.children = grandchildren | |
display(TabTasks) | |
else: # Less than 17 tasks | |
TabTasks = ipywidgets.widgets.Tab(location = 'start') | |
children = [] | |
for j in range(len(TasksLog)): | |
TabTasks.set_title(j, TasksNames[j]) | |
content = ( | |
'<div style="height: ' | |
+ str(InterfaceHeight) | |
+ 'px;overflow: auto;color: #000000;line-height: normal;">' | |
+ TasksLog[j].replace("\n", "<br>") | |
+ '</div>' | |
) | |
children.append(ipywidgets.widgets.HTML( | |
# description = TasksNames[k], # (Useless) desc tag in tab | |
value = content | |
) | |
) | |
TabTasks.children = children | |
display(TabTasks) | |
#------------------------------ | |
# Fonction: ProjectOperations | |
#------------------------------ | |
# Operations on projects | |
# Constructs actionbuttons for each project | |
def ProjectOperations(): | |
ProjectsLogsBlocs, ProjectsNames,\ | |
AppsLogsBlocs, AppsNames,\ | |
AppsversionsLogsBlocs, AppsversionsNames,\ | |
WorkunitsLogsBlocs, WorkunitsNames,\ | |
TasksLog, TasksNames,\ | |
Timestats = (stdoutstate_infos()) | |
AccountsFilesInfo = AccountFilesInfos() | |
VBoxChildren = [] | |
for i in range(len(ProjectsNames)): | |
for j in range(len(AccountsFilesInfo)): | |
if AccountsFilesInfo[j][1] == ProjectsNames[i]: | |
ProjectURL = AccountsFilesInfo[j][0] | |
Button_suspend_name = 'But_Suspend_' + str(i) | |
Button_suspend_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_suspend'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_suspend_name.on_click(button_action) | |
Button_resume_name = 'But_Resume_' + str(i) | |
Button_resume_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_resume'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_resume_name.on_click(button_action) | |
Button_nmw_name = 'But_NMW_' + str(i) | |
Button_nmw_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_nomorewus'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_nmw_name.on_click(button_action) | |
Button_mw_name = 'But_MW_' + str(i) | |
Button_mw_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_morewus'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_mw_name.on_click(button_action) | |
Button_update_name = 'But_update_' + str(i) | |
Button_update_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_update'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_update_name.on_click(button_action) | |
Button_reset_name = 'But_reset_' + str(i) | |
Button_reset_name = ipywidgets.Button( | |
description = ( | |
menu_buttons[Language]['SubProjects_reset'] | |
+ ' ' + (str(i)) | |
), | |
layout = {'width': 'max-content'} | |
) | |
Button_reset_name.on_click(button_action) | |
Button_reset_name.style.button_color = '#903030' | |
Button_reset_name.style.font_weight = 'bold' | |
LineHBoxName = 'HBox_' + ProjectsNames[i] | |
LineHBoxName = ipywidgets.HBox([ | |
ipywidgets.Label(value=str(i) + ' ' + ProjectsNames[i], | |
layout=ipywidgets.Layout(width='150px')), | |
Button_suspend_name, | |
Button_resume_name, | |
Button_nmw_name, | |
Button_mw_name, | |
Button_update_name, | |
Button_reset_name | |
]) | |
VBoxChildren.append(LineHBoxName) | |
AllLinesVBox = ipywidgets.VBox() | |
AllLinesVBox.children = VBoxChildren | |
display(AllLinesVBox) | |
# ----------------------------------------------------------------------------- | |
# Main program (start) | |
# ----------------------------------------------------------------------------- | |
try: | |
InfoCPU, InfoGPU | |
except: | |
InfoCPU = '' | |
InfoGPU = '' | |
try: | |
running | |
except: | |
running = False | |
if running == False: | |
StartingScreenOutput = widgets.Grid(2, 1) | |
# "Updating Notebook, installing Boinc" | |
with StartingScreenOutput.output_to(0, 0): | |
Title(InitialInfo[Language]['Installing']) | |
with StartingScreenOutput.output_to(1, 0): | |
# System : machine name | |
os.system('hostname ' + Server) | |
os.system('echo ' + Server + ' > /etc/hostname') | |
os.system('echo "127.0.0.1 localhost ::1 localhost ip6-localhost\ | |
ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix\ | |
ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.28.0.2 ' | |
+ Server + '" > /etc/hosts') | |
# System : update | |
!apt-get update | |
!apt-get upgrade | |
!apt-get dist-upgrade | |
!apt-get autoremove | |
!apt-get clean | |
!apt-get autoclean | |
# System : install Boinc and NVidia-SMI tool | |
!apt-get install boinc boinc-client | |
# !apt-get install nvidia-utils-470-server | |
# Drives & files : mount Google Drive | |
if not os.path.exists('/content/drive/MyDrive'): | |
drive.mount('/content/drive') | |
# Drives & files : accessing working folder (create if doesn't exist) | |
os.chdir('/content/drive/MyDrive') | |
if not os.path.exists('Boinc/' + Server): | |
os.makedirs('Boinc/' + Server) | |
os.chdir('Boinc/' + Server) | |
DataDir = repr(os.getcwd()) | |
# Drives & files : copy useful executables to Google Drive | |
# filepath_boinccmd = ('/content/drive/MyDrive/Boinc/' | |
# + Server + '/boinccmd') | |
# if not os.path.exists(filepath_boinccmd)\ | |
# and not os.path.isdir(filepath_boinccmd)\ | |
# and not os.path.islink(filepath_boinccmd): | |
shutil.copy('/usr/bin/boinc', '.') | |
shutil.copy('/usr/bin/boinccmd', '.') | |
# shutil.copy('/usr/bin/nvidia-smi', '.') | |
# Drives & files : create default cc_config.xml | |
if not os.path.isfile('/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/cc_config.xml'): | |
os.system('echo "' | |
+ UserCCConfig | |
+ '" > "/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/cc_config.xml"') | |
# Drives & files : create default global_prefs_override.xml | |
if not os.path.isfile('/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/global_prefs_override.xml'): | |
os.system('echo "' | |
+ UserGlobalPrefsOverride | |
+ '" > ' | |
+ '"/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/global_prefs_override.xml"') | |
# Drives & files : create default gui_rpc_auth.cfg | |
if not os.path.isfile('/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/gui_rpc_auth.cfg'): | |
os.system('echo "' | |
+ RPC_Password | |
+ '" > ' | |
+ '"/content/drive/MyDrive/Boinc/' | |
+ Server | |
+ '/gui_rpc_auth.cfg"') | |
# Drives & files : release all permissions | |
!chmod -R 777 * | |
# "Kill previous Boinc clients (if any)" | |
with StartingScreenOutput.output_to(0, 0): | |
Title(InitialInfo[Language]['KillPreviousBoinc']) | |
ActiveBoincClient = True | |
while ActiveBoincClient: | |
servicio = get_ipython().getoutput('boinccmd --quit').nlstr | |
ActiveBoincClient = (servicio != "can't connect to local host") | |
if ActiveBoincClient: | |
print('...') | |
wait(0, 5, 250, 1, False) | |
# Rotate logs. Keep the last 9. | |
try: | |
os.remove('stdoutdae9.txt') # 9 | |
except: | |
pass | |
for i in range(9, 1, -1): # 9 | |
try: | |
os.rename('stdoutdae' + str(i - 1) + '.txt', | |
'stdoutdae' + str(i) + '.txt') | |
except: | |
pass | |
try: | |
os.rename('stdoutdae.txt', 'stdoutdae1.txt') | |
except: | |
pass | |
# "Launch and set Boinc client" | |
with StartingScreenOutput.output_to(0, 0): | |
Title(InitialInfo[Language]['LaunchBoinc']) | |
with StartingScreenOutput.output_to(1, 0): | |
!boinc --daemon --redirectio --run_cpu_benchmarks --start_delay 30 \ | |
--dir $DataDir | |
with StartingScreenOutput.output_to(0, 0): | |
wait(0, 5, 250, 1, False) | |
with StartingScreenOutput.output_to(1, 0): | |
!boinccmd --set_run_mode always | |
!boinccmd --set_gpu_mode always | |
!boinccmd --set_network_mode always | |
# !boinccmd --set_screensaver_mode off | |
# "Attach projects" | |
with StartingScreenOutput.output_to(0, 0): | |
Title(InitialInfo[Language]['AutoAttachProjects']) | |
with StartingScreenOutput.output_to(1, 0): | |
if not os.path.exists('projects'): | |
os.makedirs('projects') | |
AccountFilesInfo = AccountFilesInfos() | |
AttachedProjectsURLs = [] | |
for h in range(len(AccountFilesInfo)): | |
AttachedProjectsURLs.append("'" + AccountFilesInfo[h][0] + "'") | |
for i in range(len(Projects['URLs'])): | |
ProjectAttach = Projects['Attach'][i] | |
ProjectURL = repr(Projects['URLs'][i]) | |
ProjectAUTH = repr(Projects['AUTH'][i]) | |
# Si le rattachement au projet est demandé | |
if ProjectAttach: | |
# Ce projet n'est pas encore attaché : on l'attache ! | |
if not str(ProjectURL) in AttachedProjectsURLs: | |
print(InitialInfo[Language]['AutoDetachProjects'] | |
+ Projects['URLs'][i]) | |
!boinccmd --project_attach $ProjectURL $ProjectAUTH | |
# with StartingScreenOutput.output_to(0, 0): | |
# wait(0, 5, 250, 1, False) | |
# Le rattachement au projet n'est pas demandé | |
else: | |
# Ce projet est attaché : on le détache ! | |
if str(ProjectURL) in AttachedProjectsURLs: | |
print(InitialInfo[Language]['AutoAttachProjects'] | |
+ Projects['URLs'][i]) | |
!boinccmd --project $ProjectURL detach | |
# with StartingScreenOutput.output_to(0, 0): | |
# wait(0, 5, 250, 1, False) | |
# "Waiting for Boinc start sequence's end" | |
with StartingScreenOutput.output_to(0, 0): | |
Title(InitialInfo[Language]['StartSequenceEnd']) | |
with StartingScreenOutput.output_to(1, 0): | |
while not os.path.exists('stdoutdae.txt'): | |
wait(0, 5, 250, 1, False) | |
InfoCPU, InfoGPU = StartLog() | |
clear_output(wait = True) | |
running = True | |
# ----------------------------------------------------------------------------- | |
# Main : frontend interface | |
# ----------------------------------------------------------------------------- | |
# Ugly fix to unlock auto width for ipywidgets.widgets.Tab() labels | |
# doc : https://github.com/jupyter-widgets/ipywidgets/issues/1905 | |
display(HTML( | |
'<style>' | |
+ '.jupyter-widgets.widget-tab > .p-TabBar .p-TabBar-tab {' | |
+ 'flex: 0 1 auto' | |
+ '}' | |
+ '</style>' | |
)) | |
# Interface : header | |
Title(App1 + ' | ' + App2, "left") | |
# Get Boinc version | |
!boinccmd --version > boinc_version.txt | |
boincversion_desc = open('boinc_version.txt', 'r') | |
boincversion = boincversion_desc.read() | |
boincversion_desc.close() | |
# Display header | |
display(HTML('<div style="display:flex;margin: 16px 0 16px 0;">\n' | |
+ '<div style="float: left;padding: 0 10px 0 0;">' | |
+ '<b>' + Server + '</b><br>\n </div>\n' | |
+ '<div style="float: left;padding: 0 10px 0 10px; ' | |
+ 'border-left: 1px solid #c0c0c0;">' | |
+ InfoCPU + '<br>\n' + InfoGPU + '</div>\n' | |
+ '<div style="padding: 0 10px 0 10px; ' | |
+ 'border-left: 1px solid #c0c0c0;">' | |
+ boincversion[22:] + '</div>\n' | |
+ '</div>\n' | |
# + '<div style="display: block;">' | |
# + '<b>Data dir : </b>' + DataDir + '</div>\n' | |
)) | |
GoogleDriveSpace() # investigate : if put it in main header, displays out of it | |
display(HTML('<div style="display: block;"> </div>\n')) # ugly separator | |
# Interface : Menu buttons | |
MenuOutput = widgets.Grid(2, 1) | |
# Main menu | |
MenuBoinc = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['MenuBoinc'], | |
layout = {'width': 'max-content'}) | |
MenuBoinc.on_click(button_action) | |
MenuProjects = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['MenuProjects'], | |
layout = {'width': 'max-content'}) | |
MenuProjects.on_click(button_action) | |
MenuTasks = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['MenuTasks'], | |
layout = {'width': 'max-content'}) | |
MenuTasks.on_click(button_action) | |
MenuSystem = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['MenuSystem'], | |
layout = {'width': 'max-content'}) | |
MenuSystem.on_click(button_action) | |
MainMenu = ipywidgets.HBox([ | |
MenuBoinc, | |
MenuProjects, | |
MenuTasks, | |
MenuSystem | |
]) | |
# Submenu Boinc | |
SubBoinc_messages = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_messages'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_messages.on_click(button_action) | |
SubBoinc_getccstatus = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_getccstatus'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_getccstatus.on_click(button_action) | |
SubBoinc_timestats = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_timestats'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_timestats.on_click(button_action) | |
SubBoinc_filetransfers = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_filetransfers'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_filetransfers.on_click(button_action) | |
SubBoinc_readcfg = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_readcfg'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_readcfg.on_click(button_action) | |
SubBoinc_quit = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_quit'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_quit.on_click(button_action) | |
SubBoinc_quit.style.button_color = '#903030' | |
SubBoinc_quit.style.font_weight = 'bold' | |
SubBoinc_start = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubBoinc_start'], | |
layout = {'width': 'max-content'}) | |
SubBoinc_start.on_click(button_action) | |
SubBoinc_start.style.button_color = '#309030' | |
SubBoinc_start.style.font_weight = 'bold' | |
SubBoinc_menu_withquit = ipywidgets.HBox([ | |
SubBoinc_messages, | |
SubBoinc_getccstatus, | |
SubBoinc_timestats, | |
SubBoinc_filetransfers, | |
SubBoinc_readcfg, | |
SubBoinc_quit | |
]) | |
SubBoinc_menu_withstart = ipywidgets.HBox([ | |
SubBoinc_messages, | |
SubBoinc_getccstatus, | |
SubBoinc_timestats, | |
SubBoinc_filetransfers, | |
SubBoinc_readcfg, | |
SubBoinc_start | |
]) | |
# Submenu Projects | |
SubProjects_attached = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_attached'], | |
layout = {'width': 'max-content'}) | |
SubProjects_attached.on_click(button_action) | |
SubProjects_apps = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_apps'], | |
layout = {'width': 'max-content'}) | |
SubProjects_apps.on_click(button_action) | |
SubProjects_appversions = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_appversions'], | |
layout = {'width': 'max-content'}) | |
SubProjects_appversions.on_click(button_action) | |
SubProjects_workunits = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_workunits'], | |
layout = {'width': 'max-content'}) | |
SubProjects_workunits.on_click(button_action) | |
SubProjects_updateall = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_updateall'], | |
layout = {'width': 'max-content'}) | |
SubProjects_updateall.on_click(button_action) | |
SubProjects_operations = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubProjects_operations'], | |
layout = {'width': 'max-content'}) | |
SubProjects_operations.on_click(button_action) | |
SubProjects_menu = ipywidgets.HBox([ | |
SubProjects_attached, | |
SubProjects_apps, | |
SubProjects_appversions, | |
SubProjects_workunits, | |
SubProjects_updateall, | |
SubProjects_operations, | |
]) | |
# Submenu Tasks | |
SubTasks_running = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubTasks_running'], | |
layout = {'width': 'max-content'}) | |
SubTasks_running.on_click(button_action) | |
SubTasks_upload = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubTasks_upload'], | |
layout = {'width': 'max-content'}) | |
SubTasks_upload.on_click(button_action) | |
SubTasks_error = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubTasks_error'], | |
layout = {'width': 'max-content'}) | |
SubTasks_error.on_click(button_action) | |
SubTasks_aborted = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubTasks_aborted'], | |
layout = {'width': 'max-content'}) | |
SubTasks_aborted.on_click(button_action) | |
SubTasks_menu = ipywidgets.HBox([ | |
SubTasks_running, | |
SubTasks_upload, | |
SubTasks_error, | |
SubTasks_aborted | |
]) | |
# Submenu System infos | |
SubSystem_hostinfo = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubSystem_hostinfo'], | |
layout = {'width': 'max-content'}) | |
SubSystem_hostinfo.on_click(button_action) | |
SubSystem_CPU = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubSystem_CPU'], | |
layout = {'width': 'max-content'}) | |
SubSystem_CPU.on_click(button_action) | |
SubSystem_GPU = ipywidgets.widgets.Button( | |
description = menu_buttons[Language]['SubSystem_GPU'], | |
layout = {'width': 'max-content'}) | |
SubSystem_GPU.on_click(button_action) | |
SubSystem_menu = ipywidgets.HBox([ | |
SubSystem_hostinfo, | |
SubSystem_CPU, | |
SubSystem_GPU | |
]) | |
with MenuOutput.output_to(0, 0): | |
display(MainMenu) | |
display(HTML('<div style="display: block;"> </div>\n')) # ugly separator | |
# Interface : main output | |
RunningScreenOutput = widgets.Grid(4, 1) | |
# Default menu display | |
with MenuOutput.output_to(1, 0): | |
TestBoincRunning = get_ipython().\ | |
getoutput('boinccmd --get_file_transfers').nlstr | |
isBoincRunning = (TestBoincRunning != "can't connect to local host") | |
if isBoincRunning: | |
display(SubBoinc_menu_withquit) | |
else: | |
display(SubBoinc_menu_withstart) | |
# Default output display | |
with RunningScreenOutput.output_to(0, 0): | |
RunningScreenOutput.clear_cell() | |
display(HTML('<div style="background-color: #606060;padding: 5px;">' | |
+ menu_buttons[Language]['SubBoinc_messages'] | |
+ '</div>\n')) | |
with RunningScreenOutput.output_to(2, 0): | |
RunningScreenOutput.clear_cell() | |
Messages() | |
# Date/time of last command | |
with RunningScreenOutput.output_to(3, 0): | |
RunningScreenOutput.clear_cell() | |
print (time.strftime('%d/%m/%Y %H:%M:%S')) |
Depuis quelques jours ca plante au niveau des tabulations, tout est en linéaire...
Surement une maj d'une biblio chargée par défaut
Depuis quelques jours ca plante au niveau des tabulations, tout est en linéaire... Surement une maj d'une biblio chargée par défaut
Hello PhilTheNet !
Je viens de relancer mon Colab (qui roupillait depuis des semaines) avec la même version de code que celle ci-dessus et... Ben je vois rien de bizarre :/
T'as peut-être un souci commun : des fois, le "notebook" garde une session ouverte après qu'elle a planté et ne parvient pas à la redémarrer correctement : elle tourne, mais il y a plein de bugs bizarres. Dans ce cas là, il faut l'arrêter manuellement et la relancer complètement.
Après, difficile de garantir qu'il n'y a pas effectivement un problème de biblio, notamment celle servant à faire la "mise en page" des onglets : elle est notoirement buggée :( Le vrai souci (et la raison pour laquelle j'ai un peu lâché l'affaire sur Colab), c'est qu'on ne sait jamais sur quel environnement on va tomber quand on crée un nouveau "notebook" : le matos (CPU/GPU) change, et j'ai l'impression qu'on n'a pas toujours accès aux mêmes dépôts Ubuntu selon les sessions : pas simple de garantir que "ça va marcher comme ça" à tous les coups.
Dans l'immédiat, vu que je ne parviens pas à reproduire l'erreur que tu décris, je ne peux pas faire grand chose :/
Salut,
Merci pour la réponse mais bon en fait je viens de me rendre compte en parcourant le code que j'utilise pas ce code mais une version modifiée du code original dans lequel j'ai rajouté la prise en compte de BAM!
:)
Ah. C'est déjà pas mal de savoir qu'on n'a pas (forcément) un problème sur la même version... :D
Honnêtement, je ne crois pas que j'irai plus loin sur ce projet : Colab n'est manifestement pas fait pour tourner à 100% plus de quelques heures et a la fâcheuse tendance à être imprévisible quant à la déconnexion des sessions.
Si queqlu'un se sent d'améliorer mon bazar, qu'il se fasse plaisir ! :D
Je me remet sur le coup et j'ai un pb bizarre tout marche bien avec ton script (et avec le mien) mais au bout d'une dizaine de mn les commandes du style !boinccmd --lacommande provoquent une erreur Authorization failure: -102, les taches boinc continuant de calculer
C'est pas une histoire de mot de passe j'ai essayé.
Il n'y a que la commande !boinccmd --version qui passe
Etrange...
Hello ! Bizarre... A quoi l'erreur 112 correspond-elle ? Je ne trouve pas de référence dans Colab.
Par contre, ell eexiste dans boinccmd et correspondrait au fait que l'exécutable est lancé dans le dossier des données (voir : https://boinc.berkeley.edu/forum_thread.php?id=8298)...
Salut !
Authorization failure: -102 pas 112 (j'avais mis 112 mais j'ai modifié le post)
Ah. C'est boinccmd ou le "notebook" qui renvoie l'erreur ?
boinccmd
Un extrait du code de test que j'ai mis pour tenter de voir ce qui se passe 👍
!boinccmd --version => pas de soucis
!boinccmd --lacommande => en erreur au bout de qlqes minutes => Authorization failure: -102
time.sleep(10) => pour avoir le temps de voir les messages d'erreur
Mmm... à tous les coups tu tombes dans le délai de "veille" du notebook : s'il ne se passe rien sur la console, il "débranche".
Tente un truc : lance ton script principal et, dans la seconde console, en-dessous de la première dans laquelle tourne ton truc, entre ça :
while True:pass
... ça va lancer une boucle infinie qui "occupe" le notebook et l'empêche de déconnecter.
Le souci, c'est que Colab te demandera quand même de signaler ta présence en cliquant sur un popup de temps à autre, et il faudra stopper la boucle infinie pour interagir dans le script principal...
je ne pense pas que cela soit ca parce que je j'active la routine de test toutes les 2 ou 3 mn
Ah. Bizarre... Je peux mater ça "en vrai" tout à l'heure : là, je suis au taf :/
Oki
Thks
Bon en fait la connexion avec le rpc se coupe au bout de +-5mn même en faisant une boucle inifine d'appels rpc...
Bah ! Cherche pas : c'est pourri de limitations dans la version gratuite. Le pire, c'est qu'elles ne sont pas "prévisibles" : un jour ça coupe au bout de 5 minutes, le lendemain au bout d'une demi-heure, trois jours après ça ne marche pas.
C'est pour ça que j'ai lâché l'affaire :/
2022-04-18
As Colab will consider the notebook is stalled if no action takes place in the main interface and will shut it down within minutes, you may simulate actions in a secondary script pane below the main one.
A really dumb-but-efficient oneliner :