1
0

Compare commits

...

176 Commits

Author SHA1 Message Date
b087e85ec5 Semplificati alcuni messaggi nell'output.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 23:22:35 +01:00
3a9f13594c Fix probabilmente definitivo.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 23:08:33 +01:00
1f83db6105 Ristrutturazione codice di verifica.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 22:57:15 +01:00
8b5c87f801 Correzioni su full path.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 22:52:11 +01:00
0bea7a81bc Correzione di un paio di errori di sintassi sui percorsi multipli.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 22:17:18 +01:00
78a43350ed Cambio versione loaih.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 21:48:24 +01:00
8c3e649a25 Correzione file yaml per le build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 21:46:40 +01:00
db01651251 Gestito errore di verifica delle build con cartella quando non trovate.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 02:23:34 +01:00
64effab3d7 Corrette tutte le occorrenze di variabile rinominata.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 02:06:05 +01:00
0a3f475fa6 script è linted. Corretto codice in check su build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 02:03:31 +01:00
03620cf013 Correzione append percorsi.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 01:37:17 +01:00
c015aeea99 Correzione codice checksum.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 01:25:32 +01:00
0a18586201 Aggiunta testo per fasi. Rivista procedura.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 01:03:21 +01:00
5df2c5dbdb Ancora sul build. Aggiunte stringhe per debugging. 2023-01-07 00:59:38 +01:00
41dcbe1718 Aggiunto codice per debug, corretto lancio comando di checksum.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:52:21 +01:00
2405601d2d Sistemato codice per build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:46:45 +01:00
dff74f0a35 Ripristinate istruzioni originali, con chiamata a comando locale.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:30:56 +01:00
6bfa6a3707 Ancora correzioni al processo di checksum.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:24:35 +01:00
059518ccbf Ancora qualche correzione al codice per generare checksum.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:20:56 +01:00
7013318188 Sostituito lancio programma con codice python.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:15:42 +01:00
f6bcf610ba Correzione md5.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:07:03 +01:00
3aab2626ed Correzione script.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 00:02:20 +01:00
df079c91b5 Correzione pubblicazione.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 23:55:30 +01:00
a0c4fbcad0 Correzione rsync.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 23:39:29 +01:00
a316b85afe Correzione comando sbagliato da console - 1.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 23:29:27 +01:00
60b246c548 Correzione comando sbagliato da console.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 23:23:30 +01:00
a0c6217d95 Sistemazione build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 19:58:45 +01:00
f95c4d4b1d Sistemazione upload con rsync.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 18:28:11 +01:00
9d259c4aa5 Cambiata la logica di build in caso di assenza di build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:59:55 +01:00
07a895c86c Fix checksum che torna valore non valido.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:56:33 +01:00
05533bf5e2 Fix sintassi xpath.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:36:53 +01:00
38a78860b0 Fix procedura dopo codice debug.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:33:26 +01:00
da31e1655b Aggiunta codice debug.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:30:06 +01:00
ae9668554a Cambiamenti per esecuzione corretta verifica online.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:24:37 +01:00
9cf3119489 Correzione sintassi in build.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:14:28 +01:00
cbaf6b2e3c Corretto anche il file di build per il test.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 01:08:35 +01:00
df5012eedd Prima implementazione controllo build remota e caricamento con rsync + ssh. 2023-01-05 01:07:12 +01:00
2c19eefa05 Rimozione passaggi superflui pipeline.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-04 23:44:10 +01:00
7d9a701cae Aggiunte alla pipeline.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-04 23:37:24 +01:00
df70a1f954 Ancora modifiche alla pipeline.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-04 23:15:07 +01:00
51079c81d4 Modifiche alla pipeline.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-04 23:12:24 +01:00
a84641c6ea Ancora modifiche alla pipeline.
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-04 23:11:27 +01:00
100fa2e2ac Provo pipeline con drone.
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-04 23:06:48 +01:00
db4c957e1d Fix per numero di build vuoto. 2022-05-12 22:57:11 +02:00
3656b7d0a6 Correzione di sintassi. 2022-05-01 13:30:26 +02:00
eafcc9bc4a Ignorate le generalizzazioni per prerelease e daily. Aggiunto buildfile per daily. 2022-05-01 13:29:04 +02:00
fb92183b4b Ignoro le cartelle pycache. 2022-04-30 23:35:41 +02:00
102dfc192d Aumentata versione release in setup.py. 2022-04-30 23:34:11 +02:00
561290fc63 Aggiunta buildfile per prerelease. 2022-04-30 23:32:26 +02:00
d0f73d0f16 Gestite multiple versioni. Ora anche prerelease e daily sono supportati. 2022-04-30 23:31:06 +02:00
15369c0895 Rinominati file all'interno del progetto. 2022-04-30 17:46:46 +02:00
c30407a244 Refactor parziale dello script. Refactor della parte getversion. 2022-04-30 16:58:00 +02:00
0fae769ec0 versions rivisto e quasi riscritto. getversion da rivedere, perché non era stato previsto caso di multiple versioni ritornate. 2022-04-30 02:14:34 +02:00
638706ce2f Tentative prerelease support. Unfortunately requires the rewrite of most of the scripts, as it might provide multiple versions. 2022-04-24 22:38:40 +02:00
380fd7029e Forzato build in test.yml. 2022-04-09 02:02:04 +02:00
6fb7b052fe Forzata scrittura delle checksum. 2022-04-09 01:56:29 +02:00
529cd1d0c8 Sistemazione closing quote. 2022-04-09 01:44:06 +02:00
b0d1386b49 Aggiunto file per test con buildfile. Creati checksum anche per .zsync. 2022-04-09 01:41:48 +02:00
a3380cecc4 Creata funzione di comodo per creazione dei checksum. 2022-04-09 01:30:47 +02:00
e84f275f42 Cambiato sistema di ricerca delle release - ora basate su DownloadPage. 2022-04-09 01:18:12 +02:00
ebf1e22b0a Cambio del default per firma: sì. 2022-04-09 00:33:11 +02:00
ca1ab61e0c Sistemata modifica in place con sed. 2022-04-09 00:06:29 +02:00
f2d0630c15 Rimossi file di destinazione in caso di esistenza. 2022-04-08 23:26:50 +02:00
b21c06038d Correzione al codice per generalize. 2022-04-08 23:14:47 +02:00
dbad601df9 Chiamo la generalizzazione. 2022-04-08 23:06:49 +02:00
e51b55b41e Cambiata parte finale di implementazione per creazione file generalizzati. 2022-04-08 22:59:59 +02:00
be02b5076c Ancora microfix a versione. 2022-04-08 02:01:39 +02:00
8ded57a154 Forse sistemata versione appimage. 2022-04-08 01:59:23 +02:00
b5edfce8ab Scrittura md5 più pythonica. 2022-04-08 01:56:04 +02:00
076d5389d6 Aggiunta variabile di debug. 2022-04-08 01:45:42 +02:00
bf1d9e0446 Ancora su versione lanciata in ambiente. 2022-04-08 01:41:17 +02:00
b97939ede6 Ancora sostituzione stringhe. 2022-04-08 01:36:47 +02:00
94be1e6ac9 Chiamata build con variabile d'ambiente. 2022-04-08 01:32:10 +02:00
ff51cf8e51 Cambio logica per trovare il binaryname. 2022-04-08 01:28:18 +02:00
dc620f4b09 Mancata creazione directory di build. 2022-04-08 01:05:14 +02:00
648883d514 Ancora correzione sul richiamo funzione privata. 2022-04-08 01:02:39 +02:00
c5fac68a01 Correzione chiamata funzione privata per generazione nome file appimage. 2022-04-08 01:01:21 +02:00
413b84a1c3 Fix tentativo per creazione di link corretti e zsync truccati. 2022-04-08 00:56:28 +02:00
6387ad1ac0 Aggiornamento storage. 2022-04-07 02:34:13 +02:00
2f8b4c444a Sistemazione logica per costruzione buildopts. 2022-03-31 09:38:00 +02:00
72c36521f6 Nei buildfile firmo per default. 2022-03-31 02:53:45 +02:00
7ae5ac182a Correzione logica di esecuzione e assegnazione attributi. 2022-03-31 02:12:46 +02:00
b8b80ebdea Cambiato lo standard dei file di build per allinearsi con l'opzione sign. 2022-03-31 02:02:15 +02:00
a8e522e12d Correzione piccolo problema di richiamo costante. 2022-03-31 01:51:37 +02:00
544d805b50 Commit con funzionalità di firma complete. 2022-03-31 01:50:15 +02:00
2c60de03cb Ancora correzioni allo script di dev. 2022-03-31 01:28:06 +02:00
c88e10b2ac Refactoring di determinato codice, vediamo se potrebbe funzionare. 2022-03-31 01:19:51 +02:00
5ce7f5cc07 Rimozione forzatura stringa utf-8 da libreria. 2022-03-31 01:03:32 +02:00
a68882888a Correzione script di nuovo. 2022-03-31 01:00:13 +02:00
6510226227 Primo push con nuova versione del build. 2022-03-31 00:24:21 +02:00
11570940f7 Evito di chiamare una funzione con un controllo if. 2022-03-30 02:06:24 +02:00
d5f118f304 Adding script for building still. 2022-03-30 01:51:13 +02:00
96907ad24b Piccoli fix cosmetici allo script di build. 2022-03-30 01:47:00 +02:00
42be51b82e Implementato buildfile yml. 2022-03-30 01:36:27 +02:00
b21d14324a Trovato problema per build standard non corrette con le lingue. Corretto script di check_updates. 2022-03-30 01:10:36 +02:00
6895ec357b Corretto script di check_updates.sh. 2022-03-30 01:08:39 +02:00
eade74c29a Script per gli update. Aggiunte directory all'ignore. Non creato checksum per .ver. 2022-03-30 01:06:38 +02:00
f2c64e195f Correzione file ver. Spero sistemato problema di lingua. 2022-03-30 00:42:31 +02:00
cc31d82eb2 Trovato e fixato bug per cui basic sono più grandi di standard. 2022-03-30 00:25:42 +02:00
8c630cbc56 Aggiustato piccolo typo. 2022-03-30 00:12:15 +02:00
8d8f2b6dc4 Alcuni miglioramenti di ricerca delle build in path specifici. 2022-03-30 00:07:43 +02:00
6fe41c6e76 Spostamento codice per calcolo versione. 2022-03-26 02:54:06 +01:00
24de2a2d21 Correzione piccolo errore di sintassi. 2022-03-26 02:45:55 +01:00
960bab4dee Expliciting which file is checking out. 2022-03-26 02:45:01 +01:00
db419bb825 Cambio logica codice per trovare file buildati. 2022-03-26 02:42:53 +01:00
da8adc785f Cambiata la logica di verifica della versione. Ogni versione nominale viene buildata due volte, una con nome generico e una con specifico con versione completa. 2022-03-26 02:32:02 +01:00
8c298e85de Ancora cambio logica build nominali. 2022-03-26 02:10:25 +01:00
17fb8bb2b2 Rivista logica di build per query nominali. 2022-03-26 02:04:02 +01:00
f48189e3b3 Correzione versionamento della appimage con zsync. 2022-03-26 01:46:08 +01:00
7afedb2b90 Corretto piccolo errore di sintassi. 2022-03-26 01:45:29 +01:00
5bb8207409 Corretta sintassi per selezionare solo deb. 2022-03-26 01:35:06 +01:00
425adb5545 Corretta logica di build con il discorso updatable: solo se richiesta versione generica o daily. 2022-03-26 01:32:15 +01:00
2410098953 Aggiustato build per daily. 2022-03-22 02:10:09 +01:00
181940b365 Corretta determinazione storage in cui spostare le build. 2022-03-22 02:04:25 +01:00
66bcd2b39c Supporto a daily e prerelease. 2022-03-22 01:24:55 +01:00
d1a2b50461 Correzione sostituzione della shortversion nella stringa di replacement. 2022-03-21 01:39:56 +01:00
5430000a32 Correzione shortversion per portable. 2022-03-21 01:37:03 +01:00
be24ebf75e Ulteriori correzioni per portable. 2022-03-21 01:33:47 +01:00
ae974e613a Supporto portable. 2022-03-21 01:29:27 +01:00
1c46f9846f Sistemato appname. 2022-03-21 01:18:37 +01:00
e44a70442f Correzione flag offline_help. 2022-03-21 01:14:28 +01:00
71edb785d2 Correzione opzione exist_ok su makedirs() 2022-03-21 01:11:17 +01:00
3422c5e931 Alcune pesanti correzioni ai meccanismi di download e alla raccolta dei tarball. 2022-03-21 01:10:17 +01:00
0df231e450 Trovato forse problema: passaggio di arch. 2022-03-21 00:54:44 +01:00
daff0535d3 Trovato forse problema: passaggio di arch. 2022-03-21 00:48:42 +01:00
9ae9585d20 Debug di appimagefilename. 2022-03-21 00:46:07 +01:00
8eaa14d4d3 Debug di appimage. 2022-03-21 00:44:30 +01:00
960df20639 Probabile problema con valori di array. 2022-03-21 00:42:53 +01:00
d14a64fa8b Altre correzioni a appimagefilename. 2022-03-21 00:40:24 +01:00
5745759488 Altre correzioni alle chiamate. 2022-03-21 00:38:07 +01:00
baa0564c16 Correzione a check(). 2022-03-21 00:34:38 +01:00
c2d3c9d21a Correzione chiamata di variabile in controllo di esistenza build. 2022-03-21 00:30:22 +01:00
60db034067 Correzione chiamata in script di build. 2022-03-21 00:25:13 +01:00
da9d9807fe Correzione firma di funzione non corretta. 2022-03-21 00:23:46 +01:00
3557393d38 Chiamata sbagliata su appimagefilename. 2022-03-21 00:18:09 +01:00
564a933f65 Correzione chiamata alla classe di build. 2022-03-21 00:09:15 +01:00
6aa0b34216 Prima versione riscritta. 2022-03-20 23:57:45 +01:00
c79cc2abcf Preparato layout cartelle per libreria. 2022-03-20 14:33:07 +01:00
c153362a06 Implementata pulizia builddir. 2022-03-20 04:25:16 +01:00
27e004a84b Piccolo errore di ordine di comandi. 2022-03-20 03:49:31 +01:00
1508540847 Rimesso tutto in carreggiata. Build dovrebbero tutte prodursi al prossimo giro. 2022-03-20 03:21:22 +01:00
0fcae9c164 Trovato e risolto problema di build. 2022-03-20 03:14:56 +01:00
84452b4aba Ancora tentativi di correzione della build. 2022-03-20 03:01:32 +01:00
aa0d223670 Problemi con build dell'immagine. Rimuovo temporaneamente tutte le build e la rimozione della cartella. 2022-03-20 02:43:27 +01:00
c935c1a3d0 Attivata rimozione cartella di build, attivato spostamento delle App in Storage. 2022-03-20 01:57:20 +01:00
052b8c45ea Non correggo la versione per non spaccare la build. 2022-03-20 01:47:40 +01:00
14e592d1f2 Correzione nome dell'applicazione (2). 2022-03-20 01:45:24 +01:00
f6488c2e4f Correzione nome dell'applicazione, correzione della versione. 2022-03-20 01:42:39 +01:00
39ad25ab2f Created a download folder to speed up rebuilds. 2022-03-20 01:34:37 +01:00
a059e27a20 Corretto flusso di rebuild. 2022-03-20 01:09:53 +01:00
249527c78c Terminata costruzione di tutte le build. Previsto checksum. AppImage sono ferme lì. 2022-03-20 01:04:47 +01:00
e87d4085fb Impostazione della classe per fare il build di tutte le versioni di base. 2022-03-20 00:53:43 +01:00
e51cf40b76 Non faccio rimuovere la cartella per ulteriori controlli. 2022-03-20 00:24:35 +01:00
e837dd600e Rimozione string replacement non necessario. 2022-03-20 00:11:09 +01:00
a6fdcdc2eb Ancora sistemazione icona. 2022-03-20 00:08:03 +01:00
7a25fb5064 Correzione build. 2022-03-20 00:01:15 +01:00
52860c8a62 Ricreato distruttore. 2022-03-19 23:40:42 +01:00
565c2d9dce Correzione creazione sottocartelle. 2022-03-19 23:38:26 +01:00
8649b928bb Revisione dell'icona. 2022-03-19 23:35:37 +01:00
6a08d3bcb2 Ancora correzioni sulla build. 2022-03-19 23:18:57 +01:00
ef7202a7c6 Correzione percorsi, creazione altre cartelle necessarie. 2022-03-19 23:15:31 +01:00
29984163c3 Correzioni ai find lanciati da interno python. 2022-03-19 23:01:14 +01:00
18f06aedff Corretto unpacking dei tarball. 2022-03-19 22:53:52 +01:00
d4d279991a Correzione allo script di build. 2022-03-19 22:48:54 +01:00
2f1591cb5d Cambio output per variabili per Rundeck - 4. 2022-03-19 22:37:04 +01:00
93f7d95e3d Cambio output per variabili per Rundeck -3. 2022-03-19 22:35:40 +01:00
18a53ad0f4 Cambio output per variabili per Rundeck. 2022-03-19 22:33:56 +01:00
4f9aae424c Cambio output per variabili. 2022-03-19 22:30:52 +01:00
462bce15ad Corretto urlopen. 2022-03-19 22:23:11 +01:00
c1f3431fc1 Correzione richiamo directory. 2022-03-19 22:20:59 +01:00
e2958932b8 Correzione libreria. 2022-03-19 22:15:59 +01:00
1bc882508d Correzione chiamata con parametri. 2022-03-19 22:09:11 +01:00
fb2f9fac45 Prima versione finale di build. 2022-03-19 22:08:20 +01:00
c7648c520b Corretto script check build. Costruzione di uno script di build. 2022-03-19 03:34:53 +01:00
59ff822ca1 Correttoscript di verifica build. 2022-03-19 01:27:48 +01:00
06018439f9 Aggiunto controllo build versione. 2022-03-19 01:21:56 +01:00
14 changed files with 1276 additions and 88 deletions

24
.drone.yml Normal file
View File

@ -0,0 +1,24 @@
---
kind: pipeline
name: default
steps:
- name: compile
image: python
commands:
- pip install wheel
- python setup.py bdist_wheel
when:
event: tag
- name: release
image: plugins/gitea-release
settings:
api_key:
from_secret: gitea-deploy
base_url: https://git.sys42.eu/
files: dist/*.whl
checksum: md5
draft: true
when:
event: tag

4
.gitignore vendored
View File

@ -1 +1,5 @@
venv
build
dist
loaih.egg-info
**/__pycache__

24
check_updates.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
pushd $(dirname $0)
# Checking if pull is successfull
git fetch origin
LC_ALL=C git status | grep -q "Your branch is up to date"; retval=$?
if [[ ${retval} -ne 0 ]]; then
# Let us update the pip installation
git pull
# for the sake of consistency, let's make the check_updates.sh script
# executable
chmod +x check_updates.sh
pip3 uninstall -y loaih
# build the actual toolkit
python3 setup.py bdist_wheel
pip3 install dist/*.whl; rv=$?
if [[ ${rv} -eq 0 ]]; then
# cleanup
rm -rf dist build loaih.egg-info
fi
fi
popd

15
checkbuilt.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/bash
storage=$1
version=$2
shift 2
count=$(find "${storage}" -iname "*${version}*.AppImage" | wc -l)
if [[ ${count} -eq 0 ]]; then
echo "status: not built"
exit 1
else
echo "status: built"
# Nothing more to do!
fi

69
daily.yml Normal file
View File

@ -0,0 +1,69 @@
---
data:
repo: https://appimages.libreitalia.org
remote_host: ciccio
remote_path: /var/lib/nethserver/vhost/appimages
download: /var/tmp/downloads
force: false
sign: true
builds:
- query: daily
language: basic
offline_help: false
portable: false
- query: daily
language: basic
offline_help: true
portable: false
- query: daily
language: basic
offline_help: false
portable: true
- query: daily
language: basic
offline_help: true
portable: true
- query: daily
language: standard
offline_help: false
portable: false
- query: daily
language: standard
offline_help: true
portable: false
- query: daily
language: standard
offline_help: false
portable: true
- query: daily
language: standard
offline_help: true
portable: true
- query: daily
language: full
offline_help: false
portable: false
- query: daily
language: full
offline_help: true
portable: false
- query: daily
language: full
offline_help: false
portable: true
- query: daily
language: full
offline_help: true
portable: true

69
fresh.yml Normal file
View File

@ -0,0 +1,69 @@
---
data:
repo: https://appimages.libreitalia.org
remote_host: ciccio
remote_path: /var/lib/nethserver/vhost/appimages
download: /var/tmp/downloads
force: false
sign: true
builds:
- query: fresh
language: basic
offline_help: false
portable: false
- query: fresh
language: basic
offline_help: true
portable: false
- query: fresh
language: basic
offline_help: false
portable: true
- query: fresh
language: basic
offline_help: true
portable: true
- query: fresh
language: standard
offline_help: false
portable: false
- query: fresh
language: standard
offline_help: true
portable: false
- query: fresh
language: standard
offline_help: false
portable: true
- query: fresh
language: standard
offline_help: true
portable: true
- query: fresh
language: full
offline_help: false
portable: false
- query: fresh
language: full
offline_help: true
portable: false
- query: fresh
language: full
offline_help: false
portable: true
- query: fresh
language: full
offline_help: true
portable: true

View File

@ -1,88 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
import urllib.request
from lxml import etree
from packaging.version import parse as parse_version
import re, sys, json
ARCHIVE = "https://downloadarchive.documentfoundation.org/libreoffice/old/"
RELEASE = "https://download.documentfoundation.org/libreoffice/stable/"
DAILY = "https://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86_64@tb87-TDF/current/"
def getlatestrel(basever):
"""Search in downloadarchive for the latest version matching baseversion."""
versionlist = etree.HTML(urllib.request.urlopen(ARCHIVE).read()).xpath('//td/a')
# Getting a more polished matching list
cleanlist = list(dict.fromkeys([x.text.strip('/') for x in versionlist if x.text.startswith(basever)]))
# Sorting, then returning the last version
return sorted(cleanlist)[-1]
def getbranchrel(branch):
"""Based on branch names, get the release number."""
basedirurl = {}
version = ''
if branch == 'daily':
basedirurl = { 'x86_64': DAILY, 'x86': '-' }
version = etree.HTML(urllib.request.urlopen(DAILY).read()).xpath('//td/a')[1].text.split('_')[1]
return { 'version': version, 'basedirurl': basedirurl }
versions = etree.HTML(urllib.request.urlopen(RELEASE).read()).xpath('//td/a')
index = 1
if branch == 'still':
index = 2
elif branch == 'fresh':
index = 3
version = getlatestrel(versions[index].text.strip('/'))
return { 'version': version, 'basedirurl': getbaseurl(version) }
def getbaseurl(version):
"""Returns the links based on the numeric version."""
basediriurl = {}
url = ARCHIVE + '/' + version + '/deb/'
# x86 binaries are not anymore offered after 6.3.0.
if parse_version(version) < parse_version('6.3.0'):
basedirurl['x86'] = url + 'x86/'
else:
basedirurl['x86'] = '-'
basedirurl['x86_64'] = url + 'x86_64/'
return basedirurl
if __name__ == '__main__':
# Preparing variables for outputting
version = ''
basedirurl = {}
basever = 'fresh'
# At the end of the checks, we need a version string and a basedirurl, which
# should be a dictionaly for x86, x86_64 with the base of the directory where
# to download the files.
if len(sys.argv) > 1:
# A version has been specified.
basever = sys.argv[1]
# Once overridden with Argv, parse the inputs
if '.' in basever:
# Numbered version. Let's check it is a 4 dotted release
if len(basever.split('.')) == 4:
version = basever
else:
version = getlatestrel(basever)
basedirurl = getbaseurl(version)
else:
# String versions.
a = getbranchrel(basever)
version = a['version']
basedirurl = a['basedirurl']
output = """query: %s
version: %s
x86: %s
x86_64: %s""" % (basever, version, basedirurl['x86'] or '-', basedirurl['x86_64'])
print(output)

213
loaih/__init__.py Normal file
View File

@ -0,0 +1,213 @@
#!/usr/bin/env python
# encoding: utf-8
import urllib.request
from lxml import etree
from packaging.version import parse as parse_version
import datetime
class Definitions(object):
DOWNLOADPAGE = "https://www.libreoffice.org/download/download/"
ARCHIVE = "https://downloadarchive.documentfoundation.org/libreoffice/old/"
RELEASE = "https://download.documentfoundation.org/libreoffice/stable/"
DAILY = "https://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86_64@tb87-TDF/"
PRERELEASE = "https://dev-builds.libreoffice.org/pre-releases/deb/x86_64/"
SELECTORS = {
'still': {
'URL': DOWNLOADPAGE,
'xpath': '(//span[@class="dl_version_number"])[last()]/text()'
},
'fresh': {
'URL': DOWNLOADPAGE,
'xpath': '(//span[@class="dl_version_number"])[1]/text()'
},
'prerelease': {
'URL': DOWNLOADPAGE,
'xpath': '//p[@class="lead_libre"][last()]/following-sibling::ul[last()]/li/a/text()'
},
'daily': {
'URL': DAILY,
'xpath': '//td/a'
}
}
class Base(object):
# Class for static methods which might be useful even outside the build
# scripts.
@staticmethod
def dailyurl(date = datetime.datetime.today()):
"""Returns the URL for the latest valid daily build."""
# As per other parts of the build, we need to maintain an URL also for
# x86 versions that it isn't really provided.
# As such, the return value must be a dictionary
# Get the anchor for today's builds
a = etree.HTML(urllib.request.urlopen(Definitions.DAILY).read()).xpath("//td/a[contains(text(), '" + date.strftime('%Y-%m-%d') + "')]/text()")
if len(a) == 0:
# No results found, no version found, let's return a
return { 'x86': '-', 'x86_64': '-' }
# On the contrary, more than a version is found. let's order the
# list and get the latest item
return { 'x86': '-', 'x86_64': Definitions.SELECTORS['daily']['URL'] + sorted(a)[-1] }
@staticmethod
def dailyver(date = datetime.datetime.today()):
"""Returns versions present on the latest daily build."""
url = Base.dailyurl(date)['x86_64']
# If no daily releases has been provided yet, return empty
if url == '-':
return []
# Rerun the page parsing, this time to find out the versions built
b = etree.HTML(urllib.request.urlopen(url).read()).xpath("//td/a[contains(text(), '_deb.tar.gz')]/text()")
# This should have returned the main package for a version, but can
# have returned multiple ones, so let's treat it as a list
return [ x.split('_')[1] for x in b ]
@staticmethod
def namedver(query):
"""Gets the version for a specific named version."""
if query == 'daily' or query == 'yesterday':
# Daily needs double parsing for the same result to apply.
# We first select today's build anchor:
date = datetime.datetime.today()
if query == 'yesterday':
# Use yesterdays' date for testing purposes.
date += datetime.timedelta(days=-1)
return Base.dailyver(date)
# In case the query isn't for daily
return etree.HTML(urllib.request.urlopen(Definitions.SELECTORS[query]['URL']).read()).xpath(Definitions.SELECTORS[query]['xpath'])
@staticmethod
def fullversion(version):
"""Get latest full version from Archive based on partial version."""
versionlist = etree.HTML(urllib.request.urlopen(Definitions.ARCHIVE).read()).xpath(f"//td/a[starts-with(text(), '{version}')]/text()")
if versionlist:
cleanlist = sorted([ x.strip('/') for x in versionlist ])
# Sorting, then returning the last version
return cleanlist[-1]
return None
@staticmethod
def urlfromqueryandver(query, version):
"""Returns the fetching URL based on the queried version and the numeric version of it."""
# This has the purpose to simplify and explain how the releases are
# layed out.
# If the query tells about daily or 'yesterday' (for testing purposes),
# we might ignore versions and return the value coming from dailyurl:
if query == 'daily':
return Base.dailyurl()
if query == 'yesterday':
date = datetime.datetime.today() + datetime.timedelta(days=-1)
return Base.dailyurl(date)
# All other versions will be taken from Archive, as such we need a full
# version.
# If the version has only 2 points in it (or splits into three parts by '.'), that's not a full version and we will call the getlatestver() function
fullversion = str(version)
if len(fullversion.split('.')) <= 3:
fullversion = str(Base.fullversion(version))
# So the final URL is the Archive one, plus the full versions, plus a
# final '/deb/' - and an arch subfolder
baseurl = Definitions.ARCHIVE + fullversion + '/deb/'
retval = {}
# x86 binaries are not anymore offered after 6.3.0.
if parse_version(fullversion) < parse_version('6.3.0'):
retval['x86'] = baseurl + 'x86/'
else:
retval['x86'] = '-'
retval['x86_64'] = baseurl + 'x86_64/'
return retval
@staticmethod
def collectedbuilds(query):
"""Creates a list of Builds based on each queried version found."""
retval = []
if '.' in query:
# Called with a numeric query. Pass it to RemoteBuild
retval.append(RemoteBuild(query))
else:
# Named query
a = Base.namedver(query)
if not a:
# a is empty
return retval
if isinstance(a, list) and len(a) > 1:
retval.extend([ RemoteBuild(query, version) for version in a ])
else:
retval.append(RemoteBuild(query))
return sorted(retval, key=lambda x: x.version)
class RemoteBuild(object):
def __init__(self, query, version = None):
"""Should simplify the single builded version."""
self.query = query
self.version = ''
self.basedirurl = { 'x86': '-', 'x86_64': '-' }
if version and isinstance(version, str):
self.version = version
if not '.' in self.query:
# Named version.
# Let's check if a specific version was requested.
if self.version == '':
# In case it was not requested, we will carry on the generic
# namedver() query.
# If the results are more than one, we'll take the latest (since we are requested to provide a single build).
a = Base.namedver(self.query)
if isinstance(a, list):
# if the number of versions is zero, return and exit
if not a:
return None
if len(a) == 1:
# version is a single one.
self.version = a[0]
else:
# In this case, we will select the latest release.
self.version = sorted(a)[-1]
# If the version has already a version, as requested by user,
# continue using that version
else:
# In case of numbered queries, put it as initial version
self.version = self.query
if len(str(self.version).split('.')) < 4:
# If not 4 dotted, let's search for the 4 dotted version
self.version = Base.fullversion(self.version)
self.basedirurl = Base.urlfromqueryandver(self.query, self.version)
def todict(self):
return {
'query': self.query,
'version': self.version,
'basedirurl': self.basedirurl
}
def __str__(self):
return f"""query: {self.query}
version: {self.version}
x86: {self.basedirurl['x86']}
x86_64: {self.basedirurl['x86_64']}"""

535
loaih/build.py Normal file
View File

@ -0,0 +1,535 @@
#!/usr/bin/env python3
# encoding: utf-8
"""Classes and functions to build an AppImage."""
import os
import glob
import subprocess
import shutil
import re
import shlex
import tempfile
import urllib.request
from lxml import etree
import loaih
class Collection(list):
"""Aggregates metadata on a collection of builds."""
def __init__(self, query, arch = ['x86', 'x86_64']):
"""Build a list of version to check/build for this round."""
super().__init__()
self.extend([
Build(query, arch, version) for version in loaih.Base.collectedbuilds(query)
])
class Build(loaih.RemoteBuild):
"""Builds a single version."""
LANGSTD = [ 'ar', 'de', 'en-GB', 'es', 'fr', 'it', 'ja', 'ko', 'pt',
'pt-BR', 'ru', 'zh-CN', 'zh-TW' ]
LANGBASIC = [ 'en-GB' ]
ARCHSTD = [ 'x86', 'x86_64' ]
def __init__(self, query, arch, version = None):
super().__init__(query, version)
self.arch = arch
self.short_version = str.join('.', self.version.split('.')[0:2])
self.branch_version = None
if not '.' in self.query:
self.branch_version = self.query
self.url = self.basedirurl
# Other default values
self.language = 'basic'
self.offline_help = False
self.portable = False
self.updatable = True
self.sign = True
self.repo_type = 'local'
self.remote_host = ''
self.remote_path = ''
self.storage_path = '/mnt/appimage'
self.download_path = '/var/tmp/downloads'
self.appnamedir = ''
# Specific build version
self.appname = 'LibreOffice'
self.appversion = ''
self.appimagedir = ''
self.appimagefilename = {}
self.zsyncfilename = {}
# Other variables by build
self.languagepart = '.' + self.language
self.helppart = ''
# Creating a tempfile
self.builddir = tempfile.mkdtemp()
self.tarballs = {}
self.built = { 'x86': False, 'x86_64': False }
# Preparing the default for the relative path on the storage for
# different versions.
# The path will evaluated as part of the check() function, as it is
# understood the storage_path can be changed before that phase.
self.relative_path = []
self.full_path = ''
self.baseurl = ''
def calculate(self):
"""Calculate exclusions and other variables."""
print("--- Calculate Phase ---")
# let's check here if we are on a remote repo or local.
if self.storage_path.startswith("http"):
# Final repository is remote
self.repo_type = 'remote'
print("Repo is remote.")
else:
self.repo_type = 'local'
print("Repo is local.")
# AppName
if self.query in { 'prerelease', 'daily' }:
self.appname = 'LibreOfficeDev'
# Calculating languagepart
self.languagepart = "."
if ',' in self.language:
self.languagepart += self.language.replace(',', '-')
else:
self.languagepart += self.language
# Calculating help part
if self.offline_help:
self.helppart = '.help'
# Building the required names
for arch in Build.ARCHSTD:
self.appimagefilename[arch] = self.__gen_appimagefilename__(self.version, arch)
self.zsyncfilename[arch] = self.appimagefilename[arch] + '.zsync'
# Mandate to the private function to calculate the full_path available
# for the storage and the checks.
self.__calculate_full_path__()
def __gen_appimagefilename__(self, version, arch):
"""Generalize the construction of the name of the app."""
self.appversion = version + self.languagepart + self.helppart
return self.appname + f'-{self.appversion}-{arch}.AppImage'
def __calculate_full_path__(self):
"""Calculate relative path of the build, based on internal other variables."""
if len(self.relative_path) == 0:
if self.query == 'daily':
self.relative_path.append('daily')
elif self.query == 'prerelease':
self.relative_path.append('prerelease')
# Not the same check, an additional one
if self.portable:
self.relative_path.append('portable')
# Fullpath might be intended two ways:
if self.repo_type == 'remote':
# Repository is remote
# we build full_path as it is absolute to the root of the
# storage_path.
self.full_path = '/'
if len(self.relative_path) >= 1:
self.full_path += str.join('/', self.relative_path)
else:
# Repository is local
# If it is remote or if it is local
fullpath_arr = self.storage_path.split('/')
# Joining relative path only if it is not null
if len(self.relative_path) > 0:
fullpath_arr.extend(self.relative_path)
self.full_path = re.sub(r"/+", '/', str.join('/', fullpath_arr))
def check(self):
"""Checking if the requested AppImage has been already built."""
print("--- Check Phase ---")
if len(self.appimagefilename) != 2:
self.calculate()
for arch in self.arch:
print(f"Searching for {self.appimagefilename[arch]}")
# First, check if by metadata the repo is remote or not.
if self.repo_type == 'remote':
# Remote storage. I have to query a remote site to know if it
# was already built.
name = self.appimagefilename[arch]
url = self.storage_path.rstrip('/') + self.full_path + '/'
matching = []
try:
with urllib.request.urlopen(url) as response:
matching = etree.HTML(response.read()).xpath(
f"//a[contains(@href, '{name}')]/@href"
)
if len(matching) > 0:
# Already built.
self.built[arch] = True
except urllib.error.HTTPError:
# The URL specified do not exist. So it is to build.
pass
else:
# Repo is local
command = f"find {self.full_path} -name {self.appimagefilename[arch]}"
res = subprocess.run(shlex.split(command),
capture_output=True,
env={ "LC_ALL": "C" },
text=True, encoding='utf-8', check=True)
if "No such file or directory" in res.stderr:
# Folder is not existent: so the version was not built
# Build stays false, and we go to the next arch
continue
if res.stdout and len(res.stdout.strip("\n")) > 0:
# All good, the command was executed fine.
self.built[arch] = True
if self.built[arch]:
print(f"Found requested AppImage: {self.appimagefilename[arch]}.")
def download(self):
"""Downloads the contents of the URL as it was a folder."""
print("--- Download Phase ---")
print(f"Started downloads for {self.version}. Please wait.")
for arch in self.arch:
# Checking if a valid path has been provided
if self.url[arch] == '-':
print(f"Cannot build for arch {arch}. Continuing with other arches.")
# Faking already built it so to skip other checks.
self.built[arch] = True
continue
if self.built[arch]:
print(f"A build for {arch} was already found. Skipping specific packages.")
continue
# Identifying downloads
contents = []
with urllib.request.urlopen(self.url[arch]) as url:
contents = etree.HTML(url.read()).xpath("//td/a")
self.tarballs[arch] = [ x.text
for x in contents
if x.text.endswith('tar.gz') and 'deb' in x.text
]
tarballs = self.tarballs[arch]
# Create and change directory to the download location
os.makedirs(self.download_path, exist_ok = True)
os.chdir(self.download_path)
for archive in tarballs:
# If the archive is already there, do not do anything.
if os.path.exists(archive):
continue
# Download the archive
try:
urllib.request.urlretrieve(self.url[arch] + archive, archive)
except Exception as error:
print(f"Failed to download {archive}: {error}.")
print(f"Finished downloads for {self.version}.")
def build(self):
"""Building all the versions."""
print("--- Building Phase ---")
for arch in self.arch:
if self.built[arch]:
# Already built for arch or path not available. User has already been warned.
continue
# Preparation tasks
self.appnamedir = os.path.join(self.builddir, self.appname)
os.makedirs(self.appnamedir, exist_ok=True)
# And then cd to the appname folder.
os.chdir(self.appnamedir)
# Download appimagetool from github
appimagetoolurl = f"https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-{arch}.AppImage"
urllib.request.urlretrieve(appimagetoolurl, 'appimagetool')
os.chmod('appimagetool', 0o755)
# Build the requested version.
self.__unpackbuild__(arch)
def __unpackbuild__(self, arch):
# We start by filtering out tarballs from the list
buildtarballs = [ self.tarballs[arch][0] ]
# Let's process standard languages and append results to the
# buildtarball
if self.language == 'basic':
if self.offline_help:
buildtarballs.extend([ x for x in self.tarballs[arch] if 'pack_en-GB' in x ])
else:
buildtarballs.extend([ x for x in self.tarballs[arch] if 'langpack_en-GB' in x])
elif self.language == 'standard':
for lang in Build.LANGSTD:
if self.offline_help:
buildtarballs.extend([ x for x in self.tarballs[arch] if ('pack_' + lang) in x ])
else:
buildtarballs.extend([ x for x in self.tarballs[arch] if ('langpack_' + lang) in x ])
elif self.language == 'full':
if self.offline_help:
# We need also all help. Let's replace buildtarball with the
# whole bunch
buildtarballs = self.tarballs[arch]
else:
buildtarballs.extend([ x for x in self.tarballs[arch] if 'langpack' in x ])
else:
# Looping for each language in self.language
for lang in self.language.split(","):
if self.offline_help:
buildtarballs.extend([ x for x in self.tarballs[arch]
if 'pack' + lang in x ])
else:
buildtarballs.extend([ x for x in self.tarballs[arch]
if 'langpack' + lang in x ])
os.chdir(self.appnamedir)
# Unpacking the tarballs
for archive in buildtarballs:
subprocess.run(shlex.split(
f"tar xzf {self.download_path}/{archive}"), check=True)
# create appimagedir
self.appimagedir = os.path.join(self.builddir, self.appname, self.appname + '.AppDir')
os.makedirs(self.appimagedir, exist_ok = True)
# At this point, let's decompress the deb packages
subprocess.run(shlex.split(
r"find .. -iname '*.deb' -exec dpkg -x {} . \;"
), cwd=self.appimagedir, check=True)
if self.portable:
subprocess.run(shlex.split(
r"find . -type f -iname 'bootstraprc' " +
r"-exec sed -i 's|^UserInstallation=.*|" +
r"UserInstallation=\$SYSUSERCONFIG/libreoffice/%s|g' {} \+" % self.short_version
), cwd=self.appimagedir, check=True)
# Changing desktop file
subprocess.run(shlex.split(
r"find . -iname startcenter.desktop -exec cp {} . \;"
), cwd=self.appimagedir, check=True)
subprocess.run(shlex.split(
f"sed --in-place \'s:^Name=.*$:Name={self.appname}:\' " +
r"startcenter.desktop"
), cwd=self.appimagedir, check=False)
subprocess.run(shlex.split(
r"find . -name '*startcenter.png' -path '*hicolor*48x48*' " +
r"-exec cp {} . \;"
), cwd=self.appimagedir, check=True)
# Find the name of the binary called in the desktop file.
binaryname = ''
with open(
os.path.join(self.appimagedir, 'startcenter.desktop'),
'r', encoding="utf-8"
) as desktopfile:
for line in desktopfile.readlines():
if re.match(r'^Exec', line):
binaryname = line.split('=')[-1].split(' ')[0]
# Esci al primo match
break
#binary_exec = subprocess.run(shlex.split(r"awk 'BEGIN { FS = \"=\" } /^Exec/ { print $2; exit }' startcenter.desktop | awk '{ print $1 }'"), cwd=self.appimagedir, text=True, encoding='utf-8')
#binaryname = binary_exec.stdout.strip("\n")
bindir=os.path.join(self.appimagedir, 'usr', 'bin')
os.makedirs(bindir, exist_ok = True)
subprocess.run(shlex.split(
r"find ../../opt -iname soffice -path '*program*' " +
r"-exec ln -sf {} ./%s \;" % binaryname
), cwd=bindir, check=True)
# Download AppRun from github
apprunurl = r"https://github.com/AppImage/AppImageKit/releases/"
apprunurl += f"download/continuous/AppRun-{arch}"
dest = os.path.join(self.appimagedir, 'AppRun')
urllib.request.urlretrieve(apprunurl, dest)
os.chmod(dest, 0o755)
# Dealing with extra options
buildopts = []
if self.sign:
buildopts.append('--sign')
# adding zsync build if updatable
if self.updatable:
buildopts.append(f"-u 'zsync|{self.zsyncfilename[arch]}'")
buildopts_str = str.join(' ', buildopts)
# Build the number-specific build
subprocess.run(shlex.split(
f"{self.appnamedir}/appimagetool {buildopts_str} -v " +
f"./{self.appname}.AppDir/"
), env={ "VERSION": self.appversion }, check=True)
print(f"Built AppImage version {self.appversion}")
# Cleanup phase, before new run.
for deb in glob.glob(self.appnamedir + '/*.deb'):
os.remove(deb)
subprocess.run(shlex.split(
r"find . -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} \+"
), check=True)
def checksums(self):
"""Create checksums of the built versions."""
# Skip checksum if initally the build was already found in the storage directory
print("--- Checksum Phase ---")
if all(self.built[arch] for arch in self.arch):
return
os.chdir(self.appnamedir)
for arch in self.arch:
if not self.built[arch]:
# Here's the contrary. A newly built package has not yet been
# marked as built.
for item in [ self.appimagefilename[arch], self.zsyncfilename[arch] ]:
itempath = os.path.join(self.appnamedir, item)
if os.path.exists(itempath):
# For any built arch, find out if a file exist.
self.__create_checksum__(item)
def __create_checksum__(self, file):
"""Internal function to create checksum file."""
checksum = subprocess.run(f"md5sum {file}", shell=True,
capture_output=True, text=True, encoding='utf-8', check=True,
cwd=self.appnamedir)
if checksum.stdout:
with open(f"{file}.md5", 'w', encoding='utf-8') as checkfile:
checkfile.write(checksum.stdout)
def publish(self):
"""Moves built versions to definitive storage."""
print("--- Publish Phase ---")
if all(self.built[arch] for arch in self.arch):
# All files are already present in the full_path
return
os.chdir(self.appnamedir)
# Two cases here: local and remote storage_path.
if self.repo_type == 'remote':
# Remote first.
# Build destination directory
remotepath = self.remote_path.rstrip('/') + self.full_path
try:
subprocess.run(
r"rsync -rlIvz --munge-links *.AppImage* " +
f"{self.remote_host}:{remotepath}",
cwd=self.appnamedir, shell=True, check=True
)
finally:
pass
else:
# Local
# Forcing creation of subfolders, in case there is a new build
os.makedirs(self.full_path, exist_ok = True)
for file in glob.glob("*.AppImage*"):
subprocess.run(shlex.split(
f"cp -f {file} {self.full_path}"
), check=True)
def generalize_and_link(self, chdir = 'default'):
"""Creates the needed generalized files if needed."""
print("--- Generalize and Link Phase ---")
# If called with a pointed version, no generalize and link necessary.
if not self.branch_version:
return
# If a prerelease or a daily version, either.
if self.query in { 'daily', 'prerelease' }:
return
if chdir == 'default':
chdir = self.full_path
appimagefilename = {}
zsyncfilename = {}
# Creating versions for short version and query text
versions = [ self.short_version, self.branch_version ]
for arch in Build.ARCHSTD:
# If already built, do not do anything.
if self.built[arch]:
continue
os.chdir(chdir)
# if the appimage for the reported arch is not found, skip to next
# arch
if not os.path.exists(self.appimagefilename[arch]):
continue
# Doing it both for short_name and for branchname
for version in versions:
appimagefilename[arch] = self.appname + '-' + version
appimagefilename[arch] += self.languagepart + self.helppart
appimagefilename[arch] += f'-{arch}.AppImage'
zsyncfilename[arch] = appimagefilename[arch] + '.zsync'
# Create the symlink
print(f"Creating {appimagefilename[arch]} and checksums.")
if os.path.exists(appimagefilename[arch]):
os.unlink(appimagefilename[arch])
os.symlink(self.appimagefilename[arch], appimagefilename[arch])
# Create the checksum for the AppImage
self.__create_checksum__(appimagefilename[arch])
# Do not continue if no zsync file is provided.
if not self.updatable:
continue
print(f"Creating zsync file for version {version}.")
if os.path.exists(zsyncfilename[arch]):
os.unlink(zsyncfilename[arch])
shutil.copyfile(self.zsyncfilename[arch], zsyncfilename[arch])
# Editing the zsyncfile
subprocess.run(shlex.split(
r"sed --in-place 's/^Filename:.*$/Filename: " +
f"{appimagefilename[arch]}/' {zsyncfilename[arch]}"
), check=True)
self.__create_checksum__(zsyncfilename[arch])
def __del__(self):
"""Destructor"""
# Cleaning up build directory
shutil.rmtree(self.builddir)

148
loaih/script.py Normal file
View File

@ -0,0 +1,148 @@
#!/usr/bin/env python
# encoding: utf-8
"""Helps with command line commands."""
import json
import click
import yaml
import loaih
import loaih.build
@click.group()
def cli():
"""Helps with command line commands."""
@cli.command()
@click.option('-j', '--json', 'jsonout', default=False, is_flag=True,
help="Output format in json.")
@click.argument('query')
def getversion(query, jsonout):
"""Get the numeral version from a named version."""
batch = []
queries = []
if ',' in query:
queries.extend(query.split(','))
else:
queries.append(query)
for singlequery in queries:
batch.extend(loaih.Base.collectedbuilds(singlequery))
if len(batch) > 0:
if jsonout:
click.echo(json.dumps([x.todict() for x in batch]))
else:
for value in batch:
click.echo(value)
@cli.command()
@click.option('-a', '--arch', 'arch', default='all',
type=click.Choice(['x86', 'x86_64', 'all'], case_sensitive=False),
help="Build the AppImage for a specific architecture. If there is no specific options, the process will build for both architectures (if available). Default: all")
@click.option('-c/-C', '--check/--no-check', 'check', default=True,
help="Check in the final storage if the queried version is existent. Default: check")
@click.option('-d', '--download-path', 'download_path',
default = '/var/tmp/downloads', type=str,
help="Path to the download folder. Default: /var/tmp/downloads")
@click.option('-l', '--language', 'language', default = 'basic', type=str,
help="Languages to be included. Options: basic, standard, full, a language string (e.g. 'it') or a list of languages comma separated (e.g.: 'en-US,en-GB,it'). Default: basic")
@click.option('-o/-O', '--offline-help/--no-offline-help', 'offline', default = False,
help="Include or not the offline help for the chosen languages. Default: no offline help")
@click.option('-p/-P', '--portable/--no-portable', 'portable', default = False,
help="Create a portable version of the AppImage or not. Default: no portable")
@click.option('-r', '--repo-path', 'repo_path', default = '/mnt/appimage',
type=str, help="Path to the final storage of the AppImage. Default: /mnt/appimage")
@click.option('-s/-S', '--sign/--no-sign', 'sign', default=True,
help="Wether to sign the build. Default: sign")
@click.option('-u/-U', '--updatable/--no-updatable', 'updatable', default = True,
help="Create an updatable version of the AppImage or not. Default: updatable")
@click.argument('query')
def build(arch, language, offline, portable, updatable, download_path, repo_path, check, sign, query):
"""Builds an Appimage with the provided options."""
# Parsing options
arches = []
if arch.lower() == 'all':
# We need to build it twice.
arches = [ 'x86', 'x86_64' ]
else:
arches = [ arch.lower() ]
if query.endswith('.yml') or query.endswith('.yaml'):
# This is a buildfile. So we have to load the file and pass the build options ourselves.
config = {}
with open(query, 'r', encoding= 'utf-8') as file:
config = yaml.safe_load(file)
# With the config file, we ignore all the command line options and set
# generic default.
for cbuild in config['builds']:
# Loop a run for each build.
collection = loaih.build.Collection(cbuild['query'], arches)
for obj in collection:
# Configuration phase
obj.language = cbuild['language']
obj.offline_help = cbuild['offline_help']
obj.portable = cbuild['portable']
obj.updatable = True
obj.storage_path = "/srv/http/appimage.sys42.eu"
if 'repo' in config['data'] and config['data']['repo']:
obj.storage_path = config['data']['repo']
obj.download_path = "/var/tmp/downloads"
if 'download' in config['data'] and config['data']['download']:
obj.download_path = config['data']['download']
if 'http' in obj.storage_path:
obj.remoterepo = True
obj.remote_host = "ciccio.libreitalia.org"
if 'remote_host' in config['data'] and config['data']['remote_host']:
obj.remote_host = config['data']['remote_host']
obj.remote_path = "/var/lib/nethserver/vhost/appimages"
if 'remote_path' in config['data'] and config['data']['remote_path']:
obj.remote_path = config['data']['remote_path']
if 'sign' in config['data'] and config['data']['sign']:
obj.sign = True
# Build phase
obj.calculate()
if not 'force' in config['data'] or not config['data']['force']:
obj.check()
obj.download()
obj.build()
obj.checksums()
if obj.remoterepo and obj.appnamedir:
obj.generalize_and_link(obj.appnamedir)
obj.publish()
if not obj.remoterepo:
obj.generalize_and_link()
del obj
else:
collection = loaih.build.Collection(query, arches)
for obj in collection:
# Configuration phase
obj.language = language
obj.offline_help = offline
obj.portable = portable
obj.updatable = updatable
obj.storage_path = repo_path
obj.download_path = download_path
if sign:
obj.sign = True
# Running phase
obj.calculate()
if check:
obj.check()
obj.download()
obj.build()
obj.checksums()
obj.publish()
obj.generalize_and_link()
del obj

69
prerelease.yml Normal file
View File

@ -0,0 +1,69 @@
---
data:
repo: https://appimages.libreitalia.org
remote_host: ciccio
remote_path: /var/lib/nethserver/vhost/appimages
download: /var/tmp/downloads
force: false
sign: true
builds:
- query: prerelease
language: basic
offline_help: false
portable: false
- query: prerelease
language: basic
offline_help: true
portable: false
- query: prerelease
language: basic
offline_help: false
portable: true
- query: prerelease
language: basic
offline_help: true
portable: true
- query: prerelease
language: standard
offline_help: false
portable: false
- query: prerelease
language: standard
offline_help: true
portable: false
- query: prerelease
language: standard
offline_help: false
portable: true
- query: prerelease
language: standard
offline_help: true
portable: true
- query: prerelease
language: full
offline_help: false
portable: false
- query: prerelease
language: full
offline_help: true
portable: false
- query: prerelease
language: full
offline_help: false
portable: true
- query: prerelease
language: full
offline_help: true
portable: true

23
setup.py Normal file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
# encoding: utf-8
# vim:sts=4:sw=4
"""Helps building and automatizing building LibreOffice AppImages."""
from setuptools import setup,find_packages
setup(
name="loaih",
version="1.3.0",
description="LOAIH - LibreOffice AppImage Helpers, help build a LibreOffice AppImage",
author="Emiliano Vavassori",
author_email="syntaxerrormmm@libreoffice.org",
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
entry_points={
'console_scripts': [
'loaih = loaih.script:cli',
],
},
install_requires=[ 'click', ],
license='MIT',
url='https://git.libreitalia.org/LibreItalia/loappimage-helpers/',
)

69
still.yml Normal file
View File

@ -0,0 +1,69 @@
---
data:
repo: https://appimages.libreitalia.org
remote_host: ciccio
remote_path: /var/lib/nethserver/vhost/appimages
download: /var/tmp/downloads
force: false
sign: true
builds:
- query: still
language: basic
offline_help: false
portable: false
- query: still
language: basic
offline_help: true
portable: false
- query: still
language: basic
offline_help: false
portable: true
- query: still
language: basic
offline_help: true
portable: true
- query: still
language: standard
offline_help: false
portable: false
- query: still
language: standard
offline_help: true
portable: false
- query: still
language: standard
offline_help: false
portable: true
- query: still
language: standard
offline_help: true
portable: true
- query: still
language: full
offline_help: false
portable: false
- query: still
language: full
offline_help: true
portable: false
- query: still
language: full
offline_help: false
portable: true
- query: still
language: full
offline_help: true
portable: true

14
test.yml Normal file
View File

@ -0,0 +1,14 @@
---
data:
repo: https://appimages.libreitalia.org
remote_host: ciccio
remote_path: /var/lib/nethserver/vhost/appimages
download: /var/tmp/downloads
force: true
sign: true
builds:
- query: 7.2.3
language: basic
offline_help: false
portable: false