init
							
								
								
									
										16
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
			
		||||
 | 
			
		||||
openstreetmap-website/
 | 
			
		||||
 | 
			
		||||
openstreetmap-templates/
 | 
			
		||||
 | 
			
		||||
osm/
 | 
			
		||||
 | 
			
		||||
venv_reset/
 | 
			
		||||
 | 
			
		||||
tmpfs/
 | 
			
		||||
 | 
			
		||||
wiki/
 | 
			
		||||
 | 
			
		||||
venv/
 | 
			
		||||
 | 
			
		||||
*.tar.gz
 | 
			
		||||
							
								
								
									
										45
									
								
								00_vars.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,45 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# PUBLIC_HOSTNAME=$(curl -s ifconfig.me)
 | 
			
		||||
PUBLIC_HOSTNAME="localhost"
 | 
			
		||||
 | 
			
		||||
# Change ports as desired
 | 
			
		||||
REDDIT_PORT=28080
 | 
			
		||||
# WIKIPEDIA_PORT=28081
 | 
			
		||||
SHOPPING_PORT=28082
 | 
			
		||||
SHOPPING_ADMIN_PORT=28083
 | 
			
		||||
GITLAB_PORT=28084
 | 
			
		||||
# MAP_PORT=28085
 | 
			
		||||
HOMEPAGE_PORT=20080
 | 
			
		||||
RESET_PORT=20081
 | 
			
		||||
 | 
			
		||||
# Original webarena ports
 | 
			
		||||
# SHOPPING_PORT=7770
 | 
			
		||||
# SHOPPING_ADMIN_PORT=7780
 | 
			
		||||
# REDDIT_PORT=9999
 | 
			
		||||
# GITLAB_PORT=8023
 | 
			
		||||
# WIKIPEDIA_PORT=8888
 | 
			
		||||
# MAP_PORT=3000
 | 
			
		||||
# HOMEPAGE_PORT=4399
 | 
			
		||||
 | 
			
		||||
SHOPPING_URL="http://${PUBLIC_HOSTNAME}:${SHOPPING_PORT}"
 | 
			
		||||
SHOPPING_ADMIN_URL="http://${PUBLIC_HOSTNAME}:${SHOPPING_ADMIN_PORT}/admin"
 | 
			
		||||
REDDIT_URL="http://${PUBLIC_HOSTNAME}:${REDDIT_PORT}/forums/all"
 | 
			
		||||
GITLAB_URL="http://${PUBLIC_HOSTNAME}:${GITLAB_PORT}/explore"
 | 
			
		||||
# WIKIPEDIA_URL="http://${PUBLIC_HOSTNAME}:${WIKIPEDIA_PORT}/wikipedia_en_all_maxi_2022-05/A/User:The_other_Kiwix_guy/Landing"
 | 
			
		||||
# MAP_URL="http://${PUBLIC_HOSTNAME}:${MAP_PORT}"
 | 
			
		||||
MAP_URL="https://www.openstreetmap.org/"
 | 
			
		||||
 | 
			
		||||
# download the archives from the webarena instructions
 | 
			
		||||
# https://github.com/web-arena-x/webarena/tree/main/environment_docker
 | 
			
		||||
# Download the additional openstreetmap docker files from Zenodo (see README)
 | 
			
		||||
#  - shopping_final_0712.tar
 | 
			
		||||
#  - shopping_admin_final_0719.tar
 | 
			
		||||
#  - postmill-populated-exposed-withimg.tar
 | 
			
		||||
#  - gitlab-populated-final-port8023.tar
 | 
			
		||||
#  - openstreetmap-website-db.tar.gz
 | 
			
		||||
#  - openstreetmap-website-web.tar.gz
 | 
			
		||||
#  - openstreetmap-website.tar.gz
 | 
			
		||||
#  - wikipedia_en_all_maxi_2022-05.zim
 | 
			
		||||
 | 
			
		||||
ARCHIVES_LOCATION="/home/yuyr/webarena_docker_tar"
 | 
			
		||||
							
								
								
									
										61
									
								
								01_docker_load_images.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,61 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
source ./00_vars.sh
 | 
			
		||||
 | 
			
		||||
assert() {
 | 
			
		||||
  if ! "$@"; then
 | 
			
		||||
    echo "Assertion failed: $@" >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
load_docker_image() {
 | 
			
		||||
  local IMAGE_NAME="$1"
 | 
			
		||||
  local INPUT_FILE="$2"
 | 
			
		||||
 | 
			
		||||
  if ! docker images --format "{{.Repository}}:{{.Tag}}" | grep -q "^${IMAGE_NAME}:"; then
 | 
			
		||||
    echo "Loading Docker image ${IMAGE_NAME} from ${INPUT_FILE}"
 | 
			
		||||
    docker load --input "${INPUT_FILE}"
 | 
			
		||||
  else
 | 
			
		||||
    echo "Docker image ${IMAGE_NAME} is already loaded."
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# make sure all required files are here
 | 
			
		||||
assert [ -f ${ARCHIVES_LOCATION}/shopping_final_0712.tar ]
 | 
			
		||||
assert [ -f ${ARCHIVES_LOCATION}/shopping_admin_final_0719.tar ]
 | 
			
		||||
assert [ -f ${ARCHIVES_LOCATION}/postmill-populated-exposed-withimg.tar ]
 | 
			
		||||
assert [ -f ${ARCHIVES_LOCATION}/gitlab-populated-final-port8023.tar ]
 | 
			
		||||
# assert [ -f ${ARCHIVES_LOCATION}/openstreetmap-website-db.tar.gz ]
 | 
			
		||||
# assert [ -f ${ARCHIVES_LOCATION}/openstreetmap-website-web.tar.gz ]
 | 
			
		||||
# assert [ -f ${ARCHIVES_LOCATION}/openstreetmap-website.tar.gz ]
 | 
			
		||||
# assert [ -f ${ARCHIVES_LOCATION}/wikipedia_en_all_maxi_2022-05.zim ]
 | 
			
		||||
 | 
			
		||||
# load docker images (if needed)
 | 
			
		||||
load_docker_image "shopping_final_0712" "${ARCHIVES_LOCATION}/shopping_final_0712.tar"
 | 
			
		||||
load_docker_image "shopping_admin_final_0719" ${ARCHIVES_LOCATION}/shopping_admin_final_0719.tar
 | 
			
		||||
load_docker_image "postmill-populated-exposed-withimg" "${ARCHIVES_LOCATION}/postmill-populated-exposed-withimg.tar"
 | 
			
		||||
load_docker_image "gitlab-populated-final-port8023" "${ARCHIVES_LOCATION}/gitlab-populated-final-port8023.tar"
 | 
			
		||||
# load_docker_image "openstreetmap-website-db" "${ARCHIVES_LOCATION}/openstreetmap-website-db.tar.gz"
 | 
			
		||||
#load_docker_image "openstreetmap-website-web" "${ARCHIVES_LOCATION}/openstreetmap-website-web.tar.gz"
 | 
			
		||||
 | 
			
		||||
# extract openstreetmap archive locally (if needed)
 | 
			
		||||
# if [ ! -d ./openstreetmap-website ]; then
 | 
			
		||||
#   echo "Extracting openstreemap archive..."
 | 
			
		||||
#   tar -xzf ${ARCHIVES_LOCATION}/openstreetmap-website.tar.gz
 | 
			
		||||
# else
 | 
			
		||||
#   echo "Openstreemap archive already extracted."
 | 
			
		||||
# fi
 | 
			
		||||
 | 
			
		||||
# copy wikipedia archive to local folder (if needed)
 | 
			
		||||
# WIKIPEDIA_ARCHIVE=wikipedia_en_all_maxi_2022-05.zim
 | 
			
		||||
# if [ ! -f ./wiki/${WIKIPEDIA_ARCHIVE} ]; then
 | 
			
		||||
#   echo "Moving wikipedia archive..."
 | 
			
		||||
#   mkdir -p ./wiki
 | 
			
		||||
#   cp ${ARCHIVES_LOCATION}/${WIKIPEDIA_ARCHIVE} ./wiki
 | 
			
		||||
# else
 | 
			
		||||
#   echo "Wikipedia archive already present."
 | 
			
		||||
# fi
 | 
			
		||||
							
								
								
									
										8
									
								
								02_docker_remove_containers.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
docker stop shopping_admin forum gitlab shopping  || true
 | 
			
		||||
docker rm shopping_admin forum gitlab shopping  || true
 | 
			
		||||
 | 
			
		||||
# docker stop shopping_admin forum gitlab shopping wikipedia openstreetmap-website-db-1 openstreetmap-website-web-1 || true
 | 
			
		||||
#docker rm shopping_admin forum gitlab shopping wikipedia openstreetmap-website-db-1 openstreetmap-website-web-1 || true
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								03_docker_create_containers.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
source ./00_vars.sh
 | 
			
		||||
 | 
			
		||||
WORKING_DIR=$(pwd)
 | 
			
		||||
 | 
			
		||||
docker create --name shopping -p $SHOPPING_PORT:80 shopping_final_0712
 | 
			
		||||
docker create --name shopping_admin -p $SHOPPING_ADMIN_PORT:80 shopping_admin_final_0719
 | 
			
		||||
docker create --name forum -p $REDDIT_PORT:80 postmill-populated-exposed-withimg
 | 
			
		||||
docker create --name gitlab --sysctl net.ipv6.conf.all.disable_ipv6=0 --sysctl net.ipv6.conf.default.disable_ipv6=0 \
 | 
			
		||||
              -p $GITLAB_PORT:$GITLAB_PORT gitlab-populated-final-port8023 /opt/gitlab/embedded/bin/runsvdir-start --env GITLAB_PORT=$GITLAB_PORT
 | 
			
		||||
# docker create --name wikipedia --volume=${WORKING_DIR}/wiki_patch/start.sh:/usr/local/bin/start.sh \
 | 
			
		||||
#                 --volume=${WORKING_DIR}/wiki/:/data --network=host ghcr.io/kiwix/kiwix-serve:3.3.0  wikipedia_en_all_maxi_2022-05.zim $WIKIPEDIA_PORT
 | 
			
		||||
 | 
			
		||||
# 
 | 
			
		||||
# # openstreetmap docker set up
 | 
			
		||||
# cd openstreetmap-website/
 | 
			
		||||
 | 
			
		||||
# # tile server URL (use default openstreetmap server)
 | 
			
		||||
# OSM_TILE_SERVER_URL="http://tile-server-run/tile/{z}/{x}/{y}.png"
 | 
			
		||||
# # geocoding server URL (use default openstreetmap server)
 | 
			
		||||
# OSM_GEOCODING_SERVER_URL="http://geocoding:8080/"
 | 
			
		||||
# # routing server URLs (use default openstreetmap server)
 | 
			
		||||
# OSM_ROUTING_SERVER_URL="http://nginx"
 | 
			
		||||
# OSM_CAR_SUFFIX="/routed-car"
 | 
			
		||||
# OSM_BIKE_SUFFIX="/routed-bike"
 | 
			
		||||
# OSM_FOOT_SUFFIX="/routed-foot"
 | 
			
		||||
# # original WebArena config (CMU server with different ports for each vehicule type)
 | 
			
		||||
# # OSM_ROUTING_SERVER_URL="http://metis.lti.cs.cmu.edu"
 | 
			
		||||
# # OSM_CAR_SUFFIX=":5000"
 | 
			
		||||
# # OSM_BIKE_SUFFIX=":5001"
 | 
			
		||||
# # OSM_FOOT_SUFFIX=":5002"
 | 
			
		||||
 | 
			
		||||
# # copy template files to be set up
 | 
			
		||||
# cp ../openstreetmap-templates/docker-compose.yml ./docker-compose.yml
 | 
			
		||||
# cp ../openstreetmap-templates/nginx.conf ./nginx.conf
 | 
			
		||||
# cp ../openstreetmap-templates/leaflet.osm.js ./vendor/assets/leaflet/leaflet.osm.js
 | 
			
		||||
# cp ../openstreetmap-templates/fossgis_osrm.js ./app/assets/javascripts/index/directions/fossgis_osrm.js
 | 
			
		||||
 | 
			
		||||
# # set up web server port
 | 
			
		||||
# sed -i "s|MAP_PORT|${MAP_PORT}|g" docker-compose.yml
 | 
			
		||||
# # set up tile server URL
 | 
			
		||||
# sed -i "s|url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'|url: '${OSM_TILE_SERVER_URL}'|g" ./vendor/assets/leaflet/leaflet.osm.js
 | 
			
		||||
# # set up geocoding server URL
 | 
			
		||||
# sed -i "s|nominatim_url:.*|nominatim_url: \"$OSM_GEOCODING_SERVER_URL\"|g" ./config/settings.yml
 | 
			
		||||
# # set up routing server URLs
 | 
			
		||||
# sed -i "s|fossgis_osrm_url:.*|fossgis_osrm_url: \"$OSM_ROUTING_SERVER_URL\"|g" ./config/settings.yml
 | 
			
		||||
# sed -i "s|__OSMCarSuffix__|${OSM_CAR_SUFFIX}|g" ./app/assets/javascripts/index/directions/fossgis_osrm.js
 | 
			
		||||
# sed -i "s|__OSMBikeSuffix__|${OSM_BIKE_SUFFIX}|g" ./app/assets/javascripts/index/directions/fossgis_osrm.js
 | 
			
		||||
# sed -i "s|__OSMFootSuffix__|${OSM_FOOT_SUFFIX}|g" ./app/assets/javascripts/index/directions/fossgis_osrm.js
 | 
			
		||||
 | 
			
		||||
# docker compose create
 | 
			
		||||
							
								
								
									
										20
									
								
								04_docker_start_containers.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
docker start gitlab
 | 
			
		||||
docker start shopping
 | 
			
		||||
docker start shopping_admin
 | 
			
		||||
docker start forum
 | 
			
		||||
# docker start kiwix33
 | 
			
		||||
# docker start wikipedia
 | 
			
		||||
 | 
			
		||||
# cd openstreetmap-website/
 | 
			
		||||
# docker compose start
 | 
			
		||||
 | 
			
		||||
# 尤其是等gitlab,这个服务启动很慢,要5分钟以上
 | 
			
		||||
echo -n -e "Waiting 300 seconds for all services to start..."
 | 
			
		||||
sleep 300
 | 
			
		||||
echo -n -e " done\n"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								05_docker_patch_containers.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,48 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
source ./00_vars.sh
 | 
			
		||||
 | 
			
		||||
# reddit - make server more responsive
 | 
			
		||||
docker exec forum sed -i \
 | 
			
		||||
  -e 's/^pm.max_children = .*/pm.max_children = 32/' \
 | 
			
		||||
  -e 's/^pm.start_servers = .*/pm.start_servers = 10/' \
 | 
			
		||||
  -e 's/^pm.min_spare_servers = .*/pm.min_spare_servers = 5/' \
 | 
			
		||||
  -e 's/^pm.max_spare_servers = .*/pm.max_spare_servers = 20/' \
 | 
			
		||||
  -e 's/^;pm.max_requests = .*/pm.max_requests = 500/' \
 | 
			
		||||
  /usr/local/etc/php-fpm.d/www.conf
 | 
			
		||||
docker exec forum supervisorctl restart php-fpm
 | 
			
		||||
 | 
			
		||||
echo "Patching shopping container"
 | 
			
		||||
# shopping + shopping admin
 | 
			
		||||
docker exec shopping /var/www/magento2/bin/magento setup:store-config:set --base-url="http://$PUBLIC_HOSTNAME:$SHOPPING_PORT" # no trailing /
 | 
			
		||||
docker exec shopping mysql -u magentouser -pMyPassword magentodb -e  "UPDATE core_config_data SET value='http://$PUBLIC_HOSTNAME:$SHOPPING_PORT/' WHERE path = 'web/secure/base_url';"
 | 
			
		||||
# remove the requirement to reset password
 | 
			
		||||
echo "Removing the requirement to reset password"
 | 
			
		||||
docker exec shopping_admin php /var/www/magento2/bin/magento config:set admin/security/password_is_forced 0
 | 
			
		||||
docker exec shopping_admin php /var/www/magento2/bin/magento config:set admin/security/password_lifetime 0
 | 
			
		||||
docker exec shopping /var/www/magento2/bin/magento cache:flush
 | 
			
		||||
 | 
			
		||||
echo "Patching shopping admin container"
 | 
			
		||||
docker exec shopping_admin /var/www/magento2/bin/magento setup:store-config:set --base-url="http://$PUBLIC_HOSTNAME:$SHOPPING_ADMIN_PORT"
 | 
			
		||||
docker exec shopping_admin mysql -u magentouser -pMyPassword magentodb -e  "UPDATE core_config_data SET value='http://$PUBLIC_HOSTNAME:$SHOPPING_ADMIN_PORT/' WHERE path = 'web/secure/base_url';"
 | 
			
		||||
docker exec shopping_admin /var/www/magento2/bin/magento cache:flush
 | 
			
		||||
 | 
			
		||||
echo "Patching gitlab container"
 | 
			
		||||
# gitlab
 | 
			
		||||
docker exec gitlab sed -i "s|^external_url.*|external_url 'http://$PUBLIC_HOSTNAME:$GITLAB_PORT'|" /etc/gitlab/gitlab.rb
 | 
			
		||||
docker exec gitlab bash -c "printf '\n\npuma[\"worker_processes\"] = 4' >> /etc/gitlab/gitlab.rb"  # bugfix https://github.com/ServiceNow/BrowserGym/issues/285
 | 
			
		||||
# 添加 IPv6 支持
 | 
			
		||||
docker exec gitlab bash -c "echo '
 | 
			
		||||
# Enable IPv6
 | 
			
		||||
nginx[\"listen_addresses\"] = [\"[::]\", \"0.0.0.0\"]
 | 
			
		||||
nginx[\"listen_port\"] = $GITLAB_PORT
 | 
			
		||||
' >> /etc/gitlab/gitlab.rb"
 | 
			
		||||
docker exec gitlab gitlab-ctl reconfigure
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# echo "Patching openstreetmap container"
 | 
			
		||||
# maps
 | 
			
		||||
# docker exec openstreetmap-website-web-1 bin/rails db:migrate RAILS_ENV=development
 | 
			
		||||
							
								
								
									
										21
									
								
								06_serve_homepage.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
source ./00_vars.sh
 | 
			
		||||
 | 
			
		||||
# install flask in a venv
 | 
			
		||||
# apt install python3-venv -y
 | 
			
		||||
python3 -m venv venv
 | 
			
		||||
source venv/bin/activate
 | 
			
		||||
pip install flask
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
cd webarena-homepage
 | 
			
		||||
cp templates/index.backup templates/index.html
 | 
			
		||||
sed -i "s|SHOPPING_URL|${SHOPPING_URL}|g" templates/index.html
 | 
			
		||||
sed -i "s|SHOPPING_ADMIN_URL|${SHOPPING_ADMIN_URL}|g" templates/index.html
 | 
			
		||||
sed -i "s|GITLAB_URL|${GITLAB_URL}|g" templates/index.html
 | 
			
		||||
sed -i "s|REDDIT_URL|${REDDIT_URL}|g" templates/index.html
 | 
			
		||||
sed -i "s|MAP_URL|${MAP_URL}|g" templates/index.html
 | 
			
		||||
sed -i "s|WIKIPEDIA_URL|${WIKIPEDIA_URL}|g" templates/index.html
 | 
			
		||||
 | 
			
		||||
flask run --host=0.0.0.0 --port=$HOMEPAGE_PORT
 | 
			
		||||
							
								
								
									
										14
									
								
								07_serve_reset.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,14 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
source ./00_vars.sh
 | 
			
		||||
 | 
			
		||||
# install flask in a venv
 | 
			
		||||
# apt install python3-venv -y
 | 
			
		||||
python3 -m venv venv_reset
 | 
			
		||||
source venv_reset/bin/activate
 | 
			
		||||
 | 
			
		||||
cd reset_server/
 | 
			
		||||
python server.py --port ${RESET_PORT} 2>&1 | tee -a server.log
 | 
			
		||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,15 @@
 | 
			
		||||
 | 
			
		||||
# 简化部署WebArena-Lite环境
 | 
			
		||||
1. 只管理shopping, shopping_admin, gitlab, reddit四个网站。
 | 
			
		||||
2. Wiki在webarena-lite中移除,所以先不用部署
 | 
			
		||||
3. openstreetmap部署非常复杂,建议使用官网 https://opensteetmap.org
 | 
			
		||||
 | 
			
		||||
# 部署方法
 | 
			
		||||
1. 保证环境已经加载了四个网站的docker镜像,如果还没加载,使用`01_docker_load_images.sh`
 | 
			
		||||
2. 修改`00_vars.sh`,配置每个网页的端口
 | 
			
		||||
3. 拉起/重置环境,执行`sh reset.sh`
 | 
			
		||||
 | 
			
		||||
# 注意事项
 | 
			
		||||
1. 当前配置了访问url为`localhost`,所以只能同一台服务器上的程序能够访问,不能跨机器;
 | 
			
		||||
2. 可以使用vscode的端口映射功能映射到笔记本上,打开四个网站进行浏览。
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										75
									
								
								README_original.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,75 @@
 | 
			
		||||
> :warning: **This is not an official WebArena repo. For the official instructions refer to [WebArena](https://github.com/web-arena-x/webarena/tree/main/environment_docker)**
 | 
			
		||||
 | 
			
		||||
# webarena-setup
 | 
			
		||||
 | 
			
		||||
Setup scripts for webarena.
 | 
			
		||||
 | 
			
		||||
## Get the files
 | 
			
		||||
 | 
			
		||||
Download the necessary docker images from the [official webarena repo](https://github.com/web-arena-x/webarena/tree/main/environment_docker). You'll need the following files:
 | 
			
		||||
- shopping_final_0712.tar
 | 
			
		||||
- shopping_admin_final_0719.tar
 | 
			
		||||
- postmill-populated-exposed-withimg.tar
 | 
			
		||||
- gitlab-populated-final-port8023.tar
 | 
			
		||||
- wikipedia_en_all_maxi_2022-05.zim
 | 
			
		||||
 | 
			
		||||
Download the additional openstreetmap docker files from Zenodo:
 | 
			
		||||
```sh
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website-db.tar.gz
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website-web.tar.gz
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website.tar.gz
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(if you're planning to setup multiple instances, should download these files once in a shared location)
 | 
			
		||||
 | 
			
		||||
## Configure the scripts
 | 
			
		||||
 | 
			
		||||
Edit `00_vars.sh` with your ports and hostname (or ip address). You can also change `ARCHIVES_LOCATION="./"` to where your files are if you put them at a different location (like a shared folder).
 | 
			
		||||
 | 
			
		||||
## Extract / load the image files (very long, do it just once)
 | 
			
		||||
 | 
			
		||||
Untar the openstreemap docker folder:
 | 
			
		||||
```sh
 | 
			
		||||
tar -xzf ./openstreetmap-website.tar.gz
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Create a wiki folder and move (or copy) the wikipedia file to it
 | 
			
		||||
```sh
 | 
			
		||||
mkdir wiki
 | 
			
		||||
mv ./wikipedia_en_all_maxi_2022-05.zim wiki/
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Load the docker image files
 | 
			
		||||
```sh
 | 
			
		||||
sudo bash 01_docker_load_images.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Once these three steps are completed, you can get rid of the downloaded files (or unmount your shared folder) as these won't be needed any more.
 | 
			
		||||
 | 
			
		||||
## Run the server
 | 
			
		||||
 | 
			
		||||
Easiest way is to start a tmux or screen session, then run scripts 02 to 06 in order. The last script serves the homepage and should stay up.
 | 
			
		||||
```bash
 | 
			
		||||
sudo bash 02_docker_remove_containers.sh
 | 
			
		||||
sudo bash 03_docker_create_containers.sh
 | 
			
		||||
sudo bash 04_docker_start_containers.sh
 | 
			
		||||
sudo bash 05_docker_patch_containers.sh
 | 
			
		||||
sudo bash 06_serve_homepage.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Optional: to start the reset server (automated full instance resets) run the following in a side tmux or screen terminal
 | 
			
		||||
```bash
 | 
			
		||||
sudo bash 07_serve_reset.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then you can trigger a full instance reset by accessing `http://${PUBLIC_HOSTNAME}:${RESET_PORT}/reset` check the instance status via `http://${PUBLIC_HOSTNAME}:${RESET_PORT}/reset`.
 | 
			
		||||
 | 
			
		||||
## Safety check
 | 
			
		||||
 | 
			
		||||
Go to the homepage and click each link to make sure the websites are operational (some might take ~10 secs to load the first time).
 | 
			
		||||
 | 
			
		||||
## Reset
 | 
			
		||||
 | 
			
		||||
After an agent is evaluated on WebArena, a reset is required before another agent can be evaluated.
 | 
			
		||||
 | 
			
		||||
Run scripts 02 to 06 again, or query the reset URL `http://${PUBLIC_HOSTNAME}:${RESET_PORT}/reset` if the reset server is running.
 | 
			
		||||
							
								
								
									
										3
									
								
								download_openstreemap.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website-db.tar.gz
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website-web.tar.gz
 | 
			
		||||
wget https://zenodo.org/records/12636845/files/openstreetmap-website.tar.gz
 | 
			
		||||
							
								
								
									
										10
									
								
								reset.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
bash 02_docker_remove_containers.sh
 | 
			
		||||
bash 03_docker_create_containers.sh
 | 
			
		||||
bash 04_docker_start_containers.sh
 | 
			
		||||
bash 05_docker_patch_containers.sh
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								reset_server/fail_message
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										11
									
								
								reset_server/reset.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,11 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# stop if any error occur
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
cd ..
 | 
			
		||||
bash 02_docker_remove_containers.sh
 | 
			
		||||
bash 03_docker_create_containers.sh
 | 
			
		||||
bash 04_docker_start_containers.sh
 | 
			
		||||
bash 05_docker_patch_containers.sh
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2559
									
								
								reset_server/server.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										126
									
								
								reset_server/server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,126 @@
 | 
			
		||||
import argparse
 | 
			
		||||
import http.server
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import pathlib
 | 
			
		||||
import socketserver
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
import threading
 | 
			
		||||
 | 
			
		||||
# setup logging
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
handler = logging.StreamHandler(sys.stdout)
 | 
			
		||||
handler.setFormatter(logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s"))
 | 
			
		||||
logger.setLevel(logging.INFO)
 | 
			
		||||
logger.addHandler(handler)
 | 
			
		||||
 | 
			
		||||
# setup files config
 | 
			
		||||
lock_file_path = "reset.lock"
 | 
			
		||||
fail_file_path = "fail_message"
 | 
			
		||||
 | 
			
		||||
def write_fail_message(message: str):
 | 
			
		||||
    with open(fail_file_path, 'w') as f:
 | 
			
		||||
        f.write(message)
 | 
			
		||||
 | 
			
		||||
def read_fail_message():
 | 
			
		||||
    with open(fail_file_path, 'r') as f:
 | 
			
		||||
        fail_message = f.read()
 | 
			
		||||
    return fail_message
 | 
			
		||||
 | 
			
		||||
def reset_ongoing():
 | 
			
		||||
    return os.path.exists(lock_file_path)
 | 
			
		||||
 | 
			
		||||
def initiate_reset():
 | 
			
		||||
 | 
			
		||||
    # Attempt to acquire lock (create lock file atomically)
 | 
			
		||||
    try:
 | 
			
		||||
        fd = os.open(lock_file_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
 | 
			
		||||
        with os.fdopen(fd, 'w') as file:
 | 
			
		||||
            file.write('')  # empty file
 | 
			
		||||
    except FileExistsError:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    # Execute reset (and then release lock) in a separate thread
 | 
			
		||||
    def reset_fun():
 | 
			
		||||
        try:
 | 
			
		||||
            # Execute the reset script
 | 
			
		||||
            subprocess.run(['bash', 'reset.sh'], check=True)
 | 
			
		||||
            logger.info("Reset successful!")
 | 
			
		||||
            write_fail_message("")
 | 
			
		||||
        except subprocess.CalledProcessError as e:
 | 
			
		||||
            logger.info("Reset failed :(")
 | 
			
		||||
            write_fail_message(str(e))
 | 
			
		||||
 | 
			
		||||
        # Release lock (remove lock file)
 | 
			
		||||
        pathlib.Path(lock_file_path).unlink(missing_ok=True)
 | 
			
		||||
 | 
			
		||||
    thread = threading.Thread(target=reset_fun)
 | 
			
		||||
    thread.start()
 | 
			
		||||
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CustomHandler(http.server.SimpleHTTPRequestHandler):
 | 
			
		||||
    def do_GET(self):
 | 
			
		||||
        parsed_path = self.path
 | 
			
		||||
        logger.info(f"{parsed_path} request received")
 | 
			
		||||
        match parsed_path:
 | 
			
		||||
            case '/reset':
 | 
			
		||||
                if initiate_reset():
 | 
			
		||||
                    logger.info("Running reset script...")
 | 
			
		||||
                    self.send_response(200)  # OK
 | 
			
		||||
                    self.send_header('Content-type', 'text/html')
 | 
			
		||||
                    self.end_headers()
 | 
			
		||||
                    self.wfile.write(f'Reset initiated, check status <a href="/status">here</a>'.encode())
 | 
			
		||||
                else:
 | 
			
		||||
                    logger.warning("Reset already running, ignoring request.")
 | 
			
		||||
                    self.send_response(418)  # I'm a teapot
 | 
			
		||||
                    self.send_header('Content-type', 'text/html')
 | 
			
		||||
                    self.end_headers()
 | 
			
		||||
                    self.wfile.write(f'Reset already running, check status <a href="/status">here</a>'.encode())
 | 
			
		||||
            case "/status":
 | 
			
		||||
                fail_message = read_fail_message()
 | 
			
		||||
                if reset_ongoing():
 | 
			
		||||
                    logger.info("Returning ongoing status")
 | 
			
		||||
                    self.send_response(200)  # OK
 | 
			
		||||
                    self.send_header('Content-type', 'text/html')
 | 
			
		||||
                    self.end_headers()
 | 
			
		||||
                    self.wfile.write(f'Reset ongoing'.encode())
 | 
			
		||||
                elif fail_message:
 | 
			
		||||
                    logger.error("Returning error status")
 | 
			
		||||
                    self.send_response(500)  # Internal Server Error
 | 
			
		||||
                    self.send_header('Content-type', 'text/html')
 | 
			
		||||
                    self.end_headers()
 | 
			
		||||
                    self.wfile.write(f'Error executing reset script:<p>{fail_message}</p>'.encode())
 | 
			
		||||
                else:
 | 
			
		||||
                    logger.info("Returning ready status")
 | 
			
		||||
                    self.send_response(200)  # OK
 | 
			
		||||
                    self.send_header('Content-type', 'text/html')
 | 
			
		||||
                    self.end_headers()
 | 
			
		||||
                    self.wfile.write(f'Ready for duty!'.encode())
 | 
			
		||||
            case _:
 | 
			
		||||
                logger.info("Wrong request")
 | 
			
		||||
                self.send_response(404)  # Not Found
 | 
			
		||||
                self.send_header('Content-type', 'text/html')
 | 
			
		||||
                self.end_headers()
 | 
			
		||||
                self.wfile.write(f'Endpoint not found'.encode())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Parse command-line arguments
 | 
			
		||||
parser = argparse.ArgumentParser(description='Start a simple HTTP server to execute a reset script.')
 | 
			
		||||
parser.add_argument('--port', type=int, help='Port number the server will listen to')
 | 
			
		||||
args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
# Clear fail and lock files
 | 
			
		||||
write_fail_message("")
 | 
			
		||||
if reset_ongoing():
 | 
			
		||||
    os.remove(lock_file_path)
 | 
			
		||||
 | 
			
		||||
# Run the server
 | 
			
		||||
with http.server.ThreadingHTTPServer(('', args.port), CustomHandler) as httpd:
 | 
			
		||||
    logger.info(f'Serving on port {args.port}...')
 | 
			
		||||
    try:
 | 
			
		||||
        httpd.serve_forever()
 | 
			
		||||
    except KeyboardInterrupt:
 | 
			
		||||
        httpd.server_close()
 | 
			
		||||
							
								
								
									
										16
									
								
								serve_homepage.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
			
		||||
Requirement already satisfied: flask in ./venv/lib/python3.11/site-packages (3.1.0)
 | 
			
		||||
Requirement already satisfied: Werkzeug>=3.1 in ./venv/lib/python3.11/site-packages (from flask) (3.1.3)
 | 
			
		||||
Requirement already satisfied: Jinja2>=3.1.2 in ./venv/lib/python3.11/site-packages (from flask) (3.1.6)
 | 
			
		||||
Requirement already satisfied: itsdangerous>=2.2 in ./venv/lib/python3.11/site-packages (from flask) (2.2.0)
 | 
			
		||||
Requirement already satisfied: click>=8.1.3 in ./venv/lib/python3.11/site-packages (from flask) (8.1.8)
 | 
			
		||||
Requirement already satisfied: blinker>=1.9 in ./venv/lib/python3.11/site-packages (from flask) (1.9.0)
 | 
			
		||||
Requirement already satisfied: MarkupSafe>=2.0 in ./venv/lib/python3.11/site-packages (from Jinja2>=3.1.2->flask) (3.0.2)
 | 
			
		||||
 | 
			
		||||
[notice] A new release of pip is available: 24.0 -> 25.0.1
 | 
			
		||||
[notice] To update, run: pip install --upgrade pip
 | 
			
		||||
 * Debug mode: off
 | 
			
		||||
[31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
 | 
			
		||||
 * Running on all addresses (0.0.0.0)
 | 
			
		||||
 * Running on http://127.0.0.1:20080
 | 
			
		||||
 * Running on http://192.168.16.114:20080
 | 
			
		||||
[33mPress CTRL+C to quit[0m
 | 
			
		||||
							
								
								
									
										22
									
								
								service.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,22 @@
 | 
			
		||||
# WebArena实例服务
 | 
			
		||||
 | 
			
		||||
## 1. 背景
 | 
			
		||||
 | 
			
		||||
操作智能体项目在数据采集、模型训练、模型推理评估等环节,需要频繁的与WebArena实例服务进行交互。交互过程会对WebArena实例进行状态的修改,因此需要对WebArena实例服务进行实例化。
 | 
			
		||||
通过统一个管理服务实现WebArena实例的自动创建、销毁、状态查询等操作。
 | 
			
		||||
 | 
			
		||||
## 2. 架构
 | 
			
		||||
 | 
			
		||||
服务包含以下几个部分:
 | 
			
		||||
- 前端控制台:提供网页界面,可以实现服务器管理、WebArena实例的创建、销毁、状态查询等操作。
 | 
			
		||||
- 后端服务:提供WebArena实例的创建、销毁、状态查询等操作。
 | 
			
		||||
 | 
			
		||||
## 3. 使用流程
 | 
			
		||||
 | 
			
		||||
### 3.1 创建WebArena实例
 | 
			
		||||
 | 
			
		||||
### 3.2 销毁WebArena实例
 | 
			
		||||
 | 
			
		||||
### 3.3 查询WebArena实例状态
 | 
			
		||||
 | 
			
		||||
### 3.4 查询WebArena实例日志
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/__pycache__/app.cpython-311.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										27
									
								
								webarena-homepage/app.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,27 @@
 | 
			
		||||
from flask import Flask, render_template
 | 
			
		||||
 | 
			
		||||
app = Flask(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/")
 | 
			
		||||
def index() -> str:
 | 
			
		||||
    return render_template("index.html")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/scratchpad.html")
 | 
			
		||||
def scratchpad() -> str:
 | 
			
		||||
    return render_template("scratchpad.html")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/calculator.html")
 | 
			
		||||
def calculator() -> str:
 | 
			
		||||
    return render_template("calculator.html")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/password.html")
 | 
			
		||||
def password() -> str:
 | 
			
		||||
    return render_template("password.html")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    app.run(host="0.0.0.0", port=4399)
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/calculator.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 168 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/cms.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 382 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/gitlab.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 42 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/manual1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 174 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/manual2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 182 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/map.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 779 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/onestopshop.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 220 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/password.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 20 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/reddit.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 61 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/scratchpad.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 143 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								webarena-homepage/static/figures/wikipedia.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 698 KiB  | 
							
								
								
									
										109
									
								
								webarena-homepage/templates/calculator.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,109 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <title>Calculator</title>
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            height: 100vh;
 | 
			
		||||
            background-color: #f2f2f2;
 | 
			
		||||
            font-family: Arial, sans-serif;
 | 
			
		||||
        }
 | 
			
		||||
        #calculator {
 | 
			
		||||
            border: 1px solid #333;
 | 
			
		||||
            padding: 30px;
 | 
			
		||||
            border-radius: 10px;
 | 
			
		||||
            width: 400px;
 | 
			
		||||
            background-color: #fff;
 | 
			
		||||
            box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
            align-items: flex-end;
 | 
			
		||||
        }
 | 
			
		||||
        #calculator h1 {
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            margin-bottom: 20px;
 | 
			
		||||
            align-self: center;
 | 
			
		||||
        }
 | 
			
		||||
        #calculator p {
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            margin-bottom: 20px;
 | 
			
		||||
            color: #666;
 | 
			
		||||
            align-self: center;
 | 
			
		||||
        }
 | 
			
		||||
        #inputExpression {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            padding: 15px;
 | 
			
		||||
            font-size: 18px;
 | 
			
		||||
            border-radius: 5px;
 | 
			
		||||
            border: 1px solid #ddd;
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            margin-bottom: 10px;
 | 
			
		||||
        }
 | 
			
		||||
        #result {
 | 
			
		||||
            margin-top: 20px;
 | 
			
		||||
            font-size: 20px;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            color: #333;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            align-self: center;
 | 
			
		||||
        }
 | 
			
		||||
        button {
 | 
			
		||||
            padding: 10px 20px;
 | 
			
		||||
            margin-top: 10px;
 | 
			
		||||
            font-size: 18px;
 | 
			
		||||
            border: none;
 | 
			
		||||
            border-radius: 5px;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
            align-self: flex-end;
 | 
			
		||||
        }
 | 
			
		||||
        #calculate {
 | 
			
		||||
            background-color: #4CAF50;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
        #clear {
 | 
			
		||||
            background-color: #f44336;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="calculator">
 | 
			
		||||
        <h1>Calculator</h1>
 | 
			
		||||
        <p>Enter the expression and get the results</p>
 | 
			
		||||
        <input type="text" id="inputExpression" placeholder="Enter expression" />
 | 
			
		||||
        <button id="calculate">=</button>
 | 
			
		||||
        <button id="clear">Clear</button>
 | 
			
		||||
        <div id="result">Result: <span id="calculationResult"></span></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        document.getElementById('calculate').addEventListener('click', function() {
 | 
			
		||||
            try {
 | 
			
		||||
                const result = eval(document.getElementById('inputExpression').value);
 | 
			
		||||
                if (!isNaN(result)) {
 | 
			
		||||
                    document.getElementById('calculationResult').textContent = result;
 | 
			
		||||
                } else {
 | 
			
		||||
                    document.getElementById('calculationResult').textContent = 'Invalid expression';
 | 
			
		||||
                }
 | 
			
		||||
            } catch {
 | 
			
		||||
                document.getElementById('calculationResult').textContent = 'Invalid expression';
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        document.getElementById('clear').addEventListener('click', function() {
 | 
			
		||||
            document.getElementById('inputExpression').value = '';
 | 
			
		||||
            document.getElementById('calculationResult').textContent = '';
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        document.getElementById('inputExpression').addEventListener('keypress', function(e) {
 | 
			
		||||
            if (e.key === 'Enter') {
 | 
			
		||||
                document.getElementById('calculate').click();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										157
									
								
								webarena-homepage/templates/index.backup
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,157 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <title>Homepage</title>
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: Arial, sans-serif;
 | 
			
		||||
            background-color: white;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            line-height: 1.6;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #container {
 | 
			
		||||
            width: 90%;
 | 
			
		||||
            margin: auto;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #header {
 | 
			
		||||
            background-color: #f4f7f9;
 | 
			
		||||
            color: #232f34;
 | 
			
		||||
            padding-top: 30px;
 | 
			
		||||
            min-height: 70px;
 | 
			
		||||
            border-bottom: #b1c1c6 3px solid;
 | 
			
		||||
            font-family: 'Roboto', sans-serif;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #header h1 {
 | 
			
		||||
            padding: 5px;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card {
 | 
			
		||||
            border: 1px solid #ddd;
 | 
			
		||||
            border-radius: 5px;
 | 
			
		||||
            width: 200px; /* Changed width */
 | 
			
		||||
            height: 200px; /* Added height */
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            margin: 10px;
 | 
			
		||||
            padding: 10px;
 | 
			
		||||
            box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            overflow: auto; /* To handle content that might overflow */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card img {
 | 
			
		||||
            width: 35%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card h2 {
 | 
			
		||||
            font-size: 15px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card p {
 | 
			
		||||
            font-size: 14px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card a {
 | 
			
		||||
            color: #35424a;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="container">
 | 
			
		||||
        <div id="header">
 | 
			
		||||
            <h1>Welcome to WebArena</h1>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="OneStopShop">
 | 
			
		||||
         <img src="{{ url_for('static', filename='figures/onestopshop.png') }}"  alt="Logo for OneStopShop">
 | 
			
		||||
         <a href="SHOPPING_URL">
 | 
			
		||||
            <h2 id="appName">OneStopShop</h2>
 | 
			
		||||
         </a>
 | 
			
		||||
         <p id="appDescription">An online shopping site</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Merchant Admin Portal">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/cms.png') }}"  alt="Logo for CMS">
 | 
			
		||||
            <a href="SHOPPING_ADMIN_URL">
 | 
			
		||||
                <h2 id="appName">Merchant Admin Portal</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">An admin portal to manage E-commerce business (u: admin, p: admin1234)</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Reddit">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/reddit.png') }}"  alt="Logo for Reddit">
 | 
			
		||||
            <a href="REDDIT_URL">
 | 
			
		||||
                <h2 id="appName">Reddit</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A social news aggregation and discussion website</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Gitlab">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/gitlab.png') }}"  alt="Logo for Gitlab">
 | 
			
		||||
            <a href="GITLAB_URL">
 | 
			
		||||
                <h2 id="appName">Gitlab</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">a DevOps software</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Map">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/map.png') }}"  alt="Logo for Map">
 | 
			
		||||
            <a href="MAP_URL">
 | 
			
		||||
                <h2 id="appName">OpenStreetMap</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">North east US map</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Calculator">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/calculator.png') }}"  alt="Logo for Calculator">
 | 
			
		||||
            <a href="calculator.html">
 | 
			
		||||
                <h2 id="appName">Calculator</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A calculator</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Scratchpad">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/scratchpad.png') }}"  alt="Logo for Scratchpad">
 | 
			
		||||
            <a href="scratchpad.html">
 | 
			
		||||
                <h2 id="appName">Scratchpad</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A scratchpad for taking notes</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Wikipedia">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/wikipedia.png') }}"  alt="Logo for Wikipedia">
 | 
			
		||||
            <a href="WIKIPEDIA_URL">
 | 
			
		||||
                <h2 id="appName">Wikipedia</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">An online encyclopedia</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Gitlab Manual">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/manual1.png') }}"  alt="Logo for Gitlab Manual">
 | 
			
		||||
            <a href="https://docs.gitlab.com/">
 | 
			
		||||
                <h2 id="appName">Gitlab Documentation</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">Documentation for GitLab</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Admin Manual">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/manual2.png') }}"  alt="Logo for Admin Manual">
 | 
			
		||||
            <a href="https://experienceleague.adobe.com/docs/commerce-admin/user-guides/home.html?lang=en">
 | 
			
		||||
                <h2 id="appName">Admin Portal Manual</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">Manual on using the admin portal</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- Repeat the above card structure for each app -->
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										157
									
								
								webarena-homepage/templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,157 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <title>Homepage</title>
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: Arial, sans-serif;
 | 
			
		||||
            background-color: white;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            line-height: 1.6;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #container {
 | 
			
		||||
            width: 90%;
 | 
			
		||||
            margin: auto;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #header {
 | 
			
		||||
            background-color: #f4f7f9;
 | 
			
		||||
            color: #232f34;
 | 
			
		||||
            padding-top: 30px;
 | 
			
		||||
            min-height: 70px;
 | 
			
		||||
            border-bottom: #b1c1c6 3px solid;
 | 
			
		||||
            font-family: 'Roboto', sans-serif;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #header h1 {
 | 
			
		||||
            padding: 5px;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            font-weight: 500;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card {
 | 
			
		||||
            border: 1px solid #ddd;
 | 
			
		||||
            border-radius: 5px;
 | 
			
		||||
            width: 200px; /* Changed width */
 | 
			
		||||
            height: 200px; /* Added height */
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            margin: 10px;
 | 
			
		||||
            padding: 10px;
 | 
			
		||||
            box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            overflow: auto; /* To handle content that might overflow */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card img {
 | 
			
		||||
            width: 35%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card h2 {
 | 
			
		||||
            font-size: 15px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card p {
 | 
			
		||||
            font-size: 14px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .card a {
 | 
			
		||||
            color: #35424a;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="container">
 | 
			
		||||
        <div id="header">
 | 
			
		||||
            <h1>Welcome to WebArena</h1>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="OneStopShop">
 | 
			
		||||
         <img src="{{ url_for('static', filename='figures/onestopshop.png') }}"  alt="Logo for OneStopShop">
 | 
			
		||||
         <a href="http://localhost:28082">
 | 
			
		||||
            <h2 id="appName">OneStopShop</h2>
 | 
			
		||||
         </a>
 | 
			
		||||
         <p id="appDescription">An online shopping site</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Merchant Admin Portal">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/cms.png') }}"  alt="Logo for CMS">
 | 
			
		||||
            <a href="http://localhost:28083/admin">
 | 
			
		||||
                <h2 id="appName">Merchant Admin Portal</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">An admin portal to manage E-commerce business (u: admin, p: admin1234)</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Reddit">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/reddit.png') }}"  alt="Logo for Reddit">
 | 
			
		||||
            <a href="http://localhost:28080/forums/all">
 | 
			
		||||
                <h2 id="appName">Reddit</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A social news aggregation and discussion website</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Gitlab">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/gitlab.png') }}"  alt="Logo for Gitlab">
 | 
			
		||||
            <a href="http://localhost:28084/explore">
 | 
			
		||||
                <h2 id="appName">Gitlab</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">a DevOps software</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Map">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/map.png') }}"  alt="Logo for Map">
 | 
			
		||||
            <a href="https://www.openstreetmap.org/">
 | 
			
		||||
                <h2 id="appName">OpenStreetMap</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">North east US map</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Calculator">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/calculator.png') }}"  alt="Logo for Calculator">
 | 
			
		||||
            <a href="calculator.html">
 | 
			
		||||
                <h2 id="appName">Calculator</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A calculator</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Scratchpad">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/scratchpad.png') }}"  alt="Logo for Scratchpad">
 | 
			
		||||
            <a href="scratchpad.html">
 | 
			
		||||
                <h2 id="appName">Scratchpad</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">A scratchpad for taking notes</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Wikipedia">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/wikipedia.png') }}"  alt="Logo for Wikipedia">
 | 
			
		||||
            <a href="http://localhost:28081/wikipedia_en_all_maxi_2022-05/A/User:The_other_Kiwix_guy/Landing">
 | 
			
		||||
                <h2 id="appName">Wikipedia</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">An online encyclopedia</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Gitlab Manual">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/manual1.png') }}"  alt="Logo for Gitlab Manual">
 | 
			
		||||
            <a href="https://docs.gitlab.com/">
 | 
			
		||||
                <h2 id="appName">Gitlab Documentation</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">Documentation for GitLab</p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card" role="region" aria-label="Admin Manual">
 | 
			
		||||
            <img src="{{ url_for('static', filename='figures/manual2.png') }}"  alt="Logo for Admin Manual">
 | 
			
		||||
            <a href="https://experienceleague.adobe.com/docs/commerce-admin/user-guides/home.html?lang=en">
 | 
			
		||||
                <h2 id="appName">Admin Portal Manual</h2>
 | 
			
		||||
            </a>
 | 
			
		||||
            <p id="appDescription">Manual on using the admin portal</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- Repeat the above card structure for each app -->
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										122
									
								
								webarena-homepage/templates/scratchpad.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,122 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="UTF-8">
 | 
			
		||||
  <title>Note Taking App</title>
 | 
			
		||||
  <style>
 | 
			
		||||
    body {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: flex-start;
 | 
			
		||||
      min-height: 100vh;
 | 
			
		||||
      margin: 0;
 | 
			
		||||
      font-family: Arial, sans-serif;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    h1 {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #note-creation {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      margin-bottom: 20px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #note-form {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      width: 300px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #note-input {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      min-height: 300px;
 | 
			
		||||
      max-height: 900px;
 | 
			
		||||
      min-width: 600px;
 | 
			
		||||
      max-width: 600px;
 | 
			
		||||
      padding: 10px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      border-radius: 4px;
 | 
			
		||||
      border: 1px solid #ddd;
 | 
			
		||||
      overflow-y: auto;
 | 
			
		||||
      resize: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #note-form button {
 | 
			
		||||
      padding: 10px 20px;
 | 
			
		||||
      margin-top: 10px;
 | 
			
		||||
      color: white;
 | 
			
		||||
      background-color: #007bff;
 | 
			
		||||
      border: none;
 | 
			
		||||
      border-radius: 4px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      text-decoration: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #note-form button:hover {
 | 
			
		||||
      background-color: #0056b3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #notes-display {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      align-items: left;
 | 
			
		||||
      width: 600px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .note {
 | 
			
		||||
      margin: 1em 0;
 | 
			
		||||
      padding: 1em;
 | 
			
		||||
      border: 1px solid #ddd;
 | 
			
		||||
      border-radius: 4px;
 | 
			
		||||
      background: #f9f9f9;
 | 
			
		||||
      white-space: pre-wrap;
 | 
			
		||||
    }
 | 
			
		||||
  </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <header>
 | 
			
		||||
    <h1>My Notes</h1>
 | 
			
		||||
  </header>
 | 
			
		||||
 | 
			
		||||
  <main>
 | 
			
		||||
    <section id="note-creation">
 | 
			
		||||
      <form id="note-form">
 | 
			
		||||
        <textarea id="note-input" placeholder="Type your note here..."></textarea>
 | 
			
		||||
        <button type="submit">Add Note</button>
 | 
			
		||||
      </form>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    <h2>History</h2>
 | 
			
		||||
 | 
			
		||||
    <section id="notes-display">
 | 
			
		||||
      <!-- Notes will be dynamically added here -->
 | 
			
		||||
    </section>
 | 
			
		||||
  </main>
 | 
			
		||||
 | 
			
		||||
  <script>
 | 
			
		||||
    const form = document.querySelector("#note-form");
 | 
			
		||||
    const noteInput = document.querySelector("#note-input");
 | 
			
		||||
    const notesDisplay = document.querySelector("#notes-display");
 | 
			
		||||
 | 
			
		||||
    form.addEventListener("submit", (event) => {
 | 
			
		||||
      event.preventDefault();
 | 
			
		||||
 | 
			
		||||
      const note = document.createElement("div");
 | 
			
		||||
      note.classList.add("note");
 | 
			
		||||
      note.textContent = noteInput.value;
 | 
			
		||||
 | 
			
		||||
      note.innerHTML = noteInput.value.replace(/\n/g, '<br>');
 | 
			
		||||
      note.tabIndex = 0;
 | 
			
		||||
 | 
			
		||||
      notesDisplay.prepend(note);
 | 
			
		||||
      noteInput.value = '';
 | 
			
		||||
    });
 | 
			
		||||
  </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										27
									
								
								wiki_patch/start.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,27 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# path: /usr/local/bin/start.sh
 | 
			
		||||
 | 
			
		||||
# Download if necessary a file
 | 
			
		||||
if [ ! -z "$DOWNLOAD" ]
 | 
			
		||||
then
 | 
			
		||||
    ZIM=`basename $DOWNLOAD`
 | 
			
		||||
    wget $DOWNLOAD -O "$ZIM"
 | 
			
		||||
 | 
			
		||||
    # Set arguments
 | 
			
		||||
    if [ "$#" -eq "0" ]
 | 
			
		||||
    then
 | 
			
		||||
        set -- "$@" $ZIM
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
CMD="/usr/local/bin/kiwix-serve -v --port=$2 $1"
 | 
			
		||||
echo $CMD
 | 
			
		||||
$CMD
 | 
			
		||||
 | 
			
		||||
# If error, print the content of /data
 | 
			
		||||
if [ $? -ne 0 ]
 | 
			
		||||
then
 | 
			
		||||
    echo "Here is the content of /data:"
 | 
			
		||||
    find /data -type f
 | 
			
		||||
fi
 | 
			
		||||