# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
-DocumentRoot "/usr/local/apache2/htdocs"
-<Directory "/usr/local/apache2/htdocs">
+DocumentRoot "/application/public"
+<Directory "/application/public">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://fluidbook-toolbox:9000/application/public/$1" timeout=1800
XSendFile on
-XSendFilePath /data1/extranet
XSendFilePath /application
-XSendFilePath /home/extranet
#
autorestart=true
user=toolbox
group=www-data
-numprocs=3
+numprocs=12
redirect_stderr=true
stdout_logfile=/proc/self/fd/2
stopwaitsecs=3600
autorestart=true
user=toolbox
group=www-data
-numprocs=6
+numprocs=24
redirect_stderr=true
stdout_logfile=/proc/self/fd/2
stopwaitsecs=3600
autorestart=true
user=toolbox
group=www-data
-numprocs=48
+numprocs=96
redirect_stderr=true
stdout_logfile=/proc/self/fd/2
stopwaitsecs=3600
autorestart=true
user=toolbox
group=www-data
-numprocs=3
+numprocs=6
redirect_stderr=true
stdout_logfile=/proc/self/fd/2
stopwaitsecs=3600
services:
webserver:
container_name: fluidbook-toolbox-httpd
- build: /data1/extranet/toolbox/.docker/images/httpd
+ build: /home/toolbox/www/.docker/images/httpd
working_dir: /application
volumes:
- - '/data1/extranet/toolbox/:/application/'
- - '/mnt/sshfs/godzilla/data/fluidbook/docs/:/data1/extranet/www/fluidbook/docs/'
- - '/data1/extranet/toolbox/storage/app/public/:/usr/local/apache2/htdocs/storage/'
- - '/data1/extranet/toolbox/public/:/usr/local/apache2/htdocs/'
- - '/data1/extranet/toolbox/.docker/config/httpd/httpd.conf:/usr/local/apache2/conf/httpd.conf'
+ - '/home/toolbox/www/:/application/'
+ - '/mnt/sshfs/godzilla/data/fluidbook/docs/:/data/extranet/www/fluidbook/docs/'
+ - '/home/toolbox/www/storage/app/public/:/usr/local/apache2/htdocs/storage/'
+ - '/home/toolbox/www/.docker/config/httpd/httpd.conf:/usr/local/apache2/conf/httpd.conf'
ports:
- '37126:80'
environment:
php-fpm:
container_name: fluidbook-toolbox
- build: /data1/extranet/toolbox/.docker/images/php
+ build: /home/toolbox/www/.docker/images/php
working_dir: /application
hostname: fluidbook-toolbox
environment:
TZ: Europe/Paris
HOME: /application
volumes:
- - '/data1/extranet/toolbox/.docker/config/ssh/:/root/.ssh/'
- - '/data1/extranet/toolbox/.docker/config/ssh/:/application/.ssh/'
- - '/data1/extranet/toolbox/.docker/config/supervisor/:/etc/supervisor/conf.d/'
- - '/data1/extranet/toolbox/.docker/config/composer/:/root/.config/composer/'
- - '/data1/extranet/toolbox/.docker/config/composer/:/application/.config/composer/'
- - '/data1/extranet/toolbox/.docker/config/npm/:/root/.npm/'
- - '/data1/extranet/toolbox/.docker/config/gitconfig:/root/.gitconfig'
- - '/data1/extranet/toolbox/.docker/config/git/:/root/.config/git/'
- - '/data1/extranet/toolbox/.docker/config/git/:/application/.config/git/'
- - '/data1/extranet/toolbox/.docker/config/gitconfig:/application/.gitconfig'
- - '/data1/extranet/toolbox/.docker/config/monit/:/etc/monit/'
- - '/data1/extranet/toolbox/.docker/config/sudoers:/etc/sudoers.d/toolbox'
- - '/data1/extranet/toolbox/.docker/config/monit/id:/var/lib/monit/id'
- - '/data1/extranet:/data1/extranet'
- - '/data1/extranet/tmp:/data1/extranet/tmp'
- - '/home/extranet:/home/extranet'
+ - '/home/toolbox/www/.docker/config/ssh/:/root/.ssh/'
+ - '/home/toolbox/www/.docker/config/ssh/:/application/.ssh/'
+ - '/home/toolbox/www/.docker/config/supervisor/:/etc/supervisor/conf.d/'
+ - '/home/toolbox/www/.docker/config/composer/:/root/.config/composer/'
+ - '/home/toolbox/www/.docker/config/composer/:/application/.config/composer/'
+ - '/home/toolbox/www/.docker/config/npm/:/root/.npm/'
+ - '/home/toolbox/www/.docker/config/gitconfig:/root/.gitconfig'
+ - '/home/toolbox/www/.docker/config/git/:/root/.config/git/'
+ - '/home/toolbox/www/.docker/config/git/:/application/.config/git/'
+ - '/home/toolbox/www/.docker/config/gitconfig:/application/.gitconfig'
+ - '/home/toolbox/www/.docker/config/monit/:/etc/monit/'
+ - '/home/toolbox/www/.docker/config/sudoers:/etc/sudoers.d/toolbox'
+ - '/home/toolbox/www/.docker/config/monit/id:/var/lib/monit/id'
+ - '/home/extranet/share:/application/share'
- '/mnt:/mnt'
- - '/data1/extranet/toolbox:/application'
- - '/data1/extranet/toolbox/storage/app/public/:/application/public/storage/'
- - '/data1/extranet/toolbox/.docker/config/php.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'
- - '/data1/extranet/toolbox/.docker/config/crontab:/etc/crontab'
- - '/mnt/sshfs/godzilla/data/fluidbook/docs/:/data1/extranet/www/fluidbook/docs/'
+ - '/home/toolbox/www:/application'
+ - '/home/toolbox/www/storage/app/public/:/application/public/storage/'
+ - '/home/toolbox/www/.docker/config/php.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'
+ - '/home/toolbox/www/.docker/config/crontab:/etc/crontab'
+ - '/mnt/sshfs/godzilla/data/fluidbook/docs/:/data/extranet/www/fluidbook/docs/'
+ - '/home/extranet:/home/extranet'
+ - '/data/extranet:/data/extranet'
tmpfs:
- '/tmp:uid=1001,gid=33'
- '/application/storage/framework:uid=1001,gid=33'
- '58744:8123'
networks:
- fluidbook-toolbox
+ - fluidbook-processfarm
restart: unless-stopped
adminer:
image: adminer:latest
fluidbook-toolbox:
external:
name: fluidbook-toolbox
+ fluidbook-processfarm:
+ external:
+ name: fluidbook-processfarm
# PHPDocker.io PHP 8.1 / CLI and FPM image #
############################################
-FROM ubuntu:jammy AS cli
+FROM ubuntu:latest AS cli
WORKDIR "/application"
RUN apt-get -y --no-install-recommends install icoutils fontforge
RUN apt-get -y --no-install-recommends install ffmpeg python3 lame x264 vorbis-tools
RUN apt-get -y --no-install-recommends install inkscape mupdf-tools librsvg2-bin
-RUN apt-get -y --no-install-recommends install cron monit locate
+RUN apt-get -y --no-install-recommends install cron monit locate telnet
RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
group = 33
pm = dynamic
-pm.max_children = 80
-pm.start_servers = 24
-pm.min_spare_servers = 20
-pm.max_spare_servers = 40
+pm.max_children = 160
+pm.start_servers = 48
+pm.min_spare_servers = 40
+pm.max_spare_servers = 80
pm.max_requests = 1000
--- /dev/null
+<?php
+
+namespace App\Console\Commands;
+
+use App\Jobs\FluidbookCollectionDownload;
+
+use App\Models\User;
+use Cubist\Backpack\Console\Commands\CubistCommand;
+use Cubist\Util\PHP;
+
+class FluidbookCollection extends CubistCommand
+{
+ protected $signature = 'fluidbook:collection {id} {action}';
+ protected $description = 'Compile a fluidbook';
+
+ /**
+ * @throws \Exception
+ */
+ public function handle()
+ {
+ PHP::neverStop(true);
+ $fluidbook = \App\Models\FluidbookCollection::find($this->argument('id'));
+ $job = new FluidbookCollectionDownload($fluidbook, $this->argument('action'), User::withoutGlobalScope('ownerclause')->findOrFail(5));
+ $job->handle();
+ }
+}
namespace App\Fields;
+use App\Models\Traits\FluidbookPlayerBranches;
use Cubist\Backpack\Magic\Fields\SelectFromArray;
class FluidbookDevelopmentVersion extends SelectFromArray
{
+ use FluidbookPlayerBranches;
+
protected static $__options = null;
/**
protected function _getOptions()
{
- $cacheFile = file_get_contents('/data1/extranet/www/fluidbook/cache/activebranches');
-
- $versions = json_decode($cacheFile, true, 512, JSON_THROW_ON_ERROR);
+ $versions = $this->getActiveBranches();
$res = ['stable' => 'master : git (stable)',
'dev' => 'master : local (dev)'];
// __('Collection ":title" (#:nb) prête au téléchargement')
protected $_subject = 'Collection ":title" (#:nb) prête au téléchargement';
+
+ public function handle()
+ {
+ if ($this->action === 'install_hosting') {
+ $url = $this->installHosting($this->entry->getPageData());
+
+ $this->sendNotification(__('Collection ":title" (#:nb) installée sur le serveur hosting', ['title' => $this->_title(), 'nb' => $this->_id()]), '', $url);
+ } else {
+ parent::handle();
+ }
+ }
+
protected function _compile()
{
$compilepath = protected_path('collection/final/' . $this->entry->id);
$options = [];
foreach ($this->entry->getPageData()->override_settings as $setting) {
+ if (!$setting['key']) {
+ continue;
+ }
$options[$setting['key']] = $setting['value'];
}
}
}
+ protected function installHosting($data)
+ {
+ $ws = $this->_getws2();
+ $options = $this->getCollectionGlobalSettings();
+
+ $res = [];
+ foreach ($data->publications as $publication) {
+ $fbid = $publication['fluidbook'];
+ if ($publication['dir']) {
+ $options['dir'] = $publication['dir'];
+ } else {
+ $metadata = $ws->getMetadata($fbid);
+ $options['dir'] = $metadata->export->install_hosting->{$data->version}->dir ?? Str::slug($metadata->title);
+ }
+ $res['Fluidbook #' . $fbid] = $ws->installBookOnHosting($fbid, $options, $data->version);
+ }
+ return $res;
+ }
+
protected function compileExport($data, $path)
{
$ws = $this->_getws2();
$code = str_replace("'%!%", '', $code);
$code = str_replace("!%!'", '', $code);
- file_put_contents('/data1/extranet/www/inc/ws/Metier/class.ws.book.parametres.php', $code);
+ file_put_contents('/home/extranet/www/inc/ws/Metier/class.ws.book.parametres.php', $code);
}
public function __($str)
protected $_colorAlphaFields = [];
protected $_allFields = [];
protected $_ignore = [];
- protected $_t3dir = '/data1/extranet/www/fluidbook/themes3/';
+ protected $_t3dir = '/home/extranet/www/fluidbook/themes3/';
protected static $_colorToWS2Cache = [];
protected static $_colorAlphaToWS2Cache = [];
{
$res = $this->_getThemeData($theme);
$dest = $this->_t3dir . '/' . $theme->id . '.jpg';
- if (!file_exists($dest)) {
- $preview = storage_path('themes/' . $theme->id . '.jpg');
- `ln -sf $preview $dest`;
- }
+
+ $preview = storage_path('themes/' . $theme->id . '.jpg');
+ \Cubist\Util\Files\Files::copyFile($preview, $dest);
+
return $res;
}
if (null !== $media) {
$v = $media->getAttribute('file_name');
$dir = $this->_t3dir . $theme->id;
- if (!file_exists($dir)) {
- mkdir($dir, 0777, true);
- }
+ \Cubist\Util\Files\Files::mkdir($dir);
$dest = $dir . '/' . $v;
$path = $media->getPath();
- $exists = file_exists($dest);
- if (!$exists || realpath($dest) !== realpath($path)) {
- `rm -f $dest;ln -sf $path $dest`;
- }
+
+ \Cubist\Util\Files\Files::copyFile($path, $dest);
+
if (stristr($v, '.svg')) {
$png = str_replace('.svg', '.png', $dest);
if (!file_exists($png) || filemtime($png) < filemtime($path)) {
return ['theme_id' => $theme->id, 'nom' => $theme->name, 'proprietaire' => $theme->owner, 'icones' => $theme->iconSet, 'date' => strtotime($theme->updated_at), 'parametres' => json_encode($settings)];
}
+
public static function colorAlphaToWS2($data)
{
if ($data === '') {
*/
protected function _getFreeFileBaseDirectory()
{
- return '/data1/extranet/www/fluidbook/books/working/' . $this->id;
+ return '/data/extranet/www/fluidbook/books/working/' . $this->id;
}
/**
public function getAssetDir()
{
- return Files::mkdir('/data1/extranet/www/fluidbook/books/working/' . $this->id);
+ return Files::mkdir('/data/extranet/www/fluidbook/books/working/' . $this->id);
}
public function getCompositionUpdate(): int
return true;
}
+ public function _nothing(...$rest)
+ {
+
+ }
+
+ public function installBookOnHosting($id, $options = [], $version = 'online')
+ {
+ return $this->installBook($id, null, $options + ['action' => 'install_hosting'], $version, 3, null, '_nothing');
+ }
+
public function installBookIfNeeded($id, $dir, $options = [], $timestamp = 'auto', $version = 'online')
{
if ($timestamp === 'auto') {
$res->date = (int)$xml->date;
$res->lang = (string)$xml->lang;
$res->settings = json_decode((string)$xml->settings);
+ $res->export = json_decode((string)$xml->export);
return $res;
}
{
$url = 'ajax/exportbookExe';
- $response = $this->_request($url, 'POST', ['version' => $version, 'book_id' => $id, 'action' => 'download', 'options' => $options]);
+ $action = 'download';
+ if (isset($options['action'])) {
+ $action = $options['action'];
+ unset($options['action']);
+ }
+
+ $reqData = ['version' => $version, 'book_id' => $id, 'action' => $action, 'options' => $options];
+ if ($action === 'install_hosting') {
+ $destination = [];
+ if (isset($options['dir'])) {
+ $destination['dir'] = $options['dir'];
+ unset($options['dir']);
+ }
+ $reqData['destination'] = $destination;
+ }
+
+ $response = $this->_request($url, 'POST', $reqData);
+
+
$xml = $this->_getXMLFromResponse($response);
+ if ($action === 'install_hosting') {
+ return (string)$xml->truepopup->url;
+ }
+
if ($xml !== false && isset($xml->redirection) && !is_null($xml->redirection)) {
+
$this->$function((string)$xml->redirection, $dir, $beforeInstallCallback);
return true;
} else {
]
];
}
- if (count($actions) > 0) {
+ $actionsCount = count($actions);
+ if ($actionsCount > 0) {
$a = [
'type' => 'actions',
'block_id' => 'actions',
if (is_string($data)) {
$data = ['url' => $data];
}
- $a['elements'][] = array_merge([
- 'type' => 'button',
- 'text' => [
- 'type' => 'plain_text',
- 'text' => $label
- ],
- ], $data);
- $i++;
+ if ($i < 6) {
+ $a['elements'][] = array_merge([
+ 'type' => 'button',
+ 'text' => [
+ 'type' => 'plain_text',
+ 'text' => $label
+ ],
+ ], $data);
+ }
if ($repeatActions) {
$text .= '> ' . $label . ' : ' . $data['url'] . "\n";
}
+ $i++;
}
if ($text) {
$blocks[] = [
$this->addField('fluidbook', FluidbookID::class, __('Fluidbook #'));
$this->addField('export', Text::class, __('Nom d\'export'), ['hint'=>__('Laisser vide pour laisser le système déterminer le nom')]);
+ $this->addField('dir', Text::class, __('Répertoire d\'export'), ['hint'=>__('Laisser vide pour laisser le système déterminer le nom')]);
}
}
class FluidbookFarm
{
protected static $_farmServers = [
- ['name' => 'alien', 'host' => 'alien.cubedesigners.com', 'weight' => 1],
+ ['name' => 'alphaville', 'host' => 'fluidbook-processfarm', 'port' => 9000, 'weight' => 24],
['name' => 'brazil', 'host' => 'brazil.cubedesigners.com', 'weight' => 6],
['name' => 'clockwork', 'host' => 'clockwork.cubedesigners.com', 'weight' => 2],
['name' => 'dracula', 'host' => 'dracula.cubedesigners.com', 'weight' => 3],
public static function getLinksDir($book_id)
{
- return Files::mkdir('/data1/extranet/www/fluidbook/books/links/' . $book_id);
+ return Files::mkdir('/data/extranet/www/fluidbook/books/links/' . $book_id);
}
public static function getLinksVersions($book_id, $withLinks = false)
@php
- $actions=['download'=>__('Télécharger')];
+ $actions=['download'=>__('Télécharger'),'install_hosting'=>__('Installer sur hosting')];
if($entry->type==='scorm_multilang'){
$actions['scormcloud']=__('Tester sur Scorm Cloud');
}