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 = (
+  ('&', '&amp;'), ('<', '&lt;'), ('>', '&gt;'),
+  ('"', '&quot;'), ('\'', '&#39;'),
+)
+
+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