You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/03/04 15:30:36 UTC
svn commit: r1664013 - in /incubator/taverna/site/trunk/content: ./
community/ community/contact/ contact/
updates/commandline/3.0/stable/plugins/ updates/workbench/3.0/dev/
Author: stain
Date: Wed Mar 4 14:30:36 2015
New Revision: 1664013
URL: http://svn.apache.org/r1664013
Log:
community/contact/ -> community/lists
Added:
incubator/taverna/site/trunk/content/community/lists.md
- copied, changed from r1664010, incubator/taverna/site/trunk/content/community/contact/index.md
incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/.htaccess
incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/closer.cgi
incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.py
incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.pyc
incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.cgi
incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.list
Removed:
incubator/taverna/site/trunk/content/community/contact/index.md
incubator/taverna/site/trunk/content/contact/index.md
Modified:
incubator/taverna/site/trunk/content/.htaccess
incubator/taverna/site/trunk/content/community/edit.md
incubator/taverna/site/trunk/content/community/index.md
incubator/taverna/site/trunk/content/community/irc.md
Modified: incubator/taverna/site/trunk/content/.htaccess
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/.htaccess?rev=1664013&r1=1664012&r2=1664013&view=diff
==============================================================================
--- incubator/taverna/site/trunk/content/.htaccess (original)
+++ incubator/taverna/site/trunk/content/.htaccess Wed Mar 4 14:30:36 2015
@@ -1,10 +1,9 @@
-Redirect /contact/ /community/
Redirect /code/ /download/code/
ErrorDocument 404 /error_pages/404.html
RewriteEngine On
RewriteBase /
-RewriteRule ^(.*)\.html$ $1 [L,R]
-#RewriteRule ^(.*)\.cgi$ $1 [L,R]
+RewriteRule ^(.*)\.html$ $1 [R]
RewriteRule ^(.*)/index $1 [L,R]
-
+RewriteRule ^/community/contact.* /community/lists [L,R]
+RewriteRule ^/contact.* /community/lists [L,R]
Modified: incubator/taverna/site/trunk/content/community/edit.md
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/community/edit.md?rev=1664013&r1=1664012&r2=1664013&view=diff
==============================================================================
--- incubator/taverna/site/trunk/content/community/edit.md (original)
+++ incubator/taverna/site/trunk/content/community/edit.md Wed Mar 4 14:30:36 2015
@@ -43,10 +43,10 @@ of every `.md` file will not be rendered
To submit your suggested change, raise a
[GitHub pull request](https://github.com/apache/incubator-taverna-site/pulls)
which will send an email on your behalf to the
-[dev@taverna mailing list](http://taverna.incubator.apache.org/community/contact/), where
+[dev@taverna mailing list](http://taverna.incubator.apache.org/community/lists#devtaverna), where
an Apache Taverna committer will review your change before making it live
on the Apache Taverna website.
-Please sign up to [dev@taverna](http://taverna.incubator.apache.org/community/contact/)
+Please sign up to [dev@taverna](http://taverna.incubator.apache.org/community/lists#devtaverna)
to watch for to any follow-up comments about your changes.
@@ -73,7 +73,7 @@ If you are an existing
but don't have write access to the pages
(e.g. you are not in the `incubator` group), then your suggested edit will be sent as
an suggested patch to the
-[dev@taverna](http://taverna.incubator.apache.org/community/contact/) mailing list,
+[dev@taverna](http://taverna.incubator.apache.org/community/lists) mailing list,
which you should subscribe to in order to respond to any feedback.
@@ -88,7 +88,7 @@ prefer not to use GitHub, or if you want
involve renames, etc.
Note that in this case your suggested edit will be sent as an suggested patch to the
-[dev@taverna](http://taverna.incubator.apache.org/community/contact/) mailing list,
+[dev@taverna](http://taverna.incubator.apache.org/community/lists) mailing list,
which you should subscribe to in order to respond to any feedback.
@@ -131,7 +131,7 @@ Linking tips:
* <del>*"Code generation is automatic. More information is in [svn](#)"*</del>, try:
* *"Code is generated automatically by the [CodeGenerator](#) class"*
* Don't duplicate information. Link to existing pages - but provide sufficient context.
- * Example: *"Contact the [dev@taverna mailing list](/contact) for questions about the Maven plugin"*
+ * Example: `Contact the [dev@taverna mailing list](/community/lists) for questions about the Maven plugin"`
* Everything is easier with a link.
* Don't just say "You can find more in the documentation" - link to the right place in the documentation.
* Deep-links are good, unless the target pages becomes confusing out of context
@@ -151,7 +151,7 @@ link to `/introduction/why-use-workflows
If you are adding a new page:
* Make sure the page has a short, neutral and sensible URI
- * e.g. `community/contact` rather than <del>`the%20taverna%20community/contact-us-2`</del>
+ * e.g. `community/lists` rather than <del>`the%20taverna%20community/contact-us-2`</del>
* Make sure the page is linked from/to relevant existing Apache Taverna pages (not just the hierarchical parent)
* For example, if `/code` is describing the source code, and `/community` different ways to contribute, `/code` should link to the `/community` page and vice versa.
- * Ensure the page is included in the [navigation menu bar](https://github.com/apache/incubator-taverna-site/blob/trunk/templates/default_navbar.html) or in the listing of a higher-level page.
\ No newline at end of file
+ * Ensure the page is included in the [navigation menu bar](https://github.com/apache/incubator-taverna-site/blob/trunk/templates/default_navbar.html) or in the listing of a higher-level page.
Modified: incubator/taverna/site/trunk/content/community/index.md
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/community/index.md?rev=1664013&r1=1664012&r2=1664013&view=diff
==============================================================================
--- incubator/taverna/site/trunk/content/community/index.md (original)
+++ incubator/taverna/site/trunk/content/community/index.md Wed Mar 4 14:30:36 2015
@@ -34,7 +34,7 @@ there are opportunities for you to [get
<a name="mailinglists"></a>
##Mailing Lists##
-You are highly encouraged to participate on the Apache Taverna [mailing lists](/community/contact):
+You are highly encouraged to participate on the Apache Taverna [mailing lists](/community/lists):
<table class="table table-condensed">
<tr>
@@ -44,7 +44,7 @@ You are highly encouraged to participate
<a class="btn btn-primary" href="mailto:users-subscribe@taverna.incubator.apache.org" role="button">Subscribe</a>
<a class="btn btn-default" href="mailto:users-unsubscribe@taverna.incubator.apache.org" role="button">Unsubscribe</a>
<a class="btn btn-default" href="http://apache-taverna-users.markmail.org/search/?q=" role="button">Archive</a>
- <a class="btn btn-link" href="/community/contact/#userstaverna" role="button">More info</a>
+ <a class="btn btn-link" href="/community/lists#userstaverna" role="button">More info</a>
</td>
</tr>
<tr>
@@ -54,7 +54,7 @@ You are highly encouraged to participate
<a class="btn btn-primary" href="mailto:dev-subscribe@taverna.incubator.apache.org" role="button">Subscribe</a>
<a class="btn btn-default" href="mailto:dev-unsubscribe@taverna.incubator.apache.org" role="button">Unsubscribe</a>
<a class="btn btn-default" href="http://apache-taverna-dev.markmail.org/search/?q=" role="button">Archive</a>
- <a class="btn btn-link" href="/community/contact/#devtaverna" role="button">More info</a>
+ <a class="btn btn-link" href="/community/lists#devtaverna" role="button">More info</a>
</td>
</tr>
@@ -65,7 +65,7 @@ You are highly encouraged to participate
<a class="btn btn-primary" href="mailto:commits-subscribe@taverna.incubator.apache.org" role="button">Subscribe</a>
<a class="btn btn-default" href="mailto:commits-unsubscribe@taverna.incubator.apache.org" role="button">Unsubscribe</a>
<a class="btn btn-default" href="http://www.mail-archive.com/commits@taverna.incubator.apache.org/" role="button">Archive</a>
- <a class="btn btn-link" href="/community/contact/#commitstaverna" role="button">More info</a>
+ <a class="btn btn-link" href="/community/lists#commitstaverna" role="button">More info</a>
</td>
</tr>
</table>
@@ -80,7 +80,7 @@ To receive messages from a list, and to
Unsubscribing is done in the same way, using the *Unsubscribe* address instead.
-See the [mailing list](/community/contact) page for more details.
+See the [mailing list](/community/lists) page for more details.
### IRC chat
@@ -92,19 +92,18 @@ Some of the Apache Taverna users and dev
### Report or track a bug
Taverna's Apache Jira is still being setup.
-In the mean time the best place to report bugs is on the mailing lists.
+In the mean time, the best place to report bugs is on the mailing lists.
-The previous NONE Apache Taverna Jira can be found at:
+The previous (non-Apache) Taverna Jira can be found at:
<http://dev.mygrid.org.uk/issues/browse/T3>
-<a name="contribute"></a>
## Contribute
<a name="contribute-workflow"></a>
### Contribute a workflow
The best place to contribute Taverna workflows is on
- [My Experiment](http://www.myexperiment.org).
+ [myExperiment](http://www.myexperiment.org).
<a name="contribute-plugin"></a>
### Contribute a plugin ###
Modified: incubator/taverna/site/trunk/content/community/irc.md
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/community/irc.md?rev=1664013&r1=1664012&r2=1664013&view=diff
==============================================================================
--- incubator/taverna/site/trunk/content/community/irc.md (original)
+++ incubator/taverna/site/trunk/content/community/irc.md Wed Mar 4 14:30:36 2015
@@ -48,7 +48,7 @@ The #taverna IRC channel is <a class="al
Remember:
-> If it didn't happen on the [mailing list](/community/contact), it didn't happen.
+> If it didn't happen on the [mailing list](/community/lists), it didn't happen.
If you don't have an [IRC client](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) you can use the [freenode webchat](http://webchat.freenode.net/?channels=%23taverna&uio=MTE9MjA16a):
Copied: incubator/taverna/site/trunk/content/community/lists.md (from r1664010, incubator/taverna/site/trunk/content/community/contact/index.md)
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/community/lists.md?p2=incubator/taverna/site/trunk/content/community/lists.md&p1=incubator/taverna/site/trunk/content/community/contact/index.md&r1=1664010&r2=1664013&rev=1664013&view=diff
==============================================================================
(empty)
Added: incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/.htaccess
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/.htaccess?rev=1664013&view=auto
==============================================================================
--- incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/.htaccess (added)
+++ incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/.htaccess Wed Mar 4 14:30:36 2015
@@ -0,0 +1,2 @@
+RewriteEngine On
+RewriteRule (.*) closer.cgi/$1
Added: incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/closer.cgi
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/closer.cgi?rev=1664013&view=auto
==============================================================================
--- incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/closer.cgi (added)
+++ incubator/taverna/site/trunk/content/updates/commandline/3.0/stable/plugins/closer.cgi Wed Mar 4 14:30:36 2015
@@ -0,0 +1,4 @@
+#!/bin/sh
+# This wrapper's location identifies closer.html (aka closer.mdtext) as the
+# template for mirrors.cgi. ... and now, run the real script:
+exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $*
Added: incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.py
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.py?rev=1664013&view=auto
==============================================================================
--- incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.py (added)
+++ incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.py Wed Mar 4 14:30:36 2015
@@ -0,0 +1,657 @@
+#!/usr/bin/env python
+"""ezt.py -- EaZy Templating
+
+For documentation, please see: http://code.google.com/p/ezt/wiki/Syntax
+"""
+#
+# Copyright (C) 2001-2011 Greg Stein. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+# This software is maintained by Greg and is available at:
+# http://code.google.com/p/ezt/
+#
+
+__author__ = 'Greg Stein'
+__version__ = '1.0'
+__license__ = 'BSD'
+
+import re
+from types import IntType, FloatType, LongType
+import os
+import urllib
+import StringIO
+
+#
+# Formatting types
+#
+FORMAT_RAW = 'raw'
+FORMAT_HTML = 'html'
+FORMAT_XML = 'xml'
+FORMAT_JS = 'js'
+FORMAT_URL = 'url'
+
+#
+# This regular expression matches four alternatives:
+# expr: NEWLINE | DIRECTIVE | BRACKET | COMMENT
+# DIRECTIVE: '[' ITEM (whitespace ARG)* ']
+# ITEM: STRING | NAME
+# ARG: STRING | NAME | NUMBER
+# STRING: '"' (not-slash-or-dquote | '\' anychar)* '"'
+# NAME: (alpha | '_') (alphanum | '_' | '-' | '.')*
+# NUMBER: digit+
+# BRACKET: '[[]'
+# COMMENT: '[#' not-rbracket* ']'
+#
+# Note: the above BNR is a bit loose around ITEM/ARG/NAME/NUMBER. The
+# important point is that the first value in a directive must
+# start with '_' or an alpha character (no digits). This greatly
+# helps to avoid simple errors like '[0]' in templates.
+#
+# When used with the split() method, the return value will be composed of
+# non-matching text and the three paren groups (NEWLINE, DIRECTIVE and
+# BRACKET). Since the COMMENT matches are not placed into a group, they are
+# considered a "splitting" value and simply dropped.
+#
+_item = r'(?:"(?:[^\\"]|\\.)*"|[A-Za-z_][-\w.]*)'
+_arg = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)'
+_re_parse = re.compile(r'(\r?\n)|\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]' %
+ (_item, _arg))
+
+_re_args = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+')
+
+# block commands and their argument counts
+_block_cmd_specs = { 'if-index':2, 'for':1, 'is':2, 'define':1, 'format':1 }
+_block_cmds = _block_cmd_specs.keys()
+
+# two regular expressions for compressing whitespace. the first is used to
+# compress any whitespace including a newline into a single newline. the
+# second regex is used to compress runs of whitespace into a single space.
+_re_newline = re.compile('[ \t\r\f\v]*\n\\s*')
+_re_whitespace = re.compile(r'\s\s+')
+
+# this regex is used to substitute arguments into a value. we split the value,
+# replace the relevant pieces, and then put it all back together. splitting
+# will produce a list of: TEXT ( splitter TEXT )*. splitter will be '%' or
+# an integer.
+_re_subst = re.compile('%(%|[0-9]+)')
+
+class Template:
+
+ def __init__(self, fname=None, compress_whitespace=1,
+ base_format=FORMAT_RAW):
+ self.compress_whitespace = compress_whitespace
+ if fname:
+ self.parse_file(fname, base_format)
+
+ def parse_file(self, fname, base_format=FORMAT_RAW):
+ "fname -> a string object with pathname of file containg an EZT template."
+
+ self.parse(_FileReader(fname), base_format)
+
+ def parse(self, text_or_reader, base_format=FORMAT_RAW):
+ """Parse the template specified by text_or_reader.
+
+ The argument should be a string containing the template, or it should
+ specify a subclass of ezt.Reader which can read templates. The base
+ format for printing values is given by base_format.
+ """
+ if not isinstance(text_or_reader, Reader):
+ # assume the argument is a plain text string
+ text_or_reader = _TextReader(text_or_reader)
+
+ self.program = self._parse(text_or_reader,
+ base_printer=_parse_format(base_format))
+
+ def generate(self, fp, data):
+ if hasattr(data, '__getitem__') or callable(getattr(data, 'keys', None)):
+ # a dictionary-like object was passed. convert it to an
+ # attribute-based object.
+ class _data_ob:
+ def __init__(self, d):
+ vars(self).update(d)
+ data = _data_ob(data)
+
+ ctx = _context()
+ ctx.data = data
+ ctx.for_index = { }
+ ctx.defines = { }
+ self._execute(self.program, fp, ctx)
+
+ def _parse(self, reader, for_names=None, file_args=(), base_printer=None):
+ """text -> string object containing the template.
+
+ This is a private helper function doing the real work for method parse.
+ It returns the parsed template as a 'program'. This program is a sequence
+ made out of strings or (function, argument) 2-tuples.
+
+ Note: comment directives [# ...] are automatically dropped by _re_parse.
+ """
+
+ filename = reader.filename()
+ # parse the template program into: (TEXT NEWLINE DIRECTIVE BRACKET)* TEXT
+ parts = _re_parse.split(reader.text)
+
+ program = [ ]
+ stack = [ ]
+ if not for_names:
+ for_names = [ ]
+
+ if base_printer is None:
+ base_printer = ()
+ printers = [ base_printer ]
+
+ one_newline_copied = False
+ line_number = 1
+ for i in range(len(parts)):
+ piece = parts[i]
+ which = i % 4 # discriminate between: TEXT NEWLINE DIRECTIVE BRACKET
+ if which == 0:
+ # TEXT. append if non-empty.
+ if piece:
+ if self.compress_whitespace:
+ piece = _re_whitespace.sub(' ', piece)
+ program.append(piece)
+ one_newline_copied = False
+ elif which == 1:
+ # NEWLINE. append unless compress_whitespace requested
+ if piece:
+ line_number += 1
+ if self.compress_whitespace:
+ if not one_newline_copied:
+ program.append('\n')
+ one_newline_copied = True
+ else:
+ program.append(piece)
+ elif which == 3:
+ # BRACKET directive. append '[' if present.
+ if piece:
+ program.append('[')
+ one_newline_copied = False
+ elif piece:
+ # DIRECTIVE is present.
+ one_newline_copied = False
+ args = _re_args.findall(piece)
+ cmd = args[0]
+ if cmd == 'else':
+ if len(args) > 1:
+ raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
+ ### check: don't allow for 'for' cmd
+ idx = stack[-1][1]
+ true_section = program[idx:]
+ del program[idx:]
+ stack[-1][3] = true_section
+ elif cmd == 'end':
+ if len(args) > 1:
+ raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
+ # note: true-section may be None
+ try:
+ cmd, idx, args, true_section, start_line_number = stack.pop()
+ except IndexError:
+ raise UnmatchedEndError(None, filename, line_number)
+ else_section = program[idx:]
+ if cmd == 'format':
+ printers.pop()
+ else:
+ func = getattr(self, '_cmd_' + re.sub('-', '_', cmd))
+ program[idx:] = [ (func, (args, true_section, else_section),
+ filename, line_number) ]
+ if cmd == 'for':
+ for_names.pop()
+ elif cmd in _block_cmds:
+ if len(args) > _block_cmd_specs[cmd] + 1:
+ raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
+ ### this assumes arg1 is always a ref unless cmd is 'define'
+ if cmd != 'define':
+ args[1] = _prepare_ref(args[1], for_names, file_args)
+
+ # handle arg2 for the 'is' command
+ if cmd == 'is':
+ args[2] = _prepare_ref(args[2], for_names, file_args)
+ elif cmd == 'for':
+ for_names.append(args[1][0]) # append the refname
+ elif cmd == 'format':
+ if args[1][0]:
+ raise BadFormatConstantError(str(args[1:]), filename, line_number)
+ printers.append(_parse_format(args[1][1]))
+
+ # remember the cmd, current pos, args, and a section placeholder
+ stack.append([cmd, len(program), args[1:], None, line_number])
+ elif cmd == 'include' or cmd == 'insertfile':
+ is_insertfile = (cmd == 'insertfile')
+ # extra arguments are meaningless when using insertfile
+ if is_insertfile and len(args) != 2:
+ raise ArgCountSyntaxError(str(args), filename, line_number)
+ if args[1][0] == '"':
+ include_filename = args[1][1:-1]
+ if is_insertfile:
+ program.append(reader.read_other(include_filename).text)
+ else:
+ f_args = [ ]
+ for arg in args[2:]:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ program.extend(self._parse(reader.read_other(include_filename),
+ for_names, f_args, printers[-1]))
+ else:
+ if len(args) != 2:
+ raise ArgCountSyntaxError(str(args), filename, line_number)
+ if is_insertfile:
+ cmd = self._cmd_insertfile
+ else:
+ cmd = self._cmd_include
+ program.append((cmd,
+ (_prepare_ref(args[1], for_names, file_args),
+ reader, printers[-1]), filename, line_number))
+ elif cmd == 'if-any':
+ f_args = [ ]
+ for arg in args[1:]:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ stack.append(['if-any', len(program), f_args, None, line_number])
+ else:
+ # implied PRINT command
+ if len(args) > 1:
+ f_args = [ ]
+ for arg in args:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ program.append((self._cmd_subst,
+ (printers[-1], f_args[0], f_args[1:]),
+ filename, line_number))
+ else:
+ valref = _prepare_ref(args[0], for_names, file_args)
+ program.append((self._cmd_print, (printers[-1], valref),
+ filename, line_number))
+
+ if stack:
+ raise UnclosedBlocksError('Block opened at line %s' % stack[-1][4],
+ filename=filename)
+ return program
+
+ def _execute(self, program, fp, ctx):
+ """This private helper function takes a 'program' sequence as created
+ by the method '_parse' and executes it step by step. strings are written
+ to the file object 'fp' and functions are called.
+ """
+ for step in program:
+ if isinstance(step, basestring):
+ fp.write(step)
+ else:
+ method, method_args, filename, line_number = step
+ method(method_args, fp, ctx, filename, line_number)
+
+ def _cmd_print(self, (transforms, valref), fp, ctx, filename, line_number):
+ value = _get_value(valref, ctx, filename, line_number)
+ # if the value has a 'read' attribute, then it is a stream: copy it
+ if hasattr(value, 'read'):
+ while 1:
+ chunk = value.read(16384)
+ if not chunk:
+ break
+ for t in transforms:
+ chunk = t(chunk)
+ fp.write(chunk)
+ else:
+ for t in transforms:
+ value = t(value)
+ fp.write(value)
+
+ def _cmd_subst(self, (transforms, valref, args), fp, ctx, filename,
+ line_number):
+ fmt = _get_value(valref, ctx, filename, line_number)
+ parts = _re_subst.split(fmt)
+ for i in range(len(parts)):
+ piece = parts[i]
+ if i%2 == 1 and piece != '%':
+ idx = int(piece)
+ if idx < len(args):
+ piece = _get_value(args[idx], ctx, filename, line_number)
+ else:
+ piece = '<undef>'
+ for t in transforms:
+ piece = t(piece)
+ fp.write(piece)
+
+ def _cmd_include(self, (valref, reader, printer), fp, ctx, filename,
+ line_number):
+ fname = _get_value(valref, ctx, filename, line_number)
+ ### note: we don't have the set of for_names to pass into this parse.
+ ### I don't think there is anything to do but document it
+ self._execute(self._parse(reader.read_other(fname), base_printer=printer),
+ fp, ctx)
+
+ def _cmd_insertfile(self, (valref, reader, printer), fp, ctx, filename,
+ line_number):
+ fname = _get_value(valref, ctx, filename, line_number)
+ fp.write(reader.read_other(fname).text)
+
+ def _cmd_if_any(self, args, fp, ctx, filename, line_number):
+ "If any value is a non-empty string or non-empty list, then T else F."
+ (valrefs, t_section, f_section) = args
+ value = 0
+ for valref in valrefs:
+ if _get_value(valref, ctx, filename, line_number):
+ value = 1
+ break
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _cmd_if_index(self, args, fp, ctx, filename, line_number):
+ ((valref, value), t_section, f_section) = args
+ list, idx = ctx.for_index[valref[0]]
+ if value == 'even':
+ value = idx % 2 == 0
+ elif value == 'odd':
+ value = idx % 2 == 1
+ elif value == 'first':
+ value = idx == 0
+ elif value == 'last':
+ value = idx == len(list)-1
+ else:
+ value = idx == int(value)
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _cmd_is(self, args, fp, ctx, filename, line_number):
+ ((left_ref, right_ref), t_section, f_section) = args
+ right_value = _get_value(right_ref, ctx, filename, line_number)
+ left_value = _get_value(left_ref, ctx, filename, line_number)
+ value = left_value.lower() == right_value.lower()
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _do_if(self, value, t_section, f_section, fp, ctx):
+ if t_section is None:
+ t_section = f_section
+ f_section = None
+ if value:
+ section = t_section
+ else:
+ section = f_section
+ if section is not None:
+ self._execute(section, fp, ctx)
+
+ def _cmd_for(self, args, fp, ctx, filename, line_number):
+ ((valref,), unused, section) = args
+ list = _get_value(valref, ctx, filename, line_number)
+ refname = valref[0]
+ if isinstance(list, basestring):
+ raise NeedSequenceError(refname, filename, line_number)
+ ctx.for_index[refname] = idx = [ list, 0 ]
+ for item in list:
+ self._execute(section, fp, ctx)
+ idx[1] = idx[1] + 1
+ del ctx.for_index[refname]
+
+ def _cmd_define(self, args, fp, ctx, filename, line_number):
+ ((name,), unused, section) = args
+ valfp = StringIO.StringIO()
+ if section is not None:
+ self._execute(section, valfp, ctx)
+ ctx.defines[name] = valfp.getvalue()
+
+def boolean(value):
+ "Return a value suitable for [if-any bool_var] usage in a template."
+ if value:
+ return 'yes'
+ return None
+
+
+def _prepare_ref(refname, for_names, file_args):
+ """refname -> a string containing a dotted identifier. example:"foo.bar.bang"
+ for_names -> a list of active for sequences.
+
+ Returns a `value reference', a 3-tuple made out of (refname, start, rest),
+ for fast access later.
+ """
+ # is the reference a string constant?
+ if refname[0] == '"':
+ return None, refname[1:-1], None
+
+ parts = refname.split('.')
+ start = parts[0]
+ rest = parts[1:]
+
+ # if this is an include-argument, then just return the prepared ref
+ if start[:3] == 'arg':
+ try:
+ idx = int(start[3:])
+ except ValueError:
+ pass
+ else:
+ if idx < len(file_args):
+ orig_refname, start, more_rest = file_args[idx]
+ if more_rest is None:
+ # the include-argument was a string constant
+ return None, start, None
+
+ # prepend the argument's "rest" for our further processing
+ rest[:0] = more_rest
+
+ # rewrite the refname to ensure that any potential 'for' processing
+ # has the correct name
+ ### this can make it hard for debugging include files since we lose
+ ### the 'argNNN' names
+ if not rest:
+ return start, start, [ ]
+ refname = start + '.' + '.'.join(rest)
+
+ if for_names:
+ # From last to first part, check if this reference is part of a for loop
+ for i in range(len(parts), 0, -1):
+ name = '.'.join(parts[:i])
+ if name in for_names:
+ return refname, name, parts[i:]
+
+ return refname, start, rest
+
+def _get_value((refname, start, rest), ctx, filename, line_number):
+ """(refname, start, rest) -> a prepared `value reference' (see above).
+ ctx -> an execution context instance.
+
+ Does a name space lookup within the template name space. Active
+ for blocks take precedence over data dictionary members with the
+ same name.
+ """
+ if rest is None:
+ # it was a string constant
+ return start
+
+ # get the starting object
+ if ctx.for_index.has_key(start):
+ list, idx = ctx.for_index[start]
+ ob = list[idx]
+ elif ctx.defines.has_key(start):
+ ob = ctx.defines[start]
+ elif hasattr(ctx.data, start):
+ ob = getattr(ctx.data, start)
+ else:
+ raise UnknownReference(refname, filename, line_number)
+
+ # walk the rest of the dotted reference
+ for attr in rest:
+ try:
+ ob = getattr(ob, attr)
+ except AttributeError:
+ raise UnknownReference(refname, filename, line_number)
+
+ # make sure we return a string instead of some various Python types
+ if isinstance(ob, (IntType, FloatType, LongType)):
+ return str(ob)
+ if ob is None:
+ return ''
+
+ # string or a sequence
+ return ob
+
+def _replace(s, replace_map):
+ for orig, repl in replace_map:
+ s = s.replace(orig, repl)
+ return s
+
+REPLACE_JS_MAP = (
+ ('\\', r'\\'), ('\t', r'\t'), ('\n', r'\n'), ('\r', r'\r'),
+ ('"', r'\x22'), ('\'', r'\x27'), ('&', r'\x26'),
+ ('<', r'\x3c'), ('>', r'\x3e'), ('=', r'\x3d'),
+)
+
+# Various unicode whitespace
+REPLACE_JS_UNICODE_MAP = (
+ (u'\u0085', r'\u0085'), (u'\u2028', r'\u2028'), (u'\u2029', r'\u2029'),
+)
+
+# Why not cgi.escape? It doesn't do single quotes which are occasionally
+# used to contain HTML attributes and event handler definitions (unfortunately)
+REPLACE_HTML_MAP = (
+ ('&', '&'), ('<', '<'), ('>', '>'),
+ ('"', '"'), ('\'', '''),
+)
+
+def _js_escape(s):
+ s = _replace(s, REPLACE_JS_MAP)
+ ### perhaps attempt to coerce the string to unicode and then replace?
+ if isinstance(s, unicode):
+ s = _replace(s, REPLACE_JS_UNICODE_MAP)
+ return s
+
+def _html_escape(s):
+ return _replace(s, REPLACE_HTML_MAP)
+
+def _url_escape(s):
+ ### quote_plus barfs on non-ASCII characters. According to
+ ### http://www.w3.org/International/O-URL-code.html URIs should be
+ ### UTF-8 encoded first.
+ if isinstance(s, unicode):
+ s = s.encode('utf8')
+ return urllib.quote_plus(s)
+
+FORMATTERS = {
+ FORMAT_RAW: None,
+ FORMAT_HTML: _html_escape,
+ FORMAT_XML: _html_escape, ### use the same quoting as HTML for now
+ FORMAT_JS: _js_escape,
+ FORMAT_URL: _url_escape,
+}
+
+def _parse_format(format_string=FORMAT_RAW):
+ format_funcs = []
+ try:
+ for fspec in format_string.split(','):
+ format_func = FORMATTERS[fspec]
+ if format_func is not None:
+ format_funcs.append(format_func)
+ except KeyError:
+ raise UnknownFormatConstantError(format_string)
+ return format_funcs
+
+class _context:
+ """A container for the execution context"""
+
+
+class Reader:
+ """Abstract class which allows EZT to detect Reader objects."""
+ def filename(self):
+ return '(%s does not provide filename() method)' % repr(self)
+
+class _FileReader(Reader):
+ """Reads templates from the filesystem."""
+ def __init__(self, fname):
+ self.text = open(fname, 'rb').read()
+ self._dir = os.path.dirname(fname)
+ self.fname = fname
+ def read_other(self, relative):
+ return _FileReader(os.path.join(self._dir, relative))
+ def filename(self):
+ return self.fname
+
+class _TextReader(Reader):
+ """'Reads' a template from provided text."""
+ def __init__(self, text):
+ self.text = text
+ def read_other(self, relative):
+ raise BaseUnavailableError()
+ def filename(self):
+ return '(text)'
+
+
+class EZTException(Exception):
+ """Parent class of all EZT exceptions."""
+ def __init__(self, message=None, filename=None, line_number=None):
+ self.message = message
+ self.filename = filename
+ self.line_number = line_number
+ def __str__(self):
+ ret = []
+ if self.message is not None:
+ ret.append(self.message)
+ if self.filename is not None:
+ ret.append('in file ' + str(self.filename))
+ if self.line_number is not None:
+ ret.append('at line ' + str(self.line_number))
+ return ' '.join(ret)
+
+class ArgCountSyntaxError(EZTException):
+ """A bracket directive got the wrong number of arguments."""
+
+class UnknownReference(EZTException):
+ """The template references an object not contained in the data dictionary."""
+
+class NeedSequenceError(EZTException):
+ """The object dereferenced by the template is no sequence (tuple or list)."""
+
+class UnclosedBlocksError(EZTException):
+ """This error may be simply a missing [end]."""
+
+class UnmatchedEndError(EZTException):
+ """This error may be caused by a misspelled if directive."""
+
+class BaseUnavailableError(EZTException):
+ """Base location is unavailable, which disables includes."""
+
+class BadFormatConstantError(EZTException):
+ """Format specifiers must be string constants."""
+
+class UnknownFormatConstantError(EZTException):
+ """The format specifier is an unknown value."""
+
+
+# --- standard test environment ---
+def test_parse():
+ assert _re_parse.split('[a]') == ['', '[a]', None, '']
+ assert _re_parse.split('[a] [b]') == \
+ ['', '[a]', None, ' ', '[b]', None, '']
+ assert _re_parse.split('[a c] [b]') == \
+ ['', '[a c]', None, ' ', '[b]', None, '']
+ assert _re_parse.split('x [a] y [b] z') == \
+ ['x ', '[a]', None, ' y ', '[b]', None, ' z']
+ assert _re_parse.split('[a "b" c "d"]') == \
+ ['', '[a "b" c "d"]', None, '']
+ assert _re_parse.split(r'["a \"b[foo]" c.d f]') == \
+ ['', '["a \\"b[foo]" c.d f]', None, '']
+
+def _test(argv):
+ import doctest, ezt
+ verbose = "-v" in argv
+ return doctest.testmod(ezt, verbose=verbose)
+
+if __name__ == "__main__":
+ # invoke unit test for this module:
+ import sys
+ sys.exit(_test(sys.argv)[0])
Added: incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.pyc
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.pyc?rev=1664013&view=auto
==============================================================================
Binary files incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.pyc (added) and incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/ezt.pyc Wed Mar 4 14:30:36 2015 differ
Added: incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.cgi
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.cgi?rev=1664013&view=auto
==============================================================================
--- incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.cgi (added)
+++ incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.cgi Wed Mar 4 14:30:36 2015
@@ -0,0 +1,264 @@
+#!/usr/local/bin/python2.7
+# -*- python -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+# This is a Python CGI script that uses EZT to produce templated
+# mirror content and GeoIP to choose the appropriate mirror
+#
+
+import sys
+import os
+import cgi
+import stat
+import random
+import time
+import traceback
+import cStringIO
+import json
+import re
+
+# Should be installed in the main system library
+import GeoIP
+
+# Insert this directory into PATH so that we can import ezt
+this_dir = os.path.dirname(__file__) or '.'
+sys.path.insert(0, this_dir)
+
+import ezt
+
+
+# Configurable stuff
+MIRRORS_LIST = "/x1/www/www.apache.org/mirrors/mirrors.list"
+DEFAULT_REGION = "us"
+DEFAULT_TEMPLATE = "/x1/www/www.apache.org/dyn/closer.html"
+DEFAULT_LOCATION = "http://www.apache.org/dyn/closer.cgi"
+
+
+def get_region(environ):
+ """Use GeoIP to find the client's country, falling back to
+ DEFAULT_REGION on failure."""
+ try:
+ remote_ip = environ['REMOTE_ADDR'];
+ gi = GeoIP.new(GeoIP.GEOIP_STANDARD)
+ region = gi.country_code_by_addr(remote_ip).lower().strip()
+ if region == 'gb':
+ return 'uk'
+ else:
+ return region
+ except:
+ ### should we log an error here? absorbing without reporting is
+ ### generally bad form.
+ return DEFAULT_REGION
+
+
+def parse_mirrors(filename, country, preferred, mingood):
+ """Parse the mirror database to find the best mirrors for a client.
+
+ The Format of the mirror database is:
+ ftp au ftp://ftp.planetmirror.com/pub/apache/dist/ 1117724635 """
+
+ output = { 'http' : [ ],
+ 'ftp' : [ ],
+ 'backup' : [ ],
+ 'preferred' : None,
+ }
+
+ # Read the mirror database and put it in a list of lists
+ # skip empty lines and comment
+ mirrors = [line.split() for line in open(filename).readlines()
+ if line.strip() and not line.startswith('#')]
+
+ # Add trailing slashes where missing. Otherwise,
+ # strcat("http://www.mirror.org", pathinfo=".foo.evil") would link to
+ # http://www.mirror.org.foo.evil
+ for mir in mirrors:
+ if not mir[2].endswith('/'):
+ mir[2] += '/'
+
+ # grab the backup mirrors
+ backupmirrors = [mir for mir in mirrors if mir[1] == 'Backup'
+ and mir[0] == 'http']
+
+ # Grab the mirrors for the requested country or, failing that,
+ # from the default region (us)
+ for region in (country, DEFAULT_REGION):
+ countrymirrors = [mir for mir in mirrors if mir[1] == region]
+ random.shuffle(countrymirrors)
+ goodmirror = None
+ for mir in countrymirrors:
+ if mir[0] == 'http' and int(mir[3]) > mingood:
+ goodmirror = mir
+ break
+ if goodmirror:
+ break
+
+ # Check if the requested Preferred mirror is in the list.
+ # If the user-requested mirror doesn't have a trailing-slash, add '/'.
+ prefmir = None
+ if preferred:
+ if not preferred.endswith('/'):
+ preferred += '/'
+ for mir in mirrors:
+ if mir[2] == preferred:
+ prefmir = mir
+ break
+ # Otherwise pick a preferred mirror from our country
+ if not prefmir and goodmirror:
+ prefmir = goodmirror
+ if not prefmir: # In the worst case, choose a backup
+ prefmir = random.choice(backupmirrors)
+
+ # Record the preferred mirror
+ # Keep the trailing-slash on the URL (it is later joined to the path_info)
+ output['preferred'] = prefmir[2]
+
+ # Now assemble a list of all the other mirrors.
+ # Keep the trailing-slash on the URL (it is later joined to the path_info)
+ output['http'] = [mir[2] for mir in countrymirrors if mir[0] == 'http']
+ output['ftp'] = [mir[2] for mir in countrymirrors if mir[0] == 'ftp']
+ output['backup'] = [mir[2] for mir in backupmirrors]
+
+ return output
+
+
+def mirrorwrap(environ, start_response):
+ try:
+ return mirrorsapp(environ, start_response)
+ except:
+ status = "500 Oops"
+ response_headers = [("content-type","text/plain")]
+ start_response(status, response_headers, sys.exc_info())
+ return ["Problem running mirror.cgi; "
+ "if it persists, contact <in...@apache.org>.\n\n"
+ "In the meantime, try <" + DEFAULT_LOCATION + ">\n\n"
+ + traceback.format_exc() ]
+
+
+def locate_template(environ):
+ # Determine the correct template by noting our filesystem location
+ if environ.has_key('ASF_MIRROR_FILENAME'):
+ template_file = environ['ASF_MIRROR_FILENAME'].replace(".cgi", ".html")
+ elif environ.has_key('SCRIPT_FILENAME'):
+ template_file = environ['SCRIPT_FILENAME'].replace(".cgi", ".html")
+ else:
+ template_file = sys.argv[0].replace(".cgi", ".html")
+
+ print template_file
+ if not os.path.isfile(template_file):
+ # look in docroot instead if this is in a cgi-bin dir
+ template_file = template_file.replace("/cgi-bin/", "/content/")
+ if not os.path.isfile(template_file):
+ template_file = DEFAULT_TEMPLATE
+
+ return template_file
+
+
+def locate_mirrors(environ):
+ # Allow the MIRRORS_LIST environment variable to override the default
+ mirrors = environ.get('MIRRORS_LIST')
+ if mirrors and os.path.isfile(mirrors):
+ return mirrors
+ return MIRRORS_LIST # the default
+
+
+def mirrorsapp(environ, start_response):
+ headers = [ ]
+ resp_code = '200 OK'
+
+ # Was there a preferred mirror or update requirement?
+ form = cgi.FieldStorage(fp=environ['wsgi.input'],
+ environ=environ,
+ keep_blank_values=True)
+ preferred = form.getfirst("Preferred", "")
+ update = form.getfirst("update", "")
+
+ # Where is the client coming from ?
+ ccode = form.getfirst("ccode", None)
+ if ccode and re.match("[a-z]{2}$", ccode):
+ region = ccode
+ else:
+ region = get_region(environ)
+
+ # Get the last update time of the mirror database
+ mirrors = locate_mirrors(environ)
+ base_time = os.path.getmtime(mirrors)
+
+ # convert from YYYYMMDDhhmm to time-since-unix-epoch
+ try:
+ mingood = time.mktime(time.strptime(update, "%Y%m%d%H%M"))
+ # Never use a mirror more than a week old
+ mingood = max(mingood, base_time - 3*24*60*60)
+ except:
+ # if we didn't get a time, or we can't convert it, then
+ # use the time the mirror database was last updated minus 24 hours
+ mingood = base_time - 24*60*60
+
+ # Load the mirrors file and parse it out
+ data = parse_mirrors(mirrors, region, preferred, mingood)
+
+ # Note location to self
+ data['location'] = environ.get('SCRIPT_NAME', DEFAULT_LOCATION)
+
+ path_param = form.getfirst("path", None)
+ if path_param:
+ path_info = cgi.escape(path_param, 1)
+ else:
+ # Note any PATH_INFO
+ if environ.has_key('PATH_INFO'):
+ path_info = cgi.escape(environ['PATH_INFO'], 1)
+ if environ.has_key('SCRIPT_NAME'):
+ if environ['PATH_INFO'] == environ['SCRIPT_NAME']:
+ path_info = ''
+ else:
+ path_info = ''
+ # The mirror URL already has a trailing slash. Avoid doubling it up.
+ if path_info.startswith('/'):
+ path_info = path_info[1:]
+ data['path_info'] = path_info
+
+ template_file = locate_template(environ)
+ content_type = 'text/html'
+ output = cStringIO.StringIO()
+
+ json_param = form.getfirst("asjson", None) or form.getfirst("as_json", None)
+ if json_param:
+ output.write(json.dumps(data, sort_keys=True, indent=4))
+ content_type = 'text/plain' ;
+ else:
+ # use xml if the filename ends with the magic '--xml' string
+ if template_file.endswith('--xml.html'):
+ content_type = 'text/xml' ;
+ # still need logo and link in case referenced by templates
+ data['logo'] = None
+ data['link'] = None
+ template = ezt.Template(template_file)
+ template.generate(output, data)
+
+ # Print out the CGI header component
+ headers.append(('Content-type', content_type))
+ start_response(resp_code, headers)
+
+ return [ output.getvalue() ]
+
+
+if __name__ == '__main__':
+ #from flup.server.fcgi import WSGIServer
+ from flup.server.cgi import WSGIServer
+ WSGIServer(mirrorwrap).run()
Added: incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.list
URL: http://svn.apache.org/viewvc/incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.list?rev=1664013&view=auto
==============================================================================
--- incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.list (added)
+++ incubator/taverna/site/trunk/content/updates/workbench/3.0/dev/mirrors.list Wed Mar 4 14:30:36 2015
@@ -0,0 +1,254 @@
+# Generated ; DO NOT EDIT
+# date : Thu Jan 15 01:19:53 2015 [UTC]
+# in : /usr/home/apmirror/mirrors/mirmon
+# by : mm-merge
+
+ftp at ftp://gd.tuwien.ac.at/pub/infosys/servers/http/apache/dist/ 1421248740
+ftp at ftp://mirror2.klaus-uwe.me/apache/ 0
+ftp be ftp://apache.belnet.be/mirrors/ftp.apache.org/ 1421187540
+ftp ca ftp://apache.mirror.iweb.ca/ 1421252341
+ftp ca ftp://apache.mirror.rafal.ca/pub/apache/ 1421237940
+ftp ca ftp://apache.sunsite.ualberta.ca/pub/apache/ 1421259541
+ftp ca ftp://mirror.csclub.uwaterloo.ca/apache/ 1421234341
+ftp ch ftp://mirror.switch.ch/mirror/apache/dist/ 1421277540
+ftp cr ftp://mirrors.ucr.ac.cr/apache/ 1421230741
+ftp cz ftp://mirror.hosting90.cz/apache/ 1421205540
+ftp de ftp://ftp-stud.hs-esslingen.de/pub/Mirrors/ftp.apache.org/dist/ 1421255940
+ftp de ftp://ftp.fau.de/apache/ 1421237940
+ftp de ftp://ftp.fu-berlin.de/unix/www/apache/ 1421263140
+ftp de ftp://ftp.halifax.rwth-aachen.de/apache/ 1421281140
+ftp de ftp://mirror.netcologne.de/apache.org/ 1421255940
+ftp fi ftp://ftp.funet.fi/pub/mirrors/apache.org/ 1421259540
+ftp fr ftp://mir1.ovh.net/ftp.apache.org/dist/ 1421277540
+ftp fr ftp://mirrors.ircam.fr/pub/apache/ 1421255940
+ftp gr ftp://ftp.cc.uoc.gr/mirrors/apache/ 1421273940
+ftp gr ftp://ftp.forthnet.gr/pub/www/apache/ 1421270340
+ftp hu ftp://crysys.hit.bme.hu/pub/apache/ 1421252340
+ftp hu ftp://xenia.sote.hu/pub/mirrors/www.apache.org/ 1421277540
+ftp it ftp://ftp.panu.it/pub/mirrors/apache/ 1421266740
+ftp it ftp://mirror.nohup.it/apache/ 1421230740
+ftp jp ftp://ftp.kddilabs.jp/infosystems/apache/ 1421259541
+ftp jp ftp://ftp.meisei-u.ac.jp/mirror/apache/dist/ 1421252341
+ftp jp ftp://ftp.riken.jp/net/apache/ 1421252341
+ftp lt ftp://apache.mirror.vu.lt/apache/ 1421241540
+ftp nl ftp://apache.proserve.nl/apache/ 1421273940
+ftp nl ftp://mirror.nl.webzilla.com/apache/ 1421266740
+ftp nl ftp://mirror1.spango.com/apache/ 1421270340
+ftp no ftp://apache.uib.no/pub/apache/ 1421263140
+ftp pk ftp://stingray.cyber.net.pk/apache/ 1421194740
+ftp pl ftp://ftp.piotrkosoft.net/pub/mirrors/ftp.apache.org/ 1421209140
+ftp pl ftp://ftp.task.gda.pl/pub/www/apache/dist/ 1421241540
+ftp pt ftp://mirrors.fe.up.pt/pub/apache/ 1421270340
+ftp tr ftp://ftp.itu.edu.tr/Mirror/Apache/ 1421198340
+ftp tw ftp://ftp.stu.edu.tw/Unix/Web/apache/ 1421266741
+ftp tw ftp://ftp.twaren.net/Unix/Web/apache/ 1421183941
+ftp uk ftp://ftp.mirrorservice.org/sites/ftp.apache.org/ 1421266740
+ftp us ftp://apache.cs.utah.edu/apache.org/ 1421277541
+ftp us ftp://apache.mirrors.pair.com/ 1421263141
+ftp us ftp://apache.mirrors.tds.net/pub/apache.org/ 1421273941
+ftp us ftp://ftp.osuosl.org/pub/apache/ 1421255941
+ftp us ftp://mirror.reverse.net/pub/apache/ 1421277541
+http Backup http://www.eu.apache.org/dist/ 1421284740
+http Backup http://www.us.apache.org/dist/ 1421281141
+http ar http://apache.dattatec.com/ 1421263141
+http ar http://apache.xfree.com.ar/ 1421248741
+http ar http://mirrors.dcarsat.com.ar/apache/ 1421277541
+http ar http://mirrors.nxnethosting.com/apache/ 1421245141
+http at http://mirror2.klaus-uwe.me/apache/ 0
+http at http://tweedo.com/mirror/apache/ 1421255940
+http au http://apache.mirror.digitalpacific.com.au/ 1421263141
+http au http://apache.mirror.serversaustralia.com.au/ 1421245141
+http au http://apache.mirror.uber.com.au/ 1421237941
+http au http://mirror.rackcentral.com.au/apache/ 1421241540
+http au http://mirror.ventraip.net.au/apache/ 1421241541
+http bd http://mirrors.ispros.com.bd/apache/ 1421259541
+http be http://apache.belnet.be/ 1421187540
+http be http://apache.cu.be/ 1421259540
+http bg http://apache.cbox.biz/ 1421255940
+http br http://ftp.unicamp.br/pub/apache/ 1421259541
+http br http://mirror.nbtelecom.com.br/apache/ 1421090341
+http by http://ftp.byfly.by/pub/apache.org/ 1421252340
+http ca http://apache.mirror.gtcomm.net/ 1421266741
+http ca http://apache.mirror.iweb.ca/ 1421252341
+http ca http://apache.mirror.rafal.ca/ 1421266740
+http ca http://apache.mirror.vexxhost.com/ 1421223541
+http ca http://apache.parentingamerica.com/ 1421270341
+http ca http://apache.sunsite.ualberta.ca/ 1421259541
+http ca http://mirror.csclub.uwaterloo.ca/apache/ 1421234341
+http ca http://mirror.its.dal.ca/apache/ 1421263141
+http ch http://mirror.switch.ch/mirror/apache/dist/ 1421212740
+http ch http://www.pirbot.com/mirrors/apache/ 1421223541
+http cn http://apache.dataguru.cn/ 1421043541
+http cn http://apache.fayea.com/ 1421248741
+http cn http://mirror.bit.edu.cn/apache/ 1421237940
+http cn http://mirrors.cnnic.cn/apache/ 1421227140
+http cn http://mirrors.hust.edu.cn/apache/ 1421281140
+http cr http://mirrors.ucr.ac.cr/apache/ 1421230741
+http cz http://apache.miloslavbrada.cz/ 1420910340
+http cz http://mirror.hosting90.cz/apache/ 1421205540
+http de http://apache.lauf-forum.at/ 1421248740
+http de http://apache.mirror.digionline.de/ 1421263140
+http de http://apache.mirror.iphh.net/ 1421281140
+http de http://apache.openmirror.de/ 1421248740
+http de http://artfiles.org/apache.org/ 1421277540
+http de http://ftp-stud.hs-esslingen.de/pub/Mirrors/ftp.apache.org/dist/ 1421277540
+http de http://ftp.fau.de/apache/ 1421237940
+http de http://ftp.halifax.rwth-aachen.de/apache/ 1421259540
+http de http://mirror.23media.de/apache/ 1421277540
+http de http://mirror.arcor-online.net/www.apache.org/ 1421245140
+http de http://mirror.dkd.de/apache/ 1421255940
+http de http://mirror.netcologne.de/apache.org/ 1421266740
+http de http://mirror.serversupportforum.de/apache/ 1421248740
+http de http://mirror.softaculous.com/apache/ 1421255940
+http de http://mirror.synyx.de/apache/ 1421273940
+http de http://mirrors.ae-online.de/apache/ 1421198340
+http dk http://ftp.download-by.net/apache/ 1421259540
+http dk http://mirrors.dotsrc.org/apache/ 1421277540
+http dk http://mirrors.rackhosting.com/apache/ 1421234340
+http es http://apache.rediris.es/ 1421252340
+http es http://ftp.cixug.es/apache/ 1421230740
+http fi http://mirror.netinch.com/pub/apache/ 1421205540
+http fi http://www.nic.funet.fi/pub/mirrors/apache.org/ 1421259540
+http fr http://apache.crihan.fr/dist/ 1421281140
+http fr http://apache.websitebeheerjd.nl/ 1421273941
+http fr http://mir2.ovh.net/ftp.apache.org/dist/ 1421248740
+http fr http://mirrors.ircam.fr/pub/apache/ 1421277540
+http fr http://wwwftp.ciril.fr/pub/apache/ 1421263140
+http gr http://apache.cc.uoc.gr/ 1421273940
+http gr http://apache.forthnet.gr/ 1421270340
+http gr http://apache.otenet.gr/dist/ 1421227140
+http gr http://apache.tsl.gr/ 1421252340
+http gr http://mirrors.myaegean.gr/apache/ 1421259540
+http hk http://apache.01link.hk/ 1421259541
+http hk http://apache.communilink.net/ 1421230741
+http hk http://ftp.cuhk.edu.hk/pub/packages/apache.org/ 1421266741
+http hr http://ftp.carnet.hr/misc/apache/ 1421252340
+http hu http://xenia.sote.hu/ftp/mirrors/www.apache.org/ 1421277540
+http ie http://ftp.heanet.ie/mirrors/www.apache.org/dist/ 1421259540
+http ie http://www.whoishostingthis.com/mirrors/apache/ 1421248740
+http il http://apache.mivzakim.net/ 1421252340
+http il http://apache.spd.co.il/ 1421230740
+http in http://apache.softmirror.in/ 1421259541
+http it http://apache.fastbull.org/ 1421198340
+http it http://apache.panu.it/ 1421266740
+http it http://it.apache.contactlab.it/ 1421281140
+http it http://mirror.nohup.it/apache/ 1421230740
+http it http://mirrors.muzzy.it/apache/ 1421237941
+http jp http://ftp.jaist.ac.jp/pub/apache/ 1421252341
+http jp http://ftp.kddilabs.jp/infosystems/apache/ 1421259541
+http jp http://ftp.meisei-u.ac.jp/mirror/apache/dist/ 1421252341
+http jp http://ftp.riken.jp/net/apache/ 1421273941
+http jp http://ftp.tsukuba.wide.ad.jp/software/apache/ 1421266741
+http jp http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/ 1421266741
+http kr http://apache.mirror.cdnetworks.com/ 1421180341
+http kr http://apache.tt.co.kr/ 1421266741
+http kr http://mirror.apache-kr.org/ 1421266741
+http li http://apache.mirror.telecom.li/ 1421273940
+http lt http://apache.mirror.serveriai.lt/ 1421241540
+http lt http://apache.mirror.vu.lt/apache/ 1421241540
+http mx http://apache.webxcreen.org/ 0
+http nc http://mirror.lagoon.nc/pub/apache/ 1421237941
+http nl http://apache.cs.uu.nl/ 1421277540
+http nl http://apache.hippo.nl/ 1421245140
+http nl http://apache.mirror.triple-it.nl/ 1421263140
+http nl http://apache.mirror1.spango.com/ 1421270340
+http nl http://apache.proserve.nl/ 1421273940
+http nl http://apache.xl-mirror.nl/ 1421259540
+http nl http://ftp.nluug.nl/internet/apache/ 1421237940
+http nl http://ftp.tudelft.nl/apache/ 1421273940
+http nl http://mirror.nl.webzilla.com/apache/ 0
+http nl http://mirrors.supportex.net/apache/ 1421255940
+http no http://apache.uib.no/ 1421263140
+http no http://apache.vianett.no/ 1421263141
+http pk http://stingray.cyber.net.pk/pub/apache/ 1421194740
+http pl http://ftp.piotrkosoft.net/pub/mirrors/ftp.apache.org/ 1421209140
+http pl http://ftp.ps.pl/pub/apache/ 1421281140
+http pt http://mirrors.fe.up.pt/pub/apache/ 1421270340
+http ro http://mirrors.hostingromania.ro/apache.org/ 1421273940
+http ru http://apache-mirror.rbc.ru/pub/apache/ 1421248740
+http sa http://mirrors.isu.net.sa/pub/apache/ 1421255940
+http se http://apache.mirrors.spacedump.net/ 1421263140
+http sg http://mirror.nus.edu.sg/apache/ 1421263141
+http si http://www.apache.si/ 1421234340
+http sk http://tux.rainside.sk/apache/ 1421255940
+http th http://mirror.issp.co.th/apache/ 1421266741
+http tr http://ftp.itu.edu.tr/Mirror/Apache/ 1421198340
+http tw http://apache.stu.edu.tw/ 1421266741
+http tw http://ftp.mirror.tw/pub/apache/ 1421259541
+http tw http://ftp.tc.edu.tw/pub/Apache/ 1421270341
+http tw http://ftp.twaren.net/Unix/Web/apache/ 1421270341
+http ua http://apache.cp.if.ua/ 1421201940
+http ua http://apache.ip-connect.vn.ua/ 1421266740
+http ua http://apache.volia.net/ 1421241540
+http uk http://apache.mirror.anlx.net/ 1421237940
+http uk http://apache.mirrors.timporter.net/ 1421255940
+http uk http://mirror.catn.com/pub/apache/ 1421248740
+http uk http://mirror.gopotato.co.uk/apache/ 1421259540
+http uk http://mirror.ox.ac.uk/sites/rsync.apache.org/ 1421259540
+http uk http://mirror.vorboss.net/apache/ 1421255940
+http uk http://mirrors.ukfast.co.uk/sites/ftp.apache.org/ 1421259540
+http uk http://www.mirrorservice.org/sites/ftp.apache.org/ 1421266740
+http us http://apache.arvixe.com/ 1421263141
+http us http://apache.claz.org/ 1421259541
+http us http://apache.cs.utah.edu/ 1421263141
+http us http://apache.mesi.com.ar/ 1421263141
+http us http://apache.mirrors.hoobly.com/ 1421263141
+http us http://apache.mirrors.lucidnetworks.net/ 1421255941
+http us http://apache.mirrors.pair.com/ 1421248741
+http us http://apache.mirrors.tds.net/ 1421273941
+http us http://apache.osuosl.org/ 1421255941
+http us http://apache.petsads.us/ 1421273940
+http us http://apache.spinellicreations.com/ 1421212741
+http us http://apache.tradebit.com/pub/ 1421259541
+http us http://download.nextag.com/apache/ 1421223541
+http us http://mirror.cc.columbia.edu/pub/software/apache/ 1421255941
+http us http://mirror.cogentco.com/pub/apache/ 1421259541
+http us http://mirror.metrocast.net/apache/ 1421255941
+http us http://mirror.nexcess.net/apache/ 1421255941
+http us http://mirror.olnevhost.net/pub/apache/ 1421270341
+http us http://mirror.reverse.net/pub/apache/ 1421255941
+http us http://mirror.sdunix.com/apache/ 1421259541
+http us http://mirror.symnds.com/software/Apache/ 1421263141
+http us http://mirror.tcpdiag.net/apache/ 1421234341
+http us http://mirrors.advancedhosters.com/apache/ 1421237941
+http us http://mirrors.gigenet.com/apache/ 1421255941
+http us http://mirrors.ibiblio.org/apache/ 1421216341
+http us http://mirrors.koehn.com/apache/ 1421263141
+http us http://mirrors.sonic.net/apache/ 1421252341
+http us http://psg.mtu.edu/pub/apache/ 1421255941
+http us http://supergsego.com/apache/ 1421273941
+http us http://www.carfab.com/apachesoftware/ 1421230741
+http us http://www.eng.lsu.edu/mirrors/apache/ 1421227141
+http us http://www.gtlib.gatech.edu/pub/apache/ 1421241541
+http us http://www.interior-dsgn.com/apache/ 1421234341
+http us http://www.motorlogy.com/apache/ 1421237941
+http us http://www.trieuvan.com/apache/ 1421241541
+http us http://www.webhostingjams.com/mirror/apache/ 1421277540
+http vn http://mirrors.digipower.vn/apache/ 1421259541
+http vn http://mirrors.viethosting.vn/apache/ 1421252341
+http za http://apache.is.co.za/ 1421270340
+http za http://apache.saix.net/ 1421263140
+rsync Backup rsync://rsync.eu.apache.org/apache-dist/ 1421284740
+rsync Backup rsync://rsync.us.apache.org/apache-dist/ 1421281141
+rsync au rsync://mirror.digitalpacific.com.au/apache/ 1421263141
+rsync au rsync://mirror.rackcentral.com.au/apache/ 1421241540
+rsync au rsync://mirror.uber.com.au/apache/ 1421281141
+rsync ca rsync://mirror.its.dal.ca/apache/ 1421263141
+rsync ca rsync://mirror.vexxhost.com/apache/ 1421223541
+rsync ch rsync://rsync.pirbot.com/ftp/apache/ 1421223541
+rsync de rsync://ftp.fau.de/apache/ 1421237940
+rsync de rsync://mirror.23media.de/apache/ 1421277540
+rsync in rsync://apache.softmirror.in/apache/ 1421259541
+rsync nc rsync://mirror.lagoon.nc/pub/apache/ 1421237941
+rsync nl rsync://ftp.nluug.nl/Apache/ 1421237940
+rsync nl rsync://mirror.nl.webzilla.com/apache/ 1421266740
+rsync nl rsync://mirror.triple-it.nl/apache/ 1421281140
+rsync nl rsync://rsync.cs.uu.nl/apache-dist/ 1421277540
+rsync pl rsync://ftp.piotrkosoft.net/mirrors/ftp.apache.org/ 1421209140
+rsync ua rsync://apache.ip-connect.vn.ua/apache/ 1421237940
+rsync ua rsync://apache.volia.net/apache-dist/ 1421270340
+rsync us rsync://apache.cs.utah.edu/apache-dist/ 1421263141
+rsync us rsync://apache.mirrors.lucidnetworks.net/apache-dist/ 1421255941
+rsync us rsync://mirrors.advancedhosters.com/apache/ 1421237941
+rsync us rsync://mirrors.ibiblio.org/apache/ 1421216341
+rsync vn rsync://mirrors.viethosting.vn/apache/ 1421273941