commit 140d46690db7c16497463e635d341b2adddade55 Author: Martin Stadler Date: Sun Dec 8 13:11:59 2019 +0100 initial: mirror Drupal site with HTTrack httrack http://siarp.de -O . -N "%h%p/%n/index%[page].%t" -WqQ%v --robots=0 See https://www.lullabot.com/articles/sending-a-drupal-site-into-retirement diff --git a/backblue.gif b/backblue.gif new file mode 100644 index 0000000..da7c5c8 Binary files /dev/null and b/backblue.gif differ diff --git a/fade.gif b/fade.gif new file mode 100644 index 0000000..579cc5f Binary files /dev/null and b/fade.gif differ diff --git a/hts-cache/doit.log b/hts-cache/doit.log new file mode 100644 index 0000000..6ea8d9c --- /dev/null +++ b/hts-cache/doit.log @@ -0,0 +1,8 @@ +http://siarp.de -O . -N %h%p/%n/index%[page].%t -WqQ%v -s0 +File generated automatically on Sun, 08 Dec 2019 12:58:44, do NOT edit + +To update a mirror, just launch httrack without any parameters +The existing cache will be used (and modified) +To have other options, retype all parameters and launch HTTrack +To continue an interrupted mirror, just launch httrack without any parameters + diff --git a/hts-cache/new.lst b/hts-cache/new.lst new file mode 100644 index 0000000..4c12f29 --- /dev/null +++ b/hts-cache/new.lst @@ -0,0 +1,120 @@ +[backblue.gif] +[fade.gif] +[index.html] +[siarp.de/rss/index.xml] +[siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css] +[siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css] +[siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css] +[siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css] +[siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css] +[siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM/index.js] +[siarp.de/misc/feed/index.png] +[siarp.de/index/index.html] +[siarp.de/misc/throbber-inactive/index.png] +[siarp.de/misc/throbber-active/index.gif] +[siarp.de/misc/grippie/index.png] +[siarp.de/misc/draggable/index.png] +[siarp.de/misc/tree/index.png] +[siarp.de/misc/tree-bottom/index.png] +[siarp.de/misc/menu-expanded/index.png] +[siarp.de/misc/menu-collapsed/index.png] +[siarp.de/misc/menu-leaf/index.png] +[siarp.de/misc/message-24-ok/index.png] +[siarp.de/misc/message-24-warning/index.png] +[siarp.de/misc/message-24-error/index.png] +[siarp.de/misc/help/index.png] +[siarp.de/misc/progress/index.gif] +[siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css] +[siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css] +[siarp.de/sites/all/modules/ctools/images/status-active/index.gif] +[siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf/index.gif] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded/index.gif] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed/index.gif] +[siarp.de/themes/garland/images/task-list/index.png] +[siarp.de/misc/watchdog-ok/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/body/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white/index.png] +[siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar/index.png] +[siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css] +[siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css] +[siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA/index.js] +[siarp.de/sites/siarp.de/files/speedportcallerid/index.jar] +[siarp.de/node/232/index.html] +[siarp.de/node/231/index.html] +[siarp.de/modules/file/icons/application-octet-stream/index.png] +[siarp.de/node/228/index.html] +[siarp.de/node/229/index.html] +[siarp.de/node/227/index.html] +[siarp.de/node/223/index.html] +[siarp.de/node/222/index.html] +[siarp.de/node/221/index.html] +[siarp.de/node/220/index.html] +[siarp.de/node/218/index.html] +[siarp.de/sites/siarp.de/files/Inbox_Zero/index.jpg] +[siarp.de/modules/file/icons/image-x-generic/index.png] +[siarp.de/node/214/index.html] +[siarp.de/modules/file/icons/package-x-generic/index.png] +[siarp.de/node/211/index.html] +[siarp.de/node/204/index.html] +[siarp.de/node/202/index.html] +[siarp.de/sites/siarp.de/files/bin/index.zip] +[siarp.de/sites/siarp.de/files/Bild 10/index.png] +[siarp.de/sites/siarp.de/files/Bild 11/index.png] +[siarp.de/sites/siarp.de/files/Bild 13/index.png] +[siarp.de/node/201/index.html] +[siarp.de/node/199/index.html] +[siarp.de/node/196/index.html] +[siarp.de/node/194/index.html] +[siarp.de/node/191/index.html] +[siarp.de/node/187/index.html] +[siarp.de/node/179/index.html] +[siarp.de/sites/siarp.de/files/ubuntu_free_space/index.png] +[siarp.de/node/174/index.html] +[siarp.de/node/167/index.html] +[siarp.de/node/167_/index.html] +[siarp.de/node/167_/a_/index.html] +[siarp.de/node/163/index.html] +[siarp.de/node/160/index.html] +[siarp.de/node/143/index.html] +[siarp.de/node/135/index.html] +[siarp.de/sites/siarp.de/files/monopoly_junior/index.jpg] +[siarp.de/modules/file/icons/x-office-spreadsheet/index.png] +[siarp.de/sites/siarp.de/files/reserved_words/index.xls] +[siarp.de/node/113/index.html] +[siarp.de/node/60/index.html] +[siarp.de/node/47/index.html] +[siarp.de/node/42/index.html] +[siarp.de/node/40/index.html] +[siarp.de/node/23/index.html] +[siarp.de/node/8/index.html] +[siarp.de/blog/2/index.html] +[siarp.de/martin/index.xml] +[siarp.de/blog/3/index.html] +[siarp.de/tilman/index.xml] +[siarp.de/comment/161/index.html] +[siarp.de/comment/162/index.html] +[siarp.de/comment/184/index.html] +[siarp.de/comment/185/index.html] +[siarp.de/comment/157/index.html] +[siarp.de/comment/153/index.html] +[siarp.de/sites/siarp.de/files/Inbox_Zero/index.svg] +[siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4/index.html] +[siarp.de/comment/158/index.html] +[siarp.de/comment/200/index.html] +[siarp.de/PFAD/index/index.html] +[siarp.de/sites/siarp.de/files/subdomains/index.html] +[siarp.de/comment/14/index.html] +[siarp.de/comment/15/index.html] +[siarp.de/comment/13/index.html] +[siarp.de/comment/2/index.html] +[siarp.de/comment/3/index.html] +[siarp.de/comment/4/index.html] diff --git a/hts-cache/new.txt b/hts-cache/new.txt new file mode 100644 index 0000000..5d3eba4 --- /dev/null +++ b/hts-cache/new.txt @@ -0,0 +1,113 @@ +date size'/'remotesize flags(request:Update,Range state:File response:Modified,Chunked,gZipped) statuscode status ('servermsg') MIME Etag|Date URL localfile (from URL) +12:58:46 52379/52379 ---MC- 200 added ('OK') text/html etag:%221575804339-0%22 http://siarp.de/ ./siarp.de/index/index.html (from ) +12:58:51 7587/7587 ---M-Z 200 added ('OK') text/css etag:%228a9-5992e2adda582%22 http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css ./siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css (from http://siarp.de/) +12:58:52 2498/2498 ---M-Z 200 added ('OK') text/css etag:%2235e-5992e2ade1ab3%22 http://siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo.css ./siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css (from http://siarp.de/) +12:58:53 33462/33462 ---M-Z 200 added ('OK') text/css etag:%22c84-5992e2adeb6f3%22 http://siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE.css ./siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css (from http://siarp.de/) +12:58:54 16404/16404 ---M-Z 200 added ('OK') text/css etag:%22f71-5992e2ae08bb5%22 http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css ./siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css (from http://siarp.de/) +12:58:55 925/925 ---M-Z 200 added ('OK') text/css etag:%22175-5992e2adf0513%22 http://siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU.css ./siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css (from http://siarp.de/) +12:59:00 95990/95990 ---MC- 200 added ('OK') text/html etag:%221575804351-0%22 http://siarp.de/node/232 ./siarp.de/node/232/index.html (from http://siarp.de/) +12:59:02 105218/105218 ---M-Z 200 added ('OK') text/javascript etag:%228b73-5992e2ae01684%22 http://siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM.js ./siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM/index.js (from http://siarp.de/) +12:59:02 11500/11500 ---MC- 200 added ('OK') text/html etag:%221575804353-0%22 http://siarp.de/node/231 ./siarp.de/node/231/index.html (from http://siarp.de/) +12:59:04 11478/11478 ---MC- 200 added ('OK') text/html etag:%221575804355-0%22 http://siarp.de/node/228 ./siarp.de/node/228/index.html (from http://siarp.de/) +12:59:04 5905/5905 ---M-- 200 added ('OK') text/html etag:%221575804357-0%22 http://siarp.de/node/229 ./siarp.de/node/229/index.html (from http://siarp.de/) +12:59:06 176608/176608 ---MC- 200 added ('OK') application/rss+xml etag:%221575803716-0%22 http://siarp.de/rss.xml ./siarp.de/rss/index.xml (from http://siarp.de/) +12:59:06 6790/6790 ---M-- 200 added ('OK') text/html etag:%221575804359-0%22 http://siarp.de/node/227 ./siarp.de/node/227/index.html (from http://siarp.de/) +12:59:06 6629/6629 ---M-- 200 added ('OK') text/html etag:%221575804361-0%22 http://siarp.de/node/223 ./siarp.de/node/223/index.html (from http://siarp.de/) +12:59:08 8319/8319 ---MC- 200 added ('OK') text/html etag:%221575804362-0%22 http://siarp.de/node/222 ./siarp.de/node/222/index.html (from http://siarp.de/) +12:59:08 7018/7018 ---M-- 200 added ('OK') text/html etag:%221575804363-0%22 http://siarp.de/node/221 ./siarp.de/node/221/index.html (from http://siarp.de/) +12:59:09 7078/7078 ---M-- 200 added ('OK') text/html etag:%221575804364-0%22 http://siarp.de/node/220 ./siarp.de/node/220/index.html (from http://siarp.de/) +12:59:10 7819/7819 ---M-- 200 added ('OK') text/html etag:%221575804365-0%22 http://siarp.de/node/218 ./siarp.de/node/218/index.html (from http://siarp.de/) +12:59:11 8879/8879 ---MC- 200 added ('OK') text/html etag:%221575804366-0%22 http://siarp.de/node/214 ./siarp.de/node/214/index.html (from http://siarp.de/) +12:59:12 11549/11549 ---MC- 200 added ('OK') text/html etag:%221575804367-0%22 http://siarp.de/node/211 ./siarp.de/node/211/index.html (from http://siarp.de/) +12:59:13 9304/9304 ---MC- 200 added ('OK') text/html etag:%221575804368-0%22 http://siarp.de/node/204 ./siarp.de/node/204/index.html (from http://siarp.de/) +12:59:14 7551/7551 ---M-- 200 added ('OK') text/html etag:%221575804369-0%22 http://siarp.de/node/202 ./siarp.de/node/202/index.html (from http://siarp.de/) +12:59:15 15530/15530 ---MC- 200 added ('OK') text/html etag:%221575804370-0%22 http://siarp.de/node/201 ./siarp.de/node/201/index.html (from http://siarp.de/) +12:59:16 5997/5997 ---M-- 200 added ('OK') text/html etag:%221575804371-0%22 http://siarp.de/node/199 ./siarp.de/node/199/index.html (from http://siarp.de/) +12:59:19 46321/46321 ---MC- 200 added ('OK') text/html etag:%221575804372-0%22 http://siarp.de/node/196 ./siarp.de/node/196/index.html (from http://siarp.de/) +12:59:19 6978/6978 ---M-- 200 added ('OK') text/html etag:%221575804373-0%22 http://siarp.de/node/194 ./siarp.de/node/194/index.html (from http://siarp.de/) +12:59:21 19872/19872 ---MC- 200 added ('OK') text/html etag:%221575804374-0%22 http://siarp.de/node/191 ./siarp.de/node/191/index.html (from http://siarp.de/) +12:59:21 7072/7072 ---M-- 200 added ('OK') text/html etag:%221575804375-0%22 http://siarp.de/node/187 ./siarp.de/node/187/index.html (from http://siarp.de/) +12:59:21 8228/8228 ---MC- 200 added ('OK') text/html etag:%221575804376-0%22 http://siarp.de/node/179 ./siarp.de/node/179/index.html (from http://siarp.de/) +12:59:24 51086/51086 ---MC- 200 added ('OK') text/html etag:%221575804377-0%22 http://siarp.de/node/174 ./siarp.de/node/174/index.html (from http://siarp.de/) +12:59:24 12246/12246 ---MC- 200 added ('OK') text/html etag:%221575804378-0%22 http://siarp.de/node/167 ./siarp.de/node/167/index.html (from http://siarp.de/) +12:59:24 4037/4037 ---M-- 404 error ('Not%20Found') text/html etag:%221575804379-0%22 http://siarp.de/node/167%22 ./siarp.de/node/167_/index.html (from http://siarp.de/) +12:59:25 4060/4060 ---M-- 404 error ('Not%20Found') text/html etag:%221575804380-0%22 http://siarp.de/node/167 ./siarp.de/node/167_/a_/index.html (from http://siarp.de/) +12:59:26 7009/7009 ---M-- 200 added ('OK') text/html etag:%221575804381-0%22 http://siarp.de/node/163 ./siarp.de/node/163/index.html (from http://siarp.de/) +12:59:27 5873/5873 ---M-- 200 added ('OK') text/html etag:%221575804382-0%22 http://siarp.de/node/160 ./siarp.de/node/160/index.html (from http://siarp.de/) +12:59:28 7966/7966 ---M-- 200 added ('OK') text/html etag:%221575804383-0%22 http://siarp.de/node/143 ./siarp.de/node/143/index.html (from http://siarp.de/) +12:59:29 9616/9616 ---MC- 200 added ('OK') text/html etag:%221575804384-0%22 http://siarp.de/node/135 ./siarp.de/node/135/index.html (from http://siarp.de/) +12:59:30 8194/8194 ---MC- 200 added ('OK') text/html etag:%221575804385-0%22 http://siarp.de/node/113 ./siarp.de/node/113/index.html (from http://siarp.de/) +12:59:31 8213/8213 ---MC- 200 added ('OK') text/html etag:%221575804386-0%22 http://siarp.de/node/60 ./siarp.de/node/60/index.html (from http://siarp.de/) +12:59:32 7153/7153 ---M-- 200 added ('OK') text/html etag:%221575804387-0%22 http://siarp.de/node/47 ./siarp.de/node/47/index.html (from http://siarp.de/) +12:59:33 9374/9374 ---MC- 200 added ('OK') text/html etag:%221575804388-0%22 http://siarp.de/node/42 ./siarp.de/node/42/index.html (from http://siarp.de/) +12:59:34 6383/6383 ---M-- 200 added ('OK') text/html etag:%221575804389-0%22 http://siarp.de/node/40 ./siarp.de/node/40/index.html (from http://siarp.de/) +12:59:37 29385/29385 ---MC- 200 added ('OK') text/html etag:%221575804390-0%22 http://siarp.de/node/23 ./siarp.de/node/23/index.html (from http://siarp.de/) +12:59:37 5656/5656 ---M-- 200 added ('OK') text/html etag:%221575804391-0%22 http://siarp.de/node/8 ./siarp.de/node/8/index.html (from http://siarp.de/) +12:59:37 656/656 ---M-- 200 added ('OK') image/png etag:%22290-5887b0bd70292%22 http://siarp.de/misc/feed.png ./siarp.de/misc/feed/index.png (from http://siarp.de/) +12:59:40 33571/33571 ---MC- 200 added ('OK') text/html etag:%221575804393-0%22 http://siarp.de/blog/2 ./siarp.de/blog/2/index.html (from http://siarp.de/) +12:59:42 320/320 ---M-- 200 added ('OK') image/png etag:%22140-5887b0c979385%22 http://siarp.de/misc/throbber-inactive.png ./siarp.de/misc/throbber-inactive/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:42 26134/26134 ---MC- 200 added ('OK') text/html etag:%221575804394-0%22 http://siarp.de/blog/3 ./siarp.de/blog/3/index.html (from http://siarp.de/) +12:59:42 1233/1233 ---M-- 200 added ('OK') image/gif etag:%224d1-5887b0c7c9173%22 http://siarp.de/misc/throbber-active.gif ./siarp.de/misc/throbber-active/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:43 106/106 ---M-- 200 added ('OK') image/png etag:%226a-5887b0be840a4%22 http://siarp.de/misc/grippie.png ./siarp.de/misc/grippie/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:44 268/268 ---M-- 200 added ('OK') image/png etag:%2210c-5887b0c1ae969%22 http://siarp.de/misc/draggable.png ./siarp.de/misc/draggable/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:45 130/130 ---M-- 200 added ('OK') image/png etag:%2282-5887b0c5a3c5f%22 http://siarp.de/misc/tree.png ./siarp.de/misc/tree/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:46 129/129 ---M-- 200 added ('OK') image/png etag:%2281-5887b0c602fd0%22 http://siarp.de/misc/tree-bottom.png ./siarp.de/misc/tree-bottom/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:47 106/106 ---M-- 200 added ('OK') image/png etag:%226a-5887b0c5421df%22 http://siarp.de/misc/menu-expanded.png ./siarp.de/misc/menu-expanded/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:48 105/105 ---M-- 200 added ('OK') image/png etag:%2269-5887b0bcacd91%22 http://siarp.de/misc/menu-collapsed.png ./siarp.de/misc/menu-collapsed/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:49 126/126 ---M-- 200 added ('OK') image/png etag:%227e-5887b0c223c6a%22 http://siarp.de/misc/menu-leaf.png ./siarp.de/misc/menu-leaf/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:50 1058/1058 ---M-- 200 added ('OK') image/png etag:%22422-5887b0c82abf3%22 http://siarp.de/misc/message-24-ok.png ./siarp.de/misc/message-24-ok/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:51 753/753 ---M-- 200 added ('OK') image/png etag:%222f1-5887b0bef4585%22 http://siarp.de/misc/message-24-warning.png ./siarp.de/misc/message-24-warning/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:52 733/733 ---M-- 200 added ('OK') image/png etag:%222dd-5887b0c1c7009%22 http://siarp.de/misc/message-24-error.png ./siarp.de/misc/message-24-error/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:53 294/294 ---M-- 200 added ('OK') image/png etag:%22126-5887b0c4777ae%22 http://siarp.de/misc/help.png ./siarp.de/misc/help/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:54 5872/5872 ---M-- 200 added ('OK') image/gif etag:%2216f0-5887b0c52260f%22 http://siarp.de/misc/progress.gif ./siarp.de/misc/progress/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4.css) +12:59:55 2196/2196 ---M-- 200 added ('OK') image/gif etag:%22894-5688744c11d8f%22 http://siarp.de/sites/all/modules/ctools/images/status-active.gif ./siarp.de/sites/all/modules/ctools/images/status-active/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE.css) +12:59:56 174/174 ---M-- 200 added ('OK') image/gif etag:%22ae-5196d3a12e600%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf.gif ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +12:59:57 183/183 ---M-- 200 added ('OK') image/gif etag:%22b7-5196d3a12e600%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded.gif ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +12:59:58 176/176 ---M-- 200 added ('OK') image/gif etag:%22b0-5196d3a03a3c0%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed.gif ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed/index.gif (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +12:59:59 128/128 ---M-- 200 added ('OK') image/png etag:%2280-5887b1a4af780%22 http://siarp.de/themes/garland/images/task-list.png ./siarp.de/themes/garland/images/task-list/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:00 375/375 ---M-- 200 added ('OK') image/png etag:%22177-5887b0bd04bd2%22 http://siarp.de/misc/watchdog-ok.png ./siarp.de/misc/watchdog-ok/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:01 98/98 ---M-- 200 added ('OK') image/png etag:%2262-5196d39e51f40%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:02 214/214 ---M-- 200 added ('OK') image/png etag:%22d6-5196d39f46180%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/body.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/body/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:03 241/241 ---M-- 200 added ('OK') image/png etag:%22f1-5196d39e51f40%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:04 1991/1991 ---M-- 200 added ('OK') image/png etag:%227c7-5196d39d5dd00%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:05 2078/2078 ---M-- 200 added ('OK') image/png etag:%2281e-5196d39d5dd00%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:06 485/485 ---M-- 200 added ('OK') image/png etag:%221e5-5196d39e51f40%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:07 445/445 ---M-- 200 added ('OK') image/png etag:%221bd-5196d39e51f40%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:08 125/125 ---M-- 200 added ('OK') image/png etag:%227d-5196d39f46180%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:09 201/201 ---M-- 200 added ('OK') image/png etag:%22c9-5196d39f46180%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:10 133/133 ---M-- 200 added ('OK') image/png etag:%2285-5196d39c69ac0%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:11 139/139 ---M-- 200 added ('OK') image/png etag:%228b-5196d39d5dd00%22 http://siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar.png ./siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar/index.png (from http://siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A.css) +13:00:12 5332/5332 ---M-Z 200 added ('OK') text/javascript etag:%2273a-5992e3ae64eb1%22 http://siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA.js ./siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA/index.js (from http://siarp.de/node/232) +13:00:15 189/189 ---M-- 200 added ('OK') image/png etag:%22bd-5887b1653cc4c%22 http://siarp.de/modules/file/icons/application-octet-stream.png ./siarp.de/modules/file/icons/application-octet-stream/index.png (from http://siarp.de/node/232) +13:00:18 11478/11478 ---MC- 200 added ('OK') text/html etag:%221575804430-0%22 http://siarp.de/comment/161 ./siarp.de/comment/161/index.html (from http://siarp.de/node/228) +13:00:20 11478/11478 ---MC- 200 added ('OK') text/html etag:%221575804431-0%22 http://siarp.de/comment/162 ./siarp.de/comment/162/index.html (from http://siarp.de/node/228) +13:00:22 11478/11478 ---MC- 200 added ('OK') text/html etag:%221575804433-0%22 http://siarp.de/comment/184 ./siarp.de/comment/184/index.html (from http://siarp.de/node/228) +13:00:24 11478/11478 ---MC- 200 added ('OK') text/html etag:%221575804435-0%22 http://siarp.de/comment/185 ./siarp.de/comment/185/index.html (from http://siarp.de/node/228) +13:00:24 6790/6790 ---M-- 200 added ('OK') text/html etag:%221575804437-0%22 http://siarp.de/comment/157 ./siarp.de/comment/157/index.html (from http://siarp.de/node/227) +13:00:26 7819/7819 ---M-- 200 added ('OK') text/html etag:%221575804439-0%22 http://siarp.de/comment/153 ./siarp.de/comment/153/index.html (from http://siarp.de/node/218) +13:00:30 385/385 ---M-- 200 added ('OK') image/png etag:%22181-5887b165b947c%22 http://siarp.de/modules/file/icons/image-x-generic.png ./siarp.de/modules/file/icons/image-x-generic/index.png (from http://siarp.de/node/214) +13:00:32 15538/15538 ---M-- 200 added ('OK') image/jpeg etag:%223cb2-5196d3cb24900%22 http://siarp.de/sites/siarp.de/files/Inbox_Zero.jpg ./siarp.de/sites/siarp.de/files/Inbox_Zero/index.jpg (from http://siarp.de/node/214) +13:00:32 15864/15864 ---M-- 200 added ('OK') image/svg+xml etag:%223df8-5196d3cb24900%22 http://siarp.de/sites/siarp.de/files/Inbox_Zero.svg ./siarp.de/sites/siarp.de/files/Inbox_Zero/index.svg (from http://siarp.de/node/214) +13:00:34 260/260 ---M-- 200 added ('OK') image/png etag:%22104-5887b1675851f%22 http://siarp.de/modules/file/icons/package-x-generic.png ./siarp.de/modules/file/icons/package-x-generic/index.png (from http://siarp.de/node/211) +13:00:36 4347/4347 ---M-- 200 added ('OK') application/zip etag:%2210fb-5196d397a4f80%22 http://siarp.de/sites/siarp.de/files/bin.zip ./siarp.de/sites/siarp.de/files/bin/index.zip (from http://siarp.de/node/211) +13:00:38 5979/5979 ---M-- 200 added ('OK') text/html etag:%22175b-5196d3ee6dc40%22 http://siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4.egg ./siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4/index.html (from http://siarp.de/node/201) +13:01:12 150155/150155 ---M-- 200 added ('OK') image/png etag:%2224a8b-5196d396b0d40%22 http://siarp.de/sites/siarp.de/files/Bild%2013.png ./siarp.de/sites/siarp.de/files/Bild%2013/index.png (from http://siarp.de/node/201) +13:01:14 173790/173790 ---M-- 200 added ('OK') image/png etag:%222a6de-5196d392e0440%22 http://siarp.de/sites/siarp.de/files/Bild%2010.png ./siarp.de/sites/siarp.de/files/Bild%2010/index.png (from http://siarp.de/node/201) +13:01:16 173490/173490 ---M-- 200 added ('OK') image/png etag:%222a5b2-5196d394c88c0%22 http://siarp.de/sites/siarp.de/files/Bild%2011.png ./siarp.de/sites/siarp.de/files/Bild%2011/index.png (from http://siarp.de/node/201) +13:01:16 46321/46321 ---MC- 200 added ('OK') text/html etag:%221575804487-0%22 http://siarp.de/comment/158 ./siarp.de/comment/158/index.html (from http://siarp.de/node/196) +13:01:18 46321/46321 ---MC- 200 added ('OK') text/html etag:%221575804489-0%22 http://siarp.de/comment/200 ./siarp.de/comment/200/index.html (from http://siarp.de/node/196) +13:01:22 183/183 ---M-- 200 added ('OK') image/png etag:%22b7-5887b1644d82a%22 http://siarp.de/modules/file/icons/x-office-spreadsheet.png ./siarp.de/modules/file/icons/x-office-spreadsheet/index.png (from http://siarp.de/node/113) +13:01:27 46181/46181 ---M-- 200 added ('OK') image/png etag:%22b465-5196d40b09fc0%22 http://siarp.de/sites/siarp.de/files/ubuntu_free_space.png ./siarp.de/sites/siarp.de/files/ubuntu_free_space/index.png (from http://siarp.de/node/187) +13:01:28 4131/4131 ---M-- 404 error ('Not%20Found') text/html etag:%221575804502-0%22 http://siarp.de/sites/siarp.de/files/subdomains.gif ./siarp.de/sites/siarp.de/files/subdomains/index.gif (from http://siarp.de/node/60) +13:01:30 38912/38912 ---M-- 200 added ('OK') application/vnd.ms-excel etag:%229800-5196d3ef61e80%22 http://siarp.de/sites/siarp.de/files/reserved_words.xls ./siarp.de/sites/siarp.de/files/reserved_words/index.xls (from http://siarp.de/node/113) +13:01:30 4017/4017 ---M-- 404 error ('Not%20Found') text/html etag:%221575804503-0%22 http://siarp.de/PFAD/ ./siarp.de/PFAD/index/index.html (from http://siarp.de/node/60) +13:01:32 61619/61619 ---M-- 200 added ('OK') image/jpeg etag:%22f0b3-5196d3ee6dc40%22 http://siarp.de/sites/siarp.de/files/monopoly_junior.jpg ./siarp.de/sites/siarp.de/files/monopoly_junior/index.jpg (from http://siarp.de/node/174) +13:01:32 9374/9374 ---MC- 200 added ('OK') text/html etag:%221575804505-0%22 http://siarp.de/comment/14 ./siarp.de/comment/14/index.html (from http://siarp.de/node/42) +13:01:34 9374/9374 ---MC- 200 added ('OK') text/html etag:%221575804507-0%22 http://siarp.de/comment/15 ./siarp.de/comment/15/index.html (from http://siarp.de/node/42) +13:01:34 6383/6383 ---M-- 200 added ('OK') text/html etag:%221575804509-0%22 http://siarp.de/comment/13 ./siarp.de/comment/13/index.html (from http://siarp.de/node/40) +13:01:38 29385/29385 ---MC- 200 added ('OK') text/html etag:%221575804511-0%22 http://siarp.de/comment/2 ./siarp.de/comment/2/index.html (from http://siarp.de/node/23) +13:01:40 29385/29385 ---MC- 200 added ('OK') text/html etag:%221575804513-0%22 http://siarp.de/comment/3 ./siarp.de/comment/3/index.html (from http://siarp.de/node/23) +13:01:42 29385/29385 ---MC- 200 added ('OK') text/html etag:%221575804515-0%22 http://siarp.de/comment/4 ./siarp.de/comment/4/index.html (from http://siarp.de/node/23) +13:01:44 10261/10261 ---MC- 200 added ('OK') application/rss+xml etag:%221575804517-0%22 http://siarp.de/martin.xml ./siarp.de/martin/index.xml (from http://siarp.de/blog/2) +13:01:46 11552/11552 ---MC- 200 added ('OK') application/rss+xml etag:%221575804519-0%22 http://siarp.de/tilman.xml ./siarp.de/tilman/index.xml (from http://siarp.de/blog/3) +13:05:00 3143313/3143313 ---M-- 200 added ('OK') application/java-archive etag:%222ff691-5196d40921b40%22 http://siarp.de/sites/siarp.de/files/speedportcallerid.jar ./siarp.de/sites/siarp.de/files/speedportcallerid/index.jar (from http://siarp.de/node/232) diff --git a/hts-cache/new.zip b/hts-cache/new.zip new file mode 100644 index 0000000..a726cb3 Binary files /dev/null and b/hts-cache/new.zip differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..4cdb0be --- /dev/null +++ b/index.html @@ -0,0 +1,144 @@ + + + + + + + Local index - HTTrack Website Copier + + + + + + + + + +
HTTrack Website Copier - Open Source offline browser
+ + + + +
+ + + + +
+ + + + +
+ + + + Local index - HTTrack + + +

Index of locally available sites:

+ + + + +
+ · + + siarp.de/index/index.html + +
+
+
+
+
+ Mirror and index made by HTTrack Website Copier [XR&CO'2008] +
+ + + + + + +
+
+
+ + + + + +
+ + + + + + diff --git a/siarp.de/PFAD/index/index.html b/siarp.de/PFAD/index/index.html new file mode 100644 index 0000000..e9a551f --- /dev/null +++ b/siarp.de/PFAD/index/index.html @@ -0,0 +1,70 @@ + + + + + + + Page not found | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+ +

Page not found

+
+
+
+ + +
+ The requested page "/PFAD/" could not be found.
+
+
+
+ +
+ + +
+
+ + diff --git a/siarp.de/blog/2/index.html b/siarp.de/blog/2/index.html new file mode 100644 index 0000000..1948ce7 --- /dev/null +++ b/siarp.de/blog/2/index.html @@ -0,0 +1,604 @@ + + + + + + + + + + + Martin‘s posts | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Martin‘s posts

+
+
+
+ + +
+
+ + + +
+
+
+ + +

MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren

+ + + +
+
sudo vim /etc/apt/sources.list
+> # MongoDB
+> deb http://downloads.mongodb.org/distros/ubuntu 9.4 10gen

+sudo aptitude update && sudo aptitude install mongodb-stable

+sudo /etc/init.d/mongodb start

+git clone http://github.com/ry/node.git
+cd node
+git checkout -b tags/v0.2.0
+./configure --prefix=/home/martin
+make
+make install

+curl http://npmjs.org/install.sh | sh
+npm install mongodb mustache
+
+ + + +
+
+
+
+ + +

Committeten auf deutsch

+ + + +
+

Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:

+ +

Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...

+ +

Also, wisst ihr bescheid.

+
+ + + +
+
+
+
+ + +

Plone: Item Type as Criterion for Collection but not to show up in Search

+ + + +
+

You can't select an item type as a criterion for a collection if it is not selected to be included in search results. In the "Search settings" (/@@search-controlpanel) you can exclude certain content types from being "searched and be available in the user facing part of the site". That actually corresponds to the list of types_not_searched in site_properties.

+ + + +
+
+
+
+ + +

My SilverStripe Usability Test

+ + + +
+

So I decided to try out SilveStripe (Version 2.3.3) to check out if it's of any value for me as a freelance web developer. I'm kind of an expert in Drupal, I also work with Plone, and lately I'm very interested in usability and I do track initiatives in the Drupal and Plone community to give users a better experience. I know that feedback of a first-time user is valuable so I thought I'd write down my impressions of SilverStripe right away.

+ + + +
+
+
+
+ + +

YAML und Listen im IE6

+ + + +
+

Achtung! Böse Falle mit YAML und Listen im Internet Explorer 6! Folgender Code steht in der iehacks.css und gilt für den IE6.

+ + + +
+
+
+
+ + +

YAML, jQuery slideToggle and IE6

+ + + +
+

As usual with browser bugs and hacks this took me a while to find out.

+ +

I have an unordered list with complex items like floats and stuff. This list is supposed to hide when I click on a button by slowly decreasing its height. I use jQuery's slideToggle for that.

+ +

Problem: In Internet Explorer 6 the content (or parts of it) is hidden after the list is shown (slid down).

+ + + +
+
+
+
+ + +

Bazaar: incompatible format 2a and rich-root support

+ + + +
+

I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message

+ + + +
+
+
+
+ + +

Ruby on Rails deployen

+ + + +
+

Das Szenario: Es sollen neben statischen Webseiten und PHP-Anwendungen auch Ruby-on-Rails-Anwendungen auf dem Server laufen. Die klassische Variante ist für jede Rails-Anwendung einen oder mehrere (Load Balancing) Mongrel-Server laufen zu lassen und die mittels Reverse Proxy hinter den Apache zu schalten (Port 80, SSL, Sicherheit). Außerdem gibt es (relativ neu) das Apache-Modul Phusion Passenger (a.k.a. mod_rails / mod_rack).

+ + + +
+
+
+
+ + +

Plone 3: How to really exclude from navigation

+ + + +
+

Plone has multiple ways of excluding a content object from the navigation:

+ + + +
+
+ +
+
+ + +

Using AppleScript and cURL to import Content from iPhoto into Drupal

+ + + +
+

I'm using Apple's iPhoto to organize my private photographs and Drupal is what comes to my mind first when there's need for a web-based solution. Having lots of pictures from a recent trip I want to show people I started thinking about some kind of web gallery. Being a developer I need to come up with something fancier than just some stock gallery product like Gallery2 (actually I don't really know that product so bear with me). I did some research and found some article about different approaches to build photo galleries in Drupal and also a nice video tutorial. I've used image module and gallery module before but the flexibility that CCK extended by imagefield and imagecache and views seem to offer is just too tempting. +

+ + + +
+
+
+
+ + +

Ubuntu-Installation: den größten freien Speicherbereich benutzen

+ + + +
+

Installiert man Ubuntu zum ersten Mal auf einem Windows-Rechner ist die Auswahl bei der Partitionierung der Festplatte meist einfach: erste Partition verkleinern und den freigewordenen Platz zur Installation nutzen. Wenn man wie ich aber schon zum hundertsten Male (oder zum zweiten Mal) eine Linux-Distribution auf so einem Rechner installiert, möchte man den irgendwann mal erstellten Bereich jenseits von Windows nutzen.

+ + + +
+
+
+
+ + +

Drupal-Tutorial: Administratoren-Blog

+ + + +
+

Für das Siarp-Portal (derzeit Drupal 5) wollten wir eine Möglichkeit haben, Meldungen oder Nachrichten zu kommunizieren, die über Vorgänge bei Projekten wie der Server-Administration oder auch dem Siarp-Portal selber informieren. Da das eher einem ausführlichen Changelog ähnelt sollte, wollten wir es nicht über das Project-Modul laufen lassen. Eher eine Art Blog mit bestimmten Rechten und Einstellungen und einer gesonderten Ansicht, wofür Drupal ja bestens ausgerüstet ist.
+

+ + + +
+
+
+
+ + +

Buildout-basiertes Zope2 (Plone) unter Debian/Ubuntu installieren

+ + + +
+

Ubuntu 8.04 Server / Plone 3.1.5.1

+ +

Voraussetzungen buildout:

+ +

$ sudo aptitude install gcc python2.4 python2.4-dev python-imaging python-elementtree

+ +

(Für Ubuntu Desktop muss noch zlib1g-dev installiert werden.)

+ +

Ergänzung von <a href="http://siarp.de/node/167" rel="nofollow">http://siarp.de/node/167</a> für Plone 3.3 unter Ubuntu Jaunty
+========================================================================
+
+Ubuntu Jaunty enthält zwar Python 2.4 aber keine Image Library (PIL) für 2.4.
+Diese kann auch als Egg mittels buildout installiert werden [1]. Dafür braucht

+

+ + + +
+
+
+
+ + +

Krasse Sache APC

+ + + +
+

Aufgrund des Vortrags von Rasmus Lehrdorf auf der FrOSCon 2008 hab ich mir mal kurz APC, den Alternative PHP Cache angesehen. Wollte damit nicht viel Zeit verbringen, aber unsere Drupal-Seiten auf siarp.de laufen eher langsam, weil der Drupal-Cache nur für anonyme Besucher funktioniert und wir alles schön personalisiert und geschützt haben.

+ + + +
+
+
+
+ + +

Zope unter Fedora 9

+ + + +
+

Fedora 9 bringt nur Python 2.5, Zope benötigt z.Z. aber Python 2.4. Das Repository http://rpm.livna.org/ bietet alle nötigen Pakete.

+ + + +
+
+
+
+ + +

Plone: Entwicklungsumgebung Mac

+ + + +
+

10.4 Tiger

+ +

Dem Buch "Professional Plone Development" von Martin Aspeli folgend, soll nicht auf einen fertigen Installer zurückgegriffen werden. Ein automatisierter Build-Out Prozess soll möglich sein.

+ +

OS X 10.4.10 liefert zwar Python 2.4 mit, es fehlt aber z.B. ein Wrapper für die libxml2. Um nicht unnötig im System rumzufummeln, soll MacPorts verwendet werden:

+ +

$ sudo port install python24 py-libxml2 py-elementtree py-pil

+ +

+ + + +
+
+
+
+ + +

Reservierte Begriffe in JavaScript

+ + + +
+

abstract (r)
+anchors (b)
+applets (b)
+arguments (g)
+Array (g)
+as (z)
+Boolean (g)
+boolean (r)
+break (t)
+byte (r)
+case (t)
+catch (t)
+char (r)
+class (r)
+const (r)
+continue (t)
+Date (g)
+debugger (r)
+decodeURI (g)
+decodeURIComponent (g)
+default (t)
+delete (t)
+do (t)
+document (b)
+double (r)
+elements (b)
+else (t)
+encodeURI (g)
+enum (r)
+Error (g)
+escape (g)
+eval (g)
+EvalError (g)
+export (r)
+extend (r)
+false (t)
+final (r)
+finally (t)
+float (r)
+for (t)
+forms (b)
+frames (b)
+Function (g)
+function (t)
+goto (r)
+history (b)
+if (t)
+images (b)
+implements (r)
+

+ + + +
+
+
+
+ + +

SVN Migration

+ + + +
+

Migration von BerkeleyDB nach FSFS sollte ganz leicht sein.

+

Man kann einen Dump exportieren. Das ist eine menschenlesbare Datei, die man für heftige Änderungen auch bearbeiten kann. Tolle Sache das, damit gehen auch so Sachen, wie Zusammenlegung von zwei Repositories etc. Noch besser: LIES ES NACH. In der wie immer hervorragenden Doku.

+
+ + + +
+
+
+
+ + +

Erste Apache-Konfiguration

+ + + +
+

"SIARP.de" - ich sehe meinen Namen in Leuchtbuchstaben...

+ +

Wir fassten den Entschluss, die aufgefächerte Konfiguration zu einer handlichen kleinen httpd.conf zusammenzuführen. Ein Backup der (fast) originalen Konfigurationdateien befindet sich in /home/root/bak/apache2.tar.gz. Dann haben wir festgestellt, dass es zwingend das Verzeichnis samt Dateien sysconfig.d erfordert. Also die betreffenden Teile wieder ausgelagert und TADA! - "SIARP.de".

+
+ + + +
+
+
+ + + + + + +
+
+
+
+ Subscribe to Martin‘s posts +
+ + + +
+
+ + + + diff --git a/siarp.de/blog/3/index.html b/siarp.de/blog/3/index.html new file mode 100644 index 0000000..1d410e6 --- /dev/null +++ b/siarp.de/blog/3/index.html @@ -0,0 +1,418 @@ + + + + + + + + + + + Tilman‘s posts | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Tilman‘s posts

+
+
+
+ + +
+
+ + + +
+
+
+ + +

Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts

+ + + +
+

Seit kurzem haben wir VDSL von der Telekom (yeah!) und deshalb einen neuen Router. Das Gerät ist ein Speedport W 723V A mit relativ vielen Funktionen. Unter anderem können DECT-Telefone direkt angebunden werden und brauchen dann keinen eigene Basisstation. Diese Funktion wollte ich gerne nutzen, weil beim Anschluss des Telefons über die analoge TAE-Buchse nur eine Leitung genutzt werden kann und außerdem die Sprachqualität über die analoge Schnittstelle eher mäßig war.

+ + + +
+
+
+
+ + +

Reinventing the wheel: Automatic Bidirectional Directory Synchronization

+ + + +
+

As already mentioned, I am the proud owner of an online hard drive and I love it. Enough space for everything that's worth keeping, secure access over lots of different protocols (including rsync), an automatic backup function... It would be perfect if I had an Internet connection of at least 100 MBit/s. But I haven't. (Actually the thing almost feels like a local disk when I use it from my computer at work. But that's through a university network.) So I had to come up with a little more sophisticated architecture.

+ + + +
+
+
+
+ + +

Strato HiDrive unter Ubuntu einbinden

+ + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen.

+ + + +
+
+
+
+ + +

Neue E-Mail-Organisation - Inbox Zero

+ + + +
+

Nachdem Hosteurope nun schon seit einiger Zeit regelmäßig anmahnt, dass die Speicherplatz für E-Mails langsam zu Ende geht, woraufhin ich regelmäßig ein paar dicke Mails lösche um die Galgenfrist zu verlängern, habe ich nun endlich die Organisationsstruktur meines Posteingangs grundlegend erneuert. Bisher hatte ich zwar schon nach Jahren archiviert, die einzelnen E-Mails aber in ein recht komplexes System an Unterordnern einsortiert. (Einer für jeden Mailaccount, Unterordner für verschiedene Korrespondenzpartner und Themen, usw.

+ + + +
+
+
+
+ + +

Funambol SyncML-Server

+ + + +
+

Funambol ist derzeit die komfortabelste Möglichkeit, Adressen und Termine aus Thunderbird und Lightning mit dem Handy zu synchronisieren.

+ +

Funambol auf dem VPS installieren

+ +
    +
  1. Download und Ausführen von funambol-8.0.0.bin (Installation nach /opt/Funambol) ohne am Ende den Server zu starten
  2. +
  3. Anpassung von FUNAMBOL_HOME in /bin/funambol, /bin/funambol-server und /bin/install
+ + + +
+
+
+
+ + +

GPS mit dem E71: Initialzündung

+ + + +
+

Seit zweieinhalb Monaten habe ich ein Nokia E71 und bin eigentlich absolut zufrieden: Die Tastatur ist super (dafür gebe ich sogar gerne die Hälfte des Bildschirms im Vergleich zum iPhone her), E-Mail funktioniert wunderbar, Internet per WLAN für zu Hause, alles super. Nur das GPS... Ich hatte mich bewusst für ein Handy mit GPS entschieden, aber irgendwie wollte das Ding nicht recht. Bis zur Bestimmung der Position konnten gut 10 Minuten vergehen, absolut inakzeptabel.

+ + + +
+
+
+
+ + +

Erste Erfahrungen in 64 Bit

+ + + +
+

Seit ein paar Tagen bin ich auf Windows Vista umgestiegen. Und um ganz vorne mit dabei zu sein, durfte es gleich die 64-Bit-Variante sein - ich denke es ist absehbar, wann man sich über mehr als vier GB Arbeitsspeicher freuen wird. Bisher sind die Erfahrungen ganz gut, ein paar Ecken und Kanten gibt es aber:

+ + + +
+
+
+
+ + +

Borland Real48 in Java

+ + + +
+

When writing a converter tool for a binary file format, I had problems reading some of the floating point numbers. After a little bit of research I found out that this very special format was used in programs written in Borland Pascal/Delphi. Since I couldn't find any Java class that's able to read this kind of number I wrote it myself.

+ +

As far as I remember these are basically reverse IEEE floating point numbers of six bytes. (It's been a while since I wrote this. See the PDF file by Richard Biffl for a detailed description of the format.)

+ +

References:

+ + + +
+
+
+
+ + +

Informatiker-Zeitvertreib

+ + + +
+

Am 1.1. wollte Bettina unbedingt "Mensch ärgere dich nicht" spielen. Ich war nicht so begeistert, weil ich das Spiel für ziemlich langweilig halte. Zunächst diskutierten wir also meinen Standpunkt ("Da würfelt man doch nur abwechselnd") und den von Bettina ("Gar nicht, das hat voll viel mit Taktik zu tun"). Schlussendlich haben wir dann drei Runden gespielt. Später hatten wir Hunger und da nichts zu Essen im Haus war, haben wir uns Happy Meals bei McDonald's geholt. Als Spielzeug gab es "Monopoly Junior", also wurde auch das gespielt.

+ + + +
+
+
+
+ + +

Primat des Primaten: Ubuntu Gutsy Gibbon auf dem VPS 3.0

+ + + +
+

Mit etwas Überredung hat sich der Gibbon doch noch auf dem neuen Server wecken lassen. Anscheinend wird nach dem Upgrade der SSH-Port einfach nicht mehr abgehört. (Der Server lief ja.) Vermutlich liegt es daran, dass in Gutsy xinetd (und nicht mehr inetd) verwendet wird. Nach dem Upgrade auf Ubuntu 7.10 muss xinetd umkonfiguriert werden, damit der Daemon im inetd-Kompatibilitätsmodus startet und auch das inetd-configfile berücksichtigt.

+ + + +
+
+
+
+ + +

Subdomains

+ + + +
+

Problem: Normale Zertifikate gelten nur für eine (Sub-)Domain
+Erkenntnis: Es gibt auch Wildcard-Zertifikate, die alle Subdomains abdecken
+Folgefrage: Bekommt man diese Wildcardzertifikate von einer halbwegs anerkannten CA ohne kosten?

+ +

Allgemein zum Thema pro/contra Subdomains:
++ sie sehen hübsch aus
+- wirklich sinnvoll eingesetzt sind sie nur, wenn sie auf verschiedene Recher bzw. IPs zeigen, was sie bei uns nicht tun
+- uns fällt kein Service ein, für den eine Subdomain wirklich nötig wäre.

+ +

Die Entscheidung: Es sollen alle Dienste ohne Subdomain unter protokoll://siarp.de erreichbar sein.
+

+ + + +
+
+
+
+ + +

Sandkastenspiele I - Automatisches "svn update"

+ + + +
+

Ich habe ein Repository tests, in dem sich ein Verzeichnis automaticupdate/website befindet, das bei jedem Commit automatisch ins htdocs-Verzeichnis ausgecheckt werden soll.

+ +

Dazu erstelle ich ein Verzeichnis htdocs/tests und übertrage es an Benutzer svn.
+Danach wird manuell der 'initial checkout' durchgeführt:
+

su svn
+cd /usr/local/apache2/htdocs/tests
+svn checkout file:///home/svn-repos/tilman/tests/automaticupdate/website
+exit

+ +

Für die automatischen Updates wird jetzt noch ein hook-Skript geschrieben. Es heißt post-commit, gehört selbstverständlich dem Benutzer svn, ist ausführbar und liegt im Unterverzeichnis /hooks des Repository. (Da sind auch schon templates für die verschiedenen möglichen hooks.)
+

+ + + +
+
+
+
+ + +

Mein erstes echtes bash-Skript!

+ + + +
+

...erstellt ein Repository und liegt unter /root/tilman/create_repository.sh. Nächstes Ziel: Subversion hook script für automatisiertes Update, damit die Webentwicklung so richtig losgehen kann.
+

+ + + +
+
+
+
+ + +

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+ + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+
+ + + +
+
+
+ + + + + + +
+
+
+
+ Subscribe to Tilman‘s posts +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/13/index.html b/siarp.de/comment/13/index.html new file mode 100644 index 0000000..db0e684 --- /dev/null +++ b/siarp.de/comment/13/index.html @@ -0,0 +1,130 @@ + + + + + + + + + + + + SVN Migration | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

SVN Migration

+
+
+
+ + +
+
+ + + + + +
+

Migration von BerkeleyDB nach FSFS sollte ganz leicht sein.

+

Man kann einen Dump exportieren. Das ist eine menschenlesbare Datei, die man für heftige Änderungen auch bearbeiten kann. Tolle Sache das, damit gehen auch so Sachen, wie Zusammenlegung von zwei Repositories etc. Noch besser: LIES ES NACH. In der wie immer hervorragenden Doku.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Ich liebe Subversion! Wirklich!

+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/14/index.html b/siarp.de/comment/14/index.html new file mode 100644 index 0000000..bad9d92 --- /dev/null +++ b/siarp.de/comment/14/index.html @@ -0,0 +1,208 @@ + + + + + + + + + + + + Mein erstes echtes bash-Skript! | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Mein erstes echtes bash-Skript!

+
+
+
+ + +
+
+ + + + + +
+

...erstellt ein Repository und liegt unter /root/tilman/create_repository.sh. Nächstes Ziel: Subversion hook script für automatisiertes Update, damit die Webentwicklung so richtig losgehen kann.
+
+

#!/bin/sh
+
+# Erstellt ein Repository unterhalb von /home/svn-repos,
+# traegt es in die httpd.conf ein und startet Apache neu
+#
+# Optionen: -n um den Eintrag in die httpd.conf und den Apache-Neustart
+#   abzuschalten
+# Parameter: Pfad des neuen Repository (unterhalb von /home/svn-repos/)
+
+if [ $# -eq 2 ]
+then
+  if [ $1 == "-n" ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${2%\/}
+    repos=${repos#\/}
+    updateconf=false
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 1
+  fi
+else
+  if [ $# -eq 1 ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${1%\/}
+    repos=${repos#\/}
+    updateconf=true
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 2
+  fi
+fi
+
+mkdir /home/svn-repos/$repos
+svnadmin create /home/svn-repos/$repos
+chown -R svn.svn /home/svn-repos/$repos
+chmod -R ug+w /home/svn-repos/$repos
+chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/*
+
+# in httpd.conf eintragen und Apache neu starten
+if [ $updateconf = true ]
+then
+  echo "
+<Location /svn/$repos>
+  DAV svn
+  SVNPath /home/svn-repos/$repos
+  SVNIndexXSLT \"/subversion-xslt/svnindex.xsl\"
+  AuthType Basic
+  AuthName \"siarp.de repository\"
+  AuthUserFile /home/svn-repos/svn-auth-file
+  Require user martin tilman
+  SSLRequireSSL
+</Location>
+" >> /usr/local/apache2/conf/httpd.conf
+
+  /usr/local/apache2/bin/apachectl restart
+fi

+

+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

/usr/local/apache2/bin/apachectl restart

+ +

Was macht denn chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/* und warum geht das nicht rekursiv?

+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also eigentlich habe ich diese drei Zeilen mit den Rechten aus einer c't und benutze sie immer, ohne sie zu hinterfragen...

+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/15/index.html b/siarp.de/comment/15/index.html new file mode 100644 index 0000000..f54bb15 --- /dev/null +++ b/siarp.de/comment/15/index.html @@ -0,0 +1,208 @@ + + + + + + + + + + + + Mein erstes echtes bash-Skript! | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Mein erstes echtes bash-Skript!

+
+
+
+ + +
+
+ + + + + +
+

...erstellt ein Repository und liegt unter /root/tilman/create_repository.sh. Nächstes Ziel: Subversion hook script für automatisiertes Update, damit die Webentwicklung so richtig losgehen kann.
+
+

#!/bin/sh
+
+# Erstellt ein Repository unterhalb von /home/svn-repos,
+# traegt es in die httpd.conf ein und startet Apache neu
+#
+# Optionen: -n um den Eintrag in die httpd.conf und den Apache-Neustart
+#   abzuschalten
+# Parameter: Pfad des neuen Repository (unterhalb von /home/svn-repos/)
+
+if [ $# -eq 2 ]
+then
+  if [ $1 == "-n" ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${2%\/}
+    repos=${repos#\/}
+    updateconf=false
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 1
+  fi
+else
+  if [ $# -eq 1 ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${1%\/}
+    repos=${repos#\/}
+    updateconf=true
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 2
+  fi
+fi
+
+mkdir /home/svn-repos/$repos
+svnadmin create /home/svn-repos/$repos
+chown -R svn.svn /home/svn-repos/$repos
+chmod -R ug+w /home/svn-repos/$repos
+chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/*
+
+# in httpd.conf eintragen und Apache neu starten
+if [ $updateconf = true ]
+then
+  echo "
+<Location /svn/$repos>
+  DAV svn
+  SVNPath /home/svn-repos/$repos
+  SVNIndexXSLT \"/subversion-xslt/svnindex.xsl\"
+  AuthType Basic
+  AuthName \"siarp.de repository\"
+  AuthUserFile /home/svn-repos/svn-auth-file
+  Require user martin tilman
+  SSLRequireSSL
+</Location>
+" >> /usr/local/apache2/conf/httpd.conf
+
+  /usr/local/apache2/bin/apachectl restart
+fi

+

+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

/usr/local/apache2/bin/apachectl restart

+ +

Was macht denn chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/* und warum geht das nicht rekursiv?

+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also eigentlich habe ich diese drei Zeilen mit den Rechten aus einer c't und benutze sie immer, ohne sie zu hinterfragen...

+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/153/index.html b/siarp.de/comment/153/index.html new file mode 100644 index 0000000..8821b73 --- /dev/null +++ b/siarp.de/comment/153/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + + + Bazaar: incompatible format 2a and rich-root support | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Bazaar: incompatible format 2a and rich-root support

+
+
+
+ + +
+
+ + + + + +
+

I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message

+ +
bzr: ERROR: RemoteRepository(bzr+ssh://SERVER/path/to/repo/.bzr/)      
+is not compatible with
+CHKInventoryRepository('file:///path/to/repo/.bzr/repository/')
+different rich-root support
+ +

Reading http://www.nabble.com/bazaar-error-on-repository-td25868297.html it seems different Bazaar versions make different repository formats which are incompatible. But

+ +
+

[...] you could move the server to a rich root capable format; then + it would work (though crossing the format boundary can be slow). + 1.3.1 is new enough to support rich-root-pack.

+
+ +

So on the server I did

+ +
bzr upgrade --rich-root-pack repo/
+ +

and now it works. I can push my local branch to the remote repository.

+ +

But only once!

+ +

Second time I wanted to push I got another error:

+ +
bzr: ERROR: bzrlib.errors.ErrorFromSmartServer: Error received from smart server: ('error', "'Bazaar repository format 2a (needs bzr 1.16 or later)\\n'")
+ +

Looks like the format 2a, which is the default for Bazaar >= 2.0 is incompatible with the one on my server. Downgrading to an older format of my local tree did the trick:

+ +
bzr upgrade --format=1.14-rich-root
+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Thanks, helped a lot :)

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/157/index.html b/siarp.de/comment/157/index.html new file mode 100644 index 0000000..9f0ab44 --- /dev/null +++ b/siarp.de/comment/157/index.html @@ -0,0 +1,134 @@ + + + + + + + + + + + + Committeten auf deutsch | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Committeten auf deutsch

+
+
+
+ + +
+
+ + + + + +
+

Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:

+ +

Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...

+ +

Also, wisst ihr bescheid. Übersetzt eure Werkzeuge und pflegt die Sprachkultur!

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Für die Übersetzung von „Repository“ sollte man ähnlich lange bei einem Bier im Lebowski nachdenken. „Magazin“ gefällt mir nicht sonderlich gut.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/158/index.html b/siarp.de/comment/158/index.html new file mode 100644 index 0000000..f6e92e9 --- /dev/null +++ b/siarp.de/comment/158/index.html @@ -0,0 +1,452 @@ + + + + + + + + + + + + Using AppleScript and cURL to import Content from iPhoto into Drupal | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Using AppleScript and cURL to import Content from iPhoto into Drupal

+
+
+
+ + +
+
+ + + + + +
+

I'm using Apple's iPhoto to organize my private photographs and Drupal is what comes to my mind first when there's need for a web-based solution. Having lots of pictures from a recent trip I want to show people I started thinking about some kind of web gallery. Being a developer I need to come up with something fancier than just some stock gallery product like Gallery2 (actually I don't really know that product so bear with me). I did some research and found some article about different approaches to build photo galleries in Drupal and also a nice video tutorial. I've used image module and gallery module before but the flexibility that CCK extended by imagefield and imagecache and views seem to offer is just too tempting. + +But how would I get my hundreds of pictures imported into my yet-to-be-built gallery site? There are plenty of exporter plug-ins for iPhoto sending pictures to galleries like said Gallery2, Flickr and so on. I did not find much information on how to write a plug-in for iPhoto but I found some AppleScript code that did just an export to Drupal. This one seemed to be very outdated but it was a good start. I started a thread on the Drupal developer mailing list which gave me interesting options but I stayed with the concept of using cURL because it's the most flexible and probably the fasted way for my one-time requirement and there are no dependencies. The missing piece was this handbook page on d.o.

+ +

Note: The following is a kind of tutorial but the result is just a custom script that needs to be adjusted to your scenario.

+ +

AppleScript is probably not the most powerful language but it allows us to call shell scripts. The idea is to get all the image information from iPhoto and then use shell commands to upload to a Drupal site. The first step is to extract the cURL commands from the PHP code from the handbook page so I don't need a separate script. Here are the shell commands to create content on a Drupal site:

+ +

First we log in which means getting a cookie with session data.

+ +
curl http://localhost/drupal/?q=user \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'name=user' \
+        -F 'pass=pass' \
+        -F 'form_id=user_login' \
+        -F 'op=Log in' \
+        --output ~/response_login.html
+ +

This calls the user page with your username and password. Check response_login.html to see if this has been successful.

+ +

Next we need to get the security token of the content creation form.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        --output ~/response_create_form.html
+ +

I'm using a custom content type called "image" – substitute that with whatever your content type is. response_create_form.html contains the HTML form to add an image including the security token which we can extract using a perl regular expression:

+ +
s/.*edit-image-node-form-form-token" *value="([^"]*)".*/$1/s
+ +

Finally we actually upload our content.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'title=My Title' \
+        -F 'field_image[0][fid]=0' \
+        -F 'field_image[0][list]=1' \
+        -F 'files[field_image_0]=@/Users/me/myimage.jpg' \
+        -F 'body=My content.' \
+        -F 'name=Myself' \
+        -F 'status=1' \
+        -F 'revision=1' \
+        -F 'op=Save' \
+        -F 'form_id=image_node_form' \
+        -F 'form_token=63fe773e820d2a4565720ab3bd0fc991' \
+ +

Check your Drupal site – there should be new content. My content type contains an imagefield that takes the above values. The "@" makes cURL upload the actual file.

+ +

Now to upload all selected images in iPhoto to the Drupal site I merge the snippets above with the AppleScript from iPhotoToDrupal:

+ +

Update: I had an issue with special characters as I entered "'" in iPhoto's description field. I found out about quoted form of variablename which is used to escape strings in AppleScript to use them in shell scripts. This funtion puts the string in single quotes automatically so I couldn't use it like " -F 'body=" & quoted form of this_comment & "'". Fortunately it's also possible to quote the value only like -F body='xxx' so " -F body=" & quoted form of this_comment works. Just being at it I replaced it for other variables also. Finally, I added a "Done" dialog.

+ +
set DrupalUsername to "user"
+set DrupalPassword to "pass"
+set DrupalSite to "http://localhost/drupal/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                        set this_uploadfile to (POSIX path of this_imagefile)
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+ +

Just go to iPhoto, select some images and start the script. The images including title and description will be uploaded as new nodes to your Drupal site.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Hi-

+ +

Nice job. I've been trying to use your applescript but am getting an error, "the command exited with a non-zero status". My Drupal install has clean URLs on. Do I need to modify the strings in your script to fit, or will the "non-clean" URLs still work?

+ +

Here's the details on my parts: +Drupal 6.17 +iPhoto 7.1.5 (aka iPhoto '08)

+ +

Thanks!

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

In my Drupal 7.12 i needed to alter your regex line :

+ +
set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

to:

+ +
set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

Somehow the name attribute was "form_token" and not "edit-image-node-form-form-token" as your code suggested.

+ +

Now it works great. Thanks for sharing!

+ +

I also added on the fly image resizing. All credits here go to https://discussions.apple.com/thread/2174350?start=0&tstart=0 from where I borrowed the resize code.

+ +
set longest_side to 1024
+
+set DrupalUsername to "admin"
+set DrupalPassword to "XXXXXX"
+set DrupalSite to "http://localhost/~arminhelbach/drupal7/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+set tmp_path to "/tmp"
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                       
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        tell application "Image Events" to set t to PNG
+                        copy (my convert_image(this_imagefile as alias, tmp_path, longest_side)) to tmpimagefile
+                        set this_uploadfile to (POSIX path of tmpimagefile)
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[und][0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[und][0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_und_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                        do shell script "rm '" & this_uploadfile & "'"
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+
+
+on convert_image(this_item, target_path, longest_side)
+        tell application "Image Events"
+                try
+                        launch
+                        -- open the image file
+                        set this_image to open this_item
+                        tell application "Finder"
+                                set new_item to ((target_path) as string) & (name of this_item) & ".jpg"
+                        end tell
+                        copy dimensions of this_image to {current_width, current_height}
+                        if current_width is greater than current_height then
+                                set new_height to (longest_side * current_height) / current_width
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        scale this_image to size longest_side
+                                end if
+                        else
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        set new_height to (longest_side * current_width) / current_height
+                                        scale this_image to size new_height
+                                end if
+                        end if
+                        save this_image in new_item as JPEG
+                        return new_item
+                on error msg
+                        return msg
+                end try
+        end tell
+end convert_image
+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/161/index.html b/siarp.de/comment/161/index.html new file mode 100644 index 0000000..d39e5e7 --- /dev/null +++ b/siarp.de/comment/161/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + + Strato HiDrive unter Ubuntu einbinden | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Strato HiDrive unter Ubuntu einbinden

+
+
+
+ + +
+
+ + + + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per sshfs. Fühlt sich fast an, als wäre es die lokale Festplatte.

+ +

Vorbereitung:

+ +
sudo adduser username fuse         # Benutzer "username" der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)
+sudo mkdir /media/hidrive                    # Mountpoint anlegen
+sudo chmod 777 /media/hidrive
+ +

mount funktioniert so:

+ +
sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +

Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).

+ +

unmount so:

+ +
fusermount -u /media/hidrive
+ +

Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297

+ +

Das Login-Skript sieht dann so aus:

+ +
#!/bin/sh
+sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +


+ +
+ +

Edit:

+ +

Nachtrag

+ +

Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:

+ +
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
+ +

Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:

+ +
fusermount: failed to open /etc/fuse.conf: Permission denied
+ +

Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Funktioniert das bei dir noch? Bei mir kommt nach dem Login "remote host has disconnected".

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Bei mir gibt's dasselbe Problem.

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also bei mir geht es wunderbar :)

+
+
+ +
+
+
+ +
+ + + + + +

+ +
+

Hallo,

+ +

vielen Dank für den Tipp.

+ +

Klappt wunderbar auch unter der neusten Ubuntu Version 11.10 64bit.

+ +

Aber man muss noch die Datei /etc/fuse.conf bearbeitet und:

+ +

user_allow_other hinzufügen.

+ +

Gruß +Jens

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/162/index.html b/siarp.de/comment/162/index.html new file mode 100644 index 0000000..496d03d --- /dev/null +++ b/siarp.de/comment/162/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + + Strato HiDrive unter Ubuntu einbinden | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Strato HiDrive unter Ubuntu einbinden

+
+
+
+ + +
+
+ + + + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per sshfs. Fühlt sich fast an, als wäre es die lokale Festplatte.

+ +

Vorbereitung:

+ +
sudo adduser username fuse         # Benutzer "username" der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)
+sudo mkdir /media/hidrive                    # Mountpoint anlegen
+sudo chmod 777 /media/hidrive
+ +

mount funktioniert so:

+ +
sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +

Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).

+ +

unmount so:

+ +
fusermount -u /media/hidrive
+ +

Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297

+ +

Das Login-Skript sieht dann so aus:

+ +
#!/bin/sh
+sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +


+ +
+ +

Edit:

+ +

Nachtrag

+ +

Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:

+ +
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
+ +

Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:

+ +
fusermount: failed to open /etc/fuse.conf: Permission denied
+ +

Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Funktioniert das bei dir noch? Bei mir kommt nach dem Login "remote host has disconnected".

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Bei mir gibt's dasselbe Problem.

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also bei mir geht es wunderbar :)

+
+
+ +
+
+
+ +
+ + + + + +

+ +
+

Hallo,

+ +

vielen Dank für den Tipp.

+ +

Klappt wunderbar auch unter der neusten Ubuntu Version 11.10 64bit.

+ +

Aber man muss noch die Datei /etc/fuse.conf bearbeitet und:

+ +

user_allow_other hinzufügen.

+ +

Gruß +Jens

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/184/index.html b/siarp.de/comment/184/index.html new file mode 100644 index 0000000..55f8287 --- /dev/null +++ b/siarp.de/comment/184/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + + Strato HiDrive unter Ubuntu einbinden | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Strato HiDrive unter Ubuntu einbinden

+
+
+
+ + +
+
+ + + + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per sshfs. Fühlt sich fast an, als wäre es die lokale Festplatte.

+ +

Vorbereitung:

+ +
sudo adduser username fuse         # Benutzer "username" der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)
+sudo mkdir /media/hidrive                    # Mountpoint anlegen
+sudo chmod 777 /media/hidrive
+ +

mount funktioniert so:

+ +
sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +

Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).

+ +

unmount so:

+ +
fusermount -u /media/hidrive
+ +

Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297

+ +

Das Login-Skript sieht dann so aus:

+ +
#!/bin/sh
+sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +


+ +
+ +

Edit:

+ +

Nachtrag

+ +

Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:

+ +
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
+ +

Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:

+ +
fusermount: failed to open /etc/fuse.conf: Permission denied
+ +

Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Funktioniert das bei dir noch? Bei mir kommt nach dem Login "remote host has disconnected".

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Bei mir gibt's dasselbe Problem.

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also bei mir geht es wunderbar :)

+
+
+ +
+
+
+ +
+ + + + + +

+ +
+

Hallo,

+ +

vielen Dank für den Tipp.

+ +

Klappt wunderbar auch unter der neusten Ubuntu Version 11.10 64bit.

+ +

Aber man muss noch die Datei /etc/fuse.conf bearbeitet und:

+ +

user_allow_other hinzufügen.

+ +

Gruß +Jens

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/185/index.html b/siarp.de/comment/185/index.html new file mode 100644 index 0000000..cafb926 --- /dev/null +++ b/siarp.de/comment/185/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + + Strato HiDrive unter Ubuntu einbinden | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Strato HiDrive unter Ubuntu einbinden

+
+
+
+ + +
+
+ + + + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per sshfs. Fühlt sich fast an, als wäre es die lokale Festplatte.

+ +

Vorbereitung:

+ +
sudo adduser username fuse         # Benutzer "username" der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)
+sudo mkdir /media/hidrive                    # Mountpoint anlegen
+sudo chmod 777 /media/hidrive
+ +

mount funktioniert so:

+ +
sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +

Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).

+ +

unmount so:

+ +
fusermount -u /media/hidrive
+ +

Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297

+ +

Das Login-Skript sieht dann so aus:

+ +
#!/bin/sh
+sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +


+ +
+ +

Edit:

+ +

Nachtrag

+ +

Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:

+ +
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
+ +

Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:

+ +
fusermount: failed to open /etc/fuse.conf: Permission denied
+ +

Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Funktioniert das bei dir noch? Bei mir kommt nach dem Login "remote host has disconnected".

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Bei mir gibt's dasselbe Problem.

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also bei mir geht es wunderbar :)

+
+
+ +
+
+
+ +
+ + + + + +

+ +
+

Hallo,

+ +

vielen Dank für den Tipp.

+ +

Klappt wunderbar auch unter der neusten Ubuntu Version 11.10 64bit.

+ +

Aber man muss noch die Datei /etc/fuse.conf bearbeitet und:

+ +

user_allow_other hinzufügen.

+ +

Gruß +Jens

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/2/index.html b/siarp.de/comment/2/index.html new file mode 100644 index 0000000..3d2f76d --- /dev/null +++ b/siarp.de/comment/2/index.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+
+
+
+ + +
+
+ + + + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+

MySQL, Apache, PHP 5

+
  • + Nach Empfehlung von http://www.kofler.cc/forum/forumthread.php?rootID=3538 deinstalliere ich Apache, PHP und MySQL über yast.
    + Dabei ignoriere ich sämtliche Abhängigkeiten mit irgendwelchen installierten 'frontpage extensions', 'mambo' und vor allem dem Paket 'psa' → Plesk wird kastriert. +
    + $ rcapache2 stop
    + $ yast
    → nach 'mysql', 'php' und 'apache' suchen, alles raushauen und neu starten +
    +
  • +
  • + Ich lege im Home-Verzeichnis von root ein Verzeichnis siarp an, in dem ich herunterladen und entpacken kann. Dahin lade ich die Apache-Quellen, MySQL, PHP und Subversion. +
    + $ cd ~

    + $ md siarp
    + $ cd siarp
    + $ wget http://ftp.wayne.edu/apache/httpd/httpd-2.2.2.tar.gz
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-server-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-client-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-devel-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-shared-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://de2.php.net/get/php-5.1.4.tar.gz/from/de3.php.net/mirror +
    +
  • +
  • + Dann noch entpacken: +
    + $ gunzip httpd-2.2.2.tar.gz
    + $ gunzip php-5.1.4.tar.gz
    + $ tar -xvf httpd-2.2.2.tar
    + $ tar -xvf php-5.1.4.tar +
    +
  • +
  • + MySQL installieren +
    + $ cd ~/siarp
    + $ rpm -i MySQL*.rpm +
    +
  • +
  • + Weiter nach der Kofler-Anleitung: +
    + $ wget http://kent.dl.sourceforge.net/sourceforge/libpng/zlib-1.2.3.tar.gz
    + $ wget ftp://xmlsoft.org/libxml2/libxml2-2.6.24.tar.gz
    + $ gunzip zlib-1.2.3.tar.gz
    + $ gunzip libxml2-2.6.24.tar.gz
    + $ tar -xvf zlib-1.2.3.tar
    + $ tar -xvf libxml2-2.6.24.tar +
    +
  • +
  • + Installation der Libraries +
    + $ cd zlib-1.2.3/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd ..
    + $ cd libxml2-2.6.24/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + Apache2 in /usr/local/apache2 installieren. Ich habe hier noch ein paar zusätzliche Module aktiviert, WebDAV wird von Subversion benötigt. +
    + $ cd httpd-2.2.2/
    + $ ./configure --prefix=/usr/local/apache2 --enable-so --enable-dav --enable-ssl --enable-alias --enable-dir --enable-deflate
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + PHP installieren +
    + $ cd php-5.1.4/
    + $ ./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-libxml-dir=/usr/local/lib --with-zlib --with-zlib-dir=/usr/local/lib --with-mysql=/usr --with-mysqli=/usr/bin/mysql_config --with-gd --enable-soap --enable-sockets
    + $ make
    + $ make install +
    +
  • +
  • + In die /usr/local/apache2/conf/httpd.conf füge ich in Zeile 55 ein: +
    + #siarp (manuell eingefuegt nach php-Installation)
    + AddType application/x-httpd-php .php +
    +
  • +
  • + Testlauf +
    + $ /usr/local/apache2/bin/apachectl start
    + $ touch /usr/local/apache2/htdocs/phptest.php +
    +

    Dann in die Datei phptest.php die Zeile <?php phpinfo(); ?> einfügen und speichern. Und siehe: Die PHP-Konfiguration ist einsehbar. +

  • +
  • + Aber: Schon verhält er sich komisch! HTML-Seiten, in denen auf ein Bild verwiesen wird, werden nicht ausgeliefert. (Wieder das Dateigrößen-Problem?)
    Nach etwas Suchen dann die Lösung: In der httpd.conf muss die Zeile "EnableSendfile off" aktiviert werden (Z. 360). → Die Sendfile-Unterstützung wurde beim Kompilieren wohl nicht richtig erkannt; ein Klassiker.
    Frage: Sollte auch MMAP (Zeile darüber) deaktiviert werden? (Das war der Standard-Trick beim XAMPP.) Da MMAP und Sendfile aber wohl für Performanceverbesserungen stehen (größerer Adressraum, glaube ich), lasse ich zumindest MMAP bis auf Weiteres drin. +
  • +
  • + Weil's bis hierher so schön lief, logge ich mich in Virtuzzo ein, und erstelle vor der Subversion-Installation noch ein Backup.:
    + "May 27, 2006 01:48:45 PM, 580.83 Mb" (SuSE-Apache, -PHP und -MySQL deinstalliert und separat installiert) +
  • +

Subversion: Installation

+
  • + Erst mal zurück nach Hause und Subversion herunterladen und entpacken +
    + $ cd ~/siarp
    + $ wget http://subversion.tigris.org/downloads/subversion-1.3.1.tar.gz
    + $ gunzip subversion-1.3.1.tar.gz
    + $ tar -xvf subversion-1.3.1.tar +
    +
  • +
  • + Jetzt mit den magischen Parametern installieren. (Im Wesentlichen nach http://svn.collab.net/repos/svn/trunk/INSTALL mit Hilfe von http://iedb.org/blog/howtos/svn_install_de/.) +
    + $ cd subversion-1.3.1/
    + $ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib +
    +

    Am Schluss heult configure noch rum, dass keine BerkeleyDB installiert ist. Wunderbar, FSFS ist sowieso moderner. (→ http://svnbook.red-bean.com/en/1.1/ch05.html#svn-ch-5-sect-1.3.2 und Vergleich unter http://svnbook.red-bean.com/en/1.2/svn.reposadmin.html#svn.reposadmin.basics.backends)
    + Und weiter:

    +
    + $ make
    + $ make install +
    +
  • +
  • + Leider will Apache jetzt nicht mehr starten und meldet

    + httpd: Syntax error on line 54 of /usr/local/apache2/conf/httpd.conf: Cannot load /usr/local/apache2/modules/mod_dav_svn.so into server: libsvn_repos-1.so.0: cannot open shared object file: No such file or directory

    + Aber das kenne ich schon vom XAMPP - Google hilft. Unter http://svn.haxx.se/users/archive-2004-11/0390.shtml wird mir empfohlen, in der Datei /etc/ld.so.conf die Zeile /usr/local/lib einzufügen. Da die bereits vorhanden ist und ich ja auf die Libraries vom separat installierten Apache verweisen möchte, versuche ich es mit /usr/local/apache2/lib (weil make install am Schluss ausgiebt, dass die Libraries dorthin installiert wurden). Danach muss die Konfiguration erneuert werden: +
    + $ /sbin/ldconfig +
    +

    Und schon will er wieder. +

  • +

Subversion: Konfiguration

+
  • + Erste Frage: Wohin mit dem Repository? (Ich habe diese UNIX-Verzeichnisstruktur nie so wirklich verinnerlicht.) Nach einem Blick in http://de.wikibooks.org/wiki/Linux-Kompendium:_Verzeichnisse_unter_Linux bin ich nur unwesentlich schlauer und entscheide ich mich für /home/svn-repos. +
    + $ cd /home
    + $ md svn-repos +
    +
  • +
  • + Die zweite Frage ist, wofür und wieviele Repositories angelegt werden sollten. Ich beginne mal mit siarp. Subversion arbeitet dabei als Benutzer svn. +
    + $ cd /home/svn-repos
    + $ md siarp
    + $ svnadmin create /home/svn-repos/siarp
    + $ chown -R svn.svn /home/svn-repos/siarp
    + $ chmod -R ug+w /home/svn-repos/siarp
    + $ chmod ug+s /home/svn-repos/siarp /home/svn-repos/siarp/* +
    +
  • +
  • + Damit die Repositories etwas schöner gelistet werden, bringt Subversion noch ein Stylesheet für Apache mit, das in die htdocs muss. +
    + $ cd ~/siarp/subversion-1.3.1/tools/xslt/
    + $ md /usr/local/apache2/htdocs/subversion-xslt
    + $ cp * /usr/local/apache2/htdocs/subversion-xslt
    + $ chmod 644 /usr/local/apache2/htdocs/subversion-xslt/* +
    +
  • +
  • + Apache muss auf die Repositories zugreifen können. In der Subversion-Installationsanleitung heißt es dazu lapidar: +
    + NOTE: Make sure that the user 'nobody' (or whatever UID the httpd process runs as) has permission to read and write the Berkeley DB files! This is a very common problem. +
    +

    Davon weiß ich allerdings nicht, wie man das am sinnvollsten regelt. Auch im Subversion Handbuch steht nur was von "There is no single correct way to set up your permissions".
    + Die Repositories einfach allgemein freigben? In der schönen (und häufig zitierten) Deadbeef-Anleitung für Apache+Subversion wird einfach der gesamte Apache mit dem svn-User gestartet. Allerdings geht das nur, wenn man den Server nicht auf den Standard-Ports betreibt. Meine Lösung wird im Subversion Handbuch zwar nur angedeutet, sollte aber korrekt sein: Dem Apache über die httpd.conf mitteilen, dass er als Nutzer svn agieren soll. Also die Zeilen 70 und 71 ändern auf. (Davor lief Apache als daemon.)

    +
    + User svn
    + Group svn +
    +
  • +
  • + Jetzt muss noch Apache das neue Repository in der https.conf bekannt gegeben werden: +
    + # siarp Subversion-Anhang
    + <Location /svn/siarp>
    +   DAV svn
    +   SVNPath /home/svn-repos/siarp
    +    SVNIndexXSLT "/subversion-xslt/svnindex.xsl"
    +   AuthType Basic
    +   AuthName "siarp.de repository"
    +   AuthUserFile /home/svn-repos/svn-auth-file
    +   Require user martin tilman
    + </Location> +
    +
  • +
  • + Für die Nutzerverwaltung braucht Subversion ein Userfile, das ich unter /home/svn-repos/svn-auth-file anlegen will. Dafür muss ich das htpasswd-Tool vom Apache benutzen: +
    + $ /usr/local/apache2/bin/htpasswd -cm /home/svn-repos/svn-auth-file tilman

    + New password:
    + Re-type new password:
    + Adding password for user tilman
    +
    +

    Neue Benutzer fügt man mit dem Befehl /usr/local/apache2/bin/htpasswd -m /home/svn-repos/svn-auth-file benutzername hinzu. +

  • +
  • + Das war's. Subversion ist unter http://www.siarp.de/svn/siarp/ erreichbar, sobald Apache gestartet ist. +
    + $ /usr/local/apache2/bin/apachectl start +
    +
  • +
  • + Als krönenden Abschluss kopiere ich mein Protokoll in htdocs, so dass es unter http://www.siarp.de/installation-log.html erreichbar ist und mache mit Virtuzzo ein Backup ("May 27, 2006 05:41:32 PM, 707.27 Mb"). +
  • +

+

Zusammenfassung, To-Do und Fragen

+

+ So weit, so gut. Wir haben jetzt Apache mit MySQL und PHP und außerdem ein funktionierendes Subversion. Was muss jetzt noch kommen? +

+
  • Subversion mit SSL nutzen. Dafür habe ich Apache mit --enable-ssl kompiliert, aber noch nix probiert.
  • +
  • MySQL testen. Noch nicht gemacht.
  • +
  • Eventuell noch etwas Sicherheits-Tuning. MySQL ist noch unkonfiguriert (Passwort) und der Subversion-User ist auch noch ohne Passwort.
  • +
  • Noch mal eine schöne "Wie legt man ein Repository an"-Anleitung, die man dann nur noch abarbeiten muss
  • +
  • Automatisiertes Backup für Repositories und htdocs. Was noch?
  • +
  • Vielleicht sollte Apache nach einem Reboot automatisch starten. Wie das geht steht in der Kofler-Anleitung.
  • +
  • Noch mal die Frage: Brauchen wir System-Nutzer-Accounts? Oder müssen wir sowieso als root arbeiten, bei dem, was wir tun?
  • +

+ Allgemeine Bemerkungen zur Konfiguration +

+
  • Apache wird gestartet mit /usr/local/apache2/bin/apachectl start
  • +
  • Die Webseite liegt unter /usr/local/apache2/htdocs/, die Repositories unter /home/svn-repos/
  • +
  • Wir sollten wohl doch für jedes Projekt ein extra Repository anlegen, da sonst das System der Gesamt-Versionsnummer von Subversion keinen Sinn macht
  • +

+

Further reading: Backup und Vorsorge

+
  • + Noch ein paar Überlegungen zum Thema Backup: Virtuzzo geht relativ fix (ca. 20 Min), allerdings sind nur zwei Backups möglich. Also am besten später mal durch ein Backup des komplett eingerichteten Systems ersetzen. Dann hat man immer noch ein Backup für akutes übrig. +
  • +
  • + Im Hosteurope-Hilfesystem wird außerdem ReoBack empfohlen. Vielleicht bei Gelegenheit mal anschauen. +
  • +
  • + Noch was anderes: Anscheinend kann man (im Gegensatz zu den WebPacks) den Traffic nicht hart limitieren. Bis jetzt hatten wir beim Rumbasteln immer unter 400MB im Monat. Freivolumen ist laut KIS 250GB (die neuen Pakete haben 500GB bei gleichem Preis, das hätten sie ruhig mal rückwirkend upgraden können), das macht also ca. 8GB am Tag. Ich habe jedenfalls erst mal eine Warnbenachrichtigung bei mehr als 2GB am Tag eingerichtet. +
  • +
  • + Hab mich bei der Suche nach einer harten Traffic-Begrenzung nochmal in Plesk eingeloggt. Das ist jetzt wohl wirklich blind und taub, man bekommt keine Server-Optionen mehr angezeigt. +
  • +

Dank an (Linksammlung)

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Wie gesagt, es muss noch ein Repositories-erstellen-HowTo folgen. Um es zu dokumentieren schon mal die Bemerkung:

+

Man muss nicht unbedingt jedes Repository einzeln in die httpd.conf eintragen, sondern kann dort auch einen SVNParentPath angeben. Alle Repositories, die in diesem Verzeichnis liegen, werden dann automatisch gelistet. Nachteil: Keine getrennte Benutzerverwaltung für die verschiedenen Repositories (soweit mir bekannt --> nochmal prüfen)

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

Sammlung: Module, die vielleicht auch noch schön für'n Apache wären. (Lassen sich durch --enable-so ja nachträglich einbinden.)

+

- mod_deflate
+Dazu Zitat aus der Subversion-Installationsanleitung:
+If you have configured mod_deflate to be in the server, you can enable compression support for your repository by adding the following line to your Location block: SetOutputFilter DEFLATE

+

- mod_mime
+MIME-Zuordnung nach Dateinamenerweiterung

+

- mod_dav_fs
+Dieses Modul bietet Zugriff auf das _lokale_ Dateisystem, falls gebraucht. So oder so ist WebDAV an sich noch mal einen Blick wert.

+

- mod_vhost_alias
+Wird's gebraucht? Ich hab noch nicht so die Ahnung von vHost-Konzept.

+

- mod_dir
+Das habe ich vergessen. Directory-Listings sind mitunter schon ganz praktisch.

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

To do so, start the server, then issue the following commands:
+/usr/bin/mysqladmin -u root password 'new-password'
+/usr/bin/mysqladmin -u root -h lvps80-237-161-173.dedicated.hosteurope.de password 'new-password'
+See the manual for more instructions.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/200/index.html b/siarp.de/comment/200/index.html new file mode 100644 index 0000000..6a06ee1 --- /dev/null +++ b/siarp.de/comment/200/index.html @@ -0,0 +1,452 @@ + + + + + + + + + + + + Using AppleScript and cURL to import Content from iPhoto into Drupal | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Using AppleScript and cURL to import Content from iPhoto into Drupal

+
+
+
+ + +
+
+ + + + + +
+

I'm using Apple's iPhoto to organize my private photographs and Drupal is what comes to my mind first when there's need for a web-based solution. Having lots of pictures from a recent trip I want to show people I started thinking about some kind of web gallery. Being a developer I need to come up with something fancier than just some stock gallery product like Gallery2 (actually I don't really know that product so bear with me). I did some research and found some article about different approaches to build photo galleries in Drupal and also a nice video tutorial. I've used image module and gallery module before but the flexibility that CCK extended by imagefield and imagecache and views seem to offer is just too tempting. + +But how would I get my hundreds of pictures imported into my yet-to-be-built gallery site? There are plenty of exporter plug-ins for iPhoto sending pictures to galleries like said Gallery2, Flickr and so on. I did not find much information on how to write a plug-in for iPhoto but I found some AppleScript code that did just an export to Drupal. This one seemed to be very outdated but it was a good start. I started a thread on the Drupal developer mailing list which gave me interesting options but I stayed with the concept of using cURL because it's the most flexible and probably the fasted way for my one-time requirement and there are no dependencies. The missing piece was this handbook page on d.o.

+ +

Note: The following is a kind of tutorial but the result is just a custom script that needs to be adjusted to your scenario.

+ +

AppleScript is probably not the most powerful language but it allows us to call shell scripts. The idea is to get all the image information from iPhoto and then use shell commands to upload to a Drupal site. The first step is to extract the cURL commands from the PHP code from the handbook page so I don't need a separate script. Here are the shell commands to create content on a Drupal site:

+ +

First we log in which means getting a cookie with session data.

+ +
curl http://localhost/drupal/?q=user \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'name=user' \
+        -F 'pass=pass' \
+        -F 'form_id=user_login' \
+        -F 'op=Log in' \
+        --output ~/response_login.html
+ +

This calls the user page with your username and password. Check response_login.html to see if this has been successful.

+ +

Next we need to get the security token of the content creation form.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        --output ~/response_create_form.html
+ +

I'm using a custom content type called "image" – substitute that with whatever your content type is. response_create_form.html contains the HTML form to add an image including the security token which we can extract using a perl regular expression:

+ +
s/.*edit-image-node-form-form-token" *value="([^"]*)".*/$1/s
+ +

Finally we actually upload our content.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'title=My Title' \
+        -F 'field_image[0][fid]=0' \
+        -F 'field_image[0][list]=1' \
+        -F 'files[field_image_0]=@/Users/me/myimage.jpg' \
+        -F 'body=My content.' \
+        -F 'name=Myself' \
+        -F 'status=1' \
+        -F 'revision=1' \
+        -F 'op=Save' \
+        -F 'form_id=image_node_form' \
+        -F 'form_token=63fe773e820d2a4565720ab3bd0fc991' \
+ +

Check your Drupal site – there should be new content. My content type contains an imagefield that takes the above values. The "@" makes cURL upload the actual file.

+ +

Now to upload all selected images in iPhoto to the Drupal site I merge the snippets above with the AppleScript from iPhotoToDrupal:

+ +

Update: I had an issue with special characters as I entered "'" in iPhoto's description field. I found out about quoted form of variablename which is used to escape strings in AppleScript to use them in shell scripts. This funtion puts the string in single quotes automatically so I couldn't use it like " -F 'body=" & quoted form of this_comment & "'". Fortunately it's also possible to quote the value only like -F body='xxx' so " -F body=" & quoted form of this_comment works. Just being at it I replaced it for other variables also. Finally, I added a "Done" dialog.

+ +
set DrupalUsername to "user"
+set DrupalPassword to "pass"
+set DrupalSite to "http://localhost/drupal/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                        set this_uploadfile to (POSIX path of this_imagefile)
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+ +

Just go to iPhoto, select some images and start the script. The images including title and description will be uploaded as new nodes to your Drupal site.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Hi-

+ +

Nice job. I've been trying to use your applescript but am getting an error, "the command exited with a non-zero status". My Drupal install has clean URLs on. Do I need to modify the strings in your script to fit, or will the "non-clean" URLs still work?

+ +

Here's the details on my parts: +Drupal 6.17 +iPhoto 7.1.5 (aka iPhoto '08)

+ +

Thanks!

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

In my Drupal 7.12 i needed to alter your regex line :

+ +
set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

to:

+ +
set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

Somehow the name attribute was "form_token" and not "edit-image-node-form-form-token" as your code suggested.

+ +

Now it works great. Thanks for sharing!

+ +

I also added on the fly image resizing. All credits here go to https://discussions.apple.com/thread/2174350?start=0&tstart=0 from where I borrowed the resize code.

+ +
set longest_side to 1024
+
+set DrupalUsername to "admin"
+set DrupalPassword to "XXXXXX"
+set DrupalSite to "http://localhost/~arminhelbach/drupal7/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+set tmp_path to "/tmp"
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                       
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        tell application "Image Events" to set t to PNG
+                        copy (my convert_image(this_imagefile as alias, tmp_path, longest_side)) to tmpimagefile
+                        set this_uploadfile to (POSIX path of tmpimagefile)
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[und][0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[und][0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_und_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                        do shell script "rm '" & this_uploadfile & "'"
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+
+
+on convert_image(this_item, target_path, longest_side)
+        tell application "Image Events"
+                try
+                        launch
+                        -- open the image file
+                        set this_image to open this_item
+                        tell application "Finder"
+                                set new_item to ((target_path) as string) & (name of this_item) & ".jpg"
+                        end tell
+                        copy dimensions of this_image to {current_width, current_height}
+                        if current_width is greater than current_height then
+                                set new_height to (longest_side * current_height) / current_width
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        scale this_image to size longest_side
+                                end if
+                        else
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        set new_height to (longest_side * current_width) / current_height
+                                        scale this_image to size new_height
+                                end if
+                        end if
+                        save this_image in new_item as JPEG
+                        return new_item
+                on error msg
+                        return msg
+                end try
+        end tell
+end convert_image
+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/3/index.html b/siarp.de/comment/3/index.html new file mode 100644 index 0000000..b0c52a3 --- /dev/null +++ b/siarp.de/comment/3/index.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+
+
+
+ + +
+
+ + + + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+

MySQL, Apache, PHP 5

+
  • + Nach Empfehlung von http://www.kofler.cc/forum/forumthread.php?rootID=3538 deinstalliere ich Apache, PHP und MySQL über yast.
    + Dabei ignoriere ich sämtliche Abhängigkeiten mit irgendwelchen installierten 'frontpage extensions', 'mambo' und vor allem dem Paket 'psa' → Plesk wird kastriert. +
    + $ rcapache2 stop
    + $ yast
    → nach 'mysql', 'php' und 'apache' suchen, alles raushauen und neu starten +
    +
  • +
  • + Ich lege im Home-Verzeichnis von root ein Verzeichnis siarp an, in dem ich herunterladen und entpacken kann. Dahin lade ich die Apache-Quellen, MySQL, PHP und Subversion. +
    + $ cd ~

    + $ md siarp
    + $ cd siarp
    + $ wget http://ftp.wayne.edu/apache/httpd/httpd-2.2.2.tar.gz
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-server-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-client-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-devel-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-shared-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://de2.php.net/get/php-5.1.4.tar.gz/from/de3.php.net/mirror +
    +
  • +
  • + Dann noch entpacken: +
    + $ gunzip httpd-2.2.2.tar.gz
    + $ gunzip php-5.1.4.tar.gz
    + $ tar -xvf httpd-2.2.2.tar
    + $ tar -xvf php-5.1.4.tar +
    +
  • +
  • + MySQL installieren +
    + $ cd ~/siarp
    + $ rpm -i MySQL*.rpm +
    +
  • +
  • + Weiter nach der Kofler-Anleitung: +
    + $ wget http://kent.dl.sourceforge.net/sourceforge/libpng/zlib-1.2.3.tar.gz
    + $ wget ftp://xmlsoft.org/libxml2/libxml2-2.6.24.tar.gz
    + $ gunzip zlib-1.2.3.tar.gz
    + $ gunzip libxml2-2.6.24.tar.gz
    + $ tar -xvf zlib-1.2.3.tar
    + $ tar -xvf libxml2-2.6.24.tar +
    +
  • +
  • + Installation der Libraries +
    + $ cd zlib-1.2.3/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd ..
    + $ cd libxml2-2.6.24/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + Apache2 in /usr/local/apache2 installieren. Ich habe hier noch ein paar zusätzliche Module aktiviert, WebDAV wird von Subversion benötigt. +
    + $ cd httpd-2.2.2/
    + $ ./configure --prefix=/usr/local/apache2 --enable-so --enable-dav --enable-ssl --enable-alias --enable-dir --enable-deflate
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + PHP installieren +
    + $ cd php-5.1.4/
    + $ ./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-libxml-dir=/usr/local/lib --with-zlib --with-zlib-dir=/usr/local/lib --with-mysql=/usr --with-mysqli=/usr/bin/mysql_config --with-gd --enable-soap --enable-sockets
    + $ make
    + $ make install +
    +
  • +
  • + In die /usr/local/apache2/conf/httpd.conf füge ich in Zeile 55 ein: +
    + #siarp (manuell eingefuegt nach php-Installation)
    + AddType application/x-httpd-php .php +
    +
  • +
  • + Testlauf +
    + $ /usr/local/apache2/bin/apachectl start
    + $ touch /usr/local/apache2/htdocs/phptest.php +
    +

    Dann in die Datei phptest.php die Zeile <?php phpinfo(); ?> einfügen und speichern. Und siehe: Die PHP-Konfiguration ist einsehbar. +

  • +
  • + Aber: Schon verhält er sich komisch! HTML-Seiten, in denen auf ein Bild verwiesen wird, werden nicht ausgeliefert. (Wieder das Dateigrößen-Problem?)
    Nach etwas Suchen dann die Lösung: In der httpd.conf muss die Zeile "EnableSendfile off" aktiviert werden (Z. 360). → Die Sendfile-Unterstützung wurde beim Kompilieren wohl nicht richtig erkannt; ein Klassiker.
    Frage: Sollte auch MMAP (Zeile darüber) deaktiviert werden? (Das war der Standard-Trick beim XAMPP.) Da MMAP und Sendfile aber wohl für Performanceverbesserungen stehen (größerer Adressraum, glaube ich), lasse ich zumindest MMAP bis auf Weiteres drin. +
  • +
  • + Weil's bis hierher so schön lief, logge ich mich in Virtuzzo ein, und erstelle vor der Subversion-Installation noch ein Backup.:
    + "May 27, 2006 01:48:45 PM, 580.83 Mb" (SuSE-Apache, -PHP und -MySQL deinstalliert und separat installiert) +
  • +

Subversion: Installation

+
  • + Erst mal zurück nach Hause und Subversion herunterladen und entpacken +
    + $ cd ~/siarp
    + $ wget http://subversion.tigris.org/downloads/subversion-1.3.1.tar.gz
    + $ gunzip subversion-1.3.1.tar.gz
    + $ tar -xvf subversion-1.3.1.tar +
    +
  • +
  • + Jetzt mit den magischen Parametern installieren. (Im Wesentlichen nach http://svn.collab.net/repos/svn/trunk/INSTALL mit Hilfe von http://iedb.org/blog/howtos/svn_install_de/.) +
    + $ cd subversion-1.3.1/
    + $ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib +
    +

    Am Schluss heult configure noch rum, dass keine BerkeleyDB installiert ist. Wunderbar, FSFS ist sowieso moderner. (→ http://svnbook.red-bean.com/en/1.1/ch05.html#svn-ch-5-sect-1.3.2 und Vergleich unter http://svnbook.red-bean.com/en/1.2/svn.reposadmin.html#svn.reposadmin.basics.backends)
    + Und weiter:

    +
    + $ make
    + $ make install +
    +
  • +
  • + Leider will Apache jetzt nicht mehr starten und meldet

    + httpd: Syntax error on line 54 of /usr/local/apache2/conf/httpd.conf: Cannot load /usr/local/apache2/modules/mod_dav_svn.so into server: libsvn_repos-1.so.0: cannot open shared object file: No such file or directory

    + Aber das kenne ich schon vom XAMPP - Google hilft. Unter http://svn.haxx.se/users/archive-2004-11/0390.shtml wird mir empfohlen, in der Datei /etc/ld.so.conf die Zeile /usr/local/lib einzufügen. Da die bereits vorhanden ist und ich ja auf die Libraries vom separat installierten Apache verweisen möchte, versuche ich es mit /usr/local/apache2/lib (weil make install am Schluss ausgiebt, dass die Libraries dorthin installiert wurden). Danach muss die Konfiguration erneuert werden: +
    + $ /sbin/ldconfig +
    +

    Und schon will er wieder. +

  • +

Subversion: Konfiguration

+
  • + Erste Frage: Wohin mit dem Repository? (Ich habe diese UNIX-Verzeichnisstruktur nie so wirklich verinnerlicht.) Nach einem Blick in http://de.wikibooks.org/wiki/Linux-Kompendium:_Verzeichnisse_unter_Linux bin ich nur unwesentlich schlauer und entscheide ich mich für /home/svn-repos. +
    + $ cd /home
    + $ md svn-repos +
    +
  • +
  • + Die zweite Frage ist, wofür und wieviele Repositories angelegt werden sollten. Ich beginne mal mit siarp. Subversion arbeitet dabei als Benutzer svn. +
    + $ cd /home/svn-repos
    + $ md siarp
    + $ svnadmin create /home/svn-repos/siarp
    + $ chown -R svn.svn /home/svn-repos/siarp
    + $ chmod -R ug+w /home/svn-repos/siarp
    + $ chmod ug+s /home/svn-repos/siarp /home/svn-repos/siarp/* +
    +
  • +
  • + Damit die Repositories etwas schöner gelistet werden, bringt Subversion noch ein Stylesheet für Apache mit, das in die htdocs muss. +
    + $ cd ~/siarp/subversion-1.3.1/tools/xslt/
    + $ md /usr/local/apache2/htdocs/subversion-xslt
    + $ cp * /usr/local/apache2/htdocs/subversion-xslt
    + $ chmod 644 /usr/local/apache2/htdocs/subversion-xslt/* +
    +
  • +
  • + Apache muss auf die Repositories zugreifen können. In der Subversion-Installationsanleitung heißt es dazu lapidar: +
    + NOTE: Make sure that the user 'nobody' (or whatever UID the httpd process runs as) has permission to read and write the Berkeley DB files! This is a very common problem. +
    +

    Davon weiß ich allerdings nicht, wie man das am sinnvollsten regelt. Auch im Subversion Handbuch steht nur was von "There is no single correct way to set up your permissions".
    + Die Repositories einfach allgemein freigben? In der schönen (und häufig zitierten) Deadbeef-Anleitung für Apache+Subversion wird einfach der gesamte Apache mit dem svn-User gestartet. Allerdings geht das nur, wenn man den Server nicht auf den Standard-Ports betreibt. Meine Lösung wird im Subversion Handbuch zwar nur angedeutet, sollte aber korrekt sein: Dem Apache über die httpd.conf mitteilen, dass er als Nutzer svn agieren soll. Also die Zeilen 70 und 71 ändern auf. (Davor lief Apache als daemon.)

    +
    + User svn
    + Group svn +
    +
  • +
  • + Jetzt muss noch Apache das neue Repository in der https.conf bekannt gegeben werden: +
    + # siarp Subversion-Anhang
    + <Location /svn/siarp>
    +   DAV svn
    +   SVNPath /home/svn-repos/siarp
    +    SVNIndexXSLT "/subversion-xslt/svnindex.xsl"
    +   AuthType Basic
    +   AuthName "siarp.de repository"
    +   AuthUserFile /home/svn-repos/svn-auth-file
    +   Require user martin tilman
    + </Location> +
    +
  • +
  • + Für die Nutzerverwaltung braucht Subversion ein Userfile, das ich unter /home/svn-repos/svn-auth-file anlegen will. Dafür muss ich das htpasswd-Tool vom Apache benutzen: +
    + $ /usr/local/apache2/bin/htpasswd -cm /home/svn-repos/svn-auth-file tilman

    + New password:
    + Re-type new password:
    + Adding password for user tilman
    +
    +

    Neue Benutzer fügt man mit dem Befehl /usr/local/apache2/bin/htpasswd -m /home/svn-repos/svn-auth-file benutzername hinzu. +

  • +
  • + Das war's. Subversion ist unter http://www.siarp.de/svn/siarp/ erreichbar, sobald Apache gestartet ist. +
    + $ /usr/local/apache2/bin/apachectl start +
    +
  • +
  • + Als krönenden Abschluss kopiere ich mein Protokoll in htdocs, so dass es unter http://www.siarp.de/installation-log.html erreichbar ist und mache mit Virtuzzo ein Backup ("May 27, 2006 05:41:32 PM, 707.27 Mb"). +
  • +

+

Zusammenfassung, To-Do und Fragen

+

+ So weit, so gut. Wir haben jetzt Apache mit MySQL und PHP und außerdem ein funktionierendes Subversion. Was muss jetzt noch kommen? +

+
  • Subversion mit SSL nutzen. Dafür habe ich Apache mit --enable-ssl kompiliert, aber noch nix probiert.
  • +
  • MySQL testen. Noch nicht gemacht.
  • +
  • Eventuell noch etwas Sicherheits-Tuning. MySQL ist noch unkonfiguriert (Passwort) und der Subversion-User ist auch noch ohne Passwort.
  • +
  • Noch mal eine schöne "Wie legt man ein Repository an"-Anleitung, die man dann nur noch abarbeiten muss
  • +
  • Automatisiertes Backup für Repositories und htdocs. Was noch?
  • +
  • Vielleicht sollte Apache nach einem Reboot automatisch starten. Wie das geht steht in der Kofler-Anleitung.
  • +
  • Noch mal die Frage: Brauchen wir System-Nutzer-Accounts? Oder müssen wir sowieso als root arbeiten, bei dem, was wir tun?
  • +

+ Allgemeine Bemerkungen zur Konfiguration +

+
  • Apache wird gestartet mit /usr/local/apache2/bin/apachectl start
  • +
  • Die Webseite liegt unter /usr/local/apache2/htdocs/, die Repositories unter /home/svn-repos/
  • +
  • Wir sollten wohl doch für jedes Projekt ein extra Repository anlegen, da sonst das System der Gesamt-Versionsnummer von Subversion keinen Sinn macht
  • +

+

Further reading: Backup und Vorsorge

+
  • + Noch ein paar Überlegungen zum Thema Backup: Virtuzzo geht relativ fix (ca. 20 Min), allerdings sind nur zwei Backups möglich. Also am besten später mal durch ein Backup des komplett eingerichteten Systems ersetzen. Dann hat man immer noch ein Backup für akutes übrig. +
  • +
  • + Im Hosteurope-Hilfesystem wird außerdem ReoBack empfohlen. Vielleicht bei Gelegenheit mal anschauen. +
  • +
  • + Noch was anderes: Anscheinend kann man (im Gegensatz zu den WebPacks) den Traffic nicht hart limitieren. Bis jetzt hatten wir beim Rumbasteln immer unter 400MB im Monat. Freivolumen ist laut KIS 250GB (die neuen Pakete haben 500GB bei gleichem Preis, das hätten sie ruhig mal rückwirkend upgraden können), das macht also ca. 8GB am Tag. Ich habe jedenfalls erst mal eine Warnbenachrichtigung bei mehr als 2GB am Tag eingerichtet. +
  • +
  • + Hab mich bei der Suche nach einer harten Traffic-Begrenzung nochmal in Plesk eingeloggt. Das ist jetzt wohl wirklich blind und taub, man bekommt keine Server-Optionen mehr angezeigt. +
  • +

Dank an (Linksammlung)

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Wie gesagt, es muss noch ein Repositories-erstellen-HowTo folgen. Um es zu dokumentieren schon mal die Bemerkung:

+

Man muss nicht unbedingt jedes Repository einzeln in die httpd.conf eintragen, sondern kann dort auch einen SVNParentPath angeben. Alle Repositories, die in diesem Verzeichnis liegen, werden dann automatisch gelistet. Nachteil: Keine getrennte Benutzerverwaltung für die verschiedenen Repositories (soweit mir bekannt --> nochmal prüfen)

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

Sammlung: Module, die vielleicht auch noch schön für'n Apache wären. (Lassen sich durch --enable-so ja nachträglich einbinden.)

+

- mod_deflate
+Dazu Zitat aus der Subversion-Installationsanleitung:
+If you have configured mod_deflate to be in the server, you can enable compression support for your repository by adding the following line to your Location block: SetOutputFilter DEFLATE

+

- mod_mime
+MIME-Zuordnung nach Dateinamenerweiterung

+

- mod_dav_fs
+Dieses Modul bietet Zugriff auf das _lokale_ Dateisystem, falls gebraucht. So oder so ist WebDAV an sich noch mal einen Blick wert.

+

- mod_vhost_alias
+Wird's gebraucht? Ich hab noch nicht so die Ahnung von vHost-Konzept.

+

- mod_dir
+Das habe ich vergessen. Directory-Listings sind mitunter schon ganz praktisch.

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

To do so, start the server, then issue the following commands:
+/usr/bin/mysqladmin -u root password 'new-password'
+/usr/bin/mysqladmin -u root -h lvps80-237-161-173.dedicated.hosteurope.de password 'new-password'
+See the manual for more instructions.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/comment/4/index.html b/siarp.de/comment/4/index.html new file mode 100644 index 0000000..c1be7f6 --- /dev/null +++ b/siarp.de/comment/4/index.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+
+
+
+ + +
+
+ + + + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+

MySQL, Apache, PHP 5

+
  • + Nach Empfehlung von http://www.kofler.cc/forum/forumthread.php?rootID=3538 deinstalliere ich Apache, PHP und MySQL über yast.
    + Dabei ignoriere ich sämtliche Abhängigkeiten mit irgendwelchen installierten 'frontpage extensions', 'mambo' und vor allem dem Paket 'psa' → Plesk wird kastriert. +
    + $ rcapache2 stop
    + $ yast
    → nach 'mysql', 'php' und 'apache' suchen, alles raushauen und neu starten +
    +
  • +
  • + Ich lege im Home-Verzeichnis von root ein Verzeichnis siarp an, in dem ich herunterladen und entpacken kann. Dahin lade ich die Apache-Quellen, MySQL, PHP und Subversion. +
    + $ cd ~

    + $ md siarp
    + $ cd siarp
    + $ wget http://ftp.wayne.edu/apache/httpd/httpd-2.2.2.tar.gz
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-server-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-client-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-devel-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-shared-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://de2.php.net/get/php-5.1.4.tar.gz/from/de3.php.net/mirror +
    +
  • +
  • + Dann noch entpacken: +
    + $ gunzip httpd-2.2.2.tar.gz
    + $ gunzip php-5.1.4.tar.gz
    + $ tar -xvf httpd-2.2.2.tar
    + $ tar -xvf php-5.1.4.tar +
    +
  • +
  • + MySQL installieren +
    + $ cd ~/siarp
    + $ rpm -i MySQL*.rpm +
    +
  • +
  • + Weiter nach der Kofler-Anleitung: +
    + $ wget http://kent.dl.sourceforge.net/sourceforge/libpng/zlib-1.2.3.tar.gz
    + $ wget ftp://xmlsoft.org/libxml2/libxml2-2.6.24.tar.gz
    + $ gunzip zlib-1.2.3.tar.gz
    + $ gunzip libxml2-2.6.24.tar.gz
    + $ tar -xvf zlib-1.2.3.tar
    + $ tar -xvf libxml2-2.6.24.tar +
    +
  • +
  • + Installation der Libraries +
    + $ cd zlib-1.2.3/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd ..
    + $ cd libxml2-2.6.24/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + Apache2 in /usr/local/apache2 installieren. Ich habe hier noch ein paar zusätzliche Module aktiviert, WebDAV wird von Subversion benötigt. +
    + $ cd httpd-2.2.2/
    + $ ./configure --prefix=/usr/local/apache2 --enable-so --enable-dav --enable-ssl --enable-alias --enable-dir --enable-deflate
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + PHP installieren +
    + $ cd php-5.1.4/
    + $ ./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-libxml-dir=/usr/local/lib --with-zlib --with-zlib-dir=/usr/local/lib --with-mysql=/usr --with-mysqli=/usr/bin/mysql_config --with-gd --enable-soap --enable-sockets
    + $ make
    + $ make install +
    +
  • +
  • + In die /usr/local/apache2/conf/httpd.conf füge ich in Zeile 55 ein: +
    + #siarp (manuell eingefuegt nach php-Installation)
    + AddType application/x-httpd-php .php +
    +
  • +
  • + Testlauf +
    + $ /usr/local/apache2/bin/apachectl start
    + $ touch /usr/local/apache2/htdocs/phptest.php +
    +

    Dann in die Datei phptest.php die Zeile <?php phpinfo(); ?> einfügen und speichern. Und siehe: Die PHP-Konfiguration ist einsehbar. +

  • +
  • + Aber: Schon verhält er sich komisch! HTML-Seiten, in denen auf ein Bild verwiesen wird, werden nicht ausgeliefert. (Wieder das Dateigrößen-Problem?)
    Nach etwas Suchen dann die Lösung: In der httpd.conf muss die Zeile "EnableSendfile off" aktiviert werden (Z. 360). → Die Sendfile-Unterstützung wurde beim Kompilieren wohl nicht richtig erkannt; ein Klassiker.
    Frage: Sollte auch MMAP (Zeile darüber) deaktiviert werden? (Das war der Standard-Trick beim XAMPP.) Da MMAP und Sendfile aber wohl für Performanceverbesserungen stehen (größerer Adressraum, glaube ich), lasse ich zumindest MMAP bis auf Weiteres drin. +
  • +
  • + Weil's bis hierher so schön lief, logge ich mich in Virtuzzo ein, und erstelle vor der Subversion-Installation noch ein Backup.:
    + "May 27, 2006 01:48:45 PM, 580.83 Mb" (SuSE-Apache, -PHP und -MySQL deinstalliert und separat installiert) +
  • +

Subversion: Installation

+
  • + Erst mal zurück nach Hause und Subversion herunterladen und entpacken +
    + $ cd ~/siarp
    + $ wget http://subversion.tigris.org/downloads/subversion-1.3.1.tar.gz
    + $ gunzip subversion-1.3.1.tar.gz
    + $ tar -xvf subversion-1.3.1.tar +
    +
  • +
  • + Jetzt mit den magischen Parametern installieren. (Im Wesentlichen nach http://svn.collab.net/repos/svn/trunk/INSTALL mit Hilfe von http://iedb.org/blog/howtos/svn_install_de/.) +
    + $ cd subversion-1.3.1/
    + $ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib +
    +

    Am Schluss heult configure noch rum, dass keine BerkeleyDB installiert ist. Wunderbar, FSFS ist sowieso moderner. (→ http://svnbook.red-bean.com/en/1.1/ch05.html#svn-ch-5-sect-1.3.2 und Vergleich unter http://svnbook.red-bean.com/en/1.2/svn.reposadmin.html#svn.reposadmin.basics.backends)
    + Und weiter:

    +
    + $ make
    + $ make install +
    +
  • +
  • + Leider will Apache jetzt nicht mehr starten und meldet

    + httpd: Syntax error on line 54 of /usr/local/apache2/conf/httpd.conf: Cannot load /usr/local/apache2/modules/mod_dav_svn.so into server: libsvn_repos-1.so.0: cannot open shared object file: No such file or directory

    + Aber das kenne ich schon vom XAMPP - Google hilft. Unter http://svn.haxx.se/users/archive-2004-11/0390.shtml wird mir empfohlen, in der Datei /etc/ld.so.conf die Zeile /usr/local/lib einzufügen. Da die bereits vorhanden ist und ich ja auf die Libraries vom separat installierten Apache verweisen möchte, versuche ich es mit /usr/local/apache2/lib (weil make install am Schluss ausgiebt, dass die Libraries dorthin installiert wurden). Danach muss die Konfiguration erneuert werden: +
    + $ /sbin/ldconfig +
    +

    Und schon will er wieder. +

  • +

Subversion: Konfiguration

+
  • + Erste Frage: Wohin mit dem Repository? (Ich habe diese UNIX-Verzeichnisstruktur nie so wirklich verinnerlicht.) Nach einem Blick in http://de.wikibooks.org/wiki/Linux-Kompendium:_Verzeichnisse_unter_Linux bin ich nur unwesentlich schlauer und entscheide ich mich für /home/svn-repos. +
    + $ cd /home
    + $ md svn-repos +
    +
  • +
  • + Die zweite Frage ist, wofür und wieviele Repositories angelegt werden sollten. Ich beginne mal mit siarp. Subversion arbeitet dabei als Benutzer svn. +
    + $ cd /home/svn-repos
    + $ md siarp
    + $ svnadmin create /home/svn-repos/siarp
    + $ chown -R svn.svn /home/svn-repos/siarp
    + $ chmod -R ug+w /home/svn-repos/siarp
    + $ chmod ug+s /home/svn-repos/siarp /home/svn-repos/siarp/* +
    +
  • +
  • + Damit die Repositories etwas schöner gelistet werden, bringt Subversion noch ein Stylesheet für Apache mit, das in die htdocs muss. +
    + $ cd ~/siarp/subversion-1.3.1/tools/xslt/
    + $ md /usr/local/apache2/htdocs/subversion-xslt
    + $ cp * /usr/local/apache2/htdocs/subversion-xslt
    + $ chmod 644 /usr/local/apache2/htdocs/subversion-xslt/* +
    +
  • +
  • + Apache muss auf die Repositories zugreifen können. In der Subversion-Installationsanleitung heißt es dazu lapidar: +
    + NOTE: Make sure that the user 'nobody' (or whatever UID the httpd process runs as) has permission to read and write the Berkeley DB files! This is a very common problem. +
    +

    Davon weiß ich allerdings nicht, wie man das am sinnvollsten regelt. Auch im Subversion Handbuch steht nur was von "There is no single correct way to set up your permissions".
    + Die Repositories einfach allgemein freigben? In der schönen (und häufig zitierten) Deadbeef-Anleitung für Apache+Subversion wird einfach der gesamte Apache mit dem svn-User gestartet. Allerdings geht das nur, wenn man den Server nicht auf den Standard-Ports betreibt. Meine Lösung wird im Subversion Handbuch zwar nur angedeutet, sollte aber korrekt sein: Dem Apache über die httpd.conf mitteilen, dass er als Nutzer svn agieren soll. Also die Zeilen 70 und 71 ändern auf. (Davor lief Apache als daemon.)

    +
    + User svn
    + Group svn +
    +
  • +
  • + Jetzt muss noch Apache das neue Repository in der https.conf bekannt gegeben werden: +
    + # siarp Subversion-Anhang
    + <Location /svn/siarp>
    +   DAV svn
    +   SVNPath /home/svn-repos/siarp
    +    SVNIndexXSLT "/subversion-xslt/svnindex.xsl"
    +   AuthType Basic
    +   AuthName "siarp.de repository"
    +   AuthUserFile /home/svn-repos/svn-auth-file
    +   Require user martin tilman
    + </Location> +
    +
  • +
  • + Für die Nutzerverwaltung braucht Subversion ein Userfile, das ich unter /home/svn-repos/svn-auth-file anlegen will. Dafür muss ich das htpasswd-Tool vom Apache benutzen: +
    + $ /usr/local/apache2/bin/htpasswd -cm /home/svn-repos/svn-auth-file tilman

    + New password:
    + Re-type new password:
    + Adding password for user tilman
    +
    +

    Neue Benutzer fügt man mit dem Befehl /usr/local/apache2/bin/htpasswd -m /home/svn-repos/svn-auth-file benutzername hinzu. +

  • +
  • + Das war's. Subversion ist unter http://www.siarp.de/svn/siarp/ erreichbar, sobald Apache gestartet ist. +
    + $ /usr/local/apache2/bin/apachectl start +
    +
  • +
  • + Als krönenden Abschluss kopiere ich mein Protokoll in htdocs, so dass es unter http://www.siarp.de/installation-log.html erreichbar ist und mache mit Virtuzzo ein Backup ("May 27, 2006 05:41:32 PM, 707.27 Mb"). +
  • +

+

Zusammenfassung, To-Do und Fragen

+

+ So weit, so gut. Wir haben jetzt Apache mit MySQL und PHP und außerdem ein funktionierendes Subversion. Was muss jetzt noch kommen? +

+
  • Subversion mit SSL nutzen. Dafür habe ich Apache mit --enable-ssl kompiliert, aber noch nix probiert.
  • +
  • MySQL testen. Noch nicht gemacht.
  • +
  • Eventuell noch etwas Sicherheits-Tuning. MySQL ist noch unkonfiguriert (Passwort) und der Subversion-User ist auch noch ohne Passwort.
  • +
  • Noch mal eine schöne "Wie legt man ein Repository an"-Anleitung, die man dann nur noch abarbeiten muss
  • +
  • Automatisiertes Backup für Repositories und htdocs. Was noch?
  • +
  • Vielleicht sollte Apache nach einem Reboot automatisch starten. Wie das geht steht in der Kofler-Anleitung.
  • +
  • Noch mal die Frage: Brauchen wir System-Nutzer-Accounts? Oder müssen wir sowieso als root arbeiten, bei dem, was wir tun?
  • +

+ Allgemeine Bemerkungen zur Konfiguration +

+
  • Apache wird gestartet mit /usr/local/apache2/bin/apachectl start
  • +
  • Die Webseite liegt unter /usr/local/apache2/htdocs/, die Repositories unter /home/svn-repos/
  • +
  • Wir sollten wohl doch für jedes Projekt ein extra Repository anlegen, da sonst das System der Gesamt-Versionsnummer von Subversion keinen Sinn macht
  • +

+

Further reading: Backup und Vorsorge

+
  • + Noch ein paar Überlegungen zum Thema Backup: Virtuzzo geht relativ fix (ca. 20 Min), allerdings sind nur zwei Backups möglich. Also am besten später mal durch ein Backup des komplett eingerichteten Systems ersetzen. Dann hat man immer noch ein Backup für akutes übrig. +
  • +
  • + Im Hosteurope-Hilfesystem wird außerdem ReoBack empfohlen. Vielleicht bei Gelegenheit mal anschauen. +
  • +
  • + Noch was anderes: Anscheinend kann man (im Gegensatz zu den WebPacks) den Traffic nicht hart limitieren. Bis jetzt hatten wir beim Rumbasteln immer unter 400MB im Monat. Freivolumen ist laut KIS 250GB (die neuen Pakete haben 500GB bei gleichem Preis, das hätten sie ruhig mal rückwirkend upgraden können), das macht also ca. 8GB am Tag. Ich habe jedenfalls erst mal eine Warnbenachrichtigung bei mehr als 2GB am Tag eingerichtet. +
  • +
  • + Hab mich bei der Suche nach einer harten Traffic-Begrenzung nochmal in Plesk eingeloggt. Das ist jetzt wohl wirklich blind und taub, man bekommt keine Server-Optionen mehr angezeigt. +
  • +

Dank an (Linksammlung)

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Wie gesagt, es muss noch ein Repositories-erstellen-HowTo folgen. Um es zu dokumentieren schon mal die Bemerkung:

+

Man muss nicht unbedingt jedes Repository einzeln in die httpd.conf eintragen, sondern kann dort auch einen SVNParentPath angeben. Alle Repositories, die in diesem Verzeichnis liegen, werden dann automatisch gelistet. Nachteil: Keine getrennte Benutzerverwaltung für die verschiedenen Repositories (soweit mir bekannt --> nochmal prüfen)

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

Sammlung: Module, die vielleicht auch noch schön für'n Apache wären. (Lassen sich durch --enable-so ja nachträglich einbinden.)

+

- mod_deflate
+Dazu Zitat aus der Subversion-Installationsanleitung:
+If you have configured mod_deflate to be in the server, you can enable compression support for your repository by adding the following line to your Location block: SetOutputFilter DEFLATE

+

- mod_mime
+MIME-Zuordnung nach Dateinamenerweiterung

+

- mod_dav_fs
+Dieses Modul bietet Zugriff auf das _lokale_ Dateisystem, falls gebraucht. So oder so ist WebDAV an sich noch mal einen Blick wert.

+

- mod_vhost_alias
+Wird's gebraucht? Ich hab noch nicht so die Ahnung von vHost-Konzept.

+

- mod_dir
+Das habe ich vergessen. Directory-Listings sind mitunter schon ganz praktisch.

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

To do so, start the server, then issue the following commands:
+/usr/bin/mysqladmin -u root password 'new-password'
+/usr/bin/mysqladmin -u root -h lvps80-237-161-173.dedicated.hosteurope.de password 'new-password'
+See the manual for more instructions.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/index/index.html b/siarp.de/index/index.html new file mode 100644 index 0000000..bc1a490 --- /dev/null +++ b/siarp.de/index/index.html @@ -0,0 +1,849 @@ + + + + + + + + + + + siarp.de | hm... Name! + + + + + + + + + + + + + +
+
+ + + + +
+
+
+ + +
+

siarp.de is a project started by Tilman and Martin many years ago. Basically it is about running your own virtual server for experimenting with technology and running a few services on the web.

+
+
+
+
+
+
+
+ + +
+
+ + +

Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts

+ + + +
+

Seit kurzem haben wir VDSL von der Telekom (yeah!) und deshalb einen neuen Router. Das Gerät ist ein Speedport W 723V A mit relativ vielen Funktionen. Unter anderem können DECT-Telefone direkt angebunden werden und brauchen dann keinen eigene Basisstation. Diese Funktion wollte ich gerne nutzen, weil beim Anschluss des Telefons über die analoge TAE-Buchse nur eine Leitung genutzt werden kann und außerdem die Sprachqualität über die analoge Schnittstelle eher mäßig war.

+ + + +
+
+ + +

Reinventing the wheel: Automatic Bidirectional Directory Synchronization

+ + + +
+

As already mentioned, I am the proud owner of an online hard drive and I love it. Enough space for everything that's worth keeping, secure access over lots of different protocols (including rsync), an automatic backup function... It would be perfect if I had an Internet connection of at least 100 MBit/s. But I haven't. (Actually the thing almost feels like a local disk when I use it from my computer at work. But that's through a university network.) So I had to come up with a little more sophisticated architecture.

+ + + +
+
+ + +

MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren

+ + + +
+
sudo vim /etc/apt/sources.list
+> # MongoDB
+> deb http://downloads.mongodb.org/distros/ubuntu 9.4 10gen

+sudo aptitude update && sudo aptitude install mongodb-stable

+sudo /etc/init.d/mongodb start

+git clone http://github.com/ry/node.git
+cd node
+git checkout -b tags/v0.2.0
+./configure --prefix=/home/martin
+make
+make install

+curl http://npmjs.org/install.sh | sh
+npm install mongodb mustache
+
+ + + +
+
+ + +

Strato HiDrive unter Ubuntu einbinden

+ + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen.

+ + + +
+
+ + +

Committeten auf deutsch

+ + + +
+

Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:

+ +

Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...

+ +

Also, wisst ihr bescheid.

+
+ + + +
+
+ + +

Plone: Item Type as Criterion for Collection but not to show up in Search

+ + + +
+

You can't select an item type as a criterion for a collection if it is not selected to be included in search results. In the "Search settings" (/@@search-controlpanel) you can exclude certain content types from being "searched and be available in the user facing part of the site". That actually corresponds to the list of types_not_searched in site_properties.

+ + + +
+
+ + +

My SilverStripe Usability Test

+ + + +
+

So I decided to try out SilveStripe (Version 2.3.3) to check out if it's of any value for me as a freelance web developer. I'm kind of an expert in Drupal, I also work with Plone, and lately I'm very interested in usability and I do track initiatives in the Drupal and Plone community to give users a better experience. I know that feedback of a first-time user is valuable so I thought I'd write down my impressions of SilverStripe right away.

+ + + +
+
+ + +

YAML und Listen im IE6

+ + + +
+

Achtung! Böse Falle mit YAML und Listen im Internet Explorer 6! Folgender Code steht in der iehacks.css und gilt für den IE6.

+ + + +
+
+ + +

YAML, jQuery slideToggle and IE6

+ + + +
+

As usual with browser bugs and hacks this took me a while to find out.

+ +

I have an unordered list with complex items like floats and stuff. This list is supposed to hide when I click on a button by slowly decreasing its height. I use jQuery's slideToggle for that.

+ +

Problem: In Internet Explorer 6 the content (or parts of it) is hidden after the list is shown (slid down).

+ + + +
+
+ + +

Bazaar: incompatible format 2a and rich-root support

+ + + +
+

I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message

+ + + +
+
+ + +

Neue E-Mail-Organisation - Inbox Zero

+ + + +
+

Nachdem Hosteurope nun schon seit einiger Zeit regelmäßig anmahnt, dass die Speicherplatz für E-Mails langsam zu Ende geht, woraufhin ich regelmäßig ein paar dicke Mails lösche um die Galgenfrist zu verlängern, habe ich nun endlich die Organisationsstruktur meines Posteingangs grundlegend erneuert. Bisher hatte ich zwar schon nach Jahren archiviert, die einzelnen E-Mails aber in ein recht komplexes System an Unterordnern einsortiert. (Einer für jeden Mailaccount, Unterordner für verschiedene Korrespondenzpartner und Themen, usw.

+ + + +
+
+ + +

Funambol SyncML-Server

+ + + +
+

Funambol ist derzeit die komfortabelste Möglichkeit, Adressen und Termine aus Thunderbird und Lightning mit dem Handy zu synchronisieren.

+ +

Funambol auf dem VPS installieren

+ +
    +
  1. Download und Ausführen von funambol-8.0.0.bin (Installation nach /opt/Funambol) ohne am Ende den Server zu starten
  2. +
  3. Anpassung von FUNAMBOL_HOME in /bin/funambol, /bin/funambol-server und /bin/install
+ + + +
+
+ + +

Ruby on Rails deployen

+ + + +
+

Das Szenario: Es sollen neben statischen Webseiten und PHP-Anwendungen auch Ruby-on-Rails-Anwendungen auf dem Server laufen. Die klassische Variante ist für jede Rails-Anwendung einen oder mehrere (Load Balancing) Mongrel-Server laufen zu lassen und die mittels Reverse Proxy hinter den Apache zu schalten (Port 80, SSL, Sicherheit). Außerdem gibt es (relativ neu) das Apache-Modul Phusion Passenger (a.k.a. mod_rails / mod_rack).

+ + + +
+
+ + +

GPS mit dem E71: Initialzündung

+ + + +
+

Seit zweieinhalb Monaten habe ich ein Nokia E71 und bin eigentlich absolut zufrieden: Die Tastatur ist super (dafür gebe ich sogar gerne die Hälfte des Bildschirms im Vergleich zum iPhone her), E-Mail funktioniert wunderbar, Internet per WLAN für zu Hause, alles super. Nur das GPS... Ich hatte mich bewusst für ein Handy mit GPS entschieden, aber irgendwie wollte das Ding nicht recht. Bis zur Bestimmung der Position konnten gut 10 Minuten vergehen, absolut inakzeptabel.

+ + + +
+
+ + +

Plone 3: How to really exclude from navigation

+ + + +
+

Plone has multiple ways of excluding a content object from the navigation:

+ + + +
+
+ + +

Enabling Gallery2‘s language support by configuring locales in Ubuntu 7.10 (Gutsy)

+ + + +
+

Gallery2 didn‘t want to talk German to me :(

+ + + +
+
+ + +

Using AppleScript and cURL to import Content from iPhoto into Drupal

+ + + +
+

I'm using Apple's iPhoto to organize my private photographs and Drupal is what comes to my mind first when there's need for a web-based solution. Having lots of pictures from a recent trip I want to show people I started thinking about some kind of web gallery. Being a developer I need to come up with something fancier than just some stock gallery product like Gallery2 (actually I don't really know that product so bear with me). I did some research and found some article about different approaches to build photo galleries in Drupal and also a nice video tutorial. I've used image module and gallery module before but the flexibility that CCK extended by imagefield and imagecache and views seem to offer is just too tempting. +

+ + + +
+
+ + +

Erste Erfahrungen in 64 Bit

+ + + +
+

Seit ein paar Tagen bin ich auf Windows Vista umgestiegen. Und um ganz vorne mit dabei zu sein, durfte es gleich die 64-Bit-Variante sein - ich denke es ist absehbar, wann man sich über mehr als vier GB Arbeitsspeicher freuen wird. Bisher sind die Erfahrungen ganz gut, ein paar Ecken und Kanten gibt es aber:

+ + + +
+
+ + +

Borland Real48 in Java

+ + + +
+

When writing a converter tool for a binary file format, I had problems reading some of the floating point numbers. After a little bit of research I found out that this very special format was used in programs written in Borland Pascal/Delphi. Since I couldn't find any Java class that's able to read this kind of number I wrote it myself.

+ +

As far as I remember these are basically reverse IEEE floating point numbers of six bytes. (It's been a while since I wrote this. See the PDF file by Richard Biffl for a detailed description of the format.)

+ +

References:

+ + + +
+
+ + +

Ubuntu-Installation: den größten freien Speicherbereich benutzen

+ + + +
+

Installiert man Ubuntu zum ersten Mal auf einem Windows-Rechner ist die Auswahl bei der Partitionierung der Festplatte meist einfach: erste Partition verkleinern und den freigewordenen Platz zur Installation nutzen. Wenn man wie ich aber schon zum hundertsten Male (oder zum zweiten Mal) eine Linux-Distribution auf so einem Rechner installiert, möchte man den irgendwann mal erstellten Bereich jenseits von Windows nutzen.

+ + + +
+
+ + +

Drupal-Tutorial: Administratoren-Blog

+ + + +
+

Für das Siarp-Portal (derzeit Drupal 5) wollten wir eine Möglichkeit haben, Meldungen oder Nachrichten zu kommunizieren, die über Vorgänge bei Projekten wie der Server-Administration oder auch dem Siarp-Portal selber informieren. Da das eher einem ausführlichen Changelog ähnelt sollte, wollten wir es nicht über das Project-Modul laufen lassen. Eher eine Art Blog mit bestimmten Rechten und Einstellungen und einer gesonderten Ansicht, wofür Drupal ja bestens ausgerüstet ist.
+

+ + + +
+
+ + +

Informatiker-Zeitvertreib

+ + + +
+

Am 1.1. wollte Bettina unbedingt "Mensch ärgere dich nicht" spielen. Ich war nicht so begeistert, weil ich das Spiel für ziemlich langweilig halte. Zunächst diskutierten wir also meinen Standpunkt ("Da würfelt man doch nur abwechselnd") und den von Bettina ("Gar nicht, das hat voll viel mit Taktik zu tun"). Schlussendlich haben wir dann drei Runden gespielt. Später hatten wir Hunger und da nichts zu Essen im Haus war, haben wir uns Happy Meals bei McDonald's geholt. Als Spielzeug gab es "Monopoly Junior", also wurde auch das gespielt.

+ + + +
+
+ + +

Buildout-basiertes Zope2 (Plone) unter Debian/Ubuntu installieren

+ + + +
+

Ubuntu 8.04 Server / Plone 3.1.5.1

+ +

Voraussetzungen buildout:

+ +

$ sudo aptitude install gcc python2.4 python2.4-dev python-imaging python-elementtree

+ +

(Für Ubuntu Desktop muss noch zlib1g-dev installiert werden.)

+ +

Ergänzung von <a href="http://siarp.de/node/167" rel="nofollow">http://siarp.de/node/167</a> für Plone 3.3 unter Ubuntu Jaunty
+========================================================================
+
+Ubuntu Jaunty enthält zwar Python 2.4 aber keine Image Library (PIL) für 2.4.
+Diese kann auch als Egg mittels buildout installiert werden [1]. Dafür braucht

+

+ + + +
+
+ + +

Krasse Sache APC

+ + + +
+

Aufgrund des Vortrags von Rasmus Lehrdorf auf der FrOSCon 2008 hab ich mir mal kurz APC, den Alternative PHP Cache angesehen. Wollte damit nicht viel Zeit verbringen, aber unsere Drupal-Seiten auf siarp.de laufen eher langsam, weil der Drupal-Cache nur für anonyme Besucher funktioniert und wir alles schön personalisiert und geschützt haben.

+ + + +
+
+ + +

Zope unter Fedora 9

+ + + +
+

Fedora 9 bringt nur Python 2.5, Zope benötigt z.Z. aber Python 2.4. Das Repository http://rpm.livna.org/ bietet alle nötigen Pakete.

+ + + +
+
+ + +

Primat des Primaten: Ubuntu Gutsy Gibbon auf dem VPS 3.0

+ + + +
+

Mit etwas Überredung hat sich der Gibbon doch noch auf dem neuen Server wecken lassen. Anscheinend wird nach dem Upgrade der SSH-Port einfach nicht mehr abgehört. (Der Server lief ja.) Vermutlich liegt es daran, dass in Gutsy xinetd (und nicht mehr inetd) verwendet wird. Nach dem Upgrade auf Ubuntu 7.10 muss xinetd umkonfiguriert werden, damit der Daemon im inetd-Kompatibilitätsmodus startet und auch das inetd-configfile berücksichtigt.

+ + + +
+
+ + +

Plone: Entwicklungsumgebung Mac

+ + + +
+

10.4 Tiger

+ +

Dem Buch "Professional Plone Development" von Martin Aspeli folgend, soll nicht auf einen fertigen Installer zurückgegriffen werden. Ein automatisierter Build-Out Prozess soll möglich sein.

+ +

OS X 10.4.10 liefert zwar Python 2.4 mit, es fehlt aber z.B. ein Wrapper für die libxml2. Um nicht unnötig im System rumzufummeln, soll MacPorts verwendet werden:

+ +

$ sudo port install python24 py-libxml2 py-elementtree py-pil

+ +

+ + + +
+
+ + +

Reservierte Begriffe in JavaScript

+ + + +
+

abstract (r)
+anchors (b)
+applets (b)
+arguments (g)
+Array (g)
+as (z)
+Boolean (g)
+boolean (r)
+break (t)
+byte (r)
+case (t)
+catch (t)
+char (r)
+class (r)
+const (r)
+continue (t)
+Date (g)
+debugger (r)
+decodeURI (g)
+decodeURIComponent (g)
+default (t)
+delete (t)
+do (t)
+document (b)
+double (r)
+elements (b)
+else (t)
+encodeURI (g)
+enum (r)
+Error (g)
+escape (g)
+eval (g)
+EvalError (g)
+export (r)
+extend (r)
+false (t)
+final (r)
+finally (t)
+float (r)
+for (t)
+forms (b)
+frames (b)
+Function (g)
+function (t)
+goto (r)
+history (b)
+if (t)
+images (b)
+implements (r)
+

+ + + +
+
+ + +

Subdomains

+ + + +
+

Problem: Normale Zertifikate gelten nur für eine (Sub-)Domain
+Erkenntnis: Es gibt auch Wildcard-Zertifikate, die alle Subdomains abdecken
+Folgefrage: Bekommt man diese Wildcardzertifikate von einer halbwegs anerkannten CA ohne kosten?

+ +

Allgemein zum Thema pro/contra Subdomains:
++ sie sehen hübsch aus
+- wirklich sinnvoll eingesetzt sind sie nur, wenn sie auf verschiedene Recher bzw. IPs zeigen, was sie bei uns nicht tun
+- uns fällt kein Service ein, für den eine Subdomain wirklich nötig wäre.

+ +

Die Entscheidung: Es sollen alle Dienste ohne Subdomain unter protokoll://siarp.de erreichbar sein.
+

+ + + +
+
+ + +

Sandkastenspiele I - Automatisches "svn update"

+ + + +
+

Ich habe ein Repository tests, in dem sich ein Verzeichnis automaticupdate/website befindet, das bei jedem Commit automatisch ins htdocs-Verzeichnis ausgecheckt werden soll.

+ +

Dazu erstelle ich ein Verzeichnis htdocs/tests und übertrage es an Benutzer svn.
+Danach wird manuell der 'initial checkout' durchgeführt:
+

su svn
+cd /usr/local/apache2/htdocs/tests
+svn checkout file:///home/svn-repos/tilman/tests/automaticupdate/website
+exit

+ +

Für die automatischen Updates wird jetzt noch ein hook-Skript geschrieben. Es heißt post-commit, gehört selbstverständlich dem Benutzer svn, ist ausführbar und liegt im Unterverzeichnis /hooks des Repository. (Da sind auch schon templates für die verschiedenen möglichen hooks.)
+

+ + + +
+
+ + +

Mein erstes echtes bash-Skript!

+ + + +
+

...erstellt ein Repository und liegt unter /root/tilman/create_repository.sh. Nächstes Ziel: Subversion hook script für automatisiertes Update, damit die Webentwicklung so richtig losgehen kann.
+

+ + + +
+
+ + +

SVN Migration

+ + + +
+

Migration von BerkeleyDB nach FSFS sollte ganz leicht sein.

+

Man kann einen Dump exportieren. Das ist eine menschenlesbare Datei, die man für heftige Änderungen auch bearbeiten kann. Tolle Sache das, damit gehen auch so Sachen, wie Zusammenlegung von zwei Repositories etc. Noch besser: LIES ES NACH. In der wie immer hervorragenden Doku.

+
+ + + +
+
+ + +

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+ + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+
+ + + +
+
+ + +

Erste Apache-Konfiguration

+ + + +
+

"SIARP.de" - ich sehe meinen Namen in Leuchtbuchstaben...

+ +

Wir fassten den Entschluss, die aufgefächerte Konfiguration zu einer handlichen kleinen httpd.conf zusammenzuführen. Ein Backup der (fast) originalen Konfigurationdateien befindet sich in /home/root/bak/apache2.tar.gz. Dann haben wir festgestellt, dass es zwingend das Verzeichnis samt Dateien sysconfig.d erfordert. Also die betreffenden Teile wieder ausgelagert und TADA! - "SIARP.de".

+
+ + + +
+
+
+
+
+ Subscribe to siarp.de RSS +
+ + + +
+
+ + + + diff --git a/siarp.de/martin/index.xml b/siarp.de/martin/index.xml new file mode 100644 index 0000000..cf6f87b --- /dev/null +++ b/siarp.de/martin/index.xml @@ -0,0 +1,111 @@ + + + Martin‘s posts + http://siarp.de/blog/2 + + en + + + MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren + http://siarp.de/node/229 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><div class="geshifilter"><div class="text geshifilter-text">sudo vim /etc/apt/sources.list<br /> +&gt; # MongoDB<br /> +&gt; deb http://downloads.mongodb.org/distros/ubuntu 9.4 10gen<br /><br /> +sudo aptitude update &amp;&amp; sudo aptitude install mongodb-stable<br /><br /> +sudo /etc/init.d/mongodb start<br /><br /> +git clone http://github.com/ry/node.git<br /> +cd node<br /> +git checkout -b tags/v0.2.0<br /> +./configure --prefix=/home/martin<br /> +make<br /> +make install<br /><br /> +curl http://npmjs.org/install.sh | sh<br /> +npm install mongodb mustache</div></div> +</div></div></div> + Thu, 26 Aug 2010 11:33:58 +0000 + Martin + 229 at http://siarp.de + + + Committeten auf deutsch + http://siarp.de/node/227 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:</p> + +<p>Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...</p> + +<p>Also, wisst ihr bescheid.</p> +</div></div></div> + Thu, 06 May 2010 20:01:37 +0000 + Martin + 227 at http://siarp.de + + + Plone: Item Type as Criterion for Collection but not to show up in Search + http://siarp.de/node/223 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>You can't select an item type as a criterion for a collection if it is not selected to be included in search results. In the "Search settings" (<span class="geshifilter"><code class="text geshifilter-text">/@@search-controlpanel</code></span>) you can exclude certain content types from being "searched and be available in the user facing part of the site". That actually corresponds to the list of <span class="geshifilter"><code class="text geshifilter-text">types_not_searched</code></span> in <span class="geshifilter"><code class="text geshifilter-text">site_properties</code></span>.</p></div></div></div> + Mon, 16 Nov 2009 14:13:07 +0000 + Martin + 223 at http://siarp.de + + + My SilverStripe Usability Test + http://siarp.de/node/222 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>So I decided to try out <a href="http://silverstripe.org/">SilveStripe</a> (Version 2.3.3) to check out if it's of any value for me as a freelance web developer. I'm kind of an expert in <a href="http://drupal.org/">Drupal</a>, I also work with <a href="http://plone.org/">Plone</a>, and lately I'm very interested in usability and I do track initiatives in the Drupal and Plone community to give users a better experience. I know that feedback of a first-time user is valuable so I thought I'd write down my impressions of SilverStripe right away.</p></div></div></div> + Sat, 14 Nov 2009 10:44:13 +0000 + Martin + 222 at http://siarp.de + + + YAML und Listen im IE6 + http://siarp.de/node/221 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Achtung! Böse Falle mit YAML und Listen im Internet Explorer 6! Folgender Code steht in der iehacks.css und gilt für den IE6.</p></div></div></div> + Wed, 11 Nov 2009 09:52:50 +0000 + Martin + 221 at http://siarp.de + + + YAML, jQuery slideToggle and IE6 + http://siarp.de/node/220 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>As usual with browser bugs and hacks this took me a while to find out.</p> + +<p>I have an unordered list with complex items like floats and stuff. This list is supposed to hide when I click on a button by slowly decreasing its height. I use <a href="http://docs.jquery.com/Effects/slideToggle">jQuery's slideToggle</a> for that.</p> + +<p><strong>Problem:</strong> In Internet Explorer 6 the content (or parts of it) is hidden after the list is shown (slid down).</p></div></div></div> + Fri, 06 Nov 2009 13:46:36 +0000 + Martin + 220 at http://siarp.de + + + Bazaar: incompatible format 2a and rich-root support + http://siarp.de/node/218 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message</p></div></div></div> + Mon, 26 Oct 2009 09:38:36 +0000 + Martin + 218 at http://siarp.de + + + Ruby on Rails deployen + http://siarp.de/node/204 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Das Szenario: Es sollen neben statischen Webseiten und PHP-Anwendungen auch Ruby-on-Rails-Anwendungen auf dem Server laufen. Die klassische Variante ist für jede Rails-Anwendung einen oder mehrere (Load Balancing) <a href="http://mongrel.rubyforge.org/">Mongrel</a>-Server laufen zu lassen und die mittels <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">Reverse Proxy</a> hinter den Apache zu schalten (Port 80, SSL, Sicherheit). Außerdem gibt es (relativ neu) das Apache-Modul <a href="http://www.modrails.com/">Phusion Passenger (a.k.a. mod_rails / mod_rack)</a>.</p></div></div></div> + Sun, 27 Sep 2009 13:29:27 +0000 + Martin + 204 at http://siarp.de + + + Plone 3: How to really exclude from navigation + http://siarp.de/node/201 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Plone has multiple ways of excluding a content object from the navigation:</p></div></div></div> + Thu, 20 Aug 2009 22:49:35 +0000 + Martin + 201 at http://siarp.de + + + Enabling Gallery2‘s language support by configuring locales in Ubuntu 7.10 (Gutsy) + http://siarp.de/node/199 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Gallery2 didn‘t want to talk German to me :(</p></div></div></div> + Sat, 09 May 2009 10:14:20 +0000 + Martin + 199 at http://siarp.de + + + diff --git a/siarp.de/misc/draggable/index.png b/siarp.de/misc/draggable/index.png new file mode 100644 index 0000000..93d20d6 Binary files /dev/null and b/siarp.de/misc/draggable/index.png differ diff --git a/siarp.de/misc/feed/index.png b/siarp.de/misc/feed/index.png new file mode 100644 index 0000000..e3f5067 Binary files /dev/null and b/siarp.de/misc/feed/index.png differ diff --git a/siarp.de/misc/grippie/index.png b/siarp.de/misc/grippie/index.png new file mode 100644 index 0000000..fbd8431 Binary files /dev/null and b/siarp.de/misc/grippie/index.png differ diff --git a/siarp.de/misc/help/index.png b/siarp.de/misc/help/index.png new file mode 100644 index 0000000..dcc5cac Binary files /dev/null and b/siarp.de/misc/help/index.png differ diff --git a/siarp.de/misc/menu-collapsed/index.png b/siarp.de/misc/menu-collapsed/index.png new file mode 100644 index 0000000..91f3fd4 Binary files /dev/null and b/siarp.de/misc/menu-collapsed/index.png differ diff --git a/siarp.de/misc/menu-expanded/index.png b/siarp.de/misc/menu-expanded/index.png new file mode 100644 index 0000000..46f39ec Binary files /dev/null and b/siarp.de/misc/menu-expanded/index.png differ diff --git a/siarp.de/misc/menu-leaf/index.png b/siarp.de/misc/menu-leaf/index.png new file mode 100644 index 0000000..6b2d63f Binary files /dev/null and b/siarp.de/misc/menu-leaf/index.png differ diff --git a/siarp.de/misc/message-24-error/index.png b/siarp.de/misc/message-24-error/index.png new file mode 100644 index 0000000..b094180 Binary files /dev/null and b/siarp.de/misc/message-24-error/index.png differ diff --git a/siarp.de/misc/message-24-ok/index.png b/siarp.de/misc/message-24-ok/index.png new file mode 100644 index 0000000..bd36669 Binary files /dev/null and b/siarp.de/misc/message-24-ok/index.png differ diff --git a/siarp.de/misc/message-24-warning/index.png b/siarp.de/misc/message-24-warning/index.png new file mode 100644 index 0000000..183297d Binary files /dev/null and b/siarp.de/misc/message-24-warning/index.png differ diff --git a/siarp.de/misc/progress/index.gif b/siarp.de/misc/progress/index.gif new file mode 100644 index 0000000..f84a9de Binary files /dev/null and b/siarp.de/misc/progress/index.gif differ diff --git a/siarp.de/misc/throbber-active/index.gif b/siarp.de/misc/throbber-active/index.gif new file mode 100644 index 0000000..f88bfde Binary files /dev/null and b/siarp.de/misc/throbber-active/index.gif differ diff --git a/siarp.de/misc/throbber-inactive/index.png b/siarp.de/misc/throbber-inactive/index.png new file mode 100644 index 0000000..f914667 Binary files /dev/null and b/siarp.de/misc/throbber-inactive/index.png differ diff --git a/siarp.de/misc/tree-bottom/index.png b/siarp.de/misc/tree-bottom/index.png new file mode 100644 index 0000000..a558045 Binary files /dev/null and b/siarp.de/misc/tree-bottom/index.png differ diff --git a/siarp.de/misc/tree/index.png b/siarp.de/misc/tree/index.png new file mode 100644 index 0000000..89ea235 Binary files /dev/null and b/siarp.de/misc/tree/index.png differ diff --git a/siarp.de/misc/watchdog-ok/index.png b/siarp.de/misc/watchdog-ok/index.png new file mode 100644 index 0000000..1d7baa0 Binary files /dev/null and b/siarp.de/misc/watchdog-ok/index.png differ diff --git a/siarp.de/modules/file/icons/application-octet-stream/index.png b/siarp.de/modules/file/icons/application-octet-stream/index.png new file mode 100644 index 0000000..d545321 Binary files /dev/null and b/siarp.de/modules/file/icons/application-octet-stream/index.png differ diff --git a/siarp.de/modules/file/icons/image-x-generic/index.png b/siarp.de/modules/file/icons/image-x-generic/index.png new file mode 100644 index 0000000..c1b814f Binary files /dev/null and b/siarp.de/modules/file/icons/image-x-generic/index.png differ diff --git a/siarp.de/modules/file/icons/package-x-generic/index.png b/siarp.de/modules/file/icons/package-x-generic/index.png new file mode 100644 index 0000000..21fc382 Binary files /dev/null and b/siarp.de/modules/file/icons/package-x-generic/index.png differ diff --git a/siarp.de/modules/file/icons/x-office-spreadsheet/index.png b/siarp.de/modules/file/icons/x-office-spreadsheet/index.png new file mode 100644 index 0000000..9af7b61 Binary files /dev/null and b/siarp.de/modules/file/icons/x-office-spreadsheet/index.png differ diff --git a/siarp.de/node/113/index.html b/siarp.de/node/113/index.html new file mode 100644 index 0000000..f7e90cc --- /dev/null +++ b/siarp.de/node/113/index.html @@ -0,0 +1,228 @@ + + + + + + + + + + + + Reservierte Begriffe in JavaScript | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Reservierte Begriffe in JavaScript

+
+
+
+ + +
+
+ + + + + +
+

abstract (r)
+anchors (b)
+applets (b)
+arguments (g)
+Array (g)
+as (z)
+Boolean (g)
+boolean (r)
+break (t)
+byte (r)
+case (t)
+catch (t)
+char (r)
+class (r)
+const (r)
+continue (t)
+Date (g)
+debugger (r)
+decodeURI (g)
+decodeURIComponent (g)
+default (t)
+delete (t)
+do (t)
+document (b)
+double (r)
+elements (b)
+else (t)
+encodeURI (g)
+enum (r)
+Error (g)
+escape (g)
+eval (g)
+EvalError (g)
+export (r)
+extend (r)
+false (t)
+final (r)
+finally (t)
+float (r)
+for (t)
+forms (b)
+frames (b)
+Function (g)
+function (t)
+goto (r)
+history (b)
+if (t)
+images (b)
+implements (r)
+import (r)
+in (t)
+Infinity (g)
+instanceof (t)
+int (r)
+interface (r)
+is (z)
+isFinite (g)
+isNaN (g)
+links (b)
+location (b)
+long (r)
+Math (g)
+namespace (z)
+NaN (g)
+native (r)
+navigator (b)
+new (t)
+null (t)
+Number (g)
+Object (g)
+options (b)
+package (r)
+parent (b)
+parseFloat (g)
+parseInt (g)
+private (r)
+protected (r)
+public (r)
+RangeError (g)
+ReferenceError (g)
+RegExp (g)
+return (t)
+screen (b)
+self (b)
+short (r)
+static (r)
+String (g)
+super (r)
+switch (t)
+synchronized (r)
+SyntaxError (g)
+this (t)
+throw (t)
+throws (r)
+top (b)
+transient (r)
+true (t)
+try (t)
+TypeError (g)
+typeof (t)
+undefined (g)
+unescape (g)
+URIError (g)
+use (z)
+var (t)
+void (t)
+volatile (r)
+while (t)
+window (b)
+with (t)

+ +

(t): Tatsächlich genutzte Begriffe in ECMAScript-262 v3
+(r): Reservierte aber ungenutzte Begriffe in ECMAScript-262 v3
+(z): Möglicherweise reserviert in ECMAScript-262 v4
+(g): Global gesetzte Variablen in ECMAScript-262 v3
+(b): Gesetzte Variablen im DOM

+ + + + +
AttachmentSize
Office spreadsheet icon reserved_words.xls38 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/135/index.html b/siarp.de/node/135/index.html new file mode 100644 index 0000000..fb8b99a --- /dev/null +++ b/siarp.de/node/135/index.html @@ -0,0 +1,153 @@ + + + + + + + + + + + + Plone: Entwicklungsumgebung Mac | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Plone: Entwicklungsumgebung Mac

+
+
+
+ + +
+
+ + + + + +
+

10.4 Tiger

+ +

Dem Buch "Professional Plone Development" von Martin Aspeli folgend, soll nicht auf einen fertigen Installer zurückgegriffen werden. Ein automatisierter Build-Out Prozess soll möglich sein.

+ +

OS X 10.4.10 liefert zwar Python 2.4 mit, es fehlt aber z.B. ein Wrapper für die libxml2. Um nicht unnötig im System rumzufummeln, soll MacPorts verwendet werden:

+ +

$ sudo port install python24 py-libxml2 py-elementtree py-pil

+ +

MacPorts' Python-Packages werden in /opt/local/lib/python2.4/site-packages installiert. Irgendwo ist allerding /opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages als Installationspfad für reine Python-Packages angegeben.

+ +

Um nun Python-Packages installieren zu können, ohne in MacPorts-Installationspfade einzugreifen, werden wir ein virtuelles Python im home-Verzeichnis erstellen (http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python). Anders als beschrieben funktioniert das mit dem Installationspfad aber nicht automatisch (vermutlich wegen dem "irgendwo angegebenen" Pfad). Im Verzeichnis ~/lib/python2.4/site-packages werden .pth-Dateien nicht ausgewertet. Es muss dieses Verzeicnis im $PYTHONPATH angegeben sein.

+ +

In ~/.profile:
+

export PYTHONPATH=~/lib/python2.4/site-packages:$PYTHONPATH

+ +

Bei jeder Installation im virtuellen Python muss jetzt auch noch das Präfix angegeben werden:

+ +

$ ~/bin/python ez_setup.py --prefix=~

+ +

bzw.

+ +

$ ~/bin/easy_setup --prefix=~ ZopeSkel

+ +
+ +

Mit dem Befehl

+ +

$ ./bin/instance fg

+ +

soll der Server automatisch im Debug-Modus gestartet werden. Das ist bei mir aber nicht der Fall. Beim Buildout oder In der buildout.cfg muss explixit der Modus angegeben werden, was dann in die zope.cfg übernommen wird.

+ +

Möglicher Weise liegt es daran, dass parts/instance/bin/runzope statt parts/instance/bin/zopectl ausgefürt wird (http://www.nabble.com/Foreground,-but-not-debug.-t2287152.html).

+ +

10.5 Leopard (Ergänzungen)

+ +

Python 2.4 muss mit MacPorts installiert werden. Leopard bringt nur 2.5 mit. Die Variante "puredarwin" verhindert die Erstellung eines Frameworks (s. Beschreibung Tiger).

+ +

sudo port install python24 +puredarwin

+ +

Alle weiteren Python-Pakete müssen dann auch mit der Variante "puredarwin" installiert werden.

+ +

Mit dem Paket "py-setuptools" wird auch gleich das Skript "easy_install" installiert.

+ +

Dann noch "py-pil" und "py-elementtree"...

+ +

sudo easy_install ZopeSkel

+ +

Und am Ende doch noch ein virtuelles Python in ~/bin/ installiert, um den komplizierten Pfad /opt/local/bin/python2.4 zu vereinfachen und vielleicht doch mal nur hier etwas zu installieren.

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/143/index.html b/siarp.de/node/143/index.html new file mode 100644 index 0000000..e8fd28e --- /dev/null +++ b/siarp.de/node/143/index.html @@ -0,0 +1,133 @@ + + + + + + + + + + + + Primat des Primaten: Ubuntu Gutsy Gibbon auf dem VPS 3.0 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Primat des Primaten: Ubuntu Gutsy Gibbon auf dem VPS 3.0

+
+
+
+ + +
+
+ + + + + +
+

Mit etwas Überredung hat sich der Gibbon doch noch auf dem neuen Server wecken lassen. Anscheinend wird nach dem Upgrade der SSH-Port einfach nicht mehr abgehört. (Der Server lief ja.) Vermutlich liegt es daran, dass in Gutsy xinetd (und nicht mehr inetd) verwendet wird. Nach dem Upgrade auf Ubuntu 7.10 muss xinetd umkonfiguriert werden, damit der Daemon im inetd-Kompatibilitätsmodus startet und auch das inetd-configfile berücksichtigt. (Freundlicherweise wird man beim Upgrade ja auch eigentlich gewarnt: If you are indeed using xinetd, you will have to convert the above into /etc/xinetd.conf format, and add it manually. See /usr/share/doc/xinetd/README.Debian for more information.)

+ +

Also: Nach dem Upgrade auf Gutsy vor dem Reboot /etc/init.d/xinetd editieren und in die Startkonfiguration um den Parameter -inetd_compat erweitern.

+ +

start-stop-daemon --start --quiet --background --exec /usr/sbin/xinetd -- -pidfile /var/run/xinetd.pid $XINETD_OPTS

+ +

wird zu

+ +

start-stop-daemon --start --quiet --background --exec /usr/sbin/xinetd -- -inetd_compat -pidfile /var/run/xinetd.pid $XINETD_OPTS

+ +

Nochmal das Upgrade-Protokoll in Kurzfassung:
+

apt-get update
+apt-get upgrade
+apt-get install mc     :)
+apt-get dist-upgrade
+<span style="font-style:italic"> /etc/apt/sources.list auf gutsy geändert</span>
+apt-get update
+apt-get dist-upgrade
+<span style="font-style:italic"> xinetd im inetd-Kompatibilitätsmodus starten: <a href="http://ubuntuforums.org/showthread.php?t=200408&page=2" rel="nofollow">http://ubuntuforums.org/showthread.php?t=200408&page=2</a></span>
+/etc/init.d/xinetd restart
+reboot

+
+

+ +

Quellen:
+http://ubuntuforums.org/showthread.php?t=200408&page=2

+ +

ps: Ein paar Dinge sind mir aber immer noch nicht ganz klar: Wie virtuell ist die Kiste bei Hosteurope jetzt eigentlich? Woher kommt der Kernel (/boot ist ja leer)? Und warum läuft auf einem vServer Samba?

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/160/index.html b/siarp.de/node/160/index.html new file mode 100644 index 0000000..7d320f2 --- /dev/null +++ b/siarp.de/node/160/index.html @@ -0,0 +1,111 @@ + + + + + + + + + + + + Zope unter Fedora 9 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Zope unter Fedora 9

+
+
+
+ + +
+
+ + + + + +
+

Fedora 9 bringt nur Python 2.5, Zope benötigt z.Z. aber Python 2.4. Das Repository http://rpm.livna.org/ bietet alle nötigen Pakete.

+ +

Installation:
+

su -c 'rpm -ivh <a href="http://rpm.livna.org/livna-release-9.rpm'
+sudo" rel="nofollow">http://rpm.livna.org/livna-release-9.rpm'
+sudo</a> yum install compat-python24 compat-python24-devel compat-python24-elementtree compat-python24-imaging

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/163/index.html b/siarp.de/node/163/index.html new file mode 100644 index 0000000..2ad1dba --- /dev/null +++ b/siarp.de/node/163/index.html @@ -0,0 +1,114 @@ + + + + + + + + + + + + Krasse Sache APC | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Krasse Sache APC

+
+
+
+ + +
+
+ + + + + +
+

Aufgrund des Vortrags von Rasmus Lehrdorf auf der FrOSCon 2008 hab ich mir mal kurz APC, den Alternative PHP Cache angesehen. Wollte damit nicht viel Zeit verbringen, aber unsere Drupal-Seiten auf siarp.de laufen eher langsam, weil der Drupal-Cache nur für anonyme Besucher funktioniert und wir alles schön personalisiert und geschützt haben. Zuerst bin ich auf einen etwas älteren Vergleich der Serverkonfigurationen für Drupal gestoßen und das hat noch mehr Interesse für den APC geweckt. Den habe ich dann wie in dieser Anleitung auf siarp.de installiert.

+ +

Ich bin davon ausgegangen, dass die Datenbank-Verbindung der Flaschenhals ist und habe nicht wirklich mit einer deutlichen Verbesserung gerechnet. Da wir nicht wirklich viel Speicher zur Verfügung haben, hätte ich an dieser Stelle sogar mit Nachteilen gerechnet.

+ +

Getestet habe ich den Unterschied auf dem Grillexamen, und zwar in der Gallerieliste, da dort die meisten Aufrufe an Drupal stattfinden (jedes Bild wird auf seine Berechtigungen geprüft).

+ +

Das Ergbenis war eine Verbesserung der Ladezeit von ca. 5 Sekunden auf gut 1 Sekunde! Sensationell dafür, dass ich das nur schnell mal installiert habe. Der Speicherbedarf pro Apache Arbeiter ist von 14 MB auf 20 MB gestiegen - verkraftbar, denke ich.

+ +

Also, schöne Sache das. Vor allem das Verhältnis Aufwand - Effekt.

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/167/index.html b/siarp.de/node/167/index.html new file mode 100644 index 0000000..7cccb35 --- /dev/null +++ b/siarp.de/node/167/index.html @@ -0,0 +1,223 @@ + + + + + + + + + + + + Buildout-basiertes Zope2 (Plone) unter Debian/Ubuntu installieren | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Buildout-basiertes Zope2 (Plone) unter Debian/Ubuntu installieren

+
+
+
+ + +
+
+ + + + + +
+

Ubuntu 8.04 Server / Plone 3.1.5.1

+ +

Voraussetzungen buildout:

+ +

$ sudo aptitude install gcc python2.4 python2.4-dev python-imaging python-elementtree

+ +

(Für Ubuntu Desktop muss noch zlib1g-dev installiert werden.)

+ +

Ergänzung von <a href="http://siarp.de/node/167" rel="nofollow">http://siarp.de/node/167</a> für Plone 3.3 unter Ubuntu Jaunty
+========================================================================
+
+Ubuntu Jaunty enthält zwar Python 2.4 aber keine Image Library (PIL) für 2.4.
+Diese kann auch als Egg mittels buildout installiert werden [1]. Dafür braucht
+man die Header-Dateien von Python, libjpeg und zlib [2]:
+   
+    sudo aptitude install build-essential python2.4-dev zlib1g-dev libjpeg62-dev
+
+PIL gibt es zwar als offizielles Egg [3], doch nur die Version von der ZOPE-Site
+"PILwoTk" funktioniert mir Plone. buildout.cfg sieht dann so aus:
+
+    [buildout]
+    ...
+    find-links += <a href="http://download.zope.org/distribution/
+" rel="nofollow">http://download.zope.org/distribution/
+</a>    eggs += PILwoTk
+    ...
+
+Zusätzlich kann das Problem auftauchen, dass sich ZOPE beschwert, es habe keine
+Berechtigung seine Eier abzulegen (Permission denied: ... .python-eggs). Wenn
+Eggs entpackt werden müssen, werden diese standardmäßig in ~/.python-eggs
+abgelegt, was aber durch den Benutzer zope nicht erlaubt ist. Dafür kann man
+PYTHON_EGG_CACHE im Buildout neu setzen [4]:
+
+    [instance]
+    effective-user = zope
+    environment-vars = PYTHON_EGG_CACHE ${buildout:directory}/var/.python-eggs
+    ...
+
+
+[1] <a href="http://www.veit-schiele.de/dienstleistungen/technische-dokumentation/plo...
+" rel="nofollow">http://www.veit-schiele.de/dienstleistungen/technische-dokumentation/plo...
+</a>[2] <a href="https://svn.infrae.com/buildout/silva/INSTALL.txt
+" rel="nofollow">https://svn.infrae.com/buildout/silva/INSTALL.txt
+</a>[3] <a href="http://pypi.python.org/pypi/PIL
+" rel="nofollow">http://pypi.python.org/pypi/PIL
+</a>[4] <a href="http://plone.org/documentation/error/permission-denied-python-eggs
+" rel="nofollow">http://plone.org/documentation/error/permission-denied-python-eggs
+</a>

+ +

Installation:

+ +

Ziel ist die systemweite Installation mit automatischem Start des Dienstes beim Booten. Zur Entwicklung und zum Testen reicht es, das ganze im Benutzer-Verzeichnis zu machen.

+ +

Zunächste wird der Code nach /opt kopiert:

+ +

$ sudo svn co SERVER/PFAD/ PROJEKTNAME

+ +

Dann der Buildout installiert:

+ +

$ cd PROJEKTNAME
+$ sudo python2.4 bootstrap.py
+$ sudo bin/buildout
+$ sudo bin/instance fg

+ +

Läuft? Dann wollen wir das ganze noch dem User „zope“ zuordnen:

+ +

sudo adduser zope

+ +

In buildout.cfg:

+ +

[instance]
+effective-user = zope

+ +

Das wird dann beim nächsten Aufruf von bin/buildout in zope.conf eingetragen. Beim Start durch sudo bin/instance start wird nun „zope“ als User des Prozesses verwendet.

+ +

Start beim Hochfahren:

+ +

$ sudo vim /etc/init.d/PROJEKTNAME
+
+#!/bin/bash
+cd /opt/PROJEKTNAME
+bin/instance start
+
+$ sudo chmod +x /etc/init.d/PROJEKTNAME
+$ update-rc.d PROJEKTNAME defaults

+ +

Quelle: http://ubuntu.wordpress.com/2005/09/07/adding-a-startup-script-to-be-run-at-bootup/

+ +

Hinter Apache laufen lassen (Reverse Proxy):

+ +

$ sudo aptitude install apache2
+$ sudo vim /etc/apache2/sites-available/PROJEKTNAME
+
+NameVirtualHost *:80
+
+<VirtualHost *:80>
+        ServerName HOST
+        DocumentRoot /var/www/
+        RewriteEngine On
+
+        <Proxy *>
+                Order deny,allow
+                Deny from all
+                Allow from HOST
+        </Proxy>
+
+        RewriteEngine On
+        RewriteRule ^(.*) http://localhost:8080/VirtualHostBase/http/HOST:80/PLONESITENAME/Virtual...$1 [L,P]
+
+        CustomLog /var/log/apache2/access.log combined
+</VirtualHost>
+
+$ sudo a2enmod proxy
+$ sudo a2enmod proxy_http
+$ sudo a2enmod rewrite
+$ sudo a2ensite PROJEKTNAME
+$ sudo /etc/init.d/apache2 restart

+

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/167_/a_/index.html b/siarp.de/node/167_/a_/index.html new file mode 100644 index 0000000..df48431 --- /dev/null +++ b/siarp.de/node/167_/a_/index.html @@ -0,0 +1,70 @@ + + + + + + + Page not found | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+ +

Page not found

+
+
+
+ + +
+ The requested page "/node/167</a>" could not be found.
+
+
+
+ +
+ + +
+
+ + diff --git a/siarp.de/node/167_/index.html b/siarp.de/node/167_/index.html new file mode 100644 index 0000000..68bab2d --- /dev/null +++ b/siarp.de/node/167_/index.html @@ -0,0 +1,70 @@ + + + + + + + Page not found | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+ +

Page not found

+
+
+
+ + +
+ The requested page "/node/167%22" could not be found.
+
+
+
+ +
+ + +
+
+ + diff --git a/siarp.de/node/174/index.html b/siarp.de/node/174/index.html new file mode 100644 index 0000000..3f43bd8 --- /dev/null +++ b/siarp.de/node/174/index.html @@ -0,0 +1,346 @@ + + + + + + + + + + + + Informatiker-Zeitvertreib | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Informatiker-Zeitvertreib

+
+
+
+ + +
+
+ + + + + +
+

Am 1.1. wollte Bettina unbedingt "Mensch ärgere dich nicht" spielen. Ich war nicht so begeistert, weil ich das Spiel für ziemlich langweilig halte. Zunächst diskutierten wir also meinen Standpunkt ("Da würfelt man doch nur abwechselnd") und den von Bettina ("Gar nicht, das hat voll viel mit Taktik zu tun"). Schlussendlich haben wir dann drei Runden gespielt. Später hatten wir Hunger und da nichts zu Essen im Haus war, haben wir uns Happy Meals bei McDonald's geholt. Als Spielzeug gab es "Monopoly Junior", also wurde auch das gespielt. Im Vergleich zum normalen Monopoly geht es deutlich vereinfacht zu - wenn man auf einer Straße ohne Besitzer landet kauft man und markiert sie mit einem Haus - zusätzliche Häuser kann man nicht erwerben.

+ +

Monopoly Junior

+ +

Das Spiel war ganz lustig und ich hatte zunächst das Gefühl, sehr viel mehr Kontrolle über mein Schicksal als bei "Mensch ärgere dich nicht" zu haben. Schließlich hatte man Geldscheine in der Hand, konnte Straßen kaufen und musste Miete bezahlen. Aber nach einer Weile dämmerte mir, dass durch die vereinfachten Regeln das Ganze mehr einer griechischen Tragödie ähnelt: das Schicksal ist vorherbestimmt. Schließlich muss man kaufen, wenn man auf einer Straße ohne Besitzer landet und gezieltes Investieren ist durch die Nur-ein-Haus-Regel auch nicht möglich. Also schlimmer als "Mensch ärgere dich nicht", bei dem man immerhin noch überlegen kann, wo man seine erwürfelten Punkte am besten investiert; nämlich dort, wo die Chance am geringsten ist, sie wieder zu verlieren. +Außerdem fiel uns auf, dass bei uns immer der Spieler die Partie gewann, der als erster gezogen hatte. Ist es wirklich so ein Vorteil, die erste Runde vor dem anderen herzulaufen oder war das Zufall? +Da inzwischen klar war, dass es - anders als bei "Mensch ärgere dich nicht" - wirklich nur um abwechselndes Würfeln geht und man absolut keinen Einfluss auf den Spielverlauf hat (verbotenes Glücksspiel!), war die nächste Neujahrsbeschäftigung schnell gefunden: Wir haben eine Monopoly-Junior-Simulation geschrieben um herauszufinden, wie deutlich sich der Startvorteil auswirkt (wenn es ihn denn gibt). +Nach zwei Stunden programmieren und 1.000.000 simulierten Spielen hatten wir das Ergebnis:

+ +

Gewinnchancen bei Monopoly Junior:

+ +

Bei zwei Spielern: + Spieler 1: 57.24% + Spieler 2: 41.50% + Unentschieden: 1.26%

+ +

Bei drei Spielern: + Spieler 1: 42.62% + Spieler 2: 30.96% + Spieler 3: 23.80% + Unentschieden: 2.62%

+ +

Bei vier Spielern: + Spieler 1: 34.35% + Spieler 2: 25.20% + Spieler 3: 19.13% + Spieler 4: 14.96% + Unentschieden: 6.36%

+ +

Also: Immer bei Monopoly Junior als erster ziehen und mit möglichst vielen Leuten spielen (die man am besten abwechselnd auf unterschiedlichen Positionen starten lässt). Das ist kein Schummeln - nur ein schlechtes Spieldesign.

+ +

Und für alle, die diese bahnbrechenden Ergebnisse überprüfen wollen, hier noch der Quellcode:

+ +
package mcmonopolyjunior;
+
+import java.util.Random;
+
+/**
+ * Simuliert das Spiel Monopoly Junior (aus dem McDonald's Happy Meal)
+ * um herauszufinden, wie sehr die Gewinnchancen von der Startposition
+ * des Spielers abhängen. Da man bei diesem Spiel keinen taktischen
+ * Entscheidungsspielraum hat, lässt es sich vollständig simulieren.
+ *
+ * Wie sich bei den Simulationen gezeigt hat, kann das Spiel ins Leere
+ * laufen: Es kann so lange keinen Gewinner geben, dass die Bank kein Geld
+ * mehr hat. Setzt für die Bank Liquidität voraus (unendlich viel Geld
+ * im Spiel), so kann es passieren, dass die Spieler so viel Geld
+ * ansammeln, dass die Partie in eine Endlosschleife gerät. Deshalb wird
+ * ein unentschieden angenommen, wenn ein Spieler mehr Geld hat, als die
+ * Bank im realen Spiel (100$).
+ * Wenn zwei Spieler gleich viel Geld haben, wenn die Partie endet, wird
+ * ebenfalls ein Unentschieden gezählt.
+ *
+ * @author Bettina Selig und Tilman Walther
+ */

+public class McMonopolyJunior {
+       
+        int[] money;
+        int[] position;
+       
+        int[] rent = { 1, 2, 2, 3, 3, 4, 4, 5 };
+        int[][] streets = new int[8][2];
+        int jackpot;
+       
+        private Random rnd = new Random();
+        boolean gameOver;
+       
+        public int simulate(int numPlayers) {
+               
+                if ((numPlayers < 2) || (numPlayers > 4)) {
+                        System.err.println("Diese Spielerzahl ist nicht möglich.");
+                        System.exit(1);
+                }
+               
+                gameOver = false;
+                money = new int[numPlayers];
+                position = new int[numPlayers];
+               
+                int budget;
+               
+                if (numPlayers == 2)
+                        budget = 25;
+                else if (numPlayers == 3)
+                        budget = 20;
+                else
+                        budget = 15;
+               
+                for (int i = 0; i < numPlayers; i++) {
+                        money[i] = budget;
+                }
+               
+                for (int i = 0; i < streets.length; i++) {
+                        streets[i][0] = -1;
+                        streets[i][1] = -1;
+                }
+               
+                // Spielen!
+                while (!gameOver) {
+                        for (int i = 0; (i < numPlayers) && (!gameOver); i++) {
+                                move(i);
+                        }
+                }
+               
+                // Abbruchbedingung: Wenn ein Spieler mehr Dollar hat, als die Bank ursprünglich besitzt,
+                // wird das Spiel nicht gewertet
+                for (int i = 0; i < numPlayers; i++) {
+                        if (money[i] > 100)
+                                return -1;
+                }
+               
+                int winner = 0;
+                for (int i = 1; i < numPlayers; i++) {
+                        if (money[i] > money[winner]) {
+                                winner = i;
+                        }
+                        else if (money[i] == money[winner]) {
+                                // bei einem Unentschieden wird das Spiel nicht gewertet
+                                return -1;
+                        }
+                }
+               
+                return winner;
+        }
+       
+        private void move(int player) {
+                position[player] = position[player] + rnd.nextInt(6) + 1;
+               
+                // Ziehen über Start
+                if (position[player] > 27) {
+                        money[player] += 2;
+                        position[player] = position[player] % 28;
+                }
+               
+                // nochmals ziehen
+                if ((position[player] == 3) || (position[player] == 11) || (position[player] == 17) || (position[player] == 25)) {
+                        move(player);
+                }
+                // 2$ bekommen
+                else if ((position[player] == 4) || (position[player] == 18)) {
+                        money[player] += 2;
+                }
+                // 2$ bezahlen
+                else if ((position[player] == 7) || (position[player] == 21)) {
+                        money[player] -= 2;
+                }
+                // Jackpot einziehen
+                else if (position[player] == 14) {
+                        money[player] += jackpot;
+                        jackpot = 0;
+                }
+                // McDonald's-Gefängnis
+                else if (position[player] == 2) {
+                        money[player] -= 3;
+                        jackpot += 3;
+                        position[player] = 8;
+                }
+                // Straße kaufen / Miete zahlen
+                else {
+                        int street;
+                        int house;
+                       
+                        if ((position[player] == 1) || (position[player] == 5) || (position[player] == 9) ||
+                                        (position[player] == 12) ||(position[player] == 15) || (position[player] == 19) ||
+                                        (position[player] == 23) || (position[player] == 26))
+                                house = 0;
+                        else
+                                house = 1;
+                       
+                        if (position[player] < 3)
+                                street = 0;
+                        else if (position[player] < 7)
+                                street = 1;
+                        else if (position[player] < 11)
+                                street = 2;
+                        else if (position[player] < 14)
+                                street = 3;
+                        else if (position[player] < 17)
+                                street = 4;
+                        else if (position[player] < 21)
+                                street = 5;
+                        else if (position[player] < 25)
+                                street = 6;
+                        else
+                                street = 7;
+                       
+                        if (streets[street][house] < 0) {
+                                money[player] -= rent[street];
+                                streets[street][house] = player;
+                        }
+                        else if (streets[street][house] != player) {
+                                if (streets[street][0] != streets[street][1]) {
+                                        money[player] -= rent[street];
+                                        money[streets[street][house]] += rent[street];
+                                }
+                                else {
+                                        money[player] -= 2*rent[street];
+                                        money[streets[street][house]] += 2*rent[street];
+                                }
+                        }
+                }
+               
+                if (money[player] < 0)
+                        gameOver = true;
+               
+                if (money[player] > 100)
+                        gameOver = true;
+        }
+       
+        public static void main(String[] args) {
+               
+                int numPlayers = 4;  // Anzahl der Spieler (1 bis 4)
+                int numRuns = 1000000;  // Anzahl der simulierten Spiele
+               
+                McMonopolyJunior monopoly = new McMonopolyJunior();
+                int[] wins = new int[numPlayers];
+                int draws = 0;
+               
+                for (int i = 0; i < numRuns; i++) {
+                        int winner = monopoly.simulate(numPlayers);
+                        if (winner >= 0)
+                                wins[winner]++;
+                        else
+                                draws++;                       
+                }
+               
+                System.out.println("Chancenverteilung:");
+                for (int i = 0; i < numPlayers; i++) {
+                        System.out.println(" Spieler "+(i+1)+": "+(wins[i] * 100.0 / numRuns)+"%");
+                }
+                System.out.println(" Unentschieden: "+(draws * 100.0 / numRuns)+"%");
+        }
+
+}
+
+ + + + +
AttachmentSize
Image icon monopoly_junior.jpg60.17 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/179/index.html b/siarp.de/node/179/index.html new file mode 100644 index 0000000..cfb0172 --- /dev/null +++ b/siarp.de/node/179/index.html @@ -0,0 +1,136 @@ + + + + + + + + + + + + Drupal-Tutorial: Administratoren-Blog | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Drupal-Tutorial: Administratoren-Blog

+
+
+
+ + +
+
+ + + + + +
+

Für das Siarp-Portal (derzeit Drupal 5) wollten wir eine Möglichkeit haben, Meldungen oder Nachrichten zu kommunizieren, die über Vorgänge bei Projekten wie der Server-Administration oder auch dem Siarp-Portal selber informieren. Da das eher einem ausführlichen Changelog ähnelt sollte, wollten wir es nicht über das Project-Modul laufen lassen. Eher eine Art Blog mit bestimmten Rechten und Einstellungen und einer gesonderten Ansicht, wofür Drupal ja bestens ausgerüstet ist.
+
+

Inhaltstyp

+ +

Zunächst habe ich einen neuen Inhaltstyp angelegt:

+ +

Inhaltsverwaltung > Inhaltstypen > Inhaltstyp hinzufügen:
+


    +
  • Name: „Nachricht“

  • +
  • Typ: „message“

  • +
  • soll nicht auf Startseite angezeigt werden

  • +

+ +

Ggf. noch Berechtigungen für den neuen Typ setzen (benutzerverwaltung > Zugriffskontrolle).

+ +

Zugriffskontrolle

+ +

Drupal ermöglicht es zwar, Erstellen- und Bearbeiten-Berechtigungen separat für den neuen Inhaltstyp zu setzen, nicht aber die Ansehen-Berechtigung („view“). Wir wollen aber, dass nur Benutzer einer bestimmten Rolle auf die Meldungen zugreifen können.

+ +

Dafür habe ich aus den zahlreichen Zugriffsbeschränkungsmodulen Content Access herausgesucht, weil es ziemlich genau (nur) das macht, was ich brauche und das attraktiv wirkende Node Access Control noch nicht auf Drupal 6 portiert ist, was zukünftig aber wichtig sein dürfte und es außerdem anscheinend auch sonst nicht ganz so zielstrebig weiterentwickelt wird.

+ +

Nach der Installation von Content Access 5.x-1.5 gibt es bei den Einstellungen zum Inhaltstyp einen Reiter „Zugriffskontrolle“, wo nun die Rechte für die Rollen gesetzt werden können.

+ +

Ansichten

+ +

Um die Ansichten der Meldungen umzusetzen, habe ich auf Views zurückgegriffen. Die Ansicht (Strukturierung > Ansichten > Hinzufügen) enthält eine Seite mit Teaser List und einen Block mit List View. Für die Seite lasse ich einen Menüeintrag anlegen. Für die List View im Block definiere ich das Feld „Node Title“. Dann noch nach „Node: Type“ filtern und als Sortierkriterium das Erstellungsdatum absteigend wählen.

+ +

Um einen RSS-Feed zu erzeugen habe ich noch unter „Argumente“ „RSS: RSS Feedauswahl“ („Alle Werte anzeigen“) hinzugefügt.

+ +

Nun muss noch der Block aktiviert und platziert werden (Strukturierung > Blöcke). Für unser Nachrichtensystem gebe ich dem Benutzer die Möglichkeit, den Block zu deaktivieren.
+

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/187/index.html b/siarp.de/node/187/index.html new file mode 100644 index 0000000..19d7aaf --- /dev/null +++ b/siarp.de/node/187/index.html @@ -0,0 +1,113 @@ + + + + + + + + + + + + Ubuntu-Installation: den größten freien Speicherbereich benutzen | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Ubuntu-Installation: den größten freien Speicherbereich benutzen

+
+
+
+ + +
+
+ + + + + +
+

Installiert man Ubuntu zum ersten Mal auf einem Windows-Rechner ist die Auswahl bei der Partitionierung der Festplatte meist einfach: erste Partition verkleinern und den freigewordenen Platz zur Installation nutzen. Wenn man wie ich aber schon zum hundertsten Male (oder zum zweiten Mal) eine Linux-Distribution auf so einem Rechner installiert, möchte man den irgendwann mal erstellten Bereich jenseits von Windows nutzen.

+ +

Ubuntu (hier 8.10) mag es meiner Erfahrung nach nicht so, wenn es außer der Windows-Partition noch weitere gibt (die überschrieben werden sollen). Deshalb habe ich Windows noch mal gestartet (wenn es Probleme mit den Überresten eines Bootloaders - „Grub“ - gibt, Windows-CD rein und in der Rettungskonsole fixmbr) und dort in der Datenträgerverwaltung alle zusätzlichen Partitionen gelöscht. (An dieser Stelle muss ich mal sagen, dass es bestimmt eleganter und besser geht, aber ich habe einfach keinen Bock, mich ernsthaft mit der Partitionierung auseinander zu setzen und deshalb meide ich auch die „manuelle“ Partitionierung.)

+ +

In dieser Konstellation ist die Einstellung „den größten freien Speicherbereich benutzen“ zu wählen. Das wollte ich eigentlich nur sagen. Denn die folgende Grafik fand ich sehr irreführend ich habe doch gezögert, weil ich befüchtete, die gesamte Festplatte zu löschen. Nein, es wird wirklich nur der in der oberen Zeile in weiß dargestellte „Free Space“ genutzt und nicht wie uns die untere Zeile zu sagen scheint die ganze Platte! Vor!

+ +

Ubuntu-Installation: den größten freien Speicherbereich benutzen

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/191/index.html b/siarp.de/node/191/index.html new file mode 100644 index 0000000..0ff5ffd --- /dev/null +++ b/siarp.de/node/191/index.html @@ -0,0 +1,210 @@ + + + + + + + + + + + + Borland Real48 in Java | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Borland Real48 in Java

+
+
+
+ + +
+
+ + + + + +
+

When writing a converter tool for a binary file format, I had problems reading some of the floating point numbers. After a little bit of research I found out that this very special format was used in programs written in Borland Pascal/Delphi. Since I couldn't find any Java class that's able to read this kind of number I wrote it myself.

+ +

As far as I remember these are basically reverse IEEE floating point numbers of six bytes. (It's been a while since I wrote this. See the PDF file by Richard Biffl for a detailed description of the format.)

+ +

References:

+ + + +

And here is the code:

+ +
package de.tilman.util;
+
+import java.math.BigDecimal;
+
+/**
+ * A class for representation and conversion of 6-byte/48-bit floating
+ * point numbers used in Borland Pascal/Delphi.
+ *
+ * @author Tilman Walther
+ */

+public class Real48 {
+       
+        char[] bytes;
+        double value;
+       
+        /**
+         * Represents a number in Real48 format.
+         *
+         * @param bytes the byte values of the number
+         */

+        public Real48(char[] bytes) {
+                this.bytes = bytes;
+                this.value = Real48.getDoubleFromBytes(bytes);
+        }
+       
+        /**
+         * Returns the value of the number as double.
+         *
+         * @return the number as double
+         */

+        public double getDoubleValue() {
+                return value;
+        }
+       
+        /**
+         * Returns the byte values of the Real48 as char[].
+         *
+         * @return the byte values
+         */

+        public char[] getBytes() {
+                return bytes;
+        }
+       
+        /**
+         * Converts a Real48 in a double.
+         *
+         * @param bytes the number in Real48 format
+         * @return the number as double
+         */

+        public static double getDoubleFromBytes(char[] bytes) {
+                long[] real48 = new long[6];
+                real48[0] = bytes[0];
+                real48[1] = bytes[1];
+                real48[2] = bytes[2];
+                real48[3] = bytes[3];
+                real48[4] = bytes[4];
+                real48[5] = bytes[5];
+               
+                // get sign
+                long sign = (real48[0] & 0x80) >> 7;
+               
+                // get significand
+                long significand = ((real48[0] % 0x80) << 32)
+                                                        + (real48[1] << 24)
+                                                        + (real48[2] << 16)
+                                                        + (real48[3] << 8)
+                                                        + (real48[4]);
+               
+                // get exponent
+                long exponent = bytes[5];
+               
+                // if the exponent is zero the real represents zero, too
+                if (exponent == 0) {
+                        return 0.0;
+                }
+               
+                // convert exponent (bias for Real48 is 129, bias for IEEE 754-double is 1023)
+                exponent += 894;
+               
+                long bits = (sign << 63) + (exponent << 52) + (significand << 13);
+               
+                double value = Double.longBitsToDouble(bits);
+               
+                // since Real48 has only a precision of 11 we need to set all digits > 11 to zero
+                BigDecimal bd = new BigDecimal(value);
+                bd = bd.setScale(11, BigDecimal.ROUND_DOWN);
+               
+                return bd.doubleValue();
+        }
+
+}
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/194/index.html b/siarp.de/node/194/index.html new file mode 100644 index 0000000..4803cec --- /dev/null +++ b/siarp.de/node/194/index.html @@ -0,0 +1,115 @@ + + + + + + + + + + + + Erste Erfahrungen in 64 Bit | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Erste Erfahrungen in 64 Bit

+
+
+
+ + +
+
+ + + + + +
+

Seit ein paar Tagen bin ich auf Windows Vista umgestiegen. Und um ganz vorne mit dabei zu sein, durfte es gleich die 64-Bit-Variante sein - ich denke es ist absehbar, wann man sich über mehr als vier GB Arbeitsspeicher freuen wird. Bisher sind die Erfahrungen ganz gut, ein paar Ecken und Kanten gibt es aber:

+ +
    +
  1. Das Java SDK gibt es für 64-Bit-Systeme, aber Eclipse streikt. (Exit Code=-1) Zwar kann man ein 64-Bit-Eclipse aus dem aktuellen Entwicklungszweig auschecken, aber dann hat man bei den meisten Plugins wohl schlechte Karten. Zuviel Aufwand, es bleibt bei 32-Bit Java und dem normalen Eclipse. (Hinzu kommt, dass man sowieso ein 32-Bit-JRE braucht, wenn man Java z.B. in Firefox nutzen möchte.)
  2. +
  3. Manche Software wird von Vista etwas verwirrt. Grundsätzlich werden Programme zwar schön nach alter und neuer Architektur in verschiedene Ordner einsortiert, aber unter der Haube wird es etwas verwirrend. AutoMDK braucht beispielsweise die libsndfile-1.dll, die normalerweise beim ersten Start nach C:\Windows\system32 kopiert wird. Nur unter Vista 64 hilft das leider wenig: Der Ordner system32 existiert zwar noch, ist aber für 64-Bit-Komponenten vorgesehen. Alte 32-Bit-DLLs gehören in C:\Windows\SysWOW64. Die Ordnernamen ergeben zwar absolut keinen Sinn, aber Tatsache ist, dass AutoMKV glücklich ist, sobald die DLL in SysWOW64 liegt. Und ich damit auch. +(Gefunden bei codeproject.com: "That's because 64-bit Windows still uses the C:\windows\system32 directory for native applications. Oddly enough, this misnamed directory is for 64-bit apps only!")
  4. +
+ +

Mal sehen, was sonst noch so kommt.

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/196/index.html b/siarp.de/node/196/index.html new file mode 100644 index 0000000..5febfe8 --- /dev/null +++ b/siarp.de/node/196/index.html @@ -0,0 +1,452 @@ + + + + + + + + + + + + Using AppleScript and cURL to import Content from iPhoto into Drupal | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Using AppleScript and cURL to import Content from iPhoto into Drupal

+
+
+
+ + +
+
+ + + + + +
+

I'm using Apple's iPhoto to organize my private photographs and Drupal is what comes to my mind first when there's need for a web-based solution. Having lots of pictures from a recent trip I want to show people I started thinking about some kind of web gallery. Being a developer I need to come up with something fancier than just some stock gallery product like Gallery2 (actually I don't really know that product so bear with me). I did some research and found some article about different approaches to build photo galleries in Drupal and also a nice video tutorial. I've used image module and gallery module before but the flexibility that CCK extended by imagefield and imagecache and views seem to offer is just too tempting. + +But how would I get my hundreds of pictures imported into my yet-to-be-built gallery site? There are plenty of exporter plug-ins for iPhoto sending pictures to galleries like said Gallery2, Flickr and so on. I did not find much information on how to write a plug-in for iPhoto but I found some AppleScript code that did just an export to Drupal. This one seemed to be very outdated but it was a good start. I started a thread on the Drupal developer mailing list which gave me interesting options but I stayed with the concept of using cURL because it's the most flexible and probably the fasted way for my one-time requirement and there are no dependencies. The missing piece was this handbook page on d.o.

+ +

Note: The following is a kind of tutorial but the result is just a custom script that needs to be adjusted to your scenario.

+ +

AppleScript is probably not the most powerful language but it allows us to call shell scripts. The idea is to get all the image information from iPhoto and then use shell commands to upload to a Drupal site. The first step is to extract the cURL commands from the PHP code from the handbook page so I don't need a separate script. Here are the shell commands to create content on a Drupal site:

+ +

First we log in which means getting a cookie with session data.

+ +
curl http://localhost/drupal/?q=user \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'name=user' \
+        -F 'pass=pass' \
+        -F 'form_id=user_login' \
+        -F 'op=Log in' \
+        --output ~/response_login.html
+ +

This calls the user page with your username and password. Check response_login.html to see if this has been successful.

+ +

Next we need to get the security token of the content creation form.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        --output ~/response_create_form.html
+ +

I'm using a custom content type called "image" – substitute that with whatever your content type is. response_create_form.html contains the HTML form to add an image including the security token which we can extract using a perl regular expression:

+ +
s/.*edit-image-node-form-form-token" *value="([^"]*)".*/$1/s
+ +

Finally we actually upload our content.

+ +
curl http://localhost/drupal/?q=node/add/image \
+        -s \
+        -c /tmp/curl-cookies.txt \
+        -b /tmp/curl-cookies.txt \
+        -F 'title=My Title' \
+        -F 'field_image[0][fid]=0' \
+        -F 'field_image[0][list]=1' \
+        -F 'files[field_image_0]=@/Users/me/myimage.jpg' \
+        -F 'body=My content.' \
+        -F 'name=Myself' \
+        -F 'status=1' \
+        -F 'revision=1' \
+        -F 'op=Save' \
+        -F 'form_id=image_node_form' \
+        -F 'form_token=63fe773e820d2a4565720ab3bd0fc991' \
+ +

Check your Drupal site – there should be new content. My content type contains an imagefield that takes the above values. The "@" makes cURL upload the actual file.

+ +

Now to upload all selected images in iPhoto to the Drupal site I merge the snippets above with the AppleScript from iPhotoToDrupal:

+ +

Update: I had an issue with special characters as I entered "'" in iPhoto's description field. I found out about quoted form of variablename which is used to escape strings in AppleScript to use them in shell scripts. This funtion puts the string in single quotes automatically so I couldn't use it like " -F 'body=" & quoted form of this_comment & "'". Fortunately it's also possible to quote the value only like -F body='xxx' so " -F body=" & quoted form of this_comment works. Just being at it I replaced it for other variables also. Finally, I added a "Done" dialog.

+ +
set DrupalUsername to "user"
+set DrupalPassword to "pass"
+set DrupalSite to "http://localhost/drupal/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                        set this_uploadfile to (POSIX path of this_imagefile)
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+ +

Just go to iPhoto, select some images and start the script. The images including title and description will be uploaded as new nodes to your Drupal site.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Hi-

+ +

Nice job. I've been trying to use your applescript but am getting an error, "the command exited with a non-zero status". My Drupal install has clean URLs on. Do I need to modify the strings in your script to fit, or will the "non-clean" URLs still work?

+ +

Here's the details on my parts: +Drupal 6.17 +iPhoto 7.1.5 (aka iPhoto '08)

+ +

Thanks!

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

In my Drupal 7.12 i needed to alter your regex line :

+ +
set token to do shell script "echo '" & tokenSrc & "' | perl -pe 's/.*edit-" & DrupalContentType & "-node-form-form-token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

to:

+ +
set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+ +

Somehow the name attribute was "form_token" and not "edit-image-node-form-form-token" as your code suggested.

+ +

Now it works great. Thanks for sharing!

+ +

I also added on the fly image resizing. All credits here go to https://discussions.apple.com/thread/2174350?start=0&tstart=0 from where I borrowed the resize code.

+ +
set longest_side to 1024
+
+set DrupalUsername to "admin"
+set DrupalPassword to "XXXXXX"
+set DrupalSite to "http://localhost/~arminhelbach/drupal7/"
+set DrupalContentType to "image"
+set DrupalAddPage to "?q=node/add/" & DrupalContentType
+set CookieFile to "/tmp/curl-cookies.txt"
+set tmp_path to "/tmp"
+
+set curlLogin to "curl"
+set curlLogin to curlLogin & " " & DrupalSite & "?q=user"
+set curlLogin to curlLogin & " -s"
+set curlLogin to curlLogin & " -c " & CookieFile
+set curlLogin to curlLogin & " -b " & CookieFile
+set curlLogin to curlLogin & " -F 'name=" & DrupalUsername & "'"
+set curlLogin to curlLogin & " -F 'pass=" & DrupalPassword & "'"
+set curlLogin to curlLogin & " -F 'op=Log in'"
+set curlLogin to curlLogin & " -F 'form_id=user_login'"
+do shell script curlLogin
+
+set curlAddForm to "curl"
+set curlAddForm to curlAddForm & " " & DrupalSite & DrupalAddPage
+set curlAddForm to curlAddForm & " -s"
+set curlAddForm to curlAddForm & " -c " & CookieFile
+set curlAddForm to curlAddForm & " -b " & CookieFile
+set tokenSrc to do shell script curlAddForm
+
+set token to do shell script "echo '" & tokenSrc & "' | grep form_token | perl -pe 's/.*name=\"form_token\" *value=\"([^\"]*)\".*/$1/s';"
+
+tell application "iPhoto"
+        activate
+       
+        try
+                copy (my selected_images()) to these_images
+               
+                -- Make sure we have one or more image selected, and if we do, then grab the details of each and upload
+                if these_images is false or (the count of these_images) is 0 then
+                        error "Please select one or more images."
+                end if
+               
+                repeat with this_image in these_images
+                       
+                        set this_imagefile to ((image path of this_image) as POSIX file)
+                       
+                        set this_comment to (the comment of this_image) as string
+                        set this_name to the title of this_image
+                       
+                        tell application "Image Events" to set t to PNG
+                        copy (my convert_image(this_imagefile as alias, tmp_path, longest_side)) to tmpimagefile
+                        set this_uploadfile to (POSIX path of tmpimagefile)
+                       
+                        set curlCreate to "curl"
+                        set curlCreate to curlCreate & " " & DrupalSite & DrupalAddPage
+                        set curlCreate to curlCreate & " -s"
+                        set curlCreate to curlCreate & " -c " & CookieFile
+                        set curlCreate to curlCreate & " -b " & CookieFile
+                        set curlCreate to curlCreate & " -F title=" & quoted form of this_name
+                        set curlCreate to curlCreate & " -F field_image[und][0][fid]=0"
+                        set curlCreate to curlCreate & " -F field_image[und][0][list]=1"
+                        set curlCreate to curlCreate & " -F files[field_image_und_0]=@" & quoted form of this_uploadfile
+                        set curlCreate to curlCreate & " -F body=" & quoted form of this_comment
+                        set curlCreate to curlCreate & " -F name=" & quoted form of DrupalUsername
+                        set curlCreate to curlCreate & " -F status=1"
+                        set curlCreate to curlCreate & " -F revision=1"
+                        set curlCreate to curlCreate & " -F op="
+                        set curlCreate to curlCreate & " -F form_id=" & DrupalContentType & "_node_form"
+                        set curlCreate to curlCreate & " -F form_token=" & token
+                        do shell script curlCreate
+                       
+                        do shell script "rm '" & this_uploadfile & "'"
+                end repeat
+               
+        on error error_message number error_number
+                if the error_number is not -128 then
+                        display dialog error_message buttons {"Cancel"} default button 1
+                end if
+        end try
+       
+end tell
+
+display dialog "Done." buttons {"Ok"} default button 1
+
+
+-- Taken right out the "Show Image File" AppleScript on the Apple site:
+-- http://www.apple.com/applescript/iphoto/
+on selected_images()
+        tell application "iPhoto"
+                try
+                        -- get selection
+                        set these_items to the selection
+                        -- check for single album selected
+                        if the class of item 1 of these_items is album then error
+                        -- return the list of selected photos
+                        return these_items
+                on error
+                        return false
+                end try
+        end tell
+end selected_images
+
+
+on convert_image(this_item, target_path, longest_side)
+        tell application "Image Events"
+                try
+                        launch
+                        -- open the image file
+                        set this_image to open this_item
+                        tell application "Finder"
+                                set new_item to ((target_path) as string) & (name of this_item) & ".jpg"
+                        end tell
+                        copy dimensions of this_image to {current_width, current_height}
+                        if current_width is greater than current_height then
+                                set new_height to (longest_side * current_height) / current_width
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        scale this_image to size longest_side
+                                end if
+                        else
+                                if (new_height * longest_side) < (current_width * current_height) then
+                                        set new_height to (longest_side * current_width) / current_height
+                                        scale this_image to size new_height
+                                end if
+                        end if
+                        save this_image in new_item as JPEG
+                        return new_item
+                on error msg
+                        return msg
+                end try
+        end tell
+end convert_image
+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/199/index.html b/siarp.de/node/199/index.html new file mode 100644 index 0000000..c3fba74 --- /dev/null +++ b/siarp.de/node/199/index.html @@ -0,0 +1,111 @@ + + + + + + + + + + + + Enabling Gallery2‘s language support by configuring locales in Ubuntu 7.10 (Gutsy) | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Enabling Gallery2‘s language support by configuring locales in Ubuntu 7.10 (Gutsy)

+
+
+
+ + +
+
+ + + + + +
+

Gallery2 didn‘t want to talk German to me :(

+ +

I found a hint in the Gallery2 FAQs which pointed me to locales that are used by gettext. On my server (Ubuntu 7.10) no locales were configured so with a little help from ubuntugeek.com I enabled de_DE.UTF-8 and en_US.UTF-8 (adding both as new lines to /var/lib/locales/supported.d/local), then dpkg-reconfigure locales and restart Apache.

+ +

Works.

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/201/index.html b/siarp.de/node/201/index.html new file mode 100644 index 0000000..ef67059 --- /dev/null +++ b/siarp.de/node/201/index.html @@ -0,0 +1,197 @@ + + + + + + + + + + + + Plone 3: How to really exclude from navigation | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Plone 3: How to really exclude from navigation

+
+
+
+ + +
+
+ + + + + +
+

Plone has multiple ways of excluding a content object from the navigation:

+ +
    +
  • In the edit tab of the object under settings check "Exclude from navigation"
  • +
  • Add the ID to idsNotToList in portal_properties/navtree_properties
  • +
  • Add the meta type to metaTypesNotToList in portal_properties/navtree_properties
  • +
+ +

This works fine but the item is still displayed in the navigation tree if it's the current item (the one you're currently viewing). This may have a reason (usability?) but it is not what I want in some cases. If you put a link to the terms and conditions in the footer, for example, you don't want this to show up in the navigation tree when you click on it.

+ +

To solve this you can override the template for the navigation portlet (it may also work for the portal tabs) and add the conditions for the exclusion there.

+ +

Overriding the navigation portlet template

+ +

Copy the files navigation.pt and navigation_recurse.pt to your package. Then create a file navigation.py with the following content to create your own renderer based the original overriding the templates:

+ +
from plone.app.portlets.portlets.navigation import Renderer
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+class MyRenderer(Renderer):
+    _template = ViewPageTemplateFile('navigation.pt')
+    recurse = ViewPageTemplateFile('navigation_recurse.pt')
+ +

Next, you have to register the class in the configure.zcml to override the original renderer.

+ +
<configure
+    xmlns:plone="http://namespaces.plone.org/plone">
+
+    <include package="plone.app.portlets" />
+
+    <plone:portletRenderer
+        portlet="plone.app.portlets.portlets.navigation.INavigationPortlet"
+        class=".navigation.MyRenderer"
+        />
+       
+</configure>
+ +

(Note: If you want to do this for one theme only, put the code into your theme package and add layer="..browser.interfaces.IThemeSpecific" to the <plone:portletRenderer> element.)

+ +

If you restart Zope now, you are using your own class and templates but there's no difference, yet.

+ +

Adding conditions to really exclude from navigation

+ +

First we expose the idsNotToList and metaTypesNotToList properties to the templates by adding the following to navigation.py:

+ +
...
+from plone.memoize.instance import memoize
+from Products.CMFCore.utils import getToolByName
+
+class MyRenderer(Renderer):
+    ...
+    @memoize
+    def getMetaTypesNotToList(self):
+        context = self.context
+        portal_properties = getToolByName(context, 'portal_properties')
+        navtree_properties = getattr(portal_properties, 'navtree_properties')
+        return list(navtree_properties.metaTypesNotToList)
+
+    @memoize
+    def getIdsNotToList(self):
+        context = self.context
+        portal_properties = getToolByName(context, 'portal_properties')
+        navtree_properties = getattr(portal_properties, 'navtree_properties')
+        return list(navtree_properties.idsNotToList)
+ +

Now we can finally add the conditions to the template so the item is not displayed in the navigation portlet any more. In navigation_recurse.pt change

+ +
tal:condition="python:bottomLevel &lt;= 0 or level &lt;= bottomLevel"
+ +

to

+ +
tal:condition="python:(not node['item'].id in view.getIdsNotToList()) and (node['portal_type'] not in view.getMetaTypesNotToList()) and (not node['item'].exclude_from_nav) and (bottomLevel &lt;= 0 or level &lt;= bottomLevel)"
+ +

That's it!

+ +

References:

+ +
    +
  • http://plone.org/documentation/how-to/override-the-portlets-in-plone-3.0/
  • +
  • http://plone.org/support/region/de#nabble-td1643152%7Ca1643152
  • +
+
+ + + + + + + +
AttachmentSize
Binary Data plonetutorial.excludefromnav-1.0dev-py2.4.egg5.84 KB
Image icon Bild 10.png169.72 KB
Image icon Bild 11.png169.42 KB
Image icon Bild 13.png146.64 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/202/index.html b/siarp.de/node/202/index.html new file mode 100644 index 0000000..f6382ef --- /dev/null +++ b/siarp.de/node/202/index.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + GPS mit dem E71: Initialzündung | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

GPS mit dem E71: Initialzündung

+
+
+
+ + +
+
+ + + + + +
+

Seit zweieinhalb Monaten habe ich ein Nokia E71 und bin eigentlich absolut zufrieden: Die Tastatur ist super (dafür gebe ich sogar gerne die Hälfte des Bildschirms im Vergleich zum iPhone her), E-Mail funktioniert wunderbar, Internet per WLAN für zu Hause, alles super. Nur das GPS... Ich hatte mich bewusst für ein Handy mit GPS entschieden, aber irgendwie wollte das Ding nicht recht. Bis zur Bestimmung der Position konnten gut 10 Minuten vergehen, absolut inakzeptabel. Auch Aktivierung von AGPS und Datenverbindung brachte nichts. An einen Hardware-Defekt konnte ich nicht recht glauben, schließlich ging es ja - irgendwann. Die Suche im Netz brachte mich auch nicht recht weiter. Nur, dass ich nicht völlig alleine mit meinem Problem bin, wusste ich danach. Die neueste Firmware war auch schon aufgespielt, irgendwie blieb also nur ein böser Serienfehler. Ich war also schon kurz davor, Nokia das Ding um die Ohren zu hauen, als ich bei einem Kollegen ebenfalls ein E71 entdeckte. Und bei dem dauerte das Locking nur ein paar Sekunden. Außerdem sah ich in Nokia Maps zum ersten mal das Netzsymbol an Stelle des Satelliten-Statussymbols in der rechten unteren Ecke (zeigt die Nutzung von AGPS an). Und siehe da: Nachdem wir die SIM-Karten getauscht hatten, ging es auch mit meinem Gerät. Nokia gut, simyo böse? Wie frustrierend - bloß weil ich mit einem Billiganbieter unterwegs bin, soll mein GPS nutzlos sein? Und dann das Wunder: Nachdem wir die Karten zurückgetauscht hatten, ging es auch bei mir. Mit Netzsymbol bei der ersten Suche und wenigen Sekunden bis zur Positionsbestimmung, auch in geschlossenen Räumen. Unglaublich. Ich habe zwar keine Erklärung für den Effekt, kann aber jedem E71-Besitzer mit ähnlichen Problemen empfehlen, es auch zu probieren. (Für Erklärung des Effekts wäre ich auch dankbar. Die geliehene Karte war übrigens von 1&1, also D2-Netz.) Gut möglich, dass es sich bei anderen Symbian-Handys ähnlich verhält. Ich bin auf jeden Fall ersmal zufrieden.

+ +

Link: Tipps zur GPS-Einstellungen beim E71

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/204/index.html b/siarp.de/node/204/index.html new file mode 100644 index 0000000..9816820 --- /dev/null +++ b/siarp.de/node/204/index.html @@ -0,0 +1,172 @@ + + + + + + + + + + + + Ruby on Rails deployen | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Ruby on Rails deployen

+
+
+
+ + +
+
+ + + + + +
+

Das Szenario: Es sollen neben statischen Webseiten und PHP-Anwendungen auch Ruby-on-Rails-Anwendungen auf dem Server laufen. Die klassische Variante ist für jede Rails-Anwendung einen oder mehrere (Load Balancing) Mongrel-Server laufen zu lassen und die mittels Reverse Proxy hinter den Apache zu schalten (Port 80, SSL, Sicherheit). Außerdem gibt es (relativ neu) das Apache-Modul Phusion Passenger (a.k.a. mod_rails / mod_rack). Passenger empfiehlt Apache mit Worker statt mit Prefork zu nutzen [1], aber das PHP-Modul für den Apache (mod_php) läuft nur mit Prefork. Leider hat das Ubuntu-Paket für Passenger eine Abhängigkeit mir Worker, so dass es nicht eingesetzt werden kann [2]. (PHP via CGI laufen zu lassen kommt erstmal nicht in Frage). Allerdings kann man Passenger auch mit RubyGems installieren (auch mit Prefork).

+ +

Weil es mit Tracks 1.7 Probleme gab und außerdem die Mongrel-Variante etwas sparsamer sein soll, haben wir dann die genommen. Es folgen trotzdem für beide Varianten Anleitungen.

+ +

Die Rails-Anwendung wird in /var/www/rails entpackt. Wir gehen davon aus, dass sich Rails selber Teil des Pakets ist.

+ +

Mongrel

+ +

Dateien dem Benutzer zuordnen:

+ +
$ sudo chmod -R www-data. /var/www/rails/tracks/
+ +

Server starten:

+ +
$ sudo mongrel_rails start -c /var/www/rails/tracks -d -p 3001 -e production --prefix /tracks --user www-data --group www-data
+ +

Server automatisch starten:

+ +
$ sudo vim /etc/init.d/PROJEKTNAME
+#!/bin/bash
+mongrel_rails start -c /var/www/rails/tracks -d -p 3001 -e production --prefix /tracks --user www-data --group www-data
+
+$ sudo chmod +x /etc/init.d/PROJEKTNAME
+$ update-rc.d PROJEKTNAME defaults
+ +

Mongrel regelmäßig neu starten wegen Ressourcen und so...

+ +
$ sudo crontab -u www-data -e
+
+# m  h          dom mon dow   command
+13 5 * * * mongrel_rails restart -c /var/www/rails/tracks
+ +

Das Ganze jetzt noch hinter den Apache. In der vhost-Konfiguration (Abhängigkeit mod_proxy und mod_proxy_http):

+ +
<Proxy *>
+    Order Deny,Allow
+    Allow from all
+</Proxy>
+
+ProxyPass /tracks http://127.0.0.1:3001/tracks
+ +

Passenger

+ +

aptitude install ruby build-essential apache2-mpm-prefork apache2-prefork-dev rake rubygems1.8 ruby1.8-dev libopenssl-ruby1.8 libmysql-ruby1.8

+ +

gem install passenger +/var/lib/gems/1.8/bin/passenger-install-apache2-module

+ +

/etc/apache2/mods-available/passenger.load: +LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-2.2.5/ext/apache2/mod_passenger.so

+ +

/etc/apache2/mods-available/passenger.conf: +PassengerRoot /var/lib/gems/1.8/gems/passenger-2.2.5 +PassengerRuby /usr/bin/ruby1.8

+ +

a2enmod passenger

+ +

http://www.modrails.com/documentation/Users%20guide.html#deploying_rails_to_sub_uri

+ +

cd DocumentRoot +ln -s /var/www/myrailsapp/public myrailsapp

+ +

vhost conf: +RailsBaseURI /myrailsapp

+ +

/etc/init.d/apache2 restart

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/211/index.html b/siarp.de/node/211/index.html new file mode 100644 index 0000000..f8deb16 --- /dev/null +++ b/siarp.de/node/211/index.html @@ -0,0 +1,181 @@ + + + + + + + + + + + + Funambol SyncML-Server | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Funambol SyncML-Server

+
+
+
+ + +
+
+ + + + + +
+

Funambol ist derzeit die komfortabelste Möglichkeit, Adressen und Termine aus Thunderbird und Lightning mit dem Handy zu synchronisieren.

+ +

Funambol auf dem VPS installieren

+ +
    +
  1. Download und Ausführen von funambol-8.0.0.bin (Installation nach /opt/Funambol) ohne am Ende den Server zu starten
  2. +
  3. Anpassung von FUNAMBOL_HOME in /bin/funambol, /bin/funambol-server und /bin/install
  4. +
  5. Auskommentieren der nicht benötigten Dienste in /bin/funambol: Hypersonic, CTP Server, Inbox Listener, Pim Listener (jeweils im Start- und Stop-Teil)
  6. +
  7. Herabsetzen von MEM_OPTS von 512 auf 12 MB in /bin/funambol-server: MEM_OPTS="-Xmx12M"
  8. +
  9. Auf das (64-Bit-)JRE verweisen (s. Funambol-Wiki):
    +Dafür in /bin/funambol und /bin/install $JAVA_HOME setzen: export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.16/jre
    +Zusätzlich noch /opt/Funambol/tools/jre-1.5.0/lib nach /usr/lib/jvm/java-6-sun-1.6.0.16 kopieren (für die DB-Initialisierung)
  10. +
  11. Den MySQL-Java-Connector herunterladen und nach /tools/jre-1.5.0/jre/lib/ext entpacken
  12. +
  13. Umstellen von der mitgelieferten Hypersonic-DB auf MySQL (nach dem Admin-Handbuch): In /ds-server/install.properties auf MySQL umstellen, die Standard-Einstellungen auskommentieren, den MySQL-Teil aktivieren und anpassen:
    +MySQL
    +=====
    +jdbc.classpath=/opt/Funambol/tools/jre-1.5.0/jre/lib/ext/mysql-connector-java-5.1.10-bin.jar
    +jdbc.driver=com.mysql.jdbc.Driver
    +jdbc.url=jdbc:mysql://localhost/funambol?characterEncoding=UTF-8
    +jdbc.user=www
    +jdbc.password=XXXXX
  14. +
  15. Datenbank funambol anlegen und Benutzer www alle Rechte einräumen
  16. +
  17. Datenbank mit Installations-Skript initialisieren: sudo /opt/Funambol/bin/install
  18. +
  19. Funambol starten: sudo /opt/Funambol/bin/funambol start
  20. +
  21. Bonus: Standard-Port 8080 umändern in der Catalina-Konfiguration (/tools/tomcat/conf/server.xml)
  22. +
+ +

Einrichtung

+ +
    +
  1. Mit dem Funambol Administration Tool zum Server verbinden
  2. +
  3. Admin-Passwort ändern
  4. +
  5. guest-Account löschen
  6. +
  7. neue Accounts anlegen
  8. +
+ +

Handy synchronisieren

+ +

(Mit meinem Nokia E71) +Synchronisations-Profil anlegen:

+ +
    +
  1. Programme 'Kontakte' und 'Kalender' aktivieren. 'Kontakte' synchronisiert mit externer Datenbank "card", 'Kalender' mit "cal"
  2. +
  3. Verbindungseinstellungen definieren
  4. +
  5. Synchronisieren
  6. +
+ +

Thunderbird und Lightning synchronisieren

+ +
    +
  1. Das Synchronisations-Plugin installieren
  2. +
  3. Optionen einstellen:
  4. +
+ +

- Server Location: http://siarp.de:5072/funambol/ds bzw. http://dienste.siarp.de/funambol/ds mit Umleitung +- Kontakte synchronisieren mit "card" +- Kalender synchronisiert mit "cal"

+ +

ToDo

+ +

https einrichten: https://wiki.ow2.org/sync4j/Wiki.jsp?page=HowtouseHttps

+ +

Quellen

+ +
    +
  • http://bjoern.taunus-server.de/cms/index.php?option=com_content&task=view&id=314&Itemid=65
  • +
  • http://download.forge.objectweb.org/sync4j/funambol-installation-and-administration-guide.pdf
  • +
+
+ + + + +
AttachmentSize
Package icon bin.zip4.25 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/214/index.html b/siarp.de/node/214/index.html new file mode 100644 index 0000000..17a90d7 --- /dev/null +++ b/siarp.de/node/214/index.html @@ -0,0 +1,128 @@ + + + + + + + + + + + + Neue E-Mail-Organisation - Inbox Zero | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Neue E-Mail-Organisation - Inbox Zero

+
+
+
+ + +
+
+ + + + + +
+

Nachdem Hosteurope nun schon seit einiger Zeit regelmäßig anmahnt, dass die Speicherplatz für E-Mails langsam zu Ende geht, woraufhin ich regelmäßig ein paar dicke Mails lösche um die Galgenfrist zu verlängern, habe ich nun endlich die Organisationsstruktur meines Posteingangs grundlegend erneuert. Bisher hatte ich zwar schon nach Jahren archiviert, die einzelnen E-Mails aber in ein recht komplexes System an Unterordnern einsortiert. (Einer für jeden Mailaccount, Unterordner für verschiedene Korrespondenzpartner und Themen, usw. usf.) Insgesamt war das alte System viel zu wartungsintensiv und unflexibel. Nachdem ich im Büro mehr aus einer Laune heraus gleich vom ersten Arbeitstag an den Posteingang täglich komplett abgearbeitet hatte, wollte ich das System für meine privaten Mails jetzt übernehmen und perfektionieren.

+ +

Grundsätzlich lehnt die Systematik an Merlin Manns Inbox Zero an. Das Basisprinzip ist, sämtliche E-Mails möglichst schnell zu kategorisieren und abzuarbeiten. Eine gute Zusammenfassung (wesentlich mehr habe ich dazu gar nicht gelesen) gibt es bei imgriff.com.

+ +

Mein System funktioniert jetzt so:

+ +

E-Mail-Systematik

+ +
    +
  1. Die E-Mails von sämtlichen Accounts landen in der Inbox - keine automatische Vorsortierung in irgendwelche Unterordner. Wenn man eine E-Mail lesen will, fasst man sie ohnehin an. Und wenn man sie nicht lesen will, dann sollte man dafür sorgen, dass man sie gar nicht erst bekommt. Auf jeden Fall trainiert es vom ewigen "das lese ich dann später" wegzukommen.
  2. +
  3. Die Inbox wird manuell sortiert. E-Mails werden entweder sofort gelöscht, archiviert oder kommen in den Ordner 'Erledigen', falls sie sich tatsächlich nicht sofort abarbeiten lassen.
    +Das Archiv ist unterteilt in E-Mails, die an mich persönlich geschrieben wurden und alles andere (Rechnungen, archivierungswürdige Newsletter, etc.)
  4. +
  5. Zum Jahresbeginn wird der gesamte Bestand gesichert und im IMAP in einen Archiv-Ordner verschoben. Der Ordner vom vorletzten Jahr wird aus dem Account gelöscht, so dass immer die E-Mails des gesamten letzten plus die des laufenden Jahres online verfügbar sind. Alles andere wird per Hosteurope-Backup-Funktion im MBOX-Format wegarchiviert und kann lokal eingesehen werden.
  6. +
+
+ + + + + +
AttachmentSize
Image icon Inbox_Zero.jpg15.17 KB
File Inbox_Zero.svg15.49 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/218/index.html b/siarp.de/node/218/index.html new file mode 100644 index 0000000..af06ad8 --- /dev/null +++ b/siarp.de/node/218/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + + + Bazaar: incompatible format 2a and rich-root support | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Bazaar: incompatible format 2a and rich-root support

+
+
+
+ + +
+
+ + + + + +
+

I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message

+ +
bzr: ERROR: RemoteRepository(bzr+ssh://SERVER/path/to/repo/.bzr/)      
+is not compatible with
+CHKInventoryRepository('file:///path/to/repo/.bzr/repository/')
+different rich-root support
+ +

Reading http://www.nabble.com/bazaar-error-on-repository-td25868297.html it seems different Bazaar versions make different repository formats which are incompatible. But

+ +
+

[...] you could move the server to a rich root capable format; then + it would work (though crossing the format boundary can be slow). + 1.3.1 is new enough to support rich-root-pack.

+
+ +

So on the server I did

+ +
bzr upgrade --rich-root-pack repo/
+ +

and now it works. I can push my local branch to the remote repository.

+ +

But only once!

+ +

Second time I wanted to push I got another error:

+ +
bzr: ERROR: bzrlib.errors.ErrorFromSmartServer: Error received from smart server: ('error', "'Bazaar repository format 2a (needs bzr 1.16 or later)\\n'")
+ +

Looks like the format 2a, which is the default for Bazaar >= 2.0 is incompatible with the one on my server. Downgrading to an older format of my local tree did the trick:

+ +
bzr upgrade --format=1.14-rich-root
+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Thanks, helped a lot :)

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/220/index.html b/siarp.de/node/220/index.html new file mode 100644 index 0000000..3e4c571 --- /dev/null +++ b/siarp.de/node/220/index.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + YAML, jQuery slideToggle and IE6 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

YAML, jQuery slideToggle and IE6

+
+
+
+ + +
+
+ + + + + +
+

As usual with browser bugs and hacks this took me a while to find out.

+ +

I have an unordered list with complex items like floats and stuff. This list is supposed to hide when I click on a button by slowly decreasing its height. I use jQuery's slideToggle for that.

+ +

Problem: In Internet Explorer 6 the content (or parts of it) is hidden after the list is shown (slid down).

+ +

The only thing I found was a blog post saying you shouldn't use any positioning there. I didn't. Well, I thought I didn't…

+ +

For this project I use YAML, a CSS framework and YAML sets all lists to position: relative for IE6 (iehacks.css):

+ +
  /**
+   * Disappearing List-Background Bug
+   * @see        http://www.positioniseverything.net/explorer/ie-listbug.html
+   *
+   * @bugfix
+   * @affected   IE 5.x/Win, IE6
+   * @css-for    IE 5.x/Win, IE6
+   * @valid      yes
+   */

+
* html ul, * html ol, * html dl { position: relative; }
+ +

Overriding this for my sliding list solves the problem.

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/221/index.html b/siarp.de/node/221/index.html new file mode 100644 index 0000000..bba98eb --- /dev/null +++ b/siarp.de/node/221/index.html @@ -0,0 +1,126 @@ + + + + + + + + + + + + YAML und Listen im IE6 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

YAML und Listen im IE6

+
+
+
+ + +
+
+ + + + + +
+

Achtung! Böse Falle mit YAML und Listen im Internet Explorer 6! Folgender Code steht in der iehacks.css und gilt für den IE6.

+ +
/**
+ * Disappearing List-Background Bug
+ * @see        http://www.positioniseverything.net/explorer/ie-listbug.html
+ *
+ * @bugfix
+ * @affected   IE 5.x/Win, IE6
+ * @css-for    IE 5.x/Win, IE6
+ * @valid      yes
+ */

+
+* html ul, * html ol, * html dl { position: relative; }
+ +

Ich hatte deswegen jetzt schon ein zweites Mal Probleme. Diesmal ging es darum, dass Listenelemente sich nicht entsprechende dem overflow verhielten, wie andere Elemente. Wieder habe ich eine Weile nach dem Problem gesucht.

+ +

Der globale Ansatz des YAML-Fixes ist schon gewagt, finde ich. Man muss das immer im Hinterkopf behalten. Immer, wenn etwas nur im IE6 komisch ist mit der Darstellung von Listen, prüfen ob es daran liegt. Umgehen (quasi ein Fix-Fix) ist einfach Z.B.:

+ +
/* nur für IE6 anwenden: */
+#elem ul { position: static; }
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/222/index.html b/siarp.de/node/222/index.html new file mode 100644 index 0000000..e16402f --- /dev/null +++ b/siarp.de/node/222/index.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + My SilverStripe Usability Test | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

My SilverStripe Usability Test

+
+
+
+ + +
+
+ + + + + +
+

So I decided to try out SilveStripe (Version 2.3.3) to check out if it's of any value for me as a freelance web developer. I'm kind of an expert in Drupal, I also work with Plone, and lately I'm very interested in usability and I do track initiatives in the Drupal and Plone community to give users a better experience. I know that feedback of a first-time user is valuable so I thought I'd write down my impressions of SilverStripe right away.

+ +

Installation

+ +

On the SilverStripe homepage I found the big download button (actually I searched for "Downloads" or something in the main navigation first and it took me a second to find the blue thing on the right) and then got my stable version. I extracted it in the web root of my machine, renamed the folder to "SilverStripe" and then searched for installation instructions. In the silverstripe.org main navigation I clicked on "Help" and after skimming all of the options I clicked in "Documentation". There I found the Installing link under "Installation". There I got confused for a few seconds by the platform-dependent instructions but then I realized that this is about setting up the basic web stack, which I,of course, already have so down to "Existing Webservers" > Apache. Ok, the Installation Steps tell me that there's nothing to do but open a browser and enter the URL. Well, I know, you always have to set up a database first so CREATE DATABASE silverstripe; and then open the browser.

+ +

I had one usability issue with the layout of the installation screen. I was not sure about the "steps", where I was and what would be next. Major confusion was the placement of the button to proceed which is somewhere at the top but not at the very top of the form/page. I scrolled down to read and check everything and I expected a kind of "next" button at the bottom.

+ +

All in all, the install process was very easy, went smoothly and I could find all the information I needed. I seems as if the download button at the top right of the site is supposed to be very prominent but to me it was not. Of course this is not a big issue at all. As of the installation instructions there could be a shortcut, like: If you already have your server set up, just extract SilverStripe to your web root, create a database and point your browser to the new SilverStripe URL. The automatic installer will guide you through the setup. The layout of the installer is a major (but not critical) issue to me. There should be some overview of the steps and the button should be somewhere else with better wording.

+ +

Notes:

+ +
    +
  • Don't pre-populate the admin password - it's insecure and users won't "remember" the password as they didn't enter it in the first place
  • +
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/223/index.html b/siarp.de/node/223/index.html new file mode 100644 index 0000000..116b084 --- /dev/null +++ b/siarp.de/node/223/index.html @@ -0,0 +1,113 @@ + + + + + + + + + + + + Plone: Item Type as Criterion for Collection but not to show up in Search | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Plone: Item Type as Criterion for Collection but not to show up in Search

+
+
+
+ + +
+
+ + + + + +
+

You can't select an item type as a criterion for a collection if it is not selected to be included in search results. In the "Search settings" (/@@search-controlpanel) you can exclude certain content types from being "searched and be available in the user facing part of the site". That actually corresponds to the list of types_not_searched in site_properties. Now that list is excluded from available content types as a criterion for collections. At least for the UI–it still works.

+ +

If you want a content type to not show up in search results but in collections, you can work around that problem by enabling the type for search temporarily, set up your collection and disable the type for search afterwards. It's a bit odd, because you can't even see your selection in the criterion page afterwards but it works.

+ +

I'd say this is a bug and the collection UI should present all available types in the option box, if searchable or not. I guess I should file a report.

+ +

Update: I submitted a bug report.

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/227/index.html b/siarp.de/node/227/index.html new file mode 100644 index 0000000..b739999 --- /dev/null +++ b/siarp.de/node/227/index.html @@ -0,0 +1,134 @@ + + + + + + + + + + + + Committeten auf deutsch | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Committeten auf deutsch

+
+
+
+ + +
+
+ + + + + +
+

Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:

+ +

Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...

+ +

Also, wisst ihr bescheid. Übersetzt eure Werkzeuge und pflegt die Sprachkultur!

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Für die Übersetzung von „Repository“ sollte man ähnlich lange bei einem Bier im Lebowski nachdenken. „Magazin“ gefällt mir nicht sonderlich gut.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/228/index.html b/siarp.de/node/228/index.html new file mode 100644 index 0000000..caf14c0 --- /dev/null +++ b/siarp.de/node/228/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + + Strato HiDrive unter Ubuntu einbinden | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Strato HiDrive unter Ubuntu einbinden

+
+
+
+ + +
+
+ + + + + +
+

Mein neues HiDrive unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. so), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per sshfs. Fühlt sich fast an, als wäre es die lokale Festplatte.

+ +

Vorbereitung:

+ +
sudo adduser username fuse         # Benutzer "username" der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)
+sudo mkdir /media/hidrive                    # Mountpoint anlegen
+sudo chmod 777 /media/hidrive
+ +

mount funktioniert so:

+ +
sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +

Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).

+ +

unmount so:

+ +
fusermount -u /media/hidrive
+ +

Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297

+ +

Das Login-Skript sieht dann so aus:

+ +
#!/bin/sh
+sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive
+ +


+ +
+ +

Edit:

+ +

Nachtrag

+ +

Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:

+ +
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
+ +

Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:

+ +
fusermount: failed to open /etc/fuse.conf: Permission denied
+ +

Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Funktioniert das bei dir noch? Bei mir kommt nach dem Login "remote host has disconnected".

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Bei mir gibt's dasselbe Problem.

+
+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also bei mir geht es wunderbar :)

+
+
+ +
+
+
+ +
+ + + + + +

+ +
+

Hallo,

+ +

vielen Dank für den Tipp.

+ +

Klappt wunderbar auch unter der neusten Ubuntu Version 11.10 64bit.

+ +

Aber man muss noch die Datei /etc/fuse.conf bearbeitet und:

+ +

user_allow_other hinzufügen.

+ +

Gruß +Jens

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/229/index.html b/siarp.de/node/229/index.html new file mode 100644 index 0000000..ca748b4 --- /dev/null +++ b/siarp.de/node/229/index.html @@ -0,0 +1,125 @@ + + + + + + + + + + + + MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren

+
+
+
+ + +
+
+ + + + + +
+
sudo vim /etc/apt/sources.list
+> # MongoDB
+> deb http://downloads.mongodb.org/distros/ubuntu 9.4 10gen
+
+sudo aptitude update && sudo aptitude install mongodb-stable
+
+sudo /etc/init.d/mongodb start
+
+git clone http://github.com/ry/node.git
+cd node
+git checkout -b tags/v0.2.0
+./configure --prefix=/home/martin
+make
+make install
+
+curl http://npmjs.org/install.sh | sh
+npm install mongodb mustache
+ +

http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/23/index.html b/siarp.de/node/23/index.html new file mode 100644 index 0000000..1efec2c --- /dev/null +++ b/siarp.de/node/23/index.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1 | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Apache 2.2.2, MySQL 5.0.21, PHP 5.1.4 und Subversion 1.3.1

+
+
+
+ + +
+
+ + + + + +
+

Anmerkung: Dieses Protokoll ist mit besserer Formatierung unter http://www.siarp.de/installation-log.html abgelegt.

+
- Ziel: Apache, MySQL, PHP und Subversion auf den Hosteurope vServer unter SuSE 9.1 separat installieren -
+

siarp Neuinstallation (Kofler/Subversion-Mischung plus ein paar Extras)

+

MySQL, Apache, PHP 5

+
  • + Nach Empfehlung von http://www.kofler.cc/forum/forumthread.php?rootID=3538 deinstalliere ich Apache, PHP und MySQL über yast.
    + Dabei ignoriere ich sämtliche Abhängigkeiten mit irgendwelchen installierten 'frontpage extensions', 'mambo' und vor allem dem Paket 'psa' → Plesk wird kastriert. +
    + $ rcapache2 stop
    + $ yast
    → nach 'mysql', 'php' und 'apache' suchen, alles raushauen und neu starten +
    +
  • +
  • + Ich lege im Home-Verzeichnis von root ein Verzeichnis siarp an, in dem ich herunterladen und entpacken kann. Dahin lade ich die Apache-Quellen, MySQL, PHP und Subversion. +
    + $ cd ~

    + $ md siarp
    + $ cd siarp
    + $ wget http://ftp.wayne.edu/apache/httpd/httpd-2.2.2.tar.gz
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-server-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-client-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-devel-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://dev.mysql.com/get/Downloads/MySQL-5.0/MySQL-shared-5.0.21-0.glibc23.i386.rpm/from/ftp://ftp.fu-berlin.de/unix/databases/mysql/
    + $ wget http://de2.php.net/get/php-5.1.4.tar.gz/from/de3.php.net/mirror +
    +
  • +
  • + Dann noch entpacken: +
    + $ gunzip httpd-2.2.2.tar.gz
    + $ gunzip php-5.1.4.tar.gz
    + $ tar -xvf httpd-2.2.2.tar
    + $ tar -xvf php-5.1.4.tar +
    +
  • +
  • + MySQL installieren +
    + $ cd ~/siarp
    + $ rpm -i MySQL*.rpm +
    +
  • +
  • + Weiter nach der Kofler-Anleitung: +
    + $ wget http://kent.dl.sourceforge.net/sourceforge/libpng/zlib-1.2.3.tar.gz
    + $ wget ftp://xmlsoft.org/libxml2/libxml2-2.6.24.tar.gz
    + $ gunzip zlib-1.2.3.tar.gz
    + $ gunzip libxml2-2.6.24.tar.gz
    + $ tar -xvf zlib-1.2.3.tar
    + $ tar -xvf libxml2-2.6.24.tar +
    +
  • +
  • + Installation der Libraries +
    + $ cd zlib-1.2.3/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd ..
    + $ cd libxml2-2.6.24/
    + $ ./configure
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + Apache2 in /usr/local/apache2 installieren. Ich habe hier noch ein paar zusätzliche Module aktiviert, WebDAV wird von Subversion benötigt. +
    + $ cd httpd-2.2.2/
    + $ ./configure --prefix=/usr/local/apache2 --enable-so --enable-dav --enable-ssl --enable-alias --enable-dir --enable-deflate
    + $ make
    + $ make install
    + $ cd .. +
    +
  • +
  • + PHP installieren +
    + $ cd php-5.1.4/
    + $ ./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-libxml-dir=/usr/local/lib --with-zlib --with-zlib-dir=/usr/local/lib --with-mysql=/usr --with-mysqli=/usr/bin/mysql_config --with-gd --enable-soap --enable-sockets
    + $ make
    + $ make install +
    +
  • +
  • + In die /usr/local/apache2/conf/httpd.conf füge ich in Zeile 55 ein: +
    + #siarp (manuell eingefuegt nach php-Installation)
    + AddType application/x-httpd-php .php +
    +
  • +
  • + Testlauf +
    + $ /usr/local/apache2/bin/apachectl start
    + $ touch /usr/local/apache2/htdocs/phptest.php +
    +

    Dann in die Datei phptest.php die Zeile <?php phpinfo(); ?> einfügen und speichern. Und siehe: Die PHP-Konfiguration ist einsehbar. +

  • +
  • + Aber: Schon verhält er sich komisch! HTML-Seiten, in denen auf ein Bild verwiesen wird, werden nicht ausgeliefert. (Wieder das Dateigrößen-Problem?)
    Nach etwas Suchen dann die Lösung: In der httpd.conf muss die Zeile "EnableSendfile off" aktiviert werden (Z. 360). → Die Sendfile-Unterstützung wurde beim Kompilieren wohl nicht richtig erkannt; ein Klassiker.
    Frage: Sollte auch MMAP (Zeile darüber) deaktiviert werden? (Das war der Standard-Trick beim XAMPP.) Da MMAP und Sendfile aber wohl für Performanceverbesserungen stehen (größerer Adressraum, glaube ich), lasse ich zumindest MMAP bis auf Weiteres drin. +
  • +
  • + Weil's bis hierher so schön lief, logge ich mich in Virtuzzo ein, und erstelle vor der Subversion-Installation noch ein Backup.:
    + "May 27, 2006 01:48:45 PM, 580.83 Mb" (SuSE-Apache, -PHP und -MySQL deinstalliert und separat installiert) +
  • +

Subversion: Installation

+
  • + Erst mal zurück nach Hause und Subversion herunterladen und entpacken +
    + $ cd ~/siarp
    + $ wget http://subversion.tigris.org/downloads/subversion-1.3.1.tar.gz
    + $ gunzip subversion-1.3.1.tar.gz
    + $ tar -xvf subversion-1.3.1.tar +
    +
  • +
  • + Jetzt mit den magischen Parametern installieren. (Im Wesentlichen nach http://svn.collab.net/repos/svn/trunk/INSTALL mit Hilfe von http://iedb.org/blog/howtos/svn_install_de/.) +
    + $ cd subversion-1.3.1/
    + $ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib +
    +

    Am Schluss heult configure noch rum, dass keine BerkeleyDB installiert ist. Wunderbar, FSFS ist sowieso moderner. (→ http://svnbook.red-bean.com/en/1.1/ch05.html#svn-ch-5-sect-1.3.2 und Vergleich unter http://svnbook.red-bean.com/en/1.2/svn.reposadmin.html#svn.reposadmin.basics.backends)
    + Und weiter:

    +
    + $ make
    + $ make install +
    +
  • +
  • + Leider will Apache jetzt nicht mehr starten und meldet

    + httpd: Syntax error on line 54 of /usr/local/apache2/conf/httpd.conf: Cannot load /usr/local/apache2/modules/mod_dav_svn.so into server: libsvn_repos-1.so.0: cannot open shared object file: No such file or directory

    + Aber das kenne ich schon vom XAMPP - Google hilft. Unter http://svn.haxx.se/users/archive-2004-11/0390.shtml wird mir empfohlen, in der Datei /etc/ld.so.conf die Zeile /usr/local/lib einzufügen. Da die bereits vorhanden ist und ich ja auf die Libraries vom separat installierten Apache verweisen möchte, versuche ich es mit /usr/local/apache2/lib (weil make install am Schluss ausgiebt, dass die Libraries dorthin installiert wurden). Danach muss die Konfiguration erneuert werden: +
    + $ /sbin/ldconfig +
    +

    Und schon will er wieder. +

  • +

Subversion: Konfiguration

+
  • + Erste Frage: Wohin mit dem Repository? (Ich habe diese UNIX-Verzeichnisstruktur nie so wirklich verinnerlicht.) Nach einem Blick in http://de.wikibooks.org/wiki/Linux-Kompendium:_Verzeichnisse_unter_Linux bin ich nur unwesentlich schlauer und entscheide ich mich für /home/svn-repos. +
    + $ cd /home
    + $ md svn-repos +
    +
  • +
  • + Die zweite Frage ist, wofür und wieviele Repositories angelegt werden sollten. Ich beginne mal mit siarp. Subversion arbeitet dabei als Benutzer svn. +
    + $ cd /home/svn-repos
    + $ md siarp
    + $ svnadmin create /home/svn-repos/siarp
    + $ chown -R svn.svn /home/svn-repos/siarp
    + $ chmod -R ug+w /home/svn-repos/siarp
    + $ chmod ug+s /home/svn-repos/siarp /home/svn-repos/siarp/* +
    +
  • +
  • + Damit die Repositories etwas schöner gelistet werden, bringt Subversion noch ein Stylesheet für Apache mit, das in die htdocs muss. +
    + $ cd ~/siarp/subversion-1.3.1/tools/xslt/
    + $ md /usr/local/apache2/htdocs/subversion-xslt
    + $ cp * /usr/local/apache2/htdocs/subversion-xslt
    + $ chmod 644 /usr/local/apache2/htdocs/subversion-xslt/* +
    +
  • +
  • + Apache muss auf die Repositories zugreifen können. In der Subversion-Installationsanleitung heißt es dazu lapidar: +
    + NOTE: Make sure that the user 'nobody' (or whatever UID the httpd process runs as) has permission to read and write the Berkeley DB files! This is a very common problem. +
    +

    Davon weiß ich allerdings nicht, wie man das am sinnvollsten regelt. Auch im Subversion Handbuch steht nur was von "There is no single correct way to set up your permissions".
    + Die Repositories einfach allgemein freigben? In der schönen (und häufig zitierten) Deadbeef-Anleitung für Apache+Subversion wird einfach der gesamte Apache mit dem svn-User gestartet. Allerdings geht das nur, wenn man den Server nicht auf den Standard-Ports betreibt. Meine Lösung wird im Subversion Handbuch zwar nur angedeutet, sollte aber korrekt sein: Dem Apache über die httpd.conf mitteilen, dass er als Nutzer svn agieren soll. Also die Zeilen 70 und 71 ändern auf. (Davor lief Apache als daemon.)

    +
    + User svn
    + Group svn +
    +
  • +
  • + Jetzt muss noch Apache das neue Repository in der https.conf bekannt gegeben werden: +
    + # siarp Subversion-Anhang
    + <Location /svn/siarp>
    +   DAV svn
    +   SVNPath /home/svn-repos/siarp
    +    SVNIndexXSLT "/subversion-xslt/svnindex.xsl"
    +   AuthType Basic
    +   AuthName "siarp.de repository"
    +   AuthUserFile /home/svn-repos/svn-auth-file
    +   Require user martin tilman
    + </Location> +
    +
  • +
  • + Für die Nutzerverwaltung braucht Subversion ein Userfile, das ich unter /home/svn-repos/svn-auth-file anlegen will. Dafür muss ich das htpasswd-Tool vom Apache benutzen: +
    + $ /usr/local/apache2/bin/htpasswd -cm /home/svn-repos/svn-auth-file tilman

    + New password:
    + Re-type new password:
    + Adding password for user tilman
    +
    +

    Neue Benutzer fügt man mit dem Befehl /usr/local/apache2/bin/htpasswd -m /home/svn-repos/svn-auth-file benutzername hinzu. +

  • +
  • + Das war's. Subversion ist unter http://www.siarp.de/svn/siarp/ erreichbar, sobald Apache gestartet ist. +
    + $ /usr/local/apache2/bin/apachectl start +
    +
  • +
  • + Als krönenden Abschluss kopiere ich mein Protokoll in htdocs, so dass es unter http://www.siarp.de/installation-log.html erreichbar ist und mache mit Virtuzzo ein Backup ("May 27, 2006 05:41:32 PM, 707.27 Mb"). +
  • +

+

Zusammenfassung, To-Do und Fragen

+

+ So weit, so gut. Wir haben jetzt Apache mit MySQL und PHP und außerdem ein funktionierendes Subversion. Was muss jetzt noch kommen? +

+
  • Subversion mit SSL nutzen. Dafür habe ich Apache mit --enable-ssl kompiliert, aber noch nix probiert.
  • +
  • MySQL testen. Noch nicht gemacht.
  • +
  • Eventuell noch etwas Sicherheits-Tuning. MySQL ist noch unkonfiguriert (Passwort) und der Subversion-User ist auch noch ohne Passwort.
  • +
  • Noch mal eine schöne "Wie legt man ein Repository an"-Anleitung, die man dann nur noch abarbeiten muss
  • +
  • Automatisiertes Backup für Repositories und htdocs. Was noch?
  • +
  • Vielleicht sollte Apache nach einem Reboot automatisch starten. Wie das geht steht in der Kofler-Anleitung.
  • +
  • Noch mal die Frage: Brauchen wir System-Nutzer-Accounts? Oder müssen wir sowieso als root arbeiten, bei dem, was wir tun?
  • +

+ Allgemeine Bemerkungen zur Konfiguration +

+
  • Apache wird gestartet mit /usr/local/apache2/bin/apachectl start
  • +
  • Die Webseite liegt unter /usr/local/apache2/htdocs/, die Repositories unter /home/svn-repos/
  • +
  • Wir sollten wohl doch für jedes Projekt ein extra Repository anlegen, da sonst das System der Gesamt-Versionsnummer von Subversion keinen Sinn macht
  • +

+

Further reading: Backup und Vorsorge

+
  • + Noch ein paar Überlegungen zum Thema Backup: Virtuzzo geht relativ fix (ca. 20 Min), allerdings sind nur zwei Backups möglich. Also am besten später mal durch ein Backup des komplett eingerichteten Systems ersetzen. Dann hat man immer noch ein Backup für akutes übrig. +
  • +
  • + Im Hosteurope-Hilfesystem wird außerdem ReoBack empfohlen. Vielleicht bei Gelegenheit mal anschauen. +
  • +
  • + Noch was anderes: Anscheinend kann man (im Gegensatz zu den WebPacks) den Traffic nicht hart limitieren. Bis jetzt hatten wir beim Rumbasteln immer unter 400MB im Monat. Freivolumen ist laut KIS 250GB (die neuen Pakete haben 500GB bei gleichem Preis, das hätten sie ruhig mal rückwirkend upgraden können), das macht also ca. 8GB am Tag. Ich habe jedenfalls erst mal eine Warnbenachrichtigung bei mehr als 2GB am Tag eingerichtet. +
  • +
  • + Hab mich bei der Suche nach einer harten Traffic-Begrenzung nochmal in Plesk eingeloggt. Das ist jetzt wohl wirklich blind und taub, man bekommt keine Server-Optionen mehr angezeigt. +
  • +

Dank an (Linksammlung)

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Wie gesagt, es muss noch ein Repositories-erstellen-HowTo folgen. Um es zu dokumentieren schon mal die Bemerkung:

+

Man muss nicht unbedingt jedes Repository einzeln in die httpd.conf eintragen, sondern kann dort auch einen SVNParentPath angeben. Alle Repositories, die in diesem Verzeichnis liegen, werden dann automatisch gelistet. Nachteil: Keine getrennte Benutzerverwaltung für die verschiedenen Repositories (soweit mir bekannt --> nochmal prüfen)

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

Sammlung: Module, die vielleicht auch noch schön für'n Apache wären. (Lassen sich durch --enable-so ja nachträglich einbinden.)

+

- mod_deflate
+Dazu Zitat aus der Subversion-Installationsanleitung:
+If you have configured mod_deflate to be in the server, you can enable compression support for your repository by adding the following line to your Location block: SetOutputFilter DEFLATE

+

- mod_mime
+MIME-Zuordnung nach Dateinamenerweiterung

+

- mod_dav_fs
+Dieses Modul bietet Zugriff auf das _lokale_ Dateisystem, falls gebraucht. So oder so ist WebDAV an sich noch mal einen Blick wert.

+

- mod_vhost_alias
+Wird's gebraucht? Ich hab noch nicht so die Ahnung von vHost-Konzept.

+

- mod_dir
+Das habe ich vergessen. Directory-Listings sind mitunter schon ganz praktisch.

+
+
+ +
+ +
+ +
+ + + + + +

+ +
+

To do so, start the server, then issue the following commands:
+/usr/bin/mysqladmin -u root password 'new-password'
+/usr/bin/mysqladmin -u root -h lvps80-237-161-173.dedicated.hosteurope.de password 'new-password'
+See the manual for more instructions.

+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/231/index.html b/siarp.de/node/231/index.html new file mode 100644 index 0000000..4f71b70 --- /dev/null +++ b/siarp.de/node/231/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + + + Reinventing the wheel: Automatic Bidirectional Directory Synchronization | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Reinventing the wheel: Automatic Bidirectional Directory Synchronization

+
+
+
+ + +
+
+ + + + + +
+

As already mentioned, I am the proud owner of an online hard drive and I love it. Enough space for everything that's worth keeping, secure access over lots of different protocols (including rsync), an automatic backup function... It would be perfect if I had an Internet connection of at least 100 MBit/s. But I haven't. (Actually the thing almost feels like a local disk when I use it from my computer at work. But that's through a university network.) So I had to come up with a little more sophisticated architecture. I bought a GuruPlug server and added an external USB hard drive to it. The basic idea is to use the USB drive over the LAN while at home but still being able to have all data synchronized to the online hard drive in order to have automatic backup and fast access from everywhere else. I thought that the sychronization part would be the easiest as there is a plethora of software available for this task but when I had a closer look at the tools, I ran into problems:

+ +
    +
  • rsync, the best known synchronization software only does unidirectional synching. (So it's a mirroring tool, not a synchronization tool, to be correct.) But I want to be able to change files at home on the local drive and on the go on the online drive and have them automatically sychronized overnight.
  • +
  • Unison does bidirectional synchronization, also using the heavily traffic-optimized rsync protocol. Sounds perfect. But unison does not really work on locally mounted remote drives as it apparently calculates a hash sum for each and every file which results in downloading the entire online hard drive. (Currently 135 GB in my case.) Usually one would use a unison server for that, calculating the hashes locally on both sides but I do not have shell access to the server - it's only a hard drive.
  • +
  • JFileSync, my personal favorite, does bidirectional synchronization and can run from the shell. But when I tried to use it for my "135 GB, 70000 files" directory, it blew up my server's memory as it does a complete comparison in the first step, putting the pending actions for all files in an xml structure, as far as I can tell. (I have to add that the directories were almost in sync at that time. So it's not only because of the huge number of actions for the first sychronization.)
  • +
+ +

Is it really that hard to have two directories synchronized with the files only compared by their size and their timestamp? I ended up writing my own SyncTool in Java. And while I was at it, I added the possibility to receive the synchronization protocol via Jabber.

+ +

Libraries used

+ +

I am standing on the shoulders of giants here, I have to say. The tool uses H2 to keep track of the files, the Apache Commons and log4j for the actual copy procedure and log output, JSAP to parse the command line and Smack to connect to Jabber. So all I did was implementing the actual synchronization algorithm: Read the file list, compare and synchronize, recurse. Done using Eclipse and Maven.

+ +

Where to get it

+ +

If you want to do something similar and don't have the time to reinvent the wheel once again, you can download the SyncTool from my homepage. Available as open source under the Apache License 2.0.

+ +

How to use it

+ +

The software is intended to work in batch mode and thus performs bidirectional synchronization only without conflict resolution of any kind. If a file was modified on both sides, the older one being dismissed and overwritten by the newer one. (It should be no problem, however, to add a feature like a --dont-overwrite-conflicting-files with a few lines of additional code.) That being said, the second thing you have to think about is that you need a Java JRE. The Open JDK 6 JRE works pretty well with the program on my server, just apt-get install default-jre.

+ +

Remember to backup your files, this software comes with ABSOLUTELY NO WARRANTY.

+ +

This is the help page:

+ +
Usage: java -jar synctool-1.0.8.jar <source path> <destination path> [(-f|--dbfile) <database file>] [(-l|--logfile) <logfile>] [(-j|--jabber) <jabber address>] [(-r|--server) <jabber server>] [(-u|--user) <jabber user>] [(-p|--password) <jabber password>] [-d|--dry-run] [-h|--hashing] [-i|--ignore-directory-attributes] [-s|--silent] [--debug] [-?|--help]
+
+  <source path>
+        the source path
+
+  <destination path>
+        the destination path
+
+  [(-f|--dbfile) <database file>]
+        the path to the database file to use (default: synctool)
+
+  [(-l|--logfile) <logfile>]
+        the path for a logfile to write
+
+  [(-j|--jabber) <jabber address>]
+        send logging output as jabber message to the given address
+
+  [(-r|--server) <jabber server>]
+        the jabber server to connect to
+
+  [(-u|--user) <jabber user>]
+        the jabber user name used for logging in to the server
+
+  [(-p|--password) <jabber password>]
+        the jabber password used for logging in to the server
+
+  [-d|--dry-run]
+        perform a trial run with no changes made
+
+  [-h|--hashing]
+        generate MD5 file hashes for exact comparison
+
+  [-i|--ignore-directory-attributes]
+        do not copy attributes for directories
+
+  [-s|--silent]
+        do not print "Entering directory" and "No operation" messages
+
+  [--debug]
+        print debug messages
+
+  [-?|--help]
+        print help and exit
+
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/232/index.html b/siarp.de/node/232/index.html new file mode 100644 index 0000000..bb83755 --- /dev/null +++ b/siarp.de/node/232/index.html @@ -0,0 +1,508 @@ + + + + + + + + + + + + Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts

+
+
+
+ + +
+
+ + + + + +
+

Seit kurzem haben wir VDSL von der Telekom (yeah!) und deshalb einen neuen Router. Das Gerät ist ein Speedport W 723V A mit relativ vielen Funktionen. Unter anderem können DECT-Telefone direkt angebunden werden und brauchen dann keinen eigene Basisstation. Diese Funktion wollte ich gerne nutzen, weil beim Anschluss des Telefons über die analoge TAE-Buchse nur eine Leitung genutzt werden kann und außerdem die Sprachqualität über die analoge Schnittstelle eher mäßig war. Das Problem: Entgangene Anrufe werden nicht mehr an die Telefone übermittelt, sondern müssen über das Web-Interface nachgeschaut werden - inakzeptabel. Zumindest beim Typ A vom 723 V ist wohl schon der neue Standard CATiq-2.0 implementiert, mit dem die Anruferliste an die Telefone übertragen werden kann. Nur kennen unsere Gigaset C300 Telefone den Standard leider noch nicht. Statt neue Telefone zu kaufen machen wir das Ganze einfach selbst und viel besser: Das folgende Java-Programm ruft die Liste vom Router ab und sendet bei neuen Anrufen eine E-Mail an beliebig viele Empfänger. So bekommen wir sogar unterwegs mit, wenn wir zu Hause einen Anruf verpasst haben.

+ +

Download: speedportcallerid.jar

+ +

Wie immer alles auf eigene Gefahr! Das Programm speichert allerdings nichts und ändert auch keine Einstellungen im Router, so dass sich das Risiko in Grenzen hält :) Ob das Ganze auch mit dem Speedport W 723V B funktioniert, weiß ich nicht.

+ +

Der Aufruf funktioniert so:

+ +
Usage: java -jar speedportcallerid.jar <router password> <update interval> <e-mail adress> <e-mail password> recipient1 recipient2 ... recipientN [--contacts] [--debug] [-?|--help]
+
+  <router password>
+        the login password for the Speedport W 723V (A) router
+
+  <update interval>
+        the interval beetween runs in minutes
+
+  <e-mail adress>
+        Google mail address to send from
+
+  <e-mail password>
+        the login password for the Google account
+
+  recipient1 recipient2 ... recipientN
+        e-mail addresses to send notifications to
+
+  [--contacts]
+        retrieve contacts from Google account and resolve caller names
+
+  [--debug]
+        print debug messages
+
+  [-?|--help]
+        print help and exit
+ +

Konkret lasse ich einen cronjob laufen, der alle 15 Minuten dieses Skript aufruft:

+ +
#!/bin/sh
+cd /media/usb/hidrive/speedport
+sudo -u nobody java -Duser.timezone=Europe/Berlin -jar speedportcallerid.jar --contacts <ROUTER-PASSWORT> 15 <GMAIL-ADRESSE> <GMAIL-PASSWORT> <EMPFÄNGER1> <EMPFÄNGER2>
+ +

Der cronjob dazu sieht so aus:

+ +
*/15 * * * * /usr/local/bin/check-speedport.sh
+ +

Im Moment sind die Mail-Einstellungen auf den Gmail-Server festgelegt (StartTLS + Port 587) für andere Server muss der Code evtl. angepasst werden - vielleicht baue ich später dafür auch nochmal zusätzliche Parameter ein, wenn jemand Interesse hat.

+ +

Nachtrag: Namensauflösung mit Gmail-Kontakten

+ +

Das Programm tat was es soll, aber die Akzeptanz im Haushalt ließ zu wünschen übrig: "Woher soll ich denn wissen, wer das war, wenn da nur die Nummer steht!?" Na gut, ist wohl nicht so praktisch.
+Man kann zwar im Router eine Telefonliste pflegen, aber leider wird die nicht für die Anzeige der Rufnummern auf der Weboberfläche verwendet. Außerdem müsste man dann sämtliche Kontakte nochmal im Speedport pflegen, was sicherlich auch nicht Sinn der Sache ist. Zum Glück hab ich ja ein Android-Handy und deshalb sämtliche Telefonnummern im Google-Account gespeichert. Man muss also nur nochmal nach den passenden Namen suchen, nachdem man die Rufnummern aus dem Speedport gefischt hat. Erledigt. Das Aufruf-Skript muss nur um den Parameter --contacts ergänzt werden (s.o.)

+ +

Code

+ +
package de.tilman.callerid;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+
+import com.google.gdata.client.Query;
+import com.google.gdata.client.contacts.ContactsService;
+import com.google.gdata.data.contacts.ContactEntry;
+import com.google.gdata.data.contacts.ContactFeed;
+import com.google.gdata.data.extensions.PhoneNumber;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPException;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+/**
+ * This class retrieves the list of missed calls from a Speedport W 723V (A)
+ * router and sends notifications to a list of e-mail addresses.
+ *
+ * @author Tilman Liero tliero@gmx.net
+ */

+public class CallerIdClient {
+
+        private final static Logger log = Logger.getLogger(CallerIdClient.class);
+
+        private static final String TEXT_UNKNOWN = "unbekannt";
+        private static final String TEXT_MAILPREFIX = "Anruf von ";
+
+        String password;
+        int updateInterval;
+        JSAPResult config;
+        LinkedList<String[]> calls = new LinkedList<String[]>();
+        String cookie = null;
+
+        public CallerIdClient(JSAPResult config) {
+                this.config = config;
+                this.password = new String(Base64.encodeBase64(config.getString("router password").getBytes()));
+                this.updateInterval = config.getInt("update interval");
+
+                try {
+                        log.info("logging in to Speedport router");
+                        postUrl("https://speedport.ip/index/login.cgi", "Username=" + URLEncoder.encode("admin", "UTF-8") + "&" + "Password="
+                                        + password);
+
+                        log.info("retrieving call list");
+                        getUrl("https://speedport.ip/auth/hcti_status_telanrl.php?cookie=SessionID_R3," + cookie);
+
+                        log.info("logging out");
+                        postUrl("https://speedport.ip/auth/logout.cgi?RequestFile=/pub/top_beenden.php&cookie=SessionID_R3," + cookie, "");
+
+                        if (calls.size() > 0) {
+
+                                List<ContactEntry> contacts = null;
+                                if (config.getBoolean("check contacts")) {
+                                        log.info("retrieving Google contacts");
+                                        ContactsService service = new ContactsService("<var>SpeedportCallerIdClient</var>");
+                                        service.setUserCredentials(config.getString("e-mail adress"), config.getString("e-mail password"));
+                                        URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
+                                        Query myQuery = new Query(feedUrl);
+                                        myQuery.setMaxResults(1000);
+                                        ContactFeed resultFeed = service.query(myQuery, ContactFeed.class);
+                                        contacts = resultFeed.getEntries();
+                                }
+
+                                log.info("sending notifications");
+                                for (String[] call : calls) {
+                                        String time = call[0];
+                                        String caller = call[1];
+                                       
+                                        if (caller.equals(" ")) {
+                                                caller = TEXT_UNKNOWN;
+                                        }
+                                        else {
+                                                numberSearch:
+                                                for (ContactEntry contact : contacts) {
+                                                        for (PhoneNumber phone : contact.getPhoneNumbers()) {
+                                                                if (phone.getPhoneNumber().endsWith(caller.substring(1))) {
+                                                                        if (contact.getName().hasFullName()) {
+                                                                                caller = contact.getName().getFullName().getValue() + " (" + caller + ")";
+                                                                                log.info("found number in contact data for " + contact.getName().getFullName().getValue());
+                                                                        }
+                                                                        break numberSearch;
+                                                                }
+                                                        }
+                                                }
+                                        }
+
+                                        sendNotification(time, caller);
+                                }
+                        }
+                } catch (Exception e) {
+                        log.error(e.getMessage(), e);
+                }
+
+                log.info("done");
+        }
+
+        private void getUrl(String urlString) throws Exception {
+                log.debug("getUrl(" + urlString + ")");
+
+                URL url = new URL(urlString);
+                URLConnection connection = url.openConnection();
+
+                showHeaders(connection);
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+                String line;
+
+                while ((line = in.readLine()) != null) {
+                        if (line.startsWith("var in_call_list")) {
+                                // analyze caller list
+
+                                String s = line.substring(39);
+                                log.debug("  " + line);
+
+                                String[] result = s.split("new Array\\(");
+                                for (int x = 0; x < result.length; x++) {
+                                        // check for unanswered calls
+                                        if (result[x].substring(result[x].lastIndexOf('"') - 8, result[x].lastIndexOf('"')).equals("00:00:00")) {
+                                                log.debug("Unanswered call: " + result[x]);
+
+                                                // determine call time
+                                                int year = Integer.parseInt(result[x].substring(7, 11));
+                                                int month = Integer.parseInt(result[x].substring(4, 6));
+                                                int date = Integer.parseInt(result[x].substring(1, 3));
+                                                int hour = Integer.parseInt(result[x].substring(12, 14));
+                                                int min = Integer.parseInt(result[x].substring(15, 17));
+                                                int sec = Integer.parseInt(result[x].substring(18, 20));
+
+                                                Calendar callTime = Calendar.getInstance();
+                                                callTime.set(year, month - 1, date, hour, min, sec);
+
+                                                Calendar lastCheck = Calendar.getInstance();
+                                                lastCheck.setTimeInMillis(System.currentTimeMillis() - updateInterval * 1000 * 60);
+
+                                                if (callTime.after(lastCheck)) {
+                                                        String time = result[x].substring(1, 20);
+                                                        String number = result[x].substring(23, result[x].indexOf('"', 23));
+                                                        calls.add(new String[] { time, number });
+                                                }
+                                        }
+                                }
+
+                        }
+                        log.debug("  " + line);
+                }
+                in.close();
+
+        }
+
+        private void postUrl(String urlString, String payload) throws Exception {
+                log.debug("postUrl(" + urlString + ", " + payload + ")");
+
+                URL url = new URL(urlString);
+                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+                connection.setRequestMethod("POST");
+                connection.setInstanceFollowRedirects(false);
+                connection.setDoInput(true);
+                connection.setDoOutput(true);
+                connection.setUseCaches(false);
+                connection.setRequestProperty("Content-Length", String.valueOf(payload.length()));
+
+                if (cookie != null) {
+                        connection.setRequestProperty("Cookie", "SessionID_R3=" + cookie);
+                }
+
+                OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
+                if (payload.length() > 0) {
+                        writer.write(payload);
+                }
+                writer.flush();
+
+                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+
+                for (String line; (line = reader.readLine()) != null;) {
+                        if (line.startsWith("SessionID_R3")) {
+                                cookie = line.substring(13);
+                        } else {
+                                if (line.equals("4"))
+                                        log.error("  could not log in, Speedport adminstration account is currently in use");
+                                else
+                                        log.error("  received unexpected response: " + line);
+                        }
+                }
+
+                writer.close();
+                reader.close();
+
+                showHeaders(connection);
+        }
+
+        private void showHeaders(URLConnection connection) {
+                for (int i = 0;; i++) {
+                        String headerName = connection.getHeaderFieldKey(i);
+                        String headerValue = connection.getHeaderField(i);
+
+                        if (headerName == null && headerValue == null) {
+                                // No more headers
+                                break;
+                        }
+                        if (headerName == null) {
+                                // The header value contains the server's HTTP version
+                                log.debug("  Server HTTP version, Response code: " + headerValue);
+                        } else {
+                                log.debug("  Header: " + headerName + ", Value: " + headerValue);
+                        }
+                }
+        }
+
+        private void sendNotification(String time, String caller) throws Exception {
+                String host = "smtp.gmail.com";
+                String from = config.getString("e-mail adress");
+                String pass = config.getString("e-mail password");
+                Properties props = System.getProperties();
+                props.put("mail.smtp.starttls.enable", "true");
+                props.put("mail.smtp.host", host);
+                props.put("mail.smtp.user", from);
+                props.put("mail.smtp.password", pass);
+                props.put("mail.smtp.port", "587");
+                props.put("mail.smtp.auth", "true");
+
+                String[] to = config.getStringArray("recipient");
+
+                Session session = Session.getDefaultInstance(props, null);
+                MimeMessage message = new MimeMessage(session);
+                message.setFrom(new InternetAddress(from));
+
+                InternetAddress[] toAddress = new InternetAddress[to.length];
+
+                for (int i = 0; i < to.length; i++) {
+                        toAddress[i] = new InternetAddress(to[i]);
+                }
+
+                for (int i = 0; i < toAddress.length; i++) {
+                        message.addRecipient(Message.RecipientType.TO, toAddress[i]);
+                }
+
+                message.setSubject(TEXT_MAILPREFIX + caller);
+                message.setText(TEXT_MAILPREFIX + caller + "\n" + time);
+
+                log.info("sending message for call from " + caller + " at " + time);
+
+                Transport transport = session.getTransport("smtp");
+                transport.connect(host, from, pass);
+                transport.sendMessage(message, message.getAllRecipients());
+                transport.close();
+        }
+
+        @SuppressWarnings("rawtypes")
+        public static void main(String[] args) {
+                BasicConfigurator.configure(new ConsoleAppender(new PatternLayout("%d{ISO8601} - %m%n")));
+                log.info("Starting CallerIdClient version 1.1.2");
+
+                JSAP jsap = new JSAP();
+
+                try {
+                        UnflaggedOption routerPassword = new UnflaggedOption("router password").setStringParser(JSAP.STRING_PARSER)
+                                        .setRequired(true);
+                        routerPassword.setHelp("the login password for the Speedport W 723V (A) router");
+                        jsap.registerParameter(routerPassword);
+
+                        UnflaggedOption updateInterval = new UnflaggedOption("update interval").setStringParser(JSAP.INTEGER_PARSER)
+                                        .setRequired(true);
+                        updateInterval.setHelp("the interval beetween runs in minutes");
+                        jsap.registerParameter(updateInterval);
+
+                        UnflaggedOption fromAddress = new UnflaggedOption("e-mail adress").setStringParser(JSAP.STRING_PARSER).setRequired(
+                                        true);
+                        fromAddress.setHelp("Google mail address to send from");
+                        jsap.registerParameter(fromAddress);
+
+                        UnflaggedOption emailPassword = new UnflaggedOption("e-mail password").setStringParser(JSAP.STRING_PARSER)
+                                        .setRequired(true);
+                        emailPassword.setHelp("the login password for the Google account");
+                        jsap.registerParameter(emailPassword);
+
+                        UnflaggedOption recipients = new UnflaggedOption("recipient").setStringParser(JSAP.STRING_PARSER).setRequired(true)
+                                        .setGreedy(true);
+                        recipients.setHelp("e-mail addresses to send notifications to");
+                        jsap.registerParameter(recipients);
+
+                        Switch contactsSwitch = new Switch("check contacts").setLongFlag("contacts");
+                        contactsSwitch.setHelp("retrieve contacts from Google account and resolve caller names");
+                        jsap.registerParameter(contactsSwitch);
+
+                        Switch debugSwitch = new Switch("debug").setLongFlag("debug");
+                        debugSwitch.setHelp("print debug messages");
+                        jsap.registerParameter(debugSwitch);
+
+                        Switch helpSwitch = new Switch("help").setLongFlag("help").setShortFlag('?');
+                        helpSwitch.setHelp("print help and exit");
+                        jsap.registerParameter(helpSwitch);
+
+                } catch (JSAPException e) {
+                        log.fatal(e.getMessage(), e);
+                        System.exit(-1001);
+                }
+
+                JSAPResult config = jsap.parse(args);
+
+                if (!config.success() || config.getBoolean("help")) {
+                        for (java.util.Iterator errs = config.getErrorMessageIterator(); errs.hasNext();) {
+                                log.error("Error: " + errs.next());
+                        }
+
+                        log.error("Usage: java -jar speedportcallerid.jar " + jsap.getUsage() + "\n\n" + jsap.getHelp());
+                        System.exit(-1002);
+                }
+
+                if (config.getBoolean("debug")) {
+                        log.setLevel(Level.DEBUG);
+                } else {
+                        log.setLevel(Level.INFO);
+                }
+                log.info("Log level set to " + log.getLevel());
+
+                new CallerIdClient(config);
+        }
+}
+
+ + + + +
AttachmentSize
File speedportcallerid.jar3 MB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/40/index.html b/siarp.de/node/40/index.html new file mode 100644 index 0000000..2d63430 --- /dev/null +++ b/siarp.de/node/40/index.html @@ -0,0 +1,130 @@ + + + + + + + + + + + + SVN Migration | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

SVN Migration

+
+
+
+ + +
+
+ + + + + +
+

Migration von BerkeleyDB nach FSFS sollte ganz leicht sein.

+

Man kann einen Dump exportieren. Das ist eine menschenlesbare Datei, die man für heftige Änderungen auch bearbeiten kann. Tolle Sache das, damit gehen auch so Sachen, wie Zusammenlegung von zwei Repositories etc. Noch besser: LIES ES NACH. In der wie immer hervorragenden Doku.

+
+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

Ich liebe Subversion! Wirklich!

+
+ +
+ +
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/42/index.html b/siarp.de/node/42/index.html new file mode 100644 index 0000000..f774bc4 --- /dev/null +++ b/siarp.de/node/42/index.html @@ -0,0 +1,208 @@ + + + + + + + + + + + + Mein erstes echtes bash-Skript! | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Mein erstes echtes bash-Skript!

+
+
+
+ + +
+
+ + + + + +
+

...erstellt ein Repository und liegt unter /root/tilman/create_repository.sh. Nächstes Ziel: Subversion hook script für automatisiertes Update, damit die Webentwicklung so richtig losgehen kann.
+
+

#!/bin/sh
+
+# Erstellt ein Repository unterhalb von /home/svn-repos,
+# traegt es in die httpd.conf ein und startet Apache neu
+#
+# Optionen: -n um den Eintrag in die httpd.conf und den Apache-Neustart
+#   abzuschalten
+# Parameter: Pfad des neuen Repository (unterhalb von /home/svn-repos/)
+
+if [ $# -eq 2 ]
+then
+  if [ $1 == "-n" ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${2%\/}
+    repos=${repos#\/}
+    updateconf=false
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 1
+  fi
+else
+  if [ $# -eq 1 ]
+  then
+    # Slashes am Anfang und Ende der Pfadangabe entfernen
+    repos=${1%\/}
+    repos=${repos#\/}
+    updateconf=true
+  else
+    echo "usage: create_repository [-n] repository_path"
+    exit 2
+  fi
+fi
+
+mkdir /home/svn-repos/$repos
+svnadmin create /home/svn-repos/$repos
+chown -R svn.svn /home/svn-repos/$repos
+chmod -R ug+w /home/svn-repos/$repos
+chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/*
+
+# in httpd.conf eintragen und Apache neu starten
+if [ $updateconf = true ]
+then
+  echo "
+<Location /svn/$repos>
+  DAV svn
+  SVNPath /home/svn-repos/$repos
+  SVNIndexXSLT \"/subversion-xslt/svnindex.xsl\"
+  AuthType Basic
+  AuthName \"siarp.de repository\"
+  AuthUserFile /home/svn-repos/svn-auth-file
+  Require user martin tilman
+  SSLRequireSSL
+</Location>
+" >> /usr/local/apache2/conf/httpd.conf
+
+  /usr/local/apache2/bin/apachectl restart
+fi

+

+ +
+ + +
+

Comments

+ + +
+ +
+ + + + + +

+ +
+

/usr/local/apache2/bin/apachectl restart

+ +

Was macht denn chmod ug+s /home/svn-repos/$repos /home/svn-repos/$repos/* und warum geht das nicht rekursiv?

+
+ +
+ +
+
+ +
+ + + + + +

+ +
+

Also eigentlich habe ich diese drei Zeilen mit den Rechten aus einer c't und benutze sie immer, ohne sie zu hinterfragen...

+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/47/index.html b/siarp.de/node/47/index.html new file mode 100644 index 0000000..aad808e --- /dev/null +++ b/siarp.de/node/47/index.html @@ -0,0 +1,123 @@ + + + + + + + + + + + + Sandkastenspiele I - Automatisches "svn update" | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Sandkastenspiele I - Automatisches "svn update"

+
+
+
+ + +
+
+ + + + + +
+

Ich habe ein Repository tests, in dem sich ein Verzeichnis automaticupdate/website befindet, das bei jedem Commit automatisch ins htdocs-Verzeichnis ausgecheckt werden soll.

+ +

Dazu erstelle ich ein Verzeichnis htdocs/tests und übertrage es an Benutzer svn.
+Danach wird manuell der 'initial checkout' durchgeführt:
+

su svn
+cd /usr/local/apache2/htdocs/tests
+svn checkout file:///home/svn-repos/tilman/tests/automaticupdate/website
+exit

+ +

Für die automatischen Updates wird jetzt noch ein hook-Skript geschrieben. Es heißt post-commit, gehört selbstverständlich dem Benutzer svn, ist ausführbar und liegt im Unterverzeichnis /hooks des Repository. (Da sind auch schon templates für die verschiedenen möglichen hooks.)
+

#!/bin/sh
+svn update /usr/local/apache2/htdocs/tests/website

+ +

Jetzt wird der aktuelle Stand immer unter http://www.siarp.de/tests/website/ angezeigt.

+ +

Nächster Schritt: Kleinere Veränderungen auf den Server zum Testen übertragen, ohne gleich einen Commit machen zu müssen. (Wie?)

+ +

Es wäre außerdem noch schön, Apache grundsätzlich die Auslieferung von allem, was ein ".svn" im Pfad hat zu verbieten. Derzeit sind die Metadaten noch einsehbar.

+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/60/index.html b/siarp.de/node/60/index.html new file mode 100644 index 0000000..9d82563 --- /dev/null +++ b/siarp.de/node/60/index.html @@ -0,0 +1,154 @@ + + + + + + + + + + + + Subdomains | siarp.de + + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Subdomains

+
+
+
+ + +
+
+ + + + + +
+

Problem: Normale Zertifikate gelten nur für eine (Sub-)Domain
+Erkenntnis: Es gibt auch Wildcard-Zertifikate, die alle Subdomains abdecken
+Folgefrage: Bekommt man diese Wildcardzertifikate von einer halbwegs anerkannten CA ohne kosten?

+ +

Allgemein zum Thema pro/contra Subdomains:
++ sie sehen hübsch aus
+- wirklich sinnvoll eingesetzt sind sie nur, wenn sie auf verschiedene Recher bzw. IPs zeigen, was sie bei uns nicht tun
+- uns fällt kein Service ein, für den eine Subdomain wirklich nötig wäre.

+ +

Die Entscheidung: Es sollen alle Dienste ohne Subdomain unter protokoll://siarp.de erreichbar sein.
+
+Subdomains werde höchstens als Kurz-URL mit Weiterleitung genutzt. Dazu müssen sie über das KIS von Hosteurope angelegt werden und zwar unter
+

Administration > Domainservices > Administration > AutoDNS Domains bearbeiten

+ +

Im Apache gibt es den einen wichtigen Virtual Host für siarp.de. Alle weiteren Hosts enthalten Redirects auf siarp.de/PFAD:

+ +

NameVirtualHost *:80
+
+<VirtualHost *:80>
+  ServerName siarp.de
+  DocumentRoot /usr/local/apache2/htdocs
+</VirtualHost>
+
+<VirtualHost *:80>
+  ServerName <a href="http://www.siarp.de" rel="nofollow">www.siarp.de</a>
+  Redirect / <a href="http://siarp.de/
+</VirtualHost>
+
+<VirtualHost" rel="nofollow">http://siarp.de/
+</VirtualHost>
+
+<VirtualHost</a> *:80>
+  ServerName SUBDOMAIN.siarp.de
+  Redirect / <a href="http://siarp.de/PFAD/
+</VirtualHost>
+
+...
+" rel="nofollow">http://siarp.de/PFAD/
+</VirtualHost>
+
+...
+</a>

+ + + + +
AttachmentSize
Image icon subdomains.gif9.44 KB
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/node/8/index.html b/siarp.de/node/8/index.html new file mode 100644 index 0000000..a1c26a9 --- /dev/null +++ b/siarp.de/node/8/index.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + Erste Apache-Konfiguration | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+

You are here

+

Erste Apache-Konfiguration

+
+
+
+ + +
+
+ + + + + +
+

"SIARP.de" - ich sehe meinen Namen in Leuchtbuchstaben...

+ +

Wir fassten den Entschluss, die aufgefächerte Konfiguration zu einer handlichen kleinen httpd.conf zusammenzuführen. Ein Backup der (fast) originalen Konfigurationdateien befindet sich in /home/root/bak/apache2.tar.gz. Dann haben wir festgestellt, dass es zwingend das Verzeichnis samt Dateien sysconfig.d erfordert. Also die betreffenden Teile wieder ausgelagert und TADA! - "SIARP.de".

+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/siarp.de/rss/index.xml b/siarp.de/rss/index.xml new file mode 100644 index 0000000..21c1fd2 --- /dev/null +++ b/siarp.de/rss/index.xml @@ -0,0 +1,732 @@ + + + + siarp.de + http://siarp.de + Schnell dokumentieren, bevor ich es für selbstverständlich halte! + en + + Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts + http://siarp.de/node/232 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Seit kurzem haben wir VDSL von der Telekom (yeah!) und deshalb einen neuen Router. Das Gerät ist ein <a href="http://de.wikipedia.org/wiki/Speedport">Speedport</a> W 723V A mit relativ vielen Funktionen. Unter anderem können DECT-Telefone direkt angebunden werden und brauchen dann keinen eigene Basisstation. Diese Funktion wollte ich gerne nutzen, weil beim Anschluss des Telefons über die analoge TAE-Buchse nur eine Leitung genutzt werden kann und außerdem die Sprachqualität über die analoge Schnittstelle eher mäßig war. Das Problem: Entgangene Anrufe werden nicht mehr an die Telefone übermittelt, sondern müssen über das Web-Interface nachgeschaut werden - inakzeptabel. Zumindest beim Typ A vom 723 V ist wohl schon der neue Standard CATiq-2.0 implementiert, mit dem die Anruferliste an die Telefone übertragen werden kann. Nur kennen unsere Gigaset C300 Telefone den Standard leider noch nicht. Statt neue Telefone zu kaufen machen wir das Ganze einfach selbst und viel besser: Das folgende Java-Programm ruft die Liste vom Router ab und sendet bei neuen Anrufen eine E-Mail an beliebig viele Empfänger. So bekommen wir sogar unterwegs mit, wenn wir zu Hause einen Anruf verpasst haben.</p> + +<p>Download: <a href="http://siarp.de/sites/siarp.de/files/speedportcallerid.jar">speedportcallerid.jar</a></p> + +<p><em>Wie immer alles auf eigene Gefahr! Das Programm speichert allerdings nichts und ändert auch keine Einstellungen im Router, so dass sich das Risiko in Grenzen hält :) Ob das Ganze auch mit dem Speedport W 723V B funktioniert, weiß ich nicht.</em></p> + +<p>Der Aufruf funktioniert so:</p> + +<div class="geshifilter"><div class="text geshifilter-text">Usage: java -jar speedportcallerid.jar &lt;router password&gt; &lt;update interval&gt; &lt;e-mail adress&gt; &lt;e-mail password&gt; recipient1 recipient2 ... recipientN [--contacts] [--debug] [-?|--help]<br /> +<br /> +&nbsp; &lt;router password&gt;<br /> +&nbsp; &nbsp; &nbsp; &nbsp; the login password for the Speedport W 723V (A) router<br /> +<br /> +&nbsp; &lt;update interval&gt;<br /> +&nbsp; &nbsp; &nbsp; &nbsp; the interval beetween runs in minutes<br /> +<br /> +&nbsp; &lt;e-mail adress&gt;<br /> +&nbsp; &nbsp; &nbsp; &nbsp; Google mail address to send from<br /> +<br /> +&nbsp; &lt;e-mail password&gt;<br /> +&nbsp; &nbsp; &nbsp; &nbsp; the login password for the Google account<br /> +<br /> +&nbsp; recipient1 recipient2 ... recipientN<br /> +&nbsp; &nbsp; &nbsp; &nbsp; e-mail addresses to send notifications to<br /> +<br /> +&nbsp; [--contacts]<br /> +&nbsp; &nbsp; &nbsp; &nbsp; retrieve contacts from Google account and resolve caller names<br /> +<br /> +&nbsp; [--debug]<br /> +&nbsp; &nbsp; &nbsp; &nbsp; print debug messages<br /> +<br /> +&nbsp; [-?|--help]<br /> +&nbsp; &nbsp; &nbsp; &nbsp; print help and exit</div></div> + +<p>Konkret lasse ich einen cronjob laufen, der alle 15 Minuten dieses Skript aufruft:</p> + +<div class="geshifilter"><div class="bash geshifilter-bash"><span class="co0">#!/bin/sh</span><br /> +<span class="kw3">cd</span> <span class="sy0">/</span>media<span class="sy0">/</span>usb<span class="sy0">/</span>hidrive<span class="sy0">/</span>speedport<br /> +<span class="kw2">sudo</span> <span class="re5">-u</span> nobody java -Duser.timezone=Europe<span class="sy0">/</span>Berlin <span class="re5">-jar</span> speedportcallerid.jar <span class="re5">--contacts</span> <span class="sy0">&lt;</span>ROUTER-PASSWORT<span class="sy0">&gt;</span> <span class="nu0">15</span> <span class="sy0">&lt;</span>GMAIL-ADRESSE<span class="sy0">&gt;</span> <span class="sy0">&lt;</span>GMAIL-PASSWORT<span class="sy0">&gt;</span> <span class="sy0">&lt;</span>EMPFÄNGER1<span class="sy0">&gt;</span> <span class="sy0">&lt;</span>EMPFÄNGER2<span class="sy0">&gt;</span></div></div> + +<p>Der cronjob dazu sieht so aus:</p> + +<div class="geshifilter"><div class="text geshifilter-text">*/15 * * * * /usr/local/bin/check-speedport.sh</div></div> + +<p>Im Moment sind die Mail-Einstellungen auf den Gmail-Server festgelegt (StartTLS + Port 587) für andere Server muss der Code evtl. angepasst werden - vielleicht baue ich später dafür auch nochmal zusätzliche Parameter ein, wenn jemand Interesse hat.</p> + +<h2>Nachtrag: Namensauflösung mit Gmail-Kontakten</h2> + +<p>Das Programm tat was es soll, aber die Akzeptanz im Haushalt ließ zu wünschen übrig: "Woher soll ich denn wissen, wer das war, wenn da nur die Nummer steht!?" Na gut, ist wohl nicht so praktisch.<br /> +Man kann zwar im Router eine Telefonliste pflegen, aber leider wird die nicht für die Anzeige der Rufnummern auf der Weboberfläche verwendet. Außerdem müsste man dann sämtliche Kontakte nochmal im Speedport pflegen, was sicherlich auch nicht Sinn der Sache ist. Zum Glück hab ich ja ein Android-Handy und deshalb sämtliche Telefonnummern im Google-Account gespeichert. Man muss also nur nochmal nach den passenden Namen suchen, nachdem man die Rufnummern aus dem Speedport gefischt hat. Erledigt. Das Aufruf-Skript muss nur um den Parameter <span class="geshifilter"><code class="bash geshifilter-bash"><span class="re5">--contacts</span></code></span> ergänzt werden (s.o.)</p> + +<h2>Code</h2> + +<div class="geshifilter"><div class="java geshifilter-java"><span class="kw1">package</span> <span class="co2">de.tilman.callerid</span><span class="sy0">;</span><br /> +<br /> +<span class="kw1">import</span> <span class="co2">java.io.BufferedReader</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.io.InputStreamReader</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.io.OutputStreamWriter</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.net.HttpURLConnection</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.net.URL</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.net.URLConnection</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.net.URLEncoder</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.util.Calendar</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.util.LinkedList</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.util.List</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">java.util.Properties</span><span class="sy0">;</span><br /> +<br /> +<span class="kw1">import</span> <span class="co2">javax.mail.Message</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">javax.mail.Session</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">javax.mail.Transport</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">javax.mail.internet.InternetAddress</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">javax.mail.internet.MimeMessage</span><span class="sy0">;</span><br /> +<br /> +<span class="kw1">import</span> <span class="co2">org.apache.commons.codec.binary.Base64</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">org.apache.log4j.BasicConfigurator</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">org.apache.log4j.ConsoleAppender</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">org.apache.log4j.Level</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">org.apache.log4j.Logger</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">org.apache.log4j.PatternLayout</span><span class="sy0">;</span><br /> +<br /> +<span class="kw1">import</span> <span class="co2">com.google.gdata.client.Query</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.google.gdata.client.contacts.ContactsService</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.google.gdata.data.contacts.ContactEntry</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.google.gdata.data.contacts.ContactFeed</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.google.gdata.data.extensions.PhoneNumber</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.martiansoftware.jsap.JSAP</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.martiansoftware.jsap.JSAPException</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.martiansoftware.jsap.JSAPResult</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.martiansoftware.jsap.Switch</span><span class="sy0">;</span><br /> +<span class="kw1">import</span> <span class="co2">com.martiansoftware.jsap.UnflaggedOption</span><span class="sy0">;</span><br /> +<br /> +<span class="co3">/**<br /> +&nbsp;* This class retrieves the list of missed calls from a Speedport W 723V (A)<br /> +&nbsp;* router and sends notifications to a list of e-mail addresses.<br /> +&nbsp;* <br /> +&nbsp;* @author Tilman Liero tliero@gmx.net<br /> +&nbsp;*/</span><br /> +<span class="kw1">public</span> <span class="kw1">class</span> CallerIdClient <span class="br0">&#123;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">final</span> <span class="kw1">static</span> Logger log <span class="sy0">=</span> Logger.<span class="me1">getLogger</span><span class="br0">&#40;</span>CallerIdClient.<span class="kw1">class</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> TEXT_UNKNOWN <span class="sy0">=</span> <span class="st0">&quot;unbekannt&quot;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">static</span> <span class="kw1">final</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> TEXT_MAILPREFIX <span class="sy0">=</span> <span class="st0">&quot;Anruf von &quot;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> password<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> updateInterval<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; JSAPResult config<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; LinkedList<span class="sy0">&lt;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">&gt;</span> calls <span class="sy0">=</span> <span class="kw1">new</span> LinkedList<span class="sy0">&lt;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> cookie <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> CallerIdClient<span class="br0">&#40;</span>JSAPResult config<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">config</span> <span class="sy0">=</span> config<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">password</span> <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#40;</span>Base64.<span class="me1">encodeBase64</span><span class="br0">&#40;</span>config.<span class="me1">getString</span><span class="br0">&#40;</span><span class="st0">&quot;router password&quot;</span><span class="br0">&#41;</span>.<span class="me1">getBytes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">updateInterval</span> <span class="sy0">=</span> config.<span class="me1">getInt</span><span class="br0">&#40;</span><span class="st0">&quot;update interval&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;logging in to Speedport router&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postUrl<span class="br0">&#40;</span><span class="st0">&quot;https://speedport.ip/index/login.cgi&quot;</span>, <span class="st0">&quot;Username=&quot;</span> <span class="sy0">+</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+urlencoder"><span class="kw3">URLEncoder</span></a>.<span class="me1">encode</span><span class="br0">&#40;</span><span class="st0">&quot;admin&quot;</span>, <span class="st0">&quot;UTF-8&quot;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;&amp;&quot;</span> <span class="sy0">+</span> <span class="st0">&quot;Password=&quot;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> password<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;retrieving call list&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getUrl<span class="br0">&#40;</span><span class="st0">&quot;https://speedport.ip/auth/hcti_status_telanrl.php?cookie=SessionID_R3,&quot;</span> <span class="sy0">+</span> cookie<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;logging out&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; postUrl<span class="br0">&#40;</span><span class="st0">&quot;https://speedport.ip/auth/logout.cgi?RequestFile=/pub/top_beenden.php&amp;cookie=SessionID_R3,&quot;</span> <span class="sy0">+</span> cookie, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>calls.<span class="me1">size</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<span class="sy0">&lt;</span>ContactEntry<span class="sy0">&gt;</span> contacts <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>config.<span class="me1">getBoolean</span><span class="br0">&#40;</span><span class="st0">&quot;check contacts&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;retrieving Google contacts&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ContactsService service <span class="sy0">=</span> <span class="kw1">new</span> ContactsService<span class="br0">&#40;</span><span class="st0">&quot;&lt;var&gt;SpeedportCallerIdClient&lt;/var&gt;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; service.<span class="me1">setUserCredentials</span><span class="br0">&#40;</span>config.<span class="me1">getString</span><span class="br0">&#40;</span><span class="st0">&quot;e-mail adress&quot;</span><span class="br0">&#41;</span>, config.<span class="me1">getString</span><span class="br0">&#40;</span><span class="st0">&quot;e-mail password&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a> feedUrl <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a><span class="br0">&#40;</span><span class="st0">&quot;https://www.google.com/m8/feeds/contacts/default/full&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Query myQuery <span class="sy0">=</span> <span class="kw1">new</span> Query<span class="br0">&#40;</span>feedUrl<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myQuery.<span class="me1">setMaxResults</span><span class="br0">&#40;</span><span class="nu0">1000</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ContactFeed resultFeed <span class="sy0">=</span> service.<span class="me1">query</span><span class="br0">&#40;</span>myQuery, ContactFeed.<span class="kw1">class</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; contacts <span class="sy0">=</span> resultFeed.<span class="me1">getEntries</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;sending notifications&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> call <span class="sy0">:</span> calls<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> time <span class="sy0">=</span> call<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> caller <span class="sy0">=</span> call<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>caller.<span class="me1">equals</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caller <span class="sy0">=</span> TEXT_UNKNOWN<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; numberSearch<span class="sy0">:</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>ContactEntry contact <span class="sy0">:</span> contacts<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>PhoneNumber phone <span class="sy0">:</span> contact.<span class="me1">getPhoneNumbers</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>phone.<span class="me1">getPhoneNumber</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">endsWith</span><span class="br0">&#40;</span>caller.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>contact.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">hasFullName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caller <span class="sy0">=</span> contact.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getFullName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getValue</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot; (&quot;</span> <span class="sy0">+</span> caller <span class="sy0">+</span> <span class="st0">&quot;)&quot;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;found number in contact data for &quot;</span> <span class="sy0">+</span> contact.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getFullName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getValue</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span> numberSearch<span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendNotification<span class="br0">&#40;</span>time, caller<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">catch</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception"><span class="kw3">Exception</span></a> e<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span>e.<span class="me1">getMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, e<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;done&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> getUrl<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> urlString<span class="br0">&#41;</span> <span class="kw1">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception"><span class="kw3">Exception</span></a> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot;getUrl(&quot;</span> <span class="sy0">+</span> urlString <span class="sy0">+</span> <span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a> url <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a><span class="br0">&#40;</span>urlString<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+urlconnection"><span class="kw3">URLConnection</span></a> connection <span class="sy0">=</span> url.<span class="me1">openConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showHeaders<span class="br0">&#40;</span>connection<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader"><span class="kw3">BufferedReader</span></a> in <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader"><span class="kw3">BufferedReader</span></a><span class="br0">&#40;</span><span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+inputstreamreader"><span class="kw3">InputStreamReader</span></a><span class="br0">&#40;</span>connection.<span class="me1">getInputStream</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> line<span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>line <span class="sy0">=</span> in.<span class="me1">readLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>line.<span class="me1">startsWith</span><span class="br0">&#40;</span><span class="st0">&quot;var in_call_list&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// analyze caller list</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> s <span class="sy0">=</span> line.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">39</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;&quot;</span> <span class="sy0">+</span> line<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> result <span class="sy0">=</span> s.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot;new Array<span class="es0">\\</span>(&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> x <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> x <span class="sy0">&lt;</span> result.<span class="me1">length</span><span class="sy0">;</span> x<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// check for unanswered calls</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">lastIndexOf</span><span class="br0">&#40;</span><span class="st0">'&quot;'</span><span class="br0">&#41;</span> <span class="sy0">-</span> <span class="nu0">8</span>, result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">lastIndexOf</span><span class="br0">&#40;</span><span class="st0">'&quot;'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">equals</span><span class="br0">&#40;</span><span class="st0">&quot;00:00:00&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot;Unanswered call: &quot;</span> <span class="sy0">+</span> result<span class="br0">&#91;</span>x<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// determine call time</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> year <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">7</span>, <span class="nu0">11</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> month <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">4</span>, <span class="nu0">6</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> date <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">3</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> hour <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">12</span>, <span class="nu0">14</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> min <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">15</span>, <span class="nu0">17</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> sec <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">18</span>, <span class="nu0">20</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+calendar"><span class="kw3">Calendar</span></a> callTime <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+calendar"><span class="kw3">Calendar</span></a>.<span class="me1">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callTime.<span class="me1">set</span><span class="br0">&#40;</span>year, month <span class="sy0">-</span> <span class="nu0">1</span>, date, hour, min, sec<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+calendar"><span class="kw3">Calendar</span></a> lastCheck <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+calendar"><span class="kw3">Calendar</span></a>.<span class="me1">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastCheck.<span class="me1">setTimeInMillis</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system"><span class="kw3">System</span></a>.<span class="me1">currentTimeMillis</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">-</span> updateInterval <span class="sy0">*</span> <span class="nu0">1000</span> <span class="sy0">*</span> <span class="nu0">60</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>callTime.<span class="me1">after</span><span class="br0">&#40;</span>lastCheck<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> time <span class="sy0">=</span> result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">20</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> number <span class="sy0">=</span> result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">23</span>, result<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">indexOf</span><span class="br0">&#40;</span><span class="st0">'&quot;'</span>, <span class="nu0">23</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; calls.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#123;</span> time, number <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;&quot;</span> <span class="sy0">+</span> line<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> postUrl<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> urlString, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> payload<span class="br0">&#41;</span> <span class="kw1">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception"><span class="kw3">Exception</span></a> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot;postUrl(&quot;</span> <span class="sy0">+</span> urlString <span class="sy0">+</span> <span class="st0">&quot;, &quot;</span> <span class="sy0">+</span> payload <span class="sy0">+</span> <span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a> url <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"><span class="kw3">URL</span></a><span class="br0">&#40;</span>urlString<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+httpurlconnection"><span class="kw3">HttpURLConnection</span></a> connection <span class="sy0">=</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+httpurlconnection"><span class="kw3">HttpURLConnection</span></a><span class="br0">&#41;</span> url.<span class="me1">openConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setRequestMethod</span><span class="br0">&#40;</span><span class="st0">&quot;POST&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setInstanceFollowRedirects</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setDoInput</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setDoOutput</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setUseCaches</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setRequestProperty</span><span class="br0">&#40;</span><span class="st0">&quot;Content-Length&quot;</span>, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a>.<span class="me1">valueOf</span><span class="br0">&#40;</span>payload.<span class="me1">length</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>cookie <span class="sy0">!=</span> <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.<span class="me1">setRequestProperty</span><span class="br0">&#40;</span><span class="st0">&quot;Cookie&quot;</span>, <span class="st0">&quot;SessionID_R3=&quot;</span> <span class="sy0">+</span> cookie<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+outputstreamwriter"><span class="kw3">OutputStreamWriter</span></a> writer <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+outputstreamwriter"><span class="kw3">OutputStreamWriter</span></a><span class="br0">&#40;</span>connection.<span class="me1">getOutputStream</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>payload.<span class="me1">length</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span class="me1">write</span><span class="br0">&#40;</span>payload<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span class="me1">flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader"><span class="kw3">BufferedReader</span></a> reader <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader"><span class="kw3">BufferedReader</span></a><span class="br0">&#40;</span><span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+inputstreamreader"><span class="kw3">InputStreamReader</span></a><span class="br0">&#40;</span>connection.<span class="me1">getInputStream</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> line<span class="sy0">;</span> <span class="br0">&#40;</span>line <span class="sy0">=</span> reader.<span class="me1">readLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="kw2">null</span><span class="sy0">;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>line.<span class="me1">startsWith</span><span class="br0">&#40;</span><span class="st0">&quot;SessionID_R3&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cookie <span class="sy0">=</span> line.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">13</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>line.<span class="me1">equals</span><span class="br0">&#40;</span><span class="st0">&quot;4&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;could not log in, Speedport adminstration account is currently in use&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;received unexpected response: &quot;</span> <span class="sy0">+</span> line<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reader.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showHeaders<span class="br0">&#40;</span>connection<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> showHeaders<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+urlconnection"><span class="kw3">URLConnection</span></a> connection<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> headerName <span class="sy0">=</span> connection.<span class="me1">getHeaderFieldKey</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> headerValue <span class="sy0">=</span> connection.<span class="me1">getHeaderField</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>headerName <span class="sy0">==</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> headerValue <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// No more headers</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>headerName <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// The header value contains the server's HTTP version</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;Server HTTP version, Response code: &quot;</span> <span class="sy0">+</span> headerValue<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot; &nbsp;Header: &quot;</span> <span class="sy0">+</span> headerName <span class="sy0">+</span> <span class="st0">&quot;, Value: &quot;</span> <span class="sy0">+</span> headerValue<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> sendNotification<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> time, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> caller<span class="br0">&#41;</span> <span class="kw1">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception"><span class="kw3">Exception</span></a> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> host <span class="sy0">=</span> <span class="st0">&quot;smtp.gmail.com&quot;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> from <span class="sy0">=</span> config.<span class="me1">getString</span><span class="br0">&#40;</span><span class="st0">&quot;e-mail adress&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a> pass <span class="sy0">=</span> config.<span class="me1">getString</span><span class="br0">&#40;</span><span class="st0">&quot;e-mail password&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+properties"><span class="kw3">Properties</span></a> props <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system"><span class="kw3">System</span></a>.<span class="me1">getProperties</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.starttls.enable&quot;</span>, <span class="st0">&quot;true&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.host&quot;</span>, host<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.user&quot;</span>, from<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.password&quot;</span>, pass<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.port&quot;</span>, <span class="st0">&quot;587&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.<span class="me1">put</span><span class="br0">&#40;</span><span class="st0">&quot;mail.smtp.auth&quot;</span>, <span class="st0">&quot;true&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> to <span class="sy0">=</span> config.<span class="me1">getStringArray</span><span class="br0">&#40;</span><span class="st0">&quot;recipient&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Session session <span class="sy0">=</span> Session.<span class="me1">getDefaultInstance</span><span class="br0">&#40;</span>props, <span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MimeMessage message <span class="sy0">=</span> <span class="kw1">new</span> MimeMessage<span class="br0">&#40;</span>session<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message.<span class="me1">setFrom</span><span class="br0">&#40;</span><span class="kw1">new</span> InternetAddress<span class="br0">&#40;</span>from<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InternetAddress<span class="br0">&#91;</span><span class="br0">&#93;</span> toAddress <span class="sy0">=</span> <span class="kw1">new</span> InternetAddress<span class="br0">&#91;</span>to.<span class="me1">length</span><span class="br0">&#93;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> to.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; toAddress<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw1">new</span> InternetAddress<span class="br0">&#40;</span>to<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> toAddress.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message.<span class="me1">addRecipient</span><span class="br0">&#40;</span>Message.<span class="me1">RecipientType</span>.<span class="me1">TO</span>, toAddress<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message.<span class="me1">setSubject</span><span class="br0">&#40;</span>TEXT_MAILPREFIX <span class="sy0">+</span> caller<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message.<span class="me1">setText</span><span class="br0">&#40;</span>TEXT_MAILPREFIX <span class="sy0">+</span> caller <span class="sy0">+</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span> <span class="sy0">+</span> time<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;sending message for call from &quot;</span> <span class="sy0">+</span> caller <span class="sy0">+</span> <span class="st0">&quot; at &quot;</span> <span class="sy0">+</span> time<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Transport transport <span class="sy0">=</span> session.<span class="me1">getTransport</span><span class="br0">&#40;</span><span class="st0">&quot;smtp&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transport.<span class="me1">connect</span><span class="br0">&#40;</span>host, from, pass<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transport.<span class="me1">sendMessage</span><span class="br0">&#40;</span>message, message.<span class="me1">getAllRecipients</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transport.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; @SuppressWarnings<span class="br0">&#40;</span><span class="st0">&quot;rawtypes&quot;</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> <span class="kw4">void</span> main<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> args<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BasicConfigurator.<span class="me1">configure</span><span class="br0">&#40;</span><span class="kw1">new</span> ConsoleAppender<span class="br0">&#40;</span><span class="kw1">new</span> PatternLayout<span class="br0">&#40;</span><span class="st0">&quot;%d{ISO8601} - %m%n&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;Starting CallerIdClient version 1.1.2&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JSAP jsap <span class="sy0">=</span> <span class="kw1">new</span> JSAP<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnflaggedOption routerPassword <span class="sy0">=</span> <span class="kw1">new</span> UnflaggedOption<span class="br0">&#40;</span><span class="st0">&quot;router password&quot;</span><span class="br0">&#41;</span>.<span class="me1">setStringParser</span><span class="br0">&#40;</span>JSAP.<span class="me1">STRING_PARSER</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">setRequired</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; routerPassword.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;the login password for the Speedport W 723V (A) router&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>routerPassword<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnflaggedOption updateInterval <span class="sy0">=</span> <span class="kw1">new</span> UnflaggedOption<span class="br0">&#40;</span><span class="st0">&quot;update interval&quot;</span><span class="br0">&#41;</span>.<span class="me1">setStringParser</span><span class="br0">&#40;</span>JSAP.<span class="me1">INTEGER_PARSER</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">setRequired</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; updateInterval.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;the interval beetween runs in minutes&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>updateInterval<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnflaggedOption fromAddress <span class="sy0">=</span> <span class="kw1">new</span> UnflaggedOption<span class="br0">&#40;</span><span class="st0">&quot;e-mail adress&quot;</span><span class="br0">&#41;</span>.<span class="me1">setStringParser</span><span class="br0">&#40;</span>JSAP.<span class="me1">STRING_PARSER</span><span class="br0">&#41;</span>.<span class="me1">setRequired</span><span class="br0">&#40;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fromAddress.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;Google mail address to send from&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>fromAddress<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnflaggedOption emailPassword <span class="sy0">=</span> <span class="kw1">new</span> UnflaggedOption<span class="br0">&#40;</span><span class="st0">&quot;e-mail password&quot;</span><span class="br0">&#41;</span>.<span class="me1">setStringParser</span><span class="br0">&#40;</span>JSAP.<span class="me1">STRING_PARSER</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">setRequired</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emailPassword.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;the login password for the Google account&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>emailPassword<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnflaggedOption recipients <span class="sy0">=</span> <span class="kw1">new</span> UnflaggedOption<span class="br0">&#40;</span><span class="st0">&quot;recipient&quot;</span><span class="br0">&#41;</span>.<span class="me1">setStringParser</span><span class="br0">&#40;</span>JSAP.<span class="me1">STRING_PARSER</span><span class="br0">&#41;</span>.<span class="me1">setRequired</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">setGreedy</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; recipients.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;e-mail addresses to send notifications to&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>recipients<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Switch</span> contactsSwitch <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw1">Switch</span><span class="br0">&#40;</span><span class="st0">&quot;check contacts&quot;</span><span class="br0">&#41;</span>.<span class="me1">setLongFlag</span><span class="br0">&#40;</span><span class="st0">&quot;contacts&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; contactsSwitch.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;retrieve contacts from Google account and resolve caller names&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>contactsSwitch<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Switch</span> debugSwitch <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw1">Switch</span><span class="br0">&#40;</span><span class="st0">&quot;debug&quot;</span><span class="br0">&#41;</span>.<span class="me1">setLongFlag</span><span class="br0">&#40;</span><span class="st0">&quot;debug&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debugSwitch.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;print debug messages&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>debugSwitch<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Switch</span> helpSwitch <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw1">Switch</span><span class="br0">&#40;</span><span class="st0">&quot;help&quot;</span><span class="br0">&#41;</span>.<span class="me1">setLongFlag</span><span class="br0">&#40;</span><span class="st0">&quot;help&quot;</span><span class="br0">&#41;</span>.<span class="me1">setShortFlag</span><span class="br0">&#40;</span><span class="st0">'?'</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; helpSwitch.<span class="me1">setHelp</span><span class="br0">&#40;</span><span class="st0">&quot;print help and exit&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsap.<span class="me1">registerParameter</span><span class="br0">&#40;</span>helpSwitch<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">catch</span> <span class="br0">&#40;</span>JSAPException e<span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">fatal</span><span class="br0">&#40;</span>e.<span class="me1">getMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, e<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system"><span class="kw3">System</span></a>.<span class="me1">exit</span><span class="br0">&#40;</span><span class="sy0">-</span><span class="nu0">1001</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JSAPResult config <span class="sy0">=</span> jsap.<span class="me1">parse</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>config.<span class="me1">success</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">||</span> config.<span class="me1">getBoolean</span><span class="br0">&#40;</span><span class="st0">&quot;help&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>java.<span class="me1">util</span>.<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+iterator"><span class="kw3">Iterator</span></a> errs <span class="sy0">=</span> config.<span class="me1">getErrorMessageIterator</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> errs.<span class="me1">hasNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Error: &quot;</span> <span class="sy0">+</span> errs.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Usage: java -jar speedportcallerid.jar &quot;</span> <span class="sy0">+</span> jsap.<span class="me1">getUsage</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;<span class="es0">\n</span><span class="es0">\n</span>&quot;</span> <span class="sy0">+</span> jsap.<span class="me1">getHelp</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system"><span class="kw3">System</span></a>.<span class="me1">exit</span><span class="br0">&#40;</span><span class="sy0">-</span><span class="nu0">1002</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>config.<span class="me1">getBoolean</span><span class="br0">&#40;</span><span class="st0">&quot;debug&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">setLevel</span><span class="br0">&#40;</span>Level.<span class="me1">DEBUG</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">setLevel</span><span class="br0">&#40;</span>Level.<span class="me1">INFO</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;Log level set to &quot;</span> <span class="sy0">+</span> log.<span class="me1">getLevel</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br /> +<br /> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">new</span> CallerIdClient<span class="br0">&#40;</span>config<span class="br0">&#41;</span><span class="sy0">;</span><br /> +&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br /> +<span class="br0">&#125;</span></div></div> +</div></div></div><div class="field field-name-upload field-type-file field-label-hidden"><div class="field-items"><div class="field-item even"><table class="sticky-enabled"> + <thead><tr><th>Attachment</th><th>Size</th> </tr></thead> +<tbody> + <tr class="odd"><td><span class="file"><img class="file-icon" alt="File" title="application/java-archive" src="/modules/file/icons/application-octet-stream.png" /> <a href="http://siarp.de/sites/siarp.de/files/speedportcallerid.jar" type="application/java-archive; length=3143313" title="speedportcallerid.jar">speedportcallerid.jar</a></span></td><td>3 MB</td> </tr> +</tbody> +</table> +</div></div></div> + Mon, 30 Jul 2012 20:35:30 +0000 + Tilman + 232 at http://siarp.de + http://siarp.de/node/232#comments + + + Reinventing the wheel: Automatic Bidirectional Directory Synchronization + http://siarp.de/node/231 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>As <a href="http://siarp.de/node/228">already mentioned</a>, I am the proud owner of an online hard drive and I love it. Enough space for everything that's worth keeping, secure access over lots of different protocols (including rsync), an automatic backup function... It would be perfect if I had an Internet connection of at least 100 MBit/s. But I haven't. (Actually the thing almost feels like a local disk when I use it from my computer at work. But that's through a university network.) So I had to come up with a little more sophisticated architecture. I bought a <a href="http://www.globalscaletechnologies.com/t-guruplugdetails.aspx">GuruPlug</a> server and added an external USB hard drive to it. The basic idea is to use the USB drive over the LAN while at home but still being able to have all data synchronized to the online hard drive in order to have automatic backup and fast access from everywhere else. I thought that the sychronization part would be the easiest as there is a plethora of software available for this task but when I had a closer look at the tools, I ran into problems:</p> + +<ul> +<li><a href="http://samba.anu.edu.au/rsync/">rsync</a>, the best known synchronization software only does unidirectional synching. (So it's a mirroring tool, not a synchronization tool, to be correct.) But I want to be able to change files at home on the local drive and on the go on the online drive and have them automatically sychronized overnight.</li> +<li><a href="http://www.cis.upenn.edu/~bcpierce/unison/">Unison</a> does bidirectional synchronization, also using the heavily traffic-optimized rsync protocol. Sounds perfect. But unison <a href="https://alliance.seas.upenn.edu/~bcpierce/wiki/index.php?n=Main.UnisonFAQTips">does not really work on locally mounted remote drives</a> as it apparently calculates a hash sum for each and every file which results in <em>downloading the entire online hard drive.</em> (Currently 135 GB in my case.) Usually one would use a unison server for that, calculating the hashes locally on both sides but I do not have shell access to the server - it's only a hard drive.</li> +<li><a href="http://jfilesync.sourceforge.net/">JFileSync</a>, my personal favorite, does bidirectional synchronization and can run from the shell. But when I tried to use it for my "135 GB, 70000 files" directory, it blew up my server's memory as it does a complete comparison in the first step, putting the pending actions for all files in an xml structure, as far as I can tell. (I have to add that the directories were almost in sync at that time. So it's not only because of the huge number of actions for the first sychronization.)</li> +</ul> + +<p>Is it really that hard to have two directories synchronized with the files only compared by their size and their timestamp? I ended up writing my own SyncTool in Java. And while I was at it, I added the possibility to receive the synchronization protocol via Jabber.</p> + +<h2>Libraries used</h2> + +<p>I am standing on the shoulders of giants here, I have to say. The tool uses <a href="http://www.h2database.com">H2</a> to keep track of the files, the <a href="http://commons.apache.org/">Apache Commons</a> and <a href="http://logging.apache.org/log4j/">log4j</a> for the actual copy procedure and log output, <a href="http://martiansoftware.com/jsap/">JSAP</a> to parse the command line and <a href="http://www.igniterealtime.org/projects/smack/">Smack</a> to connect to Jabber. So all I did was implementing the actual synchronization algorithm: Read the file list, compare and synchronize, recurse. Done using Eclipse and Maven.</p> + +<h2>Where to get it</h2> + +<p>If you want to do something similar and don't have the time to reinvent the wheel once again, you can <a href="http://www.tilman.de/programme/synctool/index.en.php">download the SyncTool from my homepage</a>. Available as open source under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0.</a></p> + +<h2>How to use it</h2> + +<p>The software is intended to work in batch mode and thus performs bidirectional synchronization only without conflict resolution of any kind. If a file was modified on both sides, the older one being dismissed and overwritten by the newer one. (It should be no problem, however, to add a feature like a --dont-overwrite-conflicting-files with a few lines of additional code.) That being said, the second thing you have to think about is that you need a Java JRE. The Open JDK 6 JRE works pretty well with the program on my server, just apt-get install default-jre.</p> + +<p>Remember to backup your files, this software comes with ABSOLUTELY NO WARRANTY.</p> + +<p>This is the help page:</p> + +<pre><code>Usage: java -jar synctool-1.0.8.jar &lt;source path&gt; &lt;destination path&gt; [(-f|--dbfile) &lt;database file&gt;] [(-l|--logfile) &lt;logfile&gt;] [(-j|--jabber) &lt;jabber address&gt;] [(-r|--server) &lt;jabber server&gt;] [(-u|--user) &lt;jabber user&gt;] [(-p|--password) &lt;jabber password&gt;] [-d|--dry-run] [-h|--hashing] [-i|--ignore-directory-attributes] [-s|--silent] [--debug] [-?|--help] + + &lt;source path&gt; + the source path + + &lt;destination path&gt; + the destination path + + [(-f|--dbfile) &lt;database file&gt;] + the path to the database file to use (default: synctool) + + [(-l|--logfile) &lt;logfile&gt;] + the path for a logfile to write + + [(-j|--jabber) &lt;jabber address&gt;] + send logging output as jabber message to the given address + + [(-r|--server) &lt;jabber server&gt;] + the jabber server to connect to + + [(-u|--user) &lt;jabber user&gt;] + the jabber user name used for logging in to the server + + [(-p|--password) &lt;jabber password&gt;] + the jabber password used for logging in to the server + + [-d|--dry-run] + perform a trial run with no changes made + + [-h|--hashing] + generate MD5 file hashes for exact comparison + + [-i|--ignore-directory-attributes] + do not copy attributes for directories + + [-s|--silent] + do not print "Entering directory" and "No operation" messages + + [--debug] + print debug messages + + [-?|--help] + print help and exit +</code></pre> +</div></div></div> + Mon, 21 Mar 2011 18:11:50 +0000 + Tilman + 231 at http://siarp.de + http://siarp.de/node/231#comments + + + MongoDB und node.js auf Ubuntu 9.04 Jaunty installieren + http://siarp.de/node/229 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><div class="geshifilter"><div class="text geshifilter-text">sudo vim /etc/apt/sources.list<br /> +&gt; # MongoDB<br /> +&gt; deb http://downloads.mongodb.org/distros/ubuntu 9.4 10gen<br /> +<br /> +sudo aptitude update &amp;&amp; sudo aptitude install mongodb-stable<br /> +<br /> +sudo /etc/init.d/mongodb start<br /> +<br /> +git clone http://github.com/ry/node.git<br /> +cd node<br /> +git checkout -b tags/v0.2.0<br /> +./configure --prefix=/home/martin<br /> +make<br /> +make install<br /> +<br /> +curl http://npmjs.org/install.sh | sh<br /> +npm install mongodb mustache</div></div> + +<p>http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages</p> +</div></div></div> + Thu, 26 Aug 2010 11:33:58 +0000 + Martin + 229 at http://siarp.de + http://siarp.de/node/229#comments + + + Strato HiDrive unter Ubuntu einbinden + http://siarp.de/node/228 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Mein neues <a href="http://hidrive.strato.com">HiDrive</a> unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. <a href="http://tuxpool.blogspot.com/2009/07/webdav-bug-in-ubuntu-jaunty.html">so</a>), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen. +Die Lösung: SFTP per <a href="http://www.heise.de/ct/hotline/Dateisystem-per-SSH-320860.html">sshfs</a>. Fühlt sich fast an, als wäre es die lokale Festplatte.</p> + +<p>Vorbereitung:</p> + +<div class="geshifilter"><div class="text geshifilter-text">sudo adduser username fuse &nbsp; &nbsp; &nbsp; &nbsp; # Benutzer &quot;username&quot; der Gruppe fuse hinzufügen (wird nach nächstem Login aktiv)<br /> +sudo mkdir /media/hidrive &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Mountpoint anlegen<br /> +sudo chmod 777 /media/hidrive</div></div> + +<p>mount funktioniert so:</p> + +<div class="geshifilter"><div class="text geshifilter-text">sshfs -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive</div></div> + +<p>Nur mit workaround=rename kann ich Dateien auf dem HiDrive ersetzen und mit gedit bearbeiten (weil das normalerweise anscheinend eine temporäre Datei schreibt und die dann umbenennt).</p> + +<p>unmount so:</p> + +<div class="geshifilter"><div class="text geshifilter-text">fusermount -u /media/hidrive</div></div> + +<p>Wenn man beim Einloggen nicht immer das Passwort eingeben möchte, kann man auch einen ssh-Key verwenden, eine Anleitung dafür gibt es bei Strato unter www.strato-faq.de/artikel.html?id=2297</p> + +<p>Das Login-Skript sieht dann so aus:</p> + +<div class="geshifilter"><div class="text geshifilter-text">#!/bin/sh<br /> +sshfs -o IdentityFile=/home/user/.ssh/id_rsa -o allow_other -o workaround=rename username@sftp.hidrive.strato.com: /media/hidrive</div></div> + +<p><br /></p> + +<hr /> + +<p><strong>Edit:</strong></p> + +<h3>Nachtrag</h3> + +<p>Wie Jens in den Kommentaren richtig anmerkt, muss man noch die fusermount-Konfiguration anpassen, damit das Einbinden auch für normale user funktioniert. Beim mount bemerkt fusermount sonst auch ganz korrekt:</p> + +<div class="geshifilter"><div class="text geshifilter-text">fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf</div></div> + +<p>Die Zeile "user_allow_other" ist in /etc/fuse.conf auch schon vorhanden und muss nur wieder einkommentiert werden. Bei mir beschwert sich fusermount unter Ubuntu 12.04 (64 bit) allerdings außerdem noch über die Zugriffsrechte:</p> + +<div class="geshifilter"><div class="text geshifilter-text">fusermount: failed to open /etc/fuse.conf: Permission denied</div></div> + +<p>Sobald ich die Datei per chmod zum Lesen für alle Benutzer freigegeben habe, ist auch dieser Fehler verschwunden. Danach können dann auch normale Benutzer das hidrive mounten.</p> +</div></div></div> + Wed, 28 Jul 2010 09:09:14 +0000 + Tilman + 228 at http://siarp.de + http://siarp.de/node/228#comments + + + Committeten auf deutsch + http://siarp.de/node/227 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Bei der Frage, mit wie vielen Ts man eigentlich „committeten“ („das steht im committeten Code“) schreibt, dachte ich mir, es wäre Zeit, sich mal mit vernünftigen und vertretbaren Übersetzungen in diesem Bereich zu beschäftigen. Das Ergebnis:</p> + +<p>Ein „Commit“ ist ein „Beitrag“, etwas „committen“ etwas „beitragen“. Beim „Repository“ ist es noch unklar. Es lässt sich wohl mit „Repositorium“aber auch mit „Repository“ übersetzen. Schön wäre vielleicht auch „Magazin“. „Einen Beitrag zum Magazin leisten“...</p> + +<p>Also, wisst ihr bescheid. Übersetzt eure Werkzeuge und pflegt die Sprachkultur!</p> +</div></div></div> + Thu, 06 May 2010 20:01:37 +0000 + Martin + 227 at http://siarp.de + http://siarp.de/node/227#comments + + + Plone: Item Type as Criterion for Collection but not to show up in Search + http://siarp.de/node/223 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>You can't select an item type as a criterion for a collection if it is not selected to be included in search results. In the "Search settings" (<span class="geshifilter"><code class="text geshifilter-text">/@@search-controlpanel</code></span>) you can exclude certain content types from being "searched and be available in the user facing part of the site". That actually corresponds to the list of <span class="geshifilter"><code class="text geshifilter-text">types_not_searched</code></span> in <span class="geshifilter"><code class="text geshifilter-text">site_properties</code></span>. Now that list is excluded from available content types as a criterion for collections. At least for the UI–it still works.</p> + +<p>If you want a content type to not show up in search results but in collections, you can work around that problem by enabling the type for search temporarily, set up your collection and disable the type for search afterwards. It's a bit odd, because you can't even see your selection in the criterion page afterwards but it works.</p> + +<p>I'd say this is a bug and the collection UI should present all available types in the option box, if searchable or not. I guess I should file a report.</p> + +<p><strong>Update:</strong> I submitted a <a href="https://dev.plone.org/plone/ticket/9802">bug report</a>.</p> +</div></div></div> + Mon, 16 Nov 2009 14:13:07 +0000 + Martin + 223 at http://siarp.de + http://siarp.de/node/223#comments + + + My SilverStripe Usability Test + http://siarp.de/node/222 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>So I decided to try out <a href="http://silverstripe.org/">SilveStripe</a> (Version 2.3.3) to check out if it's of any value for me as a freelance web developer. I'm kind of an expert in <a href="http://drupal.org/">Drupal</a>, I also work with <a href="http://plone.org/">Plone</a>, and lately I'm very interested in usability and I do track initiatives in the Drupal and Plone community to give users a better experience. I know that feedback of a first-time user is valuable so I thought I'd write down my impressions of SilverStripe right away.</p> + +<h2>Installation</h2> + +<p>On the SilverStripe homepage I found the big download button (actually I searched for "Downloads" or something in the main navigation first and it took me a second to find the blue thing on the right) and then got my stable version. I extracted it in the web root of my machine, renamed the folder to "SilverStripe" and then searched for installation instructions. In the silverstripe.org main navigation I clicked on "Help" and after skimming all of the options I clicked in "Documentation". There I found the <a href="http://doc.silverstripe.org/doku.php?id=installation">Installing</a> link under "Installation". There I got confused for a few seconds by the platform-dependent instructions but then I realized that this is about setting up the basic web stack, which I,of course, already have so down to "Existing Webservers" > <a href="http://doc.silverstripe.org/doku.php?id=installation-on-webserver">Apache</a>. Ok, the Installation Steps tell me that there's nothing to do but open a browser and enter the URL. Well, I know, you always have to set up a database first so <span class="geshifilter"><code class="text geshifilter-text">CREATE DATABASE silverstripe;</code></span> and then open the browser.</p> + +<p>I had one usability issue with the layout of the installation screen. I was not sure about the "steps", where I was and what would be next. Major confusion was the placement of the button to proceed which is somewhere at the top but not at the very top of the form/page. I scrolled down to read and check everything and I expected a kind of "next" button at the bottom.</p> + +<p>All in all, the install process was very easy, went smoothly and I could find all the information I needed. I seems as if the download button at the top right of the site is supposed to be very prominent but to me it was not. Of course this is not a big issue at all. As of the installation instructions there could be a shortcut, like: <em>If you already have your server set up, just extract SilverStripe to your web root, create a database and point your browser to the new SilverStripe URL. The automatic installer will guide you through the setup.</em> The layout of the installer is a major (but not critical) issue to me. There should be some overview of the steps and the button should be somewhere else with better wording.</p> + +<p><strong>Notes:</strong></p> + +<ul> +<li>Don't pre-populate the admin password - it's insecure and users won't "remember" the password as they didn't enter it in the first place</li> +</ul> +</div></div></div> + Sat, 14 Nov 2009 10:44:13 +0000 + Martin + 222 at http://siarp.de + http://siarp.de/node/222#comments + + + YAML und Listen im IE6 + http://siarp.de/node/221 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Achtung! Böse Falle mit YAML und Listen im Internet Explorer 6! Folgender Code steht in der iehacks.css und gilt für den IE6.</p> + +<div class="geshifilter"><div class="css geshifilter-css"><span class="coMULTI">/**<br /> +&nbsp;* Disappearing List-Background Bug<br /> +&nbsp;* @see &nbsp; &nbsp; &nbsp; &nbsp;http://www.positioniseverything.net/explorer/ie-listbug.html<br /> +&nbsp;*<br /> +&nbsp;* @bugfix<br /> +&nbsp;* @affected &nbsp; IE 5.x/Win, IE6<br /> +&nbsp;* @css-for &nbsp; &nbsp;IE 5.x/Win, IE6<br /> +&nbsp;* @valid &nbsp; &nbsp; &nbsp;yes<br /> +&nbsp;*/</span><br /> +<br /> +<span class="sy0">*</span> html ul<span class="sy0">,</span> <span class="sy0">*</span> html ol<span class="sy0">,</span> <span class="sy0">*</span> html dl <span class="br0">&#123;</span> <span class="kw1">position</span><span class="sy0">:</span> <span class="kw2">relative</span><span class="sy0">;</span> <span class="br0">&#125;</span></div></div> + +<p>Ich hatte deswegen jetzt schon ein <a href="http://siarp.de/node/220">zweites Mal</a> Probleme. Diesmal ging es darum, dass Listenelemente sich nicht entsprechende dem overflow verhielten, wie andere Elemente. Wieder habe ich eine Weile nach dem Problem gesucht.</p> + +<p>Der globale Ansatz des YAML-Fixes ist schon gewagt, finde ich. Man muss das immer im Hinterkopf behalten. Immer, wenn etwas nur im IE6 komisch ist mit der Darstellung von Listen, prüfen ob es daran liegt. Umgehen (quasi ein Fix-Fix) ist einfach Z.B.:</p> + +<div class="geshifilter"><div class="css geshifilter-css"><span class="coMULTI">/* nur für IE6 anwenden: */</span><br /> +<span class="re0">#elem</span> ul <span class="br0">&#123;</span> <span class="kw1">position</span><span class="sy0">:</span> <span class="kw2">static</span><span class="sy0">;</span> <span class="br0">&#125;</span></div></div> +</div></div></div> + Wed, 11 Nov 2009 09:52:50 +0000 + Martin + 221 at http://siarp.de + http://siarp.de/node/221#comments + + + YAML, jQuery slideToggle and IE6 + http://siarp.de/node/220 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>As usual with browser bugs and hacks this took me a while to find out.</p> + +<p>I have an unordered list with complex items like floats and stuff. This list is supposed to hide when I click on a button by slowly decreasing its height. I use <a href="http://docs.jquery.com/Effects/slideToggle">jQuery's slideToggle</a> for that.</p> + +<p><strong>Problem:</strong> In Internet Explorer 6 the content (or parts of it) is hidden after the list is shown (slid down).</p> + +<p>The only thing I found was a <a href="http://www.ndoherty.biz/2007/09/jquery-slidetoggle-and-internet-explorer/">blog post</a> saying you shouldn't use any positioning there. I didn't. Well, I thought I didn't…</p> + +<p>For this project I use <a href="http://www.yaml.de/en/">YAML</a>, a CSS framework and YAML sets all lists to <span class="geshifilter"><code class="text geshifilter-text">position: relative</code></span> for IE6 (iehacks.css):</p> + +<div class="geshifilter"><div class="css geshifilter-css">&nbsp; <span class="coMULTI">/**<br /> +&nbsp; &nbsp;* Disappearing List-Background Bug<br /> +&nbsp; &nbsp;* @see &nbsp; &nbsp; &nbsp; &nbsp;http://www.positioniseverything.net/explorer/ie-listbug.html<br /> +&nbsp; &nbsp;*<br /> +&nbsp; &nbsp;* @bugfix<br /> +&nbsp; &nbsp;* @affected &nbsp; IE 5.x/Win, IE6<br /> +&nbsp; &nbsp;* @css-for &nbsp; &nbsp;IE 5.x/Win, IE6<br /> +&nbsp; &nbsp;* @valid &nbsp; &nbsp; &nbsp;yes<br /> +&nbsp; &nbsp;*/</span><br /> +<br /> +&nbsp; <span class="sy0">*</span> html ul<span class="sy0">,</span> <span class="sy0">*</span> html ol<span class="sy0">,</span> <span class="sy0">*</span> html dl <span class="br0">&#123;</span> <span class="kw1">position</span><span class="sy0">:</span> <span class="kw2">relative</span><span class="sy0">;</span> <span class="br0">&#125;</span></div></div> + +<p>Overriding this for my sliding list solves the problem.</p> +</div></div></div> + Fri, 06 Nov 2009 13:46:36 +0000 + Martin + 220 at http://siarp.de + http://siarp.de/node/220#comments + + + Bazaar: incompatible format 2a and rich-root support + http://siarp.de/node/218 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>I'm running Bazaar 2.0 on my local machine and the remote repository runs on Ubuntu Jaunty which provides Bazaar 1.13. After working locally for some time I wanted to push my branch to a newly created shared repository on the server but I got the error message</p> + +<div class="geshifilter"><div class="text geshifilter-text">bzr: ERROR: RemoteRepository(bzr+ssh://SERVER/path/to/repo/.bzr/) &nbsp; &nbsp; &nbsp; <br /> +is not compatible with<br /> +CHKInventoryRepository('file:///path/to/repo/.bzr/repository/')<br /> +different rich-root support</div></div> + +<p>Reading http://www.nabble.com/bazaar-error-on-repository-td25868297.html it seems different Bazaar versions make different repository formats which are incompatible. But</p> + +<blockquote> + <p>[...] you could move the server to a rich root capable format; then + it would work (though crossing the format boundary can be slow). + 1.3.1 is new enough to support rich-root-pack.</p> +</blockquote> + +<p>So on the server I did</p> + +<div class="geshifilter"><div class="text geshifilter-text">bzr upgrade --rich-root-pack repo/</div></div> + +<p>and now it works. I can push my local branch to the remote repository.</p> + +<p><strong>But only once!</strong></p> + +<p>Second time I wanted to push I got another error:</p> + +<div class="geshifilter"><div class="text geshifilter-text">bzr: ERROR: bzrlib.errors.ErrorFromSmartServer: Error received from smart server: ('error', &quot;'Bazaar repository format 2a (needs bzr 1.16 or later)\\n'&quot;)</div></div> + +<p>Looks like the format 2a, which is the default for Bazaar >= 2.0 is incompatible with the one on my server. Downgrading to an older format of my local tree did the trick:</p> + +<div class="geshifilter"><div class="text geshifilter-text">bzr upgrade --format=1.14-rich-root</div></div> +</div></div></div> + Mon, 26 Oct 2009 09:38:36 +0000 + Martin + 218 at http://siarp.de + http://siarp.de/node/218#comments + + + diff --git a/siarp.de/sites/all/modules/ctools/images/status-active/index.gif b/siarp.de/sites/all/modules/ctools/images/status-active/index.gif new file mode 100644 index 0000000..207e95c Binary files /dev/null and b/siarp.de/sites/all/modules/ctools/images/status-active/index.gif differ diff --git a/siarp.de/sites/siarp.de/files/Bild 10/index.png b/siarp.de/sites/siarp.de/files/Bild 10/index.png new file mode 100644 index 0000000..3ab0352 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/Bild 10/index.png differ diff --git a/siarp.de/sites/siarp.de/files/Bild 11/index.png b/siarp.de/sites/siarp.de/files/Bild 11/index.png new file mode 100644 index 0000000..c63acb9 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/Bild 11/index.png differ diff --git a/siarp.de/sites/siarp.de/files/Bild 13/index.png b/siarp.de/sites/siarp.de/files/Bild 13/index.png new file mode 100644 index 0000000..456bab5 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/Bild 13/index.png differ diff --git a/siarp.de/sites/siarp.de/files/Inbox_Zero/index.jpg b/siarp.de/sites/siarp.de/files/Inbox_Zero/index.jpg new file mode 100644 index 0000000..86cb520 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/Inbox_Zero/index.jpg differ diff --git a/siarp.de/sites/siarp.de/files/Inbox_Zero/index.svg b/siarp.de/sites/siarp.de/files/Inbox_Zero/index.svg new file mode 100644 index 0000000..3c75430 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/Inbox_Zero/index.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + E-Mail + + + + 1 + + Inbox + + + 2 + + + + + Erledigen + Archiv + + + Sonstiges + Persönlich + + Gesendet + Entwürfe + + + + 3 + + Backup + + diff --git a/siarp.de/sites/siarp.de/files/bin/index.zip b/siarp.de/sites/siarp.de/files/bin/index.zip new file mode 100644 index 0000000..e630158 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/bin/index.zip differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white/index.png new file mode 100644 index 0000000..02064a6 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar-white/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar/index.png new file mode 100644 index 0000000..0cb01fe Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-bar/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left/index.png new file mode 100644 index 0000000..ae0a92a Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-left/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right/index.png new file mode 100644 index 0000000..0f2465b Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content-right/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content/index.png new file mode 100644 index 0000000..c6fe619 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-content/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover/index.png new file mode 100644 index 0000000..6908a9e Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item-hover/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item/index.png new file mode 100644 index 0000000..1f53eba Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation-item/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation/index.png new file mode 100644 index 0000000..3920d99 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-navigation/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab/index.png new file mode 100644 index 0000000..c2eccee Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/bg-tab/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/body/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/body/index.png new file mode 100644 index 0000000..67cbb36 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/body/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner/index.png b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner/index.png new file mode 100644 index 0000000..5ceda7c Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/gradient-inner/index.png differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed/index.gif b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed/index.gif new file mode 100644 index 0000000..3dc9ca7 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-collapsed/index.gif differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded/index.gif b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded/index.gif new file mode 100644 index 0000000..126ccc1 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-expanded/index.gif differ diff --git a/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf/index.gif b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf/index.gif new file mode 100644 index 0000000..a55d802 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/color/garland-596ce30b/menu-leaf/index.gif differ diff --git a/siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css b/siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css new file mode 100644 index 0000000..f86ed97 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/css/css_NdVgz6YKifxQUEsW5xls_zI7Pn2F7E5U5Wb29zcu3vo/index.css @@ -0,0 +1,5 @@ +#comments{margin-top:15px;}.indented{margin-left:25px;}.comment-unpublished{background-color:#fff4f4;}.comment-preview{background-color:#ffffea;} +.field .field-label{font-weight:bold;}.field-label-inline .field-label,.field-label-inline .field-items{float:left;}form .field-multiple-table{margin:0;}form .field-multiple-table th.field-label{padding-left:0;}form .field-multiple-table td.field-multiple-drag{width:30px;padding-right:0;}form .field-multiple-table td.field-multiple-drag a.tabledrag-handle{padding-right:.5em;}form .field-add-more-submit{margin:.5em 0 0;} +.node-unpublished{background-color:#fff4f4;}.preview .node{background-color:#ffffea;}td.revision-current{background:#ffc;} +#permissions td.module{font-weight:bold;}#permissions td.permission{padding-left:1.5em;}#permissions tr.odd .form-item,#permissions tr.even .form-item{white-space:normal;}#user-admin-settings fieldset .fieldset-description{font-size:0.85em;padding-bottom:.5em;}#user-admin-roles td.edit-name{clear:both;}#user-admin-roles .form-item-name{float:left;margin-right:1em;}.password-strength{width:17em;float:right;margin-top:1.4em;}.password-strength-title{display:inline;}.password-strength-text{float:right;font-weight:bold;}.password-indicator{background-color:#C4C4C4;height:0.3em;width:100%;}.password-indicator div{height:100%;width:0%;background-color:#47C965;}input.password-confirm,input.password-field{width:16em;margin-bottom:0.4em;}div.password-confirm{float:right;margin-top:1.5em;visibility:hidden;width:17em;}div.form-item div.password-suggestions{padding:0.2em 0.5em;margin:0.7em 0;width:38.5em;border:1px solid #B4B4B4;}div.password-suggestions ul{margin-bottom:0;}.confirm-parent,.password-parent{clear:left;margin:0;width:36.3em;}.profile{clear:both;margin:1em 0;}.profile .user-picture{float:right;margin:0 1em 1em 0;}.profile h3{border-bottom:1px solid #ccc;}.profile dl{margin:0 0 1.5em 0;}.profile dt{margin:0 0 0.2em 0;font-weight:bold;}.profile dd{margin:0 0 1em 0;} +.views-exposed-form .views-exposed-widget{float:left;padding:.5em 1em 0 0;}.views-exposed-form .views-exposed-widget .form-submit{margin-top:1.6em;}.views-exposed-form .form-item,.views-exposed-form .form-submit{margin-top:0;margin-bottom:0;}.views-exposed-form label{font-weight:bold;}.views-exposed-widgets{margin-bottom:.5em;}.views-align-left{text-align:left;}.views-align-right{text-align:right;}.views-align-center{text-align:center;}.views-view-grid tbody{border-top:none;}.view .progress-disabled{float:none;} diff --git a/siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css b/siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css new file mode 100644 index 0000000..63ea8c9 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/css/css_OAqUol8y_hmU_lCucLyaRX-a1G627sWWbvG_VG1GKnE/index.css @@ -0,0 +1,3 @@ +.ctools-locked{color:red;border:1px solid red;padding:1em;}.ctools-owns-lock{background:#ffffdd none repeat scroll 0 0;border:1px solid #f0c020;padding:1em;}a.ctools-ajaxing,input.ctools-ajaxing,button.ctools-ajaxing,select.ctools-ajaxing{padding-right:18px !important;background:url(../../../../all/modules/ctools/images/status-active/index.gif) right center no-repeat;}div.ctools-ajaxing{float:left;width:18px;background:url(../../../../all/modules/ctools/images/status-active/index.gif) center center no-repeat;} +.apache.geshifilter-apache .de1,.apache.geshifilter-apache .de2{font-family:monospace;font-weight:normal;font-style:normal}.apache.geshifilter-apache{font-family:monospace;}.apache.geshifilter-apache .imp{font-weight:bold;color:red;}.apache.geshifilter-apache li,.apache.geshifilter-apache .li1{font-family:monospace;font-weight:normal;}.apache.geshifilter-apache .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.apache.geshifilter-apache .li2{font-family:monospace;font-weight:bold;font-style:italic;}.apache.geshifilter-apache .kw1{color:#00007f;}.apache.geshifilter-apache .kw2{color:#0000ff;}.apache.geshifilter-apache .kw3{color:#000000;font-weight:bold;}.apache.geshifilter-apache .co1{color:#adadad;font-style:italic;}.apache.geshifilter-apache .es0{color:#000099;font-weight:bold;}.apache.geshifilter-apache .br0{color:#339933;}.apache.geshifilter-apache .sy0{color:#008000;}.apache.geshifilter-apache .st0{color:#7f007f;}.apache.geshifilter-apache .nu0{color:#ff0000;}.apache.geshifilter-apache .ln-xtra,.apache.geshifilter-apache li.ln-xtra,.apache.geshifilter-apache div.ln-xtra{background-color:#ffc;}.apache.geshifilter-apache span.xtra{display:block;}.applescript.geshifilter-applescript .de1,.applescript.geshifilter-applescript .de2{font-family:monospace;font-weight:normal;font-style:normal}.applescript.geshifilter-applescript{font-family:monospace;}.applescript.geshifilter-applescript .imp{font-weight:bold;color:red;}.applescript.geshifilter-applescript li,.applescript.geshifilter-applescript .li1{font-family:monospace;font-weight:normal;}.applescript.geshifilter-applescript .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.applescript.geshifilter-applescript .li2{font-family:monospace;font-weight:bold;font-style:italic;}.applescript.geshifilter-applescript .kw1{color:#0066ff;}.applescript.geshifilter-applescript .kw2{color:#ff0033;}.applescript.geshifilter-applescript .kw3{color:#ff0033;font-weight:bold;}.applescript.geshifilter-applescript .co1{color:#808080;font-style:italic;}.applescript.geshifilter-applescript .co3{color:#ff0000;}.applescript.geshifilter-applescript .coMULTI{color:#808080;font-style:italic;}.applescript.geshifilter-applescript .es0{color:#000000;font-weight:bold;}.applescript.geshifilter-applescript .br0{color:#000000;}.applescript.geshifilter-applescript .sy0{color:#000000;}.applescript.geshifilter-applescript .st0{color:#009900;}.applescript.geshifilter-applescript .nu0{color:#000000;}.applescript.geshifilter-applescript .me1{color:#006600;}.applescript.geshifilter-applescript .me2{color:#006600;}.applescript.geshifilter-applescript .re0{color:#339933;}.applescript.geshifilter-applescript .re4{color:#0066ff;}.applescript.geshifilter-applescript .ln-xtra,.applescript.geshifilter-applescript li.ln-xtra,.applescript.geshifilter-applescript div.ln-xtra{background-color:#ffc;}.applescript.geshifilter-applescript span.xtra{display:block;}.bash.geshifilter-bash .de1,.bash.geshifilter-bash .de2{font-family:monospace;font-weight:normal;font-style:normal}.bash.geshifilter-bash{font-family:monospace;}.bash.geshifilter-bash .imp{font-weight:bold;color:red;}.bash.geshifilter-bash li,.bash.geshifilter-bash .li1{font-family:monospace;font-weight:normal;}.bash.geshifilter-bash .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.bash.geshifilter-bash .li2{font-family:monospace;font-weight:bold;font-style:italic;}.bash.geshifilter-bash .kw1{color:#000000;font-weight:bold;}.bash.geshifilter-bash .kw2{color:#c20cb9;font-weight:bold;}.bash.geshifilter-bash .kw3{color:#7a0874;font-weight:bold;}.bash.geshifilter-bash .co0{color:#666666;font-style:italic;}.bash.geshifilter-bash .co1{color:#800000;}.bash.geshifilter-bash .co2{color:#cc0000;font-style:italic;}.bash.geshifilter-bash .co3{color:#000000;font-weight:bold;}.bash.geshifilter-bash .co4{color:#666666;}.bash.geshifilter-bash .es1{color:#000099;font-weight:bold;}.bash.geshifilter-bash .es2{color:#007800;}.bash.geshifilter-bash .es3{color:#007800;}.bash.geshifilter-bash .es4{color:#007800;}.bash.geshifilter-bash .es5{color:#780078;}.bash.geshifilter-bash .es_h{color:#000099;font-weight:bold;}.bash.geshifilter-bash .br0{color:#7a0874;font-weight:bold;}.bash.geshifilter-bash .sy0{color:#000000;font-weight:bold;}.bash.geshifilter-bash .st0{color:#ff0000;}.bash.geshifilter-bash .st_h{color:#ff0000;}.bash.geshifilter-bash .nu0{color:#000000;}.bash.geshifilter-bash .re0{color:#007800;}.bash.geshifilter-bash .re1{color:#007800;}.bash.geshifilter-bash .re2{color:#007800;}.bash.geshifilter-bash .re4{color:#007800;}.bash.geshifilter-bash .re5{color:#660033;}.bash.geshifilter-bash .ln-xtra,.bash.geshifilter-bash li.ln-xtra,.bash.geshifilter-bash div.ln-xtra{background-color:#ffc;}.bash.geshifilter-bash span.xtra{display:block;}.css.geshifilter-css .de1,.css.geshifilter-css .de2{font-family:monospace;font-weight:normal;font-style:normal}.css.geshifilter-css{font-family:monospace;}.css.geshifilter-css .imp{font-weight:bold;color:red;}.css.geshifilter-css li,.css.geshifilter-css .li1{font-family:monospace;font-weight:normal;}.css.geshifilter-css .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.css.geshifilter-css .li2{font-family:monospace;font-weight:bold;font-style:italic;}.css.geshifilter-css .kw1{color:#000000;font-weight:bold;}.css.geshifilter-css .kw2{color:#993333;}.css.geshifilter-css .co1{color:#a1a100;}.css.geshifilter-css .co2{color:#ff0000;font-style:italic;}.css.geshifilter-css .coMULTI{color:#808080;font-style:italic;}.css.geshifilter-css .es0{color:#000099;font-weight:bold;}.css.geshifilter-css .es2{color:#000099;font-weight:bold;}.css.geshifilter-css .br0{color:#00AA00;}.css.geshifilter-css .sy0{color:#00AA00;}.css.geshifilter-css .st0{color:#ff0000;}.css.geshifilter-css .nu0{color:#cc66cc;}.css.geshifilter-css .re0{color:#cc00cc;}.css.geshifilter-css .re1{color:#6666ff;}.css.geshifilter-css .re2{color:#3333ff;}.css.geshifilter-css .re3{color:#933;}.css.geshifilter-css .ln-xtra,.css.geshifilter-css li.ln-xtra,.css.geshifilter-css div.ln-xtra{background-color:#ffc;}.css.geshifilter-css span.xtra{display:block;}.diff.geshifilter-diff .de1,.diff.geshifilter-diff .de2{font-family:monospace;font-weight:normal;font-style:normal}.diff.geshifilter-diff{font-family:monospace;}.diff.geshifilter-diff .imp{font-weight:bold;color:red;}.diff.geshifilter-diff li,.diff.geshifilter-diff .li1{font-family:monospace;font-weight:normal;}.diff.geshifilter-diff .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.diff.geshifilter-diff .li2{font-family:monospace;font-weight:bold;font-style:italic;}.diff.geshifilter-diff .kw1{color:#aaaaaa;font-style:italic;}.diff.geshifilter-diff .re0{color:#440088;}.diff.geshifilter-diff .re1{color:#991111;}.diff.geshifilter-diff .re2{color:#00b000;}.diff.geshifilter-diff .re3{color:#888822;}.diff.geshifilter-diff .re4{color:#888822;}.diff.geshifilter-diff .re5{color:#0011dd;}.diff.geshifilter-diff .re6{color:#440088;}.diff.geshifilter-diff .re7{color:#991111;}.diff.geshifilter-diff .re8{color:#00b000;}.diff.geshifilter-diff .re9{color:#888822;}.diff.geshifilter-diff .ln-xtra,.diff.geshifilter-diff li.ln-xtra,.diff.geshifilter-diff div.ln-xtra{background-color:#ffc;}.diff.geshifilter-diff span.xtra{display:block;}.java.geshifilter-java .de1,.java.geshifilter-java .de2{font-family:monospace;font-weight:normal;font-style:normal}.java.geshifilter-java{font-family:monospace;}.java.geshifilter-java .imp{font-weight:bold;color:red;}.java.geshifilter-java li,.java.geshifilter-java .li1{font-family:monospace;font-weight:normal;}.java.geshifilter-java .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.java.geshifilter-java .li2{font-family:monospace;font-weight:bold;font-style:italic;}.java.geshifilter-java .kw1{color:#000000;font-weight:bold;}.java.geshifilter-java .kw2{color:#000066;font-weight:bold;}.java.geshifilter-java .kw3{color:#003399;}.java.geshifilter-java .kw4{color:#000066;font-weight:bold;}.java.geshifilter-java .co1{color:#666666;font-style:italic;}.java.geshifilter-java .co2{color:#006699;}.java.geshifilter-java .co3{color:#008000;font-style:italic;font-weight:bold;}.java.geshifilter-java .coMULTI{color:#666666;font-style:italic;}.java.geshifilter-java .es0{color:#000099;font-weight:bold;}.java.geshifilter-java .br0{color:#009900;}.java.geshifilter-java .sy0{color:#339933;}.java.geshifilter-java .st0{color:#0000ff;}.java.geshifilter-java .nu0{color:#cc66cc;}.java.geshifilter-java .me1{color:#006633;}.java.geshifilter-java .me2{color:#006633;}.java.geshifilter-java .ln-xtra,.java.geshifilter-java li.ln-xtra,.java.geshifilter-java div.ln-xtra{background-color:#ffc;}.java.geshifilter-java span.xtra{display:block;}.java5.geshifilter-java5 .de1,.java5.geshifilter-java5 .de2{font-family:monospace;font-weight:normal;font-style:normal}.java5.geshifilter-java5{font-family:monospace;}.java5.geshifilter-java5 .imp{font-weight:bold;color:red;}.java5.geshifilter-java5 li,.java5.geshifilter-java5 .li1{font-family:monospace;font-weight:normal;}.java5.geshifilter-java5 .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.java5.geshifilter-java5 .li2{font-family:monospace;font-weight:bold;font-style:italic;}.java5.geshifilter-java5 .kw1{color:#000000;font-weight:bold;}.java5.geshifilter-java5 .kw2{color:#000000;font-weight:bold;}.java5.geshifilter-java5 .kw3{color:#006600;font-weight:bold;}.java5.geshifilter-java5 .kw4{color:#006600;font-weight:bold;}.java5.geshifilter-java5 .kw5{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw6{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw7{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw8{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw9{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw10{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw11{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw12{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw13{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw14{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw15{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw16{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw17{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw18{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw19{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw20{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw21{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw22{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw23{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw24{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw25{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw26{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw27{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw28{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw29{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw30{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw31{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw32{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw33{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw34{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw35{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw36{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw37{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw38{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw39{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw40{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw41{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw42{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw43{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw44{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw45{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw46{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw47{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw48{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw49{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw50{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw51{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw52{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw53{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw54{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw55{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw56{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw57{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw58{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw59{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw60{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw61{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw62{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw63{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw64{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw65{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw66{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw67{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw68{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw69{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw70{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw71{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw72{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw73{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw74{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw75{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw76{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw77{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw78{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw79{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw80{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw81{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw82{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw83{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw84{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw85{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw86{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw87{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw88{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw89{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw90{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw91{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw92{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw93{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw94{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw95{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw96{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw97{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw98{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw99{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw100{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw101{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw102{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw103{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw104{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw105{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw106{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw107{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw108{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw109{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw110{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw111{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw112{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw113{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw114{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw115{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw116{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw117{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw118{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw119{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw120{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw121{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw122{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw123{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw124{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw125{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw126{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw127{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw128{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw129{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw130{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw131{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw132{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw133{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw134{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw135{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw136{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw137{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw138{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw139{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw140{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw141{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw142{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw143{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw144{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw145{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw146{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw147{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw148{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw149{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw150{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw151{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw152{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw153{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw154{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw155{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw156{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw157{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw158{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw159{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw160{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw161{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw162{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw163{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw164{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw165{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .kw166{color:#003399;font-weight:bold;}.java5.geshifilter-java5 .co1{color:#666666;font-style:italic;}.java5.geshifilter-java5 .co2{color:#006699;}.java5.geshifilter-java5 .co3{color:#008000;font-style:italic;font-weight:bold;}.java5.geshifilter-java5 .coMULTI{color:#666666;font-style:italic;}.java5.geshifilter-java5 .es0{color:#000099;font-weight:bold;}.java5.geshifilter-java5 .br0{color:#009900;}.java5.geshifilter-java5 .sy0{color:#339933;}.java5.geshifilter-java5 .st0{color:#0000ff;}.java5.geshifilter-java5 .nu0{color:#cc66cc;}.java5.geshifilter-java5 .me1{color:#006633;}.java5.geshifilter-java5 .me2{color:#006633;}.java5.geshifilter-java5 .ln-xtra,.java5.geshifilter-java5 li.ln-xtra,.java5.geshifilter-java5 div.ln-xtra{background-color:#ffc;}.java5.geshifilter-java5 span.xtra{display:block;}.javascript.geshifilter-javascript .de1,.javascript.geshifilter-javascript .de2{font-family:monospace;font-weight:normal;font-style:normal}.javascript.geshifilter-javascript{font-family:monospace;}.javascript.geshifilter-javascript .imp{font-weight:bold;color:red;}.javascript.geshifilter-javascript li,.javascript.geshifilter-javascript .li1{font-family:monospace;font-weight:normal;}.javascript.geshifilter-javascript .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.javascript.geshifilter-javascript .li2{font-family:monospace;font-weight:bold;font-style:italic;}.javascript.geshifilter-javascript .kw1{color:#000066;font-weight:bold;}.javascript.geshifilter-javascript .kw2{color:#003366;font-weight:bold;}.javascript.geshifilter-javascript .kw3{color:#000066;}.javascript.geshifilter-javascript .kw5{color:#FF0000;}.javascript.geshifilter-javascript .co1{color:#006600;font-style:italic;}.javascript.geshifilter-javascript .co2{color:#009966;font-style:italic;}.javascript.geshifilter-javascript .coMULTI{color:#006600;font-style:italic;}.javascript.geshifilter-javascript .es0{color:#000099;font-weight:bold;}.javascript.geshifilter-javascript .br0{color:#009900;}.javascript.geshifilter-javascript .sy0{color:#339933;}.javascript.geshifilter-javascript .st0{color:#3366CC;}.javascript.geshifilter-javascript .nu0{color:#CC0000;}.javascript.geshifilter-javascript .me1{color:#660066;}.javascript.geshifilter-javascript .ln-xtra,.javascript.geshifilter-javascript li.ln-xtra,.javascript.geshifilter-javascript div.ln-xtra{background-color:#ffc;}.javascript.geshifilter-javascript span.xtra{display:block;}.mysql.geshifilter-mysql .de1,.mysql.geshifilter-mysql .de2{font-family:monospace;font-weight:normal;font-style:normal}.mysql.geshifilter-mysql{font-family:monospace;}.mysql.geshifilter-mysql .imp{font-weight:bold;color:red;}.mysql.geshifilter-mysql li,.mysql.geshifilter-mysql .li1{font-family:monospace;font-weight:normal;}.mysql.geshifilter-mysql .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.mysql.geshifilter-mysql .li2{font-family:monospace;font-weight:bold;font-style:italic;}.mysql.geshifilter-mysql .kw1{color:#990099;font-weight:bold;}.mysql.geshifilter-mysql .kw2{color:#990099;font-weight:bold;}.mysql.geshifilter-mysql .kw3{color:#9900FF;font-weight:bold;}.mysql.geshifilter-mysql .kw4{color:#999900;font-weight:bold;}.mysql.geshifilter-mysql .kw5{color:#999900;font-weight:bold;}.mysql.geshifilter-mysql .kw6{color:#FF9900;font-weight:bold;}.mysql.geshifilter-mysql .kw7{color:#FF9900;font-weight:bold;}.mysql.geshifilter-mysql .kw8{color:#9900FF;font-weight:bold;}.mysql.geshifilter-mysql .kw9{color:#9900FF;font-weight:bold;}.mysql.geshifilter-mysql .kw10{color:#CC0099;font-weight:bold;}.mysql.geshifilter-mysql .kw11{color:#CC0099;font-weight:bold;}.mysql.geshifilter-mysql .kw12{color:#009900;}.mysql.geshifilter-mysql .kw13{color:#000099;}.mysql.geshifilter-mysql .kw14{color:#000099;}.mysql.geshifilter-mysql .kw15{color:#000099;}.mysql.geshifilter-mysql .kw16{color:#000099;}.mysql.geshifilter-mysql .kw17{color:#000099;}.mysql.geshifilter-mysql .kw18{color:#000099;}.mysql.geshifilter-mysql .kw19{color:#000099;}.mysql.geshifilter-mysql .kw20{color:#000099;}.mysql.geshifilter-mysql .kw21{color:#000099;}.mysql.geshifilter-mysql .kw22{color:#000099;}.mysql.geshifilter-mysql .kw23{color:#000099;}.mysql.geshifilter-mysql .kw24{color:#000099;}.mysql.geshifilter-mysql .kw25{color:#000099;}.mysql.geshifilter-mysql .kw26{color:#000099;}.mysql.geshifilter-mysql .kw27{color:#00CC00;}.mysql.geshifilter-mysql .coMULTI{color:#808000;font-style:italic;}.mysql.geshifilter-mysql .co1{color:#808080;font-style:italic;}.mysql.geshifilter-mysql .co2{color:#808080;font-style:italic;}.mysql.geshifilter-mysql .es0{color:#004000;font-weight:bold;}.mysql.geshifilter-mysql .es1{color:#008080;font-weight:bold;}.mysql.geshifilter-mysql .br0{color:#FF00FF;}.mysql.geshifilter-mysql .sy1{color:#CC0099;}.mysql.geshifilter-mysql .sy2{color:#000033;}.mysql.geshifilter-mysql .st0{color:#008000;}.mysql.geshifilter-mysql .nu0{color:#008080;}.mysql.geshifilter-mysql .ln-xtra,.mysql.geshifilter-mysql li.ln-xtra,.mysql.geshifilter-mysql div.ln-xtra{background-color:#ffc;}.mysql.geshifilter-mysql span.xtra{display:block;}.perl.geshifilter-perl .de1,.perl.geshifilter-perl .de2{font-family:monospace;font-weight:normal;font-style:normal}.perl.geshifilter-perl{font-family:monospace;}.perl.geshifilter-perl .imp{font-weight:bold;color:red;}.perl.geshifilter-perl li,.perl.geshifilter-perl .li1{font-family:monospace;font-weight:normal;}.perl.geshifilter-perl .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.perl.geshifilter-perl .li2{font-family:monospace;font-weight:bold;font-style:italic;}.perl.geshifilter-perl .kw1{color:#b1b100;}.perl.geshifilter-perl .kw2{color:#000000;font-weight:bold;}.perl.geshifilter-perl .kw3{color:#000066;}.perl.geshifilter-perl .co1{color:#666666;font-style:italic;}.perl.geshifilter-perl .co2{color:#009966;font-style:italic;}.perl.geshifilter-perl .co3{color:#0000ff;}.perl.geshifilter-perl .co4{color:#cc0000;font-style:italic;}.perl.geshifilter-perl .co5{color:#0000ff;}.perl.geshifilter-perl .coMULTI{color:#666666;font-style:italic;}.perl.geshifilter-perl .es0{color:#000099;font-weight:bold;}.perl.geshifilter-perl .es_h{color:#000099;font-weight:bold;}.perl.geshifilter-perl .br0{color:#009900;}.perl.geshifilter-perl .sy0{color:#339933;}.perl.geshifilter-perl .st0{color:#ff0000;}.perl.geshifilter-perl .st_h{color:#ff0000;}.perl.geshifilter-perl .nu0{color:#cc66cc;}.perl.geshifilter-perl .me1{color:#006600;}.perl.geshifilter-perl .me2{color:#006600;}.perl.geshifilter-perl .re0{color:#0000ff;}.perl.geshifilter-perl .re4{color:#009999;}.perl.geshifilter-perl .ln-xtra,.perl.geshifilter-perl li.ln-xtra,.perl.geshifilter-perl div.ln-xtra{background-color:#ffc;}.perl.geshifilter-perl span.xtra{display:block;}.php.geshifilter-php .de1,.php.geshifilter-php .de2{font-family:monospace;font-weight:normal;font-style:normal}.php.geshifilter-php{font-family:monospace;}.php.geshifilter-php .imp{font-weight:bold;color:red;}.php.geshifilter-php li,.php.geshifilter-php .li1{font-family:monospace;font-weight:normal;}.php.geshifilter-php .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.php.geshifilter-php .li2{font-family:monospace;font-weight:bold;font-style:italic;}.php.geshifilter-php .kw1{color:#b1b100;}.php.geshifilter-php .kw2{color:#000000;font-weight:bold;}.php.geshifilter-php .kw3{color:#990000;}.php.geshifilter-php .kw4{color:#009900;font-weight:bold;}.php.geshifilter-php .co1{color:#666666;font-style:italic;}.php.geshifilter-php .co2{color:#666666;font-style:italic;}.php.geshifilter-php .co3{color:#0000cc;font-style:italic;}.php.geshifilter-php .co4{color:#009933;font-style:italic;}.php.geshifilter-php .coMULTI{color:#666666;font-style:italic;}.php.geshifilter-php .es0{color:#000099;font-weight:bold;}.php.geshifilter-php .es1{color:#000099;font-weight:bold;}.php.geshifilter-php .es2{color:#660099;font-weight:bold;}.php.geshifilter-php .es3{color:#660099;font-weight:bold;}.php.geshifilter-php .es4{color:#006699;font-weight:bold;}.php.geshifilter-php .es5{color:#006699;font-weight:bold;font-style:italic;}.php.geshifilter-php .es6{color:#009933;font-weight:bold;}.php.geshifilter-php .es_h{color:#000099;font-weight:bold;}.php.geshifilter-php .br0{color:#009900;}.php.geshifilter-php .sy0{color:#339933;}.php.geshifilter-php .sy1{color:#000000;font-weight:bold;}.php.geshifilter-php .st0{color:#0000ff;}.php.geshifilter-php .st_h{color:#0000ff;}.php.geshifilter-php .nu0{color:#cc66cc;}.php.geshifilter-php .nu8{color:#208080;}.php.geshifilter-php .nu12{color:#208080;}.php.geshifilter-php .nu19{color:#800080;}.php.geshifilter-php .me1{color:#004000;}.php.geshifilter-php .me2{color:#004000;}.php.geshifilter-php .re0{color:#000088;}.php.geshifilter-php .ln-xtra,.php.geshifilter-php li.ln-xtra,.php.geshifilter-php div.ln-xtra{background-color:#ffc;}.php.geshifilter-php span.xtra{display:block;}.python.geshifilter-python .de1,.python.geshifilter-python .de2{font-family:monospace;font-weight:normal;font-style:normal}.python.geshifilter-python{font-family:monospace;}.python.geshifilter-python .imp{font-weight:bold;color:red;}.python.geshifilter-python li,.python.geshifilter-python .li1{font-family:monospace;font-weight:normal;}.python.geshifilter-python .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.python.geshifilter-python .li2{font-family:monospace;font-weight:bold;font-style:italic;}.python.geshifilter-python .kw1{color:#ff7700;font-weight:bold;}.python.geshifilter-python .kw2{color:#008000;}.python.geshifilter-python .kw3{color:#dc143c;}.python.geshifilter-python .kw4{color:#0000cd;}.python.geshifilter-python .co1{color:#808080;font-style:italic;}.python.geshifilter-python .coMULTI{color:#808080;font-style:italic;}.python.geshifilter-python .es0{color:#000099;font-weight:bold;}.python.geshifilter-python .br0{color:black;}.python.geshifilter-python .sy0{color:#66cc66;}.python.geshifilter-python .st0{color:#483d8b;}.python.geshifilter-python .nu0{color:#ff4500;}.python.geshifilter-python .me1{color:black;}.python.geshifilter-python .ln-xtra,.python.geshifilter-python li.ln-xtra,.python.geshifilter-python div.ln-xtra{background-color:#ffc;}.python.geshifilter-python span.xtra{display:block;}.sql.geshifilter-sql .de1,.sql.geshifilter-sql .de2{font-family:monospace;font-weight:normal;font-style:normal}.sql.geshifilter-sql{font-family:monospace;}.sql.geshifilter-sql .imp{font-weight:bold;color:red;}.sql.geshifilter-sql li,.sql.geshifilter-sql .li1{font-family:monospace;font-weight:normal;}.sql.geshifilter-sql .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.sql.geshifilter-sql .li2{font-family:monospace;font-weight:bold;font-style:italic;}.sql.geshifilter-sql .kw1{color:#993333;font-weight:bold;}.sql.geshifilter-sql .co1{color:#808080;font-style:italic;}.sql.geshifilter-sql .coMULTI{color:#808080;font-style:italic;}.sql.geshifilter-sql .es0{color:#000099;font-weight:bold;}.sql.geshifilter-sql .br0{color:#66cc66;}.sql.geshifilter-sql .sy0{color:#66cc66;}.sql.geshifilter-sql .st0{color:#ff0000;}.sql.geshifilter-sql .nu0{color:#cc66cc;}.sql.geshifilter-sql .ln-xtra,.sql.geshifilter-sql li.ln-xtra,.sql.geshifilter-sql div.ln-xtra{background-color:#ffc;}.sql.geshifilter-sql span.xtra{display:block;}.xml.geshifilter-xml .de1,.xml.geshifilter-xml .de2{font-family:monospace;font-weight:normal;font-style:normal}.xml.geshifilter-xml{font-family:monospace;}.xml.geshifilter-xml .imp{font-weight:bold;color:red;}.xml.geshifilter-xml li,.xml.geshifilter-xml .li1{font-family:monospace;font-weight:normal;}.xml.geshifilter-xml .ln{width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}.xml.geshifilter-xml .li2{font-family:monospace;font-weight:bold;font-style:italic;}.xml.geshifilter-xml .es0{color:#000099;font-weight:bold;}.xml.geshifilter-xml .br0{color:#66cc66;}.xml.geshifilter-xml .sy0{color:#66cc66;}.xml.geshifilter-xml .st0{color:#ff0000;}.xml.geshifilter-xml .nu0{color:#cc66cc;}.xml.geshifilter-xml .sc-1{color:#808080;font-style:italic;}.xml.geshifilter-xml .sc0{color:#00bbdd;}.xml.geshifilter-xml .sc1{color:#ddbb00;}.xml.geshifilter-xml .sc2{color:#339933;}.xml.geshifilter-xml .sc3{color:#009900;}.xml.geshifilter-xml .re0{color:#000066;}.xml.geshifilter-xml .re1{color:#000000;font-weight:bold;}.xml.geshifilter-xml .re2{color:#000000;font-weight:bold;}.xml.geshifilter-xml .ln-xtra,.xml.geshifilter-xml li.ln-xtra,.xml.geshifilter-xml div.ln-xtra{background-color:#ffc;}.xml.geshifilter-xml span.xtra{display:block;} +span.geshifilter{display:inline;padding:0;margin:0;border:none;}div.geshifilter{display:block;padding:0.5em;margin:0.5em;border:1px solid #ccc;background-color:#f8f8f8;color:#222;line-height:1.3;overflow:auto;}div.geshifilter pre{margin:0;padding:0;line-height:1.3;}div.geshifilter ol{margin:0;padding:0 0 0 4em;list-style-position:outside;list-style-type:decimal;line-height:1.3;}div.geshifilter li{margin:0;padding:0;line-height:1.3;}div.geshifilter table,div.geshifilter tbody,div.geshifilter tr,div.geshifilter td{margin:0;padding:0;border-style:none;}div.geshifilter-title{padding:0.5ex 0.5em;margin:0.5em 0.5em -0.5em 0.5em;background-color:#ccc;} diff --git a/siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css b/siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css new file mode 100644 index 0000000..64b4175 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU/index.css @@ -0,0 +1 @@ +body,input,textarea,select{color:#000;background:none;font-family:Verdana,sans-serif;font-size:11pt;}ul.main-menu,ul.secondary-menu,#header-region,.sidebar{display:none;}body.two-sidebars,body.sidebar-first,body.sidebar-second,body{width:640px;}body.sidebar-first #center,body.sidebar-second #center,body.two-sidebars #center,body.sidebar-first #squeeze,body.sidebar-second #squeeze,body.two-sidebars #squeeze{margin:0;}#wrapper,#wrapper #container .breadcrumb,#wrapper #container #center,#wrapper #container #center .right-corner,#wrapper #container #center .right-corner .left-corner,#wrapper #container #footer,#wrapper #container #center #squeeze{position:static;left:0;padding:0;margin:0;width:auto;float:none;clear:both;background:none;}#wrapper #container #header{height:130px;}#wrapper #container #header h1,#wrapper #container #header h1 a:link,#wrapper #container #header h1 a:visited{text-shadow:none;color:#000;} diff --git a/siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css b/siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css new file mode 100644 index 0000000..4cd6f2c --- /dev/null +++ b/siarp.de/sites/siarp.de/files/css/css_xE-rWrJf-fncB6ztZfd2huxqgxu4WO-qwma6Xer30m4/index.css @@ -0,0 +1,4 @@ +#autocomplete{border:1px solid;overflow:hidden;position:absolute;z-index:100;}#autocomplete ul{list-style:none;list-style-image:none;margin:0;padding:0;}#autocomplete li{background:#fff;color:#000;cursor:default;white-space:pre;zoom:1;}html.js input.form-autocomplete{background-image:url(../../../../../misc/throbber-inactive/index.png);background-position:100% center;background-repeat:no-repeat;}html.js input.throbbing{background-image:url(../../../../../misc/throbber-active/index.gif);background-position:100% center;}html.js fieldset.collapsed{border-bottom-width:0;border-left-width:0;border-right-width:0;height:1em;}html.js fieldset.collapsed .fieldset-wrapper{display:none;}fieldset.collapsible{position:relative;}fieldset.collapsible .fieldset-legend{display:block;}.form-textarea-wrapper textarea{display:block;margin:0;width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;}.resizable-textarea .grippie{background:#eee url(../../../../../misc/grippie/index.png) no-repeat center 2px;border:1px solid #ddd;border-top-width:0;cursor:s-resize;height:9px;overflow:hidden;}body.drag{cursor:move;}.draggable a.tabledrag-handle{cursor:move;float:left;height:1.7em;margin-left:-1em;overflow:hidden;text-decoration:none;}a.tabledrag-handle:hover{text-decoration:none;}a.tabledrag-handle .handle{background:url(../../../../../misc/draggable/index.png) no-repeat 6px 9px;height:13px;margin:-0.4em 0.5em;padding:0.42em 0.5em;width:13px;}a.tabledrag-handle-hover .handle{background-position:6px -11px;}div.indentation{float:left;height:1.7em;margin:-0.4em 0.2em -0.4em -0.4em;padding:0.42em 0 0.42em 0.6em;width:20px;}div.tree-child{background:url(../../../../../misc/tree/index.png) no-repeat 11px center;}div.tree-child-last{background:url(../../../../../misc/tree-bottom/index.png) no-repeat 11px center;}div.tree-child-horizontal{background:url(../../../../../misc/tree/index.png) no-repeat -11px center;}.tabledrag-toggle-weight-wrapper{text-align:right;}table.sticky-header{background-color:#fff;margin-top:0;}.progress .bar{background-color:#fff;border:1px solid;}.progress .filled{background-color:#000;height:1.5em;width:5px;}.progress .percentage{float:right;}.ajax-progress{display:inline-block;}.ajax-progress .throbber{background:transparent url(../../../../../misc/throbber-active/index.gif) no-repeat 0px center;float:left;height:15px;margin:2px;width:15px;}.ajax-progress .message{padding-left:20px;}tr .ajax-progress .throbber{margin:0 2px;}.ajax-progress-bar{width:16em;}.container-inline div,.container-inline label{display:inline;}.container-inline .fieldset-wrapper{display:block;}.nowrap{white-space:nowrap;}html.js .js-hide{display:none;}.element-hidden{display:none;}.element-invisible{position:absolute !important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);overflow:hidden;height:1px;}.element-invisible.element-focusable:active,.element-invisible.element-focusable:focus{position:static !important;clip:auto;overflow:visible;height:auto;}.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}* html .clearfix{height:1%;}*:first-child + html .clearfix{min-height:1%;} +ul.menu{border:none;list-style:none;text-align:left;}ul.menu li{margin:0 0 0 0.5em;}ul li.expanded{list-style-image:url(../../../../../misc/menu-expanded/index.png);list-style-type:circle;}ul li.collapsed{list-style-image:url(../../../../../misc/menu-collapsed/index.png);list-style-type:disc;}ul li.leaf{list-style-image:url(../../../../../misc/menu-leaf/index.png);list-style-type:square;}li.expanded,li.collapsed,li.leaf{padding:0.2em 0.5em 0 0;margin:0;}li a.active{color:#000;}td.menu-disabled{background:#ccc;}ul.inline,ul.links.inline{display:inline;padding-left:0;}ul.inline li{display:inline;list-style-type:none;padding:0 0.5em;}.breadcrumb{padding-bottom:0.5em;}ul.primary{border-bottom:1px solid #bbb;border-collapse:collapse;height:auto;line-height:normal;list-style:none;margin:5px;padding:0 0 0 1em;white-space:nowrap;}ul.primary li{display:inline;}ul.primary li a{background-color:#ddd;border-color:#bbb;border-style:solid solid none solid;border-width:1px;height:auto;margin-right:0.5em;padding:0 1em;text-decoration:none;}ul.primary li.active a{background-color:#fff;border:1px solid #bbb;border-bottom:1px solid #fff;}ul.primary li a:hover{background-color:#eee;border-color:#ccc;border-bottom-color:#eee;}ul.secondary{border-bottom:1px solid #bbb;padding:0.5em 1em;margin:5px;}ul.secondary li{border-right:1px solid #ccc;display:inline;padding:0 1em;}ul.secondary a{padding:0;text-decoration:none;}ul.secondary a.active{border-bottom:4px solid #999;} +div.messages{background-position:8px 8px;background-repeat:no-repeat;border:1px solid;margin:6px 0;padding:10px 10px 10px 50px;}div.status{background-image:url(../../../../../misc/message-24-ok/index.png);border-color:#be7;}div.status,.ok{color:#234600;}div.status,table tr.ok{background-color:#f8fff0;}div.warning{background-image:url(../../../../../misc/message-24-warning/index.png);border-color:#ed5;}div.warning,.warning{color:#840;}div.warning,table tr.warning{background-color:#fffce5;}div.error{background-image:url(../../../../../misc/message-24-error/index.png);border-color:#ed541d;}div.error,.error{color:#8c2e0b;}div.error,table tr.error{background-color:#fef5f1;}div.error p.error{color:#333;}div.messages ul{margin:0 0 0 1em;padding:0;}div.messages ul li{list-style-image:none;} +fieldset{margin-bottom:1em;padding:0.5em;}form{margin:0;padding:0;}hr{border:1px solid gray;height:1px;}img{border:0;}table{border-collapse:collapse;}th{border-bottom:3px solid #ccc;padding-right:1em;text-align:left;}tbody{border-top:1px solid #ccc;}tr.even,tr.odd{background-color:#eee;border-bottom:1px solid #ccc;padding:0.1em 0.6em;}th.active img{display:inline;}td.active{background-color:#ddd;}.item-list .title{font-weight:bold;}.item-list ul{margin:0 0 0.75em 0;padding:0;}.item-list ul li{margin:0 0 0.25em 1.5em;padding:0;}.form-item,.form-actions{margin-top:1em;margin-bottom:1em;}tr.odd .form-item,tr.even .form-item{margin-top:0;margin-bottom:0;white-space:nowrap;}.form-item .description{font-size:0.85em;}label{display:block;font-weight:bold;}label.option{display:inline;font-weight:normal;}.form-checkboxes .form-item,.form-radios .form-item{margin-top:0.4em;margin-bottom:0.4em;}.form-type-radio .description,.form-type-checkbox .description{margin-left:2.4em;}input.form-checkbox,input.form-radio{vertical-align:middle;}.marker,.form-required{color:#f00;}.form-item input.error,.form-item textarea.error,.form-item select.error{border:2px solid red;}.container-inline .form-actions,.container-inline.form-actions{margin-top:0;margin-bottom:0;}.more-link{text-align:right;}.more-help-link{text-align:right;}.more-help-link a{background:url(../../../../../misc/help/index.png) 0 50% no-repeat;padding:1px 0 1px 20px;}.item-list .pager{clear:both;text-align:center;}.item-list .pager li{background-image:none;display:inline;list-style-type:none;padding:0.5em;}.pager-current{font-weight:bold;}#autocomplete li.selected{background:#0072b9;color:#fff;}html.js fieldset.collapsible .fieldset-legend{background:url(../../../../../misc/menu-expanded/index.png) 5px 65% no-repeat;padding-left:15px;}html.js fieldset.collapsed .fieldset-legend{background-image:url(../../../../../misc/menu-collapsed/index.png);background-position:5px 50%;}.fieldset-legend span.summary{color:#999;font-size:0.9em;margin-left:0.5em;}tr.drag{background-color:#fffff0;}tr.drag-previous{background-color:#ffd;}.tabledrag-toggle-weight{font-size:0.9em;}body div.tabledrag-changed-warning{margin-bottom:0.5em;}tr.selected td{background:#ffc;}td.checkbox,th.checkbox{text-align:center;}.progress{font-weight:bold;}.progress .bar{background:#ccc;border-color:#666;margin:0 0.2em;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}.progress .filled{background:#0072b9 url(../../../../../misc/progress/index.gif);} diff --git a/siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css b/siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css new file mode 100644 index 0000000..ac1da0c --- /dev/null +++ b/siarp.de/sites/siarp.de/files/css/css_xPIRNNJGw8EiKyuE5b-xAtWWTQ8U1_huTr4xL09Dq2A/index.css @@ -0,0 +1 @@ +body{margin:0;padding:0;background:#f5f6f7;font:76%/170% Verdana,sans-serif;color:#707070;}input{font:1em/100% Verdana,sans-serif;color:#707070;}textarea,select{font:1em/160% Verdana,sans-serif;color:#707070;}h1,h2,h3,h4,h5,h6{margin:0;padding:0;font-weight:normal;font-family:Helvetica,Arial,sans-serif;}h1{font-size:170%;}h2,#center h1{font-size:160%;line-height:130%;}h3{font-size:140%;}h4{font-size:130%;}h5{font-size:120%;}h6{font-size:110%;}quote,code,fieldset{margin:.5em 0;}code,pre,kbd{font-size:115%;}p{margin:0.6em 0 1.2em;padding:0;}a:link,a:visited{color:#3f728d;text-decoration:none;}a:hover{color:#216082;text-decoration:underline;}a:active,a.active{color:#858e93;}hr{margin:0;padding:0;border:none;height:1px;background:#a4a7aa;}ul,.block ul,ol{margin:0.5em 0 1em;padding:0 0 0 1.5em;}ul,ul li.leaf{list-style-image:url(../../color/garland-596ce30b/menu-leaf/index.gif);}ol{list-style-image:none;}ul.menu,.item-list ul{margin:0.35em 0 0 -0.5em;}ol li,ul li,ul.menu li,.item-list ul li,li.leaf{margin:0.15em 0 0.15em .5em;padding-bottom:.1em;}ul li.expanded{list-style-image:url(../../color/garland-596ce30b/menu-expanded/index.gif);}ul li.collapsed{list-style-image:url(../../color/garland-596ce30b/menu-collapsed/index.gif);}ul li.leaf a,ul li.expanded a,ul li.collapsed a{display:block;}ul.inline li{background:none;margin:0;padding:0 1em 0 0;}ol.task-list{margin-left:0;list-style-type:none;list-style-image:none;}ol.task-list li{padding:0.5em 1em 0.5em 2em;}ol.task-list li.active{background:transparent url(../../../../../themes/garland/images/task-list/index.png) no-repeat 3px 50%;}ol.task-list li.done{color:#44c044;background:transparent url(../../../../../misc/watchdog-ok/index.png) no-repeat 0px 50%;}ol.task-list li.active{margin-right:1em;}fieldset ul.clearfix li{margin:0;padding:0;background-image:none;}dl{margin:0.5em 0 1em 1.5em;}dl dt{}dl dd{margin:0 0 .5em 1.5em;}img,a img{border:none;}table{margin:1em 0;width:100%;}thead th{border-bottom:2px solid #e7eaee;color:#707070;font-weight:bold;}th a:link,th a:visited{color:#979797;}td,th{padding:.3em .5em;}tr.even,tr.odd,tbody th{border:solid #e7eaee;border-width:1px 0;}tr.odd,tr.info{background-color:#f5f6f7;}tr.even{background-color:#ffffff;}tr.drag{background-color:#e9f0cb;}tr.drag-previous{background-color:#f4f7e5;}tr.odd td.active{background-color:#edeef0;}tr.even td.active{background-color:#f1f2f3;}td.region-title,td.module,td.container,td.category{border-top:1.5em solid #ffffff;border-bottom:1px solid #d6dce5;background-color:#e8eaed;color:#617091;font-weight:bold;}tr:first-child td.region-title,tr:first-child td.module,tr:first-child td.container,tr:first-child td.category{border-top-width:0;}span.form-required{color:#feb517;}.submitted,.description,.vertical-tab-button .summary{font-size:0.92em;color:#a2a2a2;}.description .more-help-link{font-size:0.92em;}.description{line-height:150%;margin-bottom:0.75em;color:#a2a2a2;}.preview{margin:.75em 0 .75em;padding:.5em 1em;}.form-checkboxes,.form-radios,.form-checkboxes .form-item,.form-radios .form-item{margin:0.25em 0;}#center form{margin-bottom:2em;}.form-actions{margin:2em 0 1em;}.form-button,.form-submit{margin:0 0.5em 0 0;}#skip-link{left:50%;margin-left:-5.25em;margin-top:0;position:absolute;width:auto;z-index:1000;}#skip-link a,#skip-link a:link,#skip-link a:visited{background:#444444;background:rgba(0,0,0,0.6);color:#ffffff;display:block;font-size:0.94em;line-height:1.7;margin-top:1px;padding:2px 10px;text-decoration:none;-khtml-border-radius:0 0 2px 2px;-moz-border-radius:0 0 2px 2px;-webkit-border-bottom-left-radius:2px;-webkit-border-bottom-right-radius:2px;-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:0;border-radius:0 0 2px 2px;}#skip-link a:hover,#skip-link a:active,#skip-link a:focus{outline:0;}.region-header{min-height:1em;background:#e7e9ed url(../../color/garland-596ce30b/bg-navigation/index.png) repeat-x 50% 100%;}.region-header .block{display:block;margin:0 1em;}.region-header .block-region{display:block;margin:0 0.5em 1em;padding:0.5em;position:relative;top:0.5em;}.region-header *{display:inline;line-height:1.5em;margin-top:0;margin-bottom:0;}.region-header script{display:none;}.region-header p,.region-header img{margin-top:0.5em;}.region-header h2{margin:0 1em 0 0;}.region-header h3,.region-header label,.region-header li{margin:0 1em;padding:0;background:none;}#wrapper{background:#f5f6f7 url(../../color/garland-596ce30b/body/index.png) repeat-x 50% 0;}#wrapper #container{width:560px;margin:0 auto;padding:0 20px;}body.one-sidebar #wrapper #container{width:770px;}body.two-sidebars #wrapper #container{width:980px;}body.fluid-width #wrapper #container{width:auto;max-width:1270px;}#wrapper #container #header{height:80px;}#wrapper #container #header #logo-floater{position:absolute;}#branding,#branding a:link,#branding a:visited{line-height:120px;position:relative;z-index:2;white-space:nowrap;}#branding span{font-weight:bold;}#branding img{padding-top:14px;padding-right:20px;float:left;}body.two-sidebars{min-width:980px;}body.sidebar-first,body.sidebar-second{min-width:780px;}#wrapper #container #center{float:left;width:100%;}body.sidebar-first #center{margin-left:-210px;}body.sidebar-second #center{margin-right:-210px;}body.two-sidebars #center{margin:0 -210px;}body.sidebar-first #squeeze{margin-left:210px;}body.sidebar-second #squeeze{margin-right:210px;}body.two-sidebars #squeeze{margin:0 210px;}#wrapper #container .sidebar{margin:60px 0 5em;width:210px;float:left;z-index:2;position:relative;}#wrapper #container .sidebar .block{margin:0 0 1.5em 0;}#sidebar-first .block{padding:0 15px 0 0;}#sidebar-second .block{padding:0 0 0 15px;}.block .content{margin:0.5em 0;}#sidebar-first .block-region{margin:0 15px 0 0px;}#sidebar-second .block-region{margin:0 0px 0 15px;}.block-region{padding:1em;background:transparent;border:2px dashed #d6dce5;text-align:center;font-size:1.3em;}#wrapper #container #center #squeeze{background:#ffffff url(../../color/garland-596ce30b/bg-content/index.png) repeat-x 50% 0;position:relative;}#wrapper #container #center .right-corner{background:transparent url(../../color/garland-596ce30b/bg-content-right/index.png) no-repeat 100% 0;position:relative;left:10px;}#wrapper #container #center .right-corner .left-corner{padding:60px 25px 5em 35px;background:transparent url(../../color/garland-596ce30b/bg-content-left/index.png) no-repeat 0 0;margin-left:-10px;position:relative;left:-10px;min-height:400px;}#wrapper #container .region-footer{float:none;clear:both;text-align:center;margin:4em 0 -3em;color:#a2a2a2;}#wrapper #container .breadcrumb{position:absolute;top:15px;left:35px;z-index:3;}body.sidebar-first .region-footer{margin-left:-210px;}body.sidebar-second .region-footer{margin-right:-210px;}body.two-sidebars .region-footer{margin:0 -210px;}div#branding{font-family:Helvetica,Arial,sans-serif;}div#branding strong{font-weight:normal;}#branding,#branding a:link,#branding a:visited{color:#ffffff;text-shadow:#717c9b 0px 1px 3px;font-size:1.5em;}#branding a:hover{text-decoration:none;}#wrapper #container .breadcrumb{font-size:0.92em;}#wrapper #container .breadcrumb,#wrapper #container .breadcrumb a{color:#7c99ae;}#highlighted{padding:1em;background-color:#ffffff;border:1px solid #efeff7;margin-bottom:2em;}#overlay #overlay-tabs li a{background:#e2e8ec;color:#171717;}#overlay #overlay-tabs li a:hover,#overlay #overlay-tabs li a:focus{background:#ffffff;}#overlay #overlay-tabs li.active a{background:url(../../color/garland-596ce30b/body/index.png) repeat-x scroll 50% -58px #f1f4f5;color:#ffffff;}#overlay-content{padding:1px;}#overlay-content #header{display:none;}#overlay-content #wrapper{background-position:50% -80px;}ul.main-menu{margin:0;padding:0;float:right;position:relative;z-index:4;}ul.main-menu li{margin:0;padding:0;float:left;background-image:none;}ul.main-menu li a,ul.main-menu li a:link,ul.main-menu li a:visited{display:block;margin:0 1em;padding:.75em 0 0;color:#ffffff;background:transparent url(../../color/garland-596ce30b/bg-navigation-item/index.png) no-repeat 50% 0;}ul.main-menu li a:hover,ul.main-menu li a.active{color:#ffffff;background:transparent url(../../color/garland-596ce30b/bg-navigation-item-hover/index.png) no-repeat 50% 0;}ul.secondary-menu{margin:0;padding:18px 0 0;float:right;clear:right;position:relative;z-index:4;}ul.secondary-menu li{margin:0;padding:0;float:left;background-image:none;}ul.secondary-menu li a,ul.secondary-menu li a:link,ul.secondary-menu li a:visited{display:block;margin:0 1em;padding:.75em 0 0;color:#d9e1e5;background:transparent;}ul.secondary-menu li a:hover,ul.secondary-menu li a.active{color:#d9e1e5;background:transparent;}ul.primary,ul.primary li,ul.secondary,ul.secondary li{border:0;background:none;margin:0;padding:0;}#tabs-wrapper{margin:0 -26px 1em;padding:0 26px;border-bottom:1px solid #f2f2f2;position:relative;}ul.primary{padding:0.5em 0 10px;float:left;}ul.secondary{clear:both;text-align:left;border-bottom:1px solid #f2f2f2;margin:-0.2em -26px 1em;padding:0 26px 0.6em;}h1.with-tabs{float:left;margin:0 2em 0 0;padding:0;}ul.primary li a,ul.primary li.active a,ul.primary li a:hover,ul.primary li a:visited,ul.secondary li a,ul.secondary li.active a,ul.secondary li a:hover,ul.secondary li a:visited{border:0;background:transparent;padding:4px 1em;margin:0 0 0 1px;height:auto;text-decoration:none;position:relative;top:-1px;display:inline-block;}ul.primary li.active a,ul.primary li.active a:link,ul.primary li.active a:visited,ul.primary li a:hover,ul.secondary li.active a,ul.secondary li.active a:link,ul.secondary li.active a:visited,ul.secondary li a:hover{background:url(../../color/garland-596ce30b/bg-tab/index.png) repeat-x 0 50%;color:#ffffff;}ul.primary li.active a,ul.secondary li.active a{font-weight:bold;}.node{border-bottom:1px solid #f2f2f2;margin:0 -16px 1.5em;padding:1.5em 16px;}ul.links li,ul.inline li{margin-left:0;margin-right:0;padding-left:0;padding-right:1em;background-image:none;}.node .links,.comment .links{text-align:left;padding-left:0;}.user-picture,.comment .submitted{float:right;clear:right;padding-left:1em;}.new{color:#feb517;font-size:0.92em;font-weight:bold;float:right;}.preview .node,.preview .comment,.node-sticky{margin:0;padding:0.5em 0;border:0;background:0;}.node-sticky{padding:1em;background-color:#ffffff;border:1px solid #efeff7;margin-bottom:2em;}#comments{position:relative;top:-1px;border-bottom:1px solid #f2f2f2;margin:1.5em -25px 0;padding:0 25px;}#comments h2.comments{margin:0 -25px;padding:.5em 25px;background:#ffffff url(../../color/garland-596ce30b/gradient-inner/index.png) repeat-x 0 0;}.comment{margin:0 -25px;padding:1.5em 25px 1.5em;border-top:1px solid #f2f2f2;}.indented{margin-left:25px;}.comment h3 a.active{color:#707070;}.node .content,.comment .content{margin:0.6em 0;}#aggregator{margin-top:1em;}#aggregator .feed-item-title{font-size:160%;line-height:130%;}#aggregator .feed-item{border-bottom:1px solid #f2f2f2;margin:-1.5em -31px 1.75em;padding:1.5em 31px;}#aggregator .feed-item-categories{font-size:0.92em;}#aggregator .feed-item-meta{font-size:0.92em;color:#a2a2a2;}#palette .form-item{border:1px solid #ffffff;}#palette .item-selected{background:#ffffff url(../../color/garland-596ce30b/gradient-inner/index.png) repeat-x 0 0;border:1px solid #eaecef;}tr.odd td.menu-disabled{background-color:#f5f6f7;}tr.even td.menu-disabled{background-color:#ffffff;}.poll .bar{background:#ffffff url(../../color/garland-596ce30b/bg-bar-white/index.png) repeat-x 0 0;border:solid #f3f3f3;border-width:0 1px 1px;}.poll .bar .foreground{background:#b5b6b9 url(../../color/garland-596ce30b/bg-bar/index.png) repeat-x 0 100%;}.poll .percent{font-size:.9em;}#autocomplete li{cursor:default;padding:2px;margin:0;}fieldset{margin:1em 0;padding:1em;border:1px solid #eaecef;background:#ffffff url(../../color/garland-596ce30b/gradient-inner/index.png) repeat-x 0 0;}*:first-child+html fieldset{padding:0 1em 1em;background-position:0 .75em;background-color:transparent;}*:first-child+html .text-format-wrapper .filter-wrapper{padding:1.5em 0 1.5em;background-position:0 0;}*:first-child+html fieldset.filter-wrapper,*:first-child+html fieldset.vertical-tabs-pane{background-position:0 0;}*:first-child+html fieldset .fieldset-wrapper .fieldset-description{padding-top:1em;}html.js fieldset.collapsed{background:transparent;padding-top:0;padding-bottom:.6em;}html.js fieldset.collapsible .fieldset-legend{padding-left:2em;background:url(../../color/garland-596ce30b/menu-expanded/index.gif) no-repeat 0% 50%;}html.js fieldset.collapsed .fieldset-legend{background:url(../../color/garland-596ce30b/menu-collapsed/index.gif) no-repeat 0% 50%;}.fieldset-legend span.summary{color:#a2a2a2;}div.vertical-tabs{border-color:#eaecef;}div.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane{padding:0.5em 1em;}div.vertical-tabs ul.vertical-tabs-list{border-color:#eaecef;}div.vertical-tabs ul.vertical-tabs-list li{background-color:#f5f6f7;border-color:#eaecef;}div.vertical-tabs ul.vertical-tabs-list li strong{font-weight:normal;}div.vertical-tabs ul.vertical-tabs-list li.selected strong{font-weight:bold;}div.vertical-tabs ul.vertical-tabs-list li.selected small{color:#a2a2a2;}div.vertical-tabs ul.vertical-tabs-list li.selected{background:#ffffff repeat-x 0 0;}div.vertical-tabs ul.vertical-tabs-list li.selected.first{background-image:url(../../color/garland-596ce30b/gradient-inner/index.png);}div.vertical-tabs ul.vertical-tabs-list li.selected a strong{color:#707070;}#block-node-syndicate h2{float:left;padding-right:20px;}#block-node-syndicate img,.feed-icon{float:right;padding-top:4px;}#block-node-syndicate .content{clear:right;}#user-login-form{text-align:center;}#user-login-form ul{text-align:left;}#user-login .openid-links{padding:0;}#user-login-form .openid-links{padding-left:0.5em;}#user-login-form .openid-links li.user-link{padding-left:1em;}.profile{margin-top:1.5em;}.profile h3{border-bottom:0;margin-bottom:1em;}.profile dl{margin:0;}.profile dt{font-weight:normal;color:#a2a2a2;font-size:0.92em;line-height:1.3em;margin-top:1.4em;margin-bottom:0.45em;}.profile dd{margin-bottom:1.6em;}div.admin-panel,div.admin-panel .description,div.admin-panel .body,div.admin,div.admin .left,div.admin .right,div.admin .expert-link,div.item-list,.menu{margin:0;padding:0;}div.admin .left{float:left;width:48%;}div.admin .right{float:right;width:48%;}div.admin-panel{background:#ffffff url(../../color/garland-596ce30b/gradient-inner/index.png) repeat-x 0 0;padding:1em 1em 1.5em;}div.admin-panel .description{margin-bottom:1.5em;}div.admin-panel dl{margin:0;}div.admin-panel dd{color:#a2a2a2;font-size:0.92em;line-height:1.3em;margin-top:-.2em;margin-bottom:.65em;}table.system-status-report th{border-color:#e7eaee;}#autocomplete li.selected,tr.selected td,tr.selected td.active{background:#3f728d;color:#ffffff;}tr.selected td a:link,tr.selected td a:visited,tr.selected td a:active{color:#dde5e9;}tr.taxonomy-term-preview{opacity:0.5;}tr.taxonomy-term-divider-top{border-bottom:none;}tr.taxonomy-term-divider-bottom{border-top:1px dotted #d6d6d6;}.theme-selector h3{margin:10px 0;}.theme-selector .operations li{list-style-image:none;}.preview{background-color:#fcfce8;border:1px solid #e5e58f;}.form-item input.error,.form-item textarea.error{border:1px solid #c52020;color:#363636;}tr.dblog-user{background-color:#fcf9e5;}tr.dblog-user td.active{background-color:#fbf5cf;}tr.dblog-content{background-color:#fefefe;}tr.dblog-content td.active{background-color:#f5f5f5;}tr.dblog-warning{background-color:#fdf5e6;}tr.dblog-warning td.active{background-color:#fdf2de;}tr.dblog-error{background-color:#fbe4e4;}tr.dblog-error td.active{background-color:#fbdbdb;}tr.dblog-page-not-found,tr.dblog-access-denied{background:#d7ffd7;}tr.dblog-page-not-found td.active,tr.dblog-access-denied td.active{background:#c7eec7;}table.system-status-report tr.error,table.system-status-report tr.error th{background-color:#fcc;border-color:#ebb;color:#200;}table.system-status-report tr.warning,table.system-status-report tr.warning th{background-color:#ffd;border-color:#eeb;}table.system-status-report tr.ok,table.system-status-report tr.ok th{background-color:#dfd;border-color:#beb;} diff --git a/siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA/index.js b/siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA/index.js new file mode 100644 index 0000000..51cbe11 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/js/js_VaTlC5jNdxR2e4HzWsuiV1jhDftON6pzITcrr9IQmXA/index.js @@ -0,0 +1,134 @@ +(function ($) { + +/** + * Attaches sticky table headers. + */ +Drupal.behaviors.tableHeader = { + attach: function (context, settings) { + if (!$.support.positionFixed) { + return; + } + + $('table.sticky-enabled', context).once('tableheader', function () { + $(this).data("drupal-tableheader", new Drupal.tableHeader(this)); + }); + } +}; + +/** + * Constructor for the tableHeader object. Provides sticky table headers. + * + * @param table + * DOM object for the table to add a sticky header to. + */ +Drupal.tableHeader = function (table) { + var self = this; + + this.originalTable = $(table); + this.originalHeader = $(table).children('thead'); + this.originalHeaderCells = this.originalHeader.find('> tr > th'); + this.displayWeight = null; + + // React to columns change to avoid making checks in the scroll callback. + this.originalTable.bind('columnschange', function (e, display) { + // This will force header size to be calculated on scroll. + self.widthCalculated = (self.displayWeight !== null && self.displayWeight === display); + self.displayWeight = display; + }); + + // Clone the table header so it inherits original jQuery properties. Hide + // the table to avoid a flash of the header clone upon page load. + this.stickyTable = $('') + .insertBefore(this.originalTable) + .css({ position: 'fixed', top: '0px' }); + this.stickyHeader = this.originalHeader.clone(true) + .hide() + .appendTo(this.stickyTable); + this.stickyHeaderCells = this.stickyHeader.find('> tr > th'); + + this.originalTable.addClass('sticky-table'); + $(window) + .bind('scroll.drupal-tableheader', $.proxy(this, 'eventhandlerRecalculateStickyHeader')) + .bind('resize.drupal-tableheader', { calculateWidth: true }, $.proxy(this, 'eventhandlerRecalculateStickyHeader')) + // Make sure the anchor being scrolled into view is not hidden beneath the + // sticky table header. Adjust the scrollTop if it does. + .bind('drupalDisplaceAnchor.drupal-tableheader', function () { + window.scrollBy(0, -self.stickyTable.outerHeight()); + }) + // Make sure the element being focused is not hidden beneath the sticky + // table header. Adjust the scrollTop if it does. + .bind('drupalDisplaceFocus.drupal-tableheader', function (event) { + if (self.stickyVisible && event.clientY < (self.stickyOffsetTop + self.stickyTable.outerHeight()) && event.$target.closest('sticky-header').length === 0) { + window.scrollBy(0, -self.stickyTable.outerHeight()); + } + }) + .triggerHandler('resize.drupal-tableheader'); + + // We hid the header to avoid it showing up erroneously on page load; + // we need to unhide it now so that it will show up when expected. + this.stickyHeader.show(); +}; + +/** + * Event handler: recalculates position of the sticky table header. + * + * @param event + * Event being triggered. + */ +Drupal.tableHeader.prototype.eventhandlerRecalculateStickyHeader = function (event) { + var self = this; + var calculateWidth = event.data && event.data.calculateWidth; + + // Reset top position of sticky table headers to the current top offset. + this.stickyOffsetTop = Drupal.settings.tableHeaderOffset ? eval(Drupal.settings.tableHeaderOffset + '()') : 0; + this.stickyTable.css('top', this.stickyOffsetTop + 'px'); + + // Save positioning data. + var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight; + if (calculateWidth || this.viewHeight !== viewHeight) { + this.viewHeight = viewHeight; + this.vPosition = this.originalTable.offset().top - 4 - this.stickyOffsetTop; + this.hPosition = this.originalTable.offset().left; + this.vLength = this.originalTable[0].clientHeight - 100; + calculateWidth = true; + } + + // Track horizontal positioning relative to the viewport and set visibility. + var hScroll = document.documentElement.scrollLeft || document.body.scrollLeft; + var vOffset = (document.documentElement.scrollTop || document.body.scrollTop) - this.vPosition; + this.stickyVisible = vOffset > 0 && vOffset < this.vLength; + this.stickyTable.css({ left: (-hScroll + this.hPosition) + 'px', visibility: this.stickyVisible ? 'visible' : 'hidden' }); + + // Only perform expensive calculations if the sticky header is actually + // visible or when forced. + if (this.stickyVisible && (calculateWidth || !this.widthCalculated)) { + this.widthCalculated = true; + var $that = null; + var $stickyCell = null; + var display = null; + var cellWidth = null; + // Resize header and its cell widths. + // Only apply width to visible table cells. This prevents the header from + // displaying incorrectly when the sticky header is no longer visible. + for (var i = 0, il = this.originalHeaderCells.length; i < il; i += 1) { + $that = $(this.originalHeaderCells[i]); + $stickyCell = this.stickyHeaderCells.eq($that.index()); + display = $that.css('display'); + if (display !== 'none') { + cellWidth = $that.css('width'); + // Exception for IE7. + if (cellWidth === 'auto') { + cellWidth = $that[0].clientWidth + 'px'; + } + $stickyCell.css({'width': cellWidth, 'display': display}); + } + else { + $stickyCell.css('display', 'none'); + } + } + this.stickyTable.css('width', this.originalTable.outerWidth()); + } +}; + +})(jQuery); +; diff --git a/siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM/index.js b/siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM/index.js new file mode 100644 index 0000000..898c118 --- /dev/null +++ b/siarp.de/sites/siarp.de/files/js/js_qikmINIYTWe4jcTUn8cKiMr8bmSDiZB9LQqvceZ6wlM/index.js @@ -0,0 +1,977 @@ + +/*! + * jQuery JavaScript Library v1.4.4 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Nov 11 19:04:53 2010 -0500 + */ +(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h= +h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;kd)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La, +"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this, +e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a, +"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+ +a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/, +C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j, +s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this, +j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length}, +toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j=== +-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false; +if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload", +b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&& +!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&& +l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H
a";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"), +k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false, +scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent= +false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom= +1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="
";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="
t
";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display= +"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h= +c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando); +else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one"; +if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true}, +attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&& +b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0}; +c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem, +arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid= +d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+ +c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType=== +8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k=== +"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+ +d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired= +B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type=== +"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]=== +0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); +(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3]; +break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr, +q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h= +l;g.sort(w);if(h)for(var i=1;i0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n, +m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== +true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== +g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return in[3]-0},nth:function(g,i,n){return n[3]- +0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== +i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]]; +if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m, +g);else if(typeof g.length==="number")for(var p=g.length;n";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g); +n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&& +function(){var g=k,i=t.createElement("div");i.innerHTML="

";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F|| +p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g= +t.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition? +function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n0)for(var h=d;h0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h= +h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context): +c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a, +2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a, +b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&& +e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/\s]+\/)>/g,P={option:[1, +""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null; +else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1>");try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append", +prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument|| +b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]===""&&!x?r.childNodes:[];for(o=k.length- +1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script")))); +d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i, +jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true, +zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b), +h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b); +if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f= +d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left; +e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/)<[^<]*)*<\/script>/gi, +ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b=== +"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("
").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&& +!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})}, +getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html", +script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data|| +!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache= +false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset; +A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type", +b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&& +c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d|| +c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]= +encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess", +[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"), +e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}}); +if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show", +3),a,b,d);else{d=0;for(var e=this.length;d=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b, +d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a* +Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)} +var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true; +this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide|| +this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a= +c.timers,b=0;b-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a, +e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&& +c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase(); +c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+ +b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window); +; +/** + * For jQuery versions less than 3.4.0, this replaces the jQuery.extend + * function with the one from jQuery 3.4.0, slightly modified (documented + * below) to be compatible with older jQuery versions and browsers. + * + * This provides the Object.prototype pollution vulnerability fix to Drupal + * installations running older jQuery versions, including the versions shipped + * with Drupal core and https://www.drupal.org/project/jquery_update. + * + * @see https://github.com/jquery/jquery/pull/4333 + */ + +(function (jQuery) { + +// Do not override jQuery.extend() if the jQuery version is already >=3.4.0. +var versionParts = jQuery.fn.jquery.split('.'); +var majorVersion = parseInt(versionParts[0]); +var minorVersion = parseInt(versionParts[1]); +var patchVersion = parseInt(versionParts[2]); +var isPreReleaseVersion = (patchVersion.toString() !== versionParts[2]); +if ( + (majorVersion > 3) || + (majorVersion === 3 && minorVersion > 4) || + (majorVersion === 3 && minorVersion === 4 && patchVersion > 0) || + (majorVersion === 3 && minorVersion === 4 && patchVersion === 0 && !isPreReleaseVersion) +) { + return; +} + +/** + * This is almost verbatim copied from jQuery 3.4.0. + * + * Only two minor changes have been made: + * - The call to isFunction() is changed to jQuery.isFunction(). + * - The two calls to Array.isArray() is changed to jQuery.isArray(). + * + * The above two changes ensure compatibility with all older jQuery versions + * (1.4.4 - 3.3.1) and older browser versions (e.g., IE8). + */ +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !jQuery.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +})(jQuery); +; + +/** + * jQuery Once Plugin v1.2 + * http://plugins.jquery.com/project/once + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ + +(function ($) { + var cache = {}, uuid = 0; + + /** + * Filters elements by whether they have not yet been processed. + * + * @param id + * (Optional) If this is a string, then it will be used as the CSS class + * name that is applied to the elements for determining whether it has + * already been processed. The elements will get a class in the form of + * "id-processed". + * + * If the id parameter is a function, it will be passed off to the fn + * parameter and the id will become a unique identifier, represented as a + * number. + * + * When the id is neither a string or a function, it becomes a unique + * identifier, depicted as a number. The element's class will then be + * represented in the form of "jquery-once-#-processed". + * + * Take note that the id must be valid for usage as an element's class name. + * @param fn + * (Optional) If given, this function will be called for each element that + * has not yet been processed. The function's return value follows the same + * logic as $.each(). Returning true will continue to the next matched + * element in the set, while returning false will entirely break the + * iteration. + */ + $.fn.once = function (id, fn) { + if (typeof id != 'string') { + // Generate a numeric ID if the id passed can't be used as a CSS class. + if (!(id in cache)) { + cache[id] = ++uuid; + } + // When the fn parameter is not passed, we interpret it from the id. + if (!fn) { + fn = id; + } + id = 'jquery-once-' + cache[id]; + } + // Remove elements from the set that have already been processed. + var name = id + '-processed'; + var elements = this.not('.' + name).addClass(name); + + return $.isFunction(fn) ? elements.each(fn) : elements; + }; + + /** + * Filters elements that have been processed once already. + * + * @param id + * A required string representing the name of the class which should be used + * when filtering the elements. This only filters elements that have already + * been processed by the once function. The id should be the same id that + * was originally passed to the once() function. + * @param fn + * (Optional) If given, this function will be called for each element that + * has not yet been processed. The function's return value follows the same + * logic as $.each(). Returning true will continue to the next matched + * element in the set, while returning false will entirely break the + * iteration. + */ + $.fn.removeOnce = function (id, fn) { + var name = id + '-processed'; + var elements = this.filter('.' + name).removeClass(name); + + return $.isFunction(fn) ? elements.each(fn) : elements; + }; +})(jQuery); +; + +var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'locale': {} }; + +// Allow other JavaScript libraries to use $. +jQuery.noConflict(); + +(function ($) { + +/** + * Override jQuery.fn.init to guard against XSS attacks. + * + * See http://bugs.jquery.com/ticket/9521 + */ +var jquery_init = $.fn.init; +$.fn.init = function (selector, context, rootjQuery) { + // If the string contains a "#" before a "<", treat it as invalid HTML. + if (selector && typeof selector === 'string') { + var hash_position = selector.indexOf('#'); + if (hash_position >= 0) { + var bracket_position = selector.indexOf('<'); + if (bracket_position > hash_position) { + throw 'Syntax error, unrecognized expression: ' + selector; + } + } + } + return jquery_init.call(this, selector, context, rootjQuery); +}; +$.fn.init.prototype = jquery_init.prototype; + +/** + * Pre-filter Ajax requests to guard against XSS attacks. + * + * See https://github.com/jquery/jquery/issues/2432 + */ +if ($.ajaxPrefilter) { + // For newer versions of jQuery, use an Ajax prefilter to prevent + // auto-executing script tags from untrusted domains. This is similar to the + // fix that is built in to jQuery 3.0 and higher. + $.ajaxPrefilter(function (s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); +} +else if ($.httpData) { + // For the version of jQuery that ships with Drupal core, override + // jQuery.httpData to prevent auto-detecting "script" data types from + // untrusted domains. + var jquery_httpData = $.httpData; + $.httpData = function (xhr, type, s) { + // @todo Consider backporting code from newer jQuery versions to check for + // a cross-domain request here, rather than using Drupal.urlIsLocal() to + // block scripts from all URLs that are not on the same site. + if (!type && !Drupal.urlIsLocal(s.url)) { + var content_type = xhr.getResponseHeader('content-type') || ''; + if (content_type.indexOf('javascript') >= 0) { + // Default to a safe data type. + type = 'text'; + } + } + return jquery_httpData.call(this, xhr, type, s); + }; + $.httpData.prototype = jquery_httpData.prototype; +} + +/** + * Attach all registered behaviors to a page element. + * + * Behaviors are event-triggered actions that attach to page elements, enhancing + * default non-JavaScript UIs. Behaviors are registered in the Drupal.behaviors + * object using the method 'attach' and optionally also 'detach' as follows: + * @code + * Drupal.behaviors.behaviorName = { + * attach: function (context, settings) { + * ... + * }, + * detach: function (context, settings, trigger) { + * ... + * } + * }; + * @endcode + * + * Drupal.attachBehaviors is added below to the jQuery ready event and so + * runs on initial page load. Developers implementing AHAH/Ajax in their + * solutions should also call this function after new page content has been + * loaded, feeding in an element to be processed, in order to attach all + * behaviors to the new content. + * + * Behaviors should use + * @code + * $(selector).once('behavior-name', function () { + * ... + * }); + * @endcode + * to ensure the behavior is attached only once to a given element. (Doing so + * enables the reprocessing of given elements, which may be needed on occasion + * despite the ability to limit behavior attachment to a particular element.) + * + * @param context + * An element to attach behaviors to. If none is given, the document element + * is used. + * @param settings + * An object containing settings for the current context. If none given, the + * global Drupal.settings object is used. + */ +Drupal.attachBehaviors = function (context, settings) { + context = context || document; + settings = settings || Drupal.settings; + // Execute all of them. + $.each(Drupal.behaviors, function () { + if ($.isFunction(this.attach)) { + this.attach(context, settings); + } + }); +}; + +/** + * Detach registered behaviors from a page element. + * + * Developers implementing AHAH/Ajax in their solutions should call this + * function before page content is about to be removed, feeding in an element + * to be processed, in order to allow special behaviors to detach from the + * content. + * + * Such implementations should look for the class name that was added in their + * corresponding Drupal.behaviors.behaviorName.attach implementation, i.e. + * behaviorName-processed, to ensure the behavior is detached only from + * previously processed elements. + * + * @param context + * An element to detach behaviors from. If none is given, the document element + * is used. + * @param settings + * An object containing settings for the current context. If none given, the + * global Drupal.settings object is used. + * @param trigger + * A string containing what's causing the behaviors to be detached. The + * possible triggers are: + * - unload: (default) The context element is being removed from the DOM. + * - move: The element is about to be moved within the DOM (for example, + * during a tabledrag row swap). After the move is completed, + * Drupal.attachBehaviors() is called, so that the behavior can undo + * whatever it did in response to the move. Many behaviors won't need to + * do anything simply in response to the element being moved, but because + * IFRAME elements reload their "src" when being moved within the DOM, + * behaviors bound to IFRAME elements (like WYSIWYG editors) may need to + * take some action. + * - serialize: When an Ajax form is submitted, this is called with the + * form as the context. This provides every behavior within the form an + * opportunity to ensure that the field elements have correct content + * in them before the form is serialized. The canonical use-case is so + * that WYSIWYG editors can update the hidden textarea to which they are + * bound. + * + * @see Drupal.attachBehaviors + */ +Drupal.detachBehaviors = function (context, settings, trigger) { + context = context || document; + settings = settings || Drupal.settings; + trigger = trigger || 'unload'; + // Execute all of them. + $.each(Drupal.behaviors, function () { + if ($.isFunction(this.detach)) { + this.detach(context, settings, trigger); + } + }); +}; + +/** + * Encode special characters in a plain-text string for display as HTML. + * + * @ingroup sanitization + */ +Drupal.checkPlain = function (str) { + var character, regex, + replace = { '&': '&', "'": ''', '"': '"', '<': '<', '>': '>' }; + str = String(str); + for (character in replace) { + if (replace.hasOwnProperty(character)) { + regex = new RegExp(character, 'g'); + str = str.replace(regex, replace[character]); + } + } + return str; +}; + +/** + * Replace placeholders with sanitized values in a string. + * + * @param str + * A string with placeholders. + * @param args + * An object of replacements pairs to make. Incidences of any key in this + * array are replaced with the corresponding value. Based on the first + * character of the key, the value is escaped and/or themed: + * - !variable: inserted as is + * - @variable: escape plain text to HTML (Drupal.checkPlain) + * - %variable: escape text and theme as a placeholder for user-submitted + * content (checkPlain + Drupal.theme('placeholder')) + * + * @see Drupal.t() + * @ingroup sanitization + */ +Drupal.formatString = function(str, args) { + // Transform arguments before inserting them. + for (var key in args) { + if (args.hasOwnProperty(key)) { + switch (key.charAt(0)) { + // Escaped only. + case '@': + args[key] = Drupal.checkPlain(args[key]); + break; + // Pass-through. + case '!': + break; + // Escaped and placeholder. + default: + args[key] = Drupal.theme('placeholder', args[key]); + break; + } + } + } + + return Drupal.stringReplace(str, args, null); +}; + +/** + * Replace substring. + * + * The longest keys will be tried first. Once a substring has been replaced, + * its new value will not be searched again. + * + * @param {String} str + * A string with placeholders. + * @param {Object} args + * Key-value pairs. + * @param {Array|null} keys + * Array of keys from the "args". Internal use only. + * + * @return {String} + * Returns the replaced string. + */ +Drupal.stringReplace = function (str, args, keys) { + if (str.length === 0) { + return str; + } + + // If the array of keys is not passed then collect the keys from the args. + if (!$.isArray(keys)) { + keys = []; + for (var k in args) { + if (args.hasOwnProperty(k)) { + keys.push(k); + } + } + + // Order the keys by the character length. The shortest one is the first. + keys.sort(function (a, b) { return a.length - b.length; }); + } + + if (keys.length === 0) { + return str; + } + + // Take next longest one from the end. + var key = keys.pop(); + var fragments = str.split(key); + + if (keys.length) { + for (var i = 0; i < fragments.length; i++) { + // Process each fragment with a copy of remaining keys. + fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0)); + } + } + + return fragments.join(args[key]); +}; + +/** + * Translate strings to the page language or a given language. + * + * See the documentation of the server-side t() function for further details. + * + * @param str + * A string containing the English string to translate. + * @param args + * An object of replacements pairs to make after translation. Incidences + * of any key in this array are replaced with the corresponding value. + * See Drupal.formatString(). + * + * @param options + * - 'context' (defaults to the empty context): The context the source string + * belongs to. + * + * @return + * The translated string. + */ +Drupal.t = function (str, args, options) { + options = options || {}; + options.context = options.context || ''; + + // Fetch the localized version of the string. + if (Drupal.locale.strings && Drupal.locale.strings[options.context] && Drupal.locale.strings[options.context][str]) { + str = Drupal.locale.strings[options.context][str]; + } + + if (args) { + str = Drupal.formatString(str, args); + } + return str; +}; + +/** + * Format a string containing a count of items. + * + * This function ensures that the string is pluralized correctly. Since Drupal.t() is + * called by this function, make sure not to pass already-localized strings to it. + * + * See the documentation of the server-side format_plural() function for further details. + * + * @param count + * The item count to display. + * @param singular + * The string for the singular case. Please make sure it is clear this is + * singular, to ease translation (e.g. use "1 new comment" instead of "1 new"). + * Do not use @count in the singular string. + * @param plural + * The string for the plural case. Please make sure it is clear this is plural, + * to ease translation. Use @count in place of the item count, as in "@count + * new comments". + * @param args + * An object of replacements pairs to make after translation. Incidences + * of any key in this array are replaced with the corresponding value. + * See Drupal.formatString(). + * Note that you do not need to include @count in this array. + * This replacement is done automatically for the plural case. + * @param options + * The options to pass to the Drupal.t() function. + * @return + * A translated string. + */ +Drupal.formatPlural = function (count, singular, plural, args, options) { + args = args || {}; + args['@count'] = count; + // Determine the index of the plural form. + var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1); + + if (index == 0) { + return Drupal.t(singular, args, options); + } + else if (index == 1) { + return Drupal.t(plural, args, options); + } + else { + args['@count[' + index + ']'] = args['@count']; + delete args['@count']; + return Drupal.t(plural.replace('@count', '@count[' + index + ']'), args, options); + } +}; + +/** + * Returns the passed in URL as an absolute URL. + * + * @param url + * The URL string to be normalized to an absolute URL. + * + * @return + * The normalized, absolute URL. + * + * @see https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js + * @see https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript + * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53 + */ +Drupal.absoluteUrl = function (url) { + var urlParsingNode = document.createElement('a'); + + // Decode the URL first; this is required by IE <= 6. Decoding non-UTF-8 + // strings may throw an exception. + try { + url = decodeURIComponent(url); + } catch (e) {} + + urlParsingNode.setAttribute('href', url); + + // IE <= 7 normalizes the URL when assigned to the anchor node similar to + // the other browsers. + return urlParsingNode.cloneNode(false).href; +}; + +/** + * Returns true if the URL is within Drupal's base path. + * + * @param url + * The URL string to be tested. + * + * @return + * Boolean true if local. + * + * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58 + */ +Drupal.urlIsLocal = function (url) { + // Always use browser-derived absolute URLs in the comparison, to avoid + // attempts to break out of the base path using directory traversal. + var absoluteUrl = Drupal.absoluteUrl(url); + var protocol = location.protocol; + + // Consider URLs that match this site's base URL but use HTTPS instead of HTTP + // as local as well. + if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) { + protocol = 'https:'; + } + var baseUrl = protocol + '//' + location.host + Drupal.settings.basePath.slice(0, -1); + + // Decoding non-UTF-8 strings may throw an exception. + try { + absoluteUrl = decodeURIComponent(absoluteUrl); + } catch (e) {} + try { + baseUrl = decodeURIComponent(baseUrl); + } catch (e) {} + + // The given URL matches the site's base URL, or has a path under the site's + // base URL. + return absoluteUrl === baseUrl || absoluteUrl.indexOf(baseUrl + '/') === 0; +}; + +/** + * Generate the themed representation of a Drupal object. + * + * All requests for themed output must go through this function. It examines + * the request and routes it to the appropriate theme function. If the current + * theme does not provide an override function, the generic theme function is + * called. + * + * For example, to retrieve the HTML for text that should be emphasized and + * displayed as a placeholder inside a sentence, call + * Drupal.theme('placeholder', text). + * + * @param func + * The name of the theme function to call. + * @param ... + * Additional arguments to pass along to the theme function. + * @return + * Any data the theme function returns. This could be a plain HTML string, + * but also a complex object. + */ +Drupal.theme = function (func) { + var args = Array.prototype.slice.apply(arguments, [1]); + + return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args); +}; + +/** + * Freeze the current body height (as minimum height). Used to prevent + * unnecessary upwards scrolling when doing DOM manipulations. + */ +Drupal.freezeHeight = function () { + Drupal.unfreezeHeight(); + $('
').css({ + position: 'absolute', + top: '0px', + left: '0px', + width: '1px', + height: $('body').css('height') + }).appendTo('body'); +}; + +/** + * Unfreeze the body height. + */ +Drupal.unfreezeHeight = function () { + $('#freeze-height').remove(); +}; + +/** + * Encodes a Drupal path for use in a URL. + * + * For aesthetic reasons slashes are not escaped. + */ +Drupal.encodePath = function (item, uri) { + uri = uri || location.href; + return encodeURIComponent(item).replace(/%2F/g, '/'); +}; + +/** + * Get the text selection in a textarea. + */ +Drupal.getSelection = function (element) { + if (typeof element.selectionStart != 'number' && document.selection) { + // The current selection. + var range1 = document.selection.createRange(); + var range2 = range1.duplicate(); + // Select all text. + range2.moveToElementText(element); + // Now move 'dummy' end point to end point of original range. + range2.setEndPoint('EndToEnd', range1); + // Now we can calculate start and end points. + var start = range2.text.length - range1.text.length; + var end = start + range1.text.length; + return { 'start': start, 'end': end }; + } + return { 'start': element.selectionStart, 'end': element.selectionEnd }; +}; + +/** + * Add a global variable which determines if the window is being unloaded. + * + * This is primarily used by Drupal.displayAjaxError(). + */ +Drupal.beforeUnloadCalled = false; +$(window).bind('beforeunload pagehide', function () { + Drupal.beforeUnloadCalled = true; +}); + +/** + * Displays a JavaScript error from an Ajax response when appropriate to do so. + */ +Drupal.displayAjaxError = function (message) { + // Skip displaying the message if the user deliberately aborted (for example, + // by reloading the page or navigating to a different page) while the Ajax + // request was still ongoing. See, for example, the discussion at + // http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-clicks-refresh. + if (!Drupal.beforeUnloadCalled) { + alert(message); + } +}; + +/** + * Build an error message from an Ajax response. + */ +Drupal.ajaxError = function (xmlhttp, uri, customMessage) { + var statusCode, statusText, pathText, responseText, readyStateText, message; + if (xmlhttp.status) { + statusCode = "\n" + Drupal.t("An AJAX HTTP error occurred.") + "\n" + Drupal.t("HTTP Result Code: !status", {'!status': xmlhttp.status}); + } + else { + statusCode = "\n" + Drupal.t("An AJAX HTTP request terminated abnormally."); + } + statusCode += "\n" + Drupal.t("Debugging information follows."); + pathText = "\n" + Drupal.t("Path: !uri", {'!uri': uri} ); + statusText = ''; + // In some cases, when statusCode == 0, xmlhttp.statusText may not be defined. + // Unfortunately, testing for it with typeof, etc, doesn't seem to catch that + // and the test causes an exception. So we need to catch the exception here. + try { + statusText = "\n" + Drupal.t("StatusText: !statusText", {'!statusText': $.trim(xmlhttp.statusText)}); + } + catch (e) {} + + responseText = ''; + // Again, we don't have a way to know for sure whether accessing + // xmlhttp.responseText is going to throw an exception. So we'll catch it. + try { + responseText = "\n" + Drupal.t("ResponseText: !responseText", {'!responseText': $.trim(xmlhttp.responseText) } ); + } catch (e) {} + + // Make the responseText more readable by stripping HTML tags and newlines. + responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,""); + responseText = responseText.replace(/[\n]+\s+/g,"\n"); + + // We don't need readyState except for status == 0. + readyStateText = xmlhttp.status == 0 ? ("\n" + Drupal.t("ReadyState: !readyState", {'!readyState': xmlhttp.readyState})) : ""; + + // Additional message beyond what the xmlhttp object provides. + customMessage = customMessage ? ("\n" + Drupal.t("CustomMessage: !customMessage", {'!customMessage': customMessage})) : ""; + + message = statusCode + pathText + statusText + customMessage + responseText + readyStateText; + return message; +}; + +// Class indicating that JS is enabled; used for styling purpose. +$('html').addClass('js'); + +// 'js enabled' cookie. +document.cookie = 'has_js=1; path=/'; + +/** + * Additions to jQuery.support. + */ +$(function () { + /** + * Boolean indicating whether or not position:fixed is supported. + */ + if (jQuery.support.positionFixed === undefined) { + var el = $('
').appendTo(document.body); + jQuery.support.positionFixed = el[0].offsetTop === 10; + el.remove(); + } +}); + +//Attach all behaviors. +$(function () { + Drupal.attachBehaviors(document, Drupal.settings); +}); + +/** + * The default themes. + */ +Drupal.theme.prototype = { + + /** + * Formats text for emphasized display in a placeholder inside a sentence. + * + * @param str + * The text to format (plain-text). + * @return + * The formatted text (html). + */ + placeholder: function (str) { + return '' + Drupal.checkPlain(str) + ''; + } +}; + +})(jQuery); +; diff --git a/siarp.de/sites/siarp.de/files/monopoly_junior/index.jpg b/siarp.de/sites/siarp.de/files/monopoly_junior/index.jpg new file mode 100644 index 0000000..3c23a62 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/monopoly_junior/index.jpg differ diff --git a/siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4/index.html b/siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4/index.html new file mode 100644 index 0000000..f800032 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/plonetutorial.excludefromnav-1.0dev-py2.4/index.html differ diff --git a/siarp.de/sites/siarp.de/files/reserved_words/index.xls b/siarp.de/sites/siarp.de/files/reserved_words/index.xls new file mode 100644 index 0000000..8f6ef67 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/reserved_words/index.xls differ diff --git a/siarp.de/sites/siarp.de/files/speedportcallerid/index.jar b/siarp.de/sites/siarp.de/files/speedportcallerid/index.jar new file mode 100644 index 0000000..f0b9fc7 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/speedportcallerid/index.jar differ diff --git a/siarp.de/sites/siarp.de/files/subdomains/index.html b/siarp.de/sites/siarp.de/files/subdomains/index.html new file mode 100644 index 0000000..a40ca8c --- /dev/null +++ b/siarp.de/sites/siarp.de/files/subdomains/index.html @@ -0,0 +1,70 @@ + + + + + + + Page not found | siarp.de + + + + + + + + + + + + + +
+
+ + + + +
+ +

Page not found

+
+
+
+ + +
+ The requested page "/sites/siarp.de/files/subdomains.gif" could not be found.
+
+
+
+ +
+ + +
+
+ + diff --git a/siarp.de/sites/siarp.de/files/ubuntu_free_space/index.png b/siarp.de/sites/siarp.de/files/ubuntu_free_space/index.png new file mode 100644 index 0000000..f2ebb89 Binary files /dev/null and b/siarp.de/sites/siarp.de/files/ubuntu_free_space/index.png differ diff --git a/siarp.de/themes/garland/images/task-list/index.png b/siarp.de/themes/garland/images/task-list/index.png new file mode 100644 index 0000000..3f9b74f Binary files /dev/null and b/siarp.de/themes/garland/images/task-list/index.png differ diff --git a/siarp.de/tilman/index.xml b/siarp.de/tilman/index.xml new file mode 100644 index 0000000..9407d1f --- /dev/null +++ b/siarp.de/tilman/index.xml @@ -0,0 +1,99 @@ + + + Tilman‘s posts + http://siarp.de/blog/3 + + en + + + Speedport W 723V (A) - automatischer Abruf der Anruferliste und Abgleich mit Google Contacts + http://siarp.de/node/232 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Seit kurzem haben wir VDSL von der Telekom (yeah!) und deshalb einen neuen Router. Das Gerät ist ein <a href="http://de.wikipedia.org/wiki/Speedport">Speedport</a> W 723V A mit relativ vielen Funktionen. Unter anderem können DECT-Telefone direkt angebunden werden und brauchen dann keinen eigene Basisstation. Diese Funktion wollte ich gerne nutzen, weil beim Anschluss des Telefons über die analoge TAE-Buchse nur eine Leitung genutzt werden kann und außerdem die Sprachqualität über die analoge Schnittstelle eher mäßig war.</p></div></div></div> + Mon, 30 Jul 2012 20:35:30 +0000 + Tilman + 232 at http://siarp.de + + + Reinventing the wheel: Automatic Bidirectional Directory Synchronization + http://siarp.de/node/231 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>As <a href="http://siarp.de/node/228">already mentioned</a>, I am the proud owner of an online hard drive and I love it. Enough space for everything that's worth keeping, secure access over lots of different protocols (including rsync), an automatic backup function... It would be perfect if I had an Internet connection of at least 100 MBit/s. But I haven't. (Actually the thing almost feels like a local disk when I use it from my computer at work. But that's through a university network.) So I had to come up with a little more sophisticated architecture.</p></div></div></div> + Mon, 21 Mar 2011 18:11:50 +0000 + Tilman + 231 at http://siarp.de + + + Strato HiDrive unter Ubuntu einbinden + http://siarp.de/node/228 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Mein neues <a href="http://hidrive.strato.com">HiDrive</a> unter Ubuntu 10.04 einzubinden hat etwas Nerven gekostet. WebDAV geht sofort (z.B. <a href="http://tuxpool.blogspot.com/2009/07/webdav-bug-in-ubuntu-jaunty.html">so</a>), ist aber schweinelahm. SMB über OpenVPN ist fürchterlich einzurichten und mir ist nicht so ganz klar, wie man das VPN vom restlichen Verkehr entkoppelt - man will ja nur die Kommunikation mit dem HiDrive darüber laufen lassen.</p></div></div></div> + Wed, 28 Jul 2010 09:09:14 +0000 + Tilman + 228 at http://siarp.de + + + Neue E-Mail-Organisation - Inbox Zero + http://siarp.de/node/214 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Nachdem Hosteurope nun schon seit einiger Zeit regelmäßig anmahnt, dass die Speicherplatz für E-Mails langsam zu Ende geht, woraufhin ich regelmäßig ein paar dicke Mails lösche um die Galgenfrist zu verlängern, habe ich nun endlich die Organisationsstruktur meines Posteingangs grundlegend erneuert. Bisher hatte ich zwar schon nach Jahren archiviert, die einzelnen E-Mails aber in ein recht komplexes System an Unterordnern einsortiert. (Einer für jeden Mailaccount, Unterordner für verschiedene Korrespondenzpartner und Themen, usw.</p></div></div></div> + Sun, 11 Oct 2009 18:32:53 +0000 + Tilman + 214 at http://siarp.de + + + Funambol SyncML-Server + http://siarp.de/node/211 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p><a href="http://www.funambol.org/">Funambol</a> ist derzeit die komfortabelste Möglichkeit, Adressen und Termine aus Thunderbird und Lightning mit dem Handy zu synchronisieren.</p> + +<h2>Funambol auf dem VPS installieren</h2> + +<ol> +<li>Download und Ausführen von funambol-8.0.0.bin (Installation nach /opt/Funambol) ohne am Ende den Server zu starten</li> +<li>Anpassung von <span class="geshifilter"><code class="text geshifilter-text">FUNAMBOL_HOME</code></span> in <span class="geshifilter"><code class="text geshifilter-text">/bin/funambol</code></span>, <span class="geshifilter"><code class="text geshifilter-text">/bin/funambol-server</code></span> und <span class="geshifilter"><code class="text geshifilter-text">/bin/install</code></span></div></div></div> + Thu, 01 Oct 2009 07:50:22 +0000 + Tilman + 211 at http://siarp.de + + + GPS mit dem E71: Initialzündung + http://siarp.de/node/202 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Seit zweieinhalb Monaten habe ich ein <a href="http://www.nokia.de/produkte/mobiltelefone/nokia-e71">Nokia E71</a> und bin eigentlich absolut zufrieden: Die Tastatur ist super (dafür gebe ich sogar gerne die Hälfte des Bildschirms im Vergleich zum iPhone her), E-Mail funktioniert wunderbar, Internet per WLAN für zu Hause, alles super. Nur das GPS... Ich hatte mich bewusst für ein Handy mit GPS entschieden, aber irgendwie wollte das Ding nicht recht. Bis zur Bestimmung der Position konnten gut 10 Minuten vergehen, absolut inakzeptabel.</p></div></div></div> + Tue, 08 Sep 2009 18:24:43 +0000 + Tilman + 202 at http://siarp.de + + + Erste Erfahrungen in 64 Bit + http://siarp.de/node/194 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Seit ein paar Tagen bin ich auf Windows Vista umgestiegen. Und um ganz vorne mit dabei zu sein, durfte es gleich die 64-Bit-Variante sein - ich denke es ist absehbar, wann man sich über mehr als vier GB Arbeitsspeicher freuen wird. Bisher sind die Erfahrungen ganz gut, ein paar Ecken und Kanten gibt es aber:</p></div></div></div> + Sun, 01 Feb 2009 15:26:51 +0000 + Tilman + 194 at http://siarp.de + + + Borland Real48 in Java + http://siarp.de/node/191 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>When writing a converter tool for a binary file format, I had problems reading some of the floating point numbers. After a little bit of research I found out that this very special format was used in programs written in Borland Pascal/Delphi. Since I couldn't find any Java class that's able to read this kind of number I wrote it myself.</p> + +<p>As far as I remember these are basically reverse IEEE floating point numbers of six bytes. (It's been a while since I wrote this. See the PDF file by Richard Biffl for a detailed description of the format.)</p> + +<p>References:</p></div></div></div> + Sat, 24 Jan 2009 08:47:06 +0000 + Tilman + 191 at http://siarp.de + + + Informatiker-Zeitvertreib + http://siarp.de/node/174 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Am 1.1. wollte Bettina unbedingt "Mensch ärgere dich nicht" spielen. Ich war nicht so begeistert, weil ich das Spiel für ziemlich langweilig halte. Zunächst diskutierten wir also meinen Standpunkt ("Da würfelt man doch nur abwechselnd") und den von Bettina ("Gar nicht, das hat voll viel mit Taktik zu tun"). Schlussendlich haben wir dann drei Runden gespielt. Später hatten wir Hunger und da nichts zu Essen im Haus war, haben wir uns Happy Meals bei McDonald's geholt. Als Spielzeug gab es "Monopoly Junior", also wurde auch das gespielt.</p></div></div></div> + Sun, 11 Jan 2009 20:33:08 +0000 + Tilman + 174 at http://siarp.de + + + Primat des Primaten: Ubuntu Gutsy Gibbon auf dem VPS 3.0 + http://siarp.de/node/143 + <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>Mit etwas Überredung hat sich der Gibbon doch noch auf dem neuen Server wecken lassen. Anscheinend wird nach dem Upgrade der SSH-Port einfach nicht mehr abgehört. (Der Server lief ja.) Vermutlich liegt es daran, dass in Gutsy xinetd (und nicht mehr inetd) verwendet wird. Nach dem Upgrade auf Ubuntu 7.10 muss xinetd umkonfiguriert werden, damit der Daemon im inetd-Kompatibilitätsmodus startet und auch das inetd-configfile berücksichtigt.</p></div></div></div> + Sat, 26 Jan 2008 15:49:21 +0000 + Tilman + 143 at http://siarp.de + + +