This is an automated email from the ASF dual-hosted git repository.
rubys pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git
The following commit(s) were added to refs/heads/master by this push:
new 84aaa54 move secmail to workbench
84aaa54 is described below
commit 84aaa54ec98334ab5f80a5c3c3edb55957d1ec02
Author: Sam Ruby <[email protected]>
AuthorDate: Fri Apr 21 17:20:47 2017 -0400
move secmail to workbench
---
www/index.html | 1 -
www/secmail/Gemfile | 27 -
www/secmail/README | 85 --
www/secmail/public/spinner.gif | Bin 673 -> 0 bytes
www/{secmail => secretary/workbench}/.gitignore | 0
www/secretary/workbench/Gemfile | 22 +-
www/secretary/workbench/HOWTO.html | 179 ---
www/secretary/workbench/README | 96 +-
www/{secmail => secretary/workbench}/Rakefile | 0
www/secretary/workbench/ccla.erb | 13 -
www/{secmail => secretary/workbench}/config.rb | 0
www/{secmail => secretary/workbench}/config.ru | 0
www/{secmail => secretary/workbench}/deliver.rb | 0
www/secretary/workbench/file.cgi | 1138 --------------------
www/secretary/workbench/grant.erb | 13 -
www/{secmail => secretary/workbench}/helpers.rb | 0
www/secretary/workbench/icla.erb | 19 -
www/secretary/workbench/incomplete.erb | 16 -
www/secretary/workbench/index.html | 10 -
www/secretary/workbench/jquery-1.7.2.min.js | 4 -
www/secretary/workbench/jquery.timeago.js | 152 ---
www/secretary/workbench/local_paths.rb | 40 -
www/secretary/workbench/local_paths.yml | 6 -
www/secretary/workbench/mem.erb | 15 -
.../workbench}/models/attachment.rb | 0
.../workbench}/models/events.rb | 0
.../workbench}/models/mailbox.rb | 0
.../workbench}/models/message.rb | 0
.../workbench}/models/safetemp.rb | 0
www/secretary/workbench/nda.erb | 13 -
www/{secmail => secretary/workbench}/parsemail.rb | 0
.../workbench}/personalize.rb | 0
.../workbench}/public/HOWTO.html | 7 +-
.../workbench}/public/assets/bootstrap-min.css | 0
.../workbench}/public/assets/bootstrap-min.js | 0
.../workbench}/public/assets/jquery-min.js | 0
.../workbench}/public/assets/react-min.js | 0
.../workbench}/public/fetch.js | 0
.../workbench}/public/secmail.css | 0
www/secretary/workbench/{ => public}/spinner.gif | Bin
.../workbench}/public/tasklist.js | 0
www/secretary/workbench/publickey.erb | 16 -
www/secretary/workbench/secmail.rb | 52 -
www/{secmail => secretary/workbench}/server.rb | 0
www/{secmail => secretary/workbench}/tasks.rb | 0
.../workbench}/templates/acreq.erb | 0
.../workbench}/templates/ccla.erb | 0
.../workbench}/templates/grant.erb | 0
.../templates/icla-account-requested.erb | 0
.../workbench}/templates/icla-pmc-notified.erb | 0
.../workbench}/templates/icla.erb | 0
.../workbench}/templates/incomplete.erb | 0
.../workbench}/templates/mem.erb | 0
.../workbench}/templates/nda.erb | 0
.../workbench}/templates/pubkey.erb | 0
.../workbench}/templates/unsigned.erb | 0
.../workbench}/tmp/.gitignore | 0
www/secretary/workbench/unsigned.erb | 15 -
www/secretary/workbench/upload.cgi | 48 -
.../workbench}/views/actions/burst.json.rb | 0
.../workbench}/views/actions/ccla.json.rb | 0
.../workbench}/views/actions/check-id.json.rb | 0
.../workbench}/views/actions/check-mail.json.rb | 0
.../views/actions/check-signature.json.rb | 0
.../views/actions/delete-attachment.json.rb | 0
.../workbench}/views/actions/drop.json.rb | 0
.../workbench}/views/actions/forward.json.rb | 0
.../workbench}/views/actions/grant.json.rb | 0
.../workbench}/views/actions/icla.json.rb | 0
.../workbench}/views/actions/incomplete.json.rb | 0
.../workbench}/views/actions/memapp.json.rb | 0
.../workbench}/views/actions/pdfize.json.rb | 0
.../workbench}/views/actions/pubkey.json.rb | 0
.../views/actions/rotate-attachment.json.rb | 0
.../workbench}/views/actions/unsigned.json.rb | 0
.../workbench}/views/actions/update-mail.json.rb | 0
.../workbench}/views/app.js.rb | 0
.../workbench}/views/asciize.js.rb | 0
.../workbench}/views/body.html.rb | 0
.../workbench}/views/check-signature.js.rb | 0
.../workbench}/views/context-menu.js.rb | 0
.../workbench}/views/danger.html.rb | 0
.../workbench}/views/forms/ccla.js.rb | 0
.../workbench}/views/forms/forward.js.rb | 0
.../workbench}/views/forms/grant.js.rb | 0
.../workbench}/views/forms/icla.js.rb | 0
.../workbench}/views/forms/memapp.js.rb | 0
.../workbench}/views/forms/nda.js.rb | 0
.../workbench}/views/headers.html.rb | 0
.../workbench}/views/http.js.rb | 0
.../workbench}/views/index.html.rb | 0
.../workbench}/views/index.js.rb | 0
.../workbench}/views/index.json.rb | 0
.../workbench}/views/memapp.json.rb | 0
.../workbench}/views/message.html.rb | 0
.../workbench}/views/parts.html.rb | 0
.../workbench}/views/parts.js.rb | 0
.../workbench}/views/status.js.rb | 0
.../workbench}/views/tasklist.html.rb | 0
www/secretary/workbench/worklist.cgi | 658 -----------
www/secretary/workbench/worklist.css | 23 -
www/secretary/workbench/worklist.js | 228 ----
102 files changed, 98 insertions(+), 2798 deletions(-)
diff --git a/www/index.html b/www/index.html
index 9591b66..7f1e888 100644
--- a/www/index.html
+++ b/www/index.html
@@ -189,7 +189,6 @@
<li><a href="secretary/icla-lint">Lint test for
iclas.txt</a></li>
<li><a href="secretary/public-names">Public names: LDAP vs
icla.txt</a></li>
<li><a href="secretary/response-time">Response time
test</a></li>
- <li><a href="secmail/">Secretary Mail</a> (experimental)</li>
</ul>
</div>
</div>
diff --git a/www/secmail/Gemfile b/www/secmail/Gemfile
deleted file mode 100644
index ec4b3eb..0000000
--- a/www/secmail/Gemfile
+++ /dev/null
@@ -1,27 +0,0 @@
-source 'https://rubygems.org'
-
-root = '../../..'
-version_file = File.expand_path("#{root}/asf.version", __FILE__)
-if File.exist? version_file
- # for deployment and local testing
- asf_version = File.read(version_file).chomp
- gem 'whimsy-asf', asf_version, path: File.expand_path(root, __FILE__)
-else
- # for docker purposes (atleast for now)
- gem 'whimsy-asf'
-end
-
-gem 'mail'
-gem 'rake'
-gem 'zip'
-gem 'sinatra', '~> 1.4'
-gem 'sanitize'
-gem 'wunderbar', '~> 1.0.27'
-gem 'ruby2js', '~> 2.0.12'
-gem 'execjs'
-gem 'listen', ('~> 3.0.7' if RUBY_VERSION =~ /^2\.[01]/)
-gem 'escape'
-
-group :demo do
- gem 'puma'
-end
diff --git a/www/secmail/README b/www/secmail/README
deleted file mode 100644
index 14ec74e..0000000
--- a/www/secmail/README
+++ /dev/null
@@ -1,85 +0,0 @@
-This directory contains a script that fetches and parsed secretary emails
-and a server that will enable exploration of those emails.
-
-
-Usage:
-
- rake fetch
- rake server
-
-Notes:
-
- First fetch and parse will take approximately an hour, even with a relatively
- fast machine and internet connection. Subsequent fetches will take as
- little as ten seconds or less. (For the impatient: replace 'fetch' with
- 'fetch1' and you will only get the latest month. At some later point,
- running 'rake fetch' will fetch the remaining months as well as any new
- emails that have arrived in the current month).
-
- Secretary email archive currently requires about approximately 11 Gigabytes.
-
- Some functions will require installations of gpg, imageMagick and pdftk.
-
- OS X El Capitan users may want to look at:
- http://stackoverflow.com/a/33248310
-
-Overview of files:
-
- Gemfile: Ruby configuration (installation of gems)
- Rakefile: Command line configuration (like 'make')
- config.rb: Customizations
- config.ru: Rack (webserver) configuration
- mailbox.rb: Encapsulate interface to wb server
- officers-secretary: local copy of mailboxes and indexes (in YAML format)
- parsemail.rb: Fetch and parse emails
- server.rb: Web interface to emails
- views: HTML templates (in Wunderbar format)
-
-Overview of control flow:
-
- server.rb: Matches HTTP requests to methods and paths, and runs
- the associated code. This code will either return a
- result directly (rare) or invoke a view using a method
- name starting with an underscore. For more
- information, see:
-
- http://www.sinatrarb.com/documentation.html
- https://github.com/rubys/wunderbar/#readme
-
- views: Files in the views directory have two extensions, the
- first identifies the target type (html, json, js), the
- second indicates the language of the view (rb).
-
- html views: Method names that start with an underscore generate HTML.
- This HTML may pull in scripts, stylesheets, and have
- inline code that renders other views. Views in the
- actions subdirectory produce responses to HTTP post
- requests.
-
- js views: This code is converted from Ruby to JavaScript.
- This conversion is aware of React.js and will perform
- additional React.js mappings when it encounters classes
- that derive from "React". See
-
-
https://facebook.github.io/react/docs/component-specs.html
- https://github.com/rubys/ruby2js#readme
-
- Note: in this application app.js.rb pulls in all of the
- other javascript files and returns the result as a
- single file.
-
- json views: The last statement identifies an object (typically a
- hash or array) that will be converted to JSON and sent
- back as a response.
-
-Model:
-
- mailbox.rb: read-only interface to a mailbox files found in
- officers-secretary as well as read/write interface
- to accompanying YAML file.
-
- message.rb: representation of an individual message, backed by
- both the mbox file and the YAML file.
-
- attachment.rb: representation of an individual attachment, backed by
- both the mbox file and the YAML file.
diff --git a/www/secmail/public/spinner.gif b/www/secmail/public/spinner.gif
deleted file mode 100644
index d0bce15..0000000
Binary files a/www/secmail/public/spinner.gif and /dev/null differ
diff --git a/www/secmail/.gitignore b/www/secretary/workbench/.gitignore
similarity index 100%
rename from www/secmail/.gitignore
rename to www/secretary/workbench/.gitignore
diff --git a/www/secretary/workbench/Gemfile b/www/secretary/workbench/Gemfile
index 2924c4b..ec4b3eb 100644
--- a/www/secretary/workbench/Gemfile
+++ b/www/secretary/workbench/Gemfile
@@ -1,15 +1,27 @@
source 'https://rubygems.org'
-root = '../../../..'
+root = '../../..'
version_file = File.expand_path("#{root}/asf.version", __FILE__)
if File.exist? version_file
# for deployment and local testing
asf_version = File.read(version_file).chomp
gem 'whimsy-asf', asf_version, path: File.expand_path(root, __FILE__)
+else
+ # for docker purposes (atleast for now)
+ gem 'whimsy-asf'
end
-gem 'mime-types', ('~> 2.99' if RUBY_VERSION < '2')
-
-gem 'wunderbar'
-gem 'escape'
gem 'mail'
+gem 'rake'
+gem 'zip'
+gem 'sinatra', '~> 1.4'
+gem 'sanitize'
+gem 'wunderbar', '~> 1.0.27'
+gem 'ruby2js', '~> 2.0.12'
+gem 'execjs'
+gem 'listen', ('~> 3.0.7' if RUBY_VERSION =~ /^2\.[01]/)
+gem 'escape'
+
+group :demo do
+ gem 'puma'
+end
diff --git a/www/secretary/workbench/HOWTO.html
b/www/secretary/workbench/HOWTO.html
deleted file mode 100644
index 8c1304e..0000000
--- a/www/secretary/workbench/HOWTO.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
- <TITLE></TITLE>
- <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.4.1 (Unix)">
- <META NAME="AUTHOR" CONTENT="Craig Russell">
- <META NAME="CREATED" CONTENT="20110814;13503500">
- <META NAME="CHANGEDBY" CONTENT="Craig Russell">
- <META NAME="CHANGED" CONTENT="20130406;14553000">
- <META NAME="CHANGEDBY" CONTENT="Craig Russell">
- <META NAME="CHANGEDBY" CONTENT="Craig Russell">
- <STYLE TYPE="text/css">
- <!--
- @page { margin: 0.79in }
- P { margin-bottom: 0.08in }
- A:link { so-language: zxx }
- -->
- </STYLE>
-</HEAD>
-<BODY LANG="en-US" DIR="LTR">
-<P STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><FONT
SIZE=3>This
-tool helps file documents received via fax or email.</FONT></FONT></P>
-<P STYLE="margin-bottom: 0in"><BR>
-</P>
-<OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman,
serif"><FONT SIZE=3>Documents
- to be filed appear in the Work List area. </FONT></FONT>
- </P>
- <OL TYPE=A>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>Documents
- that are received via fax appear as .pdf files with an eFax
prefix.
- These documents can be processed directly. There is no metadata
- associated with these documents, so all information must be
entered
- manually.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>Documents
- that are received via email are in one of two forms. Metadata
- associated with the documents includes the sender's email
address
- and name. This metadata will populate certain forms for specific
- document types.</FONT></FONT></FONT></P>
- <OL TYPE=i>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- an email is received with a single document to be
processed that
- document will appear by itself. </FONT></FONT></FONT>
- </P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- an email is received with multiple documents, all of
the documents
- will be put into a single directory and the directory
appears in
- the work list.</FONT></FONT></FONT></P>
- </OL>
- </OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>To
- convert documents to a form that can be processed, select the
- directory from the Work List. The contents of the directory will be
- displayed on the view port. </FONT></FONT></FONT>
- </P>
- <OL TYPE=A>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>If
- the documents are a file and a signature (e.g. icla.txt and
- icla.txt.asc) the tool will attempt to verify the document via
the
- command "gpg --verify icla.txt.asc". The results of
the
- verification are displayed in the view port along with the list
of
- documents. If the document verifies correctly, it can be
processed
- as if it were a document. </FONT></FONT></FONT>
- </P>
- <OL TYPE=i>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the document does not verify because the public key is
not
- available, try to download the key from a public key
server via
- the command "gpg --recv-keys
<pub-key>". After the
- key is downloaded, you can try
again.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the document does not verify because the signature is
BAD, contact
- the sender and attempt to get the document in a
different mode.</FONT></FONT></FONT></P>
- </OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>If
- the documents are a collection of documents, they can be turned
- into individual documents via the Staple command in the view
port. </FONT></FONT></FONT>
- </P>
- <OL TYPE=i>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the documents comprise a single document, e.g.
icla1.pdf,
- icla2.pdf, select both documents and press the Staple
key. Both
- documents will be combined into a single .pdf document
and
- displayed in the Work List. This technique currently
works for
- .pdf and .jpg files.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the documents comprise multiple independent documents,
select a
- single document and press Staple. The single document
will be
- copied into a new document with the same metadata and
placed into
- the Work List. This technique currently works for .pdf
and .jpg
- files.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>For
- each document in the collection, after stapling the
document is
- ready for processing.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>After
- all documents have been processed, check to make sure
the
- directory has been deleted by using the "svn
status"
- command. [The directory will not appear in the Work
List if it is
- empty.] If not, remove it manually using the "svn
rm"
- command.</FONT></FONT></FONT></P>
- </OL>
- </OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>To
- process a document, select it from the Work List. If it is
- displayable, the document will appear in the view port. All
- documents must be complete and legible. Multipage documents must
- have all pages included (specifically, not just the first and last
- page) in the same transmission. </FONT></FONT></FONT>
- </P>
- <OL TYPE=A>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>ICLAs:
- Required fields are full name, email address, signature, and
date.
- If there is already an existing ICLA for the same name, you must
- establish whether the existing document is for the same person.
</FONT></FONT></FONT>
- </P>
- <OL TYPE=i>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the existing document is for the same person, process
the new ICLA
- with a different file name (e.g. existing-name2.pdf)
and before
- completing the process, create a directory (e.g.
existing-name/)
- and move both existing-name.pdf and existing-name2.pdf
into the
- new directory.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>If
- the existing document is for a different person,
contact the
- submitter and see if there is an additional (middle)
name that can
- be used in the "Full Name" section. If not,
see if there
- is a title that can be used to distinguish the
entries.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT
COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Try
- to determine if the ICLA is from a person who should be
given
- commit access. Read the original email containing the
document,
- look at the "notify PMC" field on the form,
and search
- the email records to determine if the ICLA is in
response to an
- invitation from a PMC or PPMC. If there is a valid
invitation from
- a PMC, select the url of the invitation so it can be
pasted into
- the ICLA form below the "file"
button.</FONT></FONT></FONT></P>
- </OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>If
- the acknowledgement email to the ICLA submitter bounces, try to
- resolve the issue. Common reasons for bounced emails are typos
due
- to illegible ICLAs or ambiguous special symbols, such as
"-"
- for "_", "0" for "o". Note that
email
- addresses are case-insensitive. If the proper email address
cannot
- be obtained, manually edit the foundation/officers/iclas.txt
file
- and change the incorrect email address. The address can be
changed,
- for example, from "<A
HREF="mailto:[email protected]">[email protected]</A>"
- to "Bounced Email< <A
HREF="mailto:[email protected]">[email protected]</A>>".</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>CCLAs
- must be signed by an officer of the corporation authorized to
enter
- into binding contracts. Required fields are corporation name,
- contact, and email address. </FONT></FONT></FONT>
- </P>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>NDAs
- require the apache id.</FONT></FONT></FONT></P>
- </OL>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>If
- there are duplicate documents to be processed, after processing the
- best document, remove the duplicates before committing. Choose
- "other" "junk" from the menu. After removing all
- duplicates, commit the batch.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>After
- processing an ICLA, if the sender should have an account created,
- select "New Account" from the menu. The last ICLA should
- appear in the "ASF New Account Request" form. In
- "Comments" indicate "original committer" if the
- ICLA is from a new podling. Otherwise, leave it
blank.</FONT></FONT></FONT></P>
- <LI><P STYLE="margin-bottom: 0in"><FONT COLOR="#000000"><FONT
FACE="Times New Roman, serif"><FONT SIZE=3>Forms
- received by other than the above process should be added to the
- documents/received directory and added via "svn add". The
- document will then appear in the work list to be processed as above.
- Documents that are not in the proper format should be converted to
- .pdf before adding them.</FONT></FONT></FONT></P>
-</OL>
-<P STYLE="margin-bottom: 0in"><BR>
-</P>
-<P STYLE="margin-bottom: 0in"><BR>
-</P>
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/www/secretary/workbench/README b/www/secretary/workbench/README
index 89db1ff..14ec74e 100644
--- a/www/secretary/workbench/README
+++ b/www/secretary/workbench/README
@@ -1,27 +1,85 @@
-This tool help file documents received via fax or email.
+This directory contains a script that fetches and parsed secretary emails
+and a server that will enable exploration of those emails.
-See HOWTO.html for usage.
-General design of the tool:
+Usage:
-*) configuration is done using local_paths.yml. Format is a series of
- names followed by locations. Most are directories where svn checkouts
- reside. 'mail' is a path to a ruby script that sets Mail.defaults as
- well as @from and @sig.
+ rake fetch
+ rake server
-*) index.html splits the window into two panes using old-school frames.
+Notes:
-*) worklist.cgi, worklist.css, and worklist.js are primarily responsible
- for the left pane. This is mostly an HTML forms processing, with a lot
- of JavaScript to assist.
+ First fetch and parse will take approximately an hour, even with a relatively
+ fast machine and internet connection. Subsequent fetches will take as
+ little as ten seconds or less. (For the impatient: replace 'fetch' with
+ 'fetch1' and you will only get the latest month. At some later point,
+ running 'rake fetch' will fetch the remaining months as well as any new
+ emails that have arrived in the current month).
-*) file.cgi is responsible for the right pane. This is where most of the
- server logic resides, and mostly involves invoking underlying system
- commands (e.g., svn, pdftk, convert, gpg) and returning the results as
- HTML.
+ Secretary email archive currently requires about approximately 11 Gigabytes.
-*) ccla.erb, grant.erb, icla.erb, mem.erb, and nda.erb are mail templates
- of confirmation replies sent back when the document is processed.
+ Some functions will require installations of gpg, imageMagick and pdftk.
-*) The tool assumes that the url /members/received is a symlink to a checkout
- of https://svn.apache.org/repos/private/documents/received
+ OS X El Capitan users may want to look at:
+ http://stackoverflow.com/a/33248310
+
+Overview of files:
+
+ Gemfile: Ruby configuration (installation of gems)
+ Rakefile: Command line configuration (like 'make')
+ config.rb: Customizations
+ config.ru: Rack (webserver) configuration
+ mailbox.rb: Encapsulate interface to wb server
+ officers-secretary: local copy of mailboxes and indexes (in YAML format)
+ parsemail.rb: Fetch and parse emails
+ server.rb: Web interface to emails
+ views: HTML templates (in Wunderbar format)
+
+Overview of control flow:
+
+ server.rb: Matches HTTP requests to methods and paths, and runs
+ the associated code. This code will either return a
+ result directly (rare) or invoke a view using a method
+ name starting with an underscore. For more
+ information, see:
+
+ http://www.sinatrarb.com/documentation.html
+ https://github.com/rubys/wunderbar/#readme
+
+ views: Files in the views directory have two extensions, the
+ first identifies the target type (html, json, js), the
+ second indicates the language of the view (rb).
+
+ html views: Method names that start with an underscore generate HTML.
+ This HTML may pull in scripts, stylesheets, and have
+ inline code that renders other views. Views in the
+ actions subdirectory produce responses to HTTP post
+ requests.
+
+ js views: This code is converted from Ruby to JavaScript.
+ This conversion is aware of React.js and will perform
+ additional React.js mappings when it encounters classes
+ that derive from "React". See
+
+
https://facebook.github.io/react/docs/component-specs.html
+ https://github.com/rubys/ruby2js#readme
+
+ Note: in this application app.js.rb pulls in all of the
+ other javascript files and returns the result as a
+ single file.
+
+ json views: The last statement identifies an object (typically a
+ hash or array) that will be converted to JSON and sent
+ back as a response.
+
+Model:
+
+ mailbox.rb: read-only interface to a mailbox files found in
+ officers-secretary as well as read/write interface
+ to accompanying YAML file.
+
+ message.rb: representation of an individual message, backed by
+ both the mbox file and the YAML file.
+
+ attachment.rb: representation of an individual attachment, backed by
+ both the mbox file and the YAML file.
diff --git a/www/secmail/Rakefile b/www/secretary/workbench/Rakefile
similarity index 100%
rename from www/secmail/Rakefile
rename to www/secretary/workbench/Rakefile
diff --git a/www/secretary/workbench/ccla.erb b/www/secretary/workbench/ccla.erb
deleted file mode 100644
index fc031dd..0000000
--- a/www/secretary/workbench/ccla.erb
+++ /dev/null
@@ -1,13 +0,0 @@
-to: <%= contact.inspect %> <<%= cemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Your CCLA sent to Apache Secretary
-
-Dear <%= contact %>,
-
-This message acknowledges receipt of the following document, which has been
filed in the Apache Software Foundation records:
-
- <%= commit_message %>
-
-<%= sig %>
diff --git a/www/secmail/config.rb b/www/secretary/workbench/config.rb
similarity index 100%
rename from www/secmail/config.rb
rename to www/secretary/workbench/config.rb
diff --git a/www/secmail/config.ru b/www/secretary/workbench/config.ru
similarity index 100%
rename from www/secmail/config.ru
rename to www/secretary/workbench/config.ru
diff --git a/www/secmail/deliver.rb b/www/secretary/workbench/deliver.rb
similarity index 100%
rename from www/secmail/deliver.rb
rename to www/secretary/workbench/deliver.rb
diff --git a/www/secretary/workbench/file.cgi b/www/secretary/workbench/file.cgi
deleted file mode 100755
index f24ebf8..0000000
--- a/www/secretary/workbench/file.cgi
+++ /dev/null
@@ -1,1138 +0,0 @@
-#!/usr/bin/env ruby
-$LOAD_PATH.unshift File.realpath(File.expand_path('../../../../lib', __FILE__))
-
-require 'wunderbar'
-require 'open3'
-require './local_paths'
-require 'fileutils'
-require 'ostruct'
-require 'escape'
-require 'time'
-require 'whimsy/asf'
-
-ENV['LANG'] = 'en_US.UTF-8'
-
-ENV['GNUPGHOME'] = '/srv/gpg' if Dir.exist?('/srv/gpg')
-
-def html_fragment(&block)
- x = Wunderbar::HtmlMarkup.new({})
- x.instance_eval(&block)
- x._.target!
-end
-
-OLDPODLINGS = [
- 'allura',
- 'ambari',
- 'blur',
- 'celix',
- 'chukwa',
- 'deltaspike',
- 'devicemap',
- 'drill',
- 'droids',
- 'hcatalog',
- 'jspwiki',
- 'kafka',
- 'kalumet',
- 'mesos',
- 'npanday',
- 'odf',
- 'onami',
- 's4',
- 'tashi',
- 'vxquery',
- 'wave'
-]
-
-def update_pending fields, dest
- # start with the fields provided
- fields = Hash[fields]
-
- # reject blank fields, normalize the rest
- fields.reject! {|k,v| v == [""]}
- fields.each_key {|k| fields[k]=fields[k].join(' ')}
-
- # add properties from svn
- at = svn_at(dest)
- at += '/*' if File.directory?(dest) and `svn proplist #{dest}#{at}`.empty?
- `svn proplist #{dest}#{at}`.scan(/ \w+:[-\w]+/).each do |prop|
- prop.untaint if prop.strip =~ /^\w+(:\w+)/
- value = `svn propget #{prop} #{dest}#{at}`.chomp
- value.gsub!(/\\x[0-9a-fA-F][0-9a-fA-F]/) {|c| [c[2..3].to_i(16)].pack('C')}
- value.gsub!(/\\[0-7][0-7][0-7]/) {|c| [c[1..3].to_i(8)].pack('C')}
- fields[prop.strip] = value
- end
-
- # copy email field
- fields['email'] ||= fields['gemail'] || fields['cemail'] ||
- fields['nemail'] || fields['memail'] ||
- fields['iemail'] || fields['uemail'] || fields['pemail']
- fields.delete('email') unless fields['email']
-
- # Concatenate the fields to the pending list and write to disk
- pending = YAML.load(open(PENDING_YML)) rescue []
- pending << fields
- open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
-end
-
-class Wunderbar::XmlMarkup
- def move source, dest
- if not Dir.chdir(RECEIVED) {Dir['*']}.include? source.chomp('/')
- tag! :pre, "svn mv #{source.inspect} #{dest}", class: '_stdin'
- tag! :pre, "File #{source} doesn't exist.", class: '_stderr'
- return
- end
-
- source = File.expand_path(source, RECEIVED).untaint
- source += svn_at(source)
-
- if File.exist?(dest) and !File.directory?(dest)
- # Since svn error messages aren't as helpful as they could be here,
- # let's improve on it... by pretending to run the command and then
- # producing a better error message.
- tag! :pre, "svn mv #{source.inspect} #{dest}", class: '_stdin'
- tag! :pre, "File #{dest} already exists.", class: '_stderr'
- else
- if (`svn --version --quiet`.chomp.split('.') <=> %w(1 5)) >= 1
- if source.start_with? Dir.pwd + '/'
- source = source[Dir.pwd.length+1..-1]
- end
- self.system "svn mv #{source.inspect} #{dest}"
- else
- if `svn st #{source.inspect}` =~ /^A/
- self.system "cp #{source.inspect} #{dest}"
- self.system "svn add #{dest}"
- `svn proplist #{source.inspect}`.scan(/ \w+:[-\w]+/).each do |prop|
- prop.untaint if prop.strip =~ /^\w+(:\w+)/
- value = `svn propget #{prop.strip} #{source.inspect}`.chomp
- self.system "svn propset #{prop.strip} #{value.inspect} #{dest}"
- end
- self.system "svn revert #{source.inspect}"
- elsif `svn st #{source.inspect}` !~ /^D/
- self.system "svn mv --force #{source.inspect} #{dest}"
- end
- end
- self.system "svn rm #{dest}/Thumbs.db" if
File.exist?("#{dest}/Thumbs.db")
- end
- end
-end
-
-def check
- email = {}
- prev_name = nil
- output = []
-
- open("#{OFFICERS}/iclas.txt").each do |line|
- next unless line =~ /^\w.*?:(.*?):(.*?):(.*?)(:(.*))?\n/
- name = $1
-
- if ! $3.index('@')
- output << [ 'email', "#{$1}: #{$3}" ]
- elsif ! $4 or ! $4.index('CLA')
- if not %w(:President :Treasurer).include? $4.split(';').first
- output << [ 'nocla', "#$2: #$4" ]
- end
- elsif email[$3.downcase]
- output << [ 'dupemail', "#{$3}: #{name} and #{email[$3.downcase]}" ]
- end
-
- email[$3.downcase] = name
-
- name.split.each do |word|
- next if word.length == 1 and word !~ /\w/
- next if word =~ /^\W/
- next if %w(van von da de del der den dos i tot la).include? word
- output << ['case', name] if word !~ /[A-Z][a-z]*/
- end
-
- sort_name = ASF::ICLA.lname(line)
- if prev_name and prev_name > sort_name
- output << [ 'order', "#{prev_name} > #{sort_name}" ]
- end
- prev_name = sort_name
- end
-
- html_fragment do
- if output.empty?
- _p 'No icla.txt issues.'
- else
- _h3 'icla.txt issues'
- _table border: 1, cellpadding: 10, cellspacing: 0 do
- _thead do
- _th 'issue'
- _th 'name'
- end
- output.each do |type, message|
- _tr do
- _td type
- _td message
- end
- end
- end
- end
- end
-end
-
-def svn_info(source)
- source.untaint if Dir.chdir(RECEIVED) {Dir['*']}.include? source.chomp('/')
- source = File.join(RECEIVED, source)
- source += svn_at(source)
- info = {
- 'from' => `svn propget email:name #{source}`.chomp,
- 'email' => `svn propget email:addr #{source}`.chomp
- }
-
- if info['from'].empty? and info['email'].empty?
- log=`svn log -l 9 #{source}`
- from=log.scan(/\nFrom: (.*)/).flatten.first
-
- if from and from !~ /"eFax"/
- email = from.gsub(/.*<(.*)>$/, '\1')
- info['email'] = email if email.include?('@')
-
- from.gsub! /\s<.*>$/, ''
- from.gsub! /^"(.*)"$/, '\1'
- info['from'] = from unless from.include?('@')
- end
- end
-
- info.each do |name, value|
- value.gsub!(/\\x[0-9a-fA-F][0-9a-fA-F]/) {|c| [c[2..3].to_i(16)].pack('C')}
- value.force_encoding('utf-8')
- value.force_encoding('iso-8859-1') unless value.valid_encoding?
- end
-
- info
-end
-
-def send_email(target, message)
- pending = YAML.load(open(PENDING_YML))
-
- require_relative 'secmail'
- require 'erb'
-
- mails = []
- pending.each do |pending_hash|
- next unless pending_hash['email'] == target
-
- vars = OpenStruct.new(Hash[pending_hash.map {|k,v|
- [k.gsub(/\W/,'_'), v.dup.untaint]
- }])
- vars.commit_message = message
-
- # collapse pmc and podling variable names
- vars.pmc ||= vars.cpmc || vars.gpmc || vars.ipmc || vars.upmc || vars.ppmc
- vars.podling ||= vars.cpodling || vars.gpodling || vars.ipodling ||
vars.upodling || vars.ppodling
-
- # send email, if template exists
- template = vars.doctype + '.erb'
- template.taint unless template =~ /^\w[.\w]+$/
- if File.exist?(template)
- # prepare to send mail
- ASF::Mail.configure
-
- # extract fields from the Mail defaults
- Mail.defaults do
- vars.sig = instance_eval {@sig.gsub(/^ +/,'').strip}
- vars.from = instance_eval {@from}
- vars.bcc = instance_eval {@bcc}
- end
-
- # expand template
- def vars.render(template)
- ERB.new(template).result(binding)
- end
- message = vars.render(open(template).read.untaint)
- headers = message.slice!(/\A(\w+: .*\r?\n)*(\r?\n)*/)
-
- mail = Mail.new do
- # apply headers
- headers.scan(/(\w+):[ \t]*(.*)/).each do |name, value|
- send name, value.untaint unless value.empty?
- end
-
- body message
-
- # is this a reply?
- if vars.email_id
- in_reply_to vars.email_id
- references vars.email_id
-
- # override subject?
- if vars.email_subject and !vars.email_subject.empty?
- begin
- if vars.email_subject =~ /^re:\s/i
- subject vars.email_subject
- else
- subject 'Re: ' + vars.email_subject
- end
- rescue Encoding::UndefinedConversionError
- # some error in the subject; use the subject in the .erb file
- end
- end
- end
- end
-
- # get the list of cc's as an array
- cc = mail.cc.to_a
-
- # eliminate the legal-archive from the cc list
- cc.reject! {|addr| addr =~ /\blegal-archive@apache\.org\b/}
-
- # add additional cc if email:addr != email
- if vars.email_addr and !vars.email_addr.include?(mail.to.to_s)
- if vars.email_name
- cc << "#{vars.email_name.inspect} <#{vars.email_addr}>"
- else
- cc << vars.email_addr
- end
- end
-
- # add original cc list
- cc << vars.email_cc if vars.email_cc
-
- # calculate podling list name
- if vars.podling and vars.podling =~ /^\w[-\w]+$/
- if OLDPODLINGS.include?(vars.podling)
- vars.podlinglist = "#{vars.podling}[email protected]"
- else
- vars.podlinglist = "private@#{vars.podling}.incubator.apache.org"
- end
- end
-
- # add pmc and podling lists, if supplied
- cc << "private@#{vars.pmc}.apache.org" if vars.pmc
- cc << "#{vars.podlinglist}" if vars.podlinglist
- cc << "[email protected]" if vars.podling and not vars.pmc
-
- # replace the list of cc's
- mail.cc = cc.uniq.join(', ')
-
- # update bcc
- if vars.email_bcc and not vars.email_bcc.empty?
- bcc = mail.bcc.to_s.split(/,\s*/) + vars.email_bcc.to_s.split(/,\s*/)
- mail.bcc = bcc.uniq.join(', ').untaint
- end
-
- # for debugging purposes
- mails << [vars.email, mail.to_s]
-
- # ship it!
- mail.deliver!
-
- completed = YAML.load(open(COMPLETED_YML)) rescue []
- completed << pending_hash
- open(COMPLETED_YML, 'w') {|file| file.write completed.pop(10).to_yaml}
-
- # clean up pending list
- pending.delete pending_hash
-
- if pending.empty?
- FileUtils.rm_f PENDING_YML
- else
- open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
- end
- end
- end
-
- html_fragment do
- mails.each do |dest, mail|
- _h2 "email #{dest}"
- _pre.email mail
- end
- end
-end
-
-def committable
- files = %W( #{FOUNDATION}/Correspondence/JCP/tck-nda-list.txt )
- if defined?(MEETING)
- files += %W(#{MEETING}/memapp-received.txt #{FOUNDATION}/members.txt)
- files << MEETING
- files << SUBREQ
- end
- files += [DOCUMENTS, OFFICERS]
-end
-
-_json do
- if @cmd == 'svninfo'
- _! svn_info(@source)
- elsif @cmd == 'icla.txt issues'
- _html check
- elsif @cmd =~ /email (.*)/
- _html send_email $1, @message
- elsif @cmd =~ /svn (update|revert -R|cleanup)/ and committable.include? @file
- op, file = $1.split(' '), @file
- op << ['--username', $USER, '--password', $PASSWORD] if $PASSWORD
- _html html_fragment {
- _.system [ 'svn', *op, file ]
- }
- elsif @cmd =~ /svn commit/ and committable.include? @file
- message, file = @message, @file
- _html html_fragment {
- _.system [
- 'svn', 'commit', '-m', message, '--no-auth-cache',
- (['--username', $USER, '--password', $PASSWORD] if $PASSWORD),
- file
- ]
- }
- elsif @cmd =~ /ezmlm-sub/
- message, list, email, availid = @message, @list, @email, @availid
- _html html_fragment {
- user = ASF::Person.find(availid)
- vars = {
- version: 3, # This must match http://s.apache.org/008
- availid: availid,
- addr: email,
- listkey: list,
- member_p: true,
- chair_p: ASF.pmc_chairs.include?(user),
- }
-
- fn = "#{availid}-members-#{Time.now.strftime '%Y%m%d-%H%M%S-%L'}.json"
- fn.untaint if availid =~ /^\w[-.\w]+$/
-
- Dir.chdir SUBREQ do
- File.open(fn, 'w') {|file| file.write JSON.pretty_generate(vars) +
"\n"}
- _.system [ 'svn', 'add', fn ]
- _.system [
- 'svn', 'commit', '-m', message, '--no-auth-cache',
- (['--username', $USER, '--password', $PASSWORD] if $PASSWORD),
- fn
- ]
- end
- }
- elsif @cmd =~ /modify_unix_group/
- cmd, group, availid = @cmd, @group, @availid
- _html html_fragment {
- _pre cmd, class: '_stdin'
- ldap = ASF.init_ldap(true)
- ldap.bind("uid=#{$USER},ou=people,dc=apache,dc=org", $PASSWORD)
-
- ldap.modify "cn=#{group},ou=groups,dc=apache,dc=org",
- [LDAP.mod(LDAP::LDAP_MOD_ADD, 'memberUid', [availid])]
-
- _pre "add member: #{ldap.err2string(ldap.err)} (#{ldap.err})",
- class: (ldap.err == 0 ? '_stdout' : '_stderr')
-
- ldap.unbind
-
- }
- else
- cmd = @cmd
- _html html_fragment {
- _pre cmd, class: '_stdin'
- _pre 'Unauthorized command', class: '_stderr'
- }
- end
-end
-
-DESTINATION = {
- "operations" => "to_operations",
- "dup" => "deadletter/dup",
- "incomplete" => "deadletter/incomplete",
- "unsigned" => "deadletter/unsigned"
-}
-
-line = nil
-
-_html do
- _head_ do
- _title 'File Document'
-
- if ! %w{check update commit view danger}.include?(@action.to_s.downcase)
- _script 'parent.frames[0].location.reload()'
- end
-
- _style %{
- html {background-color: #F8F8FF}
- pre {font-weight: bold; margin: 0}
- pre._stdin, pre.todo {color: #C000C0; margin-top: 1em}
- .todo {opacity: 0.2}
- pre._stdout {color: #000}
- pre._hilite {color: #000; background-color: #FF0}
- pre._stderr {color: #F00}
- pre.email {background-color: #BDF; padding: 1em 3em}
- pre.email {border-radius: 1em}
- .traceback {background-color:#ff0; margin: 1em 0; padding: 1em;
- border: 2px solid}
- #notice {color: green}
- .collision {background-color: #ee82ee}
- }
- end
-
- _body? do
-
- activity_log = nil
- File.open "#{RECEIVED}/activity.yml", File::RDWR|File::CREAT, 0644 do
|file|
- file.flock File::LOCK_EX
- activity_log = YAML.load(file.read) || []
- activity_log.unshift({'USER' => $USER, 'time' => Time.now.utc}.
- merge(Hash[params.map {|key,value| [key,value.first]}]))
- activity_log.delete_at(1) if activity_log.length > 1 and
- activity_log[1]['USER'] == $USER and
- activity_log[1]['action'] == 'update'
- file.rewind
- file.write YAML.dump(activity_log[0...5])
- file.flush
- file.truncate file.pos
- end
-
- filename = [@filename, @cfilename, @gfilename, @mfilename, @nfilename].
- find {|name| name and not name.empty?}
- filename.untaint if filename and filename =~ /^[-.\w]+/
- doctype = (@doctype == 'mem' ? 'member_apps' : @doctype.to_s+'s')
- doctype.untaint if doctype =~ /^\w+$/
- dest = File.join(DOCUMENTS, doctype, filename.to_s)
- stem = ";#{filename.sub(/\.\w+$/,'').split('/').first}" if filename
- alax = false
- if @source and Dir.chdir(RECEIVED) {Dir['*']}.include? @source.chomp('/')
- @source.untaint
- end
-
- unless %w(clr rubys jcarman sanders mnour).include? $USER
- @action = 'welcome' unless @action == 'view'
- end
-
- case (@action || @doctype).to_s.downcase
- when 'welcome'
- _h1 "Welcome!"
- _p "This tools is for the Secretarial's team use only."
- _p %{
- Feel free to look around, but none of your actions will cause any
- files to be moved, updated, or any emails to be sent.
- }
-
- when 'icla'
- if @replaces != ''
- remove_id, remove_email = @replaces.strip.split(':',2)
- else
- remove_id, remove_email = 'notinavail', nil
- end
-
- insert = [
- remove_id,
- @realname.strip,
- @pubname.strip,
- @email.strip,
- "Signed CLA#{stem}\n"
- ].join(':')
-
- Dir.chdir(OFFICERS) do
- input = open('iclas.txt') {|file| file.to_a}
- open('iclas.txt','w') do |file|
- input.each do |line|
- if insert and ASF::ICLA.lname(line) >= ASF::ICLA.lname(insert)
- if insert.split(':',2).last != line.split(':',2).last
- file.print insert
- end
- insert = nil
- end
- fields = line.split(':')
- next if fields[0] == remove_id and fields[3] == remove_email
- file.print line
- end
- file.print insert if insert
- end
-
- _h1 @pubname
- if @source=~/[^\x00-\x7F]/ and RUBY_PLATFORM=~/darwin/i
- require 'unicode'
- @source = Unicode.normalize_KC(@source)
- end
- _.move @source, dest
- _.system "svn diff iclas.txt", hilite: @pubname
- end
-
- update_pending params, dest
-
- when 'grant'
- insert = "#{@from.strip}" +
- "\n file: #{dest.split('/').last}" +
- "\n for: #{@description.strip.gsub(/\r?\n\s*/,"\n ")}"
-
- Dir.chdir(OFFICERS) do
- input = open('grants.txt') {|file| file.read}
- marker = "\n# registering. documents on way to Secretary.\n"
- input = input.split(marker).insert(1,"\n#{insert}\n",marker)
- open('grants.txt','w') do |file|
- file.write(input.join)
- end
-
- _h1 "Grant"
- _.move @source, dest
- _.system "svn diff grants.txt", hilite: insert.split("\n")
- end
-
- update_pending params, dest
-
- when 'ccla'
- insert = "notinavail:" + @company.strip
-
- unless @contact.empty?
- insert += " - #{@contact.strip}"
- end
-
- insert += ":#{@cemail.strip}:Signed Corp CLA"
-
- unless @employees.empty?
- insert += " for #{@employees.strip.gsub(/\s*\n\s*/, ', ')}"
- end
-
- unless @product.empty?
- insert += " for #{@product.strip}"
- end
-
- Dir.chdir(OFFICERS) do
- open('cclas.txt','a') {|file| file.write(insert+"\n")}
-
- _h1 @pubname
- _.move @source, dest
- _.system "svn diff cclas.txt", hilite: insert
- end
-
- update_pending params, dest
-
- when 'nda'
- @realname ||= @nname
-
- _h1 "NDA for #{@realname}"
- _.move @source, dest
-
- Dir.chdir(FOUNDATION) do
- ndalist = "Correspondence/JCP/tck-nda-list.txt"
- _.system "svn update #{ndalist}"
- text = open(ndalist).read
- open(ndalist, 'w') do |fh|
- fh.write(text)
- line = "#{@nname.ljust(20)} #{@nid.ljust(13)} "
- line += Date.today.strftime("%Y/%m/%d ")
- line += `id -un`.chomp.ljust(10) + ' No TCK access yet'
- fh.write("#{line}\n")
- end
- _.system "svn diff #{ndalist}", hilite: @nid
- end
-
- update_pending params, dest
-
- when 'incomplete'
- dest = "#{RECEIVED}/deadletter/incomplete/#{File.basename(@source)}"
-
- Dir.chdir(RECEIVED) do
- @realname ||= @iname
- _h1 "Incomplete document received from #{@iname}"
- _.move @source, dest
- end
-
- update_pending params, dest
-
- when 'unsigned'
- dest = "#{RECEIVED}/deadletter/unsigned/#{File.basename(@source)}"
-
- Dir.chdir(RECEIVED) do
- @realname ||= @uname
- _h1 "Unsigned document received from #{@uname}"
- _.move @source, dest
- end
-
- update_pending params, dest
-
- when 'publickey'
- @realname ||= @iname
-
- _h1 "Public key not found for #{@pname}"
-
- update_pending params, dest
-
- when 'mem'
- @realname ||= @mfname
- dest.untaint if dest =~ /^[-.\w]+$/
-
- _h1 "Membership Application for #{@realname}"
- _.move @source, dest
-
- if defined?(MEETING)
- _.system "svn update #{MEETING}"
- received = open("#{MEETING}/memapp-received.txt").read
- begin
- received[/(no )\s+\w+\s+\w+\s+#{@mavailid}/,1] = 'yes'
- received[/(no )\s+\w+\s+#{@mavailid}/,1] = 'yes'
- received[/(no )\s+#{@mavailid}/,1] = 'yes'
- rescue
- _pre.stderr $!
- end
- open("#{MEETING}/memapp-received.txt", 'w') do |fh|
- fh.write(received)
- end
- _.system "svn diff #{MEETING}/memapp-received.txt", hilite: @mavailid
- end
-
- _.system "svn update #{FOUNDATION}/members.txt"
- pattern = /^Active.*?^=+\n+(.*?)^Emeritus/m
- members_txt = open("#{FOUNDATION}/members.txt").read
- data = members_txt.scan(pattern).flatten.first
- members = data.split(/^\s+\*\)\s+/)
- members.shift
-
- members.push [
- "#{@mfname}",
- "#{@maddr.gsub(/^/,' ').gsub(/\r/,'')}",
- (" #{@mcountry}" unless @mcountry.empty?),
- " Email: #{@memail}",
- (" Tel: #{@mtele}" unless @mtele.empty?),
- (" Fax: #{@mfax}" unless @mfax.empty?),
- " Forms on File: ASF Membership Application",
- " Avail ID: #{@mavailid}"
- ].compact.join("\n") + "\n"
-
- members_txt[pattern,1] = " *) " + members.join("\n *) ")
- members_txt[/We now number (\d+) active members\./,1] =
- members.length.to_s
- File.write("#{FOUNDATION}/members.txt", ASF::Member.sort(members_txt))
-
- _.system "svn diff #{FOUNDATION}/members.txt"
-
- update_pending params, dest
-
- when 'staple'
- _h1 'Staple'
- Dir.chdir(RECEIVED) do
- @source.sub! /\/$/, ''
- @source.untaint if Dir['*'].include? @source
- selected = params.keys.grep(/include\d+/)
- selected.map! {|key| "#{@source}/#{params[key].first}"}
- selected=Dir["#{@source}/*"] if selected.empty?
- cleanup = []
-
- # convert to pdf, if necessary
- sources = []
- selected.sort.each do |file|
- file.untaint if Dir["#{@source}/*"].include? file
- ext = file.split('.').last
- if ext.downcase == 'pdf'
- sources << file
- else
- cleanup << file.sub(Regexp.new(ext+'$'),'pdf').sub(' ', '_')
- sources << cleanup.last
- _.system(['convert', file, cleanup.last])
- end
- end
-
- dest,i = @source,0
- dest = @source + (i+=1).to_s while File.exist?("#{dest}.pdf")
- at = svn_at(@source)
-
- # concatenate sources
- if sources.length > 1
- _.system "pdftk #{sources.sort.join(' ')} cat output #{dest}.pdf"
- _.system "svn add #{dest}.pdf#{at}"
- elsif selected.first =~ /\.pdf$/i
- _.system "svn mv #{sources.first}#{at} #{dest}.pdf"
- else
- _.system "mv #{cleanup.shift} #{dest}.pdf"
- _.system "svn add #{dest}.pdf#{at}"
- end
-
- # copy properties
- sfx = at
- `svn proplist #{@source}#{sfx}`.scan(/ \w+:[-\w]+/).each do |prop|
- prop.untaint if prop.strip =~ /^\w+(:\w+)/
- value = `svn propget #{prop} #{@source}#{sfx}`.chomp
- _.system(['svn', 'propset', prop.strip, value, "#{dest}.pdf#{at}"])
- end
- _.system "svn propset svn:mime-type application/pdf #{dest}.pdf#{at}"
-
- # remove temporary file and source directory
- _.system "rm #{cleanup.join(' ')}" unless cleanup.empty?
- if not (Dir["#{@source}/*"]-selected).empty?
- selected.each do |file|
- if `svn st #{file}` !~ /^D/ and File.exist? file
- _.system "svn rm --force #{file}"
- end
- end
- if Dir["#{@source}/*"].empty?
- _.system "svn remove --force #{@source}#{at}"
- end
- elsif `svn st #{@source}#{at}` !~ /^D/ and File.exist? @source
- _.system "svn remove --force #{@source}#{at}"
- end
- end
-
- when 'cleanup'
- _h1 'Revert all and cleanup'
-
- committable.each do |file|
- status = `svn status #{file}`
- unless status.empty?
- status.scan(/^[?A]\s*\+?\s*(.*)/).flatten.each do |uncommitted|
- _.system ['rm', '-rf', uncommitted]
- end
- if status =~ /^\w/
- _pre.todo "svn revert -R #{file}", 'data-file' => file
- end
- end
-
- if File.directory? file
- _pre.todo "svn cleanup #{file}", 'data-file' => file
- end
- end
-
- if File.exist?(PENDING_YML)
- _.system "rm #{PENDING_YML}"
- end
-
- ajax=true
-
- when 'commit'
- _h1 'Commit'
- log = Escape.shell_single_word(@message)
- committable.each do |file|
- unless `svn status #{file}`.empty?
- _pre.todo "svn commit -m #{log} #{file}",
- 'data-message' => @message, 'data-file' => file
- end
- end
-
- if File.exist?(PENDING_YML)
- pending = YAML.load(open(PENDING_YML))
-
- pending.each do |vars|
- if vars['memail'] and vars['mfilename']
- _pre.todo "ezmlm-sub lists/apache.org/members/ #{vars['memail']}",
- 'data-list' => 'members', 'data-email' => vars['memail'],
- 'data-availid' => vars['mavailid'], 'data-message' => @message
- end
-
- if vars['mavailid'] and vars['mfilename']
- _pre.todo "modify_unix_group.pl member --add=#{vars['mavailid']}",
- 'data-group' => 'member', 'data-availid' => vars['mavailid']
- end
-
- _h2.todo "email #{vars['email']}", 'data-message' => @message
- end
- end
-
- ajax = true
-
- when 'other'
- at = svn_at(@source)
- Dir.chdir(RECEIVED) do
- if @dest == 'burst'
- _h1 'Burst'
- dest = @source.sub(/\.\w+$/,'')
-
- _.system "mkdir #{dest}"
- _.system "pdftk #{@source} burst output #{dest}/%02d.pdf"
- _.system "svn add #{dest}#{at}"
- # copy properties
- `svn proplist #{@source}#{at}`.scan(/ \w+:[-\w]+/).each do |prop|
- prop.untaint if prop.strip =~ /^\w+(:\w+)/
- next if prop.strip == 'svn:mime-type'
- value = `svn propget #{prop} #{@source}#{at}`.chomp
- _.system ['svn', 'propset', prop.strip, value, dest+at]
- end
- _.system "rm doc_data.txt" if File.exist? 'doc_data.txt'
- _.system "svn rm #{@source}#{at}"
- elsif @dest == 'flip'
- _h1 'Flip'
- _.system "pdftk #{@source} cat 1-endSouth output #{@source}.tmp"
- _.system "mv #{@source}.tmp #{@source}"
- elsif @dest == 'restore'
- _h1 'Restore'
- _.system "pdftk #{@source} cat 1-endNorth output #{@source}.tmp"
- _.system "mv #{@source}.tmp #{@source}"
- elsif @dest == 'rotate right'
- _h1 'Rotate Right'
- _.system "pdftk #{@source} cat 1-endEast output #{@source}.tmp"
- _.system "mv #{@source}.tmp #{@source}"
- elsif @dest == 'rotate left'
- _h1 'Rotate Left'
- _.system "pdftk #{@source} cat 1-endWest output #{@source}.tmp"
- _.system "mv #{@source}.tmp #{@source}"
- elsif @dest == 'junk'
- _.system(['svn', 'rm', '--force', "#{@source}#{at}"])
- elsif DESTINATION.include? @dest
- _.move @source, DESTINATION[@dest]
- else
- _pre.stderr "Unknown destination: #{@dest}"
- end
- end
-
- when 'update'
- _h1 'Update'
- _pre.todo "svn update #{OFFICERS}", 'data-file' => OFFICERS
- _pre.todo "svn update #{DOCUMENTS}", 'data-file' => DOCUMENTS
- if defined? MEETING
- _pre.todo "svn update #{MEETING}", 'data-file' => MEETING
- _pre.todo "svn update #{SUBREQ}", 'data-file' => SUBREQ
- end
- _h3.todo 'icla.txt issues'
- ajax = true
- cleanup = Dir["#{DOCUMENTS}/members/received/*"].map(&:untaint).
- select {|name| File.directory?(name) and Dir["#{name}/*"].empty?}.
- reject {|name| name =~ /\/to_\w+$/}
- unless cleanup.empty?
- _h2 'Empty directories'
- _ul do
- cleanup.each { |name| _li name }
- end
- end
-
- _h2 'Recent Activity'
- _table border: 1, cellpadding: 5, cellspacing: 0 do
- _thead_ do
- _tr do
- _th 'Time'
- _th 'User'
- _th 'Action'
- end
- end
-
- cleanup = {
- icla: %w( realname email ),
- ccla: %w( cemail contact ),
- nda: %w( nname nemail nid ),
- incomplete: %w( iname iemail ),
- unsigned: %w( uname uemail ),
- publickey: %w( pname pemail ),
- mem: %w( memail ),
- grant: %w( gname gemail ),
- }
-
- _tbody do
- activity_log[1..-1].each do |entry|
- collision = (entry['USER'] != $USER)
- collision &&= (Time.now-entry['time'] < 600)
-
- keep = cleanup[entry['doctype']] || []
- (cleanup.values.flatten - keep).each { |var| entry.delete(var) }
-
- _tr_ class: ('collision' if collision) do
- _td! do
- time = entry.delete('time')
- _time time, datetime: time.utc.iso8601
- end
- _td entry.delete('USER')
-
- entry.delete_if {|name, value| value.empty?}
- title = entry.map {|n, v| "#{n}: #{v.inspect}"}.join(', ')
-
- name = entry['action'] || entry['doctype']
- name = entry['dest'] if name == 'other'
- _td name.to_s.downcase, title: title
- end
- end
- end
- end
-
- when 'view'
- files = nil
- Dir.chdir(RECEIVED) do
- if Dir['*'].include? @dir.chomp('/')
- files = Dir["#{@dir.untaint.chomp('/')}/*"].map(&:untaint).sort
- else
- files = []
- end
-
- if files.length == 2
- verify = nil
-
- if files.first.end_with? '.sig' or files.first.end_with? '.asc'
- unless files.last.end_with? '.sig' or files.last.end_with? '.asc'
- verify = files
- end
- elsif files.last.end_with? '.sig' or files.last.end_with? '.asc'
- verify = files.reverse
- end
-
- if verify
- stderr2out = { class: {stderr: '_stdout'} }
- _.system ['gpg', '--verify', *verify], stderr2out
- if _.target!.include? "gpg: Can't check signature:"
- keyid = _.target![/[RD]SA key ID (\w+)/,1]
- if keyid
- _.system ['gpg', '--keyserver', 'pgpkeys.mit.edu',
- '--recv-keys', keyid], stderr2out
- _.system ['gpg', '--verify', *verify], stderr2out
- end
- end
- end
- end
- end
-
- _form.buttons target: 'viewport', action: 'file.cgi', method: 'post' do
- _ul style: 'list-style: none; padding: 0' do
- files.each_with_index do |line,i|
- file = line.split('/').last
- _li do
- _input type: :checkbox, name: "include#{i}", value: file
- if %w(jpg).include?(file.split('.').last)
- _img src: "/members/received/#{@dir}/#{file}"
- else
- _a file, href: "/members/received/#{@dir}/#{file}"
- end
- end
- end
- end
-
- _input name: 'source', id: 'source', type: 'hidden', value: @dir
-
- if files.length > 0
- _input type: 'submit', name: 'action', value: 'Staple'
- else
- file = "#{RECEIVED}/#{@dir}"
- stderr2out = { class: {stderr: '_stdout'} }
- _.system ['gpg', '--verify', file], stderr2out
- if _.target!.include? "gpg: Can't check signature: public key not
found"
- keyid = _.target![/[RD]SA key ID (\w+)/,1]
- if keyid
- _.system ['gpg', '--keyserver', 'pgpkeys.mit.edu',
- '--recv-keys', keyid], stderr2out
- _.system ['gpg', '--verify', file], stderr2out
- end
- end
- open(file) {|fh| _pre fh.read}
- end
-
- _script src: "jquery-1.7.2.min.js"
- _script %{
- // first, check all of the checkboxes
- $('input[type=checkbox]').attr('checked', 'checked');
-
- // on click, unclick all if all are checked.
- $('input[type=checkbox]').mousedown(function() {
- if (!$('input[type=checkbox]:not(:checked)').length) {
- $('input[type=checkbox]').removeAttr('checked');
- }
- });
- }
- end
-
- when 'cancel', 'check'
- _h1 @action
- check
-
- when 'edit cc'
- _h1 @action
-
- if File.exist?(PENDING_YML)
- pending = YAML.load(open(PENDING_YML))
-
- if @email
- pending.each do |vars|
- if vars['email'] == @email
- vars['email:cc'] = @cc.strip.gsub(/\r?\n/, ", ")
- vars['email:bcc'] = @bcc.strip.gsub(/\r?\n/, ", ")
- vars.delete('email:bcc') if vars['email:bcc'].empty?
-
- open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
- _p.notice! "cc list for #{@email} updated"
- end
- end
- end
-
- pending.each do |vars|
- vars = OpenStruct.new(Hash[vars.map {|k,v| [k.gsub(/\W/,'_'),v]}])
- _h2 "email #{vars.email}"
- _form do
- _input name: 'email', value: vars.email, type: 'hidden'
- _table do
- _tr do
- _td 'cc:'
- _td do
- _textarea vars.email_cc.to_s.gsub(/,\s+/,"\n"),
- name: 'cc', cols: 60
- end
- end
- _tr do
- _td 'bcc:'
- _td do
- _textarea vars.email_bcc.to_s.gsub(/,\s+/,"\n"),
- name: 'bcc', cols: 60
- end
- end
- end
- _input type: 'hidden', name: 'action', value: @action
- _input type: 'submit', value: 'Update'
- end
- end
- end
-
- when 'danger'
- _h2 'Potentially dangerous content'
- _a @link, href: '/members/received/' + @link
-
- else
- _h2 'Unsupported action'
- _table border: 1, cellpadding: 10, cellspacing: 0 do
- params.sort.each do |key, value|
- _tr do
- _td key
- _td value
- end
- end
- end
- end
-
- if ajax
- _script src: 'jquery-1.7.2.min.js'
-
- if @action == 'update'
- _script src: 'jquery.timeago.js'
- _script "$('time').timeago()"
- end
-
- _script %{
- function execute_todos() {
- var todo = $('.todo:first');
- if (todo.length == 1) {
- // add a spinner
- var spinner = $('<img src="spinner.gif"/>');
- todo.after(spinner);
-
- // params = cmd plus all of the data-* attributes
- var params = {cmd: todo.text()};
- for (var i=0; i<todo[0].attributes.length; i++) {
- var attr = todo[0].attributes[i];
- if (attr.name.match("^data-")) {
- params[attr.name.substr(5)] = attr.value;
- }
- }
-
- // issue request
- $.post(#{ENV['SCRIPT_NAME'].inspect}, params, function(response) {
- var replacement = $(response.html);
- if (replacement.length > 0) todo.replaceWith(replacement);
- if (replacement.filter('._stderr,._traceback').length > 0) {
- if (!confirm("Error detected. Continue?")) return;
- }
- execute_todos();
- }, 'json').done(function(data, textStatus, jqXHR) {
- if (data.toString() == '') {
- var replacement = $(
- '<pre class="_stdin">' + params.cmd + '</pre>' +
- '<pre class="_stderr"><em>no response</em></pre>'
- );
- todo.replaceWith(replacement);
- alert("Error detected. Processing terminated.");
- }
- }).fail(function(jqXHR, textStatus, errorThrown) {
- if (errorThrown == '') errorThrown = 'no response';
- var replacement = $(
- '<pre class="_stdin">' + params.cmd + '</pre>' +
- '<pre class="_stderr">' + textStatus+': '+errorThrown +
'</pre>'
- );
- todo.replaceWith(replacement);
- if (!confirm("Error detected. Continue?")) return;
- execute_todos();
- }).always(function() {
- spinner.remove();
- });
- } else {
- parent.frames[0].location.reload();
- }
- }
- execute_todos();
- }
- end
- end
-end
diff --git a/www/secretary/workbench/grant.erb
b/www/secretary/workbench/grant.erb
deleted file mode 100644
index 4f91d0f..0000000
--- a/www/secretary/workbench/grant.erb
+++ /dev/null
@@ -1,13 +0,0 @@
-to: <%= gname.inspect %> <<%= gemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Your Grant sent to Apache Secretary
-
-Dear <%= gname %>,
-
-This message acknowledges receipt of the following document, which has been
filed in the Apache Software Foundation records:
-
- <%= commit_message %>
-
-<%= sig %>
diff --git a/www/secmail/helpers.rb b/www/secretary/workbench/helpers.rb
similarity index 100%
rename from www/secmail/helpers.rb
rename to www/secretary/workbench/helpers.rb
diff --git a/www/secretary/workbench/icla.erb b/www/secretary/workbench/icla.erb
deleted file mode 100644
index 772da2e..0000000
--- a/www/secretary/workbench/icla.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-to: <%= pubname.inspect %> <<%= email %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Your ICLA sent to Apache Secretary
-
-Dear <%= pubname %>,
-
-This message acknowledges receipt of your ICLA, which has been filed in the
Apache Software Foundation records.
-
-If you have been invited as a committer, please advise the project PMC that
your ICLA has been filed.
-
-If you have not been invited, please refer to
http://www.apache.org/foundation/how-it-works.html#developers
-for more information about roles at Apache.
-
-Warm Regards,
-
-<%= sig %>
-
diff --git a/www/secretary/workbench/incomplete.erb
b/www/secretary/workbench/incomplete.erb
deleted file mode 100644
index 9bcb677..0000000
--- a/www/secretary/workbench/incomplete.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-to: <%= realname.inspect %> <<%= nemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Unsigned Document
-
-Dear <%= realname %>,
-
-We received this document but it appears to be incomplete.
-Please fill all required fields and resubmit all pages
-to [email protected]
-http://www.apache.org/licenses/#submitting
-
-Warm Regards,
-
-<%= sig %>
diff --git a/www/secretary/workbench/index.html
b/www/secretary/workbench/index.html
deleted file mode 100644
index f82a156..0000000
--- a/www/secretary/workbench/index.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>ASF Secretary-Assistant Workbench</title>
- </head>
- <frameset cols="20%, 60%">
- <frame src="worklist.cgi"/>
- <frame name="viewport"/>
- </frameset>
-</html>
diff --git a/www/secretary/workbench/jquery-1.7.2.min.js
b/www/secretary/workbench/jquery-1.7.2.min.js
deleted file mode 100644
index 16ad06c..0000000
--- a/www/secretary/workbench/jquery-1.7.2.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.7.2 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return
f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function
cu(a){if(!cj[a]){var
b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype
html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.bod [...]
-a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new
RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var
c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return
f.event.special.hover?a:a.replace(B,"mouseenter$1
mouseleave$1")};f.event={add:function(a,c,d,e,g){var
h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){
[...]
-.clean(arguments);a.push.apply(a,this.toArray());return
this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return
this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var
a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return
a}},remove:function(a,b){for(var
c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagNa
[...]
\ No newline at end of file
diff --git a/www/secretary/workbench/jquery.timeago.js
b/www/secretary/workbench/jquery.timeago.js
deleted file mode 100644
index 1417747..0000000
--- a/www/secretary/workbench/jquery.timeago.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Timeago is a jQuery plugin that makes it easy to support automatically
- * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
- *
- * @name timeago
- * @version 0.11.3
- * @requires jQuery v1.2.3+
- * @author Ryan McGeary
- * @license MIT License - http://www.opensource.org/licenses/mit-license.php
- *
- * For usage and examples, visit:
- * http://timeago.yarp.com/
- *
- * Copyright (c) 2008-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
- */
-(function($) {
- $.timeago = function(timestamp) {
- if (timestamp instanceof Date) {
- return inWords(timestamp);
- } else if (typeof timestamp === "string") {
- return inWords($.timeago.parse(timestamp));
- } else if (typeof timestamp === "number") {
- return inWords(new Date(timestamp));
- } else {
- return inWords($.timeago.datetime(timestamp));
- }
- };
- var $t = $.timeago;
-
- $.extend($.timeago, {
- settings: {
- refreshMillis: 60000,
- allowFuture: false,
- strings: {
- prefixAgo: null,
- prefixFromNow: null,
- suffixAgo: "ago",
- suffixFromNow: "from now",
- seconds: "less than a minute",
- minute: "about a minute",
- minutes: "%d minutes",
- hour: "about an hour",
- hours: "about %d hours",
- day: "a day",
- days: "%d days",
- month: "about a month",
- months: "%d months",
- year: "about a year",
- years: "%d years",
- wordSeparator: " ",
- numbers: []
- }
- },
- inWords: function(distanceMillis) {
- var $l = this.settings.strings;
- var prefix = $l.prefixAgo;
- var suffix = $l.suffixAgo;
- if (this.settings.allowFuture) {
- if (distanceMillis < 0) {
- prefix = $l.prefixFromNow;
- suffix = $l.suffixFromNow;
- }
- }
-
- var seconds = Math.abs(distanceMillis) / 1000;
- var minutes = seconds / 60;
- var hours = minutes / 60;
- var days = hours / 24;
- var years = days / 365;
-
- function substitute(stringOrFunction, number) {
- var string = $.isFunction(stringOrFunction) ? stringOrFunction(number,
distanceMillis) : stringOrFunction;
- var value = ($l.numbers && $l.numbers[number]) || number;
- return string.replace(/%d/i, value);
- }
-
- var words = seconds < 45 && substitute($l.seconds, Math.round(seconds))
||
- seconds < 90 && substitute($l.minute, 1) ||
- minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
- minutes < 90 && substitute($l.hour, 1) ||
- hours < 24 && substitute($l.hours, Math.round(hours)) ||
- hours < 42 && substitute($l.day, 1) ||
- days < 30 && substitute($l.days, Math.round(days)) ||
- days < 45 && substitute($l.month, 1) ||
- days < 365 && substitute($l.months, Math.round(days / 30)) ||
- years < 1.5 && substitute($l.year, 1) ||
- substitute($l.years, Math.round(years));
-
- var separator = $l.wordSeparator === undefined ? " " : $l.wordSeparator;
- return $.trim([prefix, words, suffix].join(separator));
- },
- parse: function(iso8601) {
- var s = $.trim(iso8601);
- s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
- s = s.replace(/-/,"/").replace(/-/,"/");
- s = s.replace(/T/," ").replace(/Z/," UTC");
- s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
- return new Date(s);
- },
- datetime: function(elem) {
- var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") :
$(elem).attr("title");
- return $t.parse(iso8601);
- },
- isTime: function(elem) {
- // jQuery's `is()` doesn't play well with HTML5 in IE
- return $(elem).get(0).tagName.toLowerCase() === "time"; //
$(elem).is("time");
- }
- });
-
- $.fn.timeago = function() {
- var self = this;
- self.each(refresh);
-
- var $s = $t.settings;
- if ($s.refreshMillis > 0) {
- setInterval(function() { self.each(refresh); }, $s.refreshMillis);
- }
- return self;
- };
-
- function refresh() {
- var data = prepareData(this);
- if (!isNaN(data.datetime)) {
- $(this).text(inWords(data.datetime));
- }
- return this;
- }
-
- function prepareData(element) {
- element = $(element);
- if (!element.data("timeago")) {
- element.data("timeago", { datetime: $t.datetime(element) });
- var text = $.trim(element.text());
- if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
- element.attr("title", text);
- }
- }
- return element.data("timeago");
- }
-
- function inWords(date) {
- return $t.inWords(distance(date));
- }
-
- function distance(date) {
- return (new Date().getTime() - date.getTime());
- }
-
- // fix for IE6 suckage
- document.createElement("abbr");
- document.createElement("time");
-}(jQuery));
diff --git a/www/secretary/workbench/local_paths.rb
b/www/secretary/workbench/local_paths.rb
deleted file mode 100644
index c081a17..0000000
--- a/www/secretary/workbench/local_paths.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'fileutils'
-
-# attempt to determine where 'HOME' is
-unless ENV['HOME']
- ENV['HOME'] = $1 if ENV['SCRIPT_FILENAME'] =~ /(.*?)\/public_html\//
- ENV['HOME'] = $1 if ENV['SCRIPT_FILENAME'] =~ /(.*?)\/Sites\//
-end
-
-# override home for whimsy
-ENV['HOME'] = '/var/www' if `hostname`.chomp == 'whimsy-vm3'
-
-# look for ~/.secassist or local_paths.yml (in that order)
-config = File.expand_path('~/.secassist')
-config = 'local_paths.yml' unless File.exist?(config)
-
-# set constants based on the configuration file
-require 'yaml'
-YAML.load(open(config).read).each do |key, value|
- FileUtils.mkdir_p value unless File.exist? value
-
- Object.const_set key.upcase,
- File.realpath(File.expand_path(value).untaint).untaint
-end
-
-# pending file
-PENDING_YML = File.join(RECEIVED, 'pending.yml')
-COMPLETED_YML = File.join(RECEIVED, 'completed.yml')
-
-# svn >= 1.5 requires a trailing '@' if the file name contains an '@'
-#
http://stackoverflow.com/questions/1985203/why-subversion-skips-files-which-contain-the-symbol
-def svn_at name
- svn_version = `svn --version --quiet`.chomp.split('.').map {|s| s.to_i}
- if (svn_version <=> [1,6,4]) < 1
- ''
- elsif name.include? '@'
- '@'
- else
- ''
- end
-end
diff --git a/www/secretary/workbench/local_paths.yml
b/www/secretary/workbench/local_paths.yml
deleted file mode 100644
index 4b08b9c..0000000
--- a/www/secretary/workbench/local_paths.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-meeting: /srv/secretary/workbench/foundation/Meetings/20170328
-foundation: /srv/secretary/workbench/foundation
-officers: /srv/secretary/workbench/foundation/officers
-documents: /srv/secretary/workbench/documents
-received: /srv/secretary/workbench/documents/received
-subreq: /srv/secretary/workbench/subreq
diff --git a/www/secretary/workbench/mem.erb b/www/secretary/workbench/mem.erb
deleted file mode 100644
index 1844415..0000000
--- a/www/secretary/workbench/mem.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-to: <%= realname.inspect %> <<%= memail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Your ASF Membership Application
-
-Dear <%= realname %>,
-
-This message acknowledges receipt of your membership application, which has
been filed in the Apache Software Foundation records.
-
-You now have access to the foundation repository and will be subscribed to the
[email protected] mailing list shortly.
-
-Warm Regards,
-
-<%= sig %>
diff --git a/www/secmail/models/attachment.rb
b/www/secretary/workbench/models/attachment.rb
similarity index 100%
rename from www/secmail/models/attachment.rb
rename to www/secretary/workbench/models/attachment.rb
diff --git a/www/secmail/models/events.rb
b/www/secretary/workbench/models/events.rb
similarity index 100%
rename from www/secmail/models/events.rb
rename to www/secretary/workbench/models/events.rb
diff --git a/www/secmail/models/mailbox.rb
b/www/secretary/workbench/models/mailbox.rb
similarity index 100%
rename from www/secmail/models/mailbox.rb
rename to www/secretary/workbench/models/mailbox.rb
diff --git a/www/secmail/models/message.rb
b/www/secretary/workbench/models/message.rb
similarity index 100%
rename from www/secmail/models/message.rb
rename to www/secretary/workbench/models/message.rb
diff --git a/www/secmail/models/safetemp.rb
b/www/secretary/workbench/models/safetemp.rb
similarity index 100%
rename from www/secmail/models/safetemp.rb
rename to www/secretary/workbench/models/safetemp.rb
diff --git a/www/secretary/workbench/nda.erb b/www/secretary/workbench/nda.erb
deleted file mode 100644
index 5d57bac..0000000
--- a/www/secretary/workbench/nda.erb
+++ /dev/null
@@ -1,13 +0,0 @@
-to: <%= realname.inspect %> <<%= nemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Your JCP NDA
-
-Dear <%= realname %>,
-
-This message acknowledges receipt of your NDA, which has been filed in the
Apache Software Foundation records.
-
-Warm Regards,
-
-<%= sig %>
diff --git a/www/secmail/parsemail.rb b/www/secretary/workbench/parsemail.rb
similarity index 100%
rename from www/secmail/parsemail.rb
rename to www/secretary/workbench/parsemail.rb
diff --git a/www/secmail/personalize.rb b/www/secretary/workbench/personalize.rb
similarity index 100%
rename from www/secmail/personalize.rb
rename to www/secretary/workbench/personalize.rb
diff --git a/www/secmail/public/HOWTO.html
b/www/secretary/workbench/public/HOWTO.html
similarity index 94%
rename from www/secmail/public/HOWTO.html
rename to www/secretary/workbench/public/HOWTO.html
index 6f2f0b8..fc01a2d 100644
--- a/www/secmail/public/HOWTO.html
+++ b/www/secretary/workbench/public/HOWTO.html
@@ -101,10 +101,11 @@
<a href="https://gitbox.apache.org/repos/asf?p=whimsy.git">ASF</a> and
<a href="https://github.com/apache/whimsy/">github</a>.</p>
- <p>The secmail application can be found in the
- <a
href="https://github.com/apache/whimsy/tree/master/www/secmail">www/secmail</a>
+ <p>The secretary workbench application can be found in the
+ <a
+href="https://github.com/apache/whimsy/tree/master/www/secretary/workbench">www/secretary/workbench</a>
subdirectory</a>.
- <p>The source to this page is in secmail/public/HOWTO.html</p>
+ <p>The source to this page is in secretary/workbench/public/HOWTO.html</p>
</body>
</html>
diff --git a/www/secmail/public/assets/bootstrap-min.css
b/www/secretary/workbench/public/assets/bootstrap-min.css
similarity index 100%
rename from www/secmail/public/assets/bootstrap-min.css
rename to www/secretary/workbench/public/assets/bootstrap-min.css
diff --git a/www/secmail/public/assets/bootstrap-min.js
b/www/secretary/workbench/public/assets/bootstrap-min.js
similarity index 100%
rename from www/secmail/public/assets/bootstrap-min.js
rename to www/secretary/workbench/public/assets/bootstrap-min.js
diff --git a/www/secmail/public/assets/jquery-min.js
b/www/secretary/workbench/public/assets/jquery-min.js
similarity index 100%
rename from www/secmail/public/assets/jquery-min.js
rename to www/secretary/workbench/public/assets/jquery-min.js
diff --git a/www/secmail/public/assets/react-min.js
b/www/secretary/workbench/public/assets/react-min.js
similarity index 100%
rename from www/secmail/public/assets/react-min.js
rename to www/secretary/workbench/public/assets/react-min.js
diff --git a/www/secmail/public/fetch.js
b/www/secretary/workbench/public/fetch.js
similarity index 100%
rename from www/secmail/public/fetch.js
rename to www/secretary/workbench/public/fetch.js
diff --git a/www/secmail/public/secmail.css
b/www/secretary/workbench/public/secmail.css
similarity index 100%
rename from www/secmail/public/secmail.css
rename to www/secretary/workbench/public/secmail.css
diff --git a/www/secretary/workbench/spinner.gif
b/www/secretary/workbench/public/spinner.gif
similarity index 100%
rename from www/secretary/workbench/spinner.gif
rename to www/secretary/workbench/public/spinner.gif
diff --git a/www/secmail/public/tasklist.js
b/www/secretary/workbench/public/tasklist.js
similarity index 100%
rename from www/secmail/public/tasklist.js
rename to www/secretary/workbench/public/tasklist.js
diff --git a/www/secretary/workbench/publickey.erb
b/www/secretary/workbench/publickey.erb
deleted file mode 100644
index 8ab0090..0000000
--- a/www/secretary/workbench/publickey.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-to: <%= realname.inspect %> <<%= pemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Missing public key
-
-Dear <%= realname %>,
-
-We received this document but cannot verify your signature without
-your public key. Please upload your public key to pgpkeys.mit.edu.
-
-http://www.apache.org/licenses/#submitting
-
-Warm Regards,
-
-<%= sig %>
diff --git a/www/secretary/workbench/secmail.rb
b/www/secretary/workbench/secmail.rb
deleted file mode 100644
index 83f2a26..0000000
--- a/www/secretary/workbench/secmail.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require 'mail'
-
-Mail.defaults do
- if $USER == 'clr'
-
- @from = 'Craig L Russell <[email protected]>'
- @sig = %{
- -- Craig L Russell
- Secretary, Apache Software Foundation
- }
-
- elsif $USER == 'jcarman'
-
- @from = 'James Carman <[email protected]>'
- @sig = %{
- -- James Carman
- Apache Software Foundation Secretarial Team
- }
-
- elsif $USER == 'rubys'
-
- @from = 'Sam Ruby <[email protected]>'
- @sig = %{
- -- Sam Ruby
- Apache Software Foundation Secretarial Team
- }
-
- elsif $USER == 'jim'
-
- @from = 'Jim Jagielski <[email protected]>'
- @sig = %{
- -- Jim Jagielski
- Apache Software Foundation Secretarial Team
- }
-
- elsif $USER == 'sanders'
-
- @from = 'Scott Sander <[email protected]>'
- @sig = %{
- -- Scott Sander
- Apache Software Foundation Secretarial Team
- }
-
- elsif $USER == 'mnour'
-
- @from = 'Mohammad Nour El-Din <[email protected]>'
- @sig = %{
- -- Mohammad Nour El-Din
- Apache Software Foundation Secretarial Team
- }
- end
-end
diff --git a/www/secmail/server.rb b/www/secretary/workbench/server.rb
similarity index 100%
rename from www/secmail/server.rb
rename to www/secretary/workbench/server.rb
diff --git a/www/secmail/tasks.rb b/www/secretary/workbench/tasks.rb
similarity index 100%
rename from www/secmail/tasks.rb
rename to www/secretary/workbench/tasks.rb
diff --git a/www/secmail/templates/acreq.erb
b/www/secretary/workbench/templates/acreq.erb
similarity index 100%
rename from www/secmail/templates/acreq.erb
rename to www/secretary/workbench/templates/acreq.erb
diff --git a/www/secmail/templates/ccla.erb
b/www/secretary/workbench/templates/ccla.erb
similarity index 100%
rename from www/secmail/templates/ccla.erb
rename to www/secretary/workbench/templates/ccla.erb
diff --git a/www/secmail/templates/grant.erb
b/www/secretary/workbench/templates/grant.erb
similarity index 100%
rename from www/secmail/templates/grant.erb
rename to www/secretary/workbench/templates/grant.erb
diff --git a/www/secmail/templates/icla-account-requested.erb
b/www/secretary/workbench/templates/icla-account-requested.erb
similarity index 100%
rename from www/secmail/templates/icla-account-requested.erb
rename to www/secretary/workbench/templates/icla-account-requested.erb
diff --git a/www/secmail/templates/icla-pmc-notified.erb
b/www/secretary/workbench/templates/icla-pmc-notified.erb
similarity index 100%
rename from www/secmail/templates/icla-pmc-notified.erb
rename to www/secretary/workbench/templates/icla-pmc-notified.erb
diff --git a/www/secmail/templates/icla.erb
b/www/secretary/workbench/templates/icla.erb
similarity index 100%
rename from www/secmail/templates/icla.erb
rename to www/secretary/workbench/templates/icla.erb
diff --git a/www/secmail/templates/incomplete.erb
b/www/secretary/workbench/templates/incomplete.erb
similarity index 100%
rename from www/secmail/templates/incomplete.erb
rename to www/secretary/workbench/templates/incomplete.erb
diff --git a/www/secmail/templates/mem.erb
b/www/secretary/workbench/templates/mem.erb
similarity index 100%
rename from www/secmail/templates/mem.erb
rename to www/secretary/workbench/templates/mem.erb
diff --git a/www/secmail/templates/nda.erb
b/www/secretary/workbench/templates/nda.erb
similarity index 100%
rename from www/secmail/templates/nda.erb
rename to www/secretary/workbench/templates/nda.erb
diff --git a/www/secmail/templates/pubkey.erb
b/www/secretary/workbench/templates/pubkey.erb
similarity index 100%
rename from www/secmail/templates/pubkey.erb
rename to www/secretary/workbench/templates/pubkey.erb
diff --git a/www/secmail/templates/unsigned.erb
b/www/secretary/workbench/templates/unsigned.erb
similarity index 100%
rename from www/secmail/templates/unsigned.erb
rename to www/secretary/workbench/templates/unsigned.erb
diff --git a/www/secmail/tmp/.gitignore b/www/secretary/workbench/tmp/.gitignore
similarity index 100%
rename from www/secmail/tmp/.gitignore
rename to www/secretary/workbench/tmp/.gitignore
diff --git a/www/secretary/workbench/unsigned.erb
b/www/secretary/workbench/unsigned.erb
deleted file mode 100644
index 191e578..0000000
--- a/www/secretary/workbench/unsigned.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-to: <%= realname.inspect %> <<%= nemail %>>
-from: <%= from %>
-cc: [email protected]
-bcc: <%= bcc %>
-subject: Unsigned Document
-
-Dear <%= realname %>,
-
-We received this document but it appears to be unsigned.
-Please sign and resubmit to [email protected]
-http://www.apache.org/licenses/#submitting
-
-Warm Regards,
-
-<%= sig %>
diff --git a/www/secretary/workbench/upload.cgi
b/www/secretary/workbench/upload.cgi
deleted file mode 100755
index f35c1a2..0000000
--- a/www/secretary/workbench/upload.cgi
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env ruby
-require 'wunderbar'
-require 'mail'
-
-_html do
- _head do
- _title 'Upload an email'
- _style %{
- pre {font-weight: bold; margin: 0}
- pre._stdin {color: #C000C0; margin-top: 1em}
- pre._stdout {color: #000}
- pre._stderr {color: #F00}
- }
- end
-
- _body do
- _h2 'Upload an email'
- _form method: 'post', enctype: 'multipart/form-data' do
- _input type: 'file', name: 'file'
- _input type: 'submit', value: 'send'
- end
-
- if @file
- Dir.chdir('/var/tools/secretary/secmail') do
- # write email to mailbox
- upload = @file.read
- mail = Mail.new {from upload[/^From: (.*?)[\r\n]/i, 1]}
- time = Time.now.asctime
- File.open('mailbox', 'w') do |file|
- file.write "From #{mail.from.first} #{time}\r\n"
- file.write upload
- end
-
- # allow emails previously processed to be processed again
- Dir['tally/*'].each {|file| File.unlink file.untaint}
-
- _.system 'python secmail.py'
- end
-
- Dir.chdir('/var/tools/secretary/documents') do
- # update received
- _.system 'svn update received'
- end
-
- _script 'parent.frames[0].location.reload()'
- end
- end
-end
diff --git a/www/secmail/views/actions/burst.json.rb
b/www/secretary/workbench/views/actions/burst.json.rb
similarity index 100%
rename from www/secmail/views/actions/burst.json.rb
rename to www/secretary/workbench/views/actions/burst.json.rb
diff --git a/www/secmail/views/actions/ccla.json.rb
b/www/secretary/workbench/views/actions/ccla.json.rb
similarity index 100%
rename from www/secmail/views/actions/ccla.json.rb
rename to www/secretary/workbench/views/actions/ccla.json.rb
diff --git a/www/secmail/views/actions/check-id.json.rb
b/www/secretary/workbench/views/actions/check-id.json.rb
similarity index 100%
rename from www/secmail/views/actions/check-id.json.rb
rename to www/secretary/workbench/views/actions/check-id.json.rb
diff --git a/www/secmail/views/actions/check-mail.json.rb
b/www/secretary/workbench/views/actions/check-mail.json.rb
similarity index 100%
rename from www/secmail/views/actions/check-mail.json.rb
rename to www/secretary/workbench/views/actions/check-mail.json.rb
diff --git a/www/secmail/views/actions/check-signature.json.rb
b/www/secretary/workbench/views/actions/check-signature.json.rb
similarity index 100%
rename from www/secmail/views/actions/check-signature.json.rb
rename to www/secretary/workbench/views/actions/check-signature.json.rb
diff --git a/www/secmail/views/actions/delete-attachment.json.rb
b/www/secretary/workbench/views/actions/delete-attachment.json.rb
similarity index 100%
rename from www/secmail/views/actions/delete-attachment.json.rb
rename to www/secretary/workbench/views/actions/delete-attachment.json.rb
diff --git a/www/secmail/views/actions/drop.json.rb
b/www/secretary/workbench/views/actions/drop.json.rb
similarity index 100%
rename from www/secmail/views/actions/drop.json.rb
rename to www/secretary/workbench/views/actions/drop.json.rb
diff --git a/www/secmail/views/actions/forward.json.rb
b/www/secretary/workbench/views/actions/forward.json.rb
similarity index 100%
rename from www/secmail/views/actions/forward.json.rb
rename to www/secretary/workbench/views/actions/forward.json.rb
diff --git a/www/secmail/views/actions/grant.json.rb
b/www/secretary/workbench/views/actions/grant.json.rb
similarity index 100%
rename from www/secmail/views/actions/grant.json.rb
rename to www/secretary/workbench/views/actions/grant.json.rb
diff --git a/www/secmail/views/actions/icla.json.rb
b/www/secretary/workbench/views/actions/icla.json.rb
similarity index 100%
rename from www/secmail/views/actions/icla.json.rb
rename to www/secretary/workbench/views/actions/icla.json.rb
diff --git a/www/secmail/views/actions/incomplete.json.rb
b/www/secretary/workbench/views/actions/incomplete.json.rb
similarity index 100%
rename from www/secmail/views/actions/incomplete.json.rb
rename to www/secretary/workbench/views/actions/incomplete.json.rb
diff --git a/www/secmail/views/actions/memapp.json.rb
b/www/secretary/workbench/views/actions/memapp.json.rb
similarity index 100%
rename from www/secmail/views/actions/memapp.json.rb
rename to www/secretary/workbench/views/actions/memapp.json.rb
diff --git a/www/secmail/views/actions/pdfize.json.rb
b/www/secretary/workbench/views/actions/pdfize.json.rb
similarity index 100%
rename from www/secmail/views/actions/pdfize.json.rb
rename to www/secretary/workbench/views/actions/pdfize.json.rb
diff --git a/www/secmail/views/actions/pubkey.json.rb
b/www/secretary/workbench/views/actions/pubkey.json.rb
similarity index 100%
rename from www/secmail/views/actions/pubkey.json.rb
rename to www/secretary/workbench/views/actions/pubkey.json.rb
diff --git a/www/secmail/views/actions/rotate-attachment.json.rb
b/www/secretary/workbench/views/actions/rotate-attachment.json.rb
similarity index 100%
rename from www/secmail/views/actions/rotate-attachment.json.rb
rename to www/secretary/workbench/views/actions/rotate-attachment.json.rb
diff --git a/www/secmail/views/actions/unsigned.json.rb
b/www/secretary/workbench/views/actions/unsigned.json.rb
similarity index 100%
rename from www/secmail/views/actions/unsigned.json.rb
rename to www/secretary/workbench/views/actions/unsigned.json.rb
diff --git a/www/secmail/views/actions/update-mail.json.rb
b/www/secretary/workbench/views/actions/update-mail.json.rb
similarity index 100%
rename from www/secmail/views/actions/update-mail.json.rb
rename to www/secretary/workbench/views/actions/update-mail.json.rb
diff --git a/www/secmail/views/app.js.rb
b/www/secretary/workbench/views/app.js.rb
similarity index 100%
rename from www/secmail/views/app.js.rb
rename to www/secretary/workbench/views/app.js.rb
diff --git a/www/secmail/views/asciize.js.rb
b/www/secretary/workbench/views/asciize.js.rb
similarity index 100%
rename from www/secmail/views/asciize.js.rb
rename to www/secretary/workbench/views/asciize.js.rb
diff --git a/www/secmail/views/body.html.rb
b/www/secretary/workbench/views/body.html.rb
similarity index 100%
rename from www/secmail/views/body.html.rb
rename to www/secretary/workbench/views/body.html.rb
diff --git a/www/secmail/views/check-signature.js.rb
b/www/secretary/workbench/views/check-signature.js.rb
similarity index 100%
rename from www/secmail/views/check-signature.js.rb
rename to www/secretary/workbench/views/check-signature.js.rb
diff --git a/www/secmail/views/context-menu.js.rb
b/www/secretary/workbench/views/context-menu.js.rb
similarity index 100%
rename from www/secmail/views/context-menu.js.rb
rename to www/secretary/workbench/views/context-menu.js.rb
diff --git a/www/secmail/views/danger.html.rb
b/www/secretary/workbench/views/danger.html.rb
similarity index 100%
rename from www/secmail/views/danger.html.rb
rename to www/secretary/workbench/views/danger.html.rb
diff --git a/www/secmail/views/forms/ccla.js.rb
b/www/secretary/workbench/views/forms/ccla.js.rb
similarity index 100%
rename from www/secmail/views/forms/ccla.js.rb
rename to www/secretary/workbench/views/forms/ccla.js.rb
diff --git a/www/secmail/views/forms/forward.js.rb
b/www/secretary/workbench/views/forms/forward.js.rb
similarity index 100%
rename from www/secmail/views/forms/forward.js.rb
rename to www/secretary/workbench/views/forms/forward.js.rb
diff --git a/www/secmail/views/forms/grant.js.rb
b/www/secretary/workbench/views/forms/grant.js.rb
similarity index 100%
rename from www/secmail/views/forms/grant.js.rb
rename to www/secretary/workbench/views/forms/grant.js.rb
diff --git a/www/secmail/views/forms/icla.js.rb
b/www/secretary/workbench/views/forms/icla.js.rb
similarity index 100%
rename from www/secmail/views/forms/icla.js.rb
rename to www/secretary/workbench/views/forms/icla.js.rb
diff --git a/www/secmail/views/forms/memapp.js.rb
b/www/secretary/workbench/views/forms/memapp.js.rb
similarity index 100%
rename from www/secmail/views/forms/memapp.js.rb
rename to www/secretary/workbench/views/forms/memapp.js.rb
diff --git a/www/secmail/views/forms/nda.js.rb
b/www/secretary/workbench/views/forms/nda.js.rb
similarity index 100%
rename from www/secmail/views/forms/nda.js.rb
rename to www/secretary/workbench/views/forms/nda.js.rb
diff --git a/www/secmail/views/headers.html.rb
b/www/secretary/workbench/views/headers.html.rb
similarity index 100%
rename from www/secmail/views/headers.html.rb
rename to www/secretary/workbench/views/headers.html.rb
diff --git a/www/secmail/views/http.js.rb
b/www/secretary/workbench/views/http.js.rb
similarity index 100%
rename from www/secmail/views/http.js.rb
rename to www/secretary/workbench/views/http.js.rb
diff --git a/www/secmail/views/index.html.rb
b/www/secretary/workbench/views/index.html.rb
similarity index 100%
rename from www/secmail/views/index.html.rb
rename to www/secretary/workbench/views/index.html.rb
diff --git a/www/secmail/views/index.js.rb
b/www/secretary/workbench/views/index.js.rb
similarity index 100%
rename from www/secmail/views/index.js.rb
rename to www/secretary/workbench/views/index.js.rb
diff --git a/www/secmail/views/index.json.rb
b/www/secretary/workbench/views/index.json.rb
similarity index 100%
rename from www/secmail/views/index.json.rb
rename to www/secretary/workbench/views/index.json.rb
diff --git a/www/secmail/views/memapp.json.rb
b/www/secretary/workbench/views/memapp.json.rb
similarity index 100%
rename from www/secmail/views/memapp.json.rb
rename to www/secretary/workbench/views/memapp.json.rb
diff --git a/www/secmail/views/message.html.rb
b/www/secretary/workbench/views/message.html.rb
similarity index 100%
rename from www/secmail/views/message.html.rb
rename to www/secretary/workbench/views/message.html.rb
diff --git a/www/secmail/views/parts.html.rb
b/www/secretary/workbench/views/parts.html.rb
similarity index 100%
rename from www/secmail/views/parts.html.rb
rename to www/secretary/workbench/views/parts.html.rb
diff --git a/www/secmail/views/parts.js.rb
b/www/secretary/workbench/views/parts.js.rb
similarity index 100%
rename from www/secmail/views/parts.js.rb
rename to www/secretary/workbench/views/parts.js.rb
diff --git a/www/secmail/views/status.js.rb
b/www/secretary/workbench/views/status.js.rb
similarity index 100%
rename from www/secmail/views/status.js.rb
rename to www/secretary/workbench/views/status.js.rb
diff --git a/www/secmail/views/tasklist.html.rb
b/www/secretary/workbench/views/tasklist.html.rb
similarity index 100%
rename from www/secmail/views/tasklist.html.rb
rename to www/secretary/workbench/views/tasklist.html.rb
diff --git a/www/secretary/workbench/worklist.cgi
b/www/secretary/workbench/worklist.cgi
deleted file mode 100755
index aff7923..0000000
--- a/www/secretary/workbench/worklist.cgi
+++ /dev/null
@@ -1,658 +0,0 @@
-#!/usr/bin/env ruby
-require 'wunderbar'
-require 'yaml'
-
-DOCTYPES = %w{icla grant ccla nda other incomplete unsigned publickey}
-
-_html do
- _head_ do
- _title 'worklist'
- _link rel: 'stylesheet', type: "text/css", href: "worklist.css"
- _script src: "jquery-1.7.2.min.js"
- _script src: 'worklist.js'
- end
-
- _body? do
-
- _pre do
- _ `date` + "\n"
- end
-
- if `which svn`.empty?
- _h2_.warn 'Unable to locate svn'
- _p 'Search PATH used:'
- _ul do
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
- _li { _code path }
- end
- end
- end
-
- begin
- begin
- require './local_paths'
- DOCTYPES.insert(-1, 'mem') if defined?(MEETING)
- rescue
- _h2_ 'Syntax error in local_paths.yml'
- raise
- end
-
- files = []
- ENV['LANG']||="en_US.UTF-8"
- if defined?(MEETING)
- IO.popen("svn st #{FOUNDATION}/members.txt").each do |line|
- files << line.sub(FOUNDATION, 'foundation')
- end
- IO.popen("svn st #{MEETING}").each do |line|
- files << line.sub(MEETING, 'meeting')
- end
- end
- IO.popen("svn st #{OFFICERS}").each do |line|
- files << line.sub(OFFICERS, 'officers')
- end
- IO.popen("svn st #{DOCUMENTS}").each do |line|
- files << line.sub(DOCUMENTS, 'documents')
- end
-
- message = 'spam'
-
- if File.exist? PENDING_YML
- pending = YAML.load(open(PENDING_YML))
- if pending.size == 1
- pending = pending.first
- if pending['doctype'] == 'icla'
- message = "ICLA from #{pending['realname']}"
- elsif pending['doctype'] == 'ccla'
- message = "CCLA from #{pending['company']}"
-
- unless pending['employees'].nil? or pending['employees'].empty?
- message += " for "
- message += pending['employees'].strip.gsub(/\s*\n\s*/, ', ')
- end
- elsif pending['doctype'] == 'grant'
- message = "Grant from #{pending['from']}"
- elsif pending['doctype'] == 'mem'
- message = "Membership Application from #{pending['realname']}"
- elsif pending['doctype'] == 'nda'
- message = "NDA for #{pending['realname']}"
- elsif pending['doctype'] == 'incomplete'
- message = "Incomplete document received from #{pending['iname']}"
- elsif pending['doctype'] == 'unsigned'
- message = "Unsigned document received from #{pending['uname']}"
- elsif pending['doctype'] == 'publickey'
- message = "Public key not found for #{pending['pname']}"
- end
- end
- end
-
- files.reject! {|f| f=~ /\/(activity|pending|completed)\.yml\s*$/}
- unless files.empty? and !File.exist?(PENDING_YML)
- _h2_ 'Pending'
- files.each {|line| _pre line.strip.sub(/\s+/,' ')}
- pending = YAML.load(open(PENDING_YML)) rescue []
- pending.each {|vars| _pre "@ #{vars['email']}" if vars['email']}
- _form.buttons target: 'viewport', action: 'file.cgi', method: 'post' do
- _input name: 'message', id: 'message', type: 'hidden',
- 'data-value' => message
- _input type: 'submit', name: 'action', value: 'Edit CC'
- _input type: 'submit', name: 'action', value: 'Cleanup'
- _input type: 'submit', name: 'action', value: 'Commit'
- end
- end
-
- files = []
- Dir.chdir("#{RECEIVED}") do
- Dir["*"].sort_by {|name| File.stat(name.untaint).mtime}.each do |file|
- next if %w{README deadletter archives}.include? file
- next if %w{pending.yml completed.yml activity.yml}.include? file
- next if file =~ /^to_\w+$/
- if File.directory? file
- next if Dir.entries(file).reject {|name| name=~/^\./}.empty?
- end
- File.chmod 0644, file if file =~ /\.pdf$/
- files << file
- end
- end
-
- _h2_ 'Work List'
- if files.empty?
- _p.worklist! { _i 'Empty' }
- else
- _ul.worklist! do
- files.each do |file|
- _li do
- ondisk = File.join(RECEIVED,file)
- file += '/' if File.directory? ondisk
- _a file, 'data-mtime' => (File.stat(ondisk).mtime.to_i rescue
nil)
- end
- end
- end
- end
-
- _div_.classify! do
- _h2_ 'Classification'
-
- _form.doctype! target: 'viewport', action: 'file.cgi', method: 'post'
do
- _table_ do
- _tr do
- DOCTYPES[0..4].each do |doctype|
- _td align: 'center' do
- _input type: 'radio', name: 'doctype', value: doctype
- end
- end
- end
- _tr do
- DOCTYPES[0..4].each do |doctype|
- _td doctype, align: 'center'
- end
- end
- end
-
- _table_ do
- _tr do
- DOCTYPES[5..-1].each do |doctype|
- _td align: 'center' do
- _input type: 'radio', name: 'doctype', value: doctype
- end
- end
- end
- _tr do
- DOCTYPES[5..-1].each do |doctype|
- _td doctype, align: 'center'
- end
- end
- end
-
- _input name: 'source', id: 'source', type: 'hidden'
-
- _table_ id: 'icla-form' do
- _tr do
- _td.label 'Real Name'
- _td.input do
- _input name: 'realname', id: 'realname', type: 'text'
- end
- end
- _tr do
- _td.label 'Public Name'
- _td.input do
- _input name: 'pubname', id: 'pubname', type: 'text'
- end
- end
- _tr do
- _td.label 'E-mail'
- _td do
- _input name: 'email', id: 'email', type: 'email'
- end
- end
- _tr do
- _td.label 'File Name'
- _td.input do
- _input name: 'filename', id: 'filename', type: 'text'
- end
- end
- end
-
- _div_ id: 'nda-form' do
- _table do
- _tr do
- _td do
- _label 'Name', for: 'nname'
- end
- _td do
- _input type: :text, name: 'nname', id: 'nname'
- end
- end
-
- _tr do
- _td do
- _label 'ASF ID', for: 'nid'
- end
- _td do
- _input type: :text, name: 'nid', id: 'nid'
- end
- end
-
- _tr do
- _td.label 'EMail'
- _td.input do
- _input name: 'nemail', id: 'nemail', type: 'email'
- end
- end
-
- _tr do
- _td.label 'File Name'
- _td.input do
- _input name: 'nfilename', id: 'nfilename', type: 'text'
- end
- end
- end
- end
-
- _div_ id: 'incomplete-form' do
- _table do
- _tr do
- _td do
- _label 'Name', for: 'iname'
- end
- _td do
- _input type: :text, name: 'iname', id: 'iname'
- end
- end
-
- _tr do
- _td.label 'EMail'
- _td.input do
- _input name: 'iemail', id: 'iemail', type: 'email'
- end
- end
- end
- end
-
- _div_ id: 'unsigned-form' do
- _table do
- _tr do
- _td do
- _label 'Name', for: 'uname'
- end
- _td do
- _input type: :text, name: 'uname', id: 'uname'
- end
- end
-
- _tr do
- _td.label 'EMail'
- _td.input do
- _input name: 'uemail', id: 'uemail', type: 'email'
- end
- end
-
- end
- end
-
- _div_ id: 'publickey-form' do
- _table do
- _tr do
- _td do
- _label 'Name', for: 'pname'
- end
- _td do
- _input type: :text, name: 'pname', id: 'pname'
- end
- end
-
- _tr do
- _td.label 'EMail'
- _td.input do
- _input name: 'pemail', id: 'pemail', type: 'email'
- end
- end
- end
- end
-
- _div id: 'mem-form' do
- if defined?(MEETING)
- received = open("#{MEETING}/memapp-received.txt").read
- else
- received = ''
- end
-
- _table do
- _tr do
- _td do
- _label 'Public Name', for: 'mpname'
- end
- _td do
- _select id: 'mavailid', name: 'mavailid' do
- pattern = /^\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(.*)\n/
- _option value: '', selected: true
- options = []
- received.scan(pattern) do |apply, mail, karma, id, name|
- next unless apply=='no'
- options << [ name.strip, id ]
- end
- options.sort.each do |name, id|
- _option name, value: id
- end
- end
- end
- end
-
- _tr do
- _td do
- _label 'Full Name', for: 'mfname'
- end
- _td do
- _input type: :text, name: 'mfname', id: 'mfname'
- end
- end
-
- _tr do
- _td do
- _label 'Address', for: 'maddr'
- end
- _td do
- _textarea rows: 5, name: 'maddr', id: 'maddr'
- end
- end
-
- _tr do
- _td do
- _label 'Country', for: 'mcountry'
- end
- _td do
- _input type: :text, name: 'mcountry', id: 'mcountry'
- end
- end
-
- _tr do
- _td do
- _label 'Telephone', for: 'mtele'
- end
- _td do
- _input type: :text, name: 'mtele', id: 'mtele'
- end
- end
-
- _tr do
- _td do
- _label 'Fax', for: 'mfax'
- end
- _td do
- _input type: :text, name: 'mfax', id: 'mfax'
- end
- end
-
- _tr do
- _td do
- _label 'E-Mail', for: 'memail'
- end
- _td do
- _input type: :email, name: 'memail', id: 'memail'
- end
- end
-
- _tr do
- _td do
- _label 'File Name', for: 'mfilename'
- end
- _td do
- _input type: :text, name: 'mfilename', id: 'mfilename'
- end
- end
- end
- end
-
- _div_ id: 'grant-form' do
- _table do
- _tr do
- _td.label 'From'
- _td do
- _input name: 'from', type: 'text'
- end
- end
- _tr do
- _td.label 'For'
- _td do
- _textarea name: 'description', rows: 5
- end
- end
- _tr do
- _td.label 'Signed By'
- _td do
- _input name: 'gname', id: 'gname', type: 'text'
- end
- end
- _tr do
- _td.label 'E-mail'
- _td do
- _input name: 'gemail', id: 'gemail', type: 'email'
- end
- end
- _tr do
- _td.label 'File Name'
- _td.input do
- _input name: 'gfilename', type: 'text'
- end
- end
- end
- end
-
- _table_ id: 'ccla-form' do
- _tr do
- _td.label 'Corporation'
- _td.input do
- _input name: 'company', id: 'company', type: 'text'
- end
- end
- _tr do
- _td.label 'Product'
- _td.input do
- _input name: 'product', id: 'product', type: 'text'
- end
- end
- _tr do
- _td.label 'Contact'
- _td do
- _input name: 'contact', id: 'contact', type: 'text'
- end
- end
- _tr do
- _td.label 'E-mail'
- _td do
- _input name: 'cemail', id: 'cemail', type: 'email'
- end
- end
- _tr do
- _td.label 'Employees'
- _td { _textarea name: 'employees', rows: 5 }
- end
- _tr do
- _td.label 'File Name'
- _td.input do
- _input name: 'cfilename', type: 'text'
- end
- end
- end
-
- _input name: 'replaces', id: 'replaces', type: 'hidden'
-
- _div_.buttons!.buttons do
- _input type: 'submit', value: 'File'
- _input type: 'submit', name: 'action', value: 'Cancel'
- end
-
- _div_.buckets!.buttons do
- _fieldset do
- _legend 'Do:'
- _input type: 'submit', name: 'dest', value: 'burst'
- _input type: 'submit', name: 'dest', value: 'flip'
- _input type: 'submit', name: 'dest', value: 'restore'
- _input type: 'submit', name: 'dest', value: 'rotate right'
- _input type: 'submit', name: 'dest', value: 'rotate left'
- end
- _fieldset do
- _legend 'File:'
- _input type: 'submit', name: 'dest', value: 'operations'
- _input type: 'submit', name: 'dest', value: 'dup'
- _input type: 'submit', name: 'dest', value: 'junk'
- _input type: 'submit', name: 'dest', value: 'incomplete'
- _input type: 'submit', name: 'dest', value: 'unsigned'
- end
- end
-
- _table id: 'icla2-form' do
- _tr do
- _td.label 'User ID'
- _td.input do
- _input name: 'user', id: 'user', type: 'text'
- end
- end
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'pmc', id: 'pmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'podling', id: 'podling', type: 'text'
- end
- end
- _tr do
- _td.label 'Vote Link'
- _td.input do
- _input name: 'votelink', id: 'votelink', type: 'text'
- end
- end
- end
-
- _table id: 'grant2-form' do
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'ggmc', id: 'gpmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'gpodling', id: 'gpodling', type: 'text'
- end
- end
- end
-
- _table id: 'ccla2-form' do
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'cpmc', id: 'cpmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'cpodling', id: 'cpodling', type: 'text'
- end
- end
- end
-
- _table id: 'incomplete2-form' do
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'ipmc', id: 'ipmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'ipodling', id: 'ipodling', type: 'text'
- end
- end
- end
-
- _table id: 'unsigned2-form' do
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'upmc', id: 'upmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'upodling', id: 'upodling', type: 'text'
- end
- end
- end
- _table id: 'publickey2-form' do
- _tr do
- _td.label 'PMC'
- _td.input do
- _input name: 'ppmc', id: 'ppmc', type: 'text'
- end
- end
- _tr do
- _td.label 'Podling'
- _td.input do
- _input name: 'ipodling', id: 'ipodling', type: 'text'
- end
- end
- end
- end
- end
-
- _h2_ 'Links'
- _ul do
- _li do
- _a 'Response time', target: 'viewport',
- href: 'https://whimsy.apache.org/secretary/response-time'
- end
- _li do
- _a 'Mail Search', href: 'https://mail-search.apache.org/',
- target: 'viewport'
- end
- _li do
- query = ''
-
- if File.exist? COMPLETED_YML
- last = YAML.load(File.read COMPLETED_YML).last
- params = {}
- %w{email user pmc podling votelink}.each do |name|
- params[name] = last[name] if last[name]
- end
- unless params.empty?
- params['iclas'] = '1'
- query = '?' + params.
- map {|name,value| "#{name}=#{CGI.escape value}"}.join('&')
- end
- end
-
- _a 'New Account', target: 'viewport', href: '/officers/acreq' + query
- end
- _li do
- _a 'Committers by id', target: 'viewport',
- href: 'http://people.apache.org/committer-index.html'
- end
- _li do
- _a 'Documents', target: 'viewport',
- href: 'https://svn.apache.org/repos/private/documents/'
- end
- _li do
- _a 'ICLA lint', target: 'viewport',
- href: 'https://whimsy.apache.org/secretary/icla-lint'
- end
- _li do
- _a 'Public names', target: 'viewport',
- href: 'https://whimsy.apache.org/secretary/public-names'
- end
- _li do
- _a 'Board subscriptions', target: 'viewport',
- href: 'https://whimsy.apache.org/board/subscriptions/'
- end
- _li do
- _a 'Mail aliases', target: 'viewport',
- href: 'https://id.apache.org/info/MailAlias.txt'
- end
- _li do
- _a 'Member list', target: 'viewport',
- href: 'https://svn.apache.org/repos/private/foundation/members.txt'
- end
- _li do
- _a 'How to use this tool', href: 'HOWTO.html',
- target: 'viewport'
- end
- _li do
- _a 'Show pending.yml', href: 'RECEIVED/pending.yml',
- target: 'viewport'
- end
-
- if File.exist? '/var/tools/secretary/secmail'
- _li {_p {_hr}}
- _li {_a 'Upload email', href: 'upload', target: 'viewport'}
- end
- end
- end
- end
-end
diff --git a/www/secretary/workbench/worklist.css
b/www/secretary/workbench/worklist.css
deleted file mode 100644
index 041c4a8..0000000
--- a/www/secretary/workbench/worklist.css
+++ /dev/null
@@ -1,23 +0,0 @@
-html {background-color: #EEE}
-input[type="email"],input[type="text"],select {width: 100%}
-textarea {width: 100%}
-p#worklist {margin-left: 2em}
-#classify {display: none}
-#doctype > table:first-child {margin-bottom: 1em}
-table {width: 100%}
-td.label {width:10em;height:2.5em}
-td.input {width:100em}
-h2 {background: #303284; color:#FFF; border-radius: 1em; padding: .25em 1em}
-h2.warn {background:yellow; color:black}
-input[type="submit"].button {width: 5em}
-input[type="submit"].bucket {width: 3.5em}
-input[type="submit"] {border-radius: 2em}
-input.loading {background-color: #EF8}
-ul {list-style:none; padding-left:0}
-li {margin: 0.5em 2em 0 1em; padding-left: 1em; border-radius: 1em}
-li:hover {background-color: #F2EEB2}
-li.selected {background-color: #FE0}
-.buttons, .buckets {text-align:center; margin-bottom:0.5em}
-pre {margin:0 0 0 2em}
-.traceback {background-color:#ff0; border: 2px solid}
-.traceback {margin: 1em 0; padding: 1em}
diff --git a/www/secretary/workbench/worklist.js
b/www/secretary/workbench/worklist.js
deleted file mode 100644
index ec9d49f..0000000
--- a/www/secretary/workbench/worklist.js
+++ /dev/null
@@ -1,228 +0,0 @@
-// prime the second frame
-if (parent.frames[1].location == 'about:blank') {
- parent.frames[1].location.href = "file.cgi?action=update"
-}
-
-// Map non-ASCII characters to lower case ASCII
-function asciize(name) {
- if (name.match(/[^\x00-\x7F]/)) {
- // digraphs. May be culturally sensitive
- name=name.replace(/\u00df/g,'ss');
- name=name.replace(/\u00e4|a\u0308/g,'ae');
- name=name.replace(/\u00e5|a\u030a/g,'aa');
- name=name.replace(/\u00e6/g,'ae');
- name=name.replace(/\u00f1|n\u0303/g,'ny');
- name=name.replace(/\u00f6|o\u0308/g,'oe');
- name=name.replace(/\u00fc|u\u0308/g,'ue');
-
- // latin 1
- name=name.replace(/[\u00e0-\u00e5]/g,'a');
- name=name.replace(/\u00e7/g,'c');
- name=name.replace(/[\u00e8-\u00eb]/g,'e');
- name=name.replace(/[\u00ec-\u00ef]/g,'i');
- name=name.replace(/[\u00f2-\u00f6]|\u00f8/g,'o');
- name=name.replace(/[\u00f9-\u00fc]/g,'u');
- name=name.replace(/[\u00fd\u00ff]/g,'y');
-
- // Latin Extended-A
- name=name.replace(/[\u0100-\u0105]/g,'a');
- name=name.replace(/[\u0106-\u010d]/g,'c');
- name=name.replace(/[\u010e-\u0111]/g,'d');
- name=name.replace(/[\u0112-\u011b]/g,'e');
- name=name.replace(/[\u011c-\u0123]/g,'g');
- name=name.replace(/[\u0124-\u0127]/g,'h');
- name=name.replace(/[\u0128-\u0131]/g,'i');
- name=name.replace(/[\u0132-\u0133]/g,'ij');
- name=name.replace(/[\u0134-\u0135]/g,'j');
- name=name.replace(/[\u0136-\u0138]/g,'k');
- name=name.replace(/[\u0139-\u0142]/g,'l');
- name=name.replace(/[\u0143-\u014b]/g,'n');
- name=name.replace(/[\u014C-\u0151]/g,'o');
- name=name.replace(/[\u0152-\u0153]/g,'oe');
- name=name.replace(/[\u0154-\u0159]/g,'r');
- name=name.replace(/[\u015a-\u0162]/g,'s');
- name=name.replace(/[\u0162-\u0167]/g,'t');
- name=name.replace(/[\u0168-\u0173]/g,'u');
- name=name.replace(/[\u0174-\u0175]/g,'w');
- name=name.replace(/[\u0176-\u0178]/g,'y');
- name=name.replace(/[\u0179-\u017e]/g,'z');
-
- // denormalized diacritics
- name=name.replace(/[\u0300-\u036f]/g,'');
- }
-
- return name.trim().replace(/[^\w]+/g,'-');
-}
-
-// Generate file name from real name (icla)
-function generateFileName(selection) {
- var value = asciize($('#realname').val());
- var source = $('#source').val();
- if (source.indexOf('.')>0) {
- if (source.indexOf('@')<0 || source.match(/\.pdf$/)) {
- value+=source.replace(/.*\./,'.');
- }
- }
- return value.replace(/-+/g, '-').toLowerCase();
-}
-
-$(document).ready(function() {
- // member autofill
- $('#mavailid').change(function() {
- var selected = $('#mavailid :selected');
- if (!$('#memail').val()) $("#memail").val($(this).val()+"@apache.org");
- $("#email").val($(this).val()+"@apache.org");
- $("#mfname").val(selected.text());
- $("#realname").val(selected.text());
- $("#mfilename").val(generateFileName());
- $("#maddr").focus();
- });
-
- // File selection
- $('#worklist a').click(function() {
- var link = $(this).text();
- var directory = link.match("/$");
- $("*[id$='-form']").hide();
- $("#buttons").hide();
- $("#buckets").hide();
- $("#doctype")[0].reset();
- $("#classify").show();
- $("#source").val(link);
-
- $("li:has(a)").removeClass('selected');
- if (directory) {
- $("li:has(a:contains('" + link + "/'))").addClass('selected');
- } else {
- $("li:has(a:contains('" + link + "'))").addClass('selected');
- }
-
- if (directory || link.match(/pgp\.txt$/)) {
- parent.frames[1].location.href = 'file.cgi?action=view&dir=' +
- encodeURIComponent(link);
- } else if (link.match(/\.(pdf|txt)$/)) {
- var href = link;
- if ($(this).attr('data-mtime')) href += '?' + $(this).attr('data-mtime');
- parent.frames[1].location.href = '/members/received/' + href;
- } else {
- parent.frames[1].location.href = 'file.cgi?action=danger&link=' +
- encodeURIComponent(link);
- }
-
- if (!link.match(/^eFax-\d+\.pdf$/)) {
- $("#icla-form input").addClass("loading");
- $("#ccla-form input").addClass("loading");
- $("#grant-form input").addClass("loading");
- $.post('file.cgi', {cmd: 'svninfo', source: link}, function(info) {
- if (!$('#realname').val()) $('#realname').val(info.from);
- if (!$('#nname').val()) $('#nname').val(info.from);
- if (!$('#iname').val()) $('#iname').val(info.from);
- if (!$('#uname').val()) $('#uname').val(info.from);
- if (!$('#pname').val()) $('#pname').val(info.from);
- if (!$('#contact').val()) $('#contact').val(info.from);
- if (!$('#gname').val()) $('#gname').val(info.from);
- if (!$('#email').val()) $('#email').val(info.email);
- if (!$('#cemail').val()) $('#cemail').val(info.email);
- if (!$('#gemail').val()) $('#gemail').val(info.email);
- if (!$('#nemail').val()) $('#nemail').val(info.email);
- if (!$('#memail').val()) $('#memail').val(info.email);
- if (!$('#iemail').val()) $('#iemail').val(info.email);
- if (!$('#uemail').val()) $('#uemail').val(info.email);
- if (!$('#pemail').val()) $('#pemail').val(info.email);
- if (!$('#nid').val()) {
- var email = $('#email').val();
- if (email.match(/^\[email protected]$/)) {
- $('#nid').val(email.split('@')[0]);
- }
- }
- $("#icla-form input").removeClass("loading");
- $("#ccla-form input").removeClass("loading");
- $("#grant-form input").removeClass("loading");
- }, 'json');
- }
- });
-
- // Classification
- $('#doctype input[name=doctype]').click(function() {
- var selection = $(this).attr('value');
- $("*[id$='-form']").slideUp();
- $("#"+selection+"-form").slideDown();
- $("#"+selection+"2-form").slideDown();
- if (selection == 'other') {
- $("#buckets").show();
- $("#buttons").hide();
- } else {
- $("#buckets").hide();
- $("#buttons").show();
- }
- $("#replaces").val("");
- if (selection == 'icla') {
- $("#archive").removeAttr("disabled");
- } else {
- $("#archive").attr("disabled", "disabled");
- }
- });
-
- // Fill in
- $("#pubname").focus(function() {
- if (this.value=='') this.value=$('#realname').val();
- });
-
- $("#email").focus(function() {
- if (this.value=='') {
- var source = $('#source').val();
- if (source.indexOf('@') == -1) source='';
- this.value = source.toLowerCase();
- }
- });
-
- $("#filename, #nfilename").focus(function() {
- if (this.value=='') this.value = generateFileName();
- });
-
- $("input[name=cfilename]").focus(function() {
- if (this.value=='') {
- var source = $('#source').val();
- var value = $('#company').val();
- var product = $('#product').val();
- if (product) value += '-' + product;
- value = asciize(value);
- if (source.indexOf('.')>0) {
- if (source.indexOf('@')<0 || source.match(/\.pdf$/)) {
- value+=source.replace(/.*\./,'.');
- }
- }
- value = value.replace(/-+/g,'-').toLowerCase();
- value = value.replace(/-[.]/,'.');
- value = value.replace(/-inc[.]/,'.');
- this.value = value;
- }
- });
-
- $("#nemail").focus(function() {
- if (this.value=='') this.value=$('#nid').val()+'@apache.org';
- });
-
- // Commit prompt
- $("input[value=Commit]").click(function() {
- var message = prompt("Commit Message?", $('#message').attr('data-value'));
- if (message) {
- $('#message').attr('value', message);
- return true;
- } else {
- return false;
- }
- });
-
- // Cleanup prompt
- $("input[value=Cleanup]").click(function() {
- return confirm("Revert all changes and cleanup subversion?");
- });
-
- // Don't validate when junking
- $("input[value=junk]").click(function() {
- $('input').attr('formnovalidate', 'formnovalidate');
- $('#message').attr('value', 'Spam')
- return true;
- });
-
-});
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].