├── hub ├── priv │ ├── .gitignore │ └── logic.sh ├── rebar ├── start-dev.cmd ├── .gitignore ├── start-dev.sh ├── include │ └── hub.hrl ├── rebar.config ├── Makefile └── src │ ├── config.erl │ ├── hub_app.erl │ ├── hub.erl │ ├── pie_sup.erl │ ├── logic_sup.erl │ ├── hub.app.src │ ├── hub_api.erl │ ├── mqueue.erl │ ├── api.erl │ ├── hub_sup.erl │ ├── logic.erl │ ├── hub_web.erl │ ├── chanlist.erl │ ├── logic_worker.erl │ ├── router.erl │ ├── chan.erl │ ├── hub_deps.erl │ └── stats.erl ├── static ├── kml │ └── .gitignore ├── banner │ └── .gitignore ├── favicon.ico ├── favicon.png ├── img │ ├── l.gif │ ├── onl.png │ ├── up.png │ ├── close.png │ ├── down.png │ ├── logo.png │ ├── quest.png │ ├── collapse.png │ ├── exclam.png │ ├── expand.png │ ├── screenshot.png │ └── progress1-demo.png ├── fonts │ ├── monofont.ttf │ └── captchafont.gdf ├── openlayers │ └── theme │ │ └── default │ │ ├── img │ │ ├── blank.gif │ │ ├── close.gif │ │ ├── ruler.png │ │ ├── pan_off.png │ │ ├── pan_on.png │ │ ├── pan-panel.png │ │ ├── zoom-panel.png │ │ ├── add_point_off.png │ │ ├── add_point_on.png │ │ ├── draw_line_off.png │ │ ├── draw_line_on.png │ │ ├── draw_point_on.png │ │ ├── view_next_off.png │ │ ├── view_next_on.png │ │ ├── draw_point_off.png │ │ ├── draw_polygon_on.png │ │ ├── move_feature_on.png │ │ ├── panning-hand-on.png │ │ ├── remove_point_on.png │ │ ├── drag-rectangle-off.png │ │ ├── drag-rectangle-on.png │ │ ├── draw_polygon_off.png │ │ ├── editing_tool_bar.png │ │ ├── move_feature_off.png │ │ ├── navigation_history.png │ │ ├── pan-panel-NOALPHA.png │ │ ├── panning-hand-off.png │ │ ├── remove_point_off.png │ │ ├── save_features_off.png │ │ ├── save_features_on.png │ │ ├── view_previous_off.png │ │ ├── view_previous_on.png │ │ ├── zoom-panel-NOALPHA.png │ │ └── overview_replacement.gif │ │ ├── ie6-style.tidy.css │ │ ├── google.tidy.css │ │ ├── ie6-style.css │ │ ├── google.css │ │ ├── style.mobile.tidy.css │ │ └── style.mobile.css ├── css │ ├── redmond │ │ └── images │ │ │ ├── ui-icons_217bc0_256x240.png │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ ├── ui-icons_469bdd_256x240.png │ │ │ ├── ui-icons_6da8d5_256x240.png │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ ├── ui-icons_d8e7f3_256x240.png │ │ │ ├── ui-icons_f9bd01_256x240.png │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ ├── ui-bg_flat_55_fbec88_40x100.png │ │ │ ├── ui-bg_glass_75_d0e5f5_1x400.png │ │ │ ├── ui-bg_glass_85_dfeffc_1x400.png │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ ├── ui-bg_inset-hard_100_f5f8f9_1x100.png │ │ │ ├── ui-bg_inset-hard_100_fcfdfd_1x100.png │ │ │ └── ui-bg_gloss-wave_55_5c9ccc_500x100.png │ ├── cupertino │ │ └── images │ │ │ ├── ui-icons_2694e8_256x240.png │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ ├── ui-icons_3d80b3_256x240.png │ │ │ ├── ui-icons_72a7cf_256x240.png │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ ├── ui-bg_flat_15_cd0a0a_40x100.png │ │ │ ├── ui-bg_glass_100_e4f1fb_1x400.png │ │ │ ├── ui-bg_glass_50_3baae3_1x400.png │ │ │ ├── ui-bg_glass_80_d7ebf9_1x400.png │ │ │ ├── ui-bg_highlight-hard_70_000000_1x100.png │ │ │ ├── ui-bg_highlight-soft_25_ffef8f_1x100.png │ │ │ ├── ui-bg_diagonals-thick_90_eeeeee_40x40.png │ │ │ ├── ui-bg_highlight-hard_100_f2f5f7_1x100.png │ │ │ └── ui-bg_highlight-soft_100_deedf7_1x100.png │ ├── mapcraft │ │ └── images │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_454545_256x240.png │ │ │ ├── ui-icons_888888_256x240.png │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ ├── ui-bg_flat_0_92836c_40x100.png │ │ │ ├── ui-bg_flat_0_ffffff_40x100.png │ │ │ ├── ui-bg_flat_55_6d926c_40x100.png │ │ │ ├── ui-bg_flat_75_637d8c_40x100.png │ │ │ ├── ui-bg_flat_75_e6e6e6_40x100.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_flat_95_92836c_40x100.png │ │ │ └── ui-bg_glass_65_ffffff_1x400.png │ ├── smoothness │ │ └── images │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ ├── ui-icons_454545_256x240.png │ │ │ ├── ui-icons_888888_256x240.png │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-lightness │ │ └── images │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png │ ├── jquery-theme-patch.css │ ├── log.css │ └── style_leaflet.css ├── js │ ├── config.js.example │ ├── lang │ │ ├── jp.js │ │ ├── en.js │ │ ├── pl.js │ │ ├── it.js │ │ ├── es.js │ │ ├── fr.js │ │ ├── de.js │ │ ├── sk.js │ │ ├── ru.js │ │ └── uk.js │ └── app_list.js ├── index.html └── help │ └── josm-remote-troubleshoot.en.html ├── data ├── wms │ └── .gitignore ├── fonts │ ├── fonts.txt │ └── Vera.ttf ├── scheme │ ├── Makefile │ └── migrations │ │ ├── 003-add-pies-settings.php │ │ ├── 004-add-pie-updated.php │ │ ├── 002-fix-ownerships.php │ │ └── 001-add-pieces-index.php └── seed │ ├── Makefile │ └── wms │ ├── 1.map │ ├── 2.map │ └── 3.map ├── .gitignore ├── configs ├── hub.config.template └── nginx.conf.devenv ├── app ├── init_session.php ├── refresher.php ├── pie_stat.php ├── json_pies.php ├── export.php ├── auth_osm.php ├── auth_fake.php ├── auth.php ├── log.php ├── index.php ├── map.php ├── oauth_callback.php ├── delete.php ├── load.php └── list.php ├── lib ├── _footer.php ├── config.php.template ├── validators.php ├── _header.php ├── update_kml.php ├── api.php ├── Log │ ├── null.php │ ├── observer.php │ └── error_log.php ├── drawers │ └── progress1.php ├── db │ └── sessions.php └── create_map.php ├── logic ├── eggs.php ├── test.sh ├── test.sh.save ├── chat.php ├── main.php ├── users.php └── cake.php ├── apache2.conf.example ├── LICENSE ├── nginx.conf.example ├── scripts ├── apache ├── common.sh ├── nginx ├── hub ├── code-reloader ├── env └── nodetool └── README.md /hub/priv/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/kml/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /data/wms/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /static/banner/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /data/fonts/fonts.txt: -------------------------------------------------------------------------------- 1 | sans Vera.ttf 2 | -------------------------------------------------------------------------------- /hub/rebar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/hub/rebar -------------------------------------------------------------------------------- /hub/priv/logic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ../logic; 4 | exec php ./main.php "$@" 5 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/favicon.png -------------------------------------------------------------------------------- /static/img/l.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/l.gif -------------------------------------------------------------------------------- /static/img/onl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/onl.png -------------------------------------------------------------------------------- /static/img/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/up.png -------------------------------------------------------------------------------- /data/fonts/Vera.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/data/fonts/Vera.ttf -------------------------------------------------------------------------------- /static/img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/close.png -------------------------------------------------------------------------------- /static/img/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/down.png -------------------------------------------------------------------------------- /static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/logo.png -------------------------------------------------------------------------------- /static/img/quest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/quest.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Config files: 2 | 3 | static/js/config.js 4 | lib/config.php 5 | /tmp 6 | /logs 7 | -------------------------------------------------------------------------------- /static/img/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/collapse.png -------------------------------------------------------------------------------- /static/img/exclam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/exclam.png -------------------------------------------------------------------------------- /static/img/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/expand.png -------------------------------------------------------------------------------- /hub/start-dev.cmd: -------------------------------------------------------------------------------- 1 | erl -pa ebin edit deps/*/ebin -boot start_sasl -sname hub_dev -s hub -s reloader 2 | -------------------------------------------------------------------------------- /static/fonts/monofont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/fonts/monofont.ttf -------------------------------------------------------------------------------- /static/img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/screenshot.png -------------------------------------------------------------------------------- /static/fonts/captchafont.gdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/fonts/captchafont.gdf -------------------------------------------------------------------------------- /static/img/progress1-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/img/progress1-demo.png -------------------------------------------------------------------------------- /hub/.gitignore: -------------------------------------------------------------------------------- 1 | /ebin 2 | /doc 3 | /_test 4 | /.eunit 5 | /docs 6 | .DS_Store 7 | /TEST-*.xml 8 | /deps 9 | erl_crash.dump -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/blank.gif -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/close.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/close.gif -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/ruler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/ruler.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/pan_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/pan_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/pan_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/pan_on.png -------------------------------------------------------------------------------- /data/scheme/Makefile: -------------------------------------------------------------------------------- 1 | DB_NAME=mapcraft-devel 2 | 3 | all: 4 | @echo "Usage:\n make update" 5 | 6 | update: 7 | pg_dump -s ${DB_NAME} >scheme.sql 8 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/pan-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/pan-panel.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/zoom-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/zoom-panel.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_217bc0_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_217bc0_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_469bdd_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_469bdd_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_6da8d5_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_6da8d5_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_d8e7f3_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_d8e7f3_256x240.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-icons_f9bd01_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-icons_f9bd01_256x240.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/add_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/add_point_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/add_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/add_point_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_line_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_line_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_line_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_line_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_point_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/view_next_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/view_next_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/view_next_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/view_next_on.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-icons_2694e8_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-icons_2694e8_256x240.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-icons_3d80b3_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-icons_3d80b3_256x240.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-icons_72a7cf_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-icons_72a7cf_256x240.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_point_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_polygon_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_polygon_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/move_feature_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/move_feature_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/panning-hand-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/panning-hand-on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/remove_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/remove_point_on.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_0_92836c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_0_92836c_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_0_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_0_ffffff_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_55_6d926c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_55_6d926c_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_75_637d8c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_75_637d8c_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_75_e6e6e6_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_75_e6e6e6_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_flat_95_92836c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_flat_95_92836c_40x100.png -------------------------------------------------------------------------------- /static/css/mapcraft/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/mapcraft/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/drag-rectangle-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/drag-rectangle-off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/drag-rectangle-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/drag-rectangle-on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/draw_polygon_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/draw_polygon_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/editing_tool_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/editing_tool_bar.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/move_feature_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/move_feature_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/navigation_history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/navigation_history.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/pan-panel-NOALPHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/pan-panel-NOALPHA.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/panning-hand-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/panning-hand-off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/remove_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/remove_point_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/save_features_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/save_features_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/save_features_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/save_features_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/view_previous_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/view_previous_off.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/view_previous_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/view_previous_on.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/zoom-panel-NOALPHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/zoom-panel-NOALPHA.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_flat_15_cd0a0a_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_flat_15_cd0a0a_40x100.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_glass_100_e4f1fb_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_glass_100_e4f1fb_1x400.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_glass_50_3baae3_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_glass_50_3baae3_1x400.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_glass_80_d7ebf9_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_glass_80_d7ebf9_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /static/openlayers/theme/default/img/overview_replacement.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/openlayers/theme/default/img/overview_replacement.gif -------------------------------------------------------------------------------- /hub/start-dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd $(dirname $0) 3 | exec erl -pa ebin edit deps/*/ebin "$@" -boot start_sasl \ 4 | -sname hub_dev \ 5 | -s hub \ 6 | -s reloader 7 | -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /static/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_highlight-hard_70_000000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_highlight-hard_70_000000_1x100.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_highlight-soft_25_ffef8f_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_highlight-soft_25_ffef8f_1x100.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png -------------------------------------------------------------------------------- /static/css/cupertino/images/ui-bg_highlight-soft_100_deedf7_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/cupertino/images/ui-bg_highlight-soft_100_deedf7_1x100.png -------------------------------------------------------------------------------- /static/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Foxhind/MapCraft/HEAD/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /configs/hub.config.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; indent-tabs-mode: nil -*- 2 | [ 3 | {hub, [ 4 | {port, ${HUB_PORT}} 5 | ]}, 6 | {gproc, [ 7 | ${GPROC_OPTIONS} 8 | ]} 9 | ]. 10 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/ie6-style.tidy.css: -------------------------------------------------------------------------------- 1 | .olControlZoomPanel div{background-image:url(img/zoom-panel-NOALPHA.png);}.olControlPanPanel div{background-image:url(img/pan-panel-NOALPHA.png);}.olControlEditingToolbar{width:200px;} -------------------------------------------------------------------------------- /data/seed/Makefile: -------------------------------------------------------------------------------- 1 | DB_NAME=mapcraft-devel 2 | 3 | all: 4 | @echo "Usage:\n make update" 5 | 6 | update: 7 | pg_dump -a ${DB_NAME} >seed.sql 8 | cp -f ../../static/kml/*.kml kml 9 | cp -f ../../data/wms/*.map wms 10 | 11 | -------------------------------------------------------------------------------- /app/init_session.php: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /hub/include/hub.hrl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -record(hub_chan, { 4 | pieid, 5 | sesid, 6 | tabid 7 | }). 8 | 9 | -record(hub_req, { 10 | pieid, 11 | sesid, 12 | tabid, 13 | type, 14 | caller, 15 | cmd 16 | }). 17 | -------------------------------------------------------------------------------- /lib/_footer.php: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/google.tidy.css: -------------------------------------------------------------------------------- 1 | .olLayerGoogleCopyright{right:3px;bottom:2px;left:auto;}.olLayerGoogleV3.olLayerGoogleCopyright{bottom:0;right:0!important;}.olLayerGooglePoweredBy{left:2px;bottom:2px;}.olLayerGoogleV3.olLayerGooglePoweredBy{bottom:0!important;} -------------------------------------------------------------------------------- /static/js/config.js.example: -------------------------------------------------------------------------------- 1 | MapCraft = {}; 2 | 3 | MapCraft.config = { 4 | hub_url: "/hub", 5 | // hub_url: "http://localhost:8080/hub", // local CORS \ 6 | // hub_url: "http://example.com:8080/hub", // external CORS - do not forget to set 'origin' in the hub config 7 | } 8 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/ie6-style.css: -------------------------------------------------------------------------------- 1 | .olControlZoomPanel div { 2 | background-image: url(img/zoom-panel-NOALPHA.png); 3 | } 4 | .olControlPanPanel div { 5 | background-image: url(img/pan-panel-NOALPHA.png); 6 | } 7 | .olControlEditingToolbar { 8 | width: 200px; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /hub/rebar.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; indent-tabs-mode: nil -*- 2 | {erl_opts, [debug_info]}. 3 | {deps, [ 4 | {mochiweb, ".*", 5 | {git, "git://github.com/mochi/mochiweb.git", "master"}}, 6 | {gproc, ".*", 7 | {git, "http://github.com/esl/gproc.git", {tag, "v0.2.11"}}} 8 | ]}. 9 | {cover_enabled, true}. 10 | {eunit_opts, [verbose, {report,{eunit_surefire,[{dir,"."}]}}]}. 11 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/google.css: -------------------------------------------------------------------------------- 1 | .olLayerGoogleCopyright { 2 | right: 3px; 3 | bottom: 2px; 4 | left: auto; 5 | } 6 | .olLayerGoogleV3.olLayerGoogleCopyright { 7 | bottom: 0px; 8 | right: 0px !important; 9 | } 10 | .olLayerGooglePoweredBy { 11 | left: 2px; 12 | bottom: 2px; 13 | } 14 | .olLayerGoogleV3.olLayerGooglePoweredBy { 15 | bottom: 0px !important; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /static/js/lang/jp.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "はい", 3 | "いいえ", 4 | "OK", 5 | "キャンセル", 6 | "チャット", 7 | "ユーザ", 8 | "プロパティ", 9 | "設定", 10 | "オーナー変更中", 11 | "ニックネーム変更中", 12 | "エディタ起動", 13 | "ケーキ表示", 14 | "なし", 15 | "コメント", 16 | "新規ユーザ名:", 17 | "オーナー:", 18 | "進捗:", 19 | "コメント:", 20 | "名前", 21 | "担当ピース番号", 22 | "権", 23 | "テーマ:", 24 | "言語:", 25 | "コメント", 26 | "このピースは既に他のユーザが担当しています。担当をあなたへ変更しますか?", 27 | "チャットへようこそ %s さん!", 28 | "ニックネーム", 29 | "担当中のピース" 30 | ]; 31 | -------------------------------------------------------------------------------- /hub/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PREFIX:=../ 3 | DEST:=$(PREFIX)$(PROJECT) 4 | 5 | REBAR=./rebar 6 | 7 | all: 8 | @$(REBAR) get-deps compile 9 | 10 | edoc: 11 | @$(REBAR) doc 12 | 13 | test: 14 | @rm -rf .eunit 15 | @mkdir -p .eunit 16 | @$(REBAR) skip_deps=true eunit 17 | 18 | clean: 19 | @$(REBAR) clean 20 | 21 | build_plt: 22 | @$(REBAR) build-plt 23 | 24 | dialyzer: 25 | @$(REBAR) dialyze 26 | 27 | app: 28 | @$(REBAR) create template=mochiwebapp dest=$(DEST) appid=$(PROJECT) 29 | 30 | -------------------------------------------------------------------------------- /logic/eggs.php: -------------------------------------------------------------------------------- 1 | to_pie($from, info_msg("%s has got the cat!", $from->nick())); 11 | } 12 | 13 | ?> -------------------------------------------------------------------------------- /hub/src/config.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(config). 8 | -export([get/1]). 9 | 10 | %% 11 | %% Interface 12 | %% 13 | get(Par) -> 14 | {ok, Val} = application:get_env(Par), 15 | Val. 16 | 17 | 18 | %%{ docroot, hub_deps:local_path(["priv", "www"]) 19 | -------------------------------------------------------------------------------- /apache2.conf.example: -------------------------------------------------------------------------------- 1 | 2 | ServerAdmin webmaster@mapcraft.local 3 | 4 | DocumentRoot /path/to/mapcraft/static 5 | 6 | Options FollowSymLinks 7 | AllowOverride None 8 | 9 | 10 | ScriptAlias /app/ /path/to/mapcraft/app/ 11 | 12 | AllowOverride None 13 | Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch 14 | Order allow,deny 15 | Allow from all 16 | 17 | 18 | ErrorLog /var/log/apache2/mapcraft.error.log 19 | CustomLog /var/log/apache2/mapcraft.access.log combined 20 | LogLevel warn 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/refresher.php: -------------------------------------------------------------------------------- 1 | getMessage(); 18 | } 19 | ?> -------------------------------------------------------------------------------- /hub/src/hub_app.erl: -------------------------------------------------------------------------------- 1 | %% @author Mochi Media 2 | %% @copyright hub Mochi Media 3 | 4 | %% @doc Callbacks for the hub application. 5 | 6 | -module(hub_app). 7 | -author("Mochi Media "). 8 | 9 | -behaviour(application). 10 | -export([start/2,stop/1]). 11 | 12 | 13 | %% @spec start(_Type, _StartArgs) -> ServerRet 14 | %% @doc application start callback for hub. 15 | start(_Type, _StartArgs) -> 16 | hub_deps:ensure(), 17 | hub_sup:start_link(). 18 | 19 | %% @spec stop(_State) -> ServerRet 20 | %% @doc application stop callback for hub. 21 | stop(_State) -> 22 | ok. 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2012 Evgeniy Zelinskiy , 5 | Artem Sorokin 6 | and contributors 7 | 8 | Everyone is permitted to copy and distribute verbatim or modified 9 | copies of this license document, and changing it is allowed as long 10 | as the name is changed. 11 | 12 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 13 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 14 | 15 | 0. You just DO WHAT THE FUCK YOU WANT TO. 16 | -------------------------------------------------------------------------------- /static/css/jquery-theme-patch.css: -------------------------------------------------------------------------------- 1 | .ui-widget { font-family: Myriad Pro,Verdana,Arial,sans; font-size: 0.8em; } 2 | .ui-dialog { padding: 0; width: 300px; } 3 | .ui-dialog .ui-dialog-titlebar { padding: .2em .1em .1em 1em; position: relative; border-style:none none solid; padding:0.2em 0.3em 0.1em 0.6em; } 4 | .ui-dialog .ui-dialog-content { border: 0; padding: .2em .3em 1em .3em; background: none; overflow: auto; zoom: 1; } 5 | .ui-button-text-only .ui-button-text { padding: .2em .5em !important; } 6 | .ui-button-text-icon-primary .ui-button-text { padding: .2em .5em .2em 2em !important; } 7 | .ui-widget-overlay { opacity: .50; filter:Alpha(Opacity=50); } 8 | -------------------------------------------------------------------------------- /app/pie_stat.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/js/lang/en.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Yes", 3 | "No", 4 | "OK", 5 | "Cancel", 6 | "Chat", 7 | "Users", 8 | "Properties", 9 | "Settings", 10 | "Nick changing", 11 | "Status changing", 12 | "Remote", 13 | "Cake", 14 | "None", 15 | "Add", 16 | "New username:", 17 | "Owner:", 18 | "Progress:", 19 | "Comments:", 20 | "Name", 21 | "Slices", 22 | "Claims", 23 | "Theme:", 24 | "Language:", 25 | "Your comment", 26 | "Are you sure you want to take this slice?", 27 | "This slice has an owner already! Put to the vote the transfer for you?", 28 | "Are you sure you want to abandon the slice?", 29 | "Welcome to our chat, %s!", 30 | "Show nicks:", 31 | "Show owned slices:" 32 | ]; 33 | -------------------------------------------------------------------------------- /static/js/lang/pl.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Tak", 3 | "Nie", 4 | "OK", 5 | "Anuluj", 6 | "Czat", 7 | "Użytkownicy", 8 | "Właściwości", 9 | "Ustawienia", 10 | "Zmiana pseudonimu", 11 | "Zmiana statusu", 12 | "Remote", 13 | "Tort", 14 | "Brak", 15 | "Dodaj", 16 | "Nowy pseudonim:", 17 | "Właściciel:", 18 | "Postęp:", 19 | "Komentarze:", 20 | "Nazwa", 21 | "Kawałki", 22 | "Prawa", 23 | "Motyw:", 24 | "Język:", 25 | "Twój komentarz", 26 | "Jesteś pewny, że chcesz przejąć ten kawałek?", 27 | "Ten kawałek ma już właściciela! Poddać pod głosowanie transfer dla ceibie?", 28 | "Jesteś pewny, że chcesz opuścić ten kawałek?", 29 | "Witaj na naszym czacie, %s!", 30 | "Pokaż pseudonimy:", 31 | "Pokaż posiadane kawałki:" 32 | ]; 33 | -------------------------------------------------------------------------------- /static/js/lang/it.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Si", 3 | "No", 4 | "OK", 5 | "Cancella", 6 | "Chat", 7 | "Utenti", 8 | "Proprietà", 9 | "Impostazioni", 10 | "Cambio nome utente", 11 | "Cambio stato", 12 | "Remoto", 13 | "Torta", 14 | "Nessuno", 15 | "Aggiungi", 16 | "Nuovo nome utente:", 17 | "Proprietario:", 18 | "Progresso:", 19 | "Commenti:", 20 | "Nome", 21 | "Fette", 22 | "Claims", 23 | "Tema:", 24 | "Lingua:", 25 | "Il tuo commento", 26 | "Sei sicuro di voler prendere in carico questa fetta?", 27 | "Questa fetta ha già un proprietario! Vuoi metterla in votazione per trasferirla a te?", 28 | "Sei sicuro/a di voler abbandonare questa fetta?", 29 | "Benuvenuto/a sulla nostra chat, %s!", 30 | "Mostra nomi utente:", 31 | "Mostra fette possedute:" 32 | ]; 33 | -------------------------------------------------------------------------------- /static/js/lang/es.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Si", 3 | "No", 4 | "OK", 5 | "Cancelar", 6 | "Chat", 7 | "Usuarios", 8 | "Propiedades", 9 | "Ajustes", 10 | "Cambiando nick", 11 | "Cambiando estado", 12 | "Remoto", 13 | "Pastel", 14 | "Ninguno", 15 | "Añadir", 16 | "Nuevo nombre de usuario:", 17 | "Propietario:", 18 | "Progreso:", 19 | "Comentarios:", 20 | "Nombre", 21 | "Rebanadas", 22 | "Reclamos", 23 | "Tema:", 24 | "Idioma:", 25 | "Su comentario", 26 | "¿Está seguro que deseas tomar esta rebanada?", 27 | "Esta rebanada ya tiene dueño! ¿Poner a votación que deseas la transferencia?", 28 | "¿Estás seguro que deseas abandonar la rebanada?", 29 | "Bienvenido a nuestro chat, %s!", 30 | "Mostrar nicks:", 31 | "Mostrar los propietarios de las rebanadas:" 32 | ]; 33 | -------------------------------------------------------------------------------- /app/json_pies.php: -------------------------------------------------------------------------------- 1 | ', true))); 14 | echo '{"type":"Feature","geometry":{"type":"Point","coordinates":'.$row['jcenter'].'},"properties":{"id":"'.$row['id'].'","name":"'.$row['name'].'","description":"'.$description.'"}}'; 15 | } 16 | echo ']}'; 17 | ?> -------------------------------------------------------------------------------- /hub/src/hub.erl: -------------------------------------------------------------------------------- 1 | %% @author Mochi Media 2 | %% @copyright 2010 Mochi Media 3 | 4 | %% @doc hub. 5 | 6 | -module(hub). 7 | -author("Mochi Media "). 8 | -export([start/0, stop/0]). 9 | 10 | ensure_started(App) -> 11 | case application:start(App) of 12 | ok -> 13 | ok; 14 | {error, {already_started, App}} -> 15 | ok 16 | end. 17 | 18 | 19 | %% @spec start() -> ok 20 | %% @doc Start the hub server. 21 | start() -> 22 | hub_deps:ensure(), 23 | ensure_started(crypto), 24 | ensure_started(gproc), 25 | application:start(hub). 26 | 27 | 28 | %% @spec stop() -> ok 29 | %% @doc Stop the hub server. 30 | stop() -> 31 | application:stop(hub). 32 | -------------------------------------------------------------------------------- /hub/src/pie_sup.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(pie_sup). 8 | -behaviour(supervisor). 9 | 10 | -export([start_link/0]). 11 | -export([init/1]). 12 | 13 | start_link() -> 14 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 15 | 16 | %% 17 | %% supervisor callbacks 18 | %% 19 | 20 | init(_Options) -> 21 | {ok, {{simple_one_for_one, 5, 60}, 22 | [{pie, {pie, start_link, []}, 23 | transient, 5000, worker, [pie]}] 24 | }}. 25 | -------------------------------------------------------------------------------- /static/js/lang/fr.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Oui", 3 | "Non", 4 | "Valider", 5 | "Annuler", 6 | "Chat", 7 | "Contributeurs", 8 | "Propriétés", 9 | "Réglages", 10 | "Changement de pseudo", 11 | "Changer le Statut", 12 | "Retour", 13 | "Diagramme", 14 | "Aucun", 15 | "Ajouter", 16 | "Nouveau Contributeur :", 17 | "Affectation:", 18 | "Progression:", 19 | "Commentaires:", 20 | "Nom", 21 | "Secteurs", 22 | "Réclamations", 23 | "Thème:", 24 | "Langue:", 25 | "Vos Commentaires", 26 | "Êtes-vous sûr de vouloir vous attribuer ce secteur ?", 27 | "Ce secteur est déjà affecté ! Voulez-vous vous l'attribuer tout de même ?", 28 | "Êtes-vous sûr de vouloir abandonner ce secteur ?", 29 | "Bienvenue sur le Chat, %s!", 30 | "Voir les Contributeurs :", 31 | "Voir les secteurs attribués :" 32 | ]; -------------------------------------------------------------------------------- /app/export.php: -------------------------------------------------------------------------------- 1 | load_from_db($id); 11 | 12 | // header("Content-type: text/plain"); 13 | // echo $pie_geometry->dump(); 14 | // var_dump($pie_geometry); 15 | 16 | header("Content-type: application/binary"); 17 | header("Content-Disposition: attachment; filename=\"mapcraft-cake-" . $id . ".osm\""); 18 | echo $pie_geometry->export_to_osm(); 19 | } catch (Exception $e) { 20 | header("HTTP/1.1 500 Internal Server Error"); 21 | header("Content-type: text/plain"); 22 | echo ($e->getMessage()); 23 | } 24 | 25 | ?> 26 | -------------------------------------------------------------------------------- /static/js/lang/de.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Ja", 3 | "Nein", 4 | "OK", 5 | "Abbrechen", 6 | "Chat", 7 | "Benutzer", 8 | "Besitztümer", 9 | "Einstellungen", 10 | "Nicknamen ändern", 11 | "Status ändern", 12 | "Remote", 13 | "Kuchen", 14 | "Keine", 15 | "Hinzufügen", 16 | "Neuer Benutzername:", 17 | "Besitzer:", 18 | "Fortschritt:", 19 | "Kommentare:", 20 | "Name", 21 | "Stücke", 22 | "Ansprüche", 23 | "Theme:", 24 | "Sprache:", 25 | "Dein Kommentar", 26 | "Bist du dir sicher, dass du dieses Stück nehmen willst?", 27 | "Dieses Stück hat bereits einen Besitzer! Soll darüber abgestimmt werden, dass es dir zugesprochen wird?", 28 | "Bist du dir sicher, dass du dieses Stück verlassen willst?", 29 | "Wilkommen zum Chat, %s!", 30 | "Zeige Nicknamen:", 31 | "Zeige beanspruchte Stücke:" 32 | ]; 33 | -------------------------------------------------------------------------------- /logic/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cmd='from!async!1!user1235678!json:["msg", {"type": "public", "message": "Hello world!"}]' 4 | echo $cmd | ./main.php -t 5 | 6 | cmd='session_join!1!user1235678' 7 | echo $cmd | ./main.php -t 8 | 9 | cmd='session_exit!1!user1235678!timeout' 10 | echo $cmd | ./main.php -t 11 | 12 | cmd='from!async!1!user1235678!json:["nocmd", {}]' 13 | echo $cmd | ./main.php -t 14 | 15 | cmd='nocmd!arg1!arg2' 16 | echo $cmd | ./main.php -t 17 | 18 | ( echo 'from!async!1!user1235678!json:["whoami", {}]'; \ 19 | echo 'from!async!1!user1235679!json:["whoami", {}]' \ 20 | ) | ./main.php 21 | 22 | cmd='from!async!1!user1235678!json:["get_cat", {}]' 23 | echo $cmd | ./main.php -t 24 | 25 | cmd='from!async!1!user1235678!json:["piece_state", {"piece_index": 1, "percent": 5}]' 26 | echo $cmd | ./main.php -t 27 | -------------------------------------------------------------------------------- /logic/test.sh.save: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cmd='from!async!1!user1235678!json:["msg", {"type": "public", "message": "Hello world!"}]' 4 | echo $cmd | ./main.php -t 5 | 6 | cmd='session_join!1!user1235678' 7 | echo $cmd | ./main.php -t 8 | 9 | cmd='session_exit!1!user1235678!timeout' 10 | echo $cmd | ./main.php -t 11 | 12 | cmd='from!async!1!user1235678!json:["init_sess", {}]' 13 | echo $cmd | ./main.php -t 14 | 15 | cmd='nocmd!arg1!arg2' 16 | echo $cmd | ./main.php -t 17 | 18 | ( echo 'from!async!1!user1235678!json:["whoami", {}]'; \ 19 | echo 'from!async!1!user1235679!json:["whoami", {}]' \ 20 | ) | ./main.php 21 | 22 | cmd='from!async!1!user1235678!json:["get_cat", {}]' 23 | echo $cmd | ./main.php -t 24 | 25 | cmd='from!async!1!user1235678!json:["piece_state", {"piece_id": 1, "percent": 5}]' 26 | echo $cmd | ./main.php -t 27 | -------------------------------------------------------------------------------- /data/scheme/migrations/003-add-pies-settings.php: -------------------------------------------------------------------------------- 1 | 1 && $argv[1] == '-r') { 29 | echo "Reverting ...\n"; 30 | revert(); 31 | } else { 32 | echo "Applying ...\n"; 33 | apply(); 34 | } 35 | } catch (Exception $e) { 36 | echo "Error: " . $e->getMessage() . "\n"; 37 | exit (1); 38 | } 39 | 40 | ?> -------------------------------------------------------------------------------- /app/auth_osm.php: -------------------------------------------------------------------------------- 1 | getRequestToken($req_url); 13 | session_start(); 14 | $_SESSION['secret'] = $request_token_info['oauth_token_secret']; 15 | header('Location: '.$authurl."?oauth_token=".$request_token_info['oauth_token']); 16 | } catch(OAuthException $E) { 17 | print_r($E); 18 | } 19 | -------------------------------------------------------------------------------- /static/js/lang/sk.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Áno", 3 | "Nie", 4 | "OK", 5 | "Zrušiť", 6 | "Chat", 7 | "Používatelia", 8 | "Vlastnosti", 9 | "Nastavenia", 10 | "Zmeniť meno", 11 | "Zmeniť stav", 12 | "Remote", 13 | "Koláč", 14 | "Žiadny", 15 | "Pridať", 16 | "Nové meno:", 17 | "Vlastník:", 18 | "Priebeh:", 19 | "Komentáre:", 20 | "Meno", 21 | "Kúsky", 22 | "Claims", 23 | "Štýl:", 24 | "Jazyk:", 25 | "Váš komentár", 26 | "Chceli by ste si zobrať tento kúsok?", 27 | "Tento kúsok už má vlastníka! Chceli by ste to dať do voľby?", 28 | "Chceli by ste si odovzdať tento kúsok?", 29 | "Vitajte v chate, %s!", 30 | "Zobrazovať mena:", 31 | "Zobrazovať vlastnené kúsky:" 32 | ]; 33 | 34 | var trans = [ 35 | 'Yes', 36 | 'Áno', 37 | 38 | 'Piece has been freed', 39 | 'Kúsok bol vrátený', 40 | 41 | 'Piece has been reserved', 42 | 'Kúsok bol rezervovaný' 43 | ]; 44 | 45 | for ( i = 0; i < 10 ; i++ ) 46 | trans.push('New state: ' + i + '/9', 'Nový stav: ' + i + '/9'); 47 | -------------------------------------------------------------------------------- /lib/config.php.template: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/validators.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nginx.conf.example: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name mapcraft.local; 4 | 5 | access_log /var/log/nginx/mapcraft.access.log; 6 | 7 | rewrite ^/pie/[0-9]+/?$ /client.html last; 8 | rewrite ^/(log|edit|delete)/([0-9]+)/?$ /app/$1.php?id=$2 last; 9 | rewrite ^/(list|map|create)$ /app/index.php?page=$1 last; 10 | rewrite ^/oauth_callback.php$ /app/oauth_callback.php last; 11 | 12 | # Static files will be served by nginx 13 | location / { 14 | root /path/to/mapcraft/static; 15 | index index.html; 16 | } 17 | 18 | # Proxy php scripts to apache on 8000 port 19 | location /app/ { 20 | proxy_pass http://127.0.0.1:8000; 21 | proxy_set_header Host $host; 22 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 23 | } 24 | 25 | # Proxy hub requests to mapcraft hub 26 | location /hub { 27 | proxy_pass http://127.0.0.1:8080; 28 | proxy_buffering off; 29 | proxy_read_timeout 3600; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/style.mobile.tidy.css: -------------------------------------------------------------------------------- 1 | div.olControlZoom{position:absolute;top:8px;left:8px;background:rgba(255,255,255,0.4);border-radius:4px;padding:2px;}*{-webkit-tap-highlight-color:rgba(0,0,0,0);}div.olControlZoom a{display:block;color:#FFF;font-size:28px;font-family:sans-serif;font-weight:700;text-decoration:none;text-align:center;height:32px;width:32px;line-height:28px;text-shadow:0 0 3px rgba(0,0,0,0.8);background:rgba(0,60,136,0.5);filter:alpha(opacity=80);margin:1px;padding:0;}a.olControlZoomIn{border-radius:4px 4px 0 0;}a.olControlZoomOut{border-radius:0 0 4px 4px;}div.olControlZoom a:hover{background:rgba(0,60,136,0.7);filter:alpha(opacity=100);}.olLayerGrid .olTileImage{-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;transition:opacity .2s linear;}@media only screen and max-width 600px{div.olControlZoom a:hover{background:rgba(0,60,136,0.5);}}@media -webkit-transform-3d{img.olTileImage{-webkit-transform:translate3d(0,0,0);}} -------------------------------------------------------------------------------- /hub/src/logic_sup.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(logic_sup). 8 | -behaviour(supervisor). 9 | 10 | -export([start_link/0]). 11 | -export([init/1]). 12 | 13 | start_link() -> 14 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 15 | 16 | init(_Args) -> 17 | Workers = initial_workers_specs(), 18 | Strategy = {one_for_one, 5, 60}, 19 | {ok, {Strategy, Workers}}. 20 | 21 | initial_workers_specs() -> 22 | {Min, _} = config:get(logic_pool_size), 23 | [worker_spec(I) || I <- lists:seq(1,Min)]. 24 | 25 | worker_spec(Index) -> 26 | Id = list_to_atom("logic_worker" ++ integer_to_list(Index)), 27 | {Id, {logic_worker, start_link, []}, 28 | permanent, 5000, worker, [logic_worker]}. 29 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MapCraft — massively mapping management tool for OpenStreetMap 5 | 6 | 7 | 8 | 9 | 10 | 11 |

MapCraft
12 |
13 |

MapCraft in Action 14 | MapCraft is a tool to use at mapping parties, or any other time you need to collaborate with others in OpenStreetMap.

15 | 16 |
17 | 18 |

Read the wiki article or... let me start mapping

19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /lib/_header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MapCraft — massively mapping management tool for OpenStreetMap 5 | 6 | 7 | 8 | 9 | 10 |

MapCraft
11 |
17 |
18 | Logout'; 21 | else { 22 | echo 'Login'; 23 | } 24 | //echo $_SESSION['osm_user'].'   Logout'; 25 | ?> 26 |
27 |
28 | -------------------------------------------------------------------------------- /hub/src/hub.app.src: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; indent-tabs-mode: nil -*- 2 | {application, hub, 3 | [{description, "MapCraft Hub"}, 4 | {vsn, "0.1"}, 5 | {modules, []}, 6 | {registered, []}, 7 | {mod, {'hub_app', []}}, 8 | {applications, [kernel, stdlib, crypto, gproc]}, 9 | {env, [ 10 | {port, 8080}, 11 | {listen, {0,0,0,0}}, 12 | {http_pool_size, 5}, % how many web_sockets will be waiting for new connection 13 | {hub_prefix, "hub"}, % first part of any URL 14 | {origin, "http://localhost"}, % for CORS 15 | 16 | {logic_cmd, "priv/logic.sh"}, % path to logic wrapper 17 | {logic_pool_size, {3,10}}, % {min, max} for logic pool 18 | {logic_timeout, 10}, % secs to wait answer from logic 19 | 20 | {poll_timeout, 30}, % when poll connection should be dropped with 'nop' 21 | {chan_expire, 60}, % how many secs channel can be without any new poll connection 22 | {pie_cleanup_interval, 30} % how often check for expired connections 23 | ]} 24 | ]}. 25 | 26 | -------------------------------------------------------------------------------- /app/auth_fake.php: -------------------------------------------------------------------------------- 1 | 0) 15 | $_SESSION['user_id'] = pg_fetch_result($result, 0 ,0); 16 | else 17 | $_SESSION['user_id'] = pg_fetch_result(pg_query($connection, 'INSERT INTO users VALUES(\''.$pg_osm_user.'\', DEFAULT, DEFAULT) RETURNING id'), 0 ,0); 18 | 19 | Header("Location: /app/auth.php?action=success"); 20 | exit(); 21 | 22 | } else { 23 | ?> 24 | 25 | 26 | Authorization 27 | 28 | 29 | 30 | 31 |
32 | Nick: 33 | 34 |
35 | 36 | 37 | 38 | 39 | 42 | -------------------------------------------------------------------------------- /static/js/app_list.js: -------------------------------------------------------------------------------- 1 | /* This program is free software. It comes without any warranty, to 2 | * the extent permitted by applicable law. You can redistribute it 3 | * and/or modify it under the terms of the Do What The Fuck You Want 4 | * To Public License, Version 2, as published by Sam Hocevar. See 5 | * http://sam.zoy.org/wtfpl/COPYING for more details. */ 6 | 7 | function getquery (uri) { 8 | var xmlhttp = new XMLHttpRequest(); 9 | xmlhttp.open('GET', uri, true); 10 | xmlhttp.send(null); 11 | } 12 | 13 | function get_toggle_id(e) { 14 | return e.id.match(/(\d+)$/)[0] || null; 15 | } 16 | 17 | function toggleDetails(e) { 18 | var toggle_id = get_toggle_id(e.target); 19 | 20 | $('.list_descr').each(function() { 21 | var id = get_toggle_id(this); 22 | if (id == toggle_id) { 23 | $('#toggle_' + id).toggleClass('closed'); 24 | $(this).toggleClass('closed'); 25 | } else { 26 | $('#toggle_' + id).addClass('closed'); 27 | $(this).addClass('closed'); 28 | } 29 | }); 30 | } 31 | 32 | 33 | $(function() { 34 | 35 | // on row click expand or collapse it 36 | $('.list_toggle').click(toggleDetails); 37 | }); -------------------------------------------------------------------------------- /data/scheme/migrations/004-add-pie-updated.php: -------------------------------------------------------------------------------- 1 | 1 && $argv[1] == '-r') { 44 | echo "Reverting ...\n"; 45 | revert(); 46 | } else { 47 | echo "Applying ...\n"; 48 | apply(); 49 | } 50 | } catch (Exception $e) { 51 | echo "Error: " . $e->getMessage() . "\n"; 52 | exit (1); 53 | } 54 | 55 | ?> -------------------------------------------------------------------------------- /static/js/lang/ru.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Да", // 0 3 | "Нет", // 1 4 | "OK", // 2 5 | "Отмена", // 3 6 | "Чатик", // 4 7 | "Пользователи", // 5 8 | "Свойства", // 6 9 | "Настройки", // 7 10 | "Смена имени пользователя", // 8 11 | "Смена статуса", // 9 12 | "Remote", // 10 13 | "Пирог", // 11 14 | "Нет", // 12 15 | "Добавить", // 13 16 | "Новое имя:", // 14 17 | "Владелец:", // 15 18 | "Готовность:", // 16 19 | "Комментарии:", // 17 20 | "Имя", // 18 21 | "Сектора", // 19 22 | "Заявки", // 20 23 | "Тема:", // 21 24 | "Язык:", // 22 25 | "Ваш комментарий", // 23 26 | "Вы уверены, что хотите взять этот сектор?", // 24 27 | "У этого сектора уже есть владелец! Поставить на голосование передачу вам?", // 25 28 | "Вы уверены, что хотите отказаться от сектора?", //26 29 | "Добро пожаловать в наш уютный чатик, %s!", // 27 30 | "Отображать владельцев:", // 28 31 | "Отображать занятые сектора:" // 29 32 | ]; 33 | 34 | var trans = [ 35 | 'Progress bar:', 36 | 'Градусник:', 37 | 38 | 'Yes', 39 | 'Да', 40 | 41 | 'Piece has been freed', 42 | 'Кусок освобождён', 43 | 44 | 'Piece has been reserved', 45 | 'Кусок зарезервирован' 46 | ]; 47 | 48 | for ( i = 0; i < 10 ; i++ ) 49 | trans.push('New state: ' + i + '/9', 'Новый статус: ' + i + '/9'); 50 | -------------------------------------------------------------------------------- /static/js/lang/uk.js: -------------------------------------------------------------------------------- 1 | var ldata = [ 2 | "Так", // 0 3 | "Ні", // 1 4 | "Гаразд", // 2 5 | "Відміна", // 3 6 | "Чат", // 4 7 | "Користувачі", // 5 8 | "Властивості", // 6 9 | "Налаштування", // 7 10 | "Зміна імені користувача", // 8 11 | "Зміна статусу", // 9 12 | "Дистанційно", // 10 13 | "Пиріг", // 11 14 | "Ні", // 12 15 | "Додати", // 13 16 | "Нове ім’я:", // 14 17 | "Власник:", // 15 18 | "Завершеність:", // 16 19 | "Коментар:", // 17 20 | "Ім’я", // 18 21 | "Шматочки", // 19 22 | "Заявки", // 20 23 | "Тема:", // 21 24 | "Мова:", // 22 25 | "Ваш коментар", // 23 26 | "Ви впевнені, що хочете взяти цей шматочок?", // 24 27 | "У цього шматочка вже є власник! Поставити на голосування передачу Вам?", // 25 28 | "Ви впевнені, що хочете відмовитися від шматочка?", //26 29 | "Ласкаво просимо до нашого затишного чату, %s!", // 27 30 | "Відображати власників:", // 28 31 | "Відображати зайняті шматочки:" // 29 32 | ]; 33 | 34 | var trans = [ 35 | 'Progress bar:', 36 | 'Індикатор прогресу:', 37 | 38 | 'Yes', 39 | 'Так', 40 | 41 | 'Piece has been freed', 42 | 'Шматочок звільнений', 43 | 44 | 'Piece has been reserved', 45 | 'Шматочок зарезервований' 46 | ]; 47 | 48 | for ( i = 0; i < 10 ; i++ ) 49 | trans.push('New state: ' + i + '/9', 'Новий стан: ' + i + '/9'); 50 | -------------------------------------------------------------------------------- /scripts/apache: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | . ./common.sh 5 | 6 | export PID_FILE=$SRC_ROOT/tmp/apache.pid 7 | export CONFIG=$TMP_DIR/apache.conf 8 | 9 | CONFIG_TMPL=$CONF_DIR/apache.conf.devenv 10 | APACHE2=/usr/sbin/apache2 11 | 12 | 13 | usage() { 14 | echo "Usage: $0 " 15 | exit 1; 16 | } 17 | 18 | is_running() { 19 | [ ! -f $PID_FILE ] && return 1 20 | ! ps $(cat $PID_FILE 2>/dev/null) >/dev/null && return 1 21 | return 0 22 | } 23 | 24 | status() { 25 | is_running && echo "Apache is running" || echo "Apache is stopped" 26 | } 27 | 28 | start() { 29 | if is_running ; then 30 | echo "Apache is already running" 31 | return 1 32 | fi 33 | 34 | convert_tmpl $CONFIG_TMPL $CONFIG 35 | $APACHE2 -f $CONFIG && echo "Apache has been started" 36 | } 37 | 38 | stop() { 39 | if ! is_running ; then 40 | echo "Apache is already stopped" 41 | return 1 42 | fi 43 | 44 | kill $(cat $PID_FILE) 45 | 46 | while is_running ; do 47 | sleep 0.1 48 | done 49 | echo "Apache has been stopped" 50 | } 51 | 52 | case "$1" in 53 | status) 54 | status 55 | ;; 56 | start) 57 | start 58 | ;; 59 | stop) 60 | stop 61 | ;; 62 | restart) 63 | stop 64 | start 65 | ;; 66 | *) 67 | usage 68 | ;; 69 | esac 70 | -------------------------------------------------------------------------------- /data/scheme/migrations/002-fix-ownerships.php: -------------------------------------------------------------------------------- 1 | 1 && $argv[1] == '-r') { 44 | echo "Reverting ...\n"; 45 | revert(); 46 | } else { 47 | echo "Applying ...\n"; 48 | apply(); 49 | } 50 | } catch (Exception $e) { 51 | echo "Error: " . $e->getMessage() . "\n"; 52 | exit (1); 53 | } 54 | 55 | ?> -------------------------------------------------------------------------------- /scripts/common.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | convert_tmpl() { 4 | FROM=$1 5 | TO=$2 6 | cat $FROM | perl -pe 's/\$\{(.*?)\}/$ENV{$1}/e' >$TO 7 | } 8 | 9 | guess_src_root() { 10 | CUR=$(pwd) 11 | while [ ! -d "$CUR/.git" ] ; do 12 | CUR=$(dirname $CUR) 13 | if [ $CUR == "/" ] ; then 14 | echo "failed guess source root. No suggestions. sorry" 15 | exit 1; 16 | fi 17 | done 18 | echo $CUR 19 | } 20 | 21 | get_version() { 22 | dpkg-query -W -f='${Version}\n' $1 23 | } 24 | 25 | version_ge() { 26 | dpkg --compare-versions $1 '>=' $2 27 | } 28 | 29 | # Common variables 30 | export SRC_ROOT=$(guess_src_root) 31 | export CONF_DIR=$SRC_ROOT/configs 32 | 33 | export LOGS_DIR=$SRC_ROOT/logs 34 | test ! -d $LOGS_DIR && mkdir $LOGS_DIR 35 | 36 | export TMP_DIR=$SRC_ROOT/tmp 37 | test ! -d $TMP_DIR && mkdir $TMP_DIR 38 | 39 | export SESSION_TMP_DIR=$TMP_DIR/sessions 40 | test ! -d $SESSION_TMP_DIR && mkdir $SESSION_TMP_DIR 41 | 42 | # Developer ports 43 | export NGINX_PORT=2000 44 | export HTTPD_PORT=2100 45 | export HUB_PORT=2200 46 | 47 | # Database 48 | export DATABASE=mapcraft-devel 49 | export DB_USER=develcrafter 50 | export DB_PASS=develaccess 51 | export DB_HOST=localhost 52 | 53 | # Auth 54 | export AUTH_TYPE="fake" 55 | 56 | # Configs 57 | export HUB_CONFIG=$TMP_DIR/hub.config 58 | export PHP_CONFIG=$TMP_DIR/php.ini 59 | 60 | # Logging 61 | export LOGIC_LOG_FILE=$LOGS_DIR/logic.log 62 | -------------------------------------------------------------------------------- /app/auth.php: -------------------------------------------------------------------------------- 1 | window.opener.location.reload(true);"); 34 | 35 | echo(""); 36 | break; 37 | 38 | case 'success': 39 | 40 | $reload = isset($_SESSION[$reload_key]); 41 | 42 | $sesid = session_id(); 43 | session_write_close(); 44 | system('curl -s -d "" "' . $hub_full_url . '/api/session/' . $sesid . '/login"'); 45 | 46 | if($reload) 47 | echo ""; 48 | 49 | echo(""); 50 | break; 51 | 52 | default: 53 | echo "Unknown action"; 54 | } 55 | 56 | ?> -------------------------------------------------------------------------------- /static/help/josm-remote-troubleshoot.en.html: -------------------------------------------------------------------------------- 1 |

Ups! Failed to send remote command to the JOSM

2 | 3 | How to find the cause: 4 |
    5 |
  • Make sure that JOSM is opened. If not, then run it and try again.
  • 6 |
  • Go to JOSM preferences (F12), open tab 'Remove Control' and make sure that this function is enabled. If not, enable it and try again.
  • 7 |
  • If you have Firefox with addon NoScript 8 | installed, then go to the plugin's preferences, tab 'Advanced' and look for tab ABE. 9 | If there is one, then open it. This function by default prevents external requests to local sites. You can disable it or add following 10 | rules into "USER" section: 11 |
    12 | 	  Site 127.0.0.1:8111
    13 | 	  Accept
    14 | 	
    15 | Then hit button 'Refresh', then 'OK' and try again.
  • 16 |
17 | 18 | Nothing helps? Go to issue tracker and search for similar bug. Try enter word 'Remote' into search box. May be there is a solve. 19 | 20 |

21 | If there are no one, then try to localize the bug: switch browser, sniff network traffic on port 127.0.0.1:8111 and so on. Then fill new issue. Thank you. 22 | -------------------------------------------------------------------------------- /static/css/log.css: -------------------------------------------------------------------------------- 1 | * { margin: 0; padding: 0; } 2 | BODY { padding: 10px; font-family: Myriad Pro,Arial,sans; } 3 | TABLE { width: 100%; border-spacing: 0 2px; } 4 | TABLE TD { vertical-align: top; padding: 2px; } 5 | TABLE TD.nick { font-weight: bold; text-align: center; text-shadow: 1px 1px 3px rgba(0,0,0,0.6); } 6 | TABLE TD.c1 { background: #637D8C; } 7 | TABLE TD.c2 { background: #6D926C; } 8 | TABLE TD.c3 { background: #92836C; } 9 | TABLE TD.time A { color: inherit; text-decoration: none; } 10 | TABLE TD.time A SPAN { color: #CCCCCC; } 11 | 12 | @-o-keyframes pulse { 0% { background-color: #FFFF77; } 50% { background-color: #FFFFFF; } 100% { background-color: #FFFF77; } } 13 | @-ms-keyframes pulse { 0% { background-color: #FFFF77; } 50% { background-color: #FFFFFF; } 100% { background-color: #FFFF77; } } 14 | @-moz-keyframes pulse { 0% { background-color: #FFFF77; } 50% { background-color: #FFFFFF; } 100% { background-color: #FFFF77; } } 15 | @-webkit-keyframes pulse { 0% { background-color: #FFFF77; } 50% { background-color: #FFFFFF; } 100% { background-color: #FFFF77; } } 16 | @keyframes pulse { 0% { background-color: #FFFF77; } 50% { background-color: #FFFFFF; } 100% { background-color: #FFFF77; } } 17 | TABLE TR.target TD { background-color: #FFFF77; -o-animation: pulse 0.5s infinite; -moz-animation: pulse 0.5s infinite; -ms-animation: pulse 0.5s infinite; -webkit-animation: pulse 0.5s infinite; animation: pulse 0.5s infinite; } 18 | 19 | -------------------------------------------------------------------------------- /hub/src/hub_api.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(hub_api). 8 | 9 | -export([handle/3]). 10 | -compiler(export_all). 11 | -include("hub.hrl"). 12 | 13 | 14 | handle('GET', Req, ["stats"]) -> 15 | hub_web:ok(Req, stats:fdump()); 16 | 17 | handle('POST', Req, ["session", SesId, Action]) -> 18 | {ok, Ids} = pie:get_ids(), 19 | [ send_ses_action(PieId, SesId, Action) || PieId <- Ids ], 20 | hub_web:ok(Req, "ok"); 21 | 22 | handle('POST', Req, ["pie", PieId, Action]) -> 23 | send_pie_action(PieId, Action), 24 | hub_web:ok(Req, "ok"). 25 | 26 | send_ses_action(PieId, SesId, Action) -> 27 | case pie:lookup(PieId, SesId) of 28 | [] -> 29 | ok; 30 | _ -> 31 | HubReq = #hub_req{ 32 | pieid = PieId, 33 | sesid = SesId, 34 | type = async, 35 | cmd = api:format_line(["session_action", PieId, SesId, Action]) 36 | }, 37 | ok = logic:process(HubReq) 38 | end. 39 | 40 | send_pie_action(PieId, Action) -> 41 | HubReq = #hub_req{ 42 | pieid = PieId, 43 | sesid = "none", 44 | type = async, 45 | cmd = api:format_line(["pie_action", PieId, Action]) 46 | }, 47 | ok = logic:process(HubReq). 48 | -------------------------------------------------------------------------------- /app/log.php: -------------------------------------------------------------------------------- 1 | %d.%m.%Y %Z'; 10 | $pie_id = $_GET['id']; 11 | $filename = $_SERVER['DOCUMENT_ROOT'].'/log/'.$pie_id.'.html'; 12 | if (!file_exists($filename) || time() - filemtime($filename) > 300) { 13 | $log = fopen($filename, 'w'); 14 | fwrite($log, 'Log of cake '.$pie_id.''); 15 | $result = pg_query($connection, 'SELECT U.nick,C.message,round(date_part(\'epoch\',C.timestamp)) AS ts FROM chat AS C JOIN users AS U ON U.id=C.author WHERE pie='.$pie_id.' ORDER BY C.timestamp ASC'); 16 | while ($row = pg_fetch_array($result)) { 17 | if (!isset($cmap[$row['nick']])) { 18 | $cmap[$row['nick']] = $c++; 19 | if ($c > $colors) $c = 1; 20 | } 21 | $ts = $row['ts']; 22 | fwrite($log, ''."\n"); 23 | } 24 | fwrite($log, "
'.$row['nick'].''.$row['message'].''.strftime($format, $ts).'
"); 25 | fclose($log); 26 | } 27 | include($filename); 28 | ?> 29 | -------------------------------------------------------------------------------- /hub/src/mqueue.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(mqueue). 8 | -behaviour(gen_server). 9 | 10 | -compile(export_all). 11 | -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). 12 | 13 | start_link() -> 14 | gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 15 | 16 | %% 17 | %% Interface 18 | %% 19 | 20 | store(ChatId, Msg) -> 21 | gen_server:call(?MODULE, {store, ChatId, Msg}). 22 | 23 | check_for_me(ChatId) -> 24 | gen_server:call(?MODULE, {check_for_me, ChatId}). 25 | 26 | %% 27 | %% gen_sever callbacks 28 | %% 29 | init(_Args) -> 30 | Tab = ets:new(mqueue, [protected, duplicate_bag]), 31 | {ok, Tab}. 32 | 33 | handle_call({store, ChatId, Msg}, _From, Tab) -> 34 | stats:incr({mqueue, stores}), 35 | stats:incr({mqueue, length}), 36 | ets:insert(Tab, {ChatId, Msg}), 37 | {reply, ok, Tab}; 38 | 39 | handle_call({check_for_me, ChatId}, _From, Tab) -> 40 | Entries = ets:lookup(Tab, ChatId), 41 | ets:delete(Tab, ChatId), 42 | List = [Msg || {_, Msg} <- Entries], 43 | stats:decr({mqueue, length}, length(List)), 44 | {reply, {ok, List}, Tab}. 45 | 46 | handle_info(_Msg, State) -> 47 | {noreply, State}. 48 | 49 | handle_cast(_Msg, State) -> 50 | {noreply, State}. 51 | 52 | code_change(_, State, _) -> 53 | {ok, State}. 54 | 55 | terminate(_Reason, _State) -> 56 | ok. 57 | -------------------------------------------------------------------------------- /scripts/nginx: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | . ./common.sh 5 | 6 | export PID_FILE=$SRC_ROOT/tmp/nginx.pid 7 | export CONFIG=$TMP_DIR/nginx.conf 8 | 9 | CONFIG_TMPL=$CONF_DIR/nginx.conf.devenv 10 | NGINX=/usr/sbin/nginx 11 | 12 | usage() { 13 | echo "Usage: $0 " 14 | exit 1; 15 | } 16 | 17 | is_running() { 18 | [ ! -f $PID_FILE ] && return 1 19 | ! ps $(cat $PID_FILE 2>/dev/null) >/dev/null && return 1 20 | return 0 21 | } 22 | 23 | status() { 24 | is_running && echo "Nginx is running" || echo "Nginx is stopped" 25 | } 26 | 27 | start() { 28 | if is_running ; then 29 | echo "Nginx is already running" 30 | return 1 31 | fi 32 | 33 | export NGINX_CONF_MODS=$(nginx_conf_modifications) 34 | convert_tmpl $CONFIG_TMPL $CONFIG 35 | $NGINX -c $CONFIG && echo "Nginx has been started" 36 | } 37 | 38 | stop() { 39 | if ! is_running ; then 40 | echo "Nginx is already stopped" 41 | return 1 42 | fi 43 | 44 | kill $(cat $PID_FILE) 45 | 46 | while is_running ; do 47 | sleep 0.1 48 | done 49 | echo "Nginx has been stopped" 50 | } 51 | 52 | nginx_conf_modifications() { 53 | 54 | echo " 55 | client_body_temp_path ${TMP_DIR}/nginx-body; 56 | proxy_temp_path ${TMP_DIR}/nginx-proxy; 57 | fastcgi_temp_path ${TMP_DIR}/nginx-fastcgi;" 58 | 59 | NGINX_VERSION=$(get_version nginx) 60 | if version_ge $NGINX_VERSION 1.0.0 ; then 61 | echo " 62 | uwsgi_temp_path ${TMP_DIR}/nginx-uwsgi; 63 | scgi_temp_path ${TMP_DIR}/nginx-scgi;" 64 | fi 65 | } 66 | 67 | case "$1" in 68 | status) 69 | status 70 | ;; 71 | start) 72 | start 73 | ;; 74 | stop) 75 | stop 76 | ;; 77 | restart) 78 | stop 79 | start 80 | ;; 81 | *) 82 | usage 83 | ;; 84 | esac 85 | -------------------------------------------------------------------------------- /scripts/hub: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | . ./common.sh 5 | 6 | export PID_FILE=$SRC_ROOT/tmp/hub.pid 7 | START_SCRIPT=$SRC_ROOT/hub/start-dev.sh 8 | REMOTE="escript $SRC_ROOT/scripts/nodetool -sname hub_dev" 9 | HOSTNAME=$(hostname) 10 | 11 | export CONFIG=$TMP_DIR/hub.conf 12 | 13 | usage() { 14 | echo "Usage: $0 15 | 16 | Commands: 17 | start|stop|restart|status -- control the daemon 18 | console -- start hub in console mode or attach to remote console 19 | " 20 | exit 1; 21 | } 22 | 23 | is_running() { 24 | $REMOTE ping >/dev/null 25 | } 26 | 27 | status() { 28 | is_running && echo "Hub is running" || echo "Hub is stopped" 29 | } 30 | 31 | start() { 32 | if is_running ; then 33 | echo "Hub is already running" 34 | return 1 35 | fi 36 | 37 | LOG_OPT="" 38 | CONFIG_OPT=$(echo "-config" $HUB_CONFIG | sed -e 's/.config$//') 39 | 40 | if echo "$@" | grep 'detached' >/dev/null; then 41 | LOG_OPT="-sasl sasl_error_logger {file,\"${LOGS_DIR}/hub.log\"}" 42 | fi 43 | 44 | 45 | $START_SCRIPT $CONFIG_OPT $LOG_OPT "$@" && echo "Hub has been started" 46 | } 47 | 48 | stop() { 49 | if ! is_running ; then 50 | echo "Hub is already stopped" 51 | return 1 52 | fi 53 | 54 | $REMOTE stop >/dev/null || return 1 55 | 56 | while is_running ; do 57 | sleep 0.1 58 | done 59 | echo "Hub has been stopped" 60 | } 61 | 62 | console() { 63 | if is_running ; then 64 | erl -remsh hub_dev@$HOSTNAME 65 | else 66 | start 67 | fi 68 | } 69 | 70 | case "$1" in 71 | status) 72 | status 73 | ;; 74 | start) 75 | start -detached 76 | ;; 77 | stop) 78 | stop 79 | ;; 80 | console) 81 | console 82 | ;; 83 | restart) 84 | stop 85 | start -detached 86 | ;; 87 | *) 88 | usage 89 | ;; 90 | esac 91 | -------------------------------------------------------------------------------- /configs/nginx.conf.devenv: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | 3 | error_log ${LOGS_DIR}/nginx-error.log; 4 | pid ${PID_FILE}; 5 | 6 | events { 7 | worker_connections 1024; 8 | # multi_accept on; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | 14 | error_log ${LOGS_DIR}/nginx-error.log; 15 | access_log ${LOGS_DIR}/nginx-access.log; 16 | 17 | ${NGINX_CONF_MODS} 18 | 19 | sendfile on; 20 | #tcp_nopush on; 21 | 22 | #keepalive_timeout 0; 23 | keepalive_timeout 65; 24 | tcp_nodelay on; 25 | 26 | gzip on; 27 | gzip_disable "MSIE [1-6]\.(?!.*SV1)"; 28 | 29 | server { 30 | listen ${NGINX_PORT}; 31 | 32 | server_name mapcraft-dev.local; 33 | 34 | rewrite ^/pie/[0-9]+/?$ /client.html last; 35 | rewrite ^/(log|edit|delete|export|update)/([0-9]+)/?$ /app/$1.php?id=$2 last; 36 | rewrite ^/(list|map|create)$ /app/index.php?page=$1 last; 37 | rewrite ^/oauth_callback.php$ /app/oauth_callback.php last; 38 | 39 | # Static files will be served by nginx 40 | location / { 41 | root ${SRC_ROOT}/static; 42 | index index.html; 43 | } 44 | 45 | # Proxy php scripts to apache on 8000 port 46 | location /app/ { 47 | proxy_pass http://127.0.0.1:${HTTPD_PORT}; 48 | proxy_set_header Host $host; 49 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 50 | } 51 | 52 | # Proxy hub requests to mapcraft hub 53 | location /hub { 54 | proxy_pass http://127.0.0.1:${HUB_PORT}; 55 | proxy_buffering off; 56 | proxy_read_timeout 3600; 57 | } 58 | 59 | location /banner/ { 60 | root ${SRC_ROOT}/static; 61 | try_files $uri @refresher; 62 | } 63 | 64 | location @refresher { 65 | rewrite ^/banner/(.*)$ /app/refresher.php/?q=$1 last; 66 | proxy_pass http://127.0.0.1:${HTTPD_PORT}; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /hub/src/api.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | 8 | -module(api). 9 | -compile(export_all). 10 | 11 | 12 | parse_line(Line) -> 13 | Parts = re:split(Line, "!json:", [{return, list}]), 14 | case Parts of 15 | [Cmd, Json] -> 16 | split_cmd(Cmd) ++ [{json, Json}]; 17 | [Cmd] -> 18 | split_cmd(Cmd) 19 | end. 20 | 21 | split_cmd(Cmd) -> 22 | string:tokens(Cmd, "!"). 23 | 24 | 25 | format_line(CmdParts) -> 26 | format_line(CmdParts, []). 27 | 28 | format_line([{json, Head} | Rest], Acc) -> 29 | Part = "json:" ++ Head, 30 | format_line(Rest, ["!", Part | Acc]); 31 | 32 | format_line([Atom | Rest], Acc) when is_atom(Atom)-> 33 | Head = atom_to_list(Atom), 34 | format_line(Rest, ["!", Head | Acc]); 35 | 36 | format_line([Head | Rest], Acc) -> 37 | format_line(Rest, ["!", Head | Acc]); 38 | 39 | format_line([], ["!" | Rest]) -> 40 | List = lists:flatten(lists:reverse(Rest)) ++ "\n", 41 | list_to_binary(List). 42 | 43 | 44 | 45 | %% 46 | %% Tests 47 | %% 48 | -ifdef(TEST). 49 | -include_lib("eunit/include/eunit.hrl"). 50 | 51 | 52 | tests() -> 53 | [ {"a!b", ["a", "b"]}, 54 | {"a", ["a"]}, 55 | {"a!b!json:c", ["a", "b", {json, "c"}]} ]. 56 | 57 | parse_test_() -> 58 | [ ?_assert(Parts =:= parse_line(Cmd)) || {Cmd, Parts} <- tests()]. 59 | 60 | format_test_() -> 61 | [ ?_assert(Cmd ++ "\n" =:= binary_to_list(format_line(Parts))) || {Cmd, Parts} <- tests()]. 62 | 63 | format_add_test_() -> 64 | [ ?_assert( <<"a!b!c\n">> =:= format_line(["a", b, "c"]) ), 65 | ?_assert( <<"a!json:b\n">> =:= format_line([a, {json, "b"}]) ) 66 | ]. 67 | 68 | -endif. 69 | 70 | -------------------------------------------------------------------------------- /lib/update_kml.php: -------------------------------------------------------------------------------- 1 | 17 | 18 | ".$pie_id.""); 19 | $result = pg_query($connection, 'SELECT pieces.index, users.nick, pieces.state, pieces.coordinates FROM pieces LEFT JOIN users ON users.id = pieces.owner WHERE pieces.pie = '.$pie_id); 20 | while ($row = pg_fetch_array($result)) { 21 | fwrite($kml, " 22 | ".$row['index']." 23 | ".$row['state']." 24 | ".$row['nick']." 25 | 26 | ".$row['coordinates']." 27 | "); 28 | } 29 | fwrite($kml, ""); 30 | fclose($kml); 31 | } 32 | 33 | // Clear banners 34 | global $banners_dir; 35 | exec("rm " . $banners_dir . $pie_id . '-*'); 36 | } 37 | ?> 38 | -------------------------------------------------------------------------------- /static/openlayers/theme/default/style.mobile.css: -------------------------------------------------------------------------------- 1 | div.olControlZoom { 2 | position: absolute; 3 | top: 8px; 4 | left: 8px; 5 | background: rgba(255,255,255,0.4); 6 | border-radius: 4px; 7 | padding: 2px; 8 | } 9 | * { 10 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 11 | } 12 | div.olControlZoom a { 13 | display: block; 14 | margin: 1px; 15 | padding: 0; 16 | color: white; 17 | font-size: 28px; 18 | font-family: sans-serif; 19 | font-weight: bold; 20 | text-decoration: none; 21 | text-align: center; 22 | height: 32px; 23 | width: 32px; 24 | line-height: 28px; 25 | text-shadow: 0 0 3px rgba(0,0,0,0.8); 26 | background: #130085; /* fallback for IE - IE6 requires background shorthand*/ 27 | background: rgba(0, 60, 136, 0.5); 28 | filter: alpha(opacity=80); 29 | } 30 | a.olControlZoomIn { 31 | border-radius: 4px 4px 0 0; 32 | } 33 | a.olControlZoomOut { 34 | border-radius: 0 0 4px 4px; 35 | } 36 | div.olControlZoom a:hover { 37 | background: #130085; /* fallback for IE */ 38 | background: rgba(0, 60, 136, 0.7); 39 | filter: alpha(opacity=100); 40 | } 41 | @media only screen and (max-width: 600px) { 42 | div.olControlZoom a:hover { 43 | background: rgba(0, 60, 136, 0.5); 44 | } 45 | } 46 | .olLayerGrid .olTileImage { 47 | -webkit-transition: opacity 0.2s linear; 48 | -moz-transition: opacity 0.2s linear; 49 | -o-transition: opacity 0.2s linear; 50 | transition: opacity 0.2s linear; 51 | } 52 | /* Enable 3d acceleration when operating on tiles, this is 53 | known to yield better performance on IOS Safari. 54 | http://osgeo-org.1803224.n2.nabble.com/Harware-accelerated-CSS3-animations-for-iOS-td6255560.html 55 | 56 | It also prevents tile blinking effects in iOS 5. 57 | See https://github.com/openlayers/openlayers/issues/511 58 | */ 59 | @media (-webkit-transform-3d) { 60 | img.olTileImage { 61 | -webkit-transform: translate3d(0, 0, 0); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /data/scheme/migrations/001-add-pieces-index.php: -------------------------------------------------------------------------------- 1 | 1 && $argv[1] == '-r') { 64 | echo "Reverting ...\n"; 65 | revert(); 66 | } else { 67 | echo "Applying ...\n"; 68 | apply(); 69 | } 70 | } catch (Exception $e) { 71 | echo "Error: " . $e->getMessage() . "\n"; 72 | exit (1); 73 | } 74 | 75 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### About ### 2 | 3 | 4 | ### How to help with developing ### 5 | 6 | 1. (optional) create virtual machine (vmware/virtualbox) and install Debian 6.0 7 | there. Another tested OS: Ubuntu 11.10. Any other is not tested yet and can 8 | cause some bugs during deployment. 9 | 10 | 2. Install dependencies: 11 | 12 | ``` 13 | apt-get install nginx apache2 erlang git postgresql php5 php5-pgsql php5-gd php-log make curl inotify-tools 14 | ``` 15 | 16 | You don't have to modify system configs of apache and nginx to make it work. 17 | There are scripts that will start you own daemons on non-standard ports. 18 | 19 | 3. Few more steps to prepare database. It will create _superuser_ database role 20 | that matches your unix login. So you can use database without any problems. 21 | 22 | ``` 23 | su - (or sudo -i on Ubuntu) 24 | su - postgres 25 | createuser -s 26 | ``` 27 | 28 | On Debian 6.0 you also have to remove suhosin module: 29 | 30 | ``` 31 | apt-get purge php5-suhosin 32 | ``` 33 | 34 | 4. Clone sources. 35 | 36 | ``` 37 | git clone git://github.com/Foxhind/MapCraft.git mapcraft 38 | cd mapcraft 39 | ``` 40 | 41 | Remember that you can allways register on github and 42 | [fork](http://help.github.com/fork-a-repo/) this project, this way you 43 | can freely commit and publish your improvements. 44 | 45 | 5. Now prepare environment and start all: 46 | 47 | ``` 48 | ./scripts/env init 49 | ./scripts/env all-start 50 | ``` 51 | 52 | The first command will create necessary config files and initialize 53 | database. You can do those steps separately: 54 | ```./scripts/env gen-configs```, ```./scripts/env db-seed```. 55 | 56 | The second command will start nginx apache and hub daemons with developers 57 | configs. You can control them separately: ```./scripts/apache```, 58 | ```./scripts/nginx```, ```./scripts hub``` 59 | 60 | 6. Test it: ```http://:2000``` 61 | 62 | ### See also ### 63 | 64 | * TODO: http://piratepad.net/YFP0rrxp4G 65 | * API: http://piratepad.net/ApS1jZmqR0 66 | 67 | -------------------------------------------------------------------------------- /app/index.php: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | MapCraft — massively mapping management tool for OpenStreetMap 21 | 22 | 23 | 24 | 25 | 26 | '; ?> 27 | 28 | 29 | 30 |


MapCraft
31 |
39 |
40 | Logout'; 43 | else { 44 | echo 'Login'; 45 | } 46 | ?> 47 |
48 |
49 | 52 |
53 | 56 | 57 | -------------------------------------------------------------------------------- /app/map.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 47 | -------------------------------------------------------------------------------- /logic/chat.php: -------------------------------------------------------------------------------- 1 | pieid.','.$from->user_id().',DEFAULT,\''.pg_escape_string($text).'\',DEFAULT) RETURNING id, timestamp'); 16 | $row = pg_fetch_array($result); 17 | 18 | $msg = chat_msg(array( 'from' => $from, 19 | 'message' => $text, 20 | 'id' => $row['id'], 21 | 'date' => $row['timestamp'] )); 22 | 23 | if ($data['type'] == 'public') { 24 | $res->to_pie($from, $msg); 25 | $res->stat_pie($from, 'chat', 'sends', '++'); 26 | } else { 27 | $to = find_session_by_nick($from, $data['target_nick']); 28 | $res->to_session($from, $msg); 29 | $res->to_session($to, $msg); 30 | } 31 | } 32 | 33 | // TODO: Move to handle_user_join? 34 | function handle_get_chat_history($type, $from, $data, $res) { 35 | global $connection; 36 | global $logger; 37 | 38 | $result = pg_query($connection, 'SELECT chat.id, users.nick, message, timestamp FROM chat JOIN users ON users.id = author WHERE pie = '.$from->pieid.' ORDER BY timestamp DESC LIMIT 10'); 39 | $messages = array(); 40 | while ($row = pg_fetch_array($result)) { 41 | $messages[] = $row; 42 | } 43 | $messages = array_reverse($messages); 44 | foreach ($messages as $row) { 45 | $msg = array( 'class' => 'chat', 46 | 'author' => $row['nick'], 47 | 'message' => $row['message'], 48 | 'id' => $row['id'], 49 | 'date' => $row['timestamp'], 50 | 'history' => true ); 51 | $res->to_sender(array('chat', $msg)); 52 | } 53 | } 54 | 55 | ?> 56 | -------------------------------------------------------------------------------- /hub/src/hub_sup.erl: -------------------------------------------------------------------------------- 1 | %% @author Mochi Media 2 | %% @copyright 2010 Mochi Media 3 | 4 | %% @doc Supervisor for the hub application. 5 | 6 | -module(hub_sup). 7 | -author("Mochi Media "). 8 | 9 | -behaviour(supervisor). 10 | 11 | %% External exports 12 | -export([start_link/0, upgrade/0]). 13 | 14 | %% supervisor callbacks 15 | -export([init/1]). 16 | 17 | %% @spec start_link() -> ServerRet 18 | %% @doc API for starting the supervisor. 19 | start_link() -> 20 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 21 | 22 | %% @spec upgrade() -> ok 23 | %% @doc Add processes if necessary. 24 | upgrade() -> 25 | {ok, {_, Specs}} = init([]), 26 | 27 | Old = sets:from_list( 28 | [Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]), 29 | New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]), 30 | Kill = sets:subtract(Old, New), 31 | 32 | sets:fold(fun (Id, ok) -> 33 | supervisor:terminate_child(?MODULE, Id), 34 | supervisor:delete_child(?MODULE, Id), 35 | ok 36 | end, ok, Kill), 37 | 38 | [supervisor:start_child(?MODULE, Spec) || Spec <- Specs], 39 | ok. 40 | 41 | %% @spec init([]) -> SupervisorTree 42 | %% @doc supervisor callback. 43 | init([]) -> 44 | Processes = stats_specs() ++ mqueue_specs() ++ web_specs() ++ logic_procs() ++ pie_procs(), 45 | Strategy = {one_for_one, 10, 10}, 46 | {ok, {Strategy, lists:flatten(Processes)}}. 47 | 48 | % 49 | % Private 50 | % 51 | web_specs() -> 52 | WebConfig = [{ip, config:get(listen)}, 53 | {port, config:get(port)}, 54 | {acceptor_pool_size, config:get(http_pool_size)} ], 55 | [ {hub_web, 56 | {hub_web, start, [WebConfig]}, 57 | permanent, 5000, worker, dynamic}]. 58 | 59 | logic_procs() -> 60 | [ {logic, {logic, start_link, []}, 61 | permanent, brutal_kill, worker, [logic]}, 62 | sup(logic_sup, [])]. 63 | 64 | pie_procs() -> 65 | [ sup(pie_sup, []) ]. 66 | 67 | stats_specs() -> 68 | [ {stats, {stats, start_link, []}, 69 | permanent, brutal_kill, worker, [stats]} ]. 70 | 71 | mqueue_specs() -> 72 | [ {mqueue, {mqueue, start_link, []}, 73 | permanent, brutal_kill, worker, [mqueue]} ]. 74 | 75 | sup(Mod, Args) -> 76 | {Mod, 77 | {Mod, start_link, Args}, 78 | permanent, 10000, supervisor, [Mod]}. 79 | 80 | -------------------------------------------------------------------------------- /scripts/code-reloader: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | . ./common.sh 5 | 6 | PID_FILE=$SRC_ROOT/tmp/code-reloader.pid 7 | LOG_FILE=$LOGS_DIR/code-reloader.log 8 | 9 | HUB_SRC_DIR=${SRC_ROOT}/hub/src 10 | LOGIC_SRC_DIR=${SRC_ROOT}/logic 11 | LIB_SRC_DIR=${SRC_ROOT}/lib 12 | 13 | # ------------------------------ 14 | # Code reloader 15 | # ----------------------------- 16 | 17 | start_reloader() { 18 | 19 | inotifywait -e close_write -m --format "%w %f" \ 20 | $HUB_SRC_DIR \ 21 | $LOGIC_SRC_DIR \ 22 | $LIB_SRC_DIR \ 23 | | while read DIR FILE ; do 24 | 25 | fullfile="$DIR$FILE" 26 | extension=${FILE##*.} 27 | echo "File $fullfile was modified" 28 | 29 | # erlang source files 30 | if [ $extension == 'erl' ] ; then 31 | echo "... Recompile erlang module" 32 | erlc -I ${SRC_ROOT}/hub/include -o ${SRC_ROOT}/hub/ebin $fullfile 33 | 34 | # logic source/lib 35 | elif [ $extension == 'php' ] ; then 36 | # very dirty kill function 37 | echo "... Check syntax and restart logic" 38 | echo -n "... " 39 | php -l $fullfile && pkill -HUP php 40 | fi 41 | 42 | done 43 | } 44 | 45 | 46 | # ------------------------------ 47 | # Service wrapper 48 | # ------------------------------ 49 | 50 | usage() { 51 | echo "Usage: $0 " 52 | exit 1; 53 | } 54 | 55 | is_running() { 56 | [ ! -f $PID_FILE ] && return 1 57 | ! ps $(cat $PID_FILE 2>/dev/null) >/dev/null && return 1 58 | return 0 59 | } 60 | 61 | status() { 62 | is_running && echo "Code reloader is running" || echo "Code reloader is stopped" 63 | } 64 | 65 | start() { 66 | if is_running ; then 67 | echo "Code reloader is already running" 68 | return 1 69 | fi 70 | 71 | ( start_reloader >>$LOG_FILE 2>&1 & echo $! >$PID_FILE ) 72 | echo "Code reloader has been started" 73 | } 74 | 75 | stop() { 76 | if ! is_running ; then 77 | echo "Code reloader is already stopped" 78 | return 1 79 | fi 80 | 81 | pkill -P $(cat $PID_FILE) 82 | 83 | while is_running ; do 84 | sleep 0.1 85 | done 86 | echo "Code reloader has been stopped" 87 | } 88 | 89 | case "$1" in 90 | status) 91 | status 92 | ;; 93 | start) 94 | start 95 | ;; 96 | stop) 97 | stop 98 | ;; 99 | restart) 100 | stop 101 | start 102 | ;; 103 | foreground) 104 | start_reloader 105 | exit; 106 | ;; 107 | *) 108 | usage 109 | ;; 110 | esac 111 | -------------------------------------------------------------------------------- /lib/api.php: -------------------------------------------------------------------------------- 1 | Hub HELPERS 11 | *********************************/ 12 | 13 | /* 14 | * Will format MSG in proper command for the hub. 15 | */ 16 | 17 | 18 | /********************************* 19 | * Logic => Javascript HELPERS 20 | *********************************/ 21 | 22 | /* 23 | * Message generators 24 | */ 25 | $_message_id_counter = 1; 26 | function _gen_new_msg_id() 27 | { 28 | global $LOGIC_ID, $_message_id_counter; 29 | return sprintf("%s-%s", $LOGIC_ID, $_message_id_counter++); 30 | } 31 | function _gen_new_msg_date() 32 | { 33 | return time(); 34 | } 35 | 36 | function _generic_msg($type, $args) 37 | { 38 | $msg = $args[0]; 39 | if (gettype($msg) == 'string') { 40 | $msg = array(); 41 | if(count($args) > 1) { 42 | $msg['message'] = call_user_func_array('sprintf', $args); 43 | } else { 44 | $msg['message'] = $args[0]; 45 | } 46 | } else { 47 | $msg = $msg; // copy hash ? 48 | } 49 | 50 | // Set author 51 | if($type == 'chat') { 52 | if( is_null($msg['from']) ) { 53 | throw new Exception('Missed value for "from" key for type=chat'); 54 | } 55 | 56 | $msg['author'] = $msg['from']->nick(); 57 | } 58 | unset($msg['from']); 59 | 60 | // Verify that message is set 61 | if( is_null($msg['message']) ) { 62 | throw new Exception('Missed value for "message" key'); 63 | } 64 | 65 | // Fill other fields structure 66 | $msg['class'] = $type; 67 | if( !isset($msg['id']) ) $msg['id'] = _gen_new_msg_id(); 68 | if( !isset($msg['date']) ) $msg['date'] = _gen_new_msg_date(); 69 | 70 | return array('chat', $msg); 71 | } 72 | 73 | 74 | function chat_msg($msg) { return _generic_msg('chat', func_get_args()); } 75 | function info_msg($msg) { return _generic_msg('info', func_get_args()); } 76 | function ok_msg($msg) { return _generic_msg('ok', func_get_args()); } 77 | function error_msg($msg) { return _generic_msg('error', func_get_args()); } 78 | 79 | 80 | ?> -------------------------------------------------------------------------------- /app/oauth_callback.php: -------------------------------------------------------------------------------- 1 | enableDebug(); 29 | 30 | $oauth->setToken($_GET['oauth_token'], $_SESSION['secret']); 31 | $access_token_info = $oauth->getAccessToken($acc_url); 32 | 33 | $_SESSION['token'] = strval($access_token_info['oauth_token']); 34 | $_SESSION['secret'] = strval($access_token_info['oauth_token_secret']); 35 | 36 | $oauth->setToken($_SESSION['token'], $_SESSION['secret']); 37 | 38 | /// получаем данные пользователя через /api/0.6/user/details 39 | $oauth->fetch($api_url."user/details"); 40 | $user_details = $oauth->getLastResponse(); 41 | 42 | // парсим ответ, получаем имя осмопользователя и его id 43 | $xml = simplexml_load_string($user_details); 44 | $_SESSION['osm_id'] = strval ($xml->user['id']); 45 | $_SESSION['osm_user'] = strval($xml->user['display_name']); 46 | 47 | // Получение id, если нету, то добавление в базу 48 | $pg_osm_user = pg_escape_string($_SESSION['osm_user']); 49 | $result = pg_query($connection, 'SELECT id FROM users WHERE nick=\''.$pg_osm_user.'\''); 50 | if (pg_num_rows($result) > 0) 51 | $_SESSION['user_id'] = pg_fetch_result($result, 0 ,0); 52 | else 53 | $_SESSION['user_id'] = pg_fetch_result(pg_query($connection, 'INSERT INTO users VALUES(\''.$pg_osm_user.'\', DEFAULT, DEFAULT) RETURNING id'), 0 ,0); 54 | 55 | /// тут мы можем создать юзера в своей базе и сохранить его osm_id, osm_user, token? и secret?. 56 | 57 | // Переход на станицу успеха 58 | Header("Location: /app/auth.php?action=success"); 59 | 60 | } catch(OAuthException $E) { 61 | echo("Exception:\n"); 62 | print_r($E); 63 | } 64 | -------------------------------------------------------------------------------- /hub/src/logic.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(logic). 8 | -behaviour(gen_server). 9 | 10 | -export([start_link/0]). 11 | -export([add_me/0, process/1, process_async/1, process_and_wait/1]). 12 | -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). 13 | 14 | start_link() -> 15 | gen_server:start_link({local, logic}, logic, [], []). 16 | 17 | %% 18 | %% Interface 19 | %% 20 | 21 | add_me() -> 22 | gen_server:call(logic, {add_worker, self()}). 23 | 24 | process(HubReq) -> 25 | case gen_server:call(logic, {process, HubReq}) of 26 | wait -> 27 | error_logger:warning_report(["all logic workers are busy. Please increase logic workers count", 28 | {self, self()}, 29 | {hubreq, HubReq}]), 30 | receive 31 | after 100 -> 32 | process(HubReq) 33 | end; 34 | Res -> 35 | Res 36 | end. 37 | 38 | process_and_wait(HubReq) -> 39 | ok = process(HubReq), 40 | wait_for_answer(HubReq, 0). 41 | 42 | wait_for_answer(HubReq, Ref) -> 43 | receive 44 | {answer, HubReq, Data} -> 45 | {ok, Data}; 46 | 47 | {follow_me, Pid} -> 48 | catch erlang:demonitor(Ref), 49 | NewRef = erlang:monitor(process, Pid), 50 | wait_for_answer(HubReq, NewRef); 51 | 52 | {'DOWN', Ref, process, From, Reason} -> 53 | Report = ["sync request failed", 54 | {hubreq, HubReq}, 55 | {following, From}, 56 | {reason, Reason}], 57 | error_logger:error_report(Report), 58 | {fail, {down, Reason}} 59 | after 10000 -> 60 | {fail, timeout} 61 | end. 62 | 63 | 64 | process_async(HubReq) -> 65 | Fun = fun() -> 66 | ok = logic:process(HubReq) 67 | end, 68 | spawn(Fun), 69 | ok. 70 | 71 | %% 72 | %% gen_server callbacks 73 | %% 74 | init(_Args) -> 75 | {ok, _Pool = []}. 76 | 77 | handle_call({add_worker, Worker}, _From, Pool) -> 78 | {reply, ok, [Worker|Pool]}; 79 | 80 | handle_call({process, HubReq}, _From, Pool) -> 81 | case Pool of 82 | [] -> 83 | {reply, wait, Pool}; 84 | [Head|Tail] -> 85 | logic_worker:process(Head, HubReq), 86 | {reply, ok, Tail} 87 | end. 88 | 89 | handle_info(_Msg, State) -> 90 | {noreply, State}. 91 | 92 | handle_cast(_Msg, State) -> 93 | {noreply, State}. 94 | 95 | code_change(_, State, _) -> 96 | {ok, State}. 97 | 98 | terminate(_Reason, _State) -> 99 | ok. 100 | -------------------------------------------------------------------------------- /lib/Log/null.php: -------------------------------------------------------------------------------- 1 | 14 | * @since Log 1.8.2 15 | * @package Log 16 | * 17 | * @example null.php Using the null handler. 18 | */ 19 | class Log_null extends Log 20 | { 21 | /** 22 | * Constructs a new Log_null object. 23 | * 24 | * @param string $name Ignored. 25 | * @param string $ident The identity string. 26 | * @param array $conf The configuration array. 27 | * @param int $level Log messages up to and including this level. 28 | * @access public 29 | */ 30 | function Log_null($name, $ident = '', $conf = array(), 31 | $level = PEAR_LOG_DEBUG) 32 | { 33 | $this->_id = md5(microtime()); 34 | $this->_ident = $ident; 35 | $this->_mask = Log::UPTO($level); 36 | } 37 | 38 | /** 39 | * Opens the handler. 40 | * 41 | * @access public 42 | * @since Log 1.9.6 43 | */ 44 | function open() 45 | { 46 | $this->_opened = true; 47 | return true; 48 | } 49 | 50 | /** 51 | * Closes the handler. 52 | * 53 | * @access public 54 | * @since Log 1.9.6 55 | */ 56 | function close() 57 | { 58 | $this->_opened = false; 59 | return true; 60 | } 61 | 62 | /** 63 | * Simply consumes the log event. The message will still be passed 64 | * along to any Log_observer instances that are observing this Log. 65 | * 66 | * @param mixed $message String or object containing the message to log. 67 | * @param string $priority The priority of the message. Valid 68 | * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, 69 | * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, 70 | * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. 71 | * @return boolean True on success or false on failure. 72 | * @access public 73 | */ 74 | function log($message, $priority = null) 75 | { 76 | /* If a priority hasn't been specified, use the default value. */ 77 | if ($priority === null) { 78 | $priority = $this->_priority; 79 | } 80 | 81 | /* Abort early if the priority is above the maximum logging level. */ 82 | if (!$this->_isMasked($priority)) { 83 | return false; 84 | } 85 | 86 | $this->_announce(array('priority' => $priority, 'message' => $message)); 87 | 88 | return true; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /hub/src/hub_web.erl: -------------------------------------------------------------------------------- 1 | %% @author Mochi Media 2 | %% @copyright 2010 Mochi Media 3 | 4 | %% @doc Web server for hub. 5 | 6 | -module(hub_web). 7 | -author("Mochi Media "). 8 | 9 | -export([start/1, stop/0, loop/1]). 10 | -export([ok/2, fail/1, follow_me/1]). 11 | 12 | -include("hub.hrl"). 13 | -define(LOOP, {?MODULE, loop}). 14 | %% 15 | %% External API 16 | %% 17 | start(Options) -> 18 | mochiweb_http:start([{name, ?MODULE}, {loop, ?LOOP} | Options]). 19 | 20 | stop() -> 21 | mochiweb_http:stop(?MODULE). 22 | 23 | loop(Req) -> 24 | Path = Req:get(path), 25 | Method = Req:get(method), 26 | Hub_prefix = config:get(hub_prefix), 27 | try 28 | case {Method, string:tokens(Path, "/")} of 29 | 30 | %% CORS support 31 | {'OPTIONS', _} -> 32 | Req:ok({_Content = "test/plain", 33 | _Headers = std_headers() ++ 34 | [{"Access-Control-Allow-Methods", "POST, GET, OPTIONS"}, 35 | {"Access-Control-Allow-Headers", "X-Requested-With"}], 36 | "ok"}); 37 | 38 | %% /hub/* -> our hub requests 39 | {Method, [ Hub_prefix | Rest ]}-> 40 | handle_hub_req(Method, Req, Rest); 41 | 42 | _ -> 43 | Req:not_found() 44 | end 45 | catch 46 | exit:normal -> 47 | fail(Req); 48 | Type:What -> 49 | Report = ["web request failed", 50 | {path, Path}, 51 | {type, Type}, {what, What}, 52 | {trace, erlang:get_stacktrace()}], 53 | error_logger:error_report(Report), 54 | fail(Req) 55 | end. 56 | 57 | %% 58 | %% Internal API - handling requests to hub/ 59 | %% 60 | 61 | %% Method on 'hub/pie/PieId/SesId/TabId -- subscribe/publish in channels 62 | handle_hub_req(Method, Req, ["pie", PieId, SesId, TabId | Rest]) -> 63 | ChanId = #hub_chan{ pieid = PieId, 64 | sesid = SesId, 65 | tabid = TabId }, 66 | Chan = chan:new(ChanId, Req), 67 | Chan:handle(Method, Rest); 68 | 69 | handle_hub_req(Method, Req, ["api" | Rest]) -> 70 | stats:incr({api, calls}), 71 | hub_api:handle(Method, Req, Rest). 72 | 73 | 74 | %% 75 | %% Helpers 76 | %% 77 | ok(Req, Msg) -> 78 | Req:ok({_Content = "text/plain", 79 | _Headers = std_headers(), 80 | Msg}). 81 | 82 | fail(Req) -> 83 | Req:respond({500, [{"Content-Type", "text/plain"}] ++ std_headers(), 84 | "request failed, sorry\n"}). 85 | 86 | std_headers() -> 87 | [{"Server", "MapCraft Hub (Mochiweb)"}, 88 | {"Access-Control-Allow-Origin", config:get(origin)}]. 89 | 90 | %% TODO: move to another module 91 | follow_me(HubReq) -> 92 | case HubReq#hub_req.type of 93 | sync -> 94 | HubReq#hub_req.caller ! {follow_me, self()}; 95 | _ -> 96 | ok 97 | end. 98 | 99 | 100 | %% 101 | %% Tests 102 | %% 103 | -ifdef(TEST). 104 | -include_lib("eunit/include/eunit.hrl"). 105 | 106 | -endif. 107 | -------------------------------------------------------------------------------- /app/delete.php: -------------------------------------------------------------------------------- 1 | 44 | 45 | 46 | 47 | MapCraft — massively mapping management tool for OpenStreetMap 48 | 49 | 50 | 51 | 52 | 53 |
MapCraft beta
54 |
60 |
61 | Logout'; 63 | ?> 64 |
65 |
66 |
Remove this cake, are you sure?

67 |
68 | 69 |
70 |
71 | 74 | 75 | -------------------------------------------------------------------------------- /hub/src/chanlist.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(chanlist, [ByChan, BySes]). 8 | -compile(export_all). 9 | 10 | -include("hub.hrl"). 11 | 12 | %% 13 | %% online/offline 14 | %% 15 | set_online(ChanId, Pid) -> 16 | ok = delete(chanid, ChanId), 17 | insert(ChanId, Pid, online). 18 | 19 | set_offline(chanid, ChanId, Pid) -> 20 | case lookup_raw(chanid, ChanId) of 21 | [Entry] -> 22 | set_offline(entry, Entry, Pid); 23 | [] -> 24 | insert(ChanId, Pid, offline) 25 | end; 26 | 27 | set_offline(entry, Entry, Pid) -> 28 | {ChanId, _, CurPid, CurState, _} = Entry, 29 | case {CurPid, CurState} of 30 | {_, offline} -> 31 | ok; 32 | {Pid, online} -> 33 | ok = delete(chanid, ChanId), 34 | insert(ChanId, Pid, offline); 35 | {CurPid, online} -> 36 | {new_pid, CurPid} 37 | end. 38 | 39 | %% 40 | %% Lookup and other info 41 | %% 42 | lookup(Type, Id) -> 43 | {ok, fmt_lookup(lookup_raw(Type, Id))}. 44 | 45 | lookup() -> 46 | {ok, fmt_lookup(lookup_raw())}. 47 | 48 | lookup_raw(sesid, SesId) -> 49 | ets:lookup(BySes, SesId); 50 | 51 | lookup_raw(chanid, ChanId) -> 52 | ets:lookup(ByChan, ChanId). 53 | 54 | lookup_raw() -> 55 | ets:tab2list(ByChan). 56 | 57 | lookup_expired() -> 58 | {ok, fmt_lookup(lookup_expired_raw())}. 59 | 60 | lookup_expired_raw() -> 61 | Now = now_secs(), 62 | OfflineExpire = Now - config:get(chan_expire), 63 | OnlineExpire = OfflineExpire - config:get(poll_timeout), 64 | ets:foldl(fun({_, _, _, State, Mtime} = X, Acc) -> 65 | case State of 66 | online when Mtime < OnlineExpire -> 67 | [ X | Acc]; 68 | offline when Mtime < OfflineExpire -> 69 | [ X | Acc]; 70 | _ -> 71 | Acc 72 | end 73 | end, [], ByChan). 74 | 75 | size() -> 76 | Info = ets:info(ByChan), 77 | proplists:get_value(size, Info). 78 | 79 | %% 80 | %% List modifications 81 | %% 82 | insert(ChanId, Pid, State) -> 83 | insert(ChanId, Pid, State, now_secs()). 84 | 85 | insert(ChanId, Pid, State, Mtime) -> 86 | Entry = {ChanId, ChanId#hub_chan.sesid, Pid, State, Mtime}, 87 | ets:insert(ByChan, Entry), 88 | ets:insert(BySes, Entry), 89 | ok. 90 | 91 | delete(Type, Id) -> 92 | Entries = lookup_raw(Type, Id), 93 | lists:foreach( fun(Entry) -> 94 | ets:delete_object(ByChan, Entry), 95 | ets:delete_object(BySes, Entry) 96 | end, Entries ), 97 | ok. 98 | 99 | %% 100 | %% Helpers 101 | %%0 102 | fmt_lookup(Entries) -> 103 | [{Pid, ChanId, State} || {ChanId, _, Pid, State, _} <- Entries]. 104 | 105 | now_secs() -> 106 | calendar:datetime_to_gregorian_seconds(calendar:universal_time()). 107 | -------------------------------------------------------------------------------- /app/load.php: -------------------------------------------------------------------------------- 1 | 'localhost', 'username' => 'mapcrafter', 'password' => 'nekosan', 'dbname' => 'pie' ); 7 | if( !mysql_connect($config['hostname'], $config['username'], $config['password']) ) 8 | { 9 | exit(); 10 | } 11 | 12 | if( !mysql_select_db($config['dbname']) ) 13 | { 14 | exit(); 15 | } 16 | mysql_query("SET NAMES 'utf8'"); 17 | 18 | Header("Cache-Control: no-cache, must-revalidate"); 19 | Header("Pragma: no-cache"); 20 | Header("Content-Type: text/javascript; charset=utf-8"); 21 | 22 | if (isset($_POST['nick'])) 23 | $nick = mysql_real_escape_string(htmlspecialchars(substr($_POST['nick'], 0, 64))); 24 | 25 | if (mysql_result(mysql_query("SELECT COUNT(*) FROM online WHERE `nick` = '".$nick."'"), 0) > 0) 26 | mysql_query("UPDATE `online` SET `lastactivity`=".time().", `online`=1 WHERE `nick`='".$nick."'"); 27 | else 28 | { 29 | mysql_query("INSERT INTO `online` SET `nick`='".$nick."',`lastactivity`=".time()); 30 | mysql_query("UPDATE `online` SET `quserlist`=1"); 31 | } 32 | 33 | $pre = mysql_result(mysql_query("SELECT COUNT(*) FROM `online` WHERE `lastactivity`<".(time()-35)." AND `online`"), 0); 34 | if ($pre > 0) { 35 | mysql_query("UPDATE `online` SET `online`=0 WHERE `lastactivity`<".(time()-35)." AND `online`"); 36 | mysql_query("UPDATE `online` SET `qnews`=1,`quserlist`=1"); 37 | } 38 | 39 | // Основной цикл ожидания событий 40 | $time = time(); 41 | while((time() - $time) < 30) { 42 | if (mysql_result(mysql_query("SELECT `qnews` FROM `online` WHERE `nick`='".$nick."'"), 0) == 1) { 43 | echo Load(); 44 | mysql_query("UPDATE `online` SET `qnews`=0 WHERE `nick`='".$nick."'"); 45 | break; 46 | } 47 | sleep(1); 48 | } 49 | 50 | function Load() 51 | { 52 | global $nick; 53 | 54 | $last_message_id = intval($_POST['last']); 55 | 56 | $query = mysql_query("SELECT * FROM `messages` WHERE ( id > $last_message_id ) ORDER BY id DESC LIMIT 10"); 57 | 58 | if( mysql_num_rows($query) > 0 ) 59 | { 60 | 61 | $js = 'var chat = $("#chat tbody");'; 62 | 63 | $messages = array(); 64 | while ( $row = mysql_fetch_array($query) ) 65 | { 66 | $messages[] = $row; 67 | } 68 | 69 | $last_message_id = $messages[0]['id']; 70 | 71 | $messages = array_reverse($messages); 72 | 73 | foreach ( $messages as $value ) 74 | { 75 | $js .= 'chat.append("<' . $value['name'] . '>' . $value['text'] . ''.substr($value['ts'],0,5).'");'; 76 | } 77 | 78 | $js .= "last_message_id = $last_message_id;"; 79 | 80 | } 81 | 82 | if (mysql_result(mysql_query("SELECT COUNT(*) FROM `online` WHERE `nick` = '".$nick."' AND `quserlist`=1"), 0) > 0) 83 | { 84 | $js .= "RenewUserlist();"; 85 | mysql_query("UPDATE `online` SET `quserlist`=0 WHERE `nick`='".$nick."'"); 86 | } 87 | if (mysql_result(mysql_query("SELECT COUNT(*) FROM `online` WHERE `nick` = '".$nick."' AND `qgeodata`=1"), 0) > 0) 88 | { 89 | $js .= "RenewKML();"; 90 | mysql_query("UPDATE `online` SET `qgeodata`=0 WHERE `nick`='".$nick."'"); 91 | } 92 | 93 | return $js; 94 | } 95 | ?> 96 | -------------------------------------------------------------------------------- /hub/src/logic_worker.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(logic_worker). 8 | -behaviour(gen_server). 9 | 10 | -export([start_link/0]). 11 | -export([process/2]). 12 | -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). 13 | 14 | -include("hub.hrl"). 15 | -record(state, {id, port}). 16 | 17 | start_link() -> 18 | gen_server:start_link(logic_worker, [], []). 19 | 20 | 21 | %% 22 | %% Interface 23 | %% 24 | process(Worker, HubReq) -> 25 | gen_server:cast(Worker, {process, HubReq}). 26 | 27 | %% 28 | %% gen_server callbacks 29 | %% 30 | init(_Options) -> 31 | Id = stats:get_next({logic, starts}), 32 | Cmd = config:get(logic_cmd) ++ " -i " ++ integer_to_list(Id), 33 | Port = open_port({spawn, Cmd}, [stream, {line, 1000}, exit_status, stderr_to_stdout]), 34 | logic:add_me(), 35 | {ok, #state{id = Id, port = Port}}. 36 | 37 | 38 | handle_cast({process, HubReq}, State) -> 39 | stats:incr({logic, requests}), 40 | hub_web:follow_me(HubReq), 41 | {ok, Res} = process_req(State#state.port, HubReq#hub_req.cmd), 42 | router:spawn_new(HubReq, Res), 43 | logic:add_me(), 44 | {noreply, State}. 45 | 46 | handle_info({Port, {exit_status, Reason}}, #state{port = Port} = State) -> 47 | stats:incr({logic, crashes}), 48 | error_logger:error_report(["Logic process terminated", {state, State}, {retcode, Reason}]), 49 | {stop, {port_terminated, Reason}, State}. 50 | 51 | terminate({port_terminated, _}, _) -> 52 | ok; 53 | terminate(_Reason, #state{port = Port}) -> 54 | port_close(Port). 55 | 56 | handle_call(_Msg, _From, State) -> 57 | {noreply, State}. 58 | 59 | code_change(_, State, _) -> 60 | {ok, State}. 61 | 62 | %% TODO: trapexit for Port, handle terminate (close port) 63 | 64 | %% 65 | %% private 66 | %% 67 | 68 | %% We are recieving response lines splitted by 1000 bytes. 69 | %% join them and return all lines 70 | skip_warning(<<"PHP Warning: ", Warn/binary>>) -> 71 | stats:incr({logic,php,warnings}), 72 | error_logger:warning_report([{php_warn, Warn}]), 73 | warn; 74 | skip_warning(_) -> 75 | ok. 76 | 77 | read_response(Port, RespAcc, LineAcc) -> 78 | receive 79 | {Port, {data, {eol, "EOR"}}} -> 80 | {ok, lists:reverse(RespAcc)}; 81 | 82 | {Port, {data, {eol, Line}}} -> 83 | Response = list_to_binary(lists:reverse([Line | LineAcc])), 84 | case skip_warning(Response) of 85 | ok -> 86 | read_response(Port, [Response | RespAcc], []); 87 | warn -> 88 | read_response(Port, RespAcc, []) 89 | end; 90 | {Port, {data, {noeol, LinePart}}} -> 91 | read_response(Port, RespAcc, [LinePart | LineAcc]) 92 | 93 | after config:get(logic_timeout) * 1000 -> 94 | timeout 95 | end. 96 | 97 | process_req(Port, Cmd) -> 98 | port_command(Port, Cmd), 99 | read_response(Port, [], []). 100 | -------------------------------------------------------------------------------- /logic/main.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | notice("Starting new logic server"); 44 | 45 | // Handle PHP errors 46 | function formatError($errno, $errstr, $errfile, $errline) { 47 | return "on " . $errfile . ":" . $errline . " [" . $errno . "]: " . $errstr; 48 | } 49 | 50 | function myErrorHandler($errno, $errstr, $errfile, $errline) { 51 | global $logger; 52 | $logger->err("PHP error " . formatError($errno, $errstr, $errfile, $errline)); 53 | } 54 | set_error_handler("myErrorHandler"); 55 | 56 | function myExceptionHandler($exception) { 57 | global $logger; 58 | $logger->err("Uncaught exception: " , $exception->getMessage()); 59 | } 60 | set_exception_handler('myExceptionHandler'); 61 | 62 | function myShutdownHandler() { 63 | global $logger; 64 | $a=error_get_last(); 65 | if($a != null) 66 | $logger->emerg("Fatal PHP error " . formatError($a['type'], $a['message'], $a['file'], $a['line'])); 67 | } 68 | register_shutdown_function('myShutdownHandler'); 69 | 70 | 71 | // Main pipe reading/writing loop 72 | $fp=fopen("php://stdin","r"); 73 | while(!feof($fp)) { 74 | $cmd = stream_get_line($fp, 4 * 1024 * 1024, "\n"); 75 | $res = new HubResult(); 76 | 77 | if ($cmd == '') 78 | continue; 79 | $logger->info("IN << $cmd"); 80 | 81 | // Try to handle command. catch all exceptions 82 | try { 83 | process_hub_message($cmd, $res); 84 | } 85 | catch(Exception $e) { 86 | $logger->err("EXCEPTION: " . $e->getMessage()); 87 | $msg = error_msg($e->getMessage()); 88 | $res->to_sender($msg); 89 | } 90 | 91 | $res->output(); 92 | 93 | foreach ($res->data as $line) { 94 | $logger->info("OUT >> $line"); 95 | } 96 | 97 | // break after first run in testing mode 98 | if($TEST_MODE) 99 | break; 100 | } 101 | fclose($fp); 102 | 103 | ?> 104 | -------------------------------------------------------------------------------- /hub/src/router.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(router). 8 | -compile(export_all). 9 | 10 | -include("hub.hrl"). 11 | 12 | %% 13 | %% Interface 14 | %% 15 | spawn_new(HubReq, Lines) -> 16 | spawn(?MODULE, route_all, [HubReq, Lines]). 17 | 18 | got_it(Pid) -> 19 | Pid ! {self(), ok}. 20 | 21 | not_me(Pid) -> 22 | Pid ! {self(), not_me}. 23 | 24 | defer(Pid) -> 25 | Pid ! {self(), defer}. 26 | 27 | %% 28 | %% Routing 29 | %% 30 | route_all(HubReq, Lines) -> 31 | stats:incr({router, spawns}), 32 | hub_web:follow_me(HubReq), 33 | [ route_one_safely(HubReq, Line) || Line <- Lines ]. 34 | 35 | route_one_safely(HubReq, Line) -> 36 | try 37 | [Cmd | Rest] = api:parse_line(Line), 38 | ok = route_one(Cmd, HubReq, Rest) 39 | catch 40 | Type:What -> 41 | stats:incr({router, lost}), 42 | Report = [ "failed to route answer line", 43 | {line, Line}, 44 | {type, Type}, {what, What}, 45 | {hubreq, HubReq}, 46 | {trace, erlang:get_stacktrace()} ], 47 | error_logger:error_report(Report) 48 | end. 49 | 50 | route_one("respond", HubReq, [{json, Json}]) -> 51 | sync = HubReq#hub_req.type, 52 | stats:incr({router, to, caller}), 53 | HubReq#hub_req.caller ! {answer, HubReq, Json}, 54 | ok; 55 | 56 | route_one("to_sender", HubReq, [Msg]) -> 57 | stats:incr({router, to, sender}), 58 | PieId = HubReq#hub_req.pieid, 59 | SesId = HubReq#hub_req.sesid, 60 | TabId = HubReq#hub_req.tabid, 61 | Dests = pie:lookup(PieId, SesId, TabId), 62 | push_event_to_chans(Dests, Msg), 63 | ok; 64 | 65 | route_one("to_session", _, [PieId, SesId, Msg]) -> 66 | stats:incr({router, to, session}), 67 | Dests = pie:lookup(PieId, SesId), 68 | push_event_to_chans(Dests, Msg), 69 | ok; 70 | 71 | route_one("to_pie", _, [PieId, Msg]) -> 72 | stats:incr({router, to, pie}), 73 | Dests = pie:lookup(PieId), 74 | push_event_to_chans(Dests, Msg, allow_empty), 75 | ok; 76 | 77 | route_one("stat", _, Args) -> 78 | stats:external(Args), 79 | ok. 80 | 81 | %route_one("to_all", _, [_Msg]) -> 82 | % TODO 83 | % ok. 84 | 85 | %% 86 | %% Pushing event to channels 87 | %% 88 | push_event_to_chans(Dests, Msg) -> 89 | push_event_to_chans(Dests, Msg, none). 90 | 91 | push_event_to_chans([], _Msg, allow_empty) -> 92 | ok; 93 | push_event_to_chans([_|_] = Dests, Msg, _) -> 94 | Cmd = api:format_line([event, Msg]), 95 | [ push(Dest, Cmd) || Dest <- Dests ]. 96 | 97 | push({_, ChanId, offline}, Cmd) -> 98 | ok = mqueue:store(ChanId, Cmd); 99 | 100 | push({Pid, ChanId, online}, Cmd) -> 101 | Pid ! {send, self(), ChanId, Cmd}, 102 | receive 103 | {Pid, ok} -> 104 | stats:incr({router, to, channel}), 105 | ok; 106 | {Pid, _Ans} -> 107 | ok = mqueue:store(ChanId, Cmd) 108 | after 50 -> 109 | case pie:suspend(ChanId, Pid) of 110 | ok -> 111 | ok = mqueue:store(ChanId, Cmd); 112 | {new_pid, NewPid} -> 113 | push({NewPid, ChanId, online}, Cmd) 114 | end 115 | end. 116 | -------------------------------------------------------------------------------- /hub/src/chan.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(chan, [ChanId, Req]). 8 | -export([handle/2]). 9 | -include("hub.hrl"). 10 | 11 | 12 | handle('POST', []) -> 13 | stats:incr({chan, pushes}), 14 | Data = binary_to_list(Req:recv_body()), 15 | [Type | Rest] = api:parse_line(Data), 16 | handle_api(Type, Rest); 17 | 18 | handle('GET', []) -> 19 | stats:incr({chan, polls}), 20 | case mqueue:check_for_me(ChanId) of 21 | {ok, []} -> 22 | Ref = pie:subscribe(ChanId), 23 | wait_loop(Ref), 24 | erlang:demonitor(Ref); 25 | {ok, Msgs} -> 26 | hub_web:ok(Req, lists:flatten(Msgs)) 27 | end; 28 | 29 | handle('GET', ["init"]) -> 30 | pie:suspend(ChanId), 31 | hub_web:ok(Req, "ok"). 32 | 33 | 34 | %% 35 | %% API handlers 36 | %% 37 | handle_api(Type, [Msg]) when Type =:= "async"; Type =:= "sync" -> 38 | HubReq = format_hub_req(Type, Msg), 39 | push(HubReq). 40 | 41 | 42 | %% 43 | %% Pushing 44 | %% 45 | push(HubReq = #hub_req{type = async}) -> 46 | stats:incr({chan, pushes, async}), 47 | ok = logic:process(HubReq), 48 | hub_web:ok(Req, "ok"); 49 | 50 | push(HubReq = #hub_req{type = sync}) -> 51 | stats:incr({chan, pushes, sync}), 52 | case logic:process_and_wait(HubReq) of 53 | {ok, Data} -> 54 | hub_web:ok(Req, Data); 55 | {fail, _} -> 56 | hub_web:fail(Req) 57 | end. 58 | 59 | format_hub_req(Type, Msg) -> 60 | PieId = ChanId#hub_chan.pieid, 61 | SesId = ChanId#hub_chan.sesid, 62 | TabId = ChanId#hub_chan.tabid, 63 | #hub_req{ 64 | pieid = PieId, 65 | sesid = SesId, 66 | tabid = TabId, 67 | type = list_to_atom(Type), 68 | caller = self(), 69 | cmd = api:format_line(["from", Type, PieId, SesId, Msg]) 70 | }. 71 | 72 | 73 | %% 74 | %% Polling 75 | %% 76 | wait_loop(Ref) -> 77 | receive 78 | {send, Router, ChanId, Line} -> 79 | router:got_it(Router), 80 | {ok, Events} = accomulate_events(Router, [Line]), 81 | hub_web:ok(Req, lists:flatten(Events)); 82 | {send, AnotherRouter, _, _} -> 83 | router:not_me(AnotherRouter), 84 | wait_loop(Ref); 85 | {'DOWN', Ref, process, _, _} -> 86 | hub_web:fail(Req) 87 | after config:get(poll_timeout) * 1000 -> 88 | hub_web:ok(Req, <<"event!json:[\"nop\", {\"reason\": \"poll timeout\"}]\n">>) 89 | end. 90 | 91 | accomulate_events(Router, Acc) -> 92 | erlang:monitor(process, Router), 93 | accomulate_events0(Router, Acc). 94 | 95 | accomulate_events0(Router, Acc) -> 96 | receive 97 | {send, Router, ChanId, Line} -> 98 | router:got_it(Router), 99 | accomulate_events0(Router, [Line | Acc]); 100 | 101 | {send, AnotherRouter, ChanId, _} -> 102 | router:defer(AnotherRouter), 103 | accomulate_events0(Router, Acc); 104 | 105 | {send, AnotherRouter, _, _} -> 106 | router:not_me(AnotherRouter), 107 | accomulate_events0(Router, Acc); 108 | 109 | {'DOWN', _, process, Router, _} -> 110 | {ok, lists:reverse(Acc)}; 111 | 112 | Any -> 113 | error_logger:error_report(["Unknown message in event accomulation", 114 | {msg, Any}]) 115 | after 1000 -> 116 | {error, timeout} 117 | end. 118 | -------------------------------------------------------------------------------- /hub/src/hub_deps.erl: -------------------------------------------------------------------------------- 1 | %% @author Mochi Media 2 | %% @copyright 2010 Mochi Media 3 | 4 | %% @doc Ensure that the relatively-installed dependencies are on the code 5 | %% loading path, and locate resources relative 6 | %% to this application's path. 7 | 8 | -module(hub_deps). 9 | -author("Mochi Media "). 10 | 11 | -export([ensure/0, ensure/1]). 12 | -export([get_base_dir/0, get_base_dir/1]). 13 | -export([local_path/1, local_path/2]). 14 | -export([deps_on_path/0, new_siblings/1]). 15 | 16 | %% @spec deps_on_path() -> [ProjNameAndVers] 17 | %% @doc List of project dependencies on the path. 18 | deps_on_path() -> 19 | F = fun (X, Acc) -> 20 | ProjDir = filename:dirname(X), 21 | case {filename:basename(X), 22 | filename:basename(filename:dirname(ProjDir))} of 23 | {"ebin", "deps"} -> 24 | [filename:basename(ProjDir) | Acc]; 25 | _ -> 26 | Acc 27 | end 28 | end, 29 | ordsets:from_list(lists:foldl(F, [], code:get_path())). 30 | 31 | %% @spec new_siblings(Module) -> [Dir] 32 | %% @doc Find new siblings paths relative to Module that aren't already on the 33 | %% code path. 34 | new_siblings(Module) -> 35 | Existing = deps_on_path(), 36 | SiblingEbin = filelib:wildcard(local_path(["deps", "*", "ebin"], Module)), 37 | Siblings = [filename:dirname(X) || X <- SiblingEbin, 38 | ordsets:is_element( 39 | filename:basename(filename:dirname(X)), 40 | Existing) =:= false], 41 | lists:filter(fun filelib:is_dir/1, 42 | lists:append([[filename:join([X, "ebin"]), 43 | filename:join([X, "include"])] || 44 | X <- Siblings])). 45 | 46 | 47 | %% @spec ensure(Module) -> ok 48 | %% @doc Ensure that all ebin and include paths for dependencies 49 | %% of the application for Module are on the code path. 50 | ensure(Module) -> 51 | code:add_paths(new_siblings(Module)), 52 | code:clash(), 53 | ok. 54 | 55 | %% @spec ensure() -> ok 56 | %% @doc Ensure that the ebin and include paths for dependencies of 57 | %% this application are on the code path. Equivalent to 58 | %% ensure(?Module). 59 | ensure() -> 60 | ensure(?MODULE). 61 | 62 | %% @spec get_base_dir(Module) -> string() 63 | %% @doc Return the application directory for Module. It assumes Module is in 64 | %% a standard OTP layout application in the ebin or src directory. 65 | get_base_dir(Module) -> 66 | {file, Here} = code:is_loaded(Module), 67 | filename:dirname(filename:dirname(Here)). 68 | 69 | %% @spec get_base_dir() -> string() 70 | %% @doc Return the application directory for this application. Equivalent to 71 | %% get_base_dir(?MODULE). 72 | get_base_dir() -> 73 | get_base_dir(?MODULE). 74 | 75 | %% @spec local_path([string()], Module) -> string() 76 | %% @doc Return an application-relative directory from Module's application. 77 | local_path(Components, Module) -> 78 | filename:join([get_base_dir(Module) | Components]). 79 | 80 | %% @spec local_path(Components) -> string() 81 | %% @doc Return an application-relative directory for this application. 82 | %% Equivalent to local_path(Components, ?MODULE). 83 | local_path(Components) -> 84 | local_path(Components, ?MODULE). 85 | -------------------------------------------------------------------------------- /lib/drawers/progress1.php: -------------------------------------------------------------------------------- 1 | array('621a1a', 'c43636'), 7 | 'middle' => array('774600', 'd17b00'), 8 | 'high' => array('00221a', '006e5a')); 9 | 10 | 11 | function draw($pie_id, $base_name, $ext, $args) { 12 | if (!in_array($ext, array('png', 'svg'))) 13 | throw new Exception("Selected banner type does not support output extension '$ext'"); 14 | 15 | // Firstly draw svg. We need it either way 16 | $svg_output = draw_svg($pie_id, $base_name, $args); 17 | 18 | if ($ext == 'svg') { 19 | header("Content-type: image/svg+xml;"); 20 | readfile($svg_output); 21 | exit; 22 | } 23 | 24 | if ($ext == 'png') { 25 | $png_output = convert_to_png($svg_output, $base_name); 26 | header("Content-type: image/png;"); 27 | readfile($png_output); 28 | exit; 29 | } 30 | } 31 | 32 | function draw_svg($pie_id, $base_name, $args) { 33 | global $output_dir; 34 | global $svg_template; 35 | global $bg_schemes; 36 | 37 | $bar_start = 48; 38 | $bar_end = 312.4; 39 | $bar_len = $bar_end - $bar_start; 40 | 41 | $svg_output = $output_dir . $base_name . '.svg'; 42 | if (file_exists($svg_output)) 43 | return $svg_output; 44 | 45 | // Parse 46 | $xdoc = new DomDocument; 47 | $xdoc->Load($svg_template); 48 | $xp = new DomXPath($xdoc); 49 | 50 | // Get progress from DB 51 | $result = pg_query("SELECT state FROM pieces WHERE pie = " . $pie_id); 52 | $states = pg_fetch_all_columns($result, 0); 53 | $progress = array(0,0,0,0,0,0,0,0,0,0); 54 | $full_sum = 9 * count($states); 55 | $current_sum = 0; 56 | foreach ($states as $st) { 57 | $progress[$st] ++; 58 | $current_sum += $st; 59 | } 60 | 61 | // Calculate bars positions and widths 62 | $offset = $bar_start; 63 | $step = $bar_len / count($states); 64 | for ($i = 0 ; $i <= 9; $i++ ) { 65 | $elem = find_by_id($xp, 'bar_' . $i); 66 | $elem->setAttribute('x', $offset); 67 | $elem->setAttribute('width', $step * $progress[$i]); 68 | $offset += $step * $progress[$i]; 69 | } 70 | 71 | // Set percent 72 | $percent = round($current_sum / $full_sum * 100); 73 | find_by_id($xp, 'percent-fg')->nodeValue = $percent . '%'; 74 | 75 | // Set BG color gradient; 76 | $current_bg_scheme = $bg_schemes['middle']; 77 | if ($progress[9] / count($states) > 0.6) { 78 | $current_bg_scheme = $bg_schemes['high']; 79 | } else if ($progress[0] / count($states) > 0.6) { 80 | $current_bg_scheme = $bg_schemes['low']; 81 | } 82 | 83 | find_by_id($xp, 'bg-grd-start')->setAttribute('style', 'stop-color:#' . $current_bg_scheme[0] . ';stop-opacity:1'); 84 | find_by_id($xp, 'bg-grd-stop')->setAttribute('style', 'stop-color:#' . $current_bg_scheme[1] . ';stop-opacity:1'); 85 | 86 | // Save it to file 87 | if (($fd = fopen($svg_output, 'w')) === false) 88 | throw new Exception("Cant open SVG file for saving"); 89 | fwrite($fd, $xdoc->saveXML()); 90 | fclose($fd); 91 | 92 | return $svg_output; 93 | } 94 | 95 | function convert_to_png($svg_input, $base_name) { 96 | global $output_dir; 97 | 98 | $png_output = $output_dir . $base_name . '.png'; 99 | exec("convert -background none $svg_input $png_output"); 100 | 101 | return $png_output; 102 | } 103 | 104 | function find_by_id($xp, $id) { 105 | $item = $xp->query("//*[@id = '$id']")->item(0); 106 | if (empty($item)) 107 | throw new Exception("Cant find element with ID = $id"); 108 | return $item; 109 | } 110 | 111 | ?> -------------------------------------------------------------------------------- /data/seed/wms/1.map: -------------------------------------------------------------------------------- 1 | MAP 2 | 3 | IMAGETYPE PNG24 4 | NAME WMS_server 5 | STATUS ON 6 | SIZE 500 500 7 | EXTENT 37.927869 44.494793 38.167698 44.667131 8 | UNITS METERS 9 | IMAGECOLOR 255 255 255 10 | IMAGEQUALITY 95 11 | IMAGETYPE png 12 | FONTSET ../fonts/fonts.txt 13 | 14 | OUTPUTFORMAT 15 | NAME png 16 | DRIVER "GD/PNG" 17 | MIMETYPE "image/png" 18 | IMAGEMODE RGBA 19 | EXTENSION "png" 20 | END 21 | 22 | 23 | WEB 24 | IMAGEPATH "/tmp/" 25 | IMAGEURL "/tmp/" 26 | METADATA 27 | "wms_title" "WMS Server" 28 | "wms_onlineresource" "http://mapcraft.nanodesu.ru/cgi-bin/mapserv?map=/srv/www.mapcraft.nanodesu.ru/data/wms/1.map&" 29 | "wms_srs" "EPSG:4326 EPSG:3857" 30 | "wms_feature_info_mime_type" "text/html" 31 | "wms_abstract" "Pie" 32 | END 33 | END 34 | 35 | PROJECTION 36 | "init=epsg:4326" 37 | END 38 | 39 | LAYER 40 | NAME "pie" 41 | METADATA 42 | "wms_title" "pie1" 43 | END 44 | TYPE POLYGON 45 | STATUS DEFAULT 46 | CONNECTIONTYPE OGR 47 | CONNECTION "../../static/kml/1.kml" 48 | PROJECTION 49 | "init=epsg:4326" 50 | END 51 | LABELITEM "name" 52 | CLASSITEM "description" 53 | CLASS 54 | NAME "0" 55 | EXPRESSION "0" 56 | STYLE 57 | WIDTH 3 58 | OUTLINECOLOR 255 0 0 59 | END 60 | LABEL 61 | FONT sans 62 | TYPE truetype 63 | SIZE 12 64 | COLOR 255 0 0 65 | END 66 | END 67 | CLASS 68 | NAME "1" 69 | EXPRESSION "1" 70 | STYLE 71 | WIDTH 3 72 | OUTLINECOLOR 255 76 0 73 | END 74 | LABEL 75 | FONT sans 76 | TYPE truetype 77 | SIZE 12 78 | COLOR 255 76 0 79 | END 80 | END 81 | CLASS 82 | NAME "2" 83 | EXPRESSION "2" 84 | STYLE 85 | WIDTH 3 86 | OUTLINECOLOR 255 134 0 87 | END 88 | LABEL 89 | FONT sans 90 | TYPE truetype 91 | SIZE 12 92 | COLOR 255 134 0 93 | END 94 | END 95 | CLASS 96 | NAME "3" 97 | EXPRESSION "3" 98 | STYLE 99 | WIDTH 3 100 | OUTLINECOLOR 255 192 0 101 | END 102 | LABEL 103 | FONT sans 104 | TYPE truetype 105 | SIZE 12 106 | COLOR 255 192 0 107 | END 108 | END 109 | CLASS 110 | NAME "4" 111 | EXPRESSION "4" 112 | STYLE 113 | WIDTH 3 114 | OUTLINECOLOR 255 238 0 115 | END 116 | LABEL 117 | FONT sans 118 | TYPE truetype 119 | SIZE 12 120 | COLOR 255 238 0 121 | END 122 | END 123 | CLASS 124 | NAME "5" 125 | EXPRESSION "5" 126 | STYLE 127 | WIDTH 3 128 | OUTLINECOLOR 255 255 0 129 | END 130 | LABEL 131 | FONT sans 132 | TYPE truetype 133 | SIZE 12 134 | COLOR 255 255 0 135 | END 136 | END 137 | CLASS 138 | NAME "6" 139 | EXPRESSION "6" 140 | STYLE 141 | WIDTH 3 142 | OUTLINECOLOR 200 255 0 143 | END 144 | LABEL 145 | FONT sans 146 | TYPE truetype 147 | SIZE 12 148 | COLOR 200 255 0 149 | END 150 | END 151 | CLASS 152 | NAME "7" 153 | EXPRESSION "7" 154 | STYLE 155 | WIDTH 3 156 | OUTLINECOLOR 150 255 0 157 | END 158 | LABEL 159 | FONT sans 160 | TYPE truetype 161 | SIZE 12 162 | COLOR 150 255 0 163 | END 164 | END 165 | CLASS 166 | NAME "8" 167 | EXPRESSION "8" 168 | STYLE 169 | WIDTH 3 170 | OUTLINECOLOR 95 255 0 171 | END 172 | LABEL 173 | FONT sans 174 | TYPE truetype 175 | SIZE 12 176 | COLOR 95 255 0 177 | END 178 | END 179 | CLASS 180 | NAME "9" 181 | EXPRESSION "9" 182 | STYLE 183 | WIDTH 3 184 | OUTLINECOLOR 0 255 0 185 | END 186 | LABEL 187 | FONT sans 188 | TYPE truetype 189 | SIZE 12 190 | COLOR 0 255 0 191 | END 192 | END 193 | END 194 | 195 | END -------------------------------------------------------------------------------- /data/seed/wms/2.map: -------------------------------------------------------------------------------- 1 | MAP 2 | 3 | IMAGETYPE PNG24 4 | NAME WMS_server 5 | STATUS ON 6 | SIZE 500 500 7 | EXTENT 37.927869 44.494793 38.167698 44.667131 8 | UNITS METERS 9 | IMAGECOLOR 255 255 255 10 | IMAGEQUALITY 95 11 | IMAGETYPE png 12 | FONTSET ../fonts/fonts.txt 13 | 14 | OUTPUTFORMAT 15 | NAME png 16 | DRIVER "GD/PNG" 17 | MIMETYPE "image/png" 18 | IMAGEMODE RGBA 19 | EXTENSION "png" 20 | END 21 | 22 | 23 | WEB 24 | IMAGEPATH "/tmp/" 25 | IMAGEURL "/tmp/" 26 | METADATA 27 | "wms_title" "WMS Server" 28 | "wms_onlineresource" "http://mapcraft.nanodesu.ru/cgi-bin/mapserv?map=/srv/www.mapcraft.nanodesu.ru/data/wms/2.map&" 29 | "wms_srs" "EPSG:4326 EPSG:3857" 30 | "wms_feature_info_mime_type" "text/html" 31 | "wms_abstract" "Pie" 32 | END 33 | END 34 | 35 | PROJECTION 36 | "init=epsg:4326" 37 | END 38 | 39 | LAYER 40 | NAME "pie" 41 | METADATA 42 | "wms_title" "pie2" 43 | END 44 | TYPE POLYGON 45 | STATUS DEFAULT 46 | CONNECTIONTYPE OGR 47 | CONNECTION "../../static/kml/2.kml" 48 | PROJECTION 49 | "init=epsg:4326" 50 | END 51 | LABELITEM "name" 52 | CLASSITEM "description" 53 | CLASS 54 | NAME "0" 55 | EXPRESSION "0" 56 | STYLE 57 | WIDTH 3 58 | OUTLINECOLOR 255 0 0 59 | END 60 | LABEL 61 | FONT sans 62 | TYPE truetype 63 | SIZE 12 64 | COLOR 255 0 0 65 | END 66 | END 67 | CLASS 68 | NAME "1" 69 | EXPRESSION "1" 70 | STYLE 71 | WIDTH 3 72 | OUTLINECOLOR 255 76 0 73 | END 74 | LABEL 75 | FONT sans 76 | TYPE truetype 77 | SIZE 12 78 | COLOR 255 76 0 79 | END 80 | END 81 | CLASS 82 | NAME "2" 83 | EXPRESSION "2" 84 | STYLE 85 | WIDTH 3 86 | OUTLINECOLOR 255 134 0 87 | END 88 | LABEL 89 | FONT sans 90 | TYPE truetype 91 | SIZE 12 92 | COLOR 255 134 0 93 | END 94 | END 95 | CLASS 96 | NAME "3" 97 | EXPRESSION "3" 98 | STYLE 99 | WIDTH 3 100 | OUTLINECOLOR 255 192 0 101 | END 102 | LABEL 103 | FONT sans 104 | TYPE truetype 105 | SIZE 12 106 | COLOR 255 192 0 107 | END 108 | END 109 | CLASS 110 | NAME "4" 111 | EXPRESSION "4" 112 | STYLE 113 | WIDTH 3 114 | OUTLINECOLOR 255 238 0 115 | END 116 | LABEL 117 | FONT sans 118 | TYPE truetype 119 | SIZE 12 120 | COLOR 255 238 0 121 | END 122 | END 123 | CLASS 124 | NAME "5" 125 | EXPRESSION "5" 126 | STYLE 127 | WIDTH 3 128 | OUTLINECOLOR 255 255 0 129 | END 130 | LABEL 131 | FONT sans 132 | TYPE truetype 133 | SIZE 12 134 | COLOR 255 255 0 135 | END 136 | END 137 | CLASS 138 | NAME "6" 139 | EXPRESSION "6" 140 | STYLE 141 | WIDTH 3 142 | OUTLINECOLOR 200 255 0 143 | END 144 | LABEL 145 | FONT sans 146 | TYPE truetype 147 | SIZE 12 148 | COLOR 200 255 0 149 | END 150 | END 151 | CLASS 152 | NAME "7" 153 | EXPRESSION "7" 154 | STYLE 155 | WIDTH 3 156 | OUTLINECOLOR 150 255 0 157 | END 158 | LABEL 159 | FONT sans 160 | TYPE truetype 161 | SIZE 12 162 | COLOR 150 255 0 163 | END 164 | END 165 | CLASS 166 | NAME "8" 167 | EXPRESSION "8" 168 | STYLE 169 | WIDTH 3 170 | OUTLINECOLOR 95 255 0 171 | END 172 | LABEL 173 | FONT sans 174 | TYPE truetype 175 | SIZE 12 176 | COLOR 95 255 0 177 | END 178 | END 179 | CLASS 180 | NAME "9" 181 | EXPRESSION "9" 182 | STYLE 183 | WIDTH 3 184 | OUTLINECOLOR 0 255 0 185 | END 186 | LABEL 187 | FONT sans 188 | TYPE truetype 189 | SIZE 12 190 | COLOR 0 255 0 191 | END 192 | END 193 | END 194 | 195 | END -------------------------------------------------------------------------------- /data/seed/wms/3.map: -------------------------------------------------------------------------------- 1 | MAP 2 | 3 | IMAGETYPE PNG24 4 | NAME WMS_server 5 | STATUS ON 6 | SIZE 500 500 7 | EXTENT 37.927869 44.494793 38.167698 44.667131 8 | UNITS METERS 9 | IMAGECOLOR 255 255 255 10 | IMAGEQUALITY 95 11 | IMAGETYPE png 12 | FONTSET ../fonts/fonts.txt 13 | 14 | OUTPUTFORMAT 15 | NAME png 16 | DRIVER "GD/PNG" 17 | MIMETYPE "image/png" 18 | IMAGEMODE RGBA 19 | EXTENSION "png" 20 | END 21 | 22 | 23 | WEB 24 | IMAGEPATH "/tmp/" 25 | IMAGEURL "/tmp/" 26 | METADATA 27 | "wms_title" "WMS Server" 28 | "wms_onlineresource" "http://mapcraft.nanodesu.ru/cgi-bin/mapserv?map=/srv/www.mapcraft.nanodesu.ru/data/wms/3.map&" 29 | "wms_srs" "EPSG:4326 EPSG:3857" 30 | "wms_feature_info_mime_type" "text/html" 31 | "wms_abstract" "Pie" 32 | END 33 | END 34 | 35 | PROJECTION 36 | "init=epsg:4326" 37 | END 38 | 39 | LAYER 40 | NAME "pie" 41 | METADATA 42 | "wms_title" "pie3" 43 | END 44 | TYPE POLYGON 45 | STATUS DEFAULT 46 | CONNECTIONTYPE OGR 47 | CONNECTION "../../static/kml/3.kml" 48 | PROJECTION 49 | "init=epsg:4326" 50 | END 51 | LABELITEM "name" 52 | CLASSITEM "description" 53 | CLASS 54 | NAME "0" 55 | EXPRESSION "0" 56 | STYLE 57 | WIDTH 3 58 | OUTLINECOLOR 255 0 0 59 | END 60 | LABEL 61 | FONT sans 62 | TYPE truetype 63 | SIZE 12 64 | COLOR 255 0 0 65 | END 66 | END 67 | CLASS 68 | NAME "1" 69 | EXPRESSION "1" 70 | STYLE 71 | WIDTH 3 72 | OUTLINECOLOR 255 76 0 73 | END 74 | LABEL 75 | FONT sans 76 | TYPE truetype 77 | SIZE 12 78 | COLOR 255 76 0 79 | END 80 | END 81 | CLASS 82 | NAME "2" 83 | EXPRESSION "2" 84 | STYLE 85 | WIDTH 3 86 | OUTLINECOLOR 255 134 0 87 | END 88 | LABEL 89 | FONT sans 90 | TYPE truetype 91 | SIZE 12 92 | COLOR 255 134 0 93 | END 94 | END 95 | CLASS 96 | NAME "3" 97 | EXPRESSION "3" 98 | STYLE 99 | WIDTH 3 100 | OUTLINECOLOR 255 192 0 101 | END 102 | LABEL 103 | FONT sans 104 | TYPE truetype 105 | SIZE 12 106 | COLOR 255 192 0 107 | END 108 | END 109 | CLASS 110 | NAME "4" 111 | EXPRESSION "4" 112 | STYLE 113 | WIDTH 3 114 | OUTLINECOLOR 255 238 0 115 | END 116 | LABEL 117 | FONT sans 118 | TYPE truetype 119 | SIZE 12 120 | COLOR 255 238 0 121 | END 122 | END 123 | CLASS 124 | NAME "5" 125 | EXPRESSION "5" 126 | STYLE 127 | WIDTH 3 128 | OUTLINECOLOR 255 255 0 129 | END 130 | LABEL 131 | FONT sans 132 | TYPE truetype 133 | SIZE 12 134 | COLOR 255 255 0 135 | END 136 | END 137 | CLASS 138 | NAME "6" 139 | EXPRESSION "6" 140 | STYLE 141 | WIDTH 3 142 | OUTLINECOLOR 200 255 0 143 | END 144 | LABEL 145 | FONT sans 146 | TYPE truetype 147 | SIZE 12 148 | COLOR 200 255 0 149 | END 150 | END 151 | CLASS 152 | NAME "7" 153 | EXPRESSION "7" 154 | STYLE 155 | WIDTH 3 156 | OUTLINECOLOR 150 255 0 157 | END 158 | LABEL 159 | FONT sans 160 | TYPE truetype 161 | SIZE 12 162 | COLOR 150 255 0 163 | END 164 | END 165 | CLASS 166 | NAME "8" 167 | EXPRESSION "8" 168 | STYLE 169 | WIDTH 3 170 | OUTLINECOLOR 95 255 0 171 | END 172 | LABEL 173 | FONT sans 174 | TYPE truetype 175 | SIZE 12 176 | COLOR 95 255 0 177 | END 178 | END 179 | CLASS 180 | NAME "9" 181 | EXPRESSION "9" 182 | STYLE 183 | WIDTH 3 184 | OUTLINECOLOR 0 255 0 185 | END 186 | LABEL 187 | FONT sans 188 | TYPE truetype 189 | SIZE 12 190 | COLOR 0 255 0 191 | END 192 | END 193 | END 194 | 195 | END -------------------------------------------------------------------------------- /logic/users.php: -------------------------------------------------------------------------------- 1 | pieid . ' ORDER BY pieces.index'); 36 | $piece_ids = pg_fetch_all_columns($result, 0); 37 | 38 | // Users who has pieces 39 | while ($row = pg_fetch_assoc($result)) { 40 | if (isset($users[$row['nick']])) 41 | $users[$row['nick']]['owns'][] = $row['index']; 42 | else 43 | $users[$row['nick']] = array('owns' => array($row['index']), 'color' => array($row['color']), 'online' => false); 44 | } 45 | 46 | 47 | if (count($piece_ids) != 0) { 48 | $result = pg_query($connection, 'SELECT claims.id, users.nick, users.color, pieces.index, score FROM claims JOIN pieces on claims.piece = pieces.id JOIN users ON users.id = claims.author WHERE piece IN ('.implode(',', $piece_ids).')'); 49 | while ($row = pg_fetch_assoc($result)) { 50 | $claim_list[1][] = array( 'claim_id' => $row['id'], 51 | 'piece_index' => $row['index'], 52 | 'vote_balance' => $row['score'], 53 | 'owner' => $row['nick'] ); 54 | // Users who has claims 55 | if (!isset($users[$row['nick']])) 56 | $users[$row['nick']] = array('owns' => array(),'color' => array($row['color']), 'online' => false); 57 | } 58 | } 59 | 60 | // Adding all online users: chat_members JOIN users 61 | $result = pg_query($connection, 'SELECT users.id, users.nick, users.color FROM chat_members LEFT JOIN users ON users.id = member WHERE pie = '.$from->pieid); 62 | while ($row = pg_fetch_assoc($result)) { 63 | // If new user -> set it fully 64 | if (!isset($users[$row['nick']])) { 65 | $users[$row['nick']] = array('owns' => array(),'color' => array($row['color'])); 66 | } 67 | $users[$row['nick']]['online'] = true; 68 | } 69 | 70 | // Generating user_list from userbuffer array 71 | foreach ($users as $user_nick => $attrs) { 72 | $user_list[1][] = array('user_nick' => $user_nick, 73 | 'color' => $attrs['color'], 74 | 'reserved' => $attrs['owns'], 75 | 'online' => $attrs['online']); 76 | } 77 | 78 | 79 | if ($to_all) { 80 | $res->to_pie($from, $user_list); 81 | $res->to_pie($from, $claim_list); 82 | } else { 83 | $res->to_sender($user_list); 84 | $res->to_sender($claim_list); 85 | } 86 | 87 | } 88 | 89 | ?> 90 | -------------------------------------------------------------------------------- /hub/src/stats.erl: -------------------------------------------------------------------------------- 1 | %% This program is free software. It comes without any warranty, to 2 | %% the extent permitted by applicable law. You can redistribute it 3 | %% and/or modify it under the terms of the Do What The Fuck You Want 4 | %% To Public License, Version 2, as published by Sam Hocevar. See 5 | %% http://sam.zoy.org/wtfpl/COPYING for more details. 6 | 7 | -module(stats). 8 | -behaviour(gen_server). 9 | 10 | -compile(export_all). 11 | -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). 12 | 13 | -define(TO_ATOM, ["pie", "users", "count", "sends", "chat", "message", "fails", "channel", "length"]). 14 | 15 | start_link() -> 16 | gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 17 | 18 | %% 19 | %% Interface 20 | %% 21 | incr(Key) -> 22 | incr(Key, 1). 23 | 24 | incr(Key, Val) -> 25 | gen_server:cast(?MODULE, {update, Key, Val}). 26 | 27 | decr(Key) -> 28 | decr(Key, 1). 29 | 30 | decr(Key, Val) -> 31 | gen_server:cast(?MODULE, {update, Key, -Val}). 32 | 33 | set(Key, Value) -> 34 | gen_server:cast(?MODULE, {set, Key, Value}). 35 | 36 | get_next(Key) -> 37 | {ok, Next} = gen_server:call(?MODULE, {get_next, Key}), 38 | Next. 39 | 40 | op(Key, "++", {}) -> 41 | incr(Key); 42 | op(Key, "--", {}) -> 43 | decr(Key); 44 | op(Key, "=", {Val}) -> 45 | set(Key, list_to_integer(Val)). 46 | 47 | external(List) -> 48 | {Key, Op, Args} = fetch_key(List, []), 49 | op(Key, Op, Args). 50 | 51 | %% 52 | %% Dumping and Output 53 | %% 54 | dump() -> 55 | {ok, Dump} = gen_server:call(?MODULE, dump), 56 | Dump. 57 | 58 | fdump() -> 59 | Dump = dump(), 60 | {Len, List} = lists:foldl(fun({K, V}, {Max, Cur}) -> 61 | S = lists:flatten(io_lib:format("~p", [K])), 62 | L = length(S), 63 | {lists:max([Max, L]), [[S, V] | Cur]} 64 | end, {0, []}, Dump), 65 | Sorted = lists:sort(List), 66 | FmtStr = lists:concat(["~-", Len, "s ~p~n"]), 67 | list_to_binary([ io_lib:format(FmtStr, Data) || Data <- Sorted]). 68 | 69 | pdump() -> 70 | Dump = fdump(), 71 | io:fwrite("~s", [Dump]), 72 | ok. 73 | 74 | %% 75 | %% gen_server callbacks 76 | %% 77 | init(_Args) -> 78 | Tab = ets:new(stats, [set, protected]), 79 | {ok, Tab}. 80 | 81 | 82 | handle_call({get_next, Key}, _From, Tab) -> 83 | ensure_key(Tab, Key), 84 | Next = ets:update_counter(Tab, Key, 1), 85 | {reply, {ok, Next}, Tab}; 86 | 87 | handle_call(dump, _From, Tab) -> 88 | Dump = lists:concat([ets:tab2list(Tab), get_mem_info(), get_sys_info()]), 89 | {reply, {ok, Dump}, Tab}. 90 | 91 | 92 | handle_cast({update, Key, Val}, Tab) -> 93 | ensure_key(Tab, Key), 94 | ets:update_counter(Tab, Key, Val), 95 | {noreply, Tab}; 96 | 97 | handle_cast({set, Key, Value}, Tab) -> 98 | ensure_key(Tab, Key), 99 | ets:update_element(Tab, Key, {2, Value}), 100 | {noreply, Tab}. 101 | 102 | handle_info(_Msg, State) -> 103 | {noreply, State}. 104 | 105 | code_change(_, State, _) -> 106 | {ok, State}. 107 | 108 | terminate(_Reason, _State) -> 109 | ok. 110 | 111 | %% 112 | %% Private 113 | %% 114 | get_mem_info() -> 115 | [ {{erlang,memory,K}, V} || {K, V} <- erlang:memory() ]. 116 | 117 | get_sys_info() -> 118 | [ {{erlang, processes, count}, erlang:system_info(process_count)} ]. 119 | 120 | 121 | fetch_key([Op | LArgs], RKey) when Op == "++"; Op == "--"; Op == "=" -> 122 | Key = list_to_tuple(lists:reverse(RKey)), 123 | Args = list_to_tuple(LArgs), 124 | {Key, Op, Args}; 125 | fetch_key([Head | Tail], RKey) -> 126 | fetch_key(Tail, [convert_key_part(Head) | RKey]). 127 | 128 | convert_key_part(Key) -> 129 | case lists:member(Key, ?TO_ATOM) of 130 | true -> 131 | list_to_atom(Key); 132 | _ -> 133 | Key 134 | end. 135 | 136 | %% 137 | %% Implementation 138 | %% 139 | ensure_key(Tab, Key) -> 140 | case ets:lookup(Tab, Key) of 141 | [] -> 142 | ets:insert(Tab, {Key, 0}); 143 | [_Obj] -> 144 | ok 145 | end. 146 | -------------------------------------------------------------------------------- /lib/db/sessions.php: -------------------------------------------------------------------------------- 1 | sesid); 15 | @session_start(); 16 | 17 | // nick 18 | if( isset($_SESSION['osm_user']) ) { 19 | $this->_nick = $_SESSION['osm_user']; 20 | } else { 21 | if( ! isset($_SESSION['nick']) ) { 22 | $_SESSION['nick'] = 'anon' . rand(1000, 9999); 23 | } 24 | $this->_nick = $_SESSION['nick']; 25 | } 26 | 27 | // anon_nick 28 | $this->_anon_nick = isset($_SESSION['nick']) ? $_SESSION['nick'] : 'anon???'; 29 | 30 | // id 31 | $this->_user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : '0'; 32 | 33 | // role 34 | $this->_role = $this->_load_role(); 35 | 36 | session_write_close(); 37 | } 38 | 39 | function _load_role() { 40 | global $connection; 41 | global $logger; 42 | 43 | if (!isset($_SESSION['user_id'])) 44 | return 'anon'; 45 | 46 | $result = pg_query_params($connection, 47 | 'SELECT role FROM access WHERE "pie" = $1 AND "user" = $2', 48 | array($this->pieid, $this->_user_id)); 49 | $role = pg_fetch_result($result, 0, 0); 50 | 51 | if ($role == null) 52 | return 'member'; 53 | 54 | if ($role == 'o') 55 | return 'owner'; 56 | 57 | if ($role == 'a') 58 | return 'admin'; 59 | 60 | $logger->err('Unknown role = "' . $role . '"'); 61 | return 'member'; 62 | } 63 | 64 | // returns osm name or anon#### 65 | function nick() { 66 | isset($this->_nick) || $this->_load_from_session(); 67 | return $this->_nick; 68 | } 69 | 70 | // returns osm name or anon#### 71 | function anon_nick() { 72 | isset($this->_anon_nick) || $this->_load_from_session(); 73 | return $this->_anon_nick; 74 | } 75 | 76 | // returns current role in the pie 77 | function role() { 78 | isset($this->_role) || $this->_load_from_session(); 79 | return $this->_role; 80 | } 81 | 82 | // returns current user id 83 | function user_id() { 84 | isset($this->_user_id) || $this->_load_from_session(); 85 | return $this->_user_id; 86 | } 87 | 88 | // return true if we have needed access level 89 | function has_level($min_role) { 90 | $levels = array( "anon" => 0, 91 | "member" => 10, 92 | "admin" => 20, 93 | "owner" => 30, 94 | "developer" => 40 ); 95 | $cur_role = $this->role(); 96 | if ($levels[$min_role] <= $levels[$cur_role]) { 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | // dies, if we have not needed access level 103 | function need_level($min_role) { 104 | if ($this->has_level($min_role)) 105 | return; 106 | 107 | if ($min_role == "member") { 108 | throw new Exception("Please, log in to access this feature"); 109 | } 110 | throw new Exception("You need $min_role rights to access this feature"); 111 | } 112 | } 113 | 114 | // Collection of channels 115 | class Channels { 116 | 117 | function find($pieid, $sesid) { 118 | $chan = new Channel(); 119 | $chan->sesid = $sesid; 120 | $chan->pieid = $pieid; 121 | 122 | return $chan; 123 | } 124 | } 125 | $channels = new Channels; 126 | ?> 127 | -------------------------------------------------------------------------------- /lib/create_map.php: -------------------------------------------------------------------------------- 1 | 211 | -------------------------------------------------------------------------------- /logic/cake.php: -------------------------------------------------------------------------------- 1 | need_level("owner"); 13 | 14 | $logger->debug("Start updating the cake " . $from->pieid . " initiated by used " . $from->user_id()); 15 | $changes = $data['data']; 16 | 17 | // name, description 18 | foreach (array('name', 'description') as $prop) { 19 | if (array_key_exists($prop, $changes)) { 20 | $logger->debug("Updating property '" . $prop . "'"); 21 | if(!pg_query_params($connection, 22 | 'UPDATE pies SET "' . $prop . '" = $2 WHERE id = $1', 23 | array($from->pieid, $changes[$prop]))) 24 | throw new Exception("Failed to update cake settings for prop: " . $prop); 25 | } 26 | } 27 | 28 | // visible = true/false 29 | if (array_key_exists('visible', $changes)) { 30 | $logger->debug("Updating property 'visible' = " . $changes['visible']); 31 | if(!pg_query($connection, 32 | 'UPDATE pies SET "visible" = ' . ($changes['visible'] ? 'true' : 'false') . ' WHERE id = ' . $from->pieid)) 33 | throw new Exception("Failed to update cake settings for prop: visible"); 34 | } 35 | 36 | // 37 | // update settings JSON 38 | // 39 | // firstly load: 40 | $result = pg_query($connection, 41 | 'SELECT settings FROM pies WHERE id = ' . $from->pieid); 42 | if (!$result) { 43 | throw new Exception("Failed to load pie information. Can't update settings JSON"); 44 | } 45 | $settings = json_decode(pg_fetch_result($result, 0, 'settings'), true); 46 | 47 | // Update with new data 48 | if (array_key_exists('links', $changes)) { 49 | $settings['links'] = $changes['links']; 50 | } 51 | 52 | // Update with new data 53 | if (array_key_exists('statuses', $changes)) { 54 | $settings['statuses'] = $changes['statuses']; 55 | } 56 | 57 | // Save new JSON 58 | if(! pg_query_params($connection, 59 | 'UPDATE pies SET settings = $1 where id = $2', 60 | array(json_encode($settings), $from->pieid))) 61 | throw new Exception("Failed to update pie entry with new JSON"); 62 | 63 | _send_cake_info($res, $from, false); 64 | } 65 | 66 | function handle_pie_act_send_refresh_pie_data($type, $from, $data, $res) { 67 | $res->to_pie($from, array('refresh_pie_data', array())); 68 | } 69 | 70 | function _send_cake_info($res, $from, $to_session) { 71 | global $connection; 72 | global $logger; 73 | 74 | $result = pg_query($connection, 75 | 'SELECT *, users.nick as author_nick 76 | FROM pies 77 | JOIN users ON users.id = pies.author 78 | WHERE pies.id = ' . $from->pieid); 79 | if (!$result) { 80 | throw new Exception("Failed to load pie information"); 81 | } 82 | $row = pg_fetch_assoc($result); 83 | $settings = json_decode($row['settings'], true); 84 | 85 | $info = array(); 86 | $info['name'] = $row['name']; 87 | $info['description'] = $row['description']; 88 | $info['created_at'] = $row['start']; 89 | $info['author'] = $row['author_nick']; 90 | $info['visible'] = $row['visible'] == 't'; 91 | $info['links'] = $settings['links'] ?: array(); 92 | $info['statuses'] = $settings['statuses'] ?: array('', '', '', '', '', '', '', '', '', 'all done'); 93 | 94 | $result = pg_query($connection, 95 | 'SELECT count(pieces.id) as pieces_count FROM pieces WHERE pie = ' . $from->pieid); 96 | $info['pieces_count'] = pg_fetch_result($result, 0, "pieces_count"); 97 | 98 | $msg = array('cake_info', $info); 99 | if ($to_session) { 100 | $res->to_session($from, $msg); 101 | } else { 102 | $res->to_pie($from, $msg); 103 | } 104 | } 105 | 106 | ?> -------------------------------------------------------------------------------- /app/list.php: -------------------------------------------------------------------------------- 1 | $piescount or $start < 0) 10 | header('Location: /list'); 11 | 12 | $result = pg_query($connection, 'SELECT pies.id, pies.name, pies.description, users.nick, pies.start, pies.updated, pies.ends, count(pieces.id) AS num, sum(pieces.state) / (count(pieces.id) * 9.0) * 100 AS state FROM pies INNER JOIN pieces ON pies.id = pieces.pie JOIN users ON pies.author=users.id WHERE pies.visible = true GROUP BY pies.id, pies.name, pies.description, users.nick, pies.start, pies.ends ORDER BY pies.updated DESC LIMIT '.$piespp.' OFFSET '.$start); 13 | 14 | if (pg_num_rows($result) > 0) { 15 | 16 | echo ''; 17 | echo ''; 18 | while ($row = pg_fetch_array($result)) { 19 | $state = round(floatval($row['state'])); 20 | $wms_link = 'wms:http://'.$_SERVER['HTTP_HOST'].'/wms/'.$row['id'].'?SRS={proj}&WIDTH={width}&height={height}&BBOX={bbox}'; 21 | $updated = preg_replace('/\.\d+$/', '', $row['updated']); 22 | $id = $row['id']; 23 | $pie_link = '/pie/' . $id; 24 | // Base line 25 | echo ''; 26 | echo ''; 27 | echo ''; 28 | echo ''; 29 | echo ''; 30 | echo ''; 31 | echo ''; 32 | echo ''; 33 | // Descr 34 | echo ''; 35 | echo ''; 36 | echo ''; 37 | } 38 | echo '
NameSlicesProgressAuthorUpdated 
'.$row['name'].''.$row['num'].''.$state.' %'.$row['nick'].''.$updated.''.(isset($_SESSION['osm_user']) && $row['nick'] === $_SESSION['osm_user'] ? 'Delete' : '').'

WMS link: '.$wms_link.'


'.(empty($row['description']) ? 'No description' : $row['description']).'
'; 39 | 40 | // Pages 41 | if ($piescount > $piespp) { 42 | $maxpage = intval(ceil($piescount / $piespp)); // 2 43 | if ($maxpage > 1) { 44 | echo '
    '; 45 | if ($pagenum > (2 + $radius * 2)) { 46 | foreach (range(1, 1 + $radius) as $num) 47 | echo '
  • '.$num.'
  • '; 48 | echo ' … '; 49 | foreach (range($pagenum - $radius, $pagenum - 1) as $num) 50 | echo '
  • '.$num.'
  • '; 51 | } 52 | else 53 | if ($pagenum > 1) 54 | foreach (range(1, $pagenum - 1) as $num) 55 | echo '
  • '.$num.'
  • '; 56 | echo '
  • '.$pagenum.'
  • '; 57 | if (($maxpage - $pagenum) >= (2 + $radius * 2)) { 58 | foreach (range($pagenum + 1, $pagenum + $radius) as $num) 59 | echo '
  • '.$num.'
  • '; 60 | echo ' … '; 61 | foreach (range($maxpage - $radius, $maxpage) as $num) 62 | echo '
  • '.$num.'
  • '; 63 | } 64 | else 65 | if ($pagenum < $maxpage) 66 | foreach (range($pagenum + 1, $maxpage) as $num) 67 | echo '
  • '.$num.'
  • '; 68 | echo '
'; 69 | } 70 | } 71 | } 72 | else { 73 | echo ''; 74 | } 75 | ?> 76 | -------------------------------------------------------------------------------- /scripts/env: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | . ./common.sh 5 | 6 | usage() { 7 | echo "Usage: $0 8 | 9 | Initialization: 10 | init - reset and recreate all needed for developing 11 | gen-configs - regenerate all configs for developer's environment 12 | db-reset - delete database and reset it to initial scheme 13 | db-seed - seed with demo data (the current data will be cleared!) 14 | 15 | Controll daemons (nginx, apache, hub): 16 | all-start - start all 17 | all-stop - stop all 18 | all-restart - restart one by one 19 | 20 | Other 21 | db-console - open PSQL console with needed credentials 22 | " 23 | exit 1; 24 | } 25 | 26 | PHP_CONFIG=${SRC_ROOT}/lib/config.php 27 | SCHEME=${SRC_ROOT}/data/scheme/scheme.sql 28 | SEED_DIR=${SRC_ROOT}/data/seed 29 | SEED=${SEED_DIR}/seed.sql 30 | 31 | HUB_CONFIG_TEMPLATE=${CONF_DIR}/hub.config.template 32 | 33 | gen-configs() { 34 | convert_tmpl $PHP_CONFIG.template $PHP_CONFIG 35 | echo "config.php has been regenerated" 36 | 37 | export GPROC_OPTIONS=$(gproc_options) 38 | convert_tmpl $HUB_CONFIG_TEMPLATE $HUB_CONFIG 39 | echo "hub.config has been regenerated" 40 | 41 | } 42 | 43 | db-reset() { 44 | # stop hub with logic. It can prevent dropdb 45 | ${SRC_ROOT}/scripts/hub 'stop' 46 | HUB_FAILED_TO_STOP=$? 47 | 48 | # stop apche. It can preven dropdb too 49 | ${SRC_ROOT}/scripts/apache 'stop' 50 | APACHE_FAILED_TO_STOP=$? 51 | 52 | # dropdb if exists 53 | if psql --list | grep $DATABASE >/dev/null ; then 54 | dropdb $DATABASE || exit 1 55 | fi 56 | 57 | # create it again 58 | createdb $DATABASE || exit 1 59 | 60 | # Create special user 61 | dropuser $DB_USER 2>/dev/null || true 62 | psql $DATABASE -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}' LOGIN CREATEUSER" >/dev/null 63 | 64 | # Prepare scheme 65 | TMP_SCHEME=${TMP_DIR}/scheme.sql 66 | cp $SCHEME ${TMP_SCHEME} 67 | sed -i $TMP_SCHEME -e "s/mapcrafter/$DB_USER/g"; 68 | psql -d ${DATABASE} <${TMP_SCHEME} >/dev/null 69 | echo "Developer's database has been recreated" 70 | 71 | # Clear static files (kml,wms etc) 72 | rm -f ${SRC_ROOT}/static/kml/*.kml 73 | rm -f ${SRC_ROOT}/data/wms/*.map 74 | 75 | # start apache again if it was stopped 76 | if [ $APACHE_FAILED_TO_STOP = 0 ] ; then 77 | ${SRC_ROOT}/scripts/apache 'start' 78 | fi 79 | 80 | # start hub again if it was stopped 81 | if [ $HUB_FAILED_TO_STOP = 0 ] ; then 82 | ${SRC_ROOT}/scripts/hub 'start' 83 | fi 84 | } 85 | 86 | db-seed() { 87 | # firstly reset all 88 | db-reset 89 | 90 | psql -d ${DATABASE} <$SEED >/dev/null 91 | 92 | # Restore saved static files (kml, wms, etc) 93 | cp -f ${SEED_DIR}/kml/* ${SRC_ROOT}/static/kml 94 | cp -f ${SEED_DIR}/wms/* ${SRC_ROOT}/data/wms 95 | 96 | echo "Test data successfully seeded" 97 | } 98 | 99 | db-seed() { 100 | # firstly reset all 101 | db-reset 102 | 103 | psql -d ${DATABASE} <$SEED >/dev/null 104 | 105 | # Restore saved static files (kml, wms, etc) 106 | cp -f ${SEED_DIR}/kml/* ${SRC_ROOT}/static/kml 107 | cp -f ${SEED_DIR}/wms/* ${SRC_ROOT}/data/wms 108 | 109 | echo "Test data successfully seeded" 110 | } 111 | 112 | db-console() { 113 | export PGOPTIONS="-c search_path=mapcraft,public" 114 | psql -d ${DATABASE} 115 | } 116 | 117 | compile-hub() { 118 | echo "Compiling and getting all dependencies for hub ..." 119 | cd ${SRC_ROOT}/hub 120 | make all || exit 1; 121 | echo "Hub has been compiled" 122 | } 123 | 124 | daemons-do() { 125 | for daemon in nginx apache hub code-reloader ; do 126 | ${SRC_ROOT}/scripts/$daemon "$@" 127 | done 128 | } 129 | 130 | gproc_options() { 131 | ERL_VERSION=$(get_version erlang) 132 | 133 | # Disable ETS tunning on erlang < 14B 134 | if ! version_ge $ERL_VERSION 1:14.b ; then 135 | echo " 136 | {ets_options, []}" 137 | fi 138 | } 139 | 140 | case "$1" in 141 | init) 142 | compile-hub 143 | gen-configs 144 | db-seed 145 | ;; 146 | db-reset) 147 | db-reset 148 | ;; 149 | db-seed) 150 | db-seed 151 | ;; 152 | db-console) 153 | db-console 154 | ;; 155 | gen-configs) 156 | gen-configs 157 | ;; 158 | all-start) 159 | daemons-do 'start' 160 | ;; 161 | all-stop) 162 | daemons-do 'stop' 163 | ;; 164 | all-restart) 165 | daemons-do 'restart' 166 | ;; 167 | *) 168 | usage; 169 | esac 170 | -------------------------------------------------------------------------------- /lib/Log/observer.php: -------------------------------------------------------------------------------- 1 | 15 | * @since Horde 1.3 16 | * @since Log 1.0 17 | * @package Log 18 | * 19 | * @example observer_mail.php An example Log_observer implementation. 20 | */ 21 | class Log_observer 22 | { 23 | /** 24 | * Instance-specific unique identification number. 25 | * 26 | * @var integer 27 | * @access private 28 | */ 29 | var $_id = 0; 30 | 31 | /** 32 | * The minimum priority level of message that we want to hear about. 33 | * PEAR_LOG_EMERG is the highest priority, so we will only hear messages 34 | * with an integer priority value less than or equal to ours. It defaults 35 | * to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG. 36 | * 37 | * @var string 38 | * @access private 39 | */ 40 | var $_priority = PEAR_LOG_INFO; 41 | 42 | /** 43 | * Creates a new basic Log_observer instance. 44 | * 45 | * @param integer $priority The highest priority at which to receive 46 | * log event notifications. 47 | * 48 | * @access public 49 | */ 50 | function Log_observer($priority = PEAR_LOG_INFO) 51 | { 52 | $this->_id = md5(microtime()); 53 | $this->_priority = $priority; 54 | } 55 | 56 | /** 57 | * Attempts to return a new concrete Log_observer instance of the requested 58 | * type. 59 | * 60 | * @param string $type The type of concreate Log_observer subclass 61 | * to return. 62 | * @param integer $priority The highest priority at which to receive 63 | * log event notifications. 64 | * @param array $conf Optional associative array of additional 65 | * configuration values. 66 | * 67 | * @return object The newly created concrete Log_observer 68 | * instance, or null on an error. 69 | */ 70 | function &factory($type, $priority = PEAR_LOG_INFO, $conf = array()) 71 | { 72 | $type = strtolower($type); 73 | $class = 'Log_observer_' . $type; 74 | 75 | /* 76 | * If the desired class already exists (because the caller has supplied 77 | * it from some custom location), simply instantiate and return a new 78 | * instance. 79 | */ 80 | if (class_exists($class)) { 81 | $object = &new $class($priority, $conf); 82 | return $object; 83 | } 84 | 85 | /* Support both the new-style and old-style file naming conventions. */ 86 | $newstyle = true; 87 | $classfile = dirname(__FILE__) . '/observer_' . $type . '.php'; 88 | 89 | if (!file_exists($classfile)) { 90 | $classfile = 'Log/' . $type . '.php'; 91 | $newstyle = false; 92 | } 93 | 94 | /* 95 | * Attempt to include our version of the named class, but don't treat 96 | * a failure as fatal. The caller may have already included their own 97 | * version of the named class. 98 | */ 99 | @include_once $classfile; 100 | 101 | /* If the class exists, return a new instance of it. */ 102 | if (class_exists($class)) { 103 | /* Support both new-style and old-style construction. */ 104 | if ($newstyle) { 105 | $object = &new $class($priority, $conf); 106 | } else { 107 | $object = &new $class($priority); 108 | } 109 | return $object; 110 | } 111 | 112 | $null = null; 113 | return $null; 114 | } 115 | 116 | /** 117 | * This is a stub method to make sure that Log_Observer classes do 118 | * something when they are notified of a message. The default behavior 119 | * is to just print the message, which is obviously not desireable in 120 | * practically any situation - which is why you need to override this 121 | * method. :) 122 | * 123 | * @param array $event A hash describing the log event. 124 | */ 125 | function notify($event) 126 | { 127 | print_r($event); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /static/css/style_leaflet.css: -------------------------------------------------------------------------------- 1 | * { padding: 0; margin: 0; font-family: Arial,sans; } 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | border: 0; 6 | overflow: hidden; 7 | height: 100%; 8 | max-height: 100%; 9 | } 10 | 11 | #llmap { 12 | position: fixed !important; 13 | top: 0; 14 | bottom: 0; 15 | left: 0; 16 | right: 0; 17 | overflow: hidden; 18 | border-width: 1px; 19 | border-color: #b6bccc #eaedf7; 20 | border-style: solid; 21 | z-index: -1; 22 | } 23 | 24 | #userlist { 25 | top: 8px; 26 | bottom: 8px; 27 | left: 8px; 28 | right: 8px; 29 | height: 100%; 30 | width: 100%; 31 | } 32 | 33 | #userlist option { 34 | height: 20px; 35 | } 36 | 37 | #inputline { 38 | height: 20px; 39 | } 40 | 41 | #chatline { 42 | height: 100%; 43 | } 44 | 45 | #dchat { 46 | overflow: hidden; 47 | } 48 | 49 | #dprop { 50 | overflow: hidden; 51 | } 52 | 53 | #dchat > table { 54 | width: 100%; 55 | height: 100%; 56 | } 57 | 58 | #chat { 59 | overflow-x: hidden; 60 | overflow-y: auto; 61 | border-width: 1px; 62 | border-color: #b6bccc #eaedf7; 63 | border-style: solid; 64 | background: white; 65 | padding: 0 10px; 66 | } 67 | 68 | #chat td { 69 | text-align: left; 70 | vertical-align: top; 71 | 72 | } 73 | 74 | #chat .history { 75 | color: gray; 76 | } 77 | 78 | #chat .history .nick { 79 | color: CadetBlue; 80 | } 81 | 82 | #chat .time { 83 | color: gray; 84 | font-size: smaller; 85 | } 86 | 87 | #chat .nick { 88 | text-align: right; 89 | color: darkblue; 90 | } 91 | 92 | .pseudolink { 93 | cursor: pointer; 94 | border-bottom: 1px dotted; 95 | } 96 | 97 | .info { 98 | color: darkgreen; 99 | } 100 | 101 | .info .pseudolink { 102 | border-bottom: 1px dotted #36c96c; 103 | } 104 | 105 | .error { 106 | color: #ff6445; 107 | } 108 | 109 | .error .pseudolink { 110 | border-bottom: 1px dotted #ff6445; 111 | } 112 | 113 | #pac_text { 114 | height: 16px; 115 | width: 100%; 116 | } 117 | 118 | #pac_nick { 119 | height: 20px; 120 | width: 100%; 121 | } 122 | 123 | #pac_color { 124 | height: 20px; 125 | width: 100%; 126 | } 127 | 128 | #comment_text { 129 | width: 100%; 130 | height: 100%; 131 | } 132 | 133 | #sstatus { 134 | margin: 20px 84px 20px 20px; 135 | } 136 | 137 | .ts { 138 | float: right; 139 | } 140 | 141 | #comments { 142 | overflow: scroll; 143 | border-width: 1px; 144 | border-color: #b6bccc #eaedf7; 145 | border-style: solid; 146 | background: white; 147 | width: 100%; 148 | height: 100%; 149 | text-align: left; 150 | white-space: pre-wrap; 151 | white-space: -moz-pre-wrap; 152 | white-space: -pre-wrap; 153 | white-space: -o-pre-wrap; 154 | word-wrap: break-word; 155 | } 156 | 157 | p { 158 | margin: 0 0 1em 0; 159 | } 160 | 161 | #panel { 162 | position: absolute; 163 | top: 10px; 164 | left: 10px; 165 | } 166 | 167 | #progress_bar { 168 | margin-top: 0.2em; 169 | } 170 | 171 | #userlist table { 172 | border-collapse: collapse; 173 | } 174 | 175 | #userlist td { 176 | border: 1px solid #cccccc; 177 | padding: 5px; 178 | } 179 | 180 | #exclamation { 181 | width: 64px; 182 | height: 64px; 183 | background: url(../img/exclam.png) center center no-repeat; 184 | float: right; 185 | } 186 | 187 | #question { 188 | width: 64px; 189 | height: 64px; 190 | background: url(../img/quest.png) center center no-repeat; 191 | float: right; 192 | } 193 | 194 | .loading { 195 | background: url(../img/l.gif) center center no-repeat; 196 | height: 100%; 197 | width: 100%; 198 | } 199 | 200 | td.msg { 201 | width: 100%; 202 | } 203 | 204 | td.nick { 205 | max-width: 10em; 206 | overflow: hidden; 207 | border-right: 1px lightgray solid; 208 | padding-right: 0.2em; 209 | } 210 | 211 | .maxima { 212 | height: 100%; 213 | } 214 | 215 | .property { 216 | height: 0%; 217 | } 218 | 219 | .nickname { 220 | text-decoration: none; 221 | display: inline-block; 222 | border-bottom: 1px dotted black; 223 | cursor: pointer; 224 | } 225 | 226 | .up { 227 | background: url(../img/up.png); 228 | width: 10px; 229 | height: 10px; 230 | display: inline-block; 231 | cursor: pointer; 232 | } 233 | 234 | .down { 235 | background: url(../img/down.png); 236 | width: 10px; 237 | height: 10px; 238 | display: inline-block; 239 | cursor: pointer; 240 | } 241 | 242 | .close { 243 | background: url(../img/close.png); 244 | width: 10px; 245 | height: 10px; 246 | display: inline-block; 247 | cursor: pointer; 248 | } 249 | 250 | .num { 251 | text-decoration: none; 252 | display: inline-block; 253 | border-bottom: 1px dotted black; 254 | cursor: pointer; 255 | } 256 | 257 | .olControlAttribution { 258 | bottom: 2em !important; 259 | } 260 | 261 | .olControlPermalink { 262 | bottom: 0.5em !important; 263 | } 264 | 265 | .claim, .nick { 266 | white-space: nowrap; 267 | } 268 | 269 | #anonscounter { 270 | margin-left: 1em; 271 | color: gray; 272 | } 273 | 274 | #comments .info strong { 275 | color: black 276 | } 277 | 278 | #comments .date { 279 | white-space: nowrap; 280 | font-size: smaller; 281 | margin-top: 0.2em; 282 | float: right; 283 | margin-right: 1em; 284 | color: gray; 285 | } 286 | -------------------------------------------------------------------------------- /lib/Log/error_log.php: -------------------------------------------------------------------------------- 1 | 14 | * @since Log 1.7.0 15 | * @package Log 16 | * 17 | * @example error_log.php Using the error_log handler. 18 | */ 19 | class Log_error_log extends Log 20 | { 21 | /** 22 | * The error_log() log type. 23 | * @var integer 24 | * @access private 25 | */ 26 | var $_type = PEAR_LOG_TYPE_SYSTEM; 27 | 28 | /** 29 | * The type-specific destination value. 30 | * @var string 31 | * @access private 32 | */ 33 | var $_destination = ''; 34 | 35 | /** 36 | * Additional headers to pass to the mail() function when the 37 | * PEAR_LOG_TYPE_MAIL type is used. 38 | * @var string 39 | * @access private 40 | */ 41 | var $_extra_headers = ''; 42 | 43 | /** 44 | * String containing the format of a log line. 45 | * @var string 46 | * @access private 47 | */ 48 | var $_lineFormat = '%2$s: %4$s'; 49 | 50 | /** 51 | * String containing the timestamp format. It will be passed directly to 52 | * strftime(). Note that the timestamp string will generated using the 53 | * current locale. 54 | * @var string 55 | * @access private 56 | */ 57 | var $_timeFormat = '%b %d %H:%M:%S'; 58 | 59 | /** 60 | * Constructs a new Log_error_log object. 61 | * 62 | * @param string $name One of the PEAR_LOG_TYPE_* constants. 63 | * @param string $ident The identity string. 64 | * @param array $conf The configuration array. 65 | * @param int $level Log messages up to and including this level. 66 | * @access public 67 | */ 68 | function Log_error_log($name, $ident = '', $conf = array(), 69 | $level = PEAR_LOG_DEBUG) 70 | { 71 | $this->_id = md5(microtime()); 72 | $this->_type = $name; 73 | $this->_ident = $ident; 74 | $this->_mask = Log::UPTO($level); 75 | 76 | if (!empty($conf['destination'])) { 77 | $this->_destination = $conf['destination']; 78 | } 79 | 80 | if (!empty($conf['extra_headers'])) { 81 | $this->_extra_headers = $conf['extra_headers']; 82 | } 83 | 84 | if (!empty($conf['lineFormat'])) { 85 | $this->_lineFormat = str_replace(array_keys($this->_formatMap), 86 | array_values($this->_formatMap), 87 | $conf['lineFormat']); 88 | } 89 | 90 | if (!empty($conf['timeFormat'])) { 91 | $this->_timeFormat = $conf['timeFormat']; 92 | } 93 | } 94 | 95 | /** 96 | * Opens the handler. 97 | * 98 | * @access public 99 | * @since Log 1.9.6 100 | */ 101 | function open() 102 | { 103 | $this->_opened = true; 104 | return true; 105 | } 106 | 107 | /** 108 | * Closes the handler. 109 | * 110 | * @access public 111 | * @since Log 1.9.6 112 | */ 113 | function close() 114 | { 115 | $this->_opened = false; 116 | return true; 117 | } 118 | 119 | /** 120 | * Logs $message using PHP's error_log() function. The message is also 121 | * passed along to any Log_observer instances that are observing this Log. 122 | * 123 | * @param mixed $message String or object containing the message to log. 124 | * @param string $priority The priority of the message. Valid 125 | * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, 126 | * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, 127 | * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. 128 | * @return boolean True on success or false on failure. 129 | * @access public 130 | */ 131 | function log($message, $priority = null) 132 | { 133 | /* If a priority hasn't been specified, use the default value. */ 134 | if ($priority === null) { 135 | $priority = $this->_priority; 136 | } 137 | 138 | /* Abort early if the priority is above the maximum logging level. */ 139 | if (!$this->_isMasked($priority)) { 140 | return false; 141 | } 142 | 143 | /* Extract the string representation of the message. */ 144 | $message = $this->_extractMessage($message); 145 | 146 | /* Build the string containing the complete log line. */ 147 | $line = $this->_format($this->_lineFormat, 148 | strftime($this->_timeFormat), 149 | $priority, $message); 150 | 151 | /* Pass the log line and parameters to the error_log() function. */ 152 | $success = error_log($line, $this->_type, $this->_destination, 153 | $this->_extra_headers); 154 | 155 | $this->_announce(array('priority' => $priority, 'message' => $message)); 156 | 157 | return $success; 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /scripts/nodetool: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | %% ------------------------------------------------------------------- 4 | %% 5 | %% nodetool: Helper Script for interacting with live nodes 6 | %% 7 | %% ------------------------------------------------------------------- 8 | 9 | main(Args) -> 10 | ok = start_epmd(), 11 | %% Extract the args 12 | {RestArgs, TargetNode} = process_args(Args, [], undefined), 13 | 14 | %% See if the node is currently running -- if it's not, we'll bail 15 | case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of 16 | {true, pong} -> 17 | ok; 18 | {_, pang} -> 19 | io:format("Node ~p not responding to pings.\n", [TargetNode]), 20 | halt(1) 21 | end, 22 | 23 | case RestArgs of 24 | ["ping"] -> 25 | %% If we got this far, the node already responsed to a ping, so just dump 26 | %% a "pong" 27 | io:format("pong\n"); 28 | ["stop"] -> 29 | io:format("~p\n", [rpc:call(TargetNode, init, stop, [], 60000)]); 30 | ["restart"] -> 31 | io:format("~p\n", [rpc:call(TargetNode, init, restart, [], 60000)]); 32 | ["reboot"] -> 33 | io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]); 34 | ["rpc", Module, Function | RpcArgs] -> 35 | case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 36 | [RpcArgs], 60000) of 37 | ok -> 38 | ok; 39 | {badrpc, Reason} -> 40 | io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), 41 | halt(1); 42 | _ -> 43 | halt(1) 44 | end; 45 | ["rpcterms", Module, Function, ArgsAsString] -> 46 | case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 47 | consult(ArgsAsString), 60000) of 48 | {badrpc, Reason} -> 49 | io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), 50 | halt(1); 51 | Other -> 52 | io:format("~p\n", [Other]) 53 | end; 54 | Other -> 55 | io:format("Other: ~p\n", [Other]), 56 | io:format("Usage: nodetool {ping|stop|restart|reboot}\n") 57 | end, 58 | net_kernel:stop(). 59 | 60 | process_args([], Acc, TargetNode) -> 61 | {lists:reverse(Acc), TargetNode}; 62 | process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> 63 | erlang:set_cookie(node(), list_to_atom(Cookie)), 64 | process_args(Rest, Acc, TargetNode); 65 | process_args(["-name", TargetName | Rest], Acc, _) -> 66 | ThisNode = append_node_suffix(TargetName, "_maint_"), 67 | {ok, _} = net_kernel:start([ThisNode, longnames]), 68 | process_args(Rest, Acc, nodename(TargetName)); 69 | process_args(["-sname", TargetName | Rest], Acc, _) -> 70 | ThisNode = append_node_suffix(TargetName, "_maint_"), 71 | {ok, _} = net_kernel:start([ThisNode, shortnames]), 72 | process_args(Rest, Acc, nodename(TargetName)); 73 | process_args([Arg | Rest], Acc, Opts) -> 74 | process_args(Rest, [Arg | Acc], Opts). 75 | 76 | 77 | start_epmd() -> 78 | [] = os:cmd(epmd_path() ++ " -daemon"), 79 | ok. 80 | 81 | epmd_path() -> 82 | ErtsBinDir = filename:dirname(escript:script_name()), 83 | Name = "epmd", 84 | case os:find_executable(Name, ErtsBinDir) of 85 | false -> 86 | case os:find_executable(Name) of 87 | false -> 88 | io:format("Could not find epmd.~n"), 89 | halt(1); 90 | GlobalEpmd -> 91 | GlobalEpmd 92 | end; 93 | Epmd -> 94 | Epmd 95 | end. 96 | 97 | 98 | nodename(Name) -> 99 | case string:tokens(Name, "@") of 100 | [_Node, _Host] -> 101 | list_to_atom(Name); 102 | [Node] -> 103 | [_, Host] = string:tokens(atom_to_list(node()), "@"), 104 | list_to_atom(lists:concat([Node, "@", Host])) 105 | end. 106 | 107 | append_node_suffix(Name, Suffix) -> 108 | case string:tokens(Name, "@") of 109 | [Node, Host] -> 110 | list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host])); 111 | [Node] -> 112 | list_to_atom(lists:concat([Node, Suffix, os:getpid()])) 113 | end. 114 | 115 | 116 | %% 117 | %% Given a string or binary, parse it into a list of terms, ala file:consult/0 118 | %% 119 | consult(Str) when is_list(Str) -> 120 | consult([], Str, []); 121 | consult(Bin) when is_binary(Bin)-> 122 | consult([], binary_to_list(Bin), []). 123 | 124 | consult(Cont, Str, Acc) -> 125 | case erl_scan:tokens(Cont, Str, 0) of 126 | {done, Result, Remaining} -> 127 | case Result of 128 | {ok, Tokens, _} -> 129 | {ok, Term} = erl_parse:parse_term(Tokens), 130 | consult([], Remaining, [Term | Acc]); 131 | {eof, _Other} -> 132 | lists:reverse(Acc); 133 | {error, Info, _} -> 134 | {error, Info} 135 | end; 136 | {more, Cont1} -> 137 | consult(Cont1, eof, Acc) 138 | end. 139 | --------------------------------------------------------------------------------