├── css ├── op.png ├── ot.png ├── rp.png ├── rt.png ├── uu.png ├── evbig.png ├── op_uns.png ├── ot_uns.png ├── rp_uns.png ├── rt_uns.png ├── evdefault.png ├── smoothness │ └── images │ │ ├── animated-overlay.gif │ │ ├── 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 ├── help.css ├── basic.css └── wimodule.css ├── data └── history.csv ├── doc ├── tutorial.rst ├── _static │ ├── wi-overview2.png │ └── generic-overview.png ├── index.rst ├── _toReview │ ├── coding_style.txt │ ├── coding_checks.sh │ └── source │ │ └── beta-testers.txt ├── introduction.rst ├── changelog.rst └── Makefile ├── .gitignore ├── examples ├── webdc3 │ ├── images │ │ ├── background.gif │ │ ├── eida-logo.png │ │ ├── eida-logo2.png │ │ ├── logo_gfz_de.gif │ │ ├── eida-orfeus3.jpg │ │ ├── gfn_logo_dark.png │ │ ├── wordmark_gfz_de.gif │ │ └── Makefile │ ├── gfz-backup.css │ ├── wi-geofon.css │ ├── index.html │ └── geofon.css ├── webdc2012 │ ├── images │ │ ├── gfn_logo_new.gif │ │ ├── neries_logo.gif │ │ └── webdc_banner.gif │ ├── date_functions.js │ ├── webdc.html │ ├── webinterface.css │ └── map_functions.js ├── basic │ ├── basic.css │ └── index.html └── generic │ ├── index.html │ └── help.html ├── wsgi ├── descriptions │ ├── media │ │ ├── wi-overview2.png │ │ └── generic-overview.png │ ├── media-src │ │ └── wi-overview2.odg │ └── webinterface.rst ├── webdc3.wsgi ├── webdc3.conf.sample ├── modules │ └── core.py ├── webinterface.cfg.sample └── wsgicomm.py ├── tools ├── openlayers │ └── theme │ │ └── default │ │ ├── img │ │ ├── blank.gif │ │ ├── close.gif │ │ ├── pan_on.png │ │ ├── ruler.png │ │ ├── pan-panel.png │ │ ├── pan_off.png │ │ ├── zoom-panel.png │ │ ├── add_point_off.png │ │ ├── add_point_on.png │ │ ├── draw_line_off.png │ │ ├── draw_line_on.png │ │ ├── draw_point_off.png │ │ ├── draw_point_on.png │ │ ├── view_next_off.png │ │ ├── view_next_on.png │ │ ├── draw_polygon_off.png │ │ ├── draw_polygon_on.png │ │ ├── editing_tool_bar.png │ │ ├── move_feature_off.png │ │ ├── move_feature_on.png │ │ ├── panning-hand-off.png │ │ ├── panning-hand-on.png │ │ ├── remove_point_off.png │ │ ├── remove_point_on.png │ │ ├── save_features_on.png │ │ ├── view_previous_on.png │ │ ├── drag-rectangle-off.png │ │ ├── drag-rectangle-on.png │ │ ├── navigation_history.png │ │ ├── pan-panel-NOALPHA.png │ │ ├── save_features_off.png │ │ ├── view_previous_off.png │ │ ├── zoom-panel-NOALPHA.png │ │ └── overview_replacement.gif │ │ ├── ie6-style.css │ │ └── google.css ├── jquery │ └── jquery.cookie.js └── jquery-ajax-native.js ├── test ├── samples │ ├── user1.csv │ ├── user0.csv │ ├── eqinfo_sample3.csv │ ├── eqinfo_sample2.csv │ └── eqinfo_sample.csv ├── testParseFile.html ├── testPublic.txt ├── eventconfig.py ├── manage.py ├── testHelpers.py ├── test.html ├── webinterfaceEvent.py ├── unittestTools.py ├── test_inv.py ├── testMetadata.py └── testEvent.html ├── error.html ├── CITATION ├── src ├── main.js ├── config.js ├── interface.js └── console.js ├── README.md ├── Makefile └── TODO /css/op.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/op.png -------------------------------------------------------------------------------- /css/ot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/ot.png -------------------------------------------------------------------------------- /css/rp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/rp.png -------------------------------------------------------------------------------- /css/rt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/rt.png -------------------------------------------------------------------------------- /css/uu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/uu.png -------------------------------------------------------------------------------- /css/evbig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/evbig.png -------------------------------------------------------------------------------- /data/history.csv: -------------------------------------------------------------------------------- 1 | # Date/time, networks, stations, locations, channels 2 | -------------------------------------------------------------------------------- /css/op_uns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/op_uns.png -------------------------------------------------------------------------------- /css/ot_uns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/ot_uns.png -------------------------------------------------------------------------------- /css/rp_uns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/rp_uns.png -------------------------------------------------------------------------------- /css/rt_uns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/rt_uns.png -------------------------------------------------------------------------------- /css/evdefault.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/evdefault.png -------------------------------------------------------------------------------- /doc/tutorial.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/doc/tutorial.rst -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.xml 2 | *.bin 3 | doc/build-doc/ 4 | doc/_build/ 5 | *.pyc 6 | *.cfg 7 | olddoc 8 | -------------------------------------------------------------------------------- /doc/_static/wi-overview2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/doc/_static/wi-overview2.png -------------------------------------------------------------------------------- /doc/_static/generic-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/doc/_static/generic-overview.png -------------------------------------------------------------------------------- /examples/webdc3/images/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/background.gif -------------------------------------------------------------------------------- /examples/webdc3/images/eida-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/eida-logo.png -------------------------------------------------------------------------------- /examples/webdc3/images/eida-logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/eida-logo2.png -------------------------------------------------------------------------------- /examples/webdc3/images/logo_gfz_de.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/logo_gfz_de.gif -------------------------------------------------------------------------------- /examples/webdc3/images/eida-orfeus3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/eida-orfeus3.jpg -------------------------------------------------------------------------------- /examples/webdc3/images/gfn_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/gfn_logo_dark.png -------------------------------------------------------------------------------- /wsgi/descriptions/media/wi-overview2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/wsgi/descriptions/media/wi-overview2.png -------------------------------------------------------------------------------- /css/smoothness/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/animated-overlay.gif -------------------------------------------------------------------------------- /examples/webdc2012/images/gfn_logo_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc2012/images/gfn_logo_new.gif -------------------------------------------------------------------------------- /examples/webdc2012/images/neries_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc2012/images/neries_logo.gif -------------------------------------------------------------------------------- /examples/webdc2012/images/webdc_banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc2012/images/webdc_banner.gif -------------------------------------------------------------------------------- /examples/webdc3/images/wordmark_gfz_de.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/examples/webdc3/images/wordmark_gfz_de.gif -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/blank.gif -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/close.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/close.gif -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/pan_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/pan_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/ruler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/ruler.png -------------------------------------------------------------------------------- /wsgi/descriptions/media-src/wi-overview2.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/wsgi/descriptions/media-src/wi-overview2.odg -------------------------------------------------------------------------------- /wsgi/descriptions/media/generic-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/wsgi/descriptions/media/generic-overview.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/pan-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/pan-panel.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/pan_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/pan_off.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/zoom-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/zoom-panel.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/add_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/add_point_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/add_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/add_point_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_line_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_line_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_line_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_line_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_point_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_point_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/view_next_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/view_next_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/view_next_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/view_next_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_polygon_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_polygon_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/draw_polygon_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/draw_polygon_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/editing_tool_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/editing_tool_bar.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/move_feature_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/move_feature_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/move_feature_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/move_feature_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/panning-hand-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/panning-hand-off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/panning-hand-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/panning-hand-on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/remove_point_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/remove_point_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/remove_point_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/remove_point_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/save_features_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/save_features_on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/view_previous_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/view_previous_on.png -------------------------------------------------------------------------------- /test/samples/user1.csv: -------------------------------------------------------------------------------- 1 | "datetime","lat","long","depth" 2 | 2013-03-01T08:00:00,15,99,10 3 | 4 | 2013-03-02T08:00:00,0,99,10 5 | 2013-03-03T08:00:00,30,99,10 6 | -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/drag-rectangle-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/drag-rectangle-off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/drag-rectangle-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/drag-rectangle-on.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/navigation_history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/navigation_history.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/pan-panel-NOALPHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/pan-panel-NOALPHA.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/save_features_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/save_features_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/view_previous_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/view_previous_off.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/zoom-panel-NOALPHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/zoom-panel-NOALPHA.png -------------------------------------------------------------------------------- /tools/openlayers/theme/default/img/overview_replacement.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/tools/openlayers/theme/default/img/overview_replacement.gif -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EIDA/webdc3/HEAD/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /wsgi/webdc3.wsgi: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.insert(0, os.path.dirname(__file__)) 5 | 6 | import webinterface 7 | 8 | application = webinterface.application 9 | -------------------------------------------------------------------------------- /test/samples/user0.csv: -------------------------------------------------------------------------------- 1 | "datetime","lat","long","depth" 2 | 2013-03-01T08:00:00,15,99,10 3 | 2013-04-01T08:00:00,99,15,10 4 | 2013-05-01T08:00:00,15,99, 5 | 2013-06-01T08:00:00,15,99,10,extra 6 | 2013-07-01T27:00:00,15,99,10 7 | 2013-03-02T08:00:00,0,99,10 8 | -------------------------------------------------------------------------------- /tools/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 | -------------------------------------------------------------------------------- /error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Error! 5 | 6 | 7 | 8 | 9 |

Loading Javascript failed. Check that the loader is available.

10 | Click here to retry.

11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/webdc3/images/Makefile: -------------------------------------------------------------------------------- 1 | RESIZE=-resize 120x48 2 | 3 | eida-logo2.png: eida-orfeus3.jpg 4 | # Adjust to 2.5:1 for 120x48, and remove text underneath: 5 | convert -crop 540x216+0+24 eida-orfeus3.jpg ${RESIZE} eida-logo2.png 6 | 7 | eida-orfeus3.jpg: 8 | wget "http://www.orfeus-eu.org/eida/eida-orfeus3.jpg" 9 | 10 | clean: 11 | -rm eida-logo2.png 12 | -rm eida-orfeus3.jpg 13 | 14 | -------------------------------------------------------------------------------- /tools/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 | -------------------------------------------------------------------------------- /wsgi/descriptions/webinterface.rst: -------------------------------------------------------------------------------- 1 | .. _configuration-options: 2 | 3 | Configuration options for webinterface 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | This refers specificially to the WSGI application providing web services. 6 | See also JavaScript documentation elsewhere?? 7 | 8 | .. note :: 9 | This file is used with `webinterface.xml` for magical 10 | configuration documentation generation. Much more to do. 11 | 12 | -------------------------------------------------------------------------------- /test/samples/eqinfo_sample3.csv: -------------------------------------------------------------------------------- 1 | "Event ID";"F-E Region";Magnitude;Status;"Origin time";Latitude;Longitude;"Depth (km)";Flags 2 | gfz2013lquu;"Near Coast of Nicaragua";6.4;M;"2013-06-15 17:34:31";11.87;-86.98;49;"big" 3 | gfz2013lqsb;"Crete, Greece";6;M;"2013-06-15 16:11:02";34.41;25.04;13;"big" 4 | gfz2013lqil;"South of Kermadec Islands";6;M;"2013-06-15 11:20:38";-33.94;179.28;210;"big" 5 | gfz2013lncg;"South of Java, Indonesia";6.7;M;"2013-06-13 16:47:25";-9.94;107.28;17;"xxl" 6 | 7 | -------------------------------------------------------------------------------- /wsgi/webdc3.conf.sample: -------------------------------------------------------------------------------- 1 | # 2 | # Apache2 configuration for the WebDC3 web interface. 3 | # This is typical for Unbuntu-style distributions, but 4 | # may require path changes for your site. 5 | # 6 | WSGIScriptAlias /webinterface/wsgi /var/www/webinterface/wsgi/webdc3.wsgi 7 | 8 | Order allow,deny 9 | Allow from all 10 | 11 | 12 | # 13 | # You may also need to add a section like: 14 | # 15 | ## 16 | ## Order allow,deny 17 | ## Allow from all 18 | ## 19 | 20 | -------------------------------------------------------------------------------- /examples/webdc3/gfz-backup.css: -------------------------------------------------------------------------------- 1 | /* gfz-backup.css 2 | * Load this before GFZ template.css to prevent serious problems 3 | * if the latter is absent. 4 | * Keep this file as small as possible to provide a *workable* site. 5 | * If template.css is present, it should override any settings here. 6 | */ 7 | 8 | #logoGFZ { 9 | position: absolute; 10 | left: -20px; 11 | bottom: 0; 12 | } 13 | 14 | #wordmarkGFZ { 15 | position: absolute; 16 | right: -8px; 17 | bottom: 0; 18 | } 19 | 20 | .boxRight { /* einzelne Box */ 21 | background: #E0EFF6; 22 | } 23 | -------------------------------------------------------------------------------- /css/help.css: -------------------------------------------------------------------------------- 1 | /* Additional style for help.html */ 2 | dl { 3 | margin: 2em 0; 4 | padding: 0; 5 | width: 60em; 6 | } 7 | 8 | dt { 9 | font-weight: bold; 10 | border: 1px Solid black; 11 | border-left: 1px solid silver; 12 | border-right: 1px solid silver; 13 | border-top: 1px solid silver; 14 | border-top-left-radius: .5em; 15 | border-top-right-radius: .5em; 16 | color:black; 17 | background: #00899F; 18 | padding: 5px 5px 5px 5px; 19 | } 20 | 21 | dd { 22 | color:black; 23 | background-color:lightyellow; 24 | padding: 8px 8px 32px 8px; 25 | border-left: 1px solid silver; 26 | border-right: 1px solid silver; 27 | border-bottom: 1px solid silver; 28 | margin: 0 0 1em 0; 29 | } 30 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. WebDC3 web interface documentation master file, created by 2 | sphinx-quickstart on Sat Jun 4 16:43:16 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Documentation for the WebDC3 web interface 7 | ========================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | introduction 13 | userguide 14 | operator 15 | developer 16 | changelog 17 | 18 | .. note:: 19 | 20 | The WebDC3 software is free software; you can redistribute it and/or 21 | modify it under the terms of the GNU General Public License as published 22 | by the Free Software Foundation; either version 2, or (at your option) any 23 | later version. For more information, see http://www.gnu.org/ 24 | 25 | Indices and tables 26 | ================== 27 | 28 | * :ref:`genindex` 29 | * :ref:`modindex` 30 | * :ref:`search` 31 | 32 | -------------------------------------------------------------------------------- /doc/_toReview/coding_style.txt: -------------------------------------------------------------------------------- 1 | For Python 2 | ========== 3 | 4 | Classes: 5 | 6 | Functions: 7 | 8 | Strings: 9 | 10 | Identifiers: 11 | 12 | Other: 13 | 14 | ** Indentation: Python-standard four spaces, please! 15 | 16 | ** header: use something like this: 17 | 18 | """ 19 | # 20 | # (one line description) 21 | # 22 | # (begun by / by / modif by) (human), GEOFON team, (month) 2013 23 | # 24 | # 25 | # Copyright (C) 2017 GEOFON team, Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 26 | # ---------------------------------------------------------------------- 27 | """ 28 | 29 | ** one blank line at the end of the file. 30 | - AH does it that way. 31 | - SeisComP coding conventions 32 | 33 | ** Use PEP-8, flake8 --max-line-length=99 to get things cleaner. 34 | 35 | For JavaScript 36 | ============== 37 | 38 | * 'wi' prefix 39 | 40 | * camelCase for identifiers. 41 | 42 | * semicolon to end statements. 43 | 44 | * tab instead of 8 spaces. 45 | 46 | * one blank line at the end of the file. 47 | 48 | -------------------------------------------------------------------------------- /test/testParseFile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Parse some input text for events

4 |

Enter your event info as CSV:

5 | URL: action="http://localhost:8005/event/parse" 6 | URL: action="http://localhost:8008/event/parse" 7 | URL: action="http://localhost/testwi/webinterface/event/parse" 8 |
9 | 10 | 11 | 15 | 16 | 17 | 22 | 23 | 26 | 27 |
Event data:
Columns:
Output Format: 24 | CSV
25 | JSON
28 | 29 | 30 |
31 |

A header row is allowed, and may be succesfully ignored. You may need to quote strings for auto-detection to work properly. YMMV.

32 | 33 | 34 | -------------------------------------------------------------------------------- /CITATION: -------------------------------------------------------------------------------- 1 | 2 | You are welcome to use and modify the webinterface software. 3 | See the README.md and COPYING files for details. 4 | 5 | If you use this software for research we would appreciate appropriate citation. 6 | This may be prepared using the bibliographic metadata contained in our DOI, accessible through the DOI system and at 7 | http://pmd.gfz-potsdam.de/panmetaworks/download.php?item=escidoc:1423080&mdrecord=datacite 8 | 9 | To cite WebDC3 in publication, please use: 10 | 11 | Bianchi, Marcelo; Evans, Peter L.; Heinloo, Andres; Quinteros, Javier (2015): WebDC3 Web Interface. GFZ Data Services. doi:10.5880/GFZ.2.4/2016.001 12 | 13 | This may need modification for the citation style of your publication. 14 | You are encouraged to include the version number of the software. 15 | This is shown on the "Console" tab when the page loads, e.g. "Loading webinterface v1.1 (2017.096)". 16 | 17 | A BibTeX entry for LaTeX users is 18 | 19 | @Book{, 20 | author = {Marcelo Bianchi and Peter L. Evans and Andres Heinloo and Javier Quinteros} 21 | title = {WebDC3 Web Interface}, 22 | publisher = {GFZ Data Services}, 23 | year = {2015}, 24 | doi = {10.5880/GFZ.2.4/2016.001}, 25 | url = {http://geofon.gfz-potsdam.de/software/webdc3}, 26 | } 27 | 28 | For information on citing software products generally, see the 29 | FORCE11 document [*]. 30 | 31 | 32 | [*] FORCE11 Software Citation Working Group (2016), "Software Citation Principles", (Editors: Arfon M. Smith, Daniel S. Katz, Kyle E. Niemeyer). 33 | Accessed 2017-08-08 at https://www.force11.org/sites/default/files/shared-documents/software-citation-principles.pdf 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * WebDC 3 3 | * 4 | * Copyright (C) 2013-2016 Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 5 | * 6 | */ 7 | 8 | import initConsole from './console' 9 | import initConfig from './config' 10 | import initMapping from './mapping' 11 | import initService from './service' 12 | import initFdsnws from './fdsnws' 13 | import initRequest from './request' 14 | import initEvents from './events' 15 | import initStation from './station' 16 | import initSubmit from './submit' 17 | import initReview from './review' 18 | import initInterface from './interface' 19 | 20 | var VERSION = "1.2 (2019.331)" 21 | 22 | window.WIError = function(message) { 23 | this.name = undefined // omit exception name on the console 24 | this.message = message 25 | this.toString = function() { return this.message } 26 | } 27 | 28 | window.WIError.prototype = new Error 29 | 30 | // The modules use interfaceLoader.debug(), so add this for compatibility. 31 | window.interfaceLoader = new function() { 32 | this.debug = function() { 33 | return (typeof eidaDebug != 'undefined') ? eidaDebug : true 34 | } 35 | } 36 | 37 | $(document).ready(function() { 38 | initConsole() 39 | .then(function() { 40 | wiConsole.info("Loading webinterface v" + VERSION + "...") 41 | }) 42 | .then(initConfig) 43 | .then(initMapping) 44 | .then(initService) 45 | .then(initFdsnws) 46 | .then(initRequest) 47 | .then(initEvents) 48 | .then(initStation) 49 | .then(initSubmit) 50 | .then(initReview) 51 | .then(initInterface) 52 | .then(function() { 53 | wiConsole.info("Ready.") 54 | }) 55 | .catch(function() { 56 | wiConsole.info("Aborted.") 57 | }) 58 | }) 59 | 60 | -------------------------------------------------------------------------------- /examples/webdc3/wi-geofon.css: -------------------------------------------------------------------------------- 1 | /* Style changes after loading the generic wimodule.css file */ 2 | /* 3 | * .wi-table-header-cell { 4 | * background: #f00; 5 | * color: yellow; 6 | * } 7 | */ 8 | 9 | /* Magic for help pop-ups: */ 10 | 11 | .boxRight h2 { 12 | /* override geofon.css */ 13 | display: inline; 14 | } 15 | 16 | .help { 17 | /* override geofon.css */ 18 | display: block; 19 | right: 8px; 20 | } 21 | 22 | .help a { 23 | color: silver; 24 | text-decoration: none; 25 | padding: 1px 6px; 26 | margin-right: 8px; 27 | border: 1px Solid silver; 28 | float: right; 29 | } 30 | 31 | .help a:hover { 32 | /* border: 1px solid silver; */ 33 | color: blue; 34 | background-color: orange; 35 | border: 1px Solid red; 36 | float: right; 37 | z-index: 999; 38 | } 39 | 40 | .help a span { 41 | display: none; 42 | } 43 | 44 | .help a:hover span { 45 | display: block; 46 | overflow: visible; 47 | position: absolute; 48 | top: auto; 49 | right:0px; 50 | text-align: right; 51 | color:red; 52 | background-color:pink; 53 | width: 24em; 54 | padding: 0px; 55 | border: 1px solid red; 56 | z-index: 999; 57 | } 58 | 59 | /* wi controls use class="wi-short-spacer" as an introducer before 60 | * a short selector e.g. a pull-down menu. 61 | * Embed it in a "wi-short-div" and use absolute positioning for 62 | * the object on the right. The "wi-short-spacer" has normal 63 | * positioning so it sets the height of the "wi-short-div". 64 | */ 65 | .wi-short-div { 66 | position: relative; 67 | } 68 | 69 | .wi-short-spacer { 70 | margin: 0 0 0.5em 0; 71 | width: 48%; 72 | } 73 | 74 | .wi-short-right { 75 | position: absolute; 76 | width: 48%; 77 | top: 0px; 78 | right: 0px; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | README file for webinterface 3 | ---------------------------- 4 | 5 | GUI tool for event- and time-based waveform selection. 6 | 7 | Copyright (C) 2013-2015 GEOFON team, Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 8 | 9 | 10 | To make the documentation: 11 | 12 | cd doc ; make latexpdf ; acroread _build/latex/WebDC3webinterface.pdf 13 | 14 | To install: 15 | see doc/ 16 | 17 | If you use this software for research we would appreciate appropriate citation. 18 | See the `CITATION` file for details. 19 | 20 | 21 | Licence 22 | ======= 23 | 24 | This program is free software; you can redistribute it and/or modify 25 | it under the terms of the GNU General Public License as published by 26 | the Free Software Foundation; either version 3, or (at your option) 27 | any later version. For more information, see http://www.gnu.org/ 28 | 29 | This program is distributed in the hope that it will be useful, 30 | but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | GNU General Public License for more details. 33 | 34 | You should have received a copy of the GNU General Public License 35 | along with this program. If not, see . 36 | 37 | 38 | IDEAS for version 2.0 39 | ===================== 40 | 41 | * Cookie to come back to a half-built search. 42 | (e.g. save a station set, update the events associated with it) 43 | 44 | * GFZ event pages have a link to go straight to waveform selection 45 | 46 | * Add search by QC parameters, etc. 47 | 48 | * :event: *important* Filter by station distance 49 | 50 | * :event: Circular filter of the catalog. 51 | 52 | * und viel mehr... see `TODO` 53 | -------------------------------------------------------------------------------- /test/testPublic.txt: -------------------------------------------------------------------------------- 1 | #! not a real script yet! 2 | 3 | # replace with python urllib2.open() 4 | wget "eida.gfz-potsdam.de/webdc3/wsgi/metadata/query?start=1980&end=2013&station=all&networktype=perm" -O eida-perm.json 5 | wget "eida.gfz-potsdam.de/webdc3/wsgi/metadata/query?start=1980&end=2013&station=all&networktype=permo" -O eida-permo.json 6 | wget "eida.gfz-potsdam.de/webdc3/wsgi/metadata/query?start=1980&end=2013&station=all&networktype=permr" -O eida-permr.json 7 | python < 17 | ka = [x[0] for x in a]; 18 | kb = [x[0] for x in b]; 19 | kr = [x[0] for x in r]; 20 | sa = set(ka) 21 | sb = set(kb) 22 | sr = set(kr) 23 | len(sa) 24 | 2478 25 | len(sb) 26 | 2318 27 | len(sr) 28 | 167 29 | sb.intersection(sr) 30 | set(['IQ-1980-HUAR-2009123', 'IQ-1980-TIRA-2009125', 'IQ-1980-PICL-2009121', 'IQ-1980-NEUQ-2009517', 'IQ-1980-POZO-2009124', 'IQ-1980-PINT-2009125', 'IQ-1980-UNAP-2009514']) 31 | assert( len(sb.intersection(sr) == 0 ) 32 | # Should be empty, but for virtual networks which are open. 33 | 34 | EOF 35 | 36 | function test_export() { 37 | local_url_base="http://localhost/webinterface" 38 | wget -S "${local_url_base}/wsgi/metadata/export?streams=[[%22GE%22,%22UGM%22,%22BHZ%22,%22%22],[%22GE%22,%22APE%22,%22BHE%22,%22%22]]" -o foo.wget -O foo.dat 39 | od -a foo.dat > 1 40 | 41 | cat >2 <, GEOFON team, June 2013 18 | 19 | """ 20 | return [ self.js_conf ] 21 | 22 | def loaderjs(self, envir, params): 23 | """It returns the Javascript code to load the loader.js file in the main page. 24 | Begun by Marcelo Bianchi , GEOFON team, June 2013 25 | 26 | """ 27 | 28 | body = [] 29 | 30 | # Create the variables that are returned in Javascript format based on the 31 | # information of the environment. 32 | serviceRoot = envir['SCRIPT_NAME'] 33 | cssSource = os.path.dirname(serviceRoot) + '/css' 34 | jsSource = os.path.dirname(serviceRoot) + '/js' 35 | debug = (self.__wi.getConfigInt('DEBUG', 0) == 1) 36 | body.append("window.eidaServiceRoot=%s;" % json.dumps(serviceRoot)) 37 | body.append("window.eidaCSSSource=%s;" % json.dumps(cssSource)) 38 | body.append("window.eidaJSSource=%s;" % json.dumps(jsSource)) 39 | body.append("window.eidaDebug=%s;" % json.dumps(debug)) 40 | body.append("$('head').append($('').attr({rel:'stylesheet',type:'text/css',href:%s}));" % 41 | json.dumps(cssSource + '/wimodule.css')) 42 | body.append("$.getScript(%s);" % json.dumps(jsSource + '/webdc3.min.js')) 43 | 44 | return body 45 | 46 | -------------------------------------------------------------------------------- /test/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Stand-alone manager for web interface testing. 4 | # 5 | # Begun by GEOFON team, July 2012 6 | # 7 | # 8 | # Copyright (C) 2012 GEOFON team, Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 9 | # ---------------------------------------------------------------------- 10 | 11 | import datetime 12 | import os 13 | import sys 14 | import wsgiref 15 | 16 | sys.path.append(os.path.join('..', 'wsgi')) # for wsgicomm 17 | sys.path.append(os.path.join('..', 'wsgi', 'module')) 18 | 19 | 20 | import argparse # New in Python version 2.7 21 | parser = argparse.ArgumentParser(description="Start stand-alone web interface for testing.") 22 | parser.add_argument("-p", "--port", type=int, nargs=1, dest="port", help="listen on PORT") 23 | 24 | try: 25 | import webinterface 26 | have_seiscomp3 = True 27 | except ImportError: 28 | import webinterface_no_sc3 as webinterface 29 | have_seiscomp3 = False 30 | 31 | 32 | if __name__ == '__main__': 33 | args = parser.parse_args() 34 | print args 35 | try: 36 | port = int(args.port[0]) 37 | except: 38 | port = 8008 39 | proto = "http://" 40 | host = 'localhost' 41 | hostport = '%s:%i' % (host, port) 42 | print "Starting wsgiref on port %(p)i" % {'p': port} 43 | 44 | print "About me:" 45 | print str(webinterface.wi) 46 | 47 | print "\nEVENTS" 48 | print "%s%s/event/catalogs" % (proto, hostport) 49 | print "%s%s/event/geofon?maxlat=-20" % (proto, hostport) 50 | print "%s%s/event/comcat?start=%s" % (proto, hostport, datetime.date.today()) 51 | print "%s%s/event/meteor" % (proto, hostport) 52 | 53 | print "\nMETADATA" 54 | print "%s%s/metadata/networktypes" % (proto, hostport) 55 | print "%s%s/metadata/sensortypes" % (proto, hostport) 56 | 57 | from wsgiref.simple_server import make_server 58 | srv = make_server(host, port, webinterface.application) 59 | srv.serve_forever() 60 | -------------------------------------------------------------------------------- /test/samples/eqinfo_sample2.csv: -------------------------------------------------------------------------------- 1 | #"Event ID"|"F-E Region"|Magnitude|Status|"Origin time"|Latitude|Longitude|"Depth (km)"|Flags 2 | # http://geofon.gfz-potsdam.de/eqinfo/list.php?latmax=-20&fmt=csv 3 | # Lines: 41 4 | "Event ID";"F-E Region";Magnitude;Status;"Origin time";Latitude;Longitude;"Depth (km)";Flags 5 | gfz2013mwbh;"Jujuy Province, Argentina";5.6;M;"2013-07-02 20:04:58";-23.87;-66.53;215;"all" 6 | gfz2013mvym;"Southeast of Easter Island";5.6;A;"2013-07-02 18:39:45";-35.88;-102.80;10;"big" 7 | gfz2013mvgr;"Catamarca Province, Argentina";4.27;M;"2013-07-02 09:39:05";-27.83;-66.68;158;"all" 8 | gfz2013muun;"Easter Island Region";4.46;M;"2013-07-02 03:30:56";-22.17;-114.04;10;"all" 9 | gfz2013mtjl;"South Sandwich Islands Region";5.01;M;"2013-07-01 08:47:16";-55.46;-28.56;10;"all" 10 | gfz2013msmy;"South of Fiji Islands";4.52;M;"2013-06-30 21:25:03";-26.76;178.89;581;"all" 11 | gfz2013mqik;"Off Coast of Central Chile";4.66;C;"2013-06-29 16:50:51";-39.42;-75.08;10;"all" 12 | gfz2013mpzu;"Vanuatu Islands";5.19;A;"2013-06-29 12:29:45";-20.10;169.48;120;"all" 13 | gfz2013mpjx;"Balleny Islands Region";4.59;A;"2013-06-29 04:28:03";-64.87;176.04;10;"all" 14 | gfz2013mpfo;"Southeast Indian Ridge";5.19;M;"2013-06-29 02:17:04";-50.29;112.66;10;"all" 15 | gfz2013mowl;"Southern East Pacific Rise";4.66;M;"2013-06-28 21:40:26";-34.85;-109.00;10;"all" 16 | gfz2013mnzy;"Southern East Pacific Rise";4.63;M;"2013-06-28 10:18:44";-37.34;-110.66;10;"all" 17 | gfz2013mnux;"Southeast of Loyalty Islands";4.72;A;"2013-06-28 07:45:22";-22.86;171.30;10;"all" 18 | gfz2013mnju;"Near Coast of Central Chile";4.73;M;"2013-06-28 02:08:13";-29.70;-71.64;10;"all" 19 | gfz2013mnei;"Northern Chile";4.8;C;"2013-06-27 23:22:51";-26.21;-69.19;10;"all" 20 | gfz2013mnac;"Chile-Argentina Border Region";4.57;M;"2013-06-27 21:14:38";-24.04;-67.66;243;"all" 21 | gfz2013mmpm;"Southwest Indian Ridge";4.8;M;"2013-06-27 15:53:28";-30.65;59.49;10;"all" 22 | gfz2013mmlw;"Chile-Bolivia Border Region";4.43;M;"2013-06-27 14:03:41";-20.38;-68.80;104;"all" 23 | gfz2013mhjf;"Chile-Argentina Border Region";4.53;A;"2013-06-24 19:04:48";-24.22;-67.46;169;"all" 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the webinterface 3 | # 4 | # ---------------------------------------------------------------------- 5 | all: js/webdc3.min.js 6 | 7 | .PHONY: all clean documentation gitcheck release test demo 8 | 9 | # sudo {zypper|apt-get|yum} install npm 10 | # npm install browserify babelify@8 babel-core babel-preset-env 11 | # PATH=./node_modules/.bin:$PATH 12 | js/webdc3.min.js: src/* 13 | mkdir -p js 14 | browserify --entry src/main.js --transform [ babelify --presets env --no-comments --minified ] --outfile $@ 15 | 16 | clean: 17 | (cd doc ; make clean) 18 | (cd wsgi ; rm -f *.pyc ; rm -f */*.pyc) 19 | (cd test ; rm -f *.pyc ) 20 | 21 | documentation: 22 | (cd doc ; make install) 23 | 24 | gitcheck: 25 | git status 26 | 27 | 28 | # What's the right way to do a release 29 | # with all the code we want, none we don't, 30 | # and the manual? 31 | # 32 | # Before doing a release, update the version number in 33 | # - doc/templates/conf.py 34 | # - src/main.js 35 | # and update doc/base/changelog.rst 36 | # (e.g. find . -type f -exec grep --color 0\\.5 {} \; -print) 37 | # Then 'make documentation' and check that it looks right. 38 | # Finally, 'make gitcheck', and when clean, 'make release' 39 | 40 | DATESTR:=$(shell date +%Y.%j) 41 | RELEASEFILE=webdc3-${DATESTR}.tgz 42 | # Ideally, release-yyyy.jjj.tgz 43 | # 44 | release: clean gitcheck 45 | make documentation 46 | rm -rf release 47 | mkdir release 48 | git archive -o release/archive.tar --prefix=webinterface/ HEAD 49 | (cd release; tar xpf archive.tar ; rm -f archive.tar ) 50 | find release -path "*/.git/*" -delete 51 | find release -name webinterfaceEvent.py -delete # NOT READY YET. 52 | cp -pr doc/webinterface.pdf doc/html release/webinterface/doc 53 | @echo -n "Uncompressed size: " 54 | @du -sh release 55 | (cd release; tar cfz ../${RELEASEFILE} . ) 56 | rm -rf release 57 | @echo "Compressed: " 58 | @ls -l ${RELEASEFILE} 59 | @md5sum ${RELEASEFILE} 60 | @echo "Done. Final product is '${RELEASEFILE}'" 61 | 62 | test: 63 | (cd test ; python testEvents.py ) 64 | 65 | demo: 66 | (cd test ; python manage.py ) 67 | 68 | -------------------------------------------------------------------------------- /doc/introduction.rst: -------------------------------------------------------------------------------- 1 | The WebDC3 web interface generator 2 | ================================== 3 | 4 | This code was developed from the old webdc.eu portal developed at GFZ in the 5 | NERIES project. In the first stage we decided to maintain the functionalities 6 | already achieved focusing on a code clean-up and technology upgrade to 7 | accommodate the current EIDA needs. 8 | 9 | The new web interface looks different, but functions more or less 10 | like the old one. Users can select waveforms, dataless SEED, and inventory XML 11 | for downloading. The selection can be constrained 12 | by streams by network, station location, channel and other properties, 13 | and the time windows chosen can be constrained based on user-selected events. 14 | 15 | The web interface mainly uses JavaScript for presentation, 16 | with Python used to provide underlying services. 17 | 18 | This documentation contains: 19 | 20 | * A :ref:`user-guide` for getting data from the running web interface. 21 | 22 | * :ref:`operator-guide`, for installing and configuring the software. 23 | 24 | * The :ref:`developer-guide`, for understanding the internal functions and 25 | contributing new code such as event services. 26 | 27 | As an appendix, there is a :ref:`self-study tutorial` as a base to get your 28 | users familiar with what they can do with the tool. 29 | 30 | We hope you find it useful. 31 | 32 | 33 | This software and documentation is released under the GPL. See the 34 | file `COPYING` for details:: 35 | 36 | This program is free software; you can redistribute it and/or modify it 37 | under the terms of the GNU General Public License as published by the 38 | Free Software Foundation; either version 3, or (at your option) any later 39 | version. For more information, see http://www.gnu.org/ 40 | 41 | This program is distributed in the hope that it will be useful, 42 | but WITHOUT ANY WARRANTY; without even the implied warranty of 43 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 44 | GNU General Public License for more details. 45 | 46 | You should have received a copy of the GNU General Public License 47 | along with this program. If not, see . 48 | 49 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * GEOFON WebInterface 3 | * 4 | * Begun by: 5 | * Marcelo Bianchi, Peter Evans, Javier Quinteros, GFZ Potsdam 6 | * 7 | * config.js module: A config proxy to load the configuration variables from 8 | * the Python interface level (server) into the JavaScript client level. 9 | * 10 | */ 11 | 12 | /* 13 | * Configuration proxy Object implementation 14 | */ 15 | function ConfigurationProxy(url) { 16 | // Private 17 | var _url = undefined; 18 | var _cache = {}; 19 | 20 | /* Reload the configuration from the server */ 21 | this.reload = function() { 22 | return new Promise(function(resolve, reject) { 23 | if (_url === undefined) { 24 | reject(new Error("server URL is not defined")); 25 | return; 26 | } 27 | 28 | _cache = {}; 29 | $.getJSON(_url + 'configuration').done(function(data) { 30 | _cache = data; 31 | resolve(); 32 | }) 33 | .fail(function() { 34 | reject(new Error("AJAX error")); 35 | }); 36 | }); 37 | }; 38 | 39 | 40 | // Public 41 | /* Get one configuration value */ 42 | this.value = function(key, defaultValue) { 43 | var current = _cache; 44 | 45 | var keys = key.split("."); 46 | for(var keyid in keys) { 47 | var level = keys[keyid]; 48 | if ( (current === null) || (current[level] === undefined) ) { 49 | current = null; 50 | break; 51 | } 52 | current = current[level]; 53 | } 54 | 55 | if (current === null) return defaultValue; 56 | return current; 57 | }; 58 | 59 | this.serviceRoot = function(){ 60 | return _url; 61 | }; 62 | 63 | // Main Object Implementation 64 | if (!url) { 65 | if (interfaceLoader.debug()) console.error('config.js: Need a base server address to query for configuration parameters.'); 66 | return; 67 | } 68 | 69 | // Check the last slash on the url 70 | _url = url + ( ( url[url.length-1] !== '/' ) ? '/' : '' ); 71 | } 72 | 73 | /* 74 | * Export for main.js 75 | */ 76 | export default function() { 77 | return new Promise(function(resolve, reject) { 78 | function error(e) { 79 | if (console.error !== wiConsole.error) 80 | console.error("config.js: " + e.message); 81 | 82 | wiConsole.error("config.js: " + e.message, e); 83 | reject(); 84 | } 85 | 86 | try { 87 | var sr = ((typeof eidaServiceRoot === 'undefined')) ? "wsgi/" : eidaServiceRoot; 88 | window.configurationProxy = new ConfigurationProxy(sr); 89 | window.configurationProxy.reload().then(resolve).catch(error); 90 | } 91 | catch (e) { 92 | error(e); 93 | } 94 | }); 95 | } 96 | 97 | -------------------------------------------------------------------------------- /tools/jquery/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.3.1 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function ($, document, undefined) { 9 | 10 | var pluses = /\+/g; 11 | 12 | function raw(s) { 13 | return s; 14 | } 15 | 16 | function decoded(s) { 17 | return unRfc2068(decodeURIComponent(s.replace(pluses, ' '))); 18 | } 19 | 20 | function unRfc2068(value) { 21 | if (value.indexOf('"') === 0) { 22 | // This is a quoted cookie as according to RFC2068, unescape 23 | value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 24 | } 25 | return value; 26 | } 27 | 28 | function fromJSON(value) { 29 | return config.json ? JSON.parse(value) : value; 30 | } 31 | 32 | var config = $.cookie = function (key, value, options) { 33 | 34 | // write 35 | if (value !== undefined) { 36 | options = $.extend({}, config.defaults, options); 37 | 38 | if (value === null) { 39 | options.expires = -1; 40 | } 41 | 42 | if (typeof options.expires === 'number') { 43 | var days = options.expires, t = options.expires = new Date(); 44 | t.setDate(t.getDate() + days); 45 | } 46 | 47 | value = config.json ? JSON.stringify(value) : String(value); 48 | 49 | return (document.cookie = [ 50 | encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), 51 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 52 | options.path ? '; path=' + options.path : '', 53 | options.domain ? '; domain=' + options.domain : '', 54 | options.secure ? '; secure' : '' 55 | ].join('')); 56 | } 57 | 58 | // read 59 | var decode = config.raw ? raw : decoded; 60 | var cookies = document.cookie.split('; '); 61 | var result = key ? null : {}; 62 | for (var i = 0, l = cookies.length; i < l; i++) { 63 | var parts = cookies[i].split('='); 64 | var name = decode(parts.shift()); 65 | var cookie = decode(parts.join('=')); 66 | 67 | if (key && key === name) { 68 | result = fromJSON(cookie); 69 | break; 70 | } 71 | 72 | if (!key) { 73 | result[name] = fromJSON(cookie); 74 | } 75 | } 76 | 77 | return result; 78 | }; 79 | 80 | config.defaults = {}; 81 | 82 | $.removeCookie = function (key, options) { 83 | if ($.cookie(key) !== null) { 84 | $.cookie(key, null, options); 85 | return true; 86 | } 87 | return false; 88 | }; 89 | 90 | })(jQuery, document); 91 | -------------------------------------------------------------------------------- /test/testHelpers.py: -------------------------------------------------------------------------------- 1 | # 2 | # Useful routines for testing. 3 | # 4 | # Begun by Peter L. Evans, summer 2013 (old code was in test*.py) 5 | # 6 | # 7 | # ---------------------------------------------------------------------- 8 | import cgi 9 | import json 10 | import urllib2 11 | 12 | def offline(): 13 | """Are we online now?""" 14 | url = "http://geofon.gfz-potsdam.de/" 15 | try: 16 | response = urllib2.urlopen(url) 17 | if response: 18 | return False 19 | else: 20 | print " *** got a non-True response from "+url 21 | return False 22 | except urllib2.URLError: 23 | return True 24 | 25 | 26 | def short_error_body(b): 27 | for line in b.splitlines(): 28 | if line.startswith("Service '") or line.startswith("Error ") or line.find("/event/") > -1: 29 | print line 30 | 31 | def count_lines(s): 32 | """Body is typically a one-item list, containing a string.""" 33 | if s: 34 | if len(s) == 1: 35 | return s[0].count('\n') 36 | else: 37 | return 'list of %i items' % len(s) 38 | else: 39 | return 'None' 40 | 41 | def count_json_obj(s): 42 | """If this is a JSON string, how big is its object?""" 43 | assert(isinstance(s, str)) 44 | 45 | verbose = False 46 | if (verbose): 47 | print "count_json_obj: (%i)" % len(s), 48 | if len(s) > 10: 49 | print s[0:10], "...", s[-10:-1] 50 | else: 51 | print 52 | 53 | try: 54 | obj = json.loads(s) # (s[2:-2]) - if it is double-wrapped 55 | return len(obj) 56 | except ValueError: 57 | return 0 58 | except TypeError as e: 59 | print "count_json_obj: TypeError!", e 60 | print "String was:", "x%sx" % s 61 | return 0 62 | 63 | def count_json_obj2(s): 64 | """If this is a JSON string, how many level-2 objects does it have?""" 65 | assert(isinstance(s, str)) 66 | 67 | count = 0 68 | try: 69 | obj = json.loads(s) # (s[2:-2]) - if it is double-wrapped 70 | for obj2 in obj: 71 | count += len(obj2) 72 | return count 73 | except ValueError: 74 | return 0 75 | 76 | def print_json_obj(body): 77 | """Quick re-format of a JSON-formatted body""" 78 | for item in json.loads(body[0]): 79 | print item 80 | 81 | def query_str(d): 82 | """Prepare a query string from a dictionary d.""" 83 | return "&".join('%s=%i' % (x, y) for x, y in d.items()) 84 | -------------------------------------------------------------------------------- /test/samples/eqinfo_sample.csv: -------------------------------------------------------------------------------- 1 | "Event ID";"F-E Region";Magnitude;Status;"Origin time";Latitude;Longitude;"Depth (km)";Flags 2 | gfz2013mvgr;"Catamarca Province, Argentina";4.27;M;"2013-07-02 09:39:05";-27.83;-66.68;158;"all" 3 | gfz2013muun;"Easter Island Region";4.46;M;"2013-07-02 03:30:56";-22.17;-114.04;10;"all" 4 | gfz2013mtjl;"South Sandwich Islands Region";5.01;M;"2013-07-01 08:47:16";-55.46;-28.56;10;"all" 5 | gfz2013msmy;"South of Fiji Islands";4.52;M;"2013-06-30 21:25:03";-26.76;178.89;581;"all" 6 | gfz2013mqik;"Off Coast of Central Chile";4.66;C;"2013-06-29 16:50:51";-39.42;-75.08;10;"all" 7 | gfz2013mpzu;"Vanuatu Islands";5.19;A;"2013-06-29 12:29:45";-20.10;169.48;120;"all" 8 | gfz2013mpjx;"Balleny Islands Region";4.59;A;"2013-06-29 04:28:03";-64.87;176.04;10;"all" 9 | gfz2013mpfo;"Southeast Indian Ridge";5.19;M;"2013-06-29 02:17:04";-50.29;112.66;10;"all" 10 | gfz2013mowl;"Southern East Pacific Rise";4.66;M;"2013-06-28 21:40:26";-34.85;-109.00;10;"all" 11 | gfz2013mnzy;"Southern East Pacific Rise";4.63;M;"2013-06-28 10:18:44";-37.34;-110.66;10;"all" 12 | gfz2013mnux;"Southeast of Loyalty Islands";4.72;A;"2013-06-28 07:45:22";-22.86;171.30;10;"all" 13 | gfz2013mnju;"Near Coast of Central Chile";4.73;M;"2013-06-28 02:08:13";-29.70;-71.64;10;"all" 14 | gfz2013mnei;"Northern Chile";4.8;C;"2013-06-27 23:22:51";-26.21;-69.19;10;"all" 15 | gfz2013mnac;"Chile-Argentina Border Region";4.57;M;"2013-06-27 21:14:38";-24.04;-67.66;243;"all" 16 | gfz2013mmpm;"Southwest Indian Ridge";4.8;M;"2013-06-27 15:53:28";-30.65;59.49;10;"all" 17 | gfz2013mmlw;"Chile-Bolivia Border Region";4.43;M;"2013-06-27 14:03:41";-20.38;-68.80;104;"all" 18 | gfz2013mhjf;"Chile-Argentina Border Region";4.53;A;"2013-06-24 19:04:48";-24.22;-67.46;169;"all" 19 | gfz2013mded;"Southern Bolivia";4.2;M;"2013-06-22 11:55:05";-21.47;-66.70;214;"all" 20 | gfz2013malg;"Santiago Del Estero Prov., Argentina";4.58;M;"2013-06-21 00:06:19";-26.90;-63.28;590;"all" 21 | gfz2013lznu;"Chile-Bolivia Border Region";4.45;M;"2013-06-20 12:15:45";-21.23;-68.39;128;"all" 22 | gfz2013lyko;"Chile-Argentina Border Region";5.3;M;"2013-06-19 21:29:13";-32.64;-70.09;112;"all" 23 | gfz2013lxyn;"Near Coast of Central Chile";4.49;M;"2013-06-19 15:24:33";-29.99;-71.36;41;"all" 24 | gfz2013lxnd;"Tonga Islands";5.18;A;"2013-06-19 09:39:30";-20.86;-174.09;10;"all" 25 | gfz2013lxed;"South of Fiji Islands";4.3;M;"2013-06-19 05:06:10";-24.50;179.81;527;"all" 26 | gfz2013lwbk;"Jujuy Province, Argentina";4.34;M;"2013-06-18 14:35:13";-22.81;-66.83;205;"all" 27 | gfz2013lvxe;"South of Fiji Islands";4.67;M;"2013-06-18 12:27:11";-23.29;-179.76;559;"all" 28 | 29 | -------------------------------------------------------------------------------- /test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Webinterface web service test page

9 |

Derived from interface-server-client.txt

10 | 11 |

Visiting the following URLs should work

12 |
    13 |
  1. Configuration 14 | Response:JSON structure
  2. 15 |
  3. Javascript 16 | loader 17 | Response: JavaScript method
  4. 18 |
19 | 20 |

Others

21 |
    22 |
  1. Metadata
  2. 23 |
  3. Event services
  4. 24 |
  5. Request services
  6. 25 |
26 | 27 |

Positioning

28 |
29 |
30 | Words words words. 31 |
32 |
33 | 34 |

More Positioning

35 |
36 |
40 | Left left left 41 |
42 |
45 | Right right right 46 |
47 |
48 | 49 |

Positioning with class

50 |
51 | 63 | MORE CONTENTS 64 |
65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /doc/_toReview/coding_checks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Some very simple checks on the source code 4 | # and documentation. 5 | # 6 | # PLE July 2013 7 | # 8 | # ---------------------------------------------------------------------- 9 | set -u 10 | 11 | base='..' 12 | 13 | # Some basic documentation checks 14 | function check_doc_links () { 15 | # No missing anchors? 16 | echo "Used: ($( sort $base/index.html | grep -c "div id=\"wi-"))" 17 | sort $base/index.html | grep --color "div id=\"wi-" # What's used on the site 18 | echo "Defined in help page ($(grep -c "dt id=" $base/help.html)):" 19 | sort $base/help.html | grep --color "dt id=" # What's defined 20 | echo "Referred to in help page ($(grep -c 'ref=\"\#' $base/help.html)):" 21 | sort $base/help.html | grep --color 'ref=\"\#' # What's cited 22 | echo "Done check_doc" 23 | } 24 | 25 | function check_doc_words () { 26 | rstfiles="$base/doc/source/*.rst $base/doc/base/*.rst $base/doc/source/specs/*" 27 | 28 | grep --color "timewindow" $rstfiles # Should be two words (getrennt) 29 | grep --color "webservice" $rstfiles # Should be two words (getrennt) 30 | grep --color "dropdown" $rstfiles # Should be two words (getrennt) 31 | grep --color "datacent" $rstfiles # Should be 'data cent(re,er)' 32 | #grep --color "[^/]webinterface" $rstfiles # Should be two words (getrennt) 33 | 34 | grep --color "JS[^SO][^N]" $rstfiles # Should be JavaScript 35 | grep --color "Javascript" $rstfiles # Should be JavaScript 36 | grep --color "Java " $rstfiles 37 | #grep --color "top" $rstfiles # no 'top layer' - use 'presentation' 38 | grep --color "backend" $rstfiles # 'back end' 39 | grep --color AJAX $rstfiles # Should be 'Ajax' 40 | grep --color ArcLink $rstfiles # Should be 'Arclink' ??? 41 | #grep --color " python" $rstfiles # Should be 'Python' 42 | 43 | # Long lines where a new sentence starts (break at '.'): 44 | #grep --color '[^0-9]\.\ [A-Z]' $rstfiles 45 | } 46 | 47 | # No stray 'print' statements 48 | function check_prints () { 49 | filelist=`find $base/wsgi -name "*.py" -print | sort` 50 | 51 | # No print statements to stdout: 52 | for f in ${filelist} ; do 53 | grep "print" $f | grep -v "print >>" 54 | done 55 | 56 | echo "Done check_prints" 57 | } 58 | 59 | # References from the index.html page to the help.html page: 60 | function check_help_links () { 61 | echo "" > 1 62 | grep "dt id=" help.html | cut -f2 -d\" | sort >> 1 63 | grep help.html index.html | sed 's/^\W* 2 64 | diff -y 1 2 65 | rm 1 2 66 | } 67 | 68 | # JavaScript: 69 | function check_js () { 70 | # All 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 58 | 59 |
60 |
61 |
62 |
63 |

Event and Station Map

64 |
65 |
66 |
67 | 68 |
69 |
70 |

Event and Station List

71 |
72 |
73 |
74 | 75 |
76 |
77 |

Request status

78 |
79 |
80 | 81 |
82 | 83 |
84 |
85 |

Console

86 |
87 |
88 |
89 |
90 | 91 |
92 |
93 |
94 |

Events Controls

95 |
96 |
97 |
98 | 99 |
100 |
101 |

Stations Controls

102 |
103 |
104 |
105 | 106 |
107 |
108 |

Submit

109 |
110 |
111 |
112 |
113 |
114 |
115 | 116 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /examples/webdc2012/date_functions.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | var date = new Date(); 3 | var datestr = date.getFullYear() + "-"; 4 | date.getMonth() < 9 ? datestr += "0" + (date.getMonth() + 1) + "-" : datestr += (date.getMonth() + 1) + "-"; 5 | date.getDate() < 10 ? datestr += "0" + date.getDate() : datestr += date.getDate(); 6 | $("#date_form input[name=startdate]").val(datestr); 7 | $("#date_form input[name=enddate]").val(datestr); 8 | $("#date_form input[name=startdate]+sub img").DatePicker({date: $("#date_form input[name=startdate]").val(), 9 | position: 'right', 10 | onBeforeShow: function() { 11 | $("#date_form input[name=startdate]+sub img").DatePickerSetDate($("#date_form input[name=startdate]").val(), true);}, 12 | onChange: function(formated, date) { 13 | $("#date_form input[name=startdate]").val(formated); 14 | $("#date_form input[name=startdate]+sub img").DatePickerHide(); 15 | clearModule("eqinfo"); clearModule("stalist"); 16 | checkDate("start");} 17 | }); 18 | $("#date_form input[name=enddate]+sub img").DatePicker({date: $("#date_form input[name=enddate]").val(), 19 | position: 'right', 20 | onBeforeShow: function() { 21 | $("#date_form input[name=enddate]+sub img").DatePickerSetDate($("#date_form input[name=enddate]").val(), true);}, 22 | onChange: function(formated, date) { 23 | $("#date_form input[name=enddate]").val(formated); 24 | $("#date_form input[name=enddate]+sub img").DatePickerHide(); 25 | clearModule("eqinfo"); clearModule("stalist"); 26 | checkDate("end");} 27 | }); 28 | $("#date_form input[name$=date]").bind("change", function() { 29 | clearModule("eqinfo"); clearModule("stalist"); 30 | checkDate($(this).attr("name").slice(0,-4)); 31 | }); 32 | $("#tw_form input[name=twstart]").val("00:00:00"); 33 | $("#tw_form input[name=twend]").val("23:59:59"); 34 | }); 35 | 36 | function saveDate() { 37 | var start = $("#date_form input[name=startdate]").val() + " " + $("#tw_form input[name=twstart]").val(); 38 | var end = $("#date_form input[name=enddate]").val() + " " + $("#tw_form input[name=twend]").val(); 39 | return "start=" + start + "&end=" + end; 40 | } 41 | 42 | function restoreDate() { 43 | var hash = window.location.hash.substr(1); 44 | var start = "", end = ""; 45 | var spattern = /start=([0-9-: ]+)/; 46 | var epattern = /end=([0-9-: ]+)/; 47 | var result = ""; 48 | if (result = spattern.exec(hash)) start = result[1]; 49 | if (result = epattern.exec(hash)) end = result[1]; 50 | if (start.length || end.length) { 51 | if (!start.length) start = end; 52 | if (!end.length) end = start; 53 | var tmp = start.split(" "); 54 | $("#date_form input[name=startdate]").val(tmp[0]); 55 | $("#tw_form input[name=twstart]").val(tmp[1]); 56 | tmp = end.split(" "); 57 | $("#date_form input[name=enddate]").val(tmp[0]); 58 | $("#tw_form input[name=twend]").val(tmp[1]); 59 | } 60 | } 61 | 62 | function checkDate(type) { 63 | if ($("#date_form input[name=startdate]").val() > $("#date_form input[name=enddate]").val()) 64 | type == "start" ? $("#date_form input[name=enddate]").val($("#date_form input[name=startdate]").val()) : 65 | $("#date_form input[name=startdate]").val($("#date_form input[name=enddate]").val()); 66 | $("select[name=typesel]").triggerHandler("change"); 67 | } 68 | 69 | function diffDate(date1, date2) { 70 | var diff1 = new Date(); 71 | var diff2 = new Date(); 72 | var pattern = new RegExp("([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})"); 73 | var matched = pattern.exec(date1); 74 | if (matched) { 75 | diff1.setFullYear(matched[1]); 76 | diff1.setMonth(matched[2] - 1); 77 | diff1.setDate(matched[3]); 78 | diff1.setHours(matched[4]); 79 | diff1.setMinutes(matched[5]); 80 | diff1.setSeconds(matched[6]); 81 | } 82 | matched = pattern.exec(date2); 83 | if (matched) { 84 | diff2.setFullYear(matched[1]); 85 | diff2.setMonth(matched[2] - 1); 86 | diff2.setDate(matched[3]); 87 | diff2.setHours(matched[4]); 88 | diff2.setMinutes(matched[5]); 89 | diff2.setSeconds(matched[6]); 90 | } 91 | return (Math.ceil(diff1.getTime()-diff2.getTime())); 92 | } 93 | -------------------------------------------------------------------------------- /css/basic.css: -------------------------------------------------------------------------------- 1 | /* * HTML tags customization ************************************************ */ 2 | html { 3 | height: 100%; 4 | overflow-y: auto; 5 | } 6 | 7 | body { 8 | height: 100%; 9 | font-family: sans-serif; 10 | font-size: 10pt; 11 | margin: 0px; 12 | padding: 0px; 13 | } 14 | 15 | h1 { 16 | font-size: 1.6em; 17 | padding: 0; 18 | margin: 0; 19 | text-align: center; 20 | } 21 | 22 | h2 { 23 | font-size: 1.2em; 24 | padding: 0; 25 | margin: 0; 26 | font-weight: normal; 27 | } 28 | 29 | h3 { 30 | font-size: 1.0em; 31 | padding: 0; 32 | margin: 0 0 5px 0; 33 | font-weight: bold; 34 | /*font-style: italic;*/ 35 | } 36 | 37 | hr { 38 | margin: 0; 39 | padding: 0; 40 | } 41 | 42 | p { 43 | margin: 0px; 44 | padding: 0; 45 | } 46 | 47 | /* ************************************************************************** */ 48 | 49 | /* * Top page elements ****************************************************** */ 50 | #holder { 51 | margin: auto; 52 | width: 1024px; 53 | min-height: 100%; 54 | position: relative; 55 | } 56 | 57 | #header { 58 | padding: 10px; 59 | margin: auto; 60 | width: 1024px; 61 | clear: both; 62 | } 63 | 64 | #menu { 65 | padding: 0; 66 | margin: auto; 67 | width: 1024px; 68 | clear: both; 69 | } 70 | 71 | #contents { 72 | margin: auto; 73 | width: 1024px; 74 | border: 0px Solid black; 75 | padding: 15px 0 20px 0; /* 20px = height of footer */ 76 | clear: both; 77 | } 78 | 79 | #footer { 80 | width: 1024px; 81 | height: 20px; 82 | position: absolute; 83 | bottom: 0px; 84 | margin: auto; 85 | padding-top: 15px; 86 | text-align: center; 87 | clear: both; 88 | } 89 | /* ************************************************************************** */ 90 | 91 | /* * Main Boxes on contents section ***************************************** */ 92 | #menu ul { 93 | padding:0px; 94 | margin: 5px 0 0 0; 95 | list-style:none; 96 | } 97 | 98 | #menu ul li { 99 | display: inline; 100 | } 101 | 102 | #menu ul li a { 103 | padding: 0 5px 0 0; 104 | display: inline-block; 105 | } 106 | 107 | #menu ul li.last { 108 | padding: 0 0 0 5px; 109 | float: right; 110 | } 111 | 112 | #contents .right { 113 | width: 744px; 114 | float: right; 115 | clear: right; 116 | } 117 | 118 | #contents .all { 119 | width: 100%; 120 | margin: auto auto; 121 | clear: left; 122 | } 123 | 124 | #contents .left { 125 | width: 280px; 126 | float: left; 127 | clear: left; 128 | } 129 | 130 | #contents .right .box { 131 | margin: 0 0 5px 5px; 132 | } 133 | 134 | #contents .left .box { 135 | margin: 0 5px 5px 0; 136 | } 137 | 138 | #contents .all .box { 139 | margin: 0 0 5px 0; 140 | } 141 | 142 | /* ************************************************************************** */ 143 | 144 | /* * Modules customization ************************************************** */ 145 | .right .titlebox { 146 | border: 1px Solid black; 147 | border-top-right-radius: .5em; 148 | padding: 5px 10px 5px 10px; 149 | background: #00899F; 150 | } 151 | 152 | .left .titlebox { 153 | border: 1px Solid black; 154 | border-top-left-radius: .5em; 155 | padding: 5px 10px 5px 10px; 156 | background: #00899F; 157 | } 158 | 159 | .all .titlebox { 160 | border: 1px Solid black; 161 | border-top-left-radius: .5em; 162 | border-top-right-radius: .5em; 163 | padding: 5px 10px 5px 10px; 164 | background: #00899F; 165 | text-align: left; 166 | } 167 | 168 | .help { 169 | padding: 2px; 170 | text-align: right; 171 | color: #dddddd; 172 | font-size: 0.85em; 173 | } 174 | 175 | .frame { 176 | border-left: 1px Solid black; 177 | border-right: 1px Solid black; 178 | border-bottom: 1px Solid black; 179 | min-height: 100px; 180 | padding: 10px; 181 | } 182 | 183 | .consoleframe { 184 | border-left: 1px Solid black; 185 | border-right: 1px Solid black; 186 | border-bottom: 1px Solid black; 187 | height: 500px; 188 | overflow-y: auto; 189 | padding: 10px; 190 | margin-bottom: 10px; 191 | text-align: left; 192 | } 193 | 194 | .statusframe { 195 | border-left: 1px Solid black; 196 | border-right: 1px Solid black; 197 | border-bottom: 1px Solid black; 198 | min-height: 100px; 199 | padding: 1px 10px 0px 10px; 200 | display: none; 201 | } 202 | 203 | .clear { 204 | clear: both; 205 | } 206 | 207 | .tab { 208 | display: none; 209 | } 210 | 211 | /* ************************************************************************** */ 212 | 213 | /* * Rolling mouse cursor *************************************************** */ 214 | body.busy, body.busy * { 215 | cursor: wait !important; 216 | } 217 | 218 | /* ************************************************************************** */ 219 | -------------------------------------------------------------------------------- /doc/_toReview/source/beta-testers.txt: -------------------------------------------------------------------------------- 1 | * MG - 30.08.2013 - Rev. 10614 2 | 3 | After selecting some events and work with them in the list located in the main part of the screen, she had to make another selection. The pop-up message that appeared confused her for some time, but she correctly pressed the OK button when asked about replacing the current selection with the new one. 4 | 5 | It took the user some seconds to find the place where the events catalog is selected. Mainly because it works from the start with a default catalog. However, she could solve it without help. 6 | 7 | It was a for the user almost impossible to select properly the region near Tonga. It was not clear if negative or positive coordinates should be used. There is no clear indication that negative values means West. Same with South. 8 | There is also no way for the user to know that they can use the Shift-click combination to select a region from the map. 9 | 10 | The selected station/network on the left part of the page (drop-down lists/menus) was lost when the start/end years were changed. This lead to wrong results in the query. The user felt that she had already selected a network and after that was surprised to see that so many streams from all the networks had been included in the result. 11 | 12 | It was difficult to select a lapse of only one year for the stations. Mainly because of the current control (slider). It is also not clear whether the "End year" is included or not in the search. 13 | 14 | The P&S phase arrival time was not found by the user, even when she realized that this "was missing in the system because she needs it to request the information". 15 | 16 | When ca. 1000 stations were in the list and shown in the map, it was almost impossible to select another region with the mouse. The system turned slow and somehow irresponsive. 17 | 18 | It was difficult to filter the non-vertical components of the streams out of the list. After one minute searching, the "Advance filter" was found and was used quite intuitively. 19 | 20 | After submission the user expects to receive an email to be able to download the information. This seems to be caused by two factors. First, the email is mandatory, because it is used as the username. But second, and most important, there is no indication from the system telling the user that he/she can already check the status of the request and/or download the information by clicking on the "next tab" (Download data). As the system was so silent, the user went to the mail client to see the incoming emails. When nothing new appeared after some seconds, the user thought that the request was possibly being processed. 21 | 22 | When asked to download the information, the user never clicked the "Package XXXXX..." line. She didn't even notice that this was clickable. The intuitive way to do it was to enter *again* the email account in the "Manage Requests" control. 23 | 24 | When the details of the request was displayed, the user found many buttons to do multiple actions but NONE of them was to download the data. To do it, the user had to dig into the text and click a hardly visible green link. It was also imposible to realize that the "plus" sign to show the lines included in the request was clickable. 25 | 26 | When the user had to request inventory information from stations for 2012 and 2013, the "Submit request" was unfortunately selected/visible from the beginning and the user tried to select the time range by means of the controls in the "Absolute time" section, despite that NO event was selected. 27 | 28 | After solving this confusion and when the time range was properly introduced, the request was unsuccessful because the 10000 lines limit was reached. However, this should not be checked when asking inventory XML data, shouldn't it? 29 | 30 | --- 31 | 32 | 33 | * VH, 17.09.2013 34 | 35 | Still the confusing "Request is Empty, Delete Request?" box. 36 | 37 | Need: negative numbers for south, west [DONE, 2013-10-04] 38 | 39 | When you drag a new region, the 40 | Lat, lon text don't get updated, even though the region changes. 41 | 42 | "Code" should be "Network" not ("All Networks") but the user found it in the end. 43 | 44 | Station TABLE shows no station description. Also not on the map. 45 | [For table, this is hard: no descriptions available in request.js; 46 | for map, no description in createStationFeature in mapping.js] 47 | 48 | Searching for sample rate "near" 46 Hz gave 49 | SH for BKB, BKNI, but BH for BOAB, DAG. Why? 50 | 51 | "Make request" tab would sound nicer than "Submit request" 52 | 53 | Again, on submitting request, the feeling that nothing happens! 54 | Sees the blinking text. "Click to open" needs a big "[+]" DONE. 55 | 56 | Network XF: The map pop-up for a station should show start:, end: dates, if convenient. 57 | [HARD: This may not be known by the JS - dates are for streams??] 58 | -------------------------------------------------------------------------------- /wsgi/wsgicomm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Resources to communicate via a WSGI module 4 | # 5 | # Begun by Javier Quinteros, GEOFON team, June 2013 6 | # 7 | # 8 | # ---------------------------------------------------------------------- 9 | 10 | 11 | """Functions and resources to communicate via a WSGI module 12 | 13 | Copyright (C) 2013 GEOFON team, Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 14 | 15 | The list of functions in this module and the information it returns is: 16 | - query: different network types (the name should change. See what returns.) 17 | 18 | The internal functions are: 19 | - __init_session: triple containing session-key, username and password. 20 | 21 | This program is free software; you can redistribute it and/or modify it 22 | under the terms of the GNU General Public License as published by the 23 | Free Software Foundation; either version 2, or (at your option) any later 24 | version. For more information, see http://www.gnu.org/ 25 | 26 | """ 27 | 28 | 29 | ################################################################## 30 | # 31 | # Exceptions to be caught (usually) by the application handler 32 | # 33 | ################################################################## 34 | 35 | 36 | class PlsRedirect(Exception): 37 | """Exception to signal that the web client should be redirected to a new URL. 38 | 39 | The constructor of the class receives a string, which is the 40 | URL where the web browser is going to be redirected. 41 | 42 | Begun by Javier Quinteros , GEOFON team, June 2013 43 | 44 | """ 45 | 46 | def __init__(self, url): 47 | self.url = url 48 | def __str__(self): 49 | return repr(self.url) 50 | 51 | 52 | class WIError(Exception): 53 | """Exception to signal that an error occurred while doing something, that the web client should see. 54 | 55 | Inputs: 56 | status - string, like "200 Good", "400 Bad" 57 | body - string, plain text content to display to the client 58 | verbosity - integer, 0 = silent, 4 = debug 59 | 60 | """ 61 | 62 | def __init__(self, status, body, verbosity = 1): 63 | self.status = status 64 | self.body = body 65 | self.verbosity = verbosity 66 | 67 | def __str__(self): 68 | return repr(self.status)+': '+repr(self.body) # body but not verbosity(?) 69 | 70 | 71 | class WIContentError(WIError): 72 | def __init__(self, *args, **kwargs): 73 | WIError.__init__(self, "204 No Content", *args, **kwargs) 74 | 75 | 76 | class WIClientError(WIError): 77 | def __init__(self, *args, **kwargs): 78 | WIError.__init__(self, "400 Bad Request", *args, **kwargs) 79 | 80 | 81 | class WIInternalError(WIError): 82 | def __init__(self, *args, **kwargs): 83 | WIError.__init__(self, "500 Internal Server Error", *args, **kwargs) 84 | 85 | 86 | class WIServiceError(WIError): 87 | def __init__(self, *args, **kwargs): 88 | WIError.__init__(self, "503 Service Unavailable", *args, **kwargs) 89 | 90 | 91 | ################################################################## 92 | # 93 | # Functions to send a response to the client 94 | # 95 | ################################################################## 96 | 97 | def redirect_page(url, start_response): 98 | """Tells the web client through the WSGI module to redirect to an URL. 99 | 100 | Begun by Javier Quinteros , GEOFON team, June 2013 101 | 102 | """ 103 | 104 | response_headers = [('Location', url)] 105 | start_response('301 Moved Permanently', response_headers) 106 | return '' 107 | 108 | def send_html_response(status, body, start_response): 109 | """Sends an HTML response in WSGI style. 110 | 111 | Begun by Javier Quinteros , GEOFON team, June 2013 112 | 113 | """ 114 | 115 | response_headers = [('Content-Type', 'text/html; charset=UTF-8'), 116 | ('Content-Length', str(len(body)))] 117 | start_response(status, response_headers) 118 | return [ body ] 119 | 120 | def send_plain_response(status, body, start_response): 121 | """Sends a plain response in WSGI style. 122 | 123 | Begun by Javier Quinteros , GEOFON team, June 2013 124 | 125 | """ 126 | 127 | response_headers = [('Content-Type', 'text/plain'), 128 | ('Content-Length', str(len(body)))] 129 | start_response(status, response_headers) 130 | return [ body ] 131 | 132 | def send_file_response(status, body, start_response): 133 | """Sends a file or similar object. 134 | 135 | Caller must set the filename, size and content_type attributes of body. 136 | 137 | """ 138 | response_headers = [('Content-Type', body.content_type), 139 | ('Content-Length', str(body.size)), 140 | ('Content-Disposition', 'attachment; filename=%s' % (body.filename))] 141 | start_response(status, response_headers) 142 | return body 143 | 144 | -------------------------------------------------------------------------------- /examples/generic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Arclink WebDC3 Web Interface 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 46 | 47 | 62 | 63 |
64 |
65 |
66 |
67 |

Console

68 |
Warnings and other messages appear here.
69 |
70 |
71 |
72 | 73 |
74 |
75 |

FDSNWS Requests

76 |
Here you can see the status of your FDSNWS requests and download data volumes.
77 |
78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |

Events Controls

86 |
Use this to select events to compose your request.
87 |
88 |
89 |
90 | 91 |
92 |
93 |

Stations Controls

94 |
Use this to add channels to your request. The selection can be made based on the currently selected events or by network/station codes.
95 |
96 |
97 |
98 | 99 |
100 |
101 |

Submit

102 |
Use this control to submit your request.
103 |
104 |
105 |
106 |
107 | 108 |
109 |
110 |
111 |

Event and Station Map

112 |
Here the events and stations you choose will be displayed. Use the mouse to drag the map around. Use the Ctrl-Mouse to draw areas for limiting the search of events and stations when the appropriate modules are enabled.
113 |
114 |
115 |
116 | 117 |
118 |
119 |

Event and Station List

120 |
Use these tables to check which events and stations have been selected by your search criteria. You can interactively remove unwanted items. Your final request will be built from the currently displayed information.
121 |
122 |
123 |
124 |
125 | 126 |
127 |
128 | 129 | 132 |
133 | 134 | 135 | -------------------------------------------------------------------------------- /test/test_inv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # test_inv_load 3 | # 4 | # How big might a JSON file for our inventory be? 5 | # 6 | # Begun by Peter L. Evans, June 2013 7 | # 8 | # 9 | # ---------------------------------------------------------------------- 10 | 11 | import datetime 12 | import doctest 13 | import json 14 | import os 15 | import tempfile 16 | import uuid # just for some random strings 17 | 18 | def nslc_str(net, sta="---", loc="--", cha="---"): 19 | """Fixed-width string for a stream""" 20 | return "%16s" % (".".join([net, sta, loc, cha])) 21 | 22 | 23 | class InventoryLite(): 24 | def __init__(self, nets, stas, locs, chas): 25 | """Prepare phony text-based inventory. 26 | 27 | Inputs: 28 | nets, stas, locs, chas - int, the number of each to create. 29 | 30 | >>> inv = InventoryLite(4, 3, 1, 3) 31 | >>> print inv 32 | InventoryLite with 4 net(s) 33 | 34 | >>> inv = InventoryLite(2, 2, 1, 3) 35 | >>> print len(inv.dump_json()) 36 | Dump_json: InventoryLite with 2 net(s) 37 | 2116 38 | 39 | """ 40 | self.inventory = {} 41 | for n in range(nets): 42 | net_name = "N%i" % n 43 | net_attrs = "Network %s description archive shared restricted" % net_name 44 | s_dict = {} 45 | for s in range(stas): 46 | sta_name = "S%02i" % s 47 | sta_attrs = "Station %s begin end lat lon elev depth etc" % sta_name 48 | l_dict = {} 49 | for l in range(locs): 50 | loc_name = "%1i0" % l # Don't use more than 10 locids! 51 | if l == locs-1: 52 | # Make sure there's an empty location code: 53 | loc_name = "" 54 | loc_attrs = "begin end lat lon elev depth" 55 | c_dict = {} 56 | for c in range(chas): 57 | cha_name = "B%02i" % c 58 | val1 = uuid.uuid4() 59 | val2 = uuid.uuid4() 60 | cha_attrs = "%s digitizer %s sensor %s sample rate type etc " % (cha_name, val1, val2) 61 | c_dict[cha_name] = (cha_attrs, {}) 62 | 63 | l_dict[loc_name] = (loc_attrs, c_dict) 64 | s_dict[sta_name] = (sta_attrs, l_dict) 65 | self.inventory[net_name] = (net_attrs, s_dict) 66 | 67 | def __repr__(self): 68 | return "InventoryLite with %i net(s)" % len(self.inventory) 69 | 70 | def count(self, level): 71 | """How many objects in inventory? 72 | 73 | >>> inv = InventoryLite(3, 4, 2, 6) 74 | >>> print inv.count('network') 75 | 3 76 | >>> print inv.count('station') 77 | 12 78 | >>> print inv.count('location') 79 | 24 80 | >>> print inv.count('channel') 81 | 144 82 | 83 | """ 84 | sum = 0 85 | if level == 'network': 86 | return len(self.inventory) 87 | elif level == 'station': 88 | for n in self.inventory.keys(): 89 | sum += len(self.inventory[n][1]) 90 | elif level == 'location': 91 | for n in self.inventory.keys(): 92 | s_dict = self.inventory[n][1] 93 | for s in s_dict.keys(): 94 | sum += len(s_dict[s][1]) 95 | elif level == 'channel': 96 | for n in self.inventory.keys(): 97 | s_dict = self.inventory[n][1] 98 | for s in s_dict.keys(): 99 | l_dict = s_dict[s][1] 100 | for l in l_dict.keys(): 101 | sum += len(l_dict[l][1]) 102 | return sum 103 | 104 | def dump_json(self, indent=None): 105 | print "Dump_json:", self.__repr__() 106 | return json.dumps(self.inventory, indent=indent) 107 | 108 | def load_json(self, fid): 109 | """Deserialise to inventory. 110 | 111 | Inputs: 112 | fid - file-like object containing a JSON document. 113 | 114 | No checking! 115 | """ 116 | tmp = json.load(fid) 117 | if len(tmp) > 0: 118 | self.inventory = tmp 119 | return 120 | 121 | def dump(self): 122 | """Does lots of sorting.""" 123 | 124 | result = "" 125 | crlf = "\n" 126 | for n in sorted(self.inventory.keys()): 127 | net = self.inventory[n] 128 | result += nslc_str(n) + "Network: " + net[0] + crlf 129 | s_dict = net[1] 130 | for s in sorted(s_dict.keys()): 131 | sta = s_dict[s] 132 | result += nslc_str(n, s) + "Station: " + sta[0] + crlf 133 | l_dict = sta[1] 134 | for l in sorted(l_dict.keys()): 135 | loc = l_dict[l] 136 | result += nslc_str(n, s, l) + "Location:" + loc[0] + crlf 137 | c_dict = loc[1] 138 | for c in sorted(c_dict.keys()): 139 | cha = c_dict[c] 140 | result += nslc_str(n, s, l, c) + "Channel:" + cha[0] + crlf 141 | return result 142 | 143 | 144 | if __name__ == '__main__': 145 | doctest.testmod() 146 | inv = InventoryLite(150, 40, 3, 12) 147 | print inv 148 | print "Networks:", inv.count('network') 149 | print "Stations:", inv.count('station') 150 | print "Locations:", inv.count('location') 151 | print "Channels:", inv.count('channel') 152 | 153 | 154 | #fid = tempfile.TemporaryFile() 155 | 156 | filename = 'test_inv.json' 157 | 158 | # Write out... 159 | t_start = datetime.datetime.now() 160 | fid = open(filename, 'w') 161 | print >>fid, inv.dump_json(indent = None) 162 | fid.close() 163 | print "Dump took", datetime.datetime.now() - t_start 164 | print "Dump file is", os.stat(filename).st_size, "bytes." 165 | 166 | # Read back in... 167 | t_start = datetime.datetime.now() 168 | fid = open(filename, 'r') 169 | inv = InventoryLite(0, 0, 0, 0) 170 | inv.load_json(fid) 171 | print "Restore took", datetime.datetime.now() - t_start 172 | print "Networks:", inv.count('network') 173 | print "Stations:", inv.count('station') 174 | print "Locations:", inv.count('location') 175 | print "Channels:", inv.count('channel') 176 | 177 | -------------------------------------------------------------------------------- /src/console.js: -------------------------------------------------------------------------------- 1 | /* 2 | * GEOFON WebInterface 3 | * 4 | * console.js: Logging functions. 5 | * 6 | * Begun by: 7 | * Marcelo Bianchi, Peter Evans, Javier Quinteros, Andres Heinloo, GFZ Potsdam 8 | * June/July 2013 9 | * 10 | * Copyright (C) 2013- GEOFON team, Helmholtz-Zentrum Potsdam - Deutsches GeoForschungsZentrum GFZ 11 | */ 12 | 13 | /* 14 | * Implementation of the wiConsole 15 | */ 16 | function WIConsole(htmlTagId) { 17 | 18 | // Private 19 | 20 | var _controlDiv = null 21 | var _callback = null 22 | var _maxMessages = 100 23 | var _level = 0 24 | var _msgClass = 'wi-console-debug' 25 | 26 | function load(htmlTagId) { 27 | var control = $(htmlTagId) 28 | 29 | // If we don't find one div ... 30 | if (control.length !== 1) { 31 | if (interfaceLoader.debug()) console.error("console.js: Cannot find a div with class '" + htmlTagId + "'") 32 | return 33 | } 34 | 35 | // otherwise finish load ... 36 | _controlDiv = control 37 | } 38 | 39 | function log(msgClass, msg, exc) { 40 | var msgList = _controlDiv.children() 41 | 42 | if (!msgList.length) { 43 | // Append a clear console link as the first element 44 | _controlDiv.append('') 45 | } 46 | 47 | if (msgList.length >= _maxMessages + 1) 48 | msgList.eq(1).remove() 49 | 50 | var msgDiv = $('
') 51 | msgDiv.text(msg) 52 | _controlDiv.append(msgDiv) 53 | 54 | if (typeof exc != 'undefined' && typeof printStackTrace != 'undefined') { 55 | var trace = printStackTrace({e: exc}) 56 | 57 | for (var i in trace) { 58 | if (msgList.length >= _maxMessages + 1) 59 | msgList.eq(1).remove() 60 | 61 | msgDiv = $('
') 62 | msgDiv.text(trace[i]) 63 | _controlDiv.append(msgDiv) 64 | } 65 | } 66 | 67 | _controlDiv.prop('scrollTop', _controlDiv.prop('scrollHeight')) 68 | } 69 | 70 | // Public 71 | 72 | this.debug = function debug(msg, exc) { 73 | var msgClass = 'wi-console-debug' 74 | 75 | if (_controlDiv) { 76 | try { 77 | log(msgClass, msg, exc) 78 | return 79 | } 80 | catch (e) { 81 | alert("console.js: " + e.message) 82 | } 83 | } 84 | 85 | if (console.debug !== debug) 86 | console.debug(msg) 87 | } 88 | 89 | this.info = function info(msg, exc) { 90 | var msgClass = 'wi-console-info' 91 | 92 | if (_level < 1) { 93 | _level = 1 94 | _msgClass = msgClass 95 | 96 | try { 97 | if (_callback) _callback(_level, msgClass) 98 | } 99 | catch (e) { 100 | alert("console.js: " + e.message) 101 | } 102 | } 103 | 104 | if (_controlDiv) { 105 | try { 106 | log(msgClass, msg, exc) 107 | return 108 | } 109 | catch (e) { 110 | alert("console.js: " + e.message) 111 | } 112 | } 113 | 114 | if (console.info !== info) 115 | console.info(msg) 116 | } 117 | 118 | this.notice = function notice(msg, exc) { 119 | var msgClass = 'wi-console-notice' 120 | 121 | if (_level < 2) { 122 | _level = 2 123 | _msgClass = msgClass 124 | 125 | try { 126 | if (_callback) _callback(_level, msgClass) 127 | } 128 | catch (e) { 129 | alert("console.js: " + e.message) 130 | } 131 | } 132 | 133 | if (_controlDiv) { 134 | try { 135 | log(msgClass, msg, exc) 136 | return 137 | } 138 | catch (e) { 139 | alert("console.js: " + e.message) 140 | } 141 | } 142 | 143 | if (console.log !== notice) 144 | console.log(msg) 145 | } 146 | 147 | this.warning = function warning(msg, exc) { 148 | var msgClass = 'wi-console-warning' 149 | 150 | if (_level < 3) { 151 | _level = 3 152 | _msgClass = msgClass 153 | 154 | try { 155 | if (_callback) _callback(_level, msgClass) 156 | } 157 | catch (e) { 158 | alert("console.js: " + e.message) 159 | } 160 | } 161 | 162 | if (_controlDiv) { 163 | try { 164 | log(msgClass, msg, exc) 165 | return 166 | } 167 | catch (e) { 168 | alert("console.js: " + e.message) 169 | } 170 | } 171 | 172 | if (console.warn !== warning) 173 | console.warn(msg) 174 | } 175 | 176 | this.error = function error(msg, exc) { 177 | var msgClass = 'wi-console-error' 178 | 179 | if (_level < 4) { 180 | _level = 4 181 | _msgClass = msgClass 182 | 183 | try { 184 | if (_callback) _callback(_level, msgClass) 185 | } 186 | catch (e) { 187 | alert("console.js: " + e.message) 188 | } 189 | } 190 | 191 | if (_controlDiv) { 192 | try { 193 | log(msgClass, msg, exc) 194 | return 195 | } 196 | catch (e) { 197 | alert("console.js: " + e.message) 198 | } 199 | } 200 | 201 | if (console.error !== error) 202 | console.error(msg) 203 | } 204 | 205 | this.clear = function() { 206 | // Clear the console 207 | _controlDiv.children().remove() 208 | } 209 | 210 | // Scrolling doesn't work while the console is invisible, so we add an 211 | // extra method to be called after the console is displayed 212 | this.scrollToBottom = function() { 213 | _controlDiv.prop('scrollTop', _controlDiv.prop('scrollHeight')) 214 | } 215 | 216 | this.resetLevel = function() { 217 | _level = 0 218 | _msgClass = 'wi-console-debug' 219 | } 220 | 221 | this.level = function() { 222 | return _level 223 | } 224 | 225 | this.setCallback = function(callback) { 226 | _callback = callback 227 | _callback(_level, _msgClass) 228 | } 229 | 230 | // Load the object into the HTML page 231 | load(htmlTagId) 232 | } 233 | 234 | /* 235 | * Export for main.js 236 | */ 237 | export default function() { 238 | return new Promise(function(resolve, reject) { 239 | try { 240 | window.wiConsole = new WIConsole("#wi-Console") 241 | 242 | // Define console object for old browsers, so we at least 243 | // might have a chance to see some errors 244 | if (window.console === undefined) 245 | window.console = {} 246 | 247 | if (window.console.debug === undefined) 248 | window.console.debug = wiConsole.debug 249 | 250 | if (window.console.info === undefined) 251 | window.console.info = wiConsole.info 252 | 253 | if (window.console.log === undefined) 254 | window.console.log = wiConsole.notice 255 | 256 | if (window.console.warn === undefined) 257 | window.console.warn = wiConsole.warning 258 | 259 | if (window.console.error === undefined) 260 | window.console.error = wiConsole.error 261 | 262 | window.onerror = function(errorMsg, url, lineNumber) { 263 | if (interfaceLoader.debug()) 264 | window.wiConsole.error(errorMsg + ' (' + url + ':' + lineNumber + ')') 265 | else 266 | window.wiConsole.error(errorMsg) 267 | } 268 | 269 | resolve() 270 | } 271 | catch (e) { 272 | alert("console.js: " + e.message) 273 | reject() 274 | } 275 | }) 276 | } 277 | 278 | -------------------------------------------------------------------------------- /examples/webdc2012/webdc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WebDC - retro version 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 47 | 52 | 53 |
35 | 36 | 37 | 38 | 40 | 41 | 42 | WebDC - Integrated Seismological Data Portal 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 |
54 | 55 | 56 | 57 | 60 | 61 |
58 | Common Data Portal for GFZ Potsdam, German and European Seismological Data Archives 59 |
62 | 63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 80 | 81 |
New RequestCheck StatusHelp
82 | 83 |
84 | 85 |
86 |
87 |
88 |
89 |

Event and Station Map

90 |
Double-click to zoom in, and drag to pan. Hold down the shift key and drag to select a region.
91 |
92 |
93 |
94 | 95 |
96 |
97 |

Event and Station List

98 |
Use these tables to check which events and stations have been selected by your search criteria. You can interactively remove unwanted items. Your final request will be built from the currently displayed information.
99 |
100 |
101 |
102 | 103 |
104 |
105 |

Request status

106 |
Here you can check the status and download your request.
107 |
108 |
109 |
110 | 111 |
112 |
113 |

Console

114 |
Warnings and other messages appear here.
115 |
116 |
117 |
118 |
119 | 120 |
121 |
122 |
123 |

Select events

124 |
Select events to compose your request.
125 |
126 |
127 |
128 | 129 |
130 |
131 |

Select stations

132 |
Use this to add channels to your request. The selection can be made according to the current selected events or by network/station codes.
133 |
134 |
135 |
136 | 137 |
138 |
139 |

Submit

140 |
Use this to submit your request to webdc.eu for processing.
141 |
142 |
143 |
144 |
145 |
146 |
147 | 148 |
149 |
150 | Optimized for Firefox 3.x! In case of problems use the old WebDC portal
Contact: eida@gfz-potsdam.de 151 |
152 | 153 | 154 | -------------------------------------------------------------------------------- /test/testMetadata.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import unittest 4 | import urllib 5 | import urllib2 6 | import urlparse 7 | 8 | sys.path.append(os.path.join('..', 'wsgi')) # for wsgicomm 9 | sys.path.append(os.path.join('..', 'wsgi', 'modules')) 10 | 11 | import metadata 12 | import webinterface # Gets too much?? Should I reimplement WebInterface here??? 13 | import wsgicomm 14 | 15 | from testHelpers import * 16 | 17 | test_verbosity = 0 # How noisy should the *unittests* be? 18 | 19 | 20 | # ---------------------------------------------------------------------- 21 | class TestMetadata(unittest.TestCase): 22 | def test_networktypes0(self): 23 | params = "" 24 | qs = '&'.join(params) 25 | env = {'PATH_INFO': 'metadata/networktypes', 'QUERY_STRING': qs} 26 | params = cgi.parse_qs(qs) 27 | nt = mod.networktypes(env, params) 28 | self.assertGreater(count_json_obj(nt), 0) 29 | 30 | def test_sensortypes0(self): 31 | params = "" 32 | qs = '&'.join(params) 33 | env = {'PATH_INFO': 'metadata/sensortypes', 'QUERY_STRING': ''} 34 | params = cgi.parse_qs(qs) 35 | st = mod.sensortypes(env, params) 36 | self.assertGreater(count_json_obj(st), 0) 37 | 38 | # TODO: 39 | # Test each function with no arguments. 40 | def test_networks0(self): 41 | pass 42 | 43 | def test_stations0(self): 44 | pass 45 | 46 | def test_streams0(self): 47 | pass 48 | 49 | def test_query0(self): 50 | pass 51 | 52 | 53 | class TestMetadata2(unittest.TestCase): 54 | """Tests with a running service. You can use 55 | 56 | >>> python manage.py -p 8008 57 | 58 | to start the stand-alone server, but this is not ideal. 59 | The setUp method could do it, but then it would be started and 60 | stopped for each test ==> SLOW. Perhaps it could start only if not 61 | already running. 62 | Also needed: some reference metadata. 63 | 64 | """ 65 | 66 | def setUp(self): 67 | self.service_url = 'http://localhost:8008/' 68 | fd = None 69 | try: 70 | print "Trying", self.service_url, '...', 71 | fd = urllib2.urlopen(self.service_url) 72 | except urllib2.HTTPError as err: 73 | if err.code == 404: 74 | print '404 is okay, service is running.' 75 | return 76 | 77 | except urllib2.URLError as err: 78 | if fd: 79 | code = fd.getcode() 80 | print 'Got', code 81 | if code == 404: 82 | print '404 is okay, service is running.' 83 | else: 84 | print 'Unexpected response at %s!' % (self.service_url) 85 | raise err 86 | else: 87 | print 'No service found at %s!' % (self.service_url) 88 | raise err 89 | 90 | def test_sequence(self): 91 | """A typical sequence: find the channel types at GE.IMMV. 92 | 93 | This requires a running web service. 94 | """ 95 | fd = urllib2.urlopen(self.service_url + 'metadata/networks') 96 | response = fd.read() 97 | # Expect a long JSON list. 98 | self.assertGreater(len(response), 10) 99 | 100 | fd = urllib2.urlopen(self.service_url + 'metadata/stations?network=GE-1993-None') 101 | response = fd.read() 102 | # Expect a long list of stations. 103 | self.assertGreater(len(response), 10) 104 | 105 | fd = urllib2.urlopen(self.service_url + 'metadata/streams?station=GE-1993-None-IMMV') 106 | response = fd.read() 107 | resp = json.loads(response) 108 | # Expect a list like this: 109 | expected = [u'BH', u'HH', u'HN', u'LH', u'SH', u'VH'] 110 | self.assertListEqual(sorted(resp), sorted(expected)) 111 | 112 | 113 | # ---------------------------------------------------------------------- 114 | 115 | class TestMetadataTimewindows(unittest.TestCase): 116 | 117 | def test_timewindows0(self): 118 | params = ('start=2013-04-01', 'end=2013-04-30') 119 | qs = '&'.join(params) 120 | env = {'PATH_INFO': 'metadata/timewindows', 'QUERY_STRING': qs} 121 | params = cgi.parse_qs(qs) 122 | 123 | # Requires Python >= 2.7?: 124 | with self.assertRaises(wsgicomm.WIClientError) as cm: 125 | response = mod.timewindows(env, params) 126 | if test_verbosity: 127 | print response 128 | response = cm.exception 129 | if test_verbosity: 130 | print "Exception body: ", response.body 131 | print "Exception mesg: ", response.message 132 | print "Exception args: ", response.args 133 | 134 | #self.assertEqual(len(response), 2) 135 | #self.assertEqual(response[0], '400 Bad Request') 136 | #self.assertGreater(response[1].find('invalid streams'), -1) 137 | self.assertGreater(response.body.find('missing streams'), -1) 138 | 139 | def test_timewindows1(self): 140 | """Call timewindows with one stream.""" 141 | 142 | params = {'start': '2013-04-01T00:00:00Z', 143 | 'end':'2013-04-30T00:00:00Z', 144 | 'streams': "[" + json.dumps(["GE","APE","BHZ",""]).replace(" ", "") + "]"} 145 | 146 | qs = urllib.urlencode(params) 147 | env = {'PATH_INFO': 'metadata/timewindows', 'QUERY_STRING': qs} 148 | 149 | response = mod.timewindows(env, params) 150 | if test_verbosity: 151 | print "QS:", qs 152 | print "params:", params 153 | print "Response:", response 154 | 155 | self.assertGreater(count_json_obj(response), 0) 156 | if test_verbosity: 157 | print json.loads(response) 158 | 159 | # ---------------------------------------------------------------------- 160 | 161 | #wi = webinterface.WebInterface(__name__) # Would be nice, but needs config 162 | wi = webinterface.WebInterface('webinterface') 163 | mod = metadata.WI_Module(wi) 164 | 165 | # ---------------------------------------------------------------------- 166 | 167 | if __name__ == '__main__': 168 | 169 | suite = None 170 | # Uncomment one of the following to test just that class: 171 | #suite = unittest.TestLoader().loadTestsFromTestCase(TestMetadata2) 172 | 173 | if suite: 174 | result = unittest.TextTestRunner().run(suite) 175 | else: 176 | result = unittest.main().result 177 | 178 | num_run = result.testsRun 179 | num_failures = len(result.failures) 180 | num_errors = len(result.errors) 181 | 182 | if num_errors == 0 and num_failures == 0: 183 | print "Hooray, no errors or failures found. Have an early dinner!" 184 | else: 185 | print "%i Error(s) %i failure(s) found, %i run." % (num_errors, num_failures, num_run) 186 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Problems 2 | ~~~~~~~~ 3 | 4 | station.js menu - null item for replace(). [Helle P, 2013-09-09] 5 | 6 | doesn't work in Opera [PLE, August 2013] 7 | 8 | Things that need fixing in the short term 9 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | 11 | * Adjust time span for stations if events are given and 'search by events'. 12 | 13 | * Event pull-downs should be 1980 to current year. 14 | 15 | * Events: maximum magnitude option on the web page [JC] 16 | 17 | * Events: display the type of magnitude, if one is available [JC] 18 | 19 | * Install procedure wasn't smooth, if the final URL is other than /webinterface 20 | 21 | * Documentation: 22 | - all tutorial items need to work. 23 | - developer notes clean-up. 24 | - configuration parameter documentation. 25 | 26 | * Dependency on seiscomp/manager.py - what can we do to ease that? 27 | 28 | * beta testing on some users. (In progress, Aug-Sep 2013) 29 | 30 | * The shrink/reduce/refine/delete feature: 31 | request.js - Pack._event_list 32 | 33 | * Logging needs to be turned down. DONE 34 | 35 | * :event: Implement ISC catalog - example URL is 36 | http://www.isc.ac.uk/cgi-bin/web-db-v4?request=COMPREHENSIVE&out_format=CATCSV&searchshape=RECT&bot_lat=0&top_lat=50&left_lon=-30&right_lon=30&ctr_lat=&ctr_lon=&radius=&max_dist_units=deg&srn=&grn=&start_year=2013&start_month=2&start_day=28&start_time=00%3A00%3A00&end_year=2013&end_month=3&end_day=01&end_time=00%3A00%3A00&min_dep=&max_dep=&min_mag=&max_mag=&req_mag_type=Any&req_mag_agcy=Any&include_links=on 37 | 38 | * :event: Read QuakeML e.g. from fdsnws-event 39 | 40 | * :event: Using parse for event catalog - depths are lost again. 41 | - also show a pop-up/console warning if NOTHING was readable. 42 | 43 | * Add webdc.html DONE and basic.html examples. 44 | - ln -s generic.html index.html 45 | - can we move webdc.html and basic.html to examples? 46 | - can we use current openlayers with the webdc.html example? 47 | 48 | * Advanced stream filter - what??? 49 | 50 | * :event/station: Add/trim/filter already-chosen events/stations 51 | 52 | * :event: Don't create temp files! 53 | 54 | * :event: GFZ service - don't allow before 1 August 2007. 55 | 56 | * :event: Still a limit problem - 2x nmax=... on parameters 57 | 58 | * :event: Upload - popup should report accepted, nnn events loaded, separator was, or zero, see console. 59 | 60 | * :view: Should be viewable with JavaScript disabled 61 | 62 | * :event: Circular regions 63 | 64 | * :metadata: Check parameters or raise WIError. 65 | 66 | * :metadata: add JQ's test cases 67 | 68 | * :metadata: query doesn't respect targetsps parameter. 69 | 70 | * Better treatment of static content, 'favicon.ico' etc. 71 | 72 | * Mapping/station list: show start and end dates, for temporary stations, 73 | on the list and/or on their map pop-ups. 74 | 75 | * :mapping: Colour code events by magnitude/depth 76 | 77 | * :python: Log to [wsgi.error] or whatever it's called. DONE? 78 | 79 | Hinted-at features (2013-09-06) 80 | ~~~~~~~~~~~~~~~~~~ 81 | 82 | * Including support for different waveform parameters 83 | e.g. qc, ground motion parameters. 84 | 85 | * Providing download of the station/stream lists, and 86 | supporting selection by uploading such a list. 87 | WH: "Making station/stream lists extendable and providing a download/upload option for these lists to make them re-usable and modifiable." 88 | 89 | * "Circular" region selection as well as "rectangular" 90 | (latitude/longitude boxes). 91 | 92 | * Flexible system of colouring schemes for events. 93 | (depth and magnitude dependent) 94 | 95 | * "Full screen" mode where the map is larger for 96 | better browsing. 97 | 98 | * Warn if the 800 event limit is hit. 99 | 100 | Features, might be nice (2016) 101 | ~~~~~~~~~~~~~~~~~~~~~~~ 102 | 103 | (Feb 2016) Upload an event XML file, and use the pick information 104 | contained in it to select stations (and their time windows, 105 | or use WebDC3's travel time computations). 106 | 107 | Important in the medium term 108 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109 | 110 | * :event: Save/download an event list 111 | 112 | * :metadata: Upload and Save/download a station list 113 | 114 | * Filter station-event pairs by azimuth/backazimuth/distance [FT, Dec 2013] 115 | and/or "station-first" selection: first a station, then appropriate events. 116 | 117 | "Requirements" that are still not implemented 118 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | 120 | * Look up by strong motion data or QC parameters. 121 | 122 | 123 | Nice to have features 124 | ~~~~~~~~~~~~~~~~~~~~~ 125 | 126 | * Produce KML files for station and event lists. [JC, 24 Sept.] 127 | 128 | * DONE? Break up big requests (1000s of lines) into chunks and manage them. 129 | 130 | * Relate present webdc.eu web server stats to user actions: 131 | - are user requests typically event-based or station-based? 132 | 133 | * Richer list of symbols for different event magnitudes/depths, 134 | and use subimages from a symbol sheet. 135 | 136 | * Time window computation: specifying a constant speed/slowness to be 137 | used with the source-receiver distance, or use OT. 138 | 139 | 140 | 141 | Known Problems 142 | ~~~~~~~~~~~~~~ 143 | 144 | Doesn't run over nx? 145 | 146 | Doesn't work on Internet Explorer x.x properly. 147 | 148 | Doesn't work on Opera/Konqueror properly?? 149 | 150 | Isn't properly relocatable? URL should be independent of location in the file system. 151 | 152 | SERVER_FOLDER to server.dir 153 | 154 | 155 | ------------ 156 | -*- org -*- 157 | 158 | Some event-related things that still need doing: 159 | 160 | * TODO Jul 2 - clipping by radius 161 | * TODO Jul 2 - clipping by azimuth 162 | 163 | * TODO July 4 - start on implementing parse POST method for CSV file input 164 | * Reopen/no temp files - partly done, could be better. 165 | * TODO Jul 10 - Filtering for params unimplemented in target service 166 | e.g. circular regions 167 | e.g. depth (for eqinfo) 168 | * TODO Jul 10 - missing data test case can be in EventData class 169 | * DONE Dateline crossing tests. 170 | * Clean up EventServices code 171 | ...in progress, uses WI_Module class. 172 | * TODO Name space - Event* classes to WI_Event* 173 | 174 | * June - where is the 404 page for URLs below /event now? 175 | * TODO Review add event service procedure - use FDSNWS case as test 176 | * DONE :important: EMSC catalog 177 | * NOT NEEDED Build lite JavaScript reader/displayer for presentation side. 178 | 179 | * TODO Get configuration sorted out :important: 180 | event.services.catalog 181 | event.service.[which].descriptions, capabilities ?? 182 | 183 | * DONE Filter by depth and magnitude in eqinfo 184 | * Accept QuakeML input :useful: 185 | * Produce QuakeML output :unimportant: 186 | 187 | * Oops: QUERY_STRING parameters get re-ordered from original request! :unimportant: 188 | * :NOTE: obspy.neries and obspy.(iris fdsn ws) exist ! 189 | 190 | 191 | -------------------------------------------------------------------------------- /tools/jquery-ajax-native.js: -------------------------------------------------------------------------------- 1 | // jQuery Ajax Native Plugin 2 | 3 | // (c) 2015 Tarik Zakaria Benmerar, Acigna Inc. 4 | // jQuery Ajax Native Plugin may be freely distributed under the MIT license. 5 | (function (root, factory) { 6 | if (typeof define === 'function' && define.amd) { 7 | // AMD. Register as an anonymous module. 8 | define(['jquery'], factory); 9 | } else if (typeof exports === 'object') { 10 | // Node. Does not work with strict CommonJS, but 11 | // only CommonJS-like environments that support module.exports, 12 | // like Node. 13 | module.exports = factory(require('jquery')); 14 | } else { 15 | // Browser globals (root is window) 16 | factory(root.jQuery); 17 | } 18 | }(this, function ( $ ) { 19 | var ajaxSettings = $.ajaxSettings; 20 | ajaxSettings.responseFields.native = 'responseNative'; 21 | ajaxSettings.converters[ '* native' ] = true; 22 | var support = {}, 23 | xhrId = 0, 24 | xhrSuccessStatus = { 25 | // file protocol always yields status code 0, assume 200 26 | 0: 200, 27 | // Support: IE9 28 | // #1450: sometimes IE returns 1223 when it should be 204 29 | 1223: 204 30 | }, 31 | xhrCallbacks = {}, 32 | xhrSupported = jQuery.ajaxSettings.xhr(); 33 | // Support: IE9 34 | // Open requests must be manually aborted on unload (#5280) 35 | if ( window.ActiveXObject ) { 36 | $( window ).on( "unload", function() { 37 | for ( var key in xhrCallbacks ) { 38 | xhrCallbacks[ key ](); 39 | } 40 | }); 41 | } 42 | support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 43 | support.ajax = xhrSupported = !!xhrSupported; 44 | 45 | //Native Data Type Ajax Transport 46 | $.ajaxTransport('native', function ( options ) { 47 | var callback; 48 | // Cross domain only allowed if supported through XMLHttpRequest 49 | if ( support.cors || xhrSupported && !options.crossDomain ) { 50 | return { 51 | send: function( headers, complete ) { 52 | var i, 53 | xhr = options.xhr(), 54 | id = ++xhrId, 55 | responses = {}; 56 | 57 | xhr.open( options.type, options.url, options.async, options.username, options.password ); 58 | 59 | // Apply custom fields if provided 60 | if ( options.xhrFields ) { 61 | for ( i in options.xhrFields ) { 62 | xhr[ i ] = options.xhrFields[ i ]; 63 | } 64 | } 65 | 66 | // Override mime type if needed 67 | if ( options.mimeType && xhr.overrideMimeType ) { 68 | xhr.overrideMimeType( options.mimeType ); 69 | } 70 | 71 | // X-Requested-With header 72 | // For cross-domain requests, seeing as conditions for a preflight are 73 | // akin to a jigsaw puzzle, we simply never set it to be sure. 74 | // (it can always be set on a per-request basis or even using ajaxSetup) 75 | // For same-domain requests, won't change header if already provided. 76 | if ( !options.crossDomain && !headers["X-Requested-With"] ) { 77 | headers["X-Requested-With"] = "XMLHttpRequest"; 78 | } 79 | 80 | // Set headers 81 | for ( i in headers ) { 82 | xhr.setRequestHeader( i, headers[ i ] ); 83 | } 84 | 85 | // Callback 86 | callback = function( type ) { 87 | return function() { 88 | if ( callback ) { 89 | delete xhrCallbacks[ id ]; 90 | callback = xhr.onload = xhr.onerror = null; 91 | 92 | if ( type === "abort" ) { 93 | xhr.abort(); 94 | } else if ( type === "error" ) { 95 | complete( 96 | // file: protocol always yields status 0; see #8605, #14207 97 | xhr.status, 98 | xhr.statusText 99 | ); 100 | } else { 101 | // The native response associated with the responseType 102 | // Stored in the xhr.response attribute (XHR2 Spec) 103 | if ( xhr.response ) { 104 | responses.native = xhr.response; 105 | } 106 | 107 | complete( 108 | xhrSuccessStatus[ xhr.status ] || xhr.status, 109 | xhr.statusText, 110 | responses, 111 | xhr.getAllResponseHeaders() 112 | ); 113 | } 114 | } 115 | }; 116 | }; 117 | 118 | // Listen to events 119 | xhr.onload = callback(); 120 | xhr.onerror = callback("error"); 121 | 122 | // Create the abort callback 123 | callback = xhrCallbacks[ id ] = callback("abort"); 124 | 125 | try { 126 | // Do send the request (this may raise an exception) 127 | xhr.send( options.hasContent && options.data || null ); 128 | } catch ( e ) { 129 | // #14683: Only rethrow if this hasn't been notified as an error yet 130 | if ( callback ) { 131 | throw e; 132 | } 133 | } 134 | }, 135 | 136 | abort: function() { 137 | if ( callback ) { 138 | callback(); 139 | } 140 | } 141 | }; 142 | } 143 | }); 144 | 145 | 146 | //$.getNative wrapper 147 | $.getNative = function ( url, callback ) { 148 | return $.ajax({ 149 | dataType: 'native', 150 | url: url, 151 | xhrFields: { 152 | responseType: 'arraybuffer' 153 | }, 154 | success: callback 155 | }); 156 | } 157 | })); 158 | -------------------------------------------------------------------------------- /examples/generic/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Web interface at GEOFON - Help 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 26 | 27 | 36 | 37 |
38 | 39 |

The web interface is built up from boxes. Here we note some features 40 | of each box.

41 | 42 |

Index

43 | 53 | 54 | 55 |

User interface boxes

56 |
57 |
The "Event Controls" box
58 |

Use this to select events to compose your request. 59 | This powerful tool is an event browser which can query several sources of 60 | information.

61 | 62 |

Catalog Services: 63 | At GFZ you can choose events from one of the following public catalog services:

64 |
    65 |
  1. GFZ - The GEOFON catalog (http://geofon.gfz-potsdam.de/eqinfo/.)
  2. 66 |
  3. EMSC - The EMSC catalog (http://www.emsc-csem.org/Earthquake/.)
  4. 67 |
  5. USGS - The ANSS Comprehensive Catalog (ComCat) service (http://comcat.cr.usgs.gov/earthquakes/feed/v0.1/search.php.)
  6. 68 |
  7. XXXX NEIC - A temporary replacement for the NEIC service, at USGS (http://earthquake.usgs.gov/earthquakes/eqarchives/epic/) based on the new Comprehensive Catalog (ComCat). XXXX
  8. 69 |
70 |

Select "Catalog Services" under "Event Information". 71 | Then use the pull-down menu under "Catalog Service" to choose the desired 72 | catalog. Now you can filter events by:

73 |
    74 |
  • Date interval
  • 75 |
  • Magnitude range
  • 76 |
  • Depth
  • 77 |
  • Location
  • 78 |
79 |

User Supplied: 80 | Alternatively you can upload your own catalog... 81 |

82 |
83 | 84 |
The "Station Controls" box
85 |

Use this to add channels to your request. The selection of stations can 86 | be made according to

87 |
    88 |
  • by geographical coordinates
  • 89 |
  • the currently selected events - distance and (back)azimuth are in degrees
  • 90 |
  • or by network/station codes.
  • 91 |
92 |

Symbols used on the pull-down lists are: 93 | * = temporary network; + = restricted access (see here) 94 |

95 |

You can limit the selection to particular types of streams/channels, either

96 |
    97 |
  • by channel code, e.g. BH (for BHE, BHZ, BH1, etc). Note that location codes 98 | appear before the channel code. You can select multiple types of channel 99 | codes by selecting with the SHIFT and/or CTRL keys.
  • 100 |
  • by sampling rate - for every station, this will return those streams with 101 | a reported sample rate closest to that specified.
  • 102 |
103 |
104 | 105 |
The "Event and Station Map" box
106 |

Here the events and stations you choose will be displayed. 107 | Use the mouse to drag the map around. 108 | Use the left SHIFT + Mouse to drag areas for limiting the search of events and stations when the appropriate modules are enabled.

109 |
110 | 111 |
The "Event and Station List" box
112 |

The tables here show the events and stations you choose. 113 | Use these tables to check which events and stations have been selected by your search criteria. 114 | You can interactively remove unwanted items. 115 | Your final request will be built from the currently displayed information. 116 | You can refine the selection of streams for stations using the "Advanced Stream Filters Control".

117 |

Triangles on the column headers allow you to sort rows by the values in those columns.

118 |

The "O/R" column shows whether the station is "open" (field is empty) or "restricted" (shown by a red "R").

119 |
120 | 121 |
The "Submit" box
122 |

Use this to send your request to a server. You can check the status of your requests using the controls under the "Download data" tab.

123 | 124 |
The "Recent Requests" box
125 |

Here you can check the status of your Arclink requests made during your current use of this service. The usual request group operations (Reroute/Retry/Resend/Delete/Refresh) as well as download links are available on the status popup. Use this box to conveniently download a small number of recent data volumes.

126 | 127 |
The "Manage Requests" box
128 |

Here you can manage all your Arclink requests (including requests made during previous visits). Downloading all your data volumes with a single click is possible if you have jDownloader installed.

129 | 130 |
The "Console" box
131 |

Warnings and other messages appear here. Unwanted messages can be 132 | removed by reloading the page, or using the "Clear" button.

133 | 134 |
135 |
136 |
137 | 138 | 141 |
142 | 143 | 144 | -------------------------------------------------------------------------------- /examples/webdc2012/webinterface.css: -------------------------------------------------------------------------------- 1 | @charset "ISO-8859-1"; 2 | 3 | html, body { 4 | width: auto; 5 | height: auto; 6 | } 7 | 8 | body { 9 | font-family: Helvetica, Arial, sans-serif; 10 | font-size: .9em; 11 | font-style: normal; 12 | font-weight: normal; 13 | background-color: #ffffff; 14 | color: #000000; 15 | } 16 | 17 | a:hover { 18 | text-decoration: underline; 19 | } 20 | 21 | a:visited { 22 | color: #0000ff; 23 | text-decoration: none; 24 | } 25 | 26 | a{ 27 | text-decoration: none; 28 | color: #0000ff; 29 | } 30 | 31 | hr { 32 | width: 100%; 33 | height: .1em; 34 | } 35 | 36 | table.fullwidth { 37 | width: 100%; 38 | } 39 | 40 | table.auto { 41 | margin-left: auto; 42 | margin-right: auto; 43 | width: auto; 44 | } 45 | 46 | tr.evnrow { 47 | background: #f8fafb none; 48 | } 49 | 50 | tr.oddrow { 51 | background: #e7eff2 none; 52 | } 53 | 54 | tr.bigevt { 55 | background: #f8e4e4 none; 56 | } 57 | 58 | tr.bigevt td.mag { 59 | font-weight: bold; 60 | } 61 | 62 | tr.xxlevt { 63 | background: #f8c8c8 none; 64 | } 65 | 66 | tr.xxlevt td.mag { 67 | font-weight: bold; 68 | color: red; 69 | } 70 | 71 | th { 72 | font-weight: bold; 73 | text-align: center; 74 | background-color: #e7eff2; 75 | } 76 | 77 | td { 78 | empty-cells: show; 79 | text-align: left; 80 | font-weight: normal; 81 | } 82 | 83 | td.typeA { 84 | text-align: center; 85 | color: red; 86 | } 87 | 88 | td.typeM { 89 | text-align: center; 90 | color: green; 91 | } 92 | 93 | td.depth { 94 | text-align: right; 95 | padding-right: 0.6em; 96 | } 97 | 98 | td.mag { 99 | text-align: center; 100 | } 101 | 102 | div.olControlMousePosition { font-family: inherit !important; 103 | font-size: inherit !important; } 104 | 105 | span.to { 106 | padding-left: .3em; 107 | padding-right: .3em; 108 | } 109 | 110 | div.head { 111 | position: relative; 112 | background-color: #4382b5; 113 | color: #fff6f4; 114 | margin: 0 0 15px 0; 115 | min-height: 20px; 116 | padding: 1px; 117 | } 118 | 119 | #timestamp { 120 | font-weight: bold; 121 | } 122 | 123 | #left { 124 | width: 33%; 125 | position: relative; 126 | float: left; 127 | } 128 | 129 | #right { 130 | width: 66%; 131 | position: relative; 132 | float: left; 133 | } 134 | 135 | #content { 136 | text-align: center; 137 | margin: auto; 138 | display: table; 139 | } 140 | 141 | #legend { 142 | font-size: .8em; 143 | margin-top: .5em; 144 | } 145 | 146 | .toggle { 147 | display: none; 148 | } 149 | 150 | .formelem { 151 | margin: .15em; 152 | } 153 | 154 | .bold { 155 | font-weight: bold; 156 | } 157 | 158 | .module { 159 | position: relative; 160 | font-weight: bold; 161 | padding: .5em; 162 | margin: .5em; 163 | background-color: #fff6f4; 164 | } 165 | 166 | .module #stalist { 167 | overflow: auto; 168 | } 169 | 170 | .minmax { 171 | float: right; 172 | } 173 | 174 | .minmaxclearbutton { 175 | width: 20px; 176 | height: 20px; 177 | margin:0; 178 | padding: 0; 179 | border: 0; 180 | background: url(../images/buttonbg.gif); 181 | color: black; 182 | } 183 | 184 | .tiny { 185 | font-weight: normal; 186 | font-size: .7em; 187 | } 188 | 189 | .button { 190 | text-align: center; 191 | } 192 | 193 | .button > input { 194 | font-weight: bold; 195 | } 196 | 197 | .strong, .strong > input { 198 | color: #ff0000; 199 | font-weight: bold; 200 | } 201 | 202 | .wait, .wait * { 203 | cursor: wait !important; 204 | } 205 | 206 | .indent { 207 | margin-left: 2em; 208 | } 209 | 210 | .normal { 211 | font-weight: normal; 212 | } 213 | 214 | /* ----- additional features from the new webinterface ----- */ 215 | 216 | /* * HTML tags customization ************************************************ */ 217 | html { 218 | overflow-y: scroll; 219 | } 220 | 221 | 222 | h1 { 223 | font-size: 1.6em; 224 | padding: 0; 225 | margin: 0; 226 | } 227 | 228 | h2 { 229 | font-size: 1.2em; 230 | padding: 0; 231 | margin: 0; 232 | /* font-weight: normal; */ 233 | } 234 | 235 | h3 { 236 | font-size: 1.0em; 237 | padding: 0; 238 | margin: 0 0 5px 0; 239 | font-weight: bold; 240 | /*font-style: italic;*/ 241 | } 242 | 243 | 244 | p { 245 | margin: 0px; 246 | padding: 0; 247 | } 248 | 249 | /* ************************************************************************** */ 250 | 251 | /* * Top page elements ****************************************************** */ 252 | 253 | #menu { 254 | padding: 0; 255 | margin: auto; 256 | width: 1024px; 257 | clear: both; 258 | } 259 | 260 | #contents { 261 | margin: auto; 262 | width: 1024px; 263 | border: 0px Solid black; 264 | padding: 15px 0 15px 0; 265 | clear: both; 266 | } 267 | 268 | 269 | /* ************************************************************************** */ 270 | 271 | /* * Main Boxes on contents section ***************************************** */ 272 | #menu ul { 273 | padding:0px; 274 | margin: 5px 0 0 0; 275 | list-style:none; 276 | } 277 | 278 | #menu ul li { 279 | display: inline; 280 | } 281 | 282 | #menu ul li a { 283 | padding: 0 5px 0 0; 284 | display: inline-block; 285 | } 286 | 287 | #menu ul li.last { 288 | padding: 0 0 0 5px; 289 | float: right; 290 | } 291 | 292 | #contents .right { 293 | width: 744px; 294 | float: right; 295 | clear: right; 296 | } 297 | 298 | #contents .all { 299 | width: 100%; 300 | margin: auto auto; 301 | clear: left; 302 | } 303 | 304 | #contents .left { 305 | width: 280px; 306 | float: left ; 307 | clear: left; 308 | } 309 | 310 | #contents .right .box { 311 | margin: 0 0 5px 5px; 312 | background-color: #fff6f4; 313 | } 314 | 315 | #contents .left .box { 316 | margin: 0 5px 5px 0; 317 | background-color: #fff6f4; 318 | } 319 | 320 | #contents .all .box { 321 | margin: 0 0 5px 0; 322 | background-color: #fff6f4; 323 | } 324 | 325 | /* ************************************************************************** */ 326 | 327 | /* * Modules customization ************************************************** */ 328 | #contents .right .titlebox { 329 | border: 1px Solid gray; 330 | padding: 5px 10px 5px 10px; 331 | color: white; 332 | font-weight: bold; 333 | background: #4382b5; 334 | } 335 | 336 | #contents .left .titlebox { 337 | border: 1px Solid gray; 338 | padding: 5px 10px 5px 10px; 339 | color: white; 340 | font-weight: bold; 341 | background: #4382b5; 342 | } 343 | 344 | #contents .all .titlebox { 345 | border: 2px Solid #4382b5; 346 | padding: 5px 10px 5px 10px; 347 | color: white; 348 | font-weight: bold; 349 | background: #4382b5; 350 | } 351 | 352 | #contents .help { 353 | padding: 2px; 354 | color: #dddddd; 355 | font-size: 0.85em; 356 | } 357 | 358 | #contents .frame { 359 | border-left: 0px Solid gray; 360 | border-right: 0px Solid gray; 361 | border-bottom: 0px Solid gray; 362 | min-height: 100px; 363 | padding: 10px; 364 | } 365 | 366 | #contents .scrollframe { 367 | border-left: 0px Solid gray; 368 | border-right: 0px Solid gray; 369 | border-bottom: 1px Solid blue; 370 | height: 100px; 371 | overflow-y: auto; 372 | padding: 10px; 373 | } 374 | 375 | .clear { 376 | clear: both; 377 | } 378 | 379 | /* ************************************************************************** */ 380 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/WebDC3webinterface.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/WebDC3webinterface.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/WebDC3webinterface" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/WebDC3webinterface" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /test/testEvent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 |

Event service test page

14 |

Visiting the following URLs should work

15 | 22 | 23 |

The following should look similar - 5 events each:

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
GEOFONeqinfo, M>7, June 2013JSONCSVRAWXOOP
COMCATComcat, M>7, June 2013JSONCSVrawxoop
EMSCEMSC, M>7, June 2013JSONCSVrawxoop
50 | 51 | 52 |

The following should give errors

53 |
    54 |
  1. /event/catalog (no 's')
  2. 55 |
  3. /events/catalog ('events')
  4. 56 |
  5. /events/XXX ('events/XXX')
  6. 57 |
  7. /event/YYY (no such service)
  8. 58 |
  9. /YYY (no handler)
  10. 59 |
60 | 61 |

The following should look similar - a few events each:

62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
GEOFONeqinfo, SW Asia, June 2013 - expect 9 eventsJSONCSVRAWXOOP
COMCATComcat, SW Asia, June 2013 - expect 12 eventsJSONCSVrawxoop
EMSCEMSC, SW Asia, June 2013 - expect 48 with M≥3.6; many small eventsJSONCSVrawxoop
88 | 89 | 90 |

The following should look similar - a few deep events each, in June 2013:

91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
GEOFONeqinfo, 200-400km, 15 events JSONCSVRAWXOOP
COMCATComcat, 200-400km - expect 14 eventsJSONCSVrawxoop
EMSCEMSC 200-400km - expect 31 events with M≥3.6JSONCSVrawxoop
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /examples/webdc3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebDC3 at eida.gfz-potsdam.de 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 49 |
50 |
51 |
52 | 59 | 60 | 80 | 81 |
82 |
83 |
84 | 88 |
89 |
90 | 91 | 98 |
99 | 100 |
101 |
102 |
103 |

Events Controls

104 | 107 |
108 |
109 |
110 | 111 | 120 | 121 |
122 |
123 |

Make Request

124 | 127 |
128 |
129 |
130 |
131 | 132 | 149 | 150 |
151 |
152 | 153 | 156 |
157 |
158 |
159 | 160 | 161 | -------------------------------------------------------------------------------- /css/wimodule.css: -------------------------------------------------------------------------------- 1 | @keyframes blink { 2 | to { 3 | color: rgba(0,0,0,0); 4 | } 5 | } 6 | 7 | .wi-warn { 8 | border: 2px Solid #d22; 9 | } 10 | 11 | .wi-request-pack-div { 12 | margin: 0 0 20px 0; 13 | } 14 | 15 | .wi-table-header { 16 | background: #4682B4; 17 | color: white; 18 | } 19 | 20 | .wi-table-header-cell { 21 | padding: 2px 2px 5px 2px; 22 | } 23 | 24 | .wi-odd { 25 | background: #E7EFF2; 26 | } 27 | 28 | .wi-even { 29 | background: #F8FAFB; 30 | } 31 | 32 | .wi-arrow-up:hover { 33 | cursor: pointer; 34 | } 35 | 36 | .wi-arrow-up { 37 | font-size: 0em; 38 | position: relative; 39 | margin: 0 2px 0 5px; 40 | bottom: 8px; 41 | border-top: 0px Solid transparent; 42 | border-bottom: 5px Solid white; 43 | border-left: 5px Solid transparent; 44 | border-right: 5px Solid transparent; 45 | } 46 | 47 | .wi-arrow-down:hover { 48 | cursor: pointer; 49 | } 50 | 51 | .wi-arrow-down { 52 | font-size: 0em; 53 | position: relative; 54 | margin: 0 5px 0 2px; 55 | top: -3px; 56 | border-top: 5px Solid white; 57 | border-bottom: 0px Solid transparent; 58 | border-left: 5px Solid transparent; 59 | border-right: 5px Solid transparent; 60 | } 61 | 62 | .wi-control-item-first { 63 | padding: 0 0 8px 0; 64 | position: relative; 65 | } 66 | 67 | .wi-control-item { 68 | padding: 8px 0 8px 0; 69 | position: relative; 70 | } 71 | 72 | .wi-control-item-last { 73 | padding: 12px 0 0 0; 74 | position: relative; 75 | text-align: right; 76 | } 77 | 78 | /* wi controls use this as a header before a control e.g. a full-width slider. */ 79 | .wi-spacer { 80 | margin: 0 0 0.5em 0; 81 | width: 100%; 82 | } 83 | 84 | /* wi controls use class="wi-short-spacer" as an introducer before 85 | * a short selector e.g. a pull-down menu. 86 | * Embed it in a "wi-short-div" and use absolute positioning for 87 | * the object on the right. The "wi-short-spacer" has normal 88 | * positioning so it sets the height of the "wi-short-div". 89 | */ 90 | .wi-short-div { 91 | position: relative; 92 | } 93 | 94 | .wi-short-spacer { 95 | margin: 0 0 0.5em 0; 96 | width: 48%; 97 | } 98 | 99 | .wi-short-right { 100 | position: absolute; 101 | width: 48%; 102 | top: 0px; 103 | right: 0px; 104 | } 105 | 106 | .wi-inline-full { 107 | padding: 0.2em 0.5em; 108 | margin: 0em 0.5em 0em 0.5em; 109 | } 110 | 111 | .wi-inline { 112 | /* padding: 0.2em 0.5em; */ 113 | margin: 0.2em 0.5em; 114 | width: 95px; 115 | } 116 | 117 | .wi-inline-small { 118 | /* padding: 0.2em 0.5em; */ 119 | margin: 0 0.5em 0em 0.5em; 120 | width: 35px; 121 | } 122 | 123 | .wi-clear { 124 | font-size: 0em; 125 | clear: both; 126 | } 127 | 128 | /* Console log */ 129 | 130 | .wi-console-debug { 131 | color: grey; 132 | padding: 2px 0 0 0; 133 | } 134 | 135 | .wi-console-info { 136 | padding: 2px 0 0 0; 137 | } 138 | 139 | .wi-console-notice { 140 | color: orange; 141 | padding: 2px 0 0 0; 142 | } 143 | 144 | .wi-console-warning { 145 | color: red; 146 | padding: 2px 0 2px 0; 147 | } 148 | 149 | .wi-console-error { 150 | color: red; 151 | padding: 2px 0 2px 0; 152 | } 153 | 154 | .wi-console-stacktrace { 155 | padding: 2px 0 2px 20px; 156 | } 157 | 158 | .wi-console-warning-tab { 159 | color: red; 160 | animation: blink 1s cubic-bezier(1,0,0,1) infinite; 161 | -khtml-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 162 | -moz-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 163 | -ms-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 164 | -o-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 165 | -webkit-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 166 | } 167 | 168 | .wi-console-error-tab { 169 | color: red; 170 | animation: blink 1s cubic-bezier(1,0,0,1) infinite; 171 | -khtml-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 172 | -moz-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 173 | -ms-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 174 | -o-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 175 | -webkit-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 176 | } 177 | 178 | /* Request status - full page */ 179 | 180 | .wi-status-full-msgs { 181 | /* no style */ 182 | } 183 | 184 | .wi-status-full-groups { 185 | /* no style */ 186 | } 187 | 188 | .wi-status-full-group { 189 | border: 1px solid black; 190 | border-radius: 20px; 191 | padding: 20px; 192 | background-color: #ffffff; 193 | color: #000; 194 | width: auto; 195 | margin-left: auto; 196 | margin-right: auto; 197 | margin-top: 10px; 198 | margin-bottom: 10px; 199 | } 200 | 201 | .wi-status-full-group-buttons { 202 | margin-bottom: 10px; 203 | } 204 | 205 | .wi-status-full-group-body { 206 | /* no style */ 207 | } 208 | 209 | /* Request status - list/popup */ 210 | 211 | .wi-status-list-buttons { 212 | margin-bottom: 10px; 213 | } 214 | 215 | .wi-status-list-body { 216 | /* no style */ 217 | } 218 | 219 | .wi-status-item-description { 220 | /* no style */ 221 | } 222 | 223 | .wi-status-item-progress { 224 | /* no style */ 225 | } 226 | 227 | .wi-status-popup { 228 | /* no style */ 229 | } 230 | 231 | .wi-status-popup-display { 232 | /* no style */ 233 | } 234 | 235 | .wi-status-popup-msgs { 236 | /* no style */ 237 | } 238 | 239 | .wi-status-popup-groups { 240 | /* no style */ 241 | } 242 | 243 | .wi-status-popup-group { 244 | /* no style */ 245 | } 246 | 247 | .wi-status-popup-group-buttons { 248 | margin-top: 20px; 249 | margin-bottom: 20px; 250 | } 251 | 252 | .wi-status-popup-group-body { 253 | margin-top: 20px; 254 | margin-bottom: 20px; 255 | max-height: 800px; 256 | overflow-y: auto; 257 | } 258 | 259 | /* Request warnings */ 260 | 261 | .wi-warning-encryption { 262 | width: auto; 263 | border: 2px Solid red; 264 | padding: 5px 5px 5px 5px; 265 | margin: 10px 0px 10px 0px; 266 | } 267 | 268 | .wi-warning-routing { 269 | color: red; 270 | margin-top: 20px; 271 | margin-bottom: 20px; 272 | max-height: 100px; 273 | overflow-y: auto; 274 | } 275 | 276 | /* Request rendering */ 277 | 278 | .wi-request { 279 | padding: 0px 0px 0px 5px; 280 | margin: 0px 0px 20px 0px; 281 | border-left: 2px Solid black; 282 | } 283 | 284 | .wi-request-datacenter { 285 | font-size: 1.2em; 286 | padding: 0; 287 | margin: 0; 288 | } 289 | 290 | .wi-request-header { 291 | margin: 0px; 292 | background: #dddddd; 293 | } 294 | 295 | .wi-request-download { 296 | font-weight: bold !important; 297 | color: green !important; 298 | } 299 | 300 | .wi-request-info { 301 | margin: 0px; 302 | } 303 | 304 | .wi-request-volume { 305 | background: #ffffff; 306 | padding: 0px 0px 0px 5px; 307 | margin: 5px 0px 5px 25px; 308 | border-left: 2px Solid black; 309 | } 310 | 311 | .wi-request-volume-header { 312 | margin: 0px; 313 | background: #dddddd; 314 | } 315 | 316 | .wi-request-volume-download { 317 | font-weight: bold !important; 318 | color: green !important; 319 | } 320 | 321 | .wi-request-volume-info { 322 | margin: 0px; 323 | } 324 | 325 | .wi-request-volume-content { 326 | margin: 0px; 327 | } 328 | 329 | .wi-request-line { 330 | /* no style */ 331 | } 332 | 333 | .wi-request-encrypted { 334 | color: red; 335 | } 336 | 337 | .wi-request-status-ok { 338 | color: green; 339 | } 340 | 341 | .wi-request-status-warn { 342 | color: #d9d600; 343 | } 344 | 345 | .wi-request-status-other { 346 | color: red; 347 | } 348 | 349 | /* Request review */ 350 | 351 | .wi-review-popup { 352 | /* no style */ 353 | } 354 | 355 | .wi-review-display { 356 | max-height: 800px; 357 | overflow-y: auto; 358 | } 359 | 360 | .wi-station-filter { 361 | padding: 0px 6px 12px 6px; 362 | /* background: #CD5C5C; */ 363 | color: #000; 364 | } 365 | 366 | .wi-disabled { 367 | color: grey; 368 | } 369 | 370 | .wi-download-alert-tab { 371 | color: red; 372 | animation: blink 1s cubic-bezier(1,0,0,1) infinite; 373 | -khtml-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 374 | -moz-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 375 | -ms-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 376 | -o-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 377 | -webkit-animation: blink 1s cubic-bezier(1,0,0,1) infinite; 378 | } 379 | 380 | .ui-progressbar { 381 | position: relative; 382 | } 383 | 384 | .wi-progress-label { 385 | position: absolute; 386 | left: 8px; 387 | top: 4px; 388 | /* font-weight: bold; */ 389 | /* text-shadow: 1px 1px 0 #fff; */ 390 | } 391 | 392 | -------------------------------------------------------------------------------- /examples/webdc3/geofon.css: -------------------------------------------------------------------------------- 1 | /* * HTML tags customization ************************************************ */ 2 | /* 3 | * PLE Aug 2013: Grabbed some features from 4 | * https://www-extern.gfz-potsdam.de/startseite/ 5 | * but it is preferable to use their style sheet (template.css) directly. 6 | * Reduced outer width to 970 px; 10 px padding on left and right leaves only 950 (was 1024). 7 | * 8 | * "Features" include: 9 | * - constrained page width 10 | * - shadows on boxes 11 | * - rounded corners 12 | * - .. 13 | */ 14 | 15 | html { 16 | height: 100%; 17 | overflow-y: auto; 18 | } 19 | 20 | body { 21 | /* background: #FFF url('images/background.gif') repeat-x; */ 22 | /* color: #000; */ 23 | height: 100%; 24 | /* font-family: sans-serif; */ 25 | /* font-size: 8.8px; */ 26 | /* font-size: 0.55rem; */ 27 | /* These should be set from gfz_text.css?? */ 28 | font-size: 11px; 29 | font-size: 0.688rem; 30 | margin: 0px; 31 | padding: 0px; 32 | } 33 | 34 | /* Probably should only apply to the Event and Station List */ 35 | #wi-RequestManagerControl td { 36 | vertical-align: middle; 37 | } 38 | 39 | h1 { 40 | color: #000; 41 | font-size: 14px; 42 | font-size: 0.875rem; 43 | padding: 0; 44 | margin: 0; 45 | text-align: center; 46 | } 47 | 48 | p { 49 | font-size: 11px; 50 | font-size: 0.688rem; 51 | margin: 0px; 52 | padding: 0; 53 | } 54 | 55 | /* ************************************************************************** */ 56 | 57 | /* Tweaks to make GFZ styles fit here */ 58 | 59 | /* The "header" element uses absolute positioning for the images, 60 | * and normal positioning for the text. 61 | * Padding, instead of vertical centering, is used to shift the

62 | * text downwards from the top of the header. 63 | */ 64 | 65 | #header { 66 | height: 65px; /* Is 100px for GFZ page, but we have no top nav stuff. */ 67 | position: relative; /* Repeats GFZ template but defends against its absence? */ 68 | } 69 | 70 | #header h1 { 71 | padding: 20px 0px 20px 0px; 72 | margin: 0px 250px; 73 | } 74 | 75 | /* Make sure border is removed; border-radius is not enough. 76 | * Set in gfz_text.css 77 | * 78 | */ 79 | img { 80 | border: 0; /* html5: border-Attribut nicht mehr erlaubt */ 81 | } 82 | 83 | #logoGFZ { 84 | left: -16px; 85 | } 86 | 87 | .inner-left { 88 | position: absolute; 89 | left: 130px; 90 | bottom: 0px; 91 | } 92 | 93 | .inner-right { 94 | position: absolute; 95 | right: 170px; 96 | bottom: 0px; 97 | } 98 | 99 | /* Footer needs centering since we don't adopt GFZ 2column layout. */ 100 | .homepage #footer { 101 | margin: 0px 0px; 102 | } 103 | 104 | .homepage #copyright { 105 | width: 942px; 106 | text-align: center; 107 | top: 0px; 108 | } 109 | /* Linked text should be grey in the footer */ 110 | #footer a { 111 | color: #999; 112 | } 113 | 114 | /* ************************************************************************** */ 115 | 116 | /* * Top page elements ****************************************************** */ 117 | #holder { 118 | margin: auto; 119 | background-color: #fff; 120 | width: 942px; /* 950? */ 121 | min-height: 100%; 122 | position: relative; 123 | padding: 8px; 124 | } 125 | 126 | #header { 127 | padding: 10px; 128 | margin: auto; 129 | /* width: 1024px; */ 130 | clear: both; 131 | } 132 | 133 | #menu { 134 | padding: 0; 135 | /* margin: auto; */ 136 | /* width: 1024px; */ 137 | clear: both; 138 | } 139 | 140 | #contents { 141 | margin: auto; 142 | /* width: 1024px; */ 143 | border: 0px Solid black; 144 | padding: 15px 0 20px 0; /* 20px = height of footer */ 145 | clear: both; 146 | } 147 | 148 | #footer { 149 | width: 942px; 150 | /* height: 20px; */ 151 | position: absolute; 152 | bottom: 0px; 153 | /* margin: auto; */ 154 | padding-top: 20px; 155 | text-align: center; 156 | clear: both; 157 | } 158 | /* ************************************************************************** */ 159 | 160 | /* * Main Boxes on contents section ***************************************** */ 161 | #menu ul { 162 | padding:0px; 163 | margin: 5px 0 0 0; 164 | list-style:none; 165 | } 166 | 167 | #menu ul li { 168 | display: inline; 169 | } 170 | 171 | #menu ul li a { 172 | padding: 0 5px 0 0; 173 | display: inline-block; 174 | } 175 | 176 | #menu ul li.last { 177 | padding: 0 0 0 5px; 178 | float: right; 179 | } 180 | 181 | #contents .right { 182 | width: 666px; /* was 744px -74 = 670 */ 183 | float: right; 184 | clear: right; 185 | } 186 | 187 | #contents .all { 188 | width: 100%; 189 | margin: auto auto; 190 | clear: left; 191 | } 192 | 193 | #contents .left { 194 | width: 276px; /* was 280px */ 195 | float: left; 196 | clear: left; 197 | } 198 | 199 | #contents .right .box { 200 | margin: 0 0 5px 5px; 201 | } 202 | 203 | #contents .left .box { 204 | margin: 0 5px 5px 0; 205 | } 206 | 207 | #contents .all .box { 208 | margin: 0 0 5px 0; 209 | } 210 | 211 | /* ************************************************************************** */ 212 | 213 | /* * Modules customization ************************************************** */ 214 | .right .titlebox { 215 | border: 0px Solid black; 216 | border-top-right-radius: 15px; /* CSS3 */ 217 | padding: 10px 10px 5px 10px; 218 | color: rgb(255, 255, 255); 219 | background: rgb(0, 88, 156); 220 | margin-bottom: 0px; /* remove space between content and header? ?? */ 221 | } 222 | 223 | .left .titlebox { 224 | border: 0px Solid black; 225 | border-top-left-radius: 15px; /* CSS3 */ 226 | padding: 10px 10px 10px 10px; 227 | color: rgb(255, 255, 255); 228 | background: rgb(0, 88, 156); 229 | margin-bottom: 0px; /* remove space between content and header? ?? */ 230 | overflow: visible; 231 | } 232 | 233 | .all .titlebox { 234 | border: 0px Solid black; 235 | border-top-left-radius: 15px; /* CSS3 */ 236 | border-top-right-radius: 15px; /* CSS3 */ 237 | padding: 10px 10px 5px 10px; 238 | color: rgb(255, 255, 255); 239 | background: rgb(0, 88, 156); 240 | text-align: left; 241 | margin-bottom: 0px; /* remove space between content and header? ?? */ 242 | } 243 | 244 | /* Shouldn't be needed?? But positions help pop-ups correctly on the left. */ 245 | .helpframe { 246 | display: inline; 247 | float: right; 248 | position: relative; 249 | } 250 | 251 | .help { 252 | display: inline; 253 | float: right; 254 | padding: 0px 2px 2px 2px; 255 | text-align: right; 256 | color: #EEE; 257 | font-size: 1.0em; 258 | } 259 | 260 | .frame { 261 | /* border-left: 1px Solid black; */ 262 | /* border-right: 1px Solid black; */ 263 | /* border-bottom: 1px Solid black; */ 264 | min-height: 100px; 265 | padding: 10px; 266 | margin-top: 0px; /* remove space between content and header? ?? */ 267 | } 268 | 269 | .consoleframe { 270 | /* border-left: 1px Solid black; */ 271 | /* border-right: 1px Solid black; */ 272 | /* border-bottom: 1px Solid black; */ 273 | height: 400px; 274 | overflow-y: auto; 275 | padding: 10px; 276 | margin-bottom: 10px; 277 | text-align: left; 278 | } 279 | 280 | .statusframe { 281 | /* border-left: 1px Solid black; */ 282 | /* border-right: 1px Solid black; */ 283 | /* border-bottom: 1px Solid black; */ 284 | min-height: 100px; 285 | padding: 1px 10px 0px 10px; 286 | display: none; 287 | } 288 | 289 | .clear { 290 | clear: both; 291 | } 292 | 293 | .tab { 294 | display: none; 295 | } 296 | 297 | /* ********************************** */ 298 | /* For GFZ-style help page */ 299 | dl { 300 | margin: 2em 2em; 301 | width: 60em; 302 | } 303 | 304 | dt { 305 | font-weight: bold; 306 | color: rgb(255, 255, 255); 307 | background: rgb(0, 88, 156); 308 | 309 | /* 310 | * border: 1px Solid black; 311 | * border-left: 1px solid silver; 312 | * border-right: 1px solid silver; 313 | * border-top: 1px solid silver; 314 | */ 315 | border-top-left-radius: 15px; /* CSS3 */ 316 | border-top-right-radius: 15px; /* CSS3 */ 317 | -moz-box-shadow: 2px 2px 6px #999; 318 | -webkit-box-shadow: 2px 2px 6px #999; 319 | box-shadow: 2px 2px 6px #999; 320 | padding: 10px; 321 | } 322 | 323 | dd { 324 | color:black; 325 | background-color:lightyellow; 326 | padding: 10px 10px 32px 10px; 327 | border-left: 1px solid silver; 328 | /* 329 | * border-right: 1px solid silver; 330 | * border-bottom: 1px solid silver; 331 | */ 332 | -moz-box-shadow: 2px 2px 6px #999; 333 | -webkit-box-shadow: 2px 2px 6px #999; 334 | box-shadow: 2px 2px 6px #999; 335 | margin: 0 0 1em 0; 336 | } 337 | 338 | 339 | /* ********************************** */ 340 | 341 | /* * Rolling mouse cursor *************************************************** */ 342 | body.busy, body.busy * { 343 | cursor: wait !important; 344 | } 345 | 346 | /* ************************************************************************** */ 347 | -------------------------------------------------------------------------------- /examples/webdc2012/map_functions.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $(window).bind("resize", resizeMap); 3 | resizeMap(); 4 | initMap(); 5 | }); 6 | 7 | var map, select, kmlLayer, boxLayer, global; 8 | 9 | function resizeMap() { 10 | $("#map").css("width", $("#right.resmodule").innerWidth()); 11 | $("#map").css("height", Math.floor($(window).height()*0.4)); 12 | } 13 | 14 | function initMap() { 15 | map = new OpenLayers.Map('map', 16 | {controls: [new OpenLayers.Control.Navigation(), 17 | new OpenLayers.Control.PanZoom(), 18 | new OpenLayers.Control.MousePosition(), 19 | new OpenLayers.Control.KeyboardDefaults({observeElement: 'map'}) 20 | ], 21 | restrictedExtent: new OpenLayers.Bounds(-210, -90, 210, 90)}); 22 | 23 | // BIANCHI 12-03-2012 Looks like that the metacarta has been down 24 | var baseLayer = new OpenLayers.Layer.WMS( 25 | "WMS base layer", 26 | "http://vmap0.tiles.osgeo.org/wms/vmap0", 27 | {layers: "basic"}, 28 | {'maxExtent': new OpenLayers.Bounds(-210, -90, 210, 90), 'maxResolution': 'auto'} 29 | ); 30 | 31 | boxLayer = new OpenLayers.Layer.Vector("Box Layer"); 32 | boxLayer.setOpacity(0.3); 33 | var options = {projection: map.displayProjection}; 34 | kmlLayer = new OpenLayers.Layer.Vector("KML Layer", options); 35 | var control = new OpenLayers.Control({ 36 | draw: function () { 37 | this.hbox = new OpenLayers.Handler.Box(control, {'done': this.notice}, {'keyMask': OpenLayers.Handler.MOD_SHIFT}); 38 | this.hbox.activate(); 39 | }, 40 | notice: function (bounds) { 41 | boxLayer.destroyFeatures(); 42 | var lb = map.getLonLatFromPixel(new OpenLayers.Pixel(bounds.left, bounds.bottom)); 43 | var rt = map.getLonLatFromPixel(new OpenLayers.Pixel(bounds.right, bounds.top)); 44 | var bounds = new OpenLayers.Bounds(lb.lon, lb.lat, rt.lon, rt.lat); 45 | var box = new OpenLayers.Feature.Vector(bounds.toGeometry()); 46 | boxLayer.addFeatures([box]); 47 | $("input[name=latmin]").val(Math.round(lb.lat*100)/100); 48 | $("input[name=latmax]").val(Math.round(rt.lat*100)/100); 49 | $("input[name=lonmin]").val(Math.round(lb.lon*100)/100); 50 | $("input[name=lonmax]").val(Math.round(rt.lon*100)/100); 51 | if ($("input[name=zoom]").attr("checked")) map.zoomToExtent(bounds, true); 52 | } 53 | }); 54 | select = new OpenLayers.Control.SelectFeature(kmlLayer); 55 | kmlLayer.events.on({"featureselected": onFeatureSelect, 56 | "featureunselected": onFeatureUnselect}); 57 | map.addLayers([baseLayer, boxLayer, kmlLayer]); 58 | map.zoomToMaxExtent(); 59 | map.addControl(control); 60 | map.addControl(select); 61 | select.activate(); 62 | $("body").css("cursor", ""); 63 | } 64 | 65 | function onPopupClose() { 66 | select.unselectAll(); 67 | } 68 | 69 | function onFeatureSelect(event) { 70 | var feature = event.feature; 71 | global = feature; 72 | var button = "

"; 73 | var popup = new OpenLayers.Popup.FramedCloud("description", 74 | feature.geometry.getBounds().getCenterLonLat(), 75 | new OpenLayers.Size(10,10), 76 | "
" + feature.attributes.name + "
" + feature.attributes.description + button, 77 | null, true, onPopupClose); 78 | feature.popup = popup; 79 | map.addPopup(popup); 80 | } 81 | 82 | function onFeatureUnselect(event) { 83 | var feature = event.feature; 84 | if (feature.popup) { 85 | map.removePopup(feature.popup); 86 | feature.popup.destroy(); 87 | delete feature.popup; 88 | } 89 | } 90 | 91 | function onRemoveFeature() { 92 | map.removePopup(global.popup); 93 | global.popup.destroy(); 94 | delete global.popup; 95 | global.style.display = "none"; 96 | kmlLayer.redraw(); 97 | $("input[name=onMap][value=" + global.attributes.name + "]").attr("checked", ""); 98 | } 99 | 100 | function eventsMap(count, start) { 101 | if (global && global.popup) { 102 | map.removePopup(global.popup); 103 | global.popup.destroy(); 104 | delete global.popup; 105 | } 106 | if (count && start != -1) kmlLayer.removeFeatures(kmlLayer.features.slice(start,start+count)); 107 | $("#eqinfo table tr").each(function(index) { 108 | if (index > 0) { 109 | if ($(this).css("display") != "none") { 110 | var chdren = $(this).children(); 111 | var date = chdren.slice(0,1).text(); 112 | var mag = chdren.slice(1,2).text(); 113 | var lat = chdren.slice(2,3).html().split(" "); 114 | lat[1] == "S" ? lat = parseFloat(lat[0]) * -1 : lat = parseFloat(lat[0]); 115 | var lon = chdren.slice(3,4).html().split(" "); 116 | lon[1] == "W" ? lon = parseFloat(lon[0]) * -1 : lon = parseFloat(lon[0]); 117 | var depth = chdren.slice(4,5).html(); 118 | var region = chdren.slice(5,6).html(); 119 | var evstyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']); 120 | evstyle.strokeColor = "#000000"; 121 | evstyle.strokeWidth = 1; 122 | evstyle.fillColor = "#000000"; 123 | evstyle.fillOpacity = 0.1; 124 | if ($(this).hasClass("bigevt")) { 125 | evstyle.strokeWidth = 4; evstyle.fillOpacity = 0.4; 126 | } 127 | if ($(this).hasClass("xxlevt")) { 128 | evstyle.strokeColor = "#ff0000"; evstyle.strokeWidth = 4; 129 | evstyle.fillColor = "#ff0000"; evstyle.fillOpacity = 0.4; 130 | } 131 | kmlLayer.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lon, lat), {name: date, 132 | description: "region: " + region + "
mag: " + mag + " depth: " + depth}, evstyle)]); 133 | } 134 | } 135 | }); 136 | $("body").css("cursor", ""); 137 | } 138 | 139 | function stationsMap(count, start) { 140 | if (global && global.popup) { 141 | map.removePopup(global.popup); 142 | global.popup.destroy(); 143 | delete global.popup; 144 | } 145 | if (count && start != -1) kmlLayer.removeFeatures(kmlLayer.features.slice(start,start+count)); 146 | $.get("data/" + $("input[name=sesskey]").val() + ".kml", function(data) { 147 | var kml = new OpenLayers.Format.KML({extractStyles: true, extractAttributes: true}); 148 | var parsed = kml.read(data); 149 | kmlLayer.addFeatures(parsed); 150 | }); 151 | } 152 | 153 | function destroyMapFeatures(count, start) { 154 | if (count && start != -1) kmlLayer.removeFeatures(kmlLayer.features.slice(start,start+count)); 155 | } 156 | 157 | function displayAllFeatures(displ, count, start) { 158 | var features = kmlLayer.features.slice(start, start+count); 159 | var len = features.length; 160 | do { 161 | var feature = features[--len]; 162 | displ ? feature.style.display = "" : feature.style.display = "none"; 163 | } while (len); 164 | kmlLayer.redraw(); 165 | } 166 | 167 | function displayFeature(displ, val, count, start) { 168 | var features = kmlLayer.features.slice(start, start+count); 169 | var len = features.length; 170 | do { 171 | var feature = features[--len]; 172 | if (feature.attributes.name == val) { 173 | displ ? feature.style.display = "" : feature.style.display = "none"; 174 | kmlLayer.redraw(); 175 | break; 176 | } 177 | } while (len); 178 | } 179 | 180 | function resetMapRegion() { 181 | boxLayer.destroyFeatures(); 182 | map.zoomToMaxExtent(); 183 | } 184 | 185 | function zoomMap(bool) { 186 | if (!bool) map.zoomToMaxExtent(); 187 | else { 188 | var bounds = boxLayer.getDataExtent(); 189 | if (!bounds) { 190 | bounds = new OpenLayers.Bounds(parseFloat($("#station_form input[name=lonmin]").val()), parseFloat($("#station_form input[name=latmin]").val()), 191 | parseFloat($("#station_form input[name=lonmax]").val()), parseFloat($("#station_form input[name=latmax]").val())); 192 | var box = new OpenLayers.Feature.Vector(bounds.toGeometry()); 193 | boxLayer.addFeatures([box]); 194 | } 195 | map.zoomToExtent(bounds, true); 196 | } 197 | } 198 | --------------------------------------------------------------------------------