diff options
author | Dave Whiteland <dave@mysociety.org> | 2014-04-22 15:48:14 +0100 |
---|---|---|
committer | Dave Whiteland <dave@mysociety.org> | 2014-04-22 16:10:33 +0100 |
commit | d87bbd9195ce5f72c1812c9dfbd5bbcd550e7e9f (patch) | |
tree | 555bbb36e02e34b53da12db996002ab41bf05ec9 |
initial githubpages commit on orphan branch
39 files changed, 6568 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..49eac9d72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.sass-cache/ +_site/ + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c7380350f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "theme"] + path = theme + url = https://github.com/mysociety/mysociety-docs-theme diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..e5c7f2c8d --- /dev/null +++ b/_config.yml @@ -0,0 +1,6 @@ +safe: true +pygments: true +baseurl: / +permalink: pretty +markdown: kramdown + diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 000000000..4ab06f601 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,93 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>{{ page.title }} | Alaveteli | mySociety</title> + <link rel="stylesheet" href="{{ site.baseurl }}assets/css/global.css"> + <link href="/atom.xml" rel="alternate" title="Alaveteli" type="application/atom+xml"> + <meta name="viewport" content="initial-scale=1"> + <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,900,400italic' rel='stylesheet' type='text/css'> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <script type="text/javascript"> + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-660910-6']); + _gaq.push(['_trackPageview']); + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); + </script> + </head> + <body> + + <div class="ms-header"> + <nav class="ms-header__row"> + <a class="ms-header__logo" href="http://www.mysociety.org">mySociety</a> + </nav> + </div> + + <header class="site-header"> + <div class="container"> + <a href="{{ site.baseurl }}" class="site-title"><h1>Alaveteli</h1></a> + </div> + </header> + + {{ content }} + + <footer> + + + </footer> + + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> + <script> + function replace_str(base, replacement) { + return base + replacement; // FIXME TODO should replace %s + } + + $(function(){ + + $('.reveal-on-click dd').hide(); + $('.reveal-on-click dt').on('click', function(){ + // $(this).find('+ dd').toggle(); + var $dd = $(this).find('+ dd'); + if ($dd.is(':visible')) { + $(this).removeClass('revealed'); + $dd.slideUp(); + } else { + $(this).addClass('revealed'); + $dd.slideDown(); + } + }); + + var reveal_all_text = {'reveal': 'Show all ', 'hide': 'Collapse all '}; // TODO add %s + + $('dl.reveal-on-click').each(function(){ + $(this).before("<div class='reveal-all revealed'> </div>"); + }); + $('.reveal-all').on('click', function(){ + console.log("reveal all clicked"); + var $dl = $(this).find('+ dl.reveal-on-click'); + var noun = $dl.data('reveal-noun'); + if ($(this).hasClass('revealed')) { + console.log("hiding all"); + $dl.find('dt').removeClass('revealed'); + $dl.find('dd').slideUp(); + $(this).removeClass('revealed'); + $(this).text(replace_str(reveal_all_text['reveal'], noun)); + } else { + console.log("showing all"); + $dl.find('dt').addClass('revealed'); + $dl.find('dd').slideDown(); + $(this).addClass('revealed'); + $(this).text(replace_str(reveal_all_text['hide'], noun)); + } + }); + $('.reveal-all').trigger('click'); + }); + </script> + </body> +</html> diff --git a/_layouts/fullwidth.html b/_layouts/fullwidth.html new file mode 100644 index 000000000..de253bff0 --- /dev/null +++ b/_layouts/fullwidth.html @@ -0,0 +1,11 @@ +--- +layout: default +--- +<div class="page"> + <div class="main-content-column-full-width"> + <main role="main" class="main-content"> + {{ content }} + </main> + </div> + + </div> diff --git a/_layouts/page.html b/_layouts/page.html new file mode 100644 index 000000000..29761afd2 --- /dev/null +++ b/_layouts/page.html @@ -0,0 +1,55 @@ +--- +layout: default +--- +<div class="page"> + <div class="main-content-column"> + <main role="main" class="main-content"> + {{ content }} + </main> + </div> + <div class="secondary-content-column"> + <nav class="sidebar"> + <ul> + <li><a href="{{ site.baseurl }}">Documentation</a> + <ul> + <li><a href="{{ site.baseurl }}glossary">Glossary</a></li> + </uL> + </li> + <li><a href="{{ site.baseurl }}getting_started">Getting Started</a></li> + <li><a href="{{ site.baseurl }}installing/">Installing</a> + <ul> + <li><a href="{{ site.baseurl }}installing/script">Install script</a></li> + <li><a href="{{ site.baseurl }}installing/ami">Alaveteli AMI for EC2</a></li> + <li><a href="{{ site.baseurl }}installing/manual_install">Installing by hand</a></li> + <li><a href="{{ site.baseurl }}installing/macos">MacOS X</a></li> + <li><a href="{{ site.baseurl }}installing/exim4">MTA (email)</a></li> + </ul> + </li> + <li><a href="{{ site.baseurl }}customising/">Customising</a> + <ul> + <li><a href="{{ site.baseurl }}customising/config">Configuration</a></li> + <li><a href="{{ site.baseurl }}customising/themes">Themes</a></li> + <li><a href="{{ site.baseurl }}customising/translation">Translation</a></li> + </ul> + </li> + <li><a href="{{ site.baseurl }}running/">Running</a> + <ul> + <li><a href="{{ site.baseurl }}running/admin_manual">Admin manual</a></li> + <li><a href="{{ site.baseurl }}running/server">Server checklist</a></li> + <li><a href="{{ site.baseurl }}running/states">States of requests</a></li> + </ul> + </li> + <li><a href="{{ site.baseurl }}developers/">For developers</a> + <ul> + <li><a href="{{ site.baseurl }}developers/overview">High-level overview</a></li> + <li><a href="{{ site.baseurl }}developers/directory_structure">Directory structure</a></li> + <li><a href="{{ site.baseurl }}developers/api">API</a></li> + </ul> + </li> + <li><a href="{{ site.baseurl }}community/">Community</a></li> + <li><a href="http://www.alaveteli.org/blog/">Blog</a></li> + </ul> + </nav> + </div> + + </div> diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 000000000..3119b371d --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,18 @@ +--- +layout: page +--- +{% assign author = site.authors[page.author] %} +<div class="post"> + <div class="blog-post-header"> + <h1 class="blog-title">{{ page.title }}</h1> + <p class="meta">by {{ author.display_name }}, on {{ page.date | date: "%d %B %Y" }}</p> + </div> + {{ content }} + + <hr> + <p>If you have any questions, or problems installing the code, please do + <a href="/community/">get in touch</a>, or post on our + <a href="https://secure.mysociety.org/admin/lists/mailman/listinfo/fixmystreet">mailing list</a>. + +</div> + diff --git a/assets/css/global.css b/assets/css/global.css new file mode 100644 index 000000000..8964cb000 --- /dev/null +++ b/assets/css/global.css @@ -0,0 +1,1527 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined in IE 8/9. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; } + +/** + * Correct `inline-block` display not defined in IE 8/9. + */ +audio, +canvas, +video { + display: inline-block; } + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; } + +/** + * Address `[hidden]` styling not present in IE 8/9. + * Hide the `template` element in IE, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; } + +/* ========================================================================== + Base + ========================================================================== */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ +html { + font-family: sans-serif; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } + +/** + * Remove default margin. + */ +body { + margin: 0; } + +/* ========================================================================== + Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background: transparent; } + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ +a:focus { + outline: thin dotted; } + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ +a:active, +a:hover { + outline: 0; } + +/* ========================================================================== + Typography + ========================================================================== */ +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari 5, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +/** + * Address styling not present in IE 8/9, Safari 5, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; } + +/** + * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ +b, +strong { + font-weight: bold; } + +/** + * Address styling not present in Safari 5 and Chrome. + */ +dfn { + font-style: italic; } + +/** + * Address differences between Firefox and other browsers. + */ +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; } + +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; } + +/** + * Correct font family set oddly in Safari 5 and Chrome. + */ +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; } + +/** + * Improve readability of pre-formatted text in all browsers. + */ +pre { + white-space: pre-wrap; } + +/** + * Set consistent quote types. + */ +q { + quotes: "\201C" "\201D" "\2018" "\2019"; } + +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +/* ========================================================================== + Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9. + */ +img { + border: 0; } + +/** + * Correct overflow displayed oddly in IE 9. + */ +svg:not(:root) { + overflow: hidden; } + +/* ========================================================================== + Figures + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari 5. + */ +figure { + margin: 0; } + +/* ========================================================================== + Forms + ========================================================================== */ +/** + * Define consistent border, margin, and padding. + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +/** + * 1. Correct `color` not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * 1. Correct font family not being inherited in all browsers. + * 2. Correct font size not being inherited in all browsers. + * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. + */ +button, +input, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 2 */ + margin: 0; + /* 3 */ } + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +button, +input { + line-height: normal; } + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ +button, +select { + text-transform: none; } + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ } + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; } + +/** + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + /* 2 */ + box-sizing: content-box; } + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +/** + * 1. Remove default vertical scrollbar in IE 8/9. + * 2. Improve readability and alignment in all browsers. + */ +textarea { + overflow: auto; + /* 1 */ + vertical-align: top; + /* 2 */ } + +/* ========================================================================== + Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; } + +.image-replacement, .ms-header__logo, .site-title, .owl-buttons .owl-next, +.owl-buttons .owl-prev { + text-indent: -1000%; + white-space: nowrap; + overflow: hidden; } + +.container, .ms-header__row, .page { + max-width: 63.333333333em; + padding: 0 1em; + margin: 0 auto; + position: relative; } + +.unstyled-list, .unstyled, .summary-of-features, .action-buttons, .site-footer ul, .primary-nav, .owl-buttons, .sidebar ul, .list-of-blog-posts, .definitions, .breadcrumb { + margin-left: 0; + padding-left: 0; + list-style: none outside none; } + +.inline-list, .definitions { + margin-left: -0.5em; + margin-bottom: 0; } + .inline-list li, .definitions li { + display: inline-block; + margin-left: 0.5em; } + +.text--center { + text-align: center; } + +.bg-default { + background: lightblue; } + +.highlight { + background: #ffffff; } + +.highlight .c { + color: #999988; + font-style: italic; } + +/* Comment */ +.highlight .err { + color: #a61717; + background-color: #e3d2d2; } + +/* Error */ +.highlight .k { + font-weight: bold; } + +/* Keyword */ +.highlight .o { + font-weight: bold; } + +/* Operator */ +.highlight .cm { + color: #999988; + font-style: italic; } + +/* Comment.Multiline */ +.highlight .cp { + color: #999999; + font-weight: bold; } + +/* Comment.Preproc */ +.highlight .c1 { + color: #999988; + font-style: italic; } + +/* Comment.Single */ +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + +/* Comment.Special */ +.highlight .gd { + color: #000000; + background-color: #ffdddd; } + +/* Generic.Deleted */ +.highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + +/* Generic.Deleted.Specific */ +.highlight .ge { + font-style: italic; } + +/* Generic.Emph */ +.highlight .gr { + color: #aa0000; } + +/* Generic.Error */ +.highlight .gh { + color: #999999; } + +/* Generic.Heading */ +.highlight .gi { + color: #000000; + background-color: #ddffdd; } + +/* Generic.Inserted */ +.highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + +/* Generic.Inserted.Specific */ +.highlight .go { + color: #888888; } + +/* Generic.Output */ +.highlight .gp { + color: #555555; } + +/* Generic.Prompt */ +.highlight .gs { + font-weight: bold; } + +/* Generic.Strong */ +.highlight .gu { + color: #800080; + font-weight: bold; } + +/* Generic.Subheading */ +.highlight .gt { + color: #aa0000; } + +/* Generic.Traceback */ +.highlight .kc { + font-weight: bold; } + +/* Keyword.Constant */ +.highlight .kd { + font-weight: bold; } + +/* Keyword.Declaration */ +.highlight .kn { + font-weight: bold; } + +/* Keyword.Namespace */ +.highlight .kp { + font-weight: bold; } + +/* Keyword.Pseudo */ +.highlight .kr { + font-weight: bold; } + +/* Keyword.Reserved */ +.highlight .kt { + color: #445588; + font-weight: bold; } + +/* Keyword.Type */ +.highlight .m { + color: #009999; } + +/* Literal.Number */ +.highlight .s { + color: #dd1144; } + +/* Literal.String */ +.highlight .na { + color: teal; } + +/* Name.Attribute */ +.highlight .nb { + color: #0086b3; } + +/* Name.Builtin */ +.highlight .nc { + color: #445588; + font-weight: bold; } + +/* Name.Class */ +.highlight .no { + color: teal; } + +/* Name.Constant */ +.highlight .ni { + color: purple; } + +/* Name.Entity */ +.highlight .ne { + color: #990000; + font-weight: bold; } + +/* Name.Exception */ +.highlight .nf { + color: #990000; + font-weight: bold; } + +/* Name.Function */ +.highlight .nn { + color: #555555; } + +/* Name.Namespace */ +.highlight .nt { + color: navy; } + +/* Name.Tag */ +.highlight .nv { + color: teal; } + +/* Name.Variable */ +.highlight .ow { + font-weight: bold; } + +/* Operator.Word */ +.highlight .w { + color: #bbbbbb; } + +/* Text.Whitespace */ +.highlight .mf { + color: #009999; } + +/* Literal.Number.Float */ +.highlight .mh { + color: #009999; } + +/* Literal.Number.Hex */ +.highlight .mi { + color: #009999; } + +/* Literal.Number.Integer */ +.highlight .mo { + color: #009999; } + +/* Literal.Number.Oct */ +.highlight .sb { + color: #dd1144; } + +/* Literal.String.Backtick */ +.highlight .sc { + color: #dd1144; } + +/* Literal.String.Char */ +.highlight .sd { + color: #dd1144; } + +/* Literal.String.Doc */ +.highlight .s2 { + color: #dd1144; } + +/* Literal.String.Double */ +.highlight .se { + color: #dd1144; } + +/* Literal.String.Escape */ +.highlight .sh { + color: #dd1144; } + +/* Literal.String.Heredoc */ +.highlight .si { + color: #dd1144; } + +/* Literal.String.Interpol */ +.highlight .sx { + color: #dd1144; } + +/* Literal.String.Other */ +.highlight .sr { + color: #009926; } + +/* Literal.String.Regex */ +.highlight .s1 { + color: #dd1144; } + +/* Literal.String.Single */ +.highlight .ss { + color: #990073; } + +/* Literal.String.Symbol */ +.highlight .bp { + color: #999999; } + +/* Name.Builtin.Pseudo */ +.highlight .vc { + color: teal; } + +/* Name.Variable.Class */ +.highlight .vg { + color: teal; } + +/* Name.Variable.Global */ +.highlight .vi { + color: teal; } + +/* Name.Variable.Instance */ +.highlight .il { + color: #009999; } + +/* Literal.Number.Integer.Long */ +.type-csharp .highlight .k { + color: blue; } + +.type-csharp .highlight .kt { + color: blue; } + +.type-csharp .highlight .nf { + color: #000000; + font-weight: normal; } + +.type-csharp .highlight .nc { + color: #2b91af; } + +.type-csharp .highlight .nn { + color: black; } + +.type-csharp .highlight .s { + color: #a31515; } + +.type-csharp .highlight .sc { + color: #a31515; } + +/** + * Core Owl Carousel CSS File + * v1.3.2 + */ +/* clearfix */ +.owl-carousel .owl-wrapper:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; } + +/* display none until init */ +.owl-carousel { + display: none; + position: relative; + width: 100%; + -ms-touch-action: pan-y; } + +.owl-carousel .owl-wrapper { + display: none; + position: relative; + -webkit-transform: translate3d(0px, 0px, 0px); } + +.owl-carousel .owl-wrapper-outer { + overflow: hidden; + position: relative; + width: 100%; } + +.owl-carousel .owl-wrapper-outer.autoHeight { + -webkit-transition: height 500ms ease-in-out; + -moz-transition: height 500ms ease-in-out; + -ms-transition: height 500ms ease-in-out; + -o-transition: height 500ms ease-in-out; + transition: height 500ms ease-in-out; } + +.owl-carousel .owl-item { + float: left; } + +.owl-controls .owl-page, +.owl-controls .owl-buttons div { + cursor: pointer; } + +.owl-controls { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } + +/* mouse grab icon */ +.grabbing { + cursor: url(grabbing.png) 8 8, move; } + +/* fix */ +.owl-carousel .owl-wrapper, +.owl-carousel .owl-item { + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); } + +/* Alaveteli's purple */ +*, *:before, *:after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; } + +html { + height: 100%; } + +body { + font-family: "Source Sans Pro", "Helvetica Neue", Arial, Helvetica, serif; + background-color: #fff; + color: #333333; + font-size: 1.125em; + line-height: 1.555555556em; + height: 100%; + min-height: 100%; } + +a { + color: #2b8cdb; + text-decoration: none; } + a:hover, a:active, a:focus { + text-decoration: underline; } + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5em; + text-rendering: optimizeLegibility; } + +h1, +.primary-heading { + font-size: 2.666666667em; + line-height: 1.1em; + font-weight: normal; } + +h2, +.secondary-heading { + font-size: 1.666666667em; + font-weight: 600; } + +h3, +.tertiary-heading { + font-size: 1.166666667em; + font-weight: 600; } + +h4, +.quarternary-heading { + font-size: 1em; + text-transform: uppercase; } + +p { + line-height: 1.4375em; } + +.lead { + font-size: 1.1875em; + color: #787774; + border-bottom: 1px solid #e4e3dd; + padding-bottom: 1em; + margin-bottom: 1.2em; + margin-top: 0; } + +.title { + font-weight: normal; } + +pre, code, kbd, samp { + font-family: Consolas, 'Liberation Mono', Courier, monospace; } + +code { + border: 1px solid #e4e3dd; + background: #f3f1eb; + color: #dd4e4d; + border-radius: 3px; + padding: 0 0.2em; } + +a code { + border-color: none; + color: inherit; } + +pre { + display: block; + white-space: pre-wrap; + background-color: #f3f1eb; + border-top: 3px solid #e4e3dd; + border-bottom: 3px solid #e4e3dd; + padding: 1em; + max-width: 100%; + overflow-x: scroll; + font-size: .9375em; + line-height: 1.4375em; } + pre code { + border: none; + padding: 0; + background: none; } + +hr { + border: none; + border-top: 1px solid #e4e3dd; + margin: 0; } + +img { + max-width: 100%; + height: auto; } + +ul { + padding-left: 1.3em; } + +/* To avoid floaty footer, make background footer colour */ +.page-wrapper { + background: #f3f1eb; + float: left; + width: 100%; } + +.page-wrapper--white { + width: 100%; + background: #fff; } + +/* mySociety header */ +.ms-header { + background: transparent; + border-top: 4px solid #424242; } + +.ms-header__logo { + display: block; + position: absolute; + right: 0.75em; + top: 0; + background-color: #424242; + background-repeat: no-repeat; + height: 38px; + width: 44px; + border-radius: 0 0 0.75em 0.75em; + background-size: 22px; + background-position: 11px 7px; + background-image: url("../../theme/img/mysociety-bloom.png"); } + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + .ms-header__logo { + background-image: url("../../theme/img/mysociety-bloom@2.png"); } } + @media (min-width: 30em) { + .ms-header__logo { + border-radius: 0 0 1em 1em; + background-position: 16px 10px; + background-size: 93px 19px; + background-repeat: no-repeat; + background-image: url("../../theme/img/mysociety-logo.png"); + width: 125px; + height: 39px; } } + @media (min-width: 30em) and (-webkit-min-device-pixel-ratio: 1.5), (min-width: 30em) and (min-resolution: 144dpi) { + .ms-header__logo { + background-image: url("../../theme/img/mysociety-logo@2.png"); } } + +.site-title { + height: 45px; + width: 240px; + max-width: 100%; + display: block; + background-position: top left; + background-repeat: no-repeat; + background-image: url("../img/alaveteli-logo.svg"); } + +.site-header { + border-top: 0.375em solid #424242; + padding: 1em 0; + background-position: center; + background-color: #93278f; } + +@media (min-width: 56.88889em) { + body.home .site-title { + margin: 0.5em auto; + height: 60px; + width: 320px; + background-size: 320px 60px; } + + body.home .site-header { + padding: 3.75em 0; } } +.main-content-column { + padding-left: 0 !Important; } + @media (min-width: 56.88889em) { + .main-content-column { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 75%; } + .main-content-column:first-child { + padding-left: 0; } } + +.main-content-column-full-width { + /* Use for multi-column grids where all columns are equal width, it gives them equal spacing */ + float: left; + padding-left: 1.5%; + padding-right: 1.5%; + width: 100%; } + .main-content-column-full-width:nth-child(odd), .main-content-column-full-width:first-child { + padding-left: 0; } + .main-content-column-full-width:nth-child(even), .main-content-column-full-width:last-child { + padding-right: 0; } + +.main-content { + background: #fff; + padding: 1.6em 5%; + position: relative; + margin-bottom: 32px; } + .main-content h2 { + border-top: 1px solid #e4e3dd; + padding-top: 1.2em; } + .main-content .lead + h2 { + border-top: none; + padding-top: 0; } + .main-content .reveal-on-click + h2 { + border-top: none; } + +@media (min-width: 56.88889em) { + .secondary-content-column { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 25%; } + .secondary-content-column:first-child { + padding-left: 0; } } + +.sidebar ul { + -webkit-column-count: 2; + -moz-column-count: 2; + -o-column-count: 2; + column-count: 2; } + @media (min-width: 56.88889em) { + .sidebar ul { + -webkit-column-count: 1; + -moz-column-count: 1; + -o-column-count: 1; + column-count: 1; } } + .sidebar ul ul { + -webkit-column-count: 1; + -moz-column-count: 1; + -o-column-count: 1; + column-count: 1; } +.sidebar h2 { + color: #333333; + text-transform: uppercase; + font-weight: 700; + font-size: 0.875em; + margin: 0; } + .sidebar h2 a { + color: #333333; + font-size: 1em; + text-decoration: underline; } +.sidebar a { + color: #787774; + font-size: 0.875em; } + .sidebar a:hover, .sidebar a:active, .sidebar a:focus { + color: #2b8cdb; } +.sidebar li li { + line-height: 1.4em; + margin-left: 1em; } + +.listed-blog-post { + margin-bottom: 2em; + padding-bottom: 1em; } + .listed-blog-post .blog-title { + font-weight: 700; } + .listed-blog-post .blog-title .meta { + font-weight: normal; } + +.blog-post-header .blog-title { + margin-bottom: 0; } +.blog-post-header .meta { + margin-top: 0; } + +.meta { + color: #787774; } + +.r, .l { + margin-bottom: 1em; + max-width: 50%; } + +.r { + float: right; + margin-left: 1em; } + +.l { + float: left; + margin-right: 1em; } + +.reveal-on-click { + border: 1px solid #e4e3dd; } + .reveal-on-click dt { + border-top: 1px solid #e4e3dd; + padding: 1em; + cursor: pointer; + position: relative; } + .reveal-on-click dt:hover { + text-decoration: underline; } + .reveal-on-click dt:first-child { + border-top: none; } + .reveal-on-click dt:after { + content: "+"; + position: absolute; + top: 0.8em; + right: 1em; + display: inline-block; + background: #f3f1eb; + border-radius: 50%; + height: 1.5em; + width: 1.5em; + text-align: center; + color: #787774; + -webkit-transition: -webkit-transform 0.2s ease-out; + -moz-transition: -moz-transform 0.2s ease-out; + -o-transition: -o-transform 0.2s ease-out; + transition: transform 0.2s ease-out; } + .reveal-on-click dt:hover:after { + background: #2b8cdb; + color: #fff; } + .reveal-on-click dt.revealed:after { + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + -webkit-transition: -webkit-transform 0.2s ease-out; + -moz-transition: -moz-transform 0.2s ease-out; + -o-transition: -o-transform 0.2s ease-out; + transition: transform 0.2s ease-out; } + .reveal-on-click dd { + margin-left: 0; + padding: 0 1em 0; + position: relative; + top: -1em; } + +dl.dir-structure, dl.dir-structure dl { + background: url(../../theme/img/tree-last.png) no-repeat; + background-position: 0 -29px; + padding: 0 0 0 21px; + margin: 0.5em 0 0 0; } + +dl.dir-structure { + margin-bottom: 1.5em; } + +dl.dir-structure dt { + background: url(../../theme/img/tree-branch.png) no-repeat; + background-position: 0 0; + padding: 20px 0 0 28px; + margin: 0; } + +dl.dir-structure dd { + background: url(../../theme/img/tree-upright.png) repeat-y; + padding: 0 0 0em 40px; + margin: 0; } + +dl.dir-structure dd p { + margin: 0; + padding: 0 0 0.5em 0; } + +dl.dir-structure dt.last { + background: url(../../theme/img/tree-last.png) no-repeat; } + +dl.dir-structure dd.last { + background-image: none; + padding-bottom: 0; + /* gap at bottom of nested trees is big enough as it is */ } + +table.table { + border: 1px solid #ccc; + margin: 0.5em 0 1em; + border-collapse: collapse; } + +table.table th { + background-color: #f5f5f5; } + +table.table th, +table.table td { + border: 1px solid #ccc; + padding: 0.666em; } + +.attention-box { + padding: 1em; + border: 1px solid #e4e3dd; + margin-bottom: 1.2em; } + +.definitions li { + margin-left: 0.25em; } +.definitions a { + display: inline-block; + background-color: #f3f1eb; + border-radius: 2em; + padding: 0.33em 0.66em; + color: #333333; + font-size: 0.875em; + margin-bottom: 1em; } + .definitions a:hover, .definitions a:active, .definitions a:focus { + color: #fff; + background-color: #333333; + text-decoration: none; } + +.glossary { + margin: 2em 0 8em 0; + /* big margin helps scroll-to #name at bottom of page */ } + +.glossary dt { + background-color: #f3f1eb; + padding: 0.66em 1em; + margin-top: 3em; + border: 1px solid #e4e3dd; + border-bottom: none; + color: #787774; } + .glossary dt a { + color: #333333; + font-size: 1.5em; + font-weight: 300; } + +.glossary dt a:hover { + text-decoration: none; } + +.glossary dd { + border: 1px solid #e4e3dd; + border-top: none; + padding: 1em 2em; + margin: 0; } + +.glossary dd p { + margin-top: 0.666em; } + +.glossary .more-info { + margin: 1em 0 0 0; } + +.glossary .more-info > p { + float: left; + color: #787774; + width: 8em; + margin: 0; } + +.glossary .more-info ul { + margin-top: 0.5em; + margin-left: 10em; } + +/* examples benefit from full-width (because they're often code snippets) */ +.glossary .more-info ul.examples { + clear: both; + padding-top: 0.666em; + margin-left: 0em; } + +/* <pre> currently used in .glossary <dl>s, needs text color fix... might be general problem? */ +.glossary pre { + color: #e4e3dd; } + +.homepage-feature { + /** + * For IE 6/7 only + * Include this rule to trigger hasLayout and contain floats. + */ } + .homepage-feature:before, .homepage-feature:after { + content: " "; + /* 1 */ + display: table; + /* 2 */ } + .homepage-feature:after { + clear: both; } + .homepage-feature { + *zoom: 1; } + @media (min-width: 60em) { + .homepage-feature .column { + /* Use for multi-column grids where all columns are equal width, it gives them equal spacing */ + float: left; + padding-left: 1.5%; + padding-right: 1.5%; + width: 50%; } + .homepage-feature .column:nth-child(odd), .homepage-feature .column:first-child { + padding-left: 0; } + .homepage-feature .column:nth-child(even), .homepage-feature .column:last-child { + padding-right: 0; } } + +.monitor { + margin: 0 auto 96px; + position: relative; } + @media (min-width: 520px) { + .monitor { + width: 469px; + height: 361px; + background: url("../../theme/img/monitor.png"); } } + @media (min-width: 50em) { + .monitor { + float: left; } } + .monitor #owl-slide { + margin: 0 auto; + width: 100%; + max-width: 412px; + height: 232px; + background: #fff; } + @media (min-width: 520px) { + .monitor #owl-slide { + position: absolute; + top: 30px; + left: 32px; } } + +.summary-of-features { + /** + * For IE 6/7 only + * Include this rule to trigger hasLayout and contain floats. + */ } + .summary-of-features:before, .summary-of-features:after { + content: " "; + /* 1 */ + display: table; + /* 2 */ } + .summary-of-features:after { + clear: both; } + .summary-of-features { + *zoom: 1; } + @media (min-width: 30em) { + .summary-of-features li { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 25%; + text-align: center; } + .summary-of-features li:first-child { + padding-left: 0; } } + .summary-of-features .circle-icon { + width: 114px; + height: 114px; + display: block; + margin: 32px auto 16px; + background-position: center top; + background-size: 114px 114px; + background-repeat: no-repeat; } + .summary-of-features .icon-opensource { + background-image: url("../../theme/img/icon-opensource.svg"); } + .summary-of-features .icon-paint { + background-image: url("../../theme/img/icon-paint.svg"); } + .summary-of-features .icon-help { + background-image: url("../../theme/img/icon-help.svg"); } + .summary-of-features .icon-world { + background-image: url("../../theme/img/icon-world.svg"); } + .summary-of-features h3 { + font-size: 1em; + margin-bottom: 16px; } + .summary-of-features p { + font-size: 1em; + margin: 8px 32px 32px; } + +.this-or-this .column { + text-align: center; + padding-bottom: 64px; + /* Use for multi-column grids where all columns are equal width, it gives them equal spacing */ + float: left; + padding-left: 1.5%; + padding-right: 1.5%; + width: 50%; } + .this-or-this .column:nth-child(odd), .this-or-this .column:first-child { + padding-left: 0; } + .this-or-this .column:nth-child(even), .this-or-this .column:last-child { + padding-right: 0; } + +@media (min-width: 50em) { + .action-buttons li { + width: 50%; + float: left; } } +.action-buttons li a { + width: 100%; + max-width: 9em; + margin: 0 auto 1em; + color: #fff; } +.action-buttons li .icon { + width: 30px; + height: 50px; + display: block; + float: left; + background-repeat: no-repeat; + background-position: center; + background-size: 20px; + opacity: 0.6; + margin-left: -10px; } +.action-buttons li .icon-document { + background-image: url("../../theme/img/icon-document.svg"); } +.action-buttons li .icon-download { + background-image: url("../../theme/img/icon-download.svg"); } +.action-buttons li .icon-github { + background-image: url("../../theme/img/icon-github.svg"); } +.action-buttons li .icon-email { + background-image: url("../../theme/img/icon-email.svg"); } +.action-buttons li .icon-twitter { + background-image: url("../../theme/img/icon-twitter.svg"); } +.action-buttons li .icon-irc { + background-image: url("../../theme/img/icon-hash.svg"); } +.action-buttons li .icon-post { + background-image: url("../../theme/img/icon-mail.svg"); } + +.site-footer { + width: 100%; + clear: left; + background: #333333; + padding: 32px 0; + /** + * For IE 6/7 only + * Include this rule to trigger hasLayout and contain floats. + */ } + .site-footer:before, .site-footer:after { + content: " "; + /* 1 */ + display: table; + /* 2 */ } + .site-footer:after { + clear: both; } + .site-footer { + *zoom: 1; } + .site-footer .column { + /* Use for multi-column grids where all columns are equal width, it gives them equal spacing */ + float: left; + padding-left: 1.5%; + padding-right: 1.5%; + width: 50%; } + .site-footer .column:nth-child(odd), .site-footer .column:first-child { + padding-left: 0; } + .site-footer .column:nth-child(even), .site-footer .column:last-child { + padding-right: 0; } + @media (min-width: 30em) { + .site-footer .column { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 25%; } + .site-footer .column:first-child { + padding-left: 0; } } + @media (min-width: 56.88889em) { + .site-footer .column { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 20%; } + .site-footer .column:first-child { + padding-left: 0; } } + .site-footer .column:last-child h3 { + margin-top: 1em; } + @media (min-width: 30em) { + .site-footer .column:last-child h3 { + margin-top: 0; } } + .site-footer .central { + float: right; } + @media (min-width: 30em) { + .site-footer .central { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 50%; } + .site-footer .central ul { + -webkit-column-count: 1; + -moz-column-count: 1; + -o-column-count: 1; + column-count: 1; } + .site-footer .central:first-child { + padding-left: 0; } } + @media (min-width: 40em) { + .site-footer .central { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 50%; } + .site-footer .central ul { + -webkit-column-count: 2; + -moz-column-count: 2; + -o-column-count: 2; + column-count: 2; } + .site-footer .central:first-child { + padding-left: 0; } } + @media (min-width: 56.88889em) { + .site-footer .central { + /* Use for grids where the columns are different widths */ + float: left; + padding-left: 3%; + width: 60%; } + .site-footer .central ul { + -webkit-column-count: 3; + -moz-column-count: 3; + -o-column-count: 3; + column-count: 3; } + .site-footer .central:first-child { + padding-left: 0; } } + .site-footer h3 { + font-size: 1em; + font-weight: normal; + margin-bottom: 0; + color: #888; } + .site-footer ul { + margin: 0; } + .site-footer a { + color: #eeeeee; } + +.primary-nav { + margin: 0; + text-align: center; } + .primary-nav li { + display: inline-block; + padding: 0 64px; } + @media (min-width: 30em) { + .primary-nav li { + display: inline; } } + .primary-nav a { + display: inline-block; + padding: 10.66667px 0; + color: #333333; } + +.btn, .btn--green, .btn--blue { + display: inline-block; + vertical-align: middle; + white-space: nowrap; + font-family: inherit; + font-size: 100%; + cursor: pointer; + border: none; + margin: 0; + padding-top: 0; + padding-bottom: 0; + line-height: 3; + padding-right: 1em; + padding-left: 1em; + border-radius: 3px; + transition-duration: 0.2s; } + .btn:hover, .btn--green:hover, .btn--blue:hover, .btn:active, .btn--green:active, .btn--blue:active { + text-decoration: none; + transition-duration: 0.2s; } + +.btn--green { + background: #61b252; } + .btn--green:hover { + background: #53a044; } + .btn--green:active { + background: #388924; + box-shadow: inset 0px 0px 6px #255b18; } + +.btn--blue { + background: #54b1e4; } + .btn--blue:hover { + background: #2b8cdb; } + .btn--blue:active { + background: #207cba; + box-shadow: inset 0px 0px 6px #15527c; } + +.bg-default { + background: #f3f1eb; } + +.spacer-top { + margin-top: 48px; } + +.spacer-bottom { + margin-bottom: 48px; } + +.section-header { + background: #333333; + padding: 16px 0; + float: left; + width: 100%; } + .section-header p { + color: #e4e3dd; + font-weight: normal; + margin: 0; + display: block; } + +.breadcrumb { + padding: 8px 0; } + .breadcrumb li { + display: inline; + font-size: 0.75em; } + .breadcrumb li:after { + content: '/'; + margin: 0 0.33em; + color: #e4e3dd; } + .breadcrumb li a { + color: #787774; } + +/** + * Owl Additions + */ +.owl-carousel .owl__gap { + float: left; + padding-right: 100px; } + @media (min-width: 520px) { + .owl-carousel .owl__gap { + padding-top: 100px; } } +.owl-carousel h3 { + margin-bottom: 0; } +.owl-carousel p { + margin-top: 0; } + +.owl-buttons { + float: right; + position: relative; + top: -70px; } + @media (min-width: 520px) { + .owl-buttons { + right: -20px; + top: -130px; } } + .owl-buttons .owl-next, + .owl-buttons .owl-prev { + display: block; + background-color: #e4e3dd; + float: left; + background-position: center center; + background-size: 16px; + background-repeat: no-repeat; + height: 48px; + width: 48px; + margin-right: 2px; } + .owl-buttons .owl-next:hover, + .owl-buttons .owl-prev:hover { + background-color: #cfcec8; } + .owl-buttons .owl-prev { + background-image: url("../../theme/img/icon-arrow-left.svg"); + border-radius: 3px 0 0 3px; } + .owl-buttons .owl-next { + background-image: url("../../theme/img/icon-arrow-right.svg"); + border-radius: 0 3px 3px 0; } diff --git a/assets/img/2012-07-27-screenshot.png b/assets/img/2012-07-27-screenshot.png Binary files differnew file mode 100644 index 000000000..47de5651c --- /dev/null +++ b/assets/img/2012-07-27-screenshot.png diff --git a/assets/img/alaveteli-bg.jpg b/assets/img/alaveteli-bg.jpg Binary files differnew file mode 100644 index 000000000..6ae252a90 --- /dev/null +++ b/assets/img/alaveteli-bg.jpg diff --git a/assets/img/alaveteli-logo.svg b/assets/img/alaveteli-logo.svg new file mode 100644 index 000000000..0cad25ca5 --- /dev/null +++ b/assets/img/alaveteli-logo.svg @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 900 300" style="enable-background:new 0 0 900 300;" xml:space="preserve">
+<style type="text/css">
+ .st0{display:none;stroke:#FFFFFF;stroke-miterlimit:10;}
+ .st1{display:none;}
+ .st2{display:inline;fill:#FFFFFF;}
+ .st3{display:inline;}
+ .st4{fill:#CCCCCC;}
+ .st5{fill:#FFFFFF;}
+ .st6{fill:#A3858F;}
+ .st7{fill:#F2F2F2;}
+ .st8{fill:#E6E6E6;}
+ .st9{fill:#E4D4C4;}
+ .st10{fill:#C8D4D2;}
+</style>
+<rect x="-62" y="-56" class="st0" width="1036" height="430"/>
+<g class="st1">
+ <path class="st2" d="M217.9,114.3h-8.4v-8.1h48.7c5.5,0,7.8,2.3,7.8,7.8v9.1h-8.4v-6.2c0-1.9-1-2.9-2.9-2.9h-27.6v34.1h33.1v8.1
+ h-33.1v40.6h-9.1V114.3z"/>
+ <path class="st2" d="M280.8,142.5c0-1.9-1-2.9-2.9-2.9h-5.5v-7.5h9.1c5.5,0,7.8,2.3,7.8,7.8v46.8c0,1.9,1,2.9,2.9,2.9h5.5v7.5h-9.1
+ c-5.5,0-7.8-2.3-7.8-7.8V142.5z M280.5,106.2h8.4v11h-8.4V106.2z"/>
+ <path class="st2" d="M326.6,163l-14.3-20.8c-1.6-2.3-3.2-2.6-5.8-2.6h-2.6v-7.5h4.5c6.5,0,8.4,1,12.3,7.1l9.4,14.6
+ c1,1.6,2.3,3.9,2.3,3.9h0.3c0,0,1.3-2.3,1.9-3.9l9.4-14.6c3.9-5.8,5.5-7.1,12.3-7.1h4.5v7.5h-2.6c-2.6,0-4.5,0.3-6.2,2.6L338,163
+ l23.1,33.8h-10.4l-15.9-24c-1-1.6-1.9-3.6-1.9-3.6h-0.3c0,0-1,1.9-2.3,3.6l-15.9,24h-10.4L326.6,163z"/>
+ <path class="st2" d="M366.2,189h4.9c1.9,0,2.6-1,2.9-2.9l6.5-79.9h9.1l24.4,52.9c2.3,4.5,4.5,10.7,4.5,10.7h0.3
+ c0,0,2.3-6.2,4.5-10.7l24.4-52.9h9.1l6.5,79.9c0,1.9,1,2.9,2.9,2.9h4.9v8.1h-8.8c-5.5,0-7.5-2.3-7.8-7.8l-4.2-55.2
+ c-0.3-4.9-0.3-12.7-0.3-12.7h-0.3c0,0-2.6,8.1-4.5,12.7l-21.8,46.1h-8.1l-22.4-46.4c-1.9-4.5-4.9-13-4.9-13h-0.3c0,0,0,8.1-0.3,13
+ l-4.2,55.2c-0.3,5.5-2.3,7.8-7.8,7.8h-8.8V189H366.2z"/>
+ <path class="st2" d="M488.3,216.2c5.8,0,9.7-4.5,12-10.7l3.9-8.8l-23.1-54.2c-1-2.3-2.3-2.9-4.5-2.9h-1.3v-7.5h3.9
+ c5.8,0,7.8,1.3,10.1,7.1l16.9,40.6c1.3,3.2,2.3,6.8,2.3,6.8h0.3c0,0,1-3.9,2.3-6.8l16.2-40.6c2.3-5.8,4.2-7.1,10.1-7.1h3.9v7.5
+ h-1.3c-2.3,0-3.6,0.6-4.5,2.9l-28.2,67.9c-3.2,8.1-10.1,13.6-18.8,13.6c-9.1,0-14.3-6.2-14.3-6.2l4.2-6.5
+ C478.6,211.4,482.8,216.2,488.3,216.2"/>
+ <path class="st2" d="M620.8,124.4c0,6.2-5.5,9.7-10.4,9.7c-2.6,0-5.2-1-7.8-4.5c-0.6-1-1.3-1.9-1.9-2.6c-2.9-3.9-7.8-6.2-15.3-6.2
+ c-9.1,0-15.6,3.2-15.6,9.4c0,1.9,0.6,3.9,2.6,5.5c1.9,1.6,5.2,2.6,11.7,4.2c20.1,5.5,22.4,5.8,26.9,8.8
+ c5.5,3.6,11.7,10.4,11.7,21.1c0,9.4-4.5,16.9-10.7,21.8c-7.5,5.8-17.2,7.8-26.9,7.8c-9.4,0-17.9-1.6-24.7-4.9
+ c-13.6-6.8-14.6-15.6-14.6-17.9c0-6.2,5.2-10.1,10.1-10.1c4.2,0,7.1,2.6,10.1,7.1c2.9,4.2,6.2,9.1,19.5,9.1c2.9,0,6.2-0.3,9.1-1.3
+ c1-0.3,6.8-2.6,6.8-9.4c0-3.6-1.6-5.8-3.9-7.1c-2.6-1.9-4.5-2.3-16.9-5.5c-14.9-3.9-32.1-8.4-32.1-27.3c0-16.6,13-27.6,36.7-27.6
+ C607.8,103.6,620.8,115.3,620.8,124.4"/>
+ <path class="st2" d="M653.6,129.9c5.5,0,6.8,0,8.4,0.6c1.3,0.6,3.6,2.6,3.6,6.2c0,1.3-0.3,2.6-1,3.6c-1.9,3.9-4.5,3.9-11,3.9v32.1
+ c0,5.8,1.9,6.5,6.8,6.5c5.2,0,6.5,3.9,6.5,6.8c0,7.8-9.1,8.4-14,8.4c-17.5,0-17.9-10.1-17.9-17.9v-35.7c-2.3,0-4.2,0-6.2-1
+ c-0.6-0.3-3.6-1.9-3.6-6.2c0-1.3,0-2.3,0.6-3.2c1.9-3.9,5.8-3.9,9.1-3.9v-9.7c0-2.9,0-6.5,2.6-9.1c0.6-0.6,2.6-2.9,7.1-2.9
+ c1.3,0,2.6,0.3,3.6,0.6c5.5,1.9,5.5,7.5,5.8,11.4v9.4H653.6z"/>
+ <path class="st2" d="M672.4,141.2c0-3.2,0-6.8,2.9-9.4c1.3-1.3,3.2-2.6,6.5-2.6c1.6,0,3.2,0.3,3.9,1c5.2,2.6,5.2,8.1,5.2,10.4v1.6
+ c0.6-1.9,1.3-3.9,2.6-5.8c2.9-5.2,8.1-7.5,13.6-7.5c7.1,0,9.7,4.2,9.7,8.8c0,2.6-0.6,4.5-2.3,6.2c-1.9,1.9-4.5,2.3-6.8,2.6
+ c-1.9,0-3.6,0-5.2,0.3c-10.1,1.6-10.1,12-10.4,19.2V186c0,2.9,0,6.8-2.6,9.4c-1.6,1.6-4.2,2.6-6.8,2.6c-0.6,0-1.9,0-3.2-0.6
+ c-6.5-1.9-6.5-7.5-6.5-11.7v-44.5H672.4z"/>
+ <path class="st2" d="M736.4,169.2c0.3,3.2,1,6.8,4.2,10.1c4.2,4.5,9.1,4.5,10.4,4.5c5.2,0,7.8-1.9,9.1-3.2c0.6-0.6,1.3-1.6,2.3-2.3
+ c1.9-1.6,3.9-2.3,5.5-2.3c4.5,0,8.4,3.9,8.4,8.4c0,2.6-1.3,5.5-5.2,8.1c-5.8,4.2-13.6,5.8-21.1,5.8c-25.3,0-34.1-18.8-34.1-34.7
+ c0-19.8,13-35.4,34.4-35.4c24,0,30.8,19.2,30.8,31.8c0,8.8-4.5,8.8-8.1,8.8h-36.7V169.2z M763.6,155.2c-0.6-2.3-1-4.5-2.3-6.8
+ c-2.6-3.6-6.5-5.2-11-5.2c-10.4,0-12.7,7.5-14,12H763.6z"/>
+ <path class="st2" d="M807.1,169.2c0.3,3.2,1,6.8,4.2,10.1c4.2,4.5,9.1,4.5,10.4,4.5c5.2,0,7.8-1.9,9.1-3.2c0.6-0.6,1.3-1.6,2.3-2.3
+ c1.9-1.6,3.9-2.3,5.5-2.3c4.5,0,8.4,3.9,8.4,8.4c0,2.6-1.3,5.5-5.2,8.1c-5.8,4.2-13.6,5.8-21.1,5.8c-25.3,0-34.1-18.8-34.1-34.7
+ c0-19.8,13-35.4,34.4-35.4c24,0,30.8,19.2,30.8,31.8c0,8.8-4.5,8.8-8.1,8.8h-36.7V169.2z M834.4,155.2c-0.6-2.3-1-4.5-2.3-6.8
+ c-2.6-3.6-6.5-5.2-11-5.2c-10.4,0-12.7,7.5-14,12H834.4z"/>
+ <path class="st2" d="M883.1,129.9c5.5,0,6.8,0,8.4,0.6c1.3,0.6,3.6,2.6,3.6,6.2c0,1.3-0.3,2.6-1,3.6c-1.9,3.9-4.5,3.9-11,3.9v32.1
+ c0,5.8,1.9,6.5,6.8,6.5c5.2,0,6.5,3.9,6.5,6.8c0,7.8-9.1,8.4-14,8.4c-17.5,0-17.9-10.1-17.9-17.9v-35.7c-2.3,0-4.2,0-6.2-1
+ c-0.6-0.3-3.6-1.9-3.6-6.2c0-1.3,0-2.3,0.6-3.2c1.9-3.9,5.8-3.9,9.1-3.9v-9.7c0-2.9,0-6.5,2.6-9.1c0.6-0.6,2.6-2.9,7.1-2.9
+ c1.3,0,2.6,0.3,3.6,0.6c5.5,1.9,5.5,7.5,5.8,11.4v9.4H883.1z"/>
+ <path class="st2" d="M85.1,70.1c-45.1,0-81.8,36.4-81.8,81.2s36.7,81.2,81.8,81.2s81.8-36.4,81.8-81.2S130.2,70.1,85.1,70.1
+ M85.1,215.3c-11.4,0-22.4-2.9-31.5-8.1l29.2-29.9l0.3-0.3c2.3,0.6,4.9,1,7.5,1c17.2,0,30.8-13.6,31.2-30.5c0-2.6-0.3-5.2-1-7.8
+ l-16.2,16.2l-17.9-3.9l-3.9-17.9L99,117.9c-2.6-0.6-5.2-1.3-8.1-1.3c-17.2,0-30.8,13.6-31.2,30.5c0,3.6,0.6,7.1,1.9,10.1
+ l-29.5,30.2C25,176.9,20.8,164.6,20.8,151c0-35.4,28.9-64.3,64.6-64.3S150,115.6,150,151C149.7,186.7,120.8,215.3,85.1,215.3"/>
+</g>
+<g class="st1">
+ <g class="st3">
+ <path class="st4" d="M214.4,120.7c-10.4-2.2-20.7-4.8-30.9-7.8c-0.1,27.2,0,54.4,0,81.6c0,3.3,0,6.5,0,10.2c-5,0.8-9,1.4-13.2,2
+ c0,5.9,0,11.6,0,17.5c19.4,0,38.3,0,57.3,0c0-6.2,0-11.9,0-17.5c-4.5-0.7-8.4-1.4-13.1-2.2C214.4,176.4,214.4,148.5,214.4,120.7z"
+ />
+ <path class="st5" d="M214.4,66.5c-15.1,0-29.4,0-44,0c0,6.3,0,12.2,0,18c12.2,1.2,13.1-1.9,13.1,13.5c0,5,0,9.9,0,14.9
+ c10.3,3,20.6,5.6,30.9,7.8C214.4,102.7,214.4,84.6,214.4,66.5z"/>
+ </g>
+ <g class="st3">
+ <path class="st5" d="M61.8,152.2c1.3-4.1,2.5-8.2,3.7-12.3c-5.9-21-10.3-42.6-13.1-64.8c-4.9,0-9.8,0-14.8,0
+ c-1.6,6.4-3.2,12.7-5,20.3c7.5,0,14,0,21.1,0c-1,3.6-1.6,6-2.3,8.3c-9.5,29.5-19,59-28.6,88.5c-3.2,9.8-3.7,12.4-16.4,12.6
+ c-0.4,0-0.9,0.6-1.2,0.8c0,6.3,0,12.4,0,19c9.5,0,18.3,0,27.2,0c9,0,18.1,0,27,0c0-7.3,0-13.5,0-19.8c-4.5-0.2-8.3-0.4-12.8-0.6
+ c3.4-11.1,6.6-21.6,9.9-32.4c6.6,0,13,0,19.3,0c-2.4-6.5-4.5-13-6.6-19.7C66.7,152.2,64.3,152.2,61.8,152.2z"/>
+ <path class="st6" d="M97.9,224.2c0.3,0,0.6,0,0.9,0c-0.3-0.6-0.6-1.1-0.9-1.7C97.9,223.1,97.9,223.6,97.9,224.2z"/>
+ <path class="st4" d="M142.2,192.3c-11.3-35.4-23.1-70.7-34.7-106.1c-7.1-3.5-14.2-7.1-21.2-11c-11.3,0-22.6,0-33.9,0
+ c2.8,22.1,7.2,43.8,13.1,64.8c4.2-13.8,8.4-27.5,12.5-41.2c0.7,0,1.3,0,2,0c5.2,17.6,10.4,35.1,15.9,53.5c-9.1,0-17.8,0-26.8,0
+ c2.1,6.6,4.3,13.2,6.6,19.7c8.6,0,17.1,0,25.7,0c3,10.8,5.9,21.3,8.9,32.3c-5,0.4-8.7,0.6-12.4,0.9c0,6.2,0,11.7,0,17.4
+ c0.3,0.6,0.6,1.2,0.9,1.7c20.2,0,40,0,59.9,0c0-6.7,0-12.9,0-20.1C147.8,207.1,144.9,200.6,142.2,192.3z"/>
+ <path class="st7" d="M106.3,82.6c-0.8-2.6-1.9-5-2.7-7.4c-5.8,0-11.5,0-17.3,0c7,3.9,14.1,7.6,21.2,11
+ C107.1,85,106.7,83.8,106.3,82.6z"/>
+ </g>
+ <g class="st3">
+ <path class="st4" d="M880.6,191.5c0-11.6,0-23.3,0-34.9c0-4.1,0-8.3,0-12.5c-7.3,24.9-16.6,48.9-27.9,71.7
+ c1.7,3.2,4.4,5.9,8.3,7.7c10.8,5,22,3.3,33,1.4c0-6.7,0-12.5,0-18.1C880.8,204.8,880.6,204.6,880.6,191.5z"/>
+ <path class="st5" d="M880.6,111.4c-8.2,0-15.4,0-22.5,0c-7.1,0-14.1,0.1-20.8,0.1c0,7,0,12.6,0,18.2c1.5,0.2,2.4,0.3,3.2,0.3
+ c9.2,0.7,9.5,1,9.6,10.4c0,1.4,0,2.8,0,4.2c0,19.7-0.1,39.4-0.1,59c0,4.5,0.8,8.7,2.7,12.2c11.3-22.9,20.7-46.8,27.9-71.7
+ C880.6,133.5,880.6,122.8,880.6,111.4z"/>
+ <path class="st5" d="M880.6,90.7c0.9-8.6,0.9-16.4,0.1-24.2c-1.6,0-3.2,0-4.8,0c-2.4,1.5-4.8,3-7.3,4.4
+ c-6.4,3.7-12.9,7.2-19.4,10.5c0,3.1,0.1,6.2,0.4,9.3C860.3,90.7,870,90.7,880.6,90.7z"/>
+ <path class="st8" d="M875.9,66.6c-9,0-17.5,0-26.4,0c-0.2,5.1-0.3,10-0.2,14.9c6.5-3.3,13-6.8,19.4-10.5
+ C871,69.5,873.4,68,875.9,66.6z"/>
+ </g>
+ <g class="st3">
+ <path class="st5" d="M754.8,120.3c-27,5.9-54.3,9.3-81.5,10.1c-0.7,1.1-1.4,2.2-2.1,3.4c-10,16.9-9.5,34.8-6.1,53.2
+ c3.4,18.1,13.5,30.9,31.2,36.5c6.5,2.1,13.5,2.6,20.4,3.2c15.5,1.2,30.3-2.1,44.7-7.4c2-0.7,4.8-3,4.9-4.6
+ c0.5-8.5,0.2-17,0.2-25.8c-4.9,0-8.7,0-12.7,0c-2.9,3.2-5.2,6.4-8.1,8.9c-8.8,7.4-19,7.9-29.8,5.9c-13.6-2.4-22-14.7-19.1-29.1
+ c23.6,0,47.3,0,71.4,0c1.8-16.4,0.7-31.4-7.1-45.6C759.3,125.5,757.3,122.7,754.8,120.3z M718.1,156.3c-7.2,0-14.3,0-22.1,0
+ c-0.9-16.4,7.4-26.3,21.4-26.7c14.8-0.4,22.3,8,22.5,26.5C732.7,156.2,725.4,156.3,718.1,156.3z"/>
+ <path class="st8" d="M749.3,116.2c-17.6-10.2-36-9.5-54.5-3.4c-9.5,3.1-16.2,9.5-21.6,17.6c27.2-0.8,54.5-4.2,81.5-10.1
+ C753.2,118.7,751.4,117.4,749.3,116.2z"/>
+ </g>
+ <g class="st3">
+ <path class="st5" d="M820.4,97.8c-10.3,4.2-20.7,7.9-31.1,11.3c0,28.5,0,57,0,85.5c0,3.3-0.3,6.5-0.5,10.1
+ c-4.7,0.7-8.7,1.2-12.7,1.8c0,6.2,0,11.8,0,17.5c19.5,0,38.4,0,57.2,0c0-6.3,0-12,0-17.5c-4.5-0.8-8.5-1.5-12.9-2.2
+ C820.4,168.7,820.4,133.4,820.4,97.8z"/>
+ <path class="st8" d="M820.4,66.6c-15.4,0-29.7,0-44.3,0c0,6.2,0,11.9,0,17.3c0.9,0.4,1.4,0.8,1.9,0.8c13.3-0.1,11.3,2.3,11.4,12.6
+ c0,3.9,0,7.9,0,11.8c10.4-3.4,20.8-7.1,31.1-11.3C820.4,87.4,820.4,77,820.4,66.6z"/>
+ </g>
+ <g class="st3">
+ <path class="st4" d="M555.5,117c-3.5-2.3-7.1-4-10.8-5.3c-2.1-0.6-4.2-1.3-6.3-1.9c-12.6-2.9-25.6-1.2-38.7,3.3
+ c-10.4,3.5-17.5,11.1-23.1,20.5c-10.2,17.2-9.7,35.3-6.1,54c3.5,18.2,13.8,31.1,31.5,36.3c22.6,6.5,45,3.3,66.6-5.4
+ c1.3-0.5,3-2.2,3-3.4c0.3-8.7,0.8-17.5-0.3-26.3c-4.8,0-8.6,0-12.9,0c-5.6,10.8-15.2,15.3-27,16c-19.4,1.2-32-11.2-29.7-30
+ c23.6,0,47.4,0,71.7,0c1.7-17,0.9-32.3-7.6-46.2C563.2,124.1,559.7,119.7,555.5,117z M544.8,155.8c-14.4,0-28.9,0-43.4,0
+ c-1.3-15.7,7.5-26.1,21.9-26.2C538,129.5,546.1,139.3,544.8,155.8z"/>
+ <path class="st9" d="M541.7,109.7c2.1,0.7,4.2,1.3,6.3,1.9C546,110.9,543.9,110.2,541.7,109.7z"/>
+ </g>
+ <g class="st3">
+ <path class="st5" d="M617.7,226.2c11,0.6,22.1-0.8,33.1-1.7c1.5-0.1,4-2.5,4.1-4c0.5-6.2,0.2-12.4,0.2-19.1
+ c-5.9,0.7-10.6,1.5-15.2,1.6c-9.8,0.1-14.6-3.4-15.8-11.6c-7.5,9.1-15.4,17.8-23.6,26.3C604.9,222.6,610.9,225.8,617.7,226.2z"/>
+ <path class="st4" d="M580.9,131.1c4.1,0.3,7.6,0.5,11.8,0.8c0,2.6,0,4.8,0,6.9c0,19.4,0,38.8-0.2,58.2c0,7.8,3,15.3,7.9,20.7
+ c8.3-8.5,16.1-17.3,23.6-26.3c-0.2-1.4-0.3-2.8-0.3-4.5c0-13.3,0-26.6,0-39.9c0-4.9,0-9.8,0-15.4c11.5,0,22.2,0,33.7,0
+ c0-0.4,0-0.7,0-1.1c-25.8-0.5-51.4-3.3-76.5-8.2C580.9,125.3,580.9,128.2,580.9,131.1z"/>
+ <path class="st8" d="M623.6,85.3c-7.5,0-14.2,0-20.9,0c-2.6,13.7-5.9,26.4-21.8,28.8c0,2.9,0,5.6,0,8.2
+ c25.1,4.9,50.7,7.7,76.5,8.2c0-6.7,0-12.5,0-19.2c-11.3,0-22.2,0-33.8,0C623.6,102.1,623.6,93.9,623.6,85.3z"/>
+ </g>
+ <g class="st3">
+ <path class="st4" d="M416.9,113.3c0,5.7,0,11,0,16.4c4.2,0.3,7.7,0.5,12.3,0.8c-7.4,21.7-14.6,42.9-21.7,64.1
+ c-0.6,0-1.3-0.1-2-0.1c-7.5-21.2-15-42.3-22.7-64.1c5.5-0.3,9.8-0.5,13.9-0.7c0-4,0-7.6,0-11.1c-18.2,4.3-36.7,7.5-55.4,9.5
+ c0,0.6,0,1.2,0,1.9c7.6-1.1,10.4,3.2,12.7,9.3c9.9,25.8,20.1,51.5,30.3,77.3c1.1,2.8,2.3,5.5,3.4,7.9c11.5,0,22.2,0,33,0
+ c10.6-28.1,21.3-55.7,31.5-83.5c2.4-6.6,4.8-12.3,13-11.3c0-6.4,0-12.1,0-17.5c-15,0-29.5,0-43.8,0
+ C419.8,112.5,418.3,112.9,416.9,113.3z"/>
+ <path class="st10" d="M416.9,112c0,0.5,0,0.9,0,1.3c1.5-0.4,3-0.9,4.5-1.3C419.8,112,418.3,112,416.9,112z"/>
+ <path class="st8" d="M396.7,111.6c-18.6,0-36.6,0-55.4,0c0,5.8,0,11,0,16.4c18.7-2,37.2-5.2,55.4-9.5
+ C396.7,116.2,396.7,113.9,396.7,111.6z"/>
+ </g>
+ <g class="st3">
+ <path class="st4" d="M333.9,193.9c0-6.2,0-12.3,0-18.5c-10.8-14.4-20.7-29.3-29.6-44.8c-0.1,0-0.2,0-0.4,0
+ c-3.3,0-6.7-0.1-10.1-0.2c4.6,1.9,7.5,5.3,8.6,10.9c1.1,5.2,0.2,10.9,0.2,17.2c-7,0-13.3-0.2-19.6,0.1
+ c-10.5,0.5-21.2,0.4-30.7,5.7c-11.1,6.1-17.3,15.3-17.3,28.2c0,12.9,5.2,23.3,16.8,29.4c12.1,6.4,24.7,5.1,37,0.6
+ c5.6-2.1,10.9-5.1,16.2-7.7c8.8,12.3,22.2,13.6,42,8.7c0-5.4,0-10.8,0-16.9c-1.4-0.3-2.2-0.5-3-0.6
+ C334.1,204.3,333.9,204.2,333.9,193.9z M302.9,194.3c-0.1,1.8-1.6,4.2-3.2,5.1c-6.9,3.9-14.4,5.6-22.3,4.2
+ c-7.2-1.3-11.1-6.1-11.1-13.2c0-6.5,4.5-12.9,10.9-13.8c8.1-1.2,16.4-1.4,25.9-2.2C303,182.2,303.3,188.3,302.9,194.3z"/>
+ <path class="st4" d="M243.8,143.9c5.9,0,11,0,16.2,0c3.1-8,8.5-12.4,15.3-14.2c-10.5-0.7-21-1.8-31.4-3.2
+ C243.8,132.3,243.8,138,243.8,143.9z"/>
+ <path class="st5" d="M304.4,130.6c-4.1-7.1-8-14.4-11.7-21.7c-9-0.4-17.8,0.5-26.6,1.4c-7.6,0.8-15.5,0.6-22.2,4.4
+ c0,4,0,7.9,0,11.8c10.5,1.4,20.9,2.5,31.4,3.2c2.4-0.6,5-0.9,7.7-0.9c4.4,0,8.1,0.5,11,1.7c3.4,0.1,6.7,0.2,10.1,0.2
+ C304.1,130.6,304.2,130.6,304.4,130.6z"/>
+ <path class="st5" d="M333.9,175.4c0-9.1,0.1-18.1,0.1-27.2c0-6-1.5-12.4-4.6-18.3c-8.4,0.5-16.7,0.7-25.1,0.7
+ C313.3,146.1,323.2,161,333.9,175.4z"/>
+ <path class="st8" d="M329.5,129.9c-5.3-10.3-15.4-18.9-30.3-20.5c-2.2-0.2-4.3-0.4-6.5-0.5c3.7,7.3,7.6,14.6,11.7,21.7
+ C312.8,130.6,321.1,130.4,329.5,129.9z"/>
+ </g>
+</g>
+<g>
+ <path class="st5" d="M52.8,95.7H32.5l4.9-19.1h62l38,115.8c1,3.1,2.1,5.7,6.4,5.7h7.4V217H93.3v-18.9h12.5l-8.8-31H55.1l-9.6,31
+ h12.9V217H6.2v-18.9H14c4.9,0,7-4.5,8.4-8.4L52.8,95.7z M77.2,98.9h-2l-15.4,50.7h32.4L77.2,98.9z"/>
+ <path class="st5" d="M165.7,86h-8V68.2h41.7V195c0,3.7,1.8,4.3,4.7,4.3h8.2V217h-54.6v-17.7h8c2.9,0,4.9-0.4,4.9-4.1V90.9
+ C170.5,86.8,168.8,86,165.7,86z"/>
+ <path class="st5" d="M280.1,155.2v-12.9c0-9.2-6.6-15.4-17.7-15.4c-6.8,0-18.9,1.4-22.2,14.6H224v-27.9c14.6-3.7,30.6-5.7,41.1-5.7
+ c28.7,0,43.7,14,43.7,39.2v44.9c0,4.5,2,7.2,7.8,7.2h5.1v17.4c-5.5,0.8-11.7,1.9-17.4,1.9c-9.9,0-18.5-3.3-22-11.9
+ c-9.4,7.2-22.8,11.9-33,11.9c-17.7,0-32.8-10.5-32.8-31.8c0-17.9,13.1-31.6,41.1-31.6H280.1z M280.1,170.6h-16.2
+ c-9.9,0-18.3,3.7-18.3,14.4c0,8.8,6.4,12.9,13.3,12.9c7.4,0,15.6-2.1,21.3-6.6V170.6z"/>
+ <path class="st5" d="M328.9,130.6c-0.6-1.4-1.8-2.1-3.9-2.1h-5.9v-17.7h52.8v17.7h-13.7l21.5,60.5h1.8l20.5-60.5h-12.1v-17.7h46.2
+ v17.7h-6.4c-1.6,0-2.7,0.8-3.1,2l-32.8,86.8H363L328.9,130.6z"/>
+ <path class="st5" d="M436.7,163.6c0-36.9,20.9-55.6,52.5-55.6c37.4,0,46.6,24.6,46.6,51.1v10.7h-68.4c0.2,20.1,9,28.5,26.7,28.5
+ c8.8,0,21.1-2.3,26.5-15.2h13.1v26.7c-12.3,6-31,9.6-42.5,9.6C456.4,219.4,436.7,202.2,436.7,163.6z M508.8,152.9
+ c0-12.3-3.5-25.2-20.5-25.2c-15,0-21.5,11.1-21.5,25.2H508.8z"/>
+ <path class="st5" d="M583.7,182.7c0,10.9,6,14.2,15.6,14.2c4.3,0,9.4-1,13.8-2.3v21.3c-8.2,2.1-18.1,3.5-26.7,3.5
+ c-13.5,0-31.6-4.5-31.6-29.6v-60.1h-11.9v-16c13.8-2.5,18.7-11.1,20.9-27.9h19.9v25h32.2v18.9h-32.2V182.7z"/>
+ <path class="st5" d="M620.7,163.6c0-36.9,20.9-55.6,52.5-55.6c37.4,0,46.6,24.6,46.6,51.1v10.7h-68.4c0.2,20.1,9,28.5,26.7,28.5
+ c8.8,0,21.1-2.3,26.5-15.2h13.1v26.7c-12.3,6-31,9.6-42.5,9.6C640.4,219.4,620.7,202.2,620.7,163.6z M692.9,152.9
+ c0-12.3-3.5-25.2-20.5-25.2c-15,0-21.5,11.1-21.5,25.2H692.9z"/>
+ <path class="st5" d="M736.3,86h-8V68.2H770V195c0,3.7,1.8,4.3,4.7,4.3h8.2V217h-54.6v-17.7h8c2.9,0,4.9-0.4,4.9-4.1V90.9
+ C741.1,86.8,739.4,86,736.3,86z"/>
+ <path class="st5" d="M833.8,199.5h6.2v17.9c-5.8,1.2-11.1,1.6-15.8,1.6c-18.1,0-25.9-6.8-25.9-23.2v-62.4c0-4.1-1.6-4.9-5.1-4.9
+ h-7.6v-17.7h41.5v80C827.1,196.2,828.7,199.5,833.8,199.5z M797.7,68.2h29.8v23.4h-29.8V68.2z"/>
+</g>
+</svg>
diff --git a/assets/sass/_config.scss b/assets/sass/_config.scss new file mode 100644 index 000000000..291dee888 --- /dev/null +++ b/assets/sass/_config.scss @@ -0,0 +1,4 @@ +$logo_path: "../img/alaveteli-logo.svg"; +$logo_height: 60px; +$logo_width: 320px; +$colour_brand: #93278F; /* Alaveteli's purple */ diff --git a/assets/scripts/modernizer.js b/assets/scripts/modernizer.js new file mode 100644 index 000000000..df1610a18 --- /dev/null +++ b/assets/scripts/modernizer.js @@ -0,0 +1,4 @@ +/* Modernizr 2.7.1 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-svg-shiv-cssclasses-load + */ +;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(prefixes.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={svg:"http://www.w3.org/2000/svg"},n={},o={},p={},q=[],r=q.slice,s,t={}.hasOwnProperty,u;!x(t,"undefined")&&!x(t.call,"undefined")?u=function(a,b){return t.call(a,b)}:u=function(a,b){return b in a&&x(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.svg=function(){return!!b.createElementNS&&!!b.createElementNS(m.svg,"svg").createSVGRect};for(var A in n)u(n,A)&&(s=A.toLowerCase(),e[s]=n[A](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)u(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},v(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function q(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return s.shivMethods?o(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(s,b.frag)}function r(a){a||(a=b);var c=n(a);return s.shivCSS&&!g&&!c.hasCSS&&(c.hasCSS=!!l(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),k||q(a,c),a}var c="3.7.0",d=a.html5||{},e=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,f=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g,h="_html5shiv",i=0,j={},k;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))}; diff --git a/assets/scripts/modernizer.min.js b/assets/scripts/modernizer.min.js new file mode 100644 index 000000000..d0ebba419 --- /dev/null +++ b/assets/scripts/modernizer.min.js @@ -0,0 +1 @@ +window.Modernizr=function(e,t,n){function r(e){m.cssText=e}function o(e,t){return typeof e===t}var a,i,c,l="2.7.1",s={},u=!0,f=t.documentElement,p="modernizr",d=t.createElement(p),m=d.style,h=({}.toString,{svg:"http://www.w3.org/2000/svg"}),g={},y=[],v=y.slice,E={}.hasOwnProperty;c=o(E,"undefined")||o(E.call,"undefined")?function(e,t){return t in e&&o(e.constructor.prototype[t],"undefined")}:function(e,t){return E.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=v.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(v.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(v.call(arguments)))};return r}),g.svg=function(){return!!t.createElementNS&&!!t.createElementNS(h.svg,"svg").createSVGRect};for(var b in g)c(g,b)&&(i=b.toLowerCase(),s[i]=g[b](),y.push((s[i]?"":"no-")+i));return s.addTest=function(e,t){if("object"==typeof e)for(var r in e)c(e,r)&&s.addTest(r,e[r]);else{if(e=e.toLowerCase(),s[e]!==n)return s;t="function"==typeof t?t():t,"undefined"!=typeof u&&u&&(f.className+=" "+(t?"":"no-")+e),s[e]=t}return s},r(""),d=a=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=v.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=y[e[h]];return t||(t={},g++,e[h]=g,y[g]=t),t}function a(e,n,r){if(n||(n=t),u)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():m.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||d.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),u)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),l=c.length;l>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return v.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(v,t.frag)}function l(e){e||(e=t);var r=o(e);return v.shivCSS&&!s&&!r.hasCSS&&(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),u||c(e,r),e}var s,u,f="3.7.0",p=e.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,m=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,y={};!function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",s="hidden"in e,u=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){s=!0,u=!0}}();var v={elements:p.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:f,shivCSS:p.shivCSS!==!1,supportsUnknownElements:u,shivMethods:p.shivMethods!==!1,type:"default",shivDocument:l,createElement:a,createDocumentFragment:i};e.html5=v,l(t)}(this,t),s._version=l,f.className=f.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(u?" js "+y.join(" "):""),s}(this,this.document),function(e,t,n){function r(e){return"[object Function]"==g.call(e)}function o(e){return"string"==typeof e}function a(){}function i(e){return!e||"loaded"==e||"complete"==e||"uninitialized"==e}function c(){var e=y.shift();v=1,e?e.t?m(function(){("c"==e.t?p.injectCss:p.injectJs)(e.s,0,e.a,e.x,e.e,1)},0):(e(),c()):v=0}function l(e,n,r,o,a,l,s){function u(t){if(!d&&i(f.readyState)&&(E.r=d=1,!v&&c(),f.onload=f.onreadystatechange=null,t)){"img"!=e&&m(function(){S.removeChild(f)},50);for(var r in F[n])F[n].hasOwnProperty(r)&&F[n][r].onload()}}var s=s||p.errorTimeout,f=t.createElement(e),d=0,g=0,E={t:r,s:n,e:a,a:l,x:s};1===F[n]&&(g=1,F[n]=[]),"object"==e?f.data=n:(f.src=n,f.type=e),f.width=f.height="0",f.onerror=f.onload=f.onreadystatechange=function(){u.call(this,g)},y.splice(o,0,E),"img"!=e&&(g||2===F[n]?(S.insertBefore(f,b?null:h),m(u,s)):F[n].push(f))}function s(e,t,n,r,a){return v=0,t=t||"j",o(e)?l("c"==t?w:j,e,t,this.i++,n,r,a):(y.splice(this.i++,0,e),1==y.length&&c()),this}function u(){var e=p;return e.loader={load:s,i:0},e}var f,p,d=t.documentElement,m=e.setTimeout,h=t.getElementsByTagName("script")[0],g={}.toString,y=[],v=0,E="MozAppearance"in d.style,b=E&&!!t.createRange().compareNode,S=b?d:h.parentNode,d=e.opera&&"[object Opera]"==g.call(e.opera),d=!!t.attachEvent&&!d,j=E?"object":d?"script":"img",w=d?"script":j,C=Array.isArray||function(e){return"[object Array]"==g.call(e)},N=[],F={},x={timeout:function(e,t){return t.length&&(e.timeout=t[0]),e}};p=function(e){function t(e){var t,n,r,e=e.split("!"),o=N.length,a=e.pop(),i=e.length,a={url:a,origUrl:a,prefixes:e};for(n=0;i>n;n++)r=e[n].split("="),(t=x[r.shift()])&&(a=t(a,r));for(n=0;o>n;n++)a=N[n](a);return a}function i(e,o,a,i,c){var l=t(e),s=l.autoCallback;l.url.split(".").pop().split("?").shift(),l.bypass||(o&&(o=r(o)?o:o[e]||o[i]||o[e.split("/").pop().split("?")[0]]),l.instead?l.instead(e,o,a,i,c):(F[l.url]?l.noexec=!0:F[l.url]=1,a.load(l.url,l.forceCSS||!l.forceJS&&"css"==l.url.split(".").pop().split("?").shift()?"c":n,l.noexec,l.attrs,l.timeout),(r(o)||r(s))&&a.load(function(){u(),o&&o(l.origUrl,c,i),s&&s(l.origUrl,c,i),F[l.url]=2})))}function c(e,t){function n(e,n){if(e){if(o(e))n||(f=function(){var e=[].slice.call(arguments);p.apply(this,e),d()}),i(e,f,t,0,s);else if(Object(e)===e)for(l in c=function(){var t,n=0;for(t in e)e.hasOwnProperty(t)&&n++;return n}(),e)e.hasOwnProperty(l)&&(!n&&!--c&&(r(f)?f=function(){var e=[].slice.call(arguments);p.apply(this,e),d()}:f[l]=function(e){return function(){var t=[].slice.call(arguments);e&&e.apply(this,t),d()}}(p[l])),i(e[l],f,t,l,s))}else!n&&d()}var c,l,s=!!e.test,u=e.load||e.both,f=e.callback||a,p=f,d=e.complete||a;n(s?e.yep:e.nope,!!u),u&&n(u)}var l,s,f=this.yepnope.loader;if(o(e))i(e,0,f,0);else if(C(e))for(l=0;l<e.length;l++)s=e[l],o(s)?i(s,0,f,0):C(s)?p(s):Object(s)===s&&c(s,f);else Object(e)===e&&c(e,f)},p.addPrefix=function(e,t){x[e]=t},p.addFilter=function(e){N.push(e)},p.errorTimeout=1e4,null==t.readyState&&t.addEventListener&&(t.readyState="loading",t.addEventListener("DOMContentLoaded",f=function(){t.removeEventListener("DOMContentLoaded",f,0),t.readyState="complete"},0)),e.yepnope=u(),e.yepnope.executeStack=c,e.yepnope.injectJs=function(e,n,r,o,l,s){var u,f,d=t.createElement("script"),o=o||p.errorTimeout;d.src=e;for(f in r)d.setAttribute(f,r[f]);n=s?c:n||a,d.onreadystatechange=d.onload=function(){!u&&i(d.readyState)&&(u=1,n(),d.onload=d.onreadystatechange=null)},m(function(){u||(u=1,n(1))},o),l?d.onload():h.parentNode.insertBefore(d,h)},e.yepnope.injectCss=function(e,n,r,o,i,l){var s,o=t.createElement("link"),n=l?c:n||a;o.href=e,o.rel="stylesheet",o.type="text/css";for(s in r)o.setAttribute(s,r[s]);i||(h.parentNode.insertBefore(o,h),m(n,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
\ No newline at end of file diff --git a/community.md b/community.md new file mode 100644 index 000000000..2b24b6529 --- /dev/null +++ b/community.md @@ -0,0 +1,75 @@ +--- +layout: page +title: Community +--- + +The Alaveteli Community +==================== + +<p class="lead"> + If you are running an Alaveteli installation — or are thinking of setting one up — let the community help. +</p> + +We actively help people set up and run Alaveteli instances all around the +world. Alaveteli is more than just software, it's also a community of people +who care enough about <a href="{{ site.baseurl}}glossary/#foi" +class="glossary">Freedom of Information</a> to build and run sites to benefit +the public. + +If you're just starting out, or you've already got your site up and running, +this page points you at the places you can find out more, ask questions, or +just say hi. + +<!-- + direct email and twitter? + + <li>Louise Crow (project lead): <a href="mailto:louise@mysociety.org">email</a>, <a href="http://twitter.com/crowbot">twitter</a></li> +--> + + +## Project mailing list + +Sign up for the <a href="https://groups.google.com/group/alaveteli-dev">Alaveteli project mailing list</a> — feel free to ask questions. Lots of helpful people are on it +— not just mySociety staff but also people (like you!) running their own +sites. + +The archives are a good source of information too. If you've got a problem, it's +always worth checking to see if someone has already solved it. + +It you're just starting out, saying hello on the mailing list is a great way to +begin <img src="http://www.alaveteli.org/wp-includes/images/smilies/icon_smile.gif" alt=":-)"> + +## IRC + +### irc.mysociety.org #mschat + +**`#mschat`** — +the mySociety developers can be found on IRC in `#mschat` on +`irc.mysociety.org` (running on port `6667`, and also `9219`) +(also available via this [web interface](http://www.irc.mysociety.org)). + +### irc.freenode.net #alaveteli + +**`#alaveteli`** — +there's an `#alaveteli` channel on +[Freenode](http://freenode.net) (`irc.freenode.net`) ...although that channel can be rather quiet +<img src="http://www.alaveteli.org/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"> + +## Alaveteli commit messages (code) + +To keep an eye on activity on the repo, join the +<a href="https://groups.google.com/group/alaveteli-commits/">Alaveteli push messages mailing list</a> (one a day). + +## Code and issues on github + +The [Alaveteli software is on github](https://github.com/mysociety/alaveteli) and we actively use +[github's issues](https://github.com/mysociety/alaveteli) — sometimes there's discussion on specific issues in there too, which can be handy (especially if it's an issue you've raised). + +## Documentation + +Although asking a human is great, often what you want to know can be +found in the documentation: + +* [this documentation]({{ site.baseurl }}) — always the first place to look +* [the dev wiki](http://github.com/mysociety/alaveteli/wiki) — informal or specific notes +* [docs in the repo](https://github.com/mysociety/alaveteli/tree/rails-3-develop/doc) (although we're slowly phasing these out in favour of the docs you're reading now) diff --git a/customising/config.md b/customising/config.md new file mode 100644 index 000000000..dc9756181 --- /dev/null +++ b/customising/config.md @@ -0,0 +1,1137 @@ +--- +layout: page +title: Configuration +--- + +# Configuring Alaveteli + +<p class="lead"> + You can control much of how Alaveteli looks and behaves just by + changing the config settings. +</p> + +## The general configuration file + +The alaveteli code ships with an example configuration file: `config/general.yml-example`. + +As part of the [installation process]({{ site.baseurl }}installing ), the +example file gets copied to `config/general.yml`. You **must** edit this file to +suit your needs. + +Note that the default settings for frontpage examples are designed to work with +the dummy data shipped with Alaveteli. Once you have real data, you should +certainly edit these. + +Note that there are [other configuration files](#other-config) too, for specific aspects of Alaveteli. + + +## Config settings by topic + +The following are all the configuration settings that you can change in `config/general.yml`. +When you edit this file, remember it must be in the <a href="http://yaml.org">YAML syntax</a>. +It's not complicated but — especially if you're editing a list — be careful to get the +indentation correct. If in doubt, look at the examples already in the file, and don't use tabs. + + +### Appearance and overall behaviour of the site: + +<code><a href="#site_name">SITE_NAME</a></code> +<br> <code><a href="#domain">DOMAIN</a></code> +<br> <code><a href="#force_ssl">FORCE_SSL</a></code> +<br> <code><a href="#force_registration_on_new_request">FORCE_REGISTRATION_ON_NEW_REQUEST</a></code> +<br> <code><a href="#theme_urls">THEME_URLS</a></code> +<br> <code><a href="#theme_branch">THEME_BRANCH</a></code> +<br> <code><a href="#frontpage_publicbody_examples">FRONTPAGE_PUBLICBODY_EXAMPLES</a></code> +<br> <code><a href="#public_body_statistics_page">PUBLIC_BODY_STATISTICS_PAGE</a></code> +<br> <code><a href="#minimum_requests_for_statistics">MINIMUM_REQUESTS_FOR_STATISTICS</a></code> + +### Site status: + +<code><a href="#read_only">READ_ONLY</a></code> +<br> <code><a href="#staging_site">STAGING_SITE</a></code> + +### Locale and internationalisation: + +<code><a href="#iso_country_code">ISO_COUNTRY_CODE</a></code> +<br> <code><a href="#time_zone">TIME_ZONE</a></code> +<br> <code><a href="#available_locales">AVAILABLE_LOCALES</a></code> +<br> <code><a href="#default_locale">DEFAULT_LOCALE</a></code> +<br> <code><a href="#use_default_browser_language">USE_DEFAULT_BROWSER_LANGUAGE</a></code> +<br> <code><a href="#include_default_locale_in_urls">INCLUDE_DEFAULT_LOCALE_IN_URLS</a></code> + +### Definition of "late": + +<code><a href="#reply_late_after_days">REPLY_LATE_AFTER_DAYS</a></code> +<br> <code><a href="#reply_very_late_after_days">REPLY_VERY_LATE_AFTER_DAYS</a></code> +<br> <code><a href="#special_reply_very_late_after_days">SPECIAL_REPLY_VERY_LATE_AFTER_DAYS</a></code> +<br> <code><a href="#working_or_calendar_days">WORKING_OR_CALENDAR_DAYS</a></code> + +### Admin access: + +<code><a href="#admin_username">ADMIN_USERNAME</a></code> +<br> <code><a href="#admin_password">ADMIN_PASSWORD</a></code> +<br> <code><a href="#admin_username">DISABLE_EMERGENCY_USER</a></code> +<br> <code><a href="#skip_admin_auth">SKIP_ADMIN_AUTH</a></code> + +### Email management: + +<code><a href="#incoming_email_domain">INCOMING_EMAIL_DOMAIN</a></code> +<br> <code><a href="#incoming_email_prefix">INCOMING_EMAIL_PREFIX</a></code> +<br> <code><a href="#incoming_email_secret">INCOMING_EMAIL_SECRET</a></code> +<br> <code><a href="#blackhole_prefix">BLACKHOLE_PREFIX</a></code> +<br> <code><a href="#contact_email">CONTACT_EMAIL</a></code> +<br> <code><a href="#contact_name">CONTACT_NAME</a></code> +<br> <code><a href="#track_sender_email">TRACK_SENDER_EMAIL</a></code> +<br> <code><a href="#track_sender_name">TRACK_SENDER_NAME</a></code> +<br> <code><a href="#raw_emails_location">RAW_EMAILS_LOCATION</a></code> +<br> <code><a href="#exception_notifications_from">EXCEPTION_NOTIFICATIONS_FROM</a></code> +<br> <code><a href="#exception_notifications_to">EXCEPTION_NOTIFICATIONS_TO</a></code> +<br> <code><a href="#forward_nonbounce_responses_to">FORWARD_NONBOUNCE_RESPONSES_TO</a></code> +<br> <code><a href="#mta_log_path">MTA_LOG_PATH</a></code> +<br> <code><a href="#mta_log_type">MTA_LOG_TYPE</a></code> + +### General admin (keys, paths, back-end services): + +<code><a href="#cookie_store_session_secret">COOKIE_STORE_SESSION_SECRET</a></code> +<br> <code><a href="#recaptcha_public_key">RECAPTCHA_PUBLIC_KEY</a></code> +<br> <code><a href="#recaptcha_private_key">RECAPTCHA_PRIVATE_KEY</a></code> +<br> <code><a href="#gaze_url">GAZE_URL</a></code> +<br> <code><a href="#ga_code">GA_CODE</a></code> (GA=Google Analytics) +<br> <code><a href="#utility_search_path">UTILITY_SEARCH_PATH</a></code> +<br> <code><a href="#shared_files_path">SHARED_FILES_PATH</a></code> +<br> <code><a href="#shared_files">SHARED_FILES</a></code> +<br> <code><a href="#shared_directories">SHARED_DIRECTORIES</a></code> + +### Behaviour settings and switches: + +<code><a href="#new_response_reminder_after_days">NEW_RESPONSE_REMINDER_AFTER_DAYS</a></code> +<br> <code><a href="#max_requests_per_user_per_day">MAX_REQUESTS_PER_USER_PER_DAY</a></code> +<br> <code><a href="#override_all_public_body_request_emails">OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS</a></code> +<br> <code><a href="#allow_batch_requests">ALLOW_BATCH_REQUESTS</a></code> +<br> <code><a href="#public_body_list_fallback_to_default_locale">PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE</a></code> +<br> <code><a href="#cache_fragments">CACHE_FRAGMENTS</a></code> + +### External public services: + +<code><a href="#blog_feed">BLOG_FEED</a></code> +<br> <code><a href="#twitter_username">TWITTER_USERNAME</a></code> +<br> <code><a href="#twitter_widget_id">TWITTER_WIDGET_ID</a></code> +<br> <code><a href="#donation_url">DONATION_URL</a></code> + +### Development work or special cases: + +<code><a href="#debug_record_memory">DEBUG_RECORD_MEMORY</a></code> +<br> <code><a href="#varnish_host">VARNISH_HOST</a></code> +<br> <code><a href="#use_mailcatcher_in_development">USE_MAILCATCHER_IN_DEVELOPMENT</a></code> +<br> <code><a href="#use_ghostscript_compression">USE_GHOSTSCRIPT_COMPRESSION</a></code> +<br> <code><a href="#html_to_pdf_command">HTML_TO_PDF_COMMAND</a></code> + + +--- + +## All the general settings + + +<dl class="glossary"> + + <dt> + <a name="site_name"><code>SITE_NAME</code></a> + </dt> + <dd> + <strong>SITE_NAME</strong> appears in various places throughout the site. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>SITE_NAME: 'Alaveteli'</code> + </li> + <li> + <code>SITE_NAME: 'WhatDoTheyKnow'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="domain"><code>DOMAIN</code></a> + </dt> + <dd> + Domain used in URLs generated by scripts (e.g. for going in some emails) + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>DOMAIN: '127.0.0.1:3000'</code> + </li> + <li> + <code>DOMAIN: 'www.example.com'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="force_ssl"><code>FORCE_SSL</code></a> + </dt> + <dd> + If true forces everyone (in the production environment) to use encrypted connections + (via https) by redirecting unencrypted connections. This is <strong>highly + recommended</strong> so that logins can't be intercepted by naughty people. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>FORCE_SSL: true</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="iso_country_code"><code>ISO_COUNTRY_CODE</code></a> + </dt> + <dd> + The <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO country code</a> + of the country in which your Alaveteli site is deployed. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>ISO_COUNTRY_CODE: GB</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="time_zone"><code>TIME_ZONE</code></a> + </dt> + <dd> + This is the <a href="http://en.wikipedia.org/wiki/List_of_tz_database_time_zones">timezone</a> + that Alaveteli usese to display times and dates. + If not set, defaults to UTC. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>TIME_ZONE: Australia/Sydney</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="blog_feed"><code>BLOG_FEED</code></a> + </dt> + <dd> + These feeds are displayed accordingly on the Alaveteli "blog" page: <!-- TODO --> + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>BLOG_FEED: 'http://www.mysociety.org/category/projects/whatdotheyknow/feed/'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="twitter_username"><code>TWITTER_USERNAME</code></a> + <a name="twitter_widget_id"><code>TWITTER_WIDGET_ID</code></a> + </dt> + <dd> + If you want a twitter feed displayed on the "blog" page, provide the widget ID and username. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>TWITTER_USERNAME: WhatDoTheyKnow</code> + </li> + <li> + <code>TWITTER_WIDGET_ID: '833549204689320031'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="available_locales"><code>AVAILABLE_LOCALES</code></a> & + <a name="default_locale"><code>DEFAULT_LOCALE</code></a> + </dt> + <dd> + <strong>AVAILABLE_LOCALES</strong> lists all the locales you want your site to support. + If there is more than one, use spaces betwween the entries. + Nominate one of these locales as the default with <strong>DEFAULT_LOCALE</strong>. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>AVAILABLE_LOCALES: 'en es'</code> + </li> + <li> + <code>DEFAULT_LOCALE: 'en'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="use_default_browser_language"><code>USE_DEFAULT_BROWSER_LANGUAGE</code></a> + </dt> + <dd> + Should Alaveteli try to use the default language of the user's browser? + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>USE_DEFAULT_BROWSER_LANGUAGE: true</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="include_default_locale_in_urls"><code>INCLUDE_DEFAULT_LOCALE_IN_URLS</code></a> + </dt> + <dd> + Normally, Alaveteli will put the locale into its URLs, like this + <code>www.example.com/en/body/list/all</code>. If you don't want this + behaviour whenever the locale is the default one, set + <strong>INCLUDE_DEFAULT_LOCALE_IN_URLS</strong> to false. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>INCLUDE_DEFAULT_LOCALE_IN_URLS: true</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="reply_late_after_days"><code>REPLY_LATE_AFTER_DAYS</code></a><br> + <a name="reply_very_late_after_days"><code>REPLY_VERY_LATE_AFTER_DAYS</code></a><br> + <a name="special_reply_very_late_after_days"><code>SPECIAL_REPLY_VERY_LATE_AFTER_DAYS</code></a> + <a name="working_or_calendar_days"><code>WORKING_OR_CALENDAR_DAYS</code></a> + </dt> + <dd> + The <strong>REPLY...AFTER_DAYS</strong> settings define how many days must have + passed before an answer to a request is officially <em>late</em>. + The SPECIAL case is for some types of authority (for example: in the UK, schools) which are + granted a bit longer than everyone else to respond to questions. + The <strong>WORKING_OR_CALENDAR_DAYS</strong> setting can be either "working" (the default) + or "calendar", and determines which days are counted. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>REPLY_LATE_AFTER_DAYS: 20</code> + </li> + <li> + <code>REPLY_VERY_LATE_AFTER_DAYS: 40</code> + </li> + <li> + <code>SPECIAL_REPLY_VERY_LATE_AFTER_DAYS: 60</code> + </li> + <li> + <code>WORKING_OR_CALENDAR_DAYS: working</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="frontpage_publicbody_examples"><code>FRONTPAGE_PUBLICBODY_EXAMPLES</code></a> + </dt> + <dd> + Specify which public bodies you want to be listed as examples on the home page, + using their <code>short_names</code>. + If you want more than one, separate them with semicolons. + Comment this out if you want this to be auto-generated. + <p> + <strong>Warning</strong>: this is slow — don't use in production! + </p> + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq'</code> + </li> + <li> + <code>FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq;foo;bar'</code> + </li> + <li> + <code># FRONTPAGE_PUBLICBODY_EXAMPLES: </code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="theme_urls"><code>THEME_URLS</code></a> + </dt> + <dd> + URLs of <a href="{{ site.baseurl }}customising/themes">themes</a> to download and use + (when running the <code>rails-post-deploy</code> script). The earlier in the list means + the templates have a higher priority. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <pre> +THEME_URLS: + - 'git://github.com/mysociety/alavetelitheme.git' +</pre> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="theme_branch"><code>THEME_BRANCH</code></a> + </dt> + <dd> + When <code>rails-post-deploy</code> installs the <a href="{{ site.baseurl }}customising/themes">themes</a>, + it will try the theme branch first, but only if you've set <code>THEME_BRANCH</code> + to be true. If the branch doesn't exist it will fall back to using a tagged version + specific to your installed alaveteli version, and if that doesn't exist it will + back to <code>master</code>. + <p> + The default theme is the "Alaveteli" theme. This gets installed automatically when + <code>rails-post-deploy</code> runs. + </p> + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>THEME_BRANCH: false</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="force_registration_on_new_request"><code>FORCE_REGISTRATION_ON_NEW_REQUEST</code></a> + </dt> + <dd> + Does a user needs to sign in to start the New Request process? + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>FORCE_REGISTRATION_ON_NEW_REQUEST: false</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="incoming_email_domain"><code>INCOMING_EMAIL_DOMAIN</code></a> + </dt> + <dd> + Your email domain for incoming mail. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>INCOMING_EMAIL_DOMAIN: 'localhost'</code> + </li> + <li> + <code>INCOMING_EMAIL_DOMAIN: 'foifa.com'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="incoming_email_prefix"><code>INCOMING_EMAIL_PREFIX</code></a> + </dt> + <dd> + An optional prefix to help you distinguish FOI requests. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>INCOMING_EMAIL_PREFIX: ''</code> + </li> + <li> + <code>INCOMING_EMAIL_PREFIX: 'foi+'</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="incoming_email_secret"><code>INCOMING_EMAIL_SECRET</code></a> + </dt> + <dd> + Used for hash in request email address. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>INCOMING_EMAIL_SECRET: '11ae 4e3b 70ff c001 3682 4a51 e86d ef5f'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="blackhole_prefix"><code>BLACKHOLE_PREFIX</code></a> + </dt> + <dd> + Used as envelope from at the incoming email domain for cases where you don't care about failure. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>BLACKHOLE_PREFIX: 'do-not-reply-to-this-address'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="admin_username"><code>ADMIN_USERNAME</code></a> + & + <a name="admin_password"><code>ADMIN_PASSWORD</code></a> + <br> + <a name="admin_username"><code>DISABLE_EMERGENCY_USER</code></a> + </dt> + <dd> + The emergency user. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>ADMIN_USERNAME: 'adminxxxx'</code> + </li> + <li> + <code>ADMIN_PASSWORD: 'passwordx'</code> + </li> + <li> + <code>DISABLE_EMERGENCY_USER: false</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="skip_admin_auth"><code>SKIP_ADMIN_AUTH</code></a> + </dt> + <dd> + Set this to true, and the admin interface will be available to anonymous users. + Obviously, you should not set this to be true in production environments. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>SKIP_ADMIN_AUTH: false</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="contact_email"><code>CONTACT_EMAIL</code></a> + & + <a name="contact_name"><code>CONTACT_NAME</code></a> + </dt> + <dd> + Email "from" details. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>CONTACT_EMAIL: 'team@example.com'</code> + </li> + <li> + <code>CONTACT_NAME: 'Alaveteli Webmaster'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="track_sender_email"><code>TRACK_SENDER_EMAIL</code></a> & + <a name="track_sender_name"><code>TRACK_SENDER_NAME</code></a> + </dt> + <dd> + Email "from" details for track messages. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>TRACK_SENDER_EMAIL: 'alaveteli@example.com'</code> + </li> + <li> + <code>TRACK_SENDER_NAME: 'Alaveteli Webmaster'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="raw_emails_location"><code>RAW_EMAILS_LOCATION</code></a> + </dt> + <dd> + Where the raw incoming email data gets stored. + <strong>Make sure you back this up!</strong> + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>RAW_EMAILS_LOCATION: 'files/raw_emails'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="cookie_store_session_secret"><code>COOKIE_STORE_SESSION_SECRET</code></a> + </dt> + <dd> + Secret key for signing cookie_store sessions. Make it long and random. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>COOKIE_STORE_SESSION_SECRET: 'uIngVC238Jn9NsaQizMNf89pliYmDBFugPjHS2JJmzOp8'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="read_only"><code>READ_ONLY</code></a> + </dt> + <dd> + If present, <strong>READ_ONLY</strong> puts the site in read-only mode, + and uses the text as reason (whole paragraph). Please use a read-only database + user as well, as it only checks in a few obvious places. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + Typically, you do <strong>not</strong> want to run your site in + read-only mode — so set <strong>READ_ONLY</strong> to be + an empty string. + <br> + <code> + READ_ONLY: '' + </code> + </li> + <li> + <code> + READ_ONLY: 'The site is not currently accepting requests while we move the server.' + </code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="staging_site"><code>STAGING_SITE</code></a> + </dt> + <dd> + Is this a staging or development site (1) or a live (production) site (0)? + This controls whether or not the <code>rails-post-deploy</code> script + will create the file <code>config/rails_env.rb</code> file to force + Rails into production environment. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>STAGING_SITE: 1</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="recaptcha_public_key"><code>RECAPTCHA_PUBLIC_KEY</code></a> & + <a name="recaptcha_private_key"><code>RECAPTCHA_PRIVATE_KEY</code></a> + </dt> + <dd> + Recaptcha, for detecting humans. Get keys here: + <a href="http://recaptcha.net/whyrecaptcha.html">http://recaptcha.net/whyrecaptcha.html</a> + + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>RECAPTCHA_PUBLIC_KEY: '7HoPjGBBBBBBBBBkmj78HF9PjjaisQ893'</code> + </li> + <li> + <code>RECAPTCHA_PRIVATE_KEY: '7HjPjGBBBBBCBBBpuTy8a33sgnGG7A'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="new_response_reminder_after_days"><code>NEW_RESPONSE_REMINDER_AFTER_DAYS</code></a> + </dt> + <dd> + Number of days after which to send a 'new response reminder'. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>NEW_RESPONSE_REMINDER_AFTER_DAYS: [3, 10, 24]</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="debug_record_memory"><code>DEBUG_RECORD_MEMORY</code></a> + </dt> + <dd> + For debugging memory problems. If true, Alaveteli logs + the memory use increase of the Ruby process due to the + request (Linux only). Since Ruby never returns memory to the OS, if the + existing process previously served a larger request, this won't + show any consumption for the later request. + + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>DEBUG_RECORD_MEMORY: false</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="use_ghostscript_compression"><code>USE_GHOSTSCRIPT_COMPRESSION</code></a> + </dt> + <dd> + Currently we default to using pdftk to compress PDFs. You can + optionally try Ghostscript, which should do a better job of + compression. Some versions of pdftk are buggy with respect to + compression, in which case Alaveteli doesn't recompress the PDFs at + all and logs a warning message "Unable to compress PDF" — which would + be another reason to try this setting. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>USE_GHOSTSCRIPT_COMPRESSION: true</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="gaze_url"><code>GAZE_URL</code></a> + </dt> + <dd> + Alateveli uses mySociety's gazeteer service to determine country from incoming + IP address (this lets us suggest an Alaveteli in their country, if one exists). + You shouldn't normally need to change this. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>GAZE_URL: http://gaze.mysociety.org</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="forward_nonbounce_responses_to"><code>FORWARD_NONBOUNCE_RESPONSES_TO</code></a> + </dt> + <dd> + The email address to which non-bounce responses should be forwarded + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>FORWARD_NONBOUNCE_RESPONSES_TO: user-support@example.com</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="html_to_pdf_command"><code>HTML_TO_PDF_COMMAND</code></a> + </dt> + <dd> + Path to a program that converts an HTML page in a file to PDF. It + should take two arguments: the URL, and a path to an output file. + A static binary of <a href="http://wkhtmltopdf.org">wkhtmltopdf</a> is recommended. + If the command is not present, a text-only version will be rendered + instead. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="exception_notifications_from"><code>EXCEPTION_NOTIFICATIONS_FROM</code></a> & + <a name="exception_notifications_to"><code>EXCEPTION_NOTIFICATIONS_TO</code></a> + </dt> + <dd> + Email address(es) used for sending exception notifications. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <pre> +EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@example.com + +EXCEPTION_NOTIFICATIONS_TO: + - robin@example.com + - seb@example.com +</pre> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="max_requests_per_user_per_day"><code>MAX_REQUESTS_PER_USER_PER_DAY</code></a> + </dt> + <dd> + This rate limiting can be turned off per-user via the admin interface. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>MAX_REQUESTS_PER_USER_PER_DAY: 6</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="varnish_host"><code>VARNISH_HOST</code></a> + </dt> + <dd> + If you're running behind Varnish, it might help to set this to + work out where to send purge requests. + Otherwise, don't set it. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>VARNISH_HOST: null</code> + </li> + <li> + <code>VARNISH_HOST: localhost</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="ga_code"><code>GA_CODE</code> (GA=Google Analytics)</a> + </dt> + <dd> + Adding a value here will enable Google Analytics on all non-admin pages for non-admin users. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>GA_CODE: ''</code> + </li> + <li> + <code>GA_CODE: 'AB-8222142-14'</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="override_all_public_body_request_emails"><code>OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS</code></a> + </dt> + <dd> + If you want to override <strong>all</strong> the public body request emails with + your own email address so that request emails that would normally go to the public body + go to you, use this setting. + This is useful for a staging server, so you can play with the whole process of sending requests + without inadvertently sending an email to a real authority. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <code>OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS: test-email@foo.com</code> + </li> + <li> + If you don't want this behaviour, comment the setting out + <br> + <code># OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS:</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="utility_search_path"><code>UTILITY_SEARCH_PATH</code></a> + </dt> + <dd> + Search path for external command-line utilities (such as pdftohtml, pdftk, unrtf). + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>UTILITY_SEARCH_PATH: ["/usr/bin", "/usr/local/bin"]</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="mta_log_path"><code>MTA_LOG_PATH</code></a> + </dt> + <dd> + Path to your exim or postfix log files that will get sucked up + by <code>script/load-mail-server-logs</code>. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>MTA_LOG_PATH: '/var/log/exim4/exim-mainlog-*'</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="mta_log_type"><code>MTA_LOG_TYPE</code></a> + </dt> + <dd> + Are you using "exim" or "postfix" for your Mail Transfer Agnt (MTA)? + + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>MTA_LOG_TYPE: "exim"</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="donation_url"><code>DONATION_URL</code></a> + </dt> + <dd> + URL where people can donate to the organisation running the site. If set, + this will be included in the message people see when their request is + successful. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>DONATION_URL: "http://www.mysociety.org/donate/"</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="public_body_statistics_page"><code>PUBLIC_BODY_STATISTICS_PAGE</code></a> & + <a name="minimum_requests_for_statistics"><code>MINIMUM_REQUESTS_FOR_STATISTICS</code></a> + </dt> + <dd> + If <strong>PUBLIC_BODY_STATISTICS_PAGE</strong> is set to true, Alaveteli will make a + page of statistics on the performance of public bodies (which you can see at + <code>/body_statistics</code>). + The page will only consider public bodies that have had at least the number of requests + set by <strong>MINIMUM_REQUESTS_FOR_STATISTICS</strong>. + + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>PUBLIC_BODY_STATISTICS_PAGE: false</code> + </li> + <li> + <code>MINIMUM_REQUESTS_FOR_STATISTICS: 50</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="public_body_list_fallback_to_default_locale"><code>PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE</code></a> + </dt> + <dd> + If you would like the public body list page to include bodies that have no translation + in the current locale (but which do have a translation in the default locale), set this to true. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE: false</code> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="use_mailcatcher_in_development"><code>USE_MAILCATCHER_IN_DEVELOPMENT</code></a> + </dt> + <dd> + <!-- TODO check mailcatcher URL --> + If true, while in development mode, try to send mail by SMTP to port + 1025 (the port the <a href="http://mailcatcher.me">mailcatcher</a> listens on by default): + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>USE_MAILCATCHER_IN_DEVELOPMENT: true</code> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="cache_fragments"><code>CACHE_FRAGMENTS</code></a> + </dt> + <dd> + Use memcached to cache HTML fragments for better performance. + This will only have an effect in environments where + <code>config.action_controller.perform_caching</code> is set to true + + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>CACHE_FRAGMENTS: true</code> + </li> + </ul> + </div> + </dd> + + + + <dt> + <a name="shared_files_path"><code>SHARED_FILES_PATH</code></a> + </dt> + <dd> + In some deployments of Alaveteli you may wish to install each newly + deployed version alongside the previous ones, in which case certain + files and resources should be shared between these installations. + For example, the <code>files</code> directory, the <code>cache</code> directory and the + generated graphs such as <code>public/foi-live-creation.png</code>. If you're + installing Alaveteli in such a setup then set <strong>SHARED_FILES_PATH</strong> to + the directory you're keeping these files under. Otherwise, leave it blank. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>SHARED_FILES_PATH: ''</code> <!-- TODO specific example --> + </li> + </ul> + </div> + </dd> + + + <dt> + <a name="shared_files"><code>SHARED_FILES</code></a> & + <a name="shared_directories"><code>SHARED_DIRECTORIES</code></a> + </dt> + <dd> + If you have <strong>SHARED_FILES_PATH</strong> set, then these options list the files + and directories that are shared; i.e. those to which the deploy scripts + should create symlinks from the repository. + <div class="more-info"> + <p>Examples:</p> + <ul> + <li> + <pre> +SHARED_FILES: + - config/database.yml + - config/general.yml + - config/rails_env.rb + - config/newrelic.yml + - config/httpd.conf + - public/foi-live-creation.png + - public/foi-user-use.png + - config/aliases + </pre> + </li> + <li> + <pre> +SHARED_DIRECTORIES: + - files/ + - cache/ + - lib/acts_as_xapian/xapiandbs/ + - vendor/bundle + - public/assets + </pre> + </li> + </ul> + </div> + </dd> + + <dt> + <a name="allow_batch_requests"><code>ALLOW_BATCH_REQUESTS</code></a> + </dt> + <dd> + Allow some users to make batch requests to multiple authorities. Once + this is set to true, you can enable batch requests for an individual + user via the user admin page. + <div class="more-info"> + <p>Example:</p> + <ul> + <li> + <code>ALLOW_BATCH_REQUESTS: false</code> + </li> + </ul> + </div> + </dd> + +</dl> + +<a name="other-config"> </a> + +## Other configuration files + +Note that there are other configuration files for Alaveteli — you'll find them all +in the `config` directory. These are presented in the git repository as `*-example` files +which you can copy into place. + +<dl> + <dt> + <strong>database.yml</strong> + </dt> + <dd> + database settings (as per Rails) + </dd> + <dt> + <strong>deploy.yml</strong> + </dt> + <dd> + deployment specifications used by Capistrano + </dd> + <dt> + <strong>httpd.conf, nginx.conf</strong> + </dt> + <dd> + Apache and Nginx configuration suggestions + </dd> + <dt> + <strong>newrelic.yml</strong> + </dt> + <dd> + Analytics configuration + </dd> +</dl>
\ No newline at end of file diff --git a/customising/index.md b/customising/index.md new file mode 100644 index 000000000..db1f5321f --- /dev/null +++ b/customising/index.md @@ -0,0 +1,44 @@ +--- +layout: page +title: Customising +--- + +# Customising Alaveteli + +<p class="lead"> + There are two ways to make your installation look and act the way you want. + Some behaviour can be controlled with <strong>configuration settings</strong>. + For more complex changes, you'll need to create a new <strong>theme</strong>. +</p> + + +## Configuration settings + +You can customise much of Alaveteli's behaviour just by editing the configuration +file. This [complete list of Alaveteli's config settings]({{ site.baseurl }}customising/config) +shows the sort of things you can control in this way. + +<!-- TODO key settings --> + +## Simple branding: colour and logo + +It's common to want to change the basic appearance of the site. Although you +can simply edit the default templates and CSS to do this, we **strongly +recommend** that you [create a theme]({{ site.baseurl }}customising/themes). + +Themes do not need to be especially complex, but they allow your changes to +work alongside the core code, which you can then update (when new releases or +updates become available). + +## Need Alaveteli in a different language? + +No problem! See the [information about translating Alaveteli]({{ site.baseurl }}customising/translation). + +## Complex changes + +If you are a developer (or you have a team of programmers available) you can +add any customisation that you want. But it's important to do this without +breaking the core code, so that you can accept new releases with updates. +There's more detail in the [page about themes]({{ site.baseurl }}customising/themes). + +See also the [documentation for developers]({{ site.baseurl }}developers). diff --git a/customising/themes.md b/customising/themes.md new file mode 100644 index 000000000..f6e504eff --- /dev/null +++ b/customising/themes.md @@ -0,0 +1,188 @@ +--- +layout: page +title: Themes +--- + +# Alaveteli's themes + +<p class="lead"> + Alaveteli uses <strong>themes</strong> to make the site look and run + differently from the default. + Simple changes like colour and logo are relatively easy, but themes can also + control more complex things like <em>how</em> the site behaves. +</p> + +When you customise your Alaveteli site, there is a lot you can change just +by editing the [config settings]({{ site.baseurl }}customising/config). +But if you want to change the way the site looks, or add more specific +behaviour, you'll need to make a **theme**. + +You don't need to be a programmer in order to make simple changes, but you will +need to be confident enough to copy and change some files. If you're not sure +about this, [ask for help](/community)! + +## What you might want to change + +The most common requirement is to brand the site: at a minimum, +inserting your own logo and colour scheme. You may also want to tweak +the different states that a request can go through. You'll also want +to edit the categories that public bodies can appear in (i.e. the +groupings on the left hand side of the +"[View authorities](http://www.whatdotheyknow.com/body/list/all)" page +on WhatDoTheyKnow. + +There may also be other things you want to customise -- drop a line on +the developer's mailing list to discuss what you need. We're still working +out the best way of doing these kinds of customisations! + +In any case, the important principle to bear in mind is that the less +you override and customise the code, the easier your site will be to +maintain in the long term. Any customisation is possible, but for +each customisation beyond the simple cases documented here, ask +yourself (or your client), "can we possibly live without this?" If the +answer is "no", then consider starting a discussion about a pluggable +way of achieving your goals, rather than overriding any of the core +code. + +## General principles + +We try to encapsulate all site-specific functionality in one of these +places: + +* Site [configuration]({{ site.baseurl }}customisation/config ) + (e.g., the name of your site, the available + languages, and so on — all in `config/general.yml`) +* Data (e.g. the public bodies to whom requests should be addressed) +* A theme, installed in `lib/themes`. + +This document is about what you can do in a theme. + +By default, the sample theme ("alavetelitheme") has already been +installed. See the setting +[`THEME_URLS`]({{ site.baseurl }}customising/config/#theme_urls) +in `general.yml` for an explanation. + +You can also install the sample theme by hand, by running: + + bundle exec rails plugin install git://github.com/mysociety/alavetelitheme.git + +The sample theme contains examples for nearly everything you might +want to customise. You should probably make a copy, rename it, and +use that as the basis for your own theme. + +## Make sure your theme is as lightweight as possible + +The more you put in your theme, the harder it will be to upgrade to +future versions of Alaveteli. Everything you place in your theme +overrides things in the core theme, so if you make a new "main +template", then new widgets that appear in the core theme won't appear +on your website. + +Therefore, you should consider how you can brand your website without +changing much in the core theme. The ideal would be if you are able +to rebrand the site by only changing the CSS. You will also need to +add custom help pages, as described below. + +## Branding the site + +The core templates that comprise the layout and user interface of an +Alaveteli site live in `app/views/`. They use Rails' ERB syntax. +For example, the template for the home page lives at +`app/views/general/frontpage.html.erb`, and the template for the "about +us" page is at `app/views/help/about.html.erb`. + +Obviously, you *could* edit those core files directly, but this would +be a Bad Idea, because you would find it increasingly hard to do +upgrades. Having said that, sometimes you may want to change the core +templates in a way that would benefit everyone, in which case, discuss +the changes on the mailing list, make them in a fork of Alaveteli, and +then issue a pull request. + +Normally, however, you should override these pages **in your own +theme**, by placing them at a corresponding location within your +theme's `lib/` directory. These means that a file at +`lib/themes/alavetelitheme/lib/help/about.rhml` will appear +instead of the core "about us" file. + +Rails expects all its stylesheets to live at `<railshome>/public`, +which presents a problem for plugins. Here's how we solve it: the +stylesheet and associated resources for your theme live (by +convention) in `alavetelitheme/public/`. This is symlinked from +the main Rails app -- see `alavetelitheme/install.rb` to see how this +happens. + +The partial at +`alavetelitheme/lib/views/general/_before_head_end.html.erb` includes the +custom CSS in your theme's stylesheet folder (by convention, in +`alavetelitheme/public/stylesheets/`), with: + + <%= stylesheet_link_tag "/alavetelitheme/stylesheets/custom" %> + +...which will, usually, need changing for your theme. + +## Adding your own categories for public bodies + +Categories are implemented in Alaveteli using tags. Specific tags can +be designated to group authorities together as a category. + +There's a file in the sample theme, +`alavetelitheme/lib/public_body_categories_en.rb`, which contains a +nested structure that defines categories. It contains a comment +describing its structure. You should make a copy of this file for each +locale you support. + +## Customising the request states + +As mentioned above, if you can possibly live with the +[default Alaveteli request statuses]({{ site.baseurl }}running/states), +it would be good to do so. Note that you can set how many days counts +as "overdue" in the main site config file — +see [`REPLY_LATE_AFTER_DAYS`]({{ site.baseurl }}customising/config/#reply_late_after_days). + +If you can't live with the states as they are, there's a very basic +way to add to them (which will get improved over time). There's not +currently a way to remove any easily. There is an example of how to +do this in the `alavetelitheme`. + +To do add states, create two modules in your theme, +`InfoRequestCustomStates` and `RequestControllerCustomStates`. The +former must have these methods: + +* `theme_calculate_status`: return a tag to identify the current state of the request +* `theme_extra_states`: return a list of tags which identify the extra states you'd like to support +* `theme_display_status`: return human-readable strings corresponding with these tags + +The latter must have one method: + +* `theme_describe_state`: Return a notice for the user suitable for + displaying after they've categorised a request; and redirect them to + a suitable next page + +When you've added your extra states, you also need to create the following files in your theme: + +* `lib/views/general/_custom_state_descriptions.html.erb`: Descriptions + of your new states, suitable for displaying to end users +* `lib/views/general/_custom_state_transitions_complete.html.erb`: + Descriptions for any new states that you might characterise as + 'completion' states, for displaying on the categorisation form that + we ask requestors to fill out +* `lib/views/general/_custom_state_transitions_pending.html.erb`: As + above, but for new states you might characterise as 'pending' + states. + +You can see examples of these customisations in +[this commit](https://github.com/sebbacon/informatazyrtare-theme/commit/2b240491237bd72415990399904361ce9bfa431d) +for the Kosovan version of Alaveteli, Informata Zyrtare (ignore the +file `lib/views/general/_custom_state_transitions.html.erb`, which is +unused). + +## Adding new pages in the navigation + +`alavetelitheme/lib/config/custom-routes.rb` allows you to extend the base routes in +Alaveteli. The example in `alavetelitheme` adds an extra help page. +You can also use this to override the behaviour of specific pages if +necessary. + +## Adding or overriding models and controllers + +If you need to extend the behaviour of Alaveteli at the controller or model level, see `alavetelitheme/lib/controller_patches.rb` and `alavetelitheme/lib/model_patches.rb` for examples.
\ No newline at end of file diff --git a/customising/translation.md b/customising/translation.md new file mode 100644 index 000000000..927067f89 --- /dev/null +++ b/customising/translation.md @@ -0,0 +1,179 @@ +--- +layout: page +title: Translation +--- + +# Translating Alaveteli + +<p class="lead"> + We've designed Alaveteli to be used in many different + jurisdictions all around the world. If it doesn't already + support the language you need, you can help by translating + it. This page explains how. +</p> + +## Alaveteli's translations + +The software translations are implemented using GNU gettext, and the resource +files are managed in Transifex. + +The Transifex project is at +[https://www.transifex.net/projects/p/alaveteli](https://www.transifex.net/proje +cts/p/alaveteli) -- you'll probably want an account there (ask on the mailing +list). It has a fairly easy-to-use interface for contributing translations. + +There are three roles in the translation process, and each one is described +below: **translator**, **developer**, and **release manager**. You probably only +need to know about the one that applies to you. + +## Translation process: translator's view + +**If you're just working on translating Alavetli into a language you know, then +this section is for you.** + +When a developer adds a new feature to the user interface in Alaveteli, they +use some code to mark sentences or words ("strings") that they think will need +to be translated. + +When the Alaveteli release manager is planning a release, they will upload a +template containing all the strings to be translated (called a POT) to +Transifex. This causes your own translations in Transifex to be updated with +the latest strings. + +When you visit Transifex, it will prompt you to fill out values for all new +strings, and all strings that have been modified. In the case where a string +has only been slightly modified, such as with punctuation ("Hello" has become +"Hello!"), Transifex will suggest a suitable translation for you (look for the +"suggestions" tab under the source string). + +In order for this feature to work properly, the release manager has to download +your translations, run a program that inserts the suggestions, and then upload +them again. Therefore, when a release candidate is announced, make sure you +have uploaded any outstanding translations, or you will lose them. + +When a release candidate has been annouced, there is a **translation freeze**: +during this period, developers must not add any new strings to the software, so +you can be confident that you're translating everything that will be in the +final release. + +The release manager will also give you a **translation deadline**. After this +date, you can continue to contribute new translations, but they won't make it +into the release. + +### General notes on translation in Transifex + +Some strings will have comments attached to them from the Alaveteli +application developers about the context in which the text appears in the +application — these comments will appear under the 'Details' tab for the text +in Transifex. + +Some strings will have **placeholders** in them to indicate that Alaveteli +will insert some text of its own into them when they're displayed. They +will be surrounded by double curly brackets, and look like this: + +<code> + some text with {{placeholder}} in it +</code> + +For these strings, don't translate the placeholder. It needs to stay exactly +the same for the text to be inserted properly: + +<code> + ein Text mit {{placeholder}} in ihm +</code> + +Similarly, some strings may contain small bits of HTML — these will have +code in angle brackets (it might really be indicating that the text is a link, +or that it needs special formatting). For example: + +<code> + please <a href=\"{{url}}\">send it to us</a> +</code> + +Again, don't edit the bits between the angle brackets — preserve them in your +translation, and just edit the text around them. So the example might become: + +<code> + bitte <a href=\"{{url}}\">schicken Sie es uns</a> +</code> + +Some strings are in the form of two pieces of text separated by a vertical +bar (`|`) character, e.g. `IncomingMessage|Subject`. These represent attribute +names, so `IncomingMessage|Subject` is the subject attribute of an incoming +message on the site. Do not prioritise these types of text when translating -- +they do not appear on the site anywhere at the moment, and when they do, they +will only be used in the admin interface. If you do translate them, only +translate the text that comes *after* the `|`. + +## Translation process: developers' view + +**If you're writing new code for Alaveteli, then you're a developer, and you +need to understand how to make any text you add easy for translators to work +with.** + +Please read our [internationalisation +guide](http://mysociety.github.io/internationalization.html) for our advice on +using strings that will need translation. This applies across all mySociety +projects, not just Alaveteli. + +The release manager will enforce a translation freeze just before a new release +is cut. During such time, you must not introduce new strings to the code if +your work is due for inclusion in this release. This is necessary to allow +translators time to complete and check their translations against all the known +strings. + +## Translation process: release manager's view + +**If you're responsible for coordinating translators and developers so that all +the work comes together in a new release, you're the release manager.** + +This is the most complicated of the three roles -- the chances are this doesn't +apply to you, so only read it if you want to understand how the process works. + +As the release manager, before you cut a new release branch, you must do the +following: + +### Before the release candidate date: + +* Pick a date for the release branch to be cut ("release candidate date"). +* Make an announcement to the translators (using the "announcements" + feature in Transifex) that they should ensure they have any pending + translations saved in Transifex before the release candidate date. +* Make an announcement to the developers that all new strings should + be committed before the release candidate date. + +### On the release candidate date: + +* Download all the current translations with `tx pull -a -f` and commit (important: there's no revision history in Transifex!). +* You should also commit these translations to a hotfix for the + previous version, so they are preserved against the last known + good msgids. +* Regenerate the POT file and individual PO files for each language, + using `bundle exec rake gettext:store_model_attributes`, followed by + `bundle exec rake gettext:find` + * Be careful not to include msgids from themes in `lib/themes`; + you might want to move them out of the way before running + the above commands. + * This updates the PO template, but also merges it with the + individual PO files, marking strings that have only changed + slightly as "fuzzy". +* Re-upload the POT and PO files to Transifex from the + current release branch with `tx push -s -t` + * The point of uploading the PO files is that Transifex + converts the "fuzzy" suggestions from Transifex into + "suggestions" under each source string. + * Note that Transifex *does not* preserve fuzzy strings in the + PO files it makes available for download, on the grounds + that Transifex supports multiple suggestions, whereas + gettext only allows one fuzzy suggestion per msgid. +* Remove the fuzzy strings from the local PO files (because they + make Rails very noisy), and then commit the result. You can do + this by re-pulling from Transifex. + +### On the release date: + +* Download and commit all the current translations to the current release branch. + + + + diff --git a/developers/api.md b/developers/api.md new file mode 100644 index 000000000..cbd4c7c85 --- /dev/null +++ b/developers/api.md @@ -0,0 +1,82 @@ +--- +layout: page +title: API +--- + +# Alaveteli API + +<p class="lead"> + There are two parts to the API for accessing or inserting data programmatically: the read API, and the write API. +</p> + +## Read API + +This is provided via JSON versions of most entities in the system, plus atom +feeds for listing entities: + +### Atom feeds + +There are Atom feeds on most pages which list FOI requests, which you can use +to get updates and links in XML format. Find the URL of the Atom feed in one of +these ways: + +* Look for the RSS feed links. +* Examine the `<link rel="alternate" type="application/atom+xml">` tag in the head of the HTML. +* Add `/feed` to the start of another URL. + +Note that even complicated search queries have Atom feeds. You can do all sorts +of things with them, such as query by authority, by file type, by date range, +or by status. See the advanced search tips for details. + +### JSON structured data + +Quite a few pages have JSON versions, which let you download information about +objects in a structured form. Find them by: + +* adding `.json` to the end of the URL. +* looking for the `<link rel="alternate" type="application/json">` tag in the head of the HTML. + +Requests, users and authorities all have JSON versions containing basic +information about them. Every Atom feed has a JSON equivalent, containing +information about the list of events in the feed. + +### Starting new requests programmatically + +To encourage users to make links to a particular public authority, use URLs of +the form `http://<yoursite>/new/<publicbody_url_name>`. These are the +parameters you can add to those URLs, either in the URL or from a form: + +* `title` - the default summary of the new request. +* `default_letter` - the default text of the body of the letter. The salutation and signoff for your locale are wrapped round this. +* `body` - as an alternative to `default_letter`, this sets the default entire text of the request, so you can customise the salutation and signoff. +* `tags` - space separated list of tags, so you can find and link up any requests made later, e.g. `openlylocal spending_id:12345`. The `:` indicates it is a machine tag. The values of machine tags may also include colons, useful for URIs. + +## Write API + +The write API is designed to be used by public bodies to create their own +requests in the system. Currently used by mySociety's [FOI +Register](https://github.com/mysociety/foi-register) software to support using +Alaveteli as a disclosure log for all FOI activity at a particular public body. + +All requests must include an API key as a variable `k`. This key can be viewed +on each authority's page in the admin interface. Other variables should be sent +as follows: + +* `/api/v2/request` - POST the following json data as a form variable `json` to create a new request: + * `title` - title for the request + * `body` - body of the request + * `external_user_name` - name of the person who originated the request + * `external_url` - URL where a canonical copy of the request can be found + Returns JSON containing a `url` for the new request, and its `id` +* `/api/v2/request/<id>.json` - GET full information about a request +* `/api/v2/request/<id>.json` - POST additional correspondence regarding a request: + * as form variable `json`: + * `direction` - either `request` (from the user - might be a followup, reminder, etc) or `response` (from the authority) + * `body` - the message itself + * `sent_at` - ISO-8601 formatted time that the correspondence was sent + * (optionally) the variable `attachments` as `multipart/form-data`: + * attachments to the correspondence. Attachments can only be attached to messages in the `response` direction + + + + diff --git a/developers/directory_structure.md b/developers/directory_structure.md new file mode 100644 index 000000000..6abbd2e4b --- /dev/null +++ b/developers/directory_structure.md @@ -0,0 +1,257 @@ +--- +layout: page +title: Directory structure +--- + + +# Alaveteli's directory structure + +<p class="lead">This page gives you an overview of where to find things in Alaveteli's +directories.</p> + +**You'll probably never need to worry about this** if you're just installing +Alaveteli -- this is really more useful if you're a developer planning on +making more substantive changes to the code. You don't need to be familiar with +Ruby to install or make basic [customisations to your +installation](/customising). + +<!-- (and if you do, +remember to read the page about [feeding your changes back](/feeding-back)).--> + +Alaveteli uses Ruby on Rails, which is a common "Model-View-Controller" web +framework — if you're familiar with Rails this will look very familiar. For +more information about the Rails structure see the [Ruby on Rails +website](http://guides.rubyonrails.org/getting_started.html). + +## Key directories and what they're for + +<dl class="dir-structure"> + <dt> + app + </dt> + <dd> + <p><em>the core Alaveteli application code</em></p> + <dl> + <dt> + controllers + </dt> + <dt> + helpers + </dt> + <dt> + mailers + </dt> + <dt> + models + </dt> + <dt> + sass + </dt> + <dt class="last"> + views + </dt> + </dl> + </dd> + <dt> + assets + </dt> + <dd> + Static assets + <dl> + <dt> + css + </dt> + <dd> + Rendered stylesheets + </dd> + <dt> + img + </dt> + <dd> + static images + </dd> + <dt> + sass + </dt> + <dd> + Stylesheets in SCSS format, which are compiled to CSS + </dd> + <dt class="last"> + scripts + </dt> + <dd class="last"> + JavaScript + </dd> + </dl> + </dd> + <dt> + bootstrap + </dt> + <dd> + <p> + Alaveteli's default style uses Bootstrap. + </p> + <dt> + commonlib + </dt> + <dd> + <p><em>mySociety's library of common functions</em></p> + <p> + We maintain a <a href="https://github.com/mysociety/commonlib">common + library</a> that we use across many of our projects (not just + Alaveteli). This is implemented as a <a + href="http://git-scm.com/book/en/Git-Tools-Submodules">git submodule</a>, + so Alaveteli contains it even though the code is separate. Normally, you + don't need to think about this (because git handles it automatically)... + but if you really <em>do</em> need to change anything here, be aware that + it is a separate git repository. + </p> + </dd> + <dt> + config + </dt> + <dd> + <p><em>configuration files</em></p> + <p> + The primary configuration file is <code>general.yml</code>. This file isn't in the git + repository (since it will contain information specific to your installation, including + the database password), but example files are. + </p> + </dd> + <dt> + db + </dt> + <dd> + <p><em>database files</em></p> + <dl> + <dt class="last"> + migrate + </dt> + <dd class="last"> + Rails' migration (updating the database scheme up or down + as the code develops). + </dd> + </dl> + </dd> + <dt> + doc + </dt> + <dd> + <p><em>documentation</em></p> + <p> + These are technical notes. This is in addition to the <a + href="http://code.fixmystreet.com">core documentation</a> — which + you are reading now — which is actually stored in the git + repository in the <code>gh-pages</code> branch, and published as GitHub + pages. + </p> + </dd> + <dt> + lib + </dt> + <dd> + <p><em>custom libraries</em></p> + <dl> + <dt> + tasks + </dt> + <dt class="last"> + whatdotheyknow + </dt> + </dl> + </dd> + <dt> + locale + </dt> + <dd> + <p><em>translations (internationalisation/i18n)</em></p> + <p> + The translation strings are stored in <code>.po</code> files in directories specific to + the locale and encoding. For example, <code>es/</code> contains the translations for the Spanish site. + </p> + </dd> + <dt> + public + </dt> + <dd> + <p><em>static assets</em></p> + <dl> + <dt> + admin + </dt> + <dd> + images, JavaScript and stylesheets used by the admin back-end + </dd> + <dt> + fcgi + </dt> + <dd> + Fast CGI files for serving static assets + </dd> + <dt> + images + </dt> + <dt> + javascripts + </dt> + <dt class="last"> + stylesheets + </dt> + </dl> + </dd> + <dt> + script + </dt> + <dd> + <p><em>server-side shell scripts</em></p> + <p> + For example, <code>alert-overdue-requests</code> for running the script + which finds overdue requests and mails them out. + </p> + </dd> + <dt> + spec + </dt> + <dd> + <p><em>tests</em></p> + <p> + Alaveteli's test suite runs under <a href="TODO">spec</a>. + </p> + </dd> + <dt> + stylesheets + </dt> + <dd> + <p> + <em>global stylesheet</em> + </p> + <p> + Actually just <code>global.css</code> + </p> + </dd> + <dt> + tmp + </dt> + <dd> + <p> + <em>temporary files</em> + </p> + </dd> + <dt class="last"> + vendor + </dt> + <dd class="last"> + <p><em>third-party software</em></p> + <dl> + <dt class="last">plugins</dt> + <dd class="last"> + <p> + Plugins + </p> + </dd> + </dl> + </dd> +</dl> + +We've missed out some of the less important subdirectories here just to keep +things clear.
\ No newline at end of file diff --git a/developers/index.md b/developers/index.md new file mode 100644 index 000000000..a358b2d3f --- /dev/null +++ b/developers/index.md @@ -0,0 +1,82 @@ +--- +layout: page +title: For developers +--- + +# Information for developers + +<p class="lead"> + Alaveteli is an open source project. Full-time mySociety developers together with devs from all around the world actively contribute to the codebase. These notes and links will help you if you want to help too. +</p> + +* The software is written in **Ruby on Rails 3.x**. We support postgresql as + the backend database. A configured mail transfer agent (MTA) like exim, + postfix or sendmail is necessary to parse incoming emails. We have production + sites deployed on Debian Squeeze and Ubuntu (10.04 LTS). For performance + reasons, we recommend the use of [Varnish](https://www.varnish-cache.org). + +* To help you understand what the code is doing, read this [high-level + overview]({{ site.baseurl }}developers/overview), which includes a diagram of + the models and how they are related. + +* See the [API documentation]({{ site.baseurl }}developers/api) for how to get + data into or out of Alaveteli. + +* If you need to change or add strings in the interface, see our [guidelines + for internationalisation](http://mysociety.github.io/internationalization.html + ), which include notes about our use of `gettext`. + +* We use the [git flow branching + model](http://nvie.com/posts/a-successful-git-branching-model/), with a small + change: currently our `develop` branch is called `rails-3-develop`, which + means that the latest development version is always found on the + [rails-3-develop + branch](https://github.com/mysociety/alaveteli/tree/rails-3-develop). The + latest stable version is always on the [master + branch](https://github.com/mysociety/alaveteli). If you plan to collaborate + on the software, you may find the [git flow + extensions](https://github.com/nvie/gitflow) useful. + +* Installing the software is a little involved, though it's getting easier. If + you stick to Debian or Ubuntu, it should be possible to get a running version + within a few hours. The documentation is in + [INSTALL.md](https://github.com/mysociety/alaveteli/blob/develop/doc/INSTALL.m + d). There is an [Alaveteli EC2 AMI]({{ site.baseurl }}installing/ami/) that + might help you get up and running quickly. [Get in + touch](http://www.alaveteli.org/contact/) on the project mailing list or IRC + for help. + +* A standard initial step for customising your deployment is [writing a + theme]({{ site.baseurl }}customising/themes). **If you only read one thing, + it should be this!** + +* Like many Ruby on Rails sites, the software is not hugely performant (see + some notes about [[performance issues]] gathered over time with + WhatDoTheyKnow). The site will run on a server with 512MB RAM but at least + 2GB is recommended. Deployment behind [Varnish](https://www.varnish-cache.org) is also fairly essential. See + [[Production Server Best Practices]] for more. + +* There's a number of [proposals for enhancements](https://github.com/mysociety/alaveteli/wiki/Proposals-for-enhancements), + such as more user-focused features, but see also... + +* ...the [github issues](https://github.com/mysociety/alaveteli/issues). We + mark issues with the label **suitable for volunteers** if we think they are + especially suitable for diving into if you're just looking for something + relatively small to get your teeth into. + +* We try to ensure every commit has a corresponding issue in the issue tracker. + This makes changelogs easier as we can gather all the fixes for a particular + release against a milestone in the issue tracker, [like this 0.4 + release](https://github.com/mysociety/alaveteli/issues?milestone=7&state=close + d). + +* If you're experiencing memory issues, [this blog post about some strategies + used in the + past](http://www.mysociety.org/2009/09/17/whatdotheyknow-growing-pains-and-rub + y-memory-leaks/) might be useful. + +* If you're coding on a mac, see these [MacOS X installation notes]({{ site.baseurl }}installing/macos). <!-- [[OS X Quickstart]] --> + +* We try to adhere to similar good practice across all our projects: see + [mysociety.github.io](http://mysociety.github.io/) for things like our + [coding standards](http://mysociety.github.io/coding-standards.html) diff --git a/developers/overview.md b/developers/overview.md new file mode 100644 index 000000000..7f0f30b04 --- /dev/null +++ b/developers/overview.md @@ -0,0 +1,52 @@ +--- +layout: page +title: High-level overview +--- + +<p class="lead"> + This page describes the process and entities that make up Alaveteli. + It's a high-level overview of how Alaveteli works to help you orientate yourself to the code. +</p> + + +# High-level overview + +_See also the [schema diagram](#schema-diagram) at the bottom of this page._ + +The main entity is **InfoRequest**, which represents a request for information by a +**User** to a **PublicBody**. A new InfoRequest results in an initial **OutgoingMessage**, +which represents the initial email. + +Once an InfoRequest is made, its state is tracked using **InfoRequestEvents**. For +example, a new InfoRequest has an initial state of `awaiting_response` and an +associated InfoRequestEvent of type `initial_request`. An InfoRequest event can +have an OutgoingMessage or an IncomingMessage or neither associated with it. + +Replies are received by the system by piping raw emails (represented by a **RawEmail**) +from the MTA to a script at `scripts/mailin`. This parses the email, tries to identify the +associated InfoRequest, and then generates an **IncomingMessage** which references +both the RawEmail and the InfoRequest. + +Any User can make **Comments** on InfoRequests. + +All events (e.g., Comments, OutgoingMessages) are tracked in InfoRequestEvent. + +A **TrackThing** is a canned search that allows users to be alerted when events +matching their criteria are found. (How this worked changed after we'd +launched, so there's still some deprecated code there for things we've phased +out.) + +The **MailServerLog** is a representation of the parsed MTA log files. +MailServerLog entries are created by a cron job that runs +`scripts/load-mail-server-logs`. This checks incoming emails and matches them +to InfoRequests; then `script/check-recent-requests-send` checkes these logs to +ensure they have an envelope-from header set (to combat spam). + +## Schema diagram + +<a name="schema-diagram" href="{{ site.baseurl }}images/railsmodels.png"><img src="{{ site.baseurl }}images/railsmodels.png"></a> + +This schema for the Rails models was generated from the code on 19 Dec 2012 using +[Railroad](http://railroad.rubyforge.org/). + +The railroad command is: `railroad -M | dot -Tpng > railsmodels.png` diff --git a/getting_started.md b/getting_started.md new file mode 100644 index 000000000..3df3b286c --- /dev/null +++ b/getting_started.md @@ -0,0 +1,381 @@ +--- +layout: page +title: Getting started +--- + +# Getting started with Alaveteli + +<p class="lead"> + This guide is aimed at people who are thinking about setting up their own + Alaveteli website in a new jurisdiction. +</p> + +For inspiration, take a look at some of the existing Alaveteli websites, like +[tuderechoasaber.es](http://tuderechoasaber.es) (Spain), +[AskTheEU](http://asktheeu.org) (EU), or +[WhatDoTheyKnow](http://www.whatdotheyknow.com) (UK). These sites all use the +Alaveteli software, plus their own custom themes installed on top to make them +look different. + +You don't even need to make a custom theme to get started. You can have a +website that looks like [the demo website](http://demo.alaveteli.org) and +simply drop in your own logo. + +The process of getting your own Alaveteli website up and running could take +anywhere from one day to three months, depending on the scale of your ambition +for customising the software, your access to technical skills, and your +available time. + +You can get a feeling for how things might turn out by reading [how an +Alaveteli was set up in +Spain](http://www.alaveteli.org/2012/04/a-right-to-know-site-for-spain/) +(remember that this was with an experienced developer in charge). You will also +need to think about how you will run the website; a successful Alaveteli +requires lots of ongoing effort to moderate and publicise (see Step 6 and Step +7, below). + +Here are the steps we suggest you follow in order to get started. + +* [Step zero: assemble your initial team](#step-0) +* [Step one: get a working, uncustomised version running](#step-1) +* [Step two: start to gather data about public authorities](#step-2) +* [Step three: customise the site](#step-3) +* [Step four: translate everything](#step-4) +* [Step five: Test drive the site](#step-5) +* [Step six: Market the website](#step-6) +* [Step seven: Maintain the website](#step-7) + + +<a name="step-0"> </a> + +## Step zero: assemble your initial team + +You're unlikely to be able to get much done on your own. You will need +translators, people to hunt down email addresses of authorities, possibly a +designer, and preferably a technical expert to help with customisations. Read +through this guide first, and think about the skills you will need to +successfully launch and maintain the website. + +It took about [ten people (including translators) working for three +days](http://groups.google.com/group/alaveteli-dev/msg/1bd4afd3091f8b4f) to +launch [Queremos Saber](http://queremossaber.org.br/), a Brazilian version of +Alaveteli. + +> It was really cool setting the site up. And even with some minor +> difficulties (most related to the fact that we had no one really experienced +> with both Ruby on Rails and Postfix) it was pretty quick and in less than a +> week we had a fully featured website! +> +> -- _Pedro Markun, Queremos Saber_ + +[AskTheEU](http://asktheeu.org), a much more complete and polished version with +a custom theme and several other customisations, took a team of 2 or 3 people +about 3 months (part time) to complete. + +Ask members of your team to consider joining one of the mailing lists. If you +have any questions, these are the first places to ask. +[alaveteli-users](http://groups.google.com/group/alaveteli-users) is a mailing +list for non-technical users of the software. Post messages there to ask for +advice about getting your project started, questions about how people use the +software, and so on. +[alaveteli-dev](http://groups.google.com/group/alaveteli-dev) is the place to +ask questions of a technical nature, such as problems installing Alaveteli. + +<a name="step-1"> </a> + +## Step one: get a working, uncustomised version running + +You have two options here: install your own copy, or ask the Alaveteli team to +provide a hosted version. + +If you install your own copy, you have complete control over the website, its +performance, how often it is upgraded, and so on. We recommend this as the best +approach. However, you will need some resources to do this. + +Alternatively, we have very limited capacity to run a handful of Alaveteli +sites for willing volunteers. We want to learn more about how we can support +third parties, and to do so we're happy to help host low-volume sites for two +or three partners. However, you will have no service level agreement, no +warranties, and no guarantee on our time: if the website goes down when we're +on holiday, you'll have to wait until we're back! If you want to try this +route, please [get in touch](http://alaveteli.org/contact-us) to find out if +we have capacity. + +### Install your own copy + +You'll need to find a tech person who knows about hosting websites using Apache +and Linux. They don't need to know Ruby on Rails, but it would be a huge +advantage if they do. + +You'll also need to source a server. You should ask your tech person to help +with this. The minimum spec for running a low traffic website is 512MB RAM and +a 20GB disk. 2GB RAM would be ideal. We recommend Debian Squeeze as the +operating system, though any sort of Linux should do. Rackspace offer suitable +cloud servers, which start out at around $25 / month. Then your tech person +should follow the [installation documentation]({{ site.baseurl }}installing). + +Alternatively, you could use Amazon Web Services. If you've not used them +before, you can get a free "micro" instance for twelve months. This has the +added advantage that you can use our preconfigured [Alaveteli EC2 +AMI]({{ site.baseurl }}installing/ami) to get you +started almost instantly. However, it's more expensive than Rackspace, +especially if you want more RAM. + +### Play around with it + +You'll need to understand how the website works. Until your own copy is +available, you can try the copy running on the [demo +server](http://demo.alaveteli.org) (though note this isn't guaranteed to be +available or working). + +Right now we don't have a guide book, so you'll just have to explore on your +own. + +When you have your own version running, try logging into the admin interface by +adding `/admin` onto the end of your domain name. This will take you to the +administrative interface. It's plain and simple, but functional. For example, +try adding new authorities there, perhaps with your own email address, so you +can see what requests look like to them. + +When trying things out, you need to wear several hats -- as a site +administrator, an ordinary site user, and as a public authority. This can get +confusing with several email addresses, so one quick and easy way to manage +this is to use a throwaway email service like http://mailinator.com. + +<a name="step-2"> </a> + +## Step two: start to gather data about public authorities + +One of the most important things you need to do before launching is to gather +together a list of all the bodies to whom you want to address FOI requests. + +It's a good idea to make a shared speadsheet that you can ask your supporters +to help fill out. A template like [this Google +spreadsheet](https://docs.google.com/spreadsheet/ccc?key=0AgIAm6PdQexvdDJKdzlNdXEtdjBETi1SLVhoUy1QM3c&hl=en_US) is ideal. + +If you email possible supporters asking for help, in addition to helping make +your job easier, it will also help you identify eager people who might be +interested in helping you maintain and run the website. We have written [a +blog post about +this](http://www.alaveteli.org/2011/07/you-need-volunteers-to-make-your-website-work/). + +The admin interface includes a page where you can upload a CSV file (that's a +file containing comma-separated values) to create or edit authorities. CSV is a +convenient format -- for example, it's easy to save data from a spreadsheet as +a CSV file. + +<a name="step-3"> </a> + +## Step three: customise the site + +### Name and social media + +Obviously, you'll want to put your own visual stamp on the site. Once you have +a name for your project (e.g., WhatDoTheyKnow in the UK, AskTheEU in the EU, +InformateZyrtare in Kosovo), register a twitter username, and a domain name. +Alaveteli relies on you keeping a blog for its "News" section, so you might +want to consider setting up a free blog at http://wordpress.com or +http://blogger.com and announce your project with a new blog post. + +### Branding and theming + +Next, think about the visual identity. At a minimum, you should probably +replace the default Alaveteli logo that you can see at the top left of +http://demo.alaveteli.org. It's also easy to change the colour scheme. + +If you have a bit more budget and time, you can rework the design more, with a +custom homepage, different fonts, etc; however, the more you customise the +site, the harder it is to upgrade in the future; and you'll need a developer +and/or designer to help do these customisations. We call the custom set of +colours, fonts, logos etc a "theme"; there are some notes for developers about +[writing a +theme](https://github.com/mysociety/alaveteli/blob/master/doc/THEMES.md). You +might spend anywhere between 1 and 15 days on this. + +### Legislative differences + +We rely on users to help categorise their own requests (e.g., as "successful", +or "refused"). We call these categories "states". Most FOI laws around the +world are sufficiently similar that you can probably use Alaveteli's states +exactly as they come out of the box. + +In addition, we have found that it's generally a bad idea to try to implement +laws exactly in the user interface. They are often complicated, and confusing +for users. Since the concept of Alaveteli is to make it easy to exercise the +right to know, we take the view that it's best to implement how a FOI process +*should* be, rather than how it *actually is right now*. + +However, if you really feel you need to alter the states that a request can go +through, it is possible to do this to some degree within your theme. Have a +think about what is required, and then send a message to the Alaveteli mailing +list for feedback and discussion. Then you'll need to ask your developer to +implement the new states. It's usually no more than a couple of days' work, +often less. But complicated workflows might take a bit longer. + +### Write the help pages + +The default help pages in Alaveteli are taken from WhatDoTheyKnow, and are +therefore relevant only to the UK. You should take these pages as inspiration, +but review their content with a view to your jurisdiction. The important pages +to translate are: + +* [About](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/about.rhtml): why the website exists, why it works, etc +* [contact](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/contact.rhtml): how to get in touch +* [credits](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/credits.rhtml): who is involved in the site. Importantly, includes a section on how users can help the project. +* [officers](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/officers.rhtml): information for the officers who deal with FOI at authorities. They get a link to this page in emails that the site sends them. +* [privacy](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/privacy.rhtml): privacy policy, plus information making it clear that requests are going to appear on the internet. Let users know if they are allowed to use pseudonyms in your jurisdiction. +* [requesting](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/requesting.rhtml): the main help page about making requests. How it works, how to decide who to write to, what they can expect in terms of responses, how to make appeals, etc. +* [unhappy](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/unhappy.rhtml): users are taken to this page after a request that has been somehow unsuccessful (e.g. the request has been refused, or the authority is insisting on a postal request). The page should encourage them to keep going, e.g. by starting a new request or addressing it to a different body. +* [why email](https://github.com/mysociety/alaveteli/blob/develop/app/views/help/_why_they_should_reply_by_email.rhtml): a snippet of information that explains why users should insist on replies by email. This is displayed next to requests that have "gone postal". + +The help pages contain some HTML. Your tech person should be able to advise on +this. + +Once the pages are written, ask your tech person to add them to your theme. + +Now is also a good time to start thinking about some of your standard emails +that you'll be sending out in response to common user queries and +administrative tasks -- for example, an email that you send to IT departments +asking them to whitelist emails from your Alaveteli website (if your emails are +being marked as spam). Review the [Administrator's +Manual](/running/admin_manual.md) for details on some of the common administrative tasks. There is a list of the +standard emails used by WhatDoTheyKnow on the [FOI Wiki]( +http://foiwiki.com/foiwiki/index.php/Common_WhatDoTheyKnow_support_responses). + +### Other software customisations + +Perhaps you would like a new usability-related feature not in Alaveteli +already, like the automated language detection for multi-language websites; or +Facebook integration; or an iPhone app. + +Perhaps you've found an area relating to translations that Alaveteli doesn't +yet support fully (for example, we've not yet needed to implement a site with a +language written right-to-left). + +Perhaps your jurisdiction *requires* a new feature not in Alaveteli -- for +example, users may need to send extra information with their requests. + +In these cases, you will need to get your tech person (or some other software +developer) to make these changes for you. This can be time consuming; new +software development, testing, and deployment is often complex. You should get +expert advice on the amount of extra time this will require. Typically, changes +like these could add between one and three months onto the project schedule. + +<a name="step-4"> </a> + +## Step four: translate everything + +This is potentially a big job! + +If you need to support multiple languages in your jurisdiction, you will need +to translate: + +* public authority names, notes, etc +* public authority bodies +* help pages +* all of the web interface instructions in the software + +It's a bit easier if you only need to support one language in your +jurisdiction: because you'll already have written the help and public authority +information, you'll only need to translate the web interface. + +Public authority names can be edited via the admin interface, or by uploading a +spreadsheet. The help pages need to have one copy saved for each language; your +tech person will put them in the right place. + +The web interface translations are managed and collaborated via a website +called Transifex. This website allows teams of translators to collaborate in +one place, using a fairly easy interface. + +The Alaveteli page on Transifex is at +https://www.transifex.net/projects/p/alaveteli/; the translations all live in a +single translation file called +[`app.pot`](https://www.transifex.net/projects/p/alaveteli/resource/apppot/). + +You can set up your language and provide translations there; you can also use +specialise software on your own computer (see the help pages on Transifex) + +There are (at the time of writing) around 1000 different sentences or fragments +of sentences (collectively known as "strings") to be translated. The meaning of +many strings should be fairly obvious, but others less so. Until we write a +guide for translators, the best route to take is translate everything you can, +and then ask your tech person or the project mailing list for advice on +anything you're unsure about. + +Over time, as bugs are fixed and new features are added, new strings are added +to the file. Therefore, you need to keep an eye on `app.pot` and periodically +review the untranslated strings. + +<a name="step-5"> </a> + +## Step five: Test drive the site + +For launch, the tech person should review the [Production Server Best +Practices](FIXME). + +A low-key launch, where you tell just a few trusted people about the site, is a +very good idea. You can then track how things work, and gauge the responses of +authorities. Responses are likely to vary widely between and within +jurisdictions, and the right way of making your website a success will vary +with these responses. + +<a name="step-6"> </a> + +## Step six: Market the website + +In general, the best way to engage authorities is with a mixture of +encouragement and exposure. In private, you can explain that in addition to +helping them meet their legal requirements and civic obligations, you may be +reducing their workload by preventing repeat requests. In public, you can work +with journalists to praise authorities that are doing a good job, and highlight +ones that refuse to take part. It is, therefore, very important to make links +with journalists with an interest in freedom of information. + +The other important marketing tool is [Google +Grants](http://www.google.com/grants/), a scheme run by Google that gives free +AdWords to charities in lots of countries around the world. You'll find these +an incredibly useful resource for driving traffic to your site. It's well worth +setting yourself up as a charity if only to take advantage of this programme. + +<a name="step-7"> </a> + +## Step seven: Maintain the website + +Running a successful Alaveteli website requires some regular, ongoing input. +This will be easier to do with a small team of people sharing jobs. Hopefully +you have been lucky enough to get funding to pay people to do these tasks. +However, you are also likely to have to rely on volunteers. We've written [a +blog post about the importance of +volunteers](http://www.alaveteli.org/2011/07/you-need-volunteers-to-make-your-we +bsite-work/), which you should read. + +You'll need to set up a group email address for all the people who will manage +the website. All site user queries will go here, as will automatic +notifications from Alaveteli. A group address is really useful for helping +coordinate responses, discuss policy, etc. + +You could get by with just one or two hours per week. This means keeping an eye +on the "holding pen" of the website, where incoming messages that the site +doesn't know how to handle are stored (things like spam, misaddressed messages, +etc). However, the more effort you put into this, the more successful your +website is. To ensure its success, you should be doing things like: + +* Responding to user help enquiries by email +* Monitoring new requests, looking for people who might need help, posting + encouraging comments on their requests +* Monitoring responses from authorities, looking for ones who are trying to + refuse to answer, offering advice to the person who made the request, possibly coming up with publicity to "shame" the authority into answering +* Tweeting about interesting requests and responses +* Writing blog posts about the progress of the project +* Communicating with journalists about potentially interesting stories +* Recruiting volunteers to help with the site +* Categorising uncategorised requests + +See also the [Administrator's Manual](/running/admin_manual), which describes +some of the typical tasks you'll need to perform when your site is up and +running. + +### What else? + +If there's anything you think would be really useful to have in this getting +started guide which is currently missing, let us know so we can add it. diff --git a/glossary.md b/glossary.md new file mode 100644 index 000000000..32952be1e --- /dev/null +++ b/glossary.md @@ -0,0 +1,289 @@ +--- +layout: page +title: Glossary +--- + +Glossary +==================== + +<p class="lead"> + Glossary of terms for Alaveteli, mySociety's freedom of information + platform. +</p> + +Definitions +----------- + +<ul class="definitions"> + <li><a href="#alaveteli">Alaveteli</a></li> + <li><a href="#agnostic">asker agnostic</a></li> + <li><a href="#authority">authority</a></li> + <li><a href="#foi">freedom of information</a></li> + <li><a href="#git">git</a></li> + <li><a href="#holding_pen">holding pen</a></li> + <li><a href="#mta">MTA</a></li> + <li><a href="#publish">publish</a></li> + <li><a href="#request">request</a></li> + <li><a href="#response">response</a></li> + <li><a href="#state">state</a></li> + <li><a href="#theme">theme</a></li> +</ul> + + +<dl class="glossary"> + + <dt> + <a name="alaveteli">Alaveteli</a> + </dt> + <dd> + <strong>Alaveteli</strong> is the name of the open source software platform created + by <a href="http://www.mysociety.org">mySociety</a> for submitting, + managing and archiving Freedom of Information requests. + <p> + It grew from the successful FOI UK project + <a href="http://www.whatdotheyknow.com">WhatDoTheyKnow</a>. + We use the name <em>Alaveteli</em> to distinguish the software + that runs the platform from any specific website that it is powering. + </p> + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + The Alaveteli website is at <a href="http://www.alaveteli.org">www.alaveteli.org</a> + </li> + <li> + The name "Alaveteli" comes from + <a href="http://en.wikipedia.org/wiki/Alaveteli,_Finland">Alaveteli in Finland</a> + where + <a href="http://en.wikipedia.org/wiki/Anders_Chydenius">an early FOI campaigner</a> + once worked. + </li> + </ul> + </div> + </dd> + + <dt> + <a name="agnostic">asker agnostic</a> + </dt> + <dd> + <a href="#foi" class="glossary">Freedom of Information</a> (FoI) law typically considers + the <a href="#response" class="glossary">responses</a> given by the + <a href="#authority" class="glossary">authorities</a> to be <strong>asker agnostic</strong>. This means + that the reply should not be any different depending on <em>who</em> asked for the + information. One consequence of this is that the response + can be <a href="#publish" class="glossary">published</a>, because in theory <em>everyone</em> + could ask for it and expect, by law, to receive the same information. + <p> + Despite this, it's still very common all around the world for authorities to reply + to FoI requests privately, instead of publishing their responses themselves. One of the + functions of Alaveteli is, therefore, to act as a public repository of published answers. + This also serves to reduce duplicate requests, by publishing the answer instead of + requiring it to be asked again. + </p> + <dt> + <a name="authority">authority</a> + </dt> + <dd> + An <strong>authority</strong> is the term we use for any of the bodies, organisations, + departments, or companies to which users can send <a href="#request" class="glossary">requests</a>. + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + An administrator can add, edit, or remove authorities in the admin + </li> + <li> + Authorities are usually, but not always, public bodies that are obliged by the local + <a href="#foi" class="glossary">Freedom of Information</a> (FoI) law to respond. Sometimes an + Alaveteli site is set up in a jurisdiction that does not yet have FoI law. In the UK, + we add some authorites to our <a href="https://www.whatdotheyknow.com">WhaDoTheyKnow</a> + site that are not subject to FoI law, but which have either voluntarily submitted themselves + to it, or which we believe should be accountable in this way. + </li> + </ul> + </div> + </dd> + + <dt> + <a name="foi">Freedom of Information</a> (also FOI) + </dt> + <dd> + <strong>Freedom of information</strong> laws allow access by the general public + to data held by national governments. They establish a "right-to-know" + legal process by which requests may be made for government-held + information, to be received freely or at minimal cost, barring standard + exceptions. + <br> + <em>[from wikipedia]</em> + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + Wikipedia summary of <a href="http://http://en.wikipedia.org/wiki/Freedom_of_information_laws_by_country">FOI laws by country</a>. + </li> + </ul> + </div> + </dd> + + <dt> + <a name="git">git</a> (also github, git repository, and git repo) + </dt> + <dd> + We use a popular source code control system called <strong>git</strong>. This + helps us track changes to the code, and also makes it easy for other people + to duplicate and even contribute to our software. + <p> + The website <a href="http://github.com/mysociety">github.com</a> is a central, public + place where we make our software available. Because it's Open Source, you can + inspect the code there (Alaveteli is mostly written in the programming language + Ruby), report bugs, suggest features and many other useful things. + </p> + <p> + The entire set of files that form the Alaveteli platform is called the + <strong>git repository</strong> or <strong>repo</strong>. When you + install Alaveteli, you are effectively cloning our repository on your + own machine. + </p> + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + See the <a href="{{ site.baseurl }}installing">installation instructions</a> which will + clone the Alaveteli repo. + </li> + <li> + Everything about git from the <a + href="//http://git-scm.com">official website</a>. + </li> + <li> + See <a href="http://github.com/mysociety">the mySociety projects on + github</a>. + </li> + </ul> + </div> + </dd> + + <dt> + <a name="holding pen">holding pen</a> + </dt> + <dd> + The <strong>holding pen</strong> is the conceptual place where responses that + could not be delivered are held. They need attention from a administrator. + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + see the <a href="{{ site.baseurl }}running/admin_manual">admin manual</a> for + information on dealing with emails in the holding pen + </li> + </ul> + </div> + </dd> + + <dt> + <a name="mta">MTA</a> (Mail Transfer Agent) + </dt> + <dd> + A <strong>Mail Tranfer Agent</strong> is the the program which actually sends + and receives email. Alaveteli sends email on behalf of its users, and processes + the <a href="#response" class="glossary">responses</a> and replies it receives. + All this email goes through the MTA, which is a seperate service on your system. + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + see these instructions for <a href="{{ site.baseurl }}installing/exim4">configuring exim4</a>, + a common MTA + </li> + </ul> + </div> + + </dd> + + <dt> + <a name="publish">publish</a> + </dt> + <dd> + Alaveteli works by <strong>publishing</strong> the + <a href="#response" class="glossary">responses</a> it recieves to the + <a href="#foi" class="glossary">Freedom of Information</a> + <a href="#request" class="glossary">requests</a> that its users send. + It does this by processing the emails it receives and presenting them + as pages — one per request — on the website. This makes it + easy for people to find, read, link to, and share the request and the + information provided in response. + </dd> + + <dt> + <a name="response">response</a> + </dt> + <dd> + A <strong>response</strong> is the email sent by an + <a href="#authority" class="glossary">authority</a> in reply to + a user's <a href="#request" class="glossary">requests</a>. + </dd> + + <dt> + <a name="request">request</a> + </dt> + <dd> + In Alaveteli, a <strong>request</strong> is the + <a href="#foi" class="glossary">Freedom of Information</a> request + that a user enters, and which the site then emails to the relevant + <a href="#authority" class="glossary">authority</a>. + Alaveteli automatically <a href="#publish" class="glossary">publishes</a> + the <a href="#response" class="glossary">responses</a> + to all the requests it sends. + </dd> + + <dt> + <a name="state">state</a> + </dt> + <dd> + Each <a href="#request" class="glossary">request</a> passes through different + <strong>states</strong> as it progresses through the system. + States help Alaveteli administrators, as well as the public, + understand the current situation with any request and what + action, if any, is required. + <p> + The states available can be customised within + your site's <a href="#theme" class="glossary">theme</a>. + </p> + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + <a href="{{ site.baseurl }}running/states">example states for WhatDoTheyKnow</a> + (Alaveteli site running in the UK) + </li> + <li> + for comparison, <a href="{{ site.baseurl }}running/states_informatazyrtare">example states for InformataZyrtare</a> + (Alaveteli site running in Kosovo) + </li> + <li> + to customise or add your own states, see <a href="{{ site.baseurl }}customising/themes">Customising the request states</a> + </li> + </ul> + </div> + + </dd> + + <dt> + <a name="theme">theme</a> + </dt> + <dd> + A <strong>theme</strong> is the collection of changes to the templates + and the code that causes the site to look or behave differently from the + default. Typically you'll need a theme to make Alaveteli show your own + brand. + <div class="more-info"> + <p>More information:</p> + <ul> + <li> + <a href="{{ site.baseurl }}customising/themes">about themes</a> + </li> + </ul> + </div> + </dd> + +</dl>
\ No newline at end of file diff --git a/images/railsmodels.png b/images/railsmodels.png Binary files differnew file mode 100644 index 000000000..db9e37d61 --- /dev/null +++ b/images/railsmodels.png diff --git a/index.md b/index.md new file mode 100644 index 000000000..1b69194b1 --- /dev/null +++ b/index.md @@ -0,0 +1,34 @@ +--- +layout: page +title: Welcome +--- + +# Alaveteli documentation + +<p class="lead"> + This is the documentation for Alaveteli, + an open source Freedom of Information platform + created by <a href="http://www.mysociety.org">mySociety</a>. +</p> + +## New to Alaveteli? + +You've found the documentation for Alaveteli. + +* Learn about the project at [www.alaveteli.org](http://www.alaveteli.org). + +* Read [Turbo Transparency](http://www.alaveteli.org/files/2012/10/Turbo-Transparency-v1.0.pdf), a paper about how and why to use Alaveteli for Freedom of Information systems + +* Read the [Getting Started guide]({{ site.baseurl }}getting_started) + +**The documentation covers +[installing]({{ site.baseurl }}installing), +[customising]({{ site.baseurl }}customising), and +[running]({{ site.baseurl }}running) your own Alaveteli site.** + +If you're making changes to the source code, we have +[documentation for developers]({{ site.baseurl }}developers) too. + +If you are an organisation who wants to use Alaveteli in your jurisdiction, or a developer who is interested in collaborating on the software, please +[get in touch]({{ site.baseurl }}community). + diff --git a/installing/ami.md b/installing/ami.md new file mode 100644 index 000000000..47dd95565 --- /dev/null +++ b/installing/ami.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Installing the easy way +--- + +# Installation on Amazon EC2 + +<p class="lead"> + We've made an Amazon Machine Image (AMI) so you can quickly deploy on Amazon EC2. This is handy if you just want to evaluate Alaveteli, for example. +</p> + +Note that there are [other ways to install Alaveteli]({{ site.baseurl }}installing). + +## Installing from our AMI + +To help people try out Alaveteli, we have created an AMI (Amazon Machine Image) +with a basic installation of Alaveteli, which you can use to create a running +server on an Amazon EC2 instance. This creates an instance that runs in +development mode, so we wouldn't recommend you use it for a production system +without changing the configuration. + +If you haven't used Amazon Web Services before, then you can get a Micro +instance which will be [free for a year](http://aws.amazon.com/free/). You will +find that a micro instance isn't powerful enough for anything other very basic +testing of Alaveteli, however. + +The AMI can be found in the EU West (Ireland) region, with the ID ami-0f24c678 +and name “Basic Alaveteli installation 2013-10-31”. You can launch an instance +based on that AMI with [this +link](https://console.aws.amazon.com/ec2/home?region=eu-west-1#launchAmi=ami-0f2 +4c678). + +When you create an EC2 instance based on that AMI, make sure that you choose +Security Groups that allows at least inbound HTTP, HTTPS, SSH and, if you want +to test incoming mail as well, SMTP. + +When your EC2 instance is launched, you will be able to log in as the `ubuntu` +user. This user can `sudo` freely to run commands as root. However, the code is +actually owned by (and runs as) the `alaveteli` user. After creating the +instance, you may want to edit a configuration file to customize the site's +configuration. That configuration file is +`/var/www/alaveteli/alaveteli/config/general.yml`, which can be edited with: + + ubuntu@ip-10-58-191-98:~$ sudo su - alaveteli + alaveteli@ip-10-58-191-98:~$ cd alaveteli + alaveteli@ip-10-58-191-98:~/alaveteli$ nano config/general.yml + +Then you should restart the Thin webserver with: + + alaveteli@ip-10-58-191-98:~/alaveteli$ logout + ubuntu@ip-10-58-191-98:~$ sudo /etc/init.d/alaveteli restart + +If you find the hostname of your EC2 instance from the AWS console, you should +then be able to see the site at +`http://your-ec2-hostname.eu-west-1.compute.amazonaws.com` + +If you have any problems or questions, please ask on the [Alaveteli Google +Group](https://groups.google.com/forum/#!forum/alaveteli-dev) or [report an +issue](https://github.com/mysociety/alaveteli/issues?state=open). + diff --git a/installing/exim4.md b/installing/exim4.md new file mode 100644 index 000000000..4cb056a26 --- /dev/null +++ b/installing/exim4.md @@ -0,0 +1,124 @@ +--- +layout: page +title: Installing MTA +--- + +# Installing the MTA + +<p class="lead"> + Alaveteli sends and recieves email. You'll need to set up your Mail + Transfer Agent (MTA) to handle this properly. +</p> + +## Example setup on exim4 + +This page shows an example of how to set up your mail transfer agent (MTA). +These instructions are for **exim4** (running on Ubuntu) -- exim is one of the most +popular MTAs. + +## Instructions + +We suggest you add the following to your exim configuration. + +In `/etc/exim4/conf.d/main/04_alaveteli_options`: + + ALAVETELI_HOME=/path/to/alaveteli/software + ALAVETELI_USER=www-data + log_file_path=/var/log/exim4/exim-%slog-%D + MAIN_LOG_SELECTOR==+all -retry_defer + extract_addresses_remove_arguments=false + +The user ALAVETELI_USER should have write permissions on ALAVETELI_HOME. + +The name and location of the log files created by Exim must match what the +`load-mail-server-logs` script expects, which is why you must provide the +`log_file_path` setting. + +The `check-recent-requests-sent` scripts expects the logs to contain the +`from=<...>` envelope information, so we make the logs more verbose with +`log_selector`. The ALAVETELI_USER may need to also need to be added to the +`trusted_users` list in your Exim config in order to set the return path on +outgoing mail, depending on your setup. + +In `/etc/exim4/conf.d/router/04_alaveteli`: + + alaveteli_request: + debug_print = "R: alaveteli for $local_part@$domain" + driver = redirect + data = ${lookup{$local_part}wildlsearch{ALAVETELI_HOME/config/aliases}} + pipe_transport = alaveteli_mailin_transport + +In `/etc/exim4/conf.d/transport/04_alaveteli`: + + alaveteli_mailin_transport: + driver = pipe + command = $address_pipe ${lc:$local_part} + current_directory = ALAVETELI_HOME + home_directory = ALAVETELI_HOME + user = ALAVETELI_USER + group = ALAVETELI_USER + +And, assuming you set +[`INCOMING_EMAIL_PREFIX`]({{ site.baseurl }}customising/config/#incoming_email_prefix) +in your config at `config/general.yml` to "foi+", create `config/aliases` with the following +content: + + ^foi\\+.*: |/path/to/alaveteli/software/script/mailin + +You should also configure exim to discard any messages sent to the +[`BLACKHOLE_PREFIX`]({{ site.baseurl }}customising/config/#blackhole_prefix) +address, whose default value is +`do-not-reply-to-this-address`. For example, add the following to +`config/aliases`: + + # We use this for envelope from for some messages where we don't care about delivery + do-not-reply-to-this-address: :blackhole: + +If you want to make use of the automatic bounce-message handling, then +set the +[`TRACK_SENDER_EMAIL`]({{ site.baseurl }}customising/config/#track_sender_email) +address to be filtered through +`script/handle-mail-replies`. Messages that are not bounces or +out-of-office autoreplies will be forwarded to +[`FORWARD_NONBOUNCE_RESPONSES_TO`]({{ site.baseurl }}customising/config/#forward_nonbounce_responses_to). +For example, in WhatDoTheyKnow the +configuration looks like this: + + raw_team: [a list of people on the team] + team: |/path/to/alaveteli/software/script/handle-mail-replies + +with `FORWARD_NONBOUNCE_RESPONSES_TO: 'raw_team@whatdotheyknow.com'` + +Finally, make sure you have `dc_use_split_config='true'` in +`/etc/exim4/update-exim4.conf.conf`, and execute the command +`update-exim4.conf`. + +Note that if the file `/etc/exim4/exim4.conf` exists then `update-exim4.conf` +will silently do nothing. Some distributions include this file. If +yours does, you will need to rename it before running `update-exim4.conf`. + +(You may also want to set `dc_eximconfig_configtype='internet'`, +`dc_local_interfaces='0.0.0.0 ; ::1'`, and +`dc_other_hostnames='<your-host-name>'`) + +## Troubleshooting + +To test mail delivery, run: + + exim -bt foi+request-1234@localhost + +This should tell you which routers are being processed. You should +see something like: + + $ exim -bt foi+request-1234@localhost + R: alaveteli pipe for snafflerequest-234@localhost + snafflerequest-234@localhost -> |/home/alaveteli/alaveteli/script/mailin + transport = alaveteli_mailin_transport + +This tells you that the routing part (making emails to +`foi\+.*@localhost` be forwarded to Alaveteli's `mailin` script) is +working. + +There is a great +[Exim Cheatsheet](http://bradthemad.org/tech/notes/exim_cheatsheet.php) +online that you may find useful. diff --git a/installing/index.md b/installing/index.md new file mode 100644 index 000000000..3db72e60f --- /dev/null +++ b/installing/index.md @@ -0,0 +1,28 @@ +--- +layout: page +title: Installing +--- + +# Installing Alaveteli + +<p class="lead"> + + There are a number of ways to install Alaveteli. + We've made an Amazon Machine Image (AMI) so you can quickly deploy on Amazon EC2 (handy if you just want to evaluate it, for example). If you prefer to use your own server, there's an installation script which does most of the work for you. +</p> + +## Installing the core code + +* [Install on Amazon EC2]({{ site.baseurl }}installing/ami) using our AMI +* [Use the installation script]({{ site.baseurl }}installing/script) which does the full installation on your own server +* [Manual installation]({{ site.baseurl }}installing/script) -- step-by-step instructions + +If you're setting up a development server on MacOS X, we've also got [MacOS installation instructions]({{ site.baseurl }}installing/macos). + +## Other installation information + +Alaveteli needs to be able to send and receive email, so you need to setup your MTA (Mail Transfer Agent) appropriately. + +* [Installing the MTA]({{ site.baseurl }}installing/exim4) + + diff --git a/installing/macos.md b/installing/macos.md new file mode 100644 index 000000000..671ec2e18 --- /dev/null +++ b/installing/macos.md @@ -0,0 +1,155 @@ +--- +layout: page +title: Installing on MacOS X +--- + +# Installation on MacOS X + +<p class="lead"> + We don't recommend using OS X in production, but if you want to get + Alaveteli running on your Mac for development, these guidelines should + help. +</p> + +Note that there are [other ways to install Alaveteli]({{ site.baseurl }}installing). + +## MacOS X 10.7 + +Follow these instructions to get Alaveteli running locally on an OS X machine. These instructions have been tested with Xcode 4.1 on OS X Lion (10.7). We do not recommend using OS X in production. + +**Note:** This guide is currently incomplete. Please help by posting issues to the [alaveteli-dev Google group](https://groups.google.com/group/alaveteli-dev) or by submitting pull requests. + +## Xcode + +If you are using OS X Lion, download *Command Line Tools for Xcode* from [Apple](https://developer.apple.com/downloads/index.action). This is a new package from Apple that provides the command-line build tools separate from the rest of Xcode. You need to register for a free Apple Developer account. + +**Note:** As of Xcode 4.2, a non-LLVM version of GCC is no longer included. Homebrew has dealt with it by [switching to Clang](https://github.com/mxcl/homebrew/issues/6852). However, you may encounter errors installing RVM. *Please report these on the [mailing list](https://groups.google.com/group/alaveteli-dev).* The following instructions have been tested with Xcode 4.1. If necessary, you can install GCC from Xcode 4.1 by running: + + brew install http://github.com/adamv/homebrew-alt/raw/master/duplicates/apple-gcc42.rb + +## Homebrew + +Homebrew is a package manager for OS X. It is preferred over alternatives such as MacPorts and Fink. If you haven't already installed Homebrew, run the command: + + ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go) + +Next, install packages required by Alaveteli: + + brew install catdoc elinks gnuplot gs imagemagick libmagic libyaml links mutt poppler tnef wkhtmltopdf wv xapian unrtf + + +### Install postgresql + +Alaveteli uses PostgreSQL by default. If you've tested Alaveteli with MySQL or SQLite, let us know in the [alaveteli-dev Google group](https://groups.google.com/group/alaveteli-dev). + + brew install postgresql + initdb /usr/local/var/postgres + mkdir -p ~/Library/LaunchAgents + cp /usr/local/Cellar/postgresql/9.0.4/org.postgresql.postgres.plist ~/Library/LaunchAgents/ + launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist + +## PDF Toolkit + +[Download the installer package](https://github.com/downloads/robinhouston/pdftk/pdftk.pkg) and install. + +## Ruby + +### Install RVM + +RVM is the preferred way to install multiple Ruby versions on OS X. Alaveteli uses Ruby 1.8.7. The following commands assume you are using the Bash shell. + + curl -L https://get.rvm.io | bash -s stable + +Read `rvm notes` and `rvm requirements` carefully for further instructions. Then, install Ruby: + + rvm install 1.8.7 + rvm install 1.9.3 + rvm use 1.9.3 --default + +### Install mahoro and pg with flags + +The `mahoro` and `pg` gems require special installation commands. Rubygems must be downgraded to 1.6.2 to avoid deprecation warnings when running tests. + + rvm 1.8.7 + gem update --system 1.6.2 + gem install mahoro -- --with-ldflags="-L/usr/local/Cellar/libmagic/5.09/lib" --with-cppflags="-I/usr/local/Cellar/libmagic/5.09/include" + env ARCHFLAGS="-arch x86_64" gem install pg + +#### Update + +As of August 22, 2012 or earlier, you can install `mahoro` in Ruby 1.9.3 on OS X 10.7 Lion with: + + brew install libmagic + gem install mahoro + +## Alaveteli + +The following is mostly from [the manual installation process]({{ site.baseur l}}/installing/manual_install). + +### Configure database + +Creates Alaveteli databases and an `foi` user with password `foi`. + + echo "CREATE DATABASE foi_development encoding = 'UTF8'; + CREATE DATABASE foi_test encoding = 'UTF8'; + CREATE USER foi WITH CREATEUSER; + ALTER USER foi WITH PASSWORD 'foi'; + ALTER USER foi WITH CREATEDB; + GRANT ALL PRIVILEGES ON DATABASE foi_development TO foi; + GRANT ALL PRIVILEGES ON DATABASE foi_test TO foi; + ALTER DATABASE foi_development OWNER TO foi; + ALTER DATABASE foi_test OWNER TO foi;" | psql -h localhost template1 + +### Clone Alaveteli + +We don't want to vendor Rails, as it causes problems locally. + + git clone https://github.com/mysociety/alaveteli.git + cd alaveteli + git submodule init + + sed -i~ 's/\\[submodule "vendor\/rails"\\]//' .git/config + + sed -i~ 's/url = git:\/\/github.com\/rails\/rails.git//' .git/config + git submodule update + +**Note:** Due to Markdown bugs, the first `sed` command above does not display properly if it appears in blockquote. + +### Configure Alaveteli + +Copy the example configuration files and configure `database.yml`. + + cp -f config/general.yml-example config/general.yml + cp -f config/memcached.yml-example config/memcached.yml + cp -f config/database.yml-example config/database.yml + sed -i~ 's/<username>/foi/' config/database.yml + sed -i~ 's/<password>/foi/' config/database.yml + sed -i~ 's/ port: 5432//' config/database.yml + sed -i~ 's/ # PostgreSQL 8.1 pretty please//' config/database.yml + +### Bundler + +Install the gems and finish setting up Alaveteli. + + rvm 1.8.7 + bundle + bundle exec rake db:create:all + bundle exec rake db:migrate + bundle exec rake db:test:prepare + +## Troubleshooting + +### Ruby version + +Ensure you are using the latest versions of Ruby. For example, some versions of Ruby 1.8.7 will segmentation fault, for example: + +``` +/Users/james/.rvm/gems/ruby-1.8.7-p357/gems/json-1.5.4/ext/json/ext/json/ext/parser.bundle: [BUG] Segmentation fault +ruby 1.8.7 (2011-12-28 patchlevel 357) [i686-darwin11.3.0] +``` + +Running `rvm install 1.8.7` should install the latest Ruby 1.8.7 patch level. Remember to switch to the new Ruby version before continuing. + +### Rake tasks + +Remember to run Rake tasks with `bundle exec`. To run the tests, for example, run `bundle exec rake`.
\ No newline at end of file diff --git a/installing/manual_install.md b/installing/manual_install.md new file mode 100644 index 000000000..f697d4563 --- /dev/null +++ b/installing/manual_install.md @@ -0,0 +1,544 @@ +--- +layout: page +title: Manual installation +--- + + +# Manual Installation + +<p class="lead"> + The following instructions describe the step-by-step process for + installing Alavetli. <em>You don't necessarily need to do it this + way:</em> it's usually easier to use the + <a href="{{ site.baseurl }}installing/script">installation script</a> + or the + <a href="{{ site.baseurl }}installing/ami">Amazon EC2 AMI</a>. +</p> + +Note that there are [other ways to install Alaveteli]({{ site.baseurl }}installing). + +## Target operating system + +These instructions assume Debian Squeeze (64-bit) or Ubuntu 12.04 LTS +(precise). Debian Squeeze is the best supported deployment platform. We also +have instructions for [installing on MacOS]({{ site.baseurl }}installing/macos). + +Commands are intended to be run via the terminal or over ssh. + + +## Get Alaveteli + +To start with, you may need to install git, e.g. with `sudo apt-get install +git-core` + +Next, get hold of the Alaveteli source code from github: + + git clone https://github.com/mysociety/alaveteli.git + cd alaveteli + +This will get the development branch, which has the latest (possibly buggy) +code. If you don't want to add or try new features, swap to the master branch +(which always contains the latest stable release): + + git checkout master + +## Package pinning + +You need to configure +[apt-pinning](http://wiki.debian.org/AptPreferences#Pinning-1) preferences in +order to prevent packages being pulled from the debian wheezy distribution in +preference to the stable distribution once you have added the wheezy repository +as described below. + +In order to configure apt-pinning and to keep most packages coming from the +Debian stable repository while installing the ones required from wheezy and the +mySociety repository you need to run the following commands: + + echo "Package: *" >> /tmp/preferences + echo "Pin: release a=squeeze-backports">> /tmp/preferences + echo "Pin-Priority: 200" >> /tmp/preferences + echo "" >> /tmp/preferences + echo "Package: *" >> /tmp/preferences + echo "Pin: release a=wheezy">> /tmp/preferences + echo "Pin-Priority: 50" >> /tmp/preferences + sudo cp /tmp/preferences /etc/apt/ + rm /tmp/preferences + +## Install system dependencies + +These are packages that the software depends on: third-party software used to +parse documents, host the site, and so on. There are also packages that contain +headers necessary to compile some of the gem dependencies in the next step. + +If you are running Debian, add the following repositories to +`/etc/apt/sources.list` and run `apt-get update`: + + deb http://debian.mysociety.org squeeze main + deb http://ftp.debian.org/debian/ wheezy main non-free contrib + deb http://backports.debian.org/debian-backports squeeze-backports main contrib non-free + +The repositories above let you install the packages `wkhtmltopdf-static` +and `bundler` using `apt`; so if you're running Ubuntu, you won't be able to +use the above repositories. Instead, comment out those two lines in +`config/packages` before following the next step (and install bundler manually). + +Now install the packages that are listed in config/packages using apt-get: + + sudo apt-get install `cut -d " " -f 1 config/packages | grep -v "^#"` + +Some of the files also have a version number listed in config/packages - check +that you have appropriate versions installed. Some also list "|" and offer a +choice of packages. + +## Install Ruby dependencies + +To install Alaveteli's Ruby dependencies, you need to install bundler. In +Debian, this is provided as a package (installed as part of the package install +process above). You could also install it as a gem: + + sudo gem1.8 install bundler + +## Install mySociety libraries + +Next, install mySociety's common ruby libraries and the Rails +code. To fetch the contents of the submodules, run: + + git submodule update --init + + +### Packages customised by mySociety + +If you're using Debian, you should add the mySociety debian archive to your +`/etc/apt/sources.list` as described above. Doing this and following the above +instructions will install a couple of custom dependencies. If you're using +some other platform, you can optionally install these dependencies manually, +as follows: + +1. If you would like users to be able to get pretty PDFs as part of the +downloadable zipfile of their request history, install +[wkhtmltopdf](http://code.google.com/p/wkhtmltopdf/downloads/list). We +recommend downloading the latest, statically compiled version from the project +website, as this allows running headless (that is, without a graphical interface +running) on Linux. If you do install `wkhtmltopdf`, you need to edit a setting +in the config file to point to it (see below). If you don't install it, +everything will still work, but users will get ugly, plain text versions of +their requests when they download them. + +2. Version 1.44 of `pdftk` contains a bug which makes it loop forever in +certain edge conditions. Until it's incorporated into an official release, you +can either hope you don't encounter the bug (it ties up a rails process until +you kill it), patch it yourself, or use the Debian package +compiled by mySociety (see link in [issue +305](https://github.com/mysociety/alaveteli/issues/305)) + + +## Configure Database + +There has been a little work done in trying to make the code work with other +databases (e.g., SQLite), but the currently supported database is PostgreSQL +("postgres"). + +If you don't have postgres installed: + + apt-get install postgresql postgresql-client + +Now you need to set up the database config file to contain the name, username +and password of your postgres database. + +* copy `database.yml-example` to `database.yml` in `alaveteli/config` +* edit it to point to your local postgresql database in the development + and test sections and create the databases: + +Make sure that the user specified in `database.yml` exists, and has full +permissions on these databases. As they need the ability to turn off +constraints whilst running the tests they also need to be a superuser. If you +don't want your database user to be a superuser, you can add this line +to the test config in `database.yml` (as seen in `database.yml-example`) + + disable_constraints: false + + +Create a `foi` user from the command line, like this: + + # su - postgres + $ createuser -s -P foi + +Then create a database: + + $ createdb -T template0 -E SQL_ASCII -O foi foi_production + $ createdb -T template0 -E SQL_ASCII -O foi foi_test + $ createdb -T template0 -E SQL_ASCII -O foi foi_development + +We create using the ``SQL_ASCII`` encoding, because in postgres this is means +"no encoding"; and because we handle and store all kinds of data that may not +be valid UTF (for example, data originating from various broken email clients +that's not 8-bit clean), it's safer to be able to store *anything*, than reject +data at runtime. + +## Configure email + +You will need to set up an email server (MTA) to send and receive emails. Full +configuration for an MTA is beyond the scope of this document -- see this +[example config for Exim4]({{ site.baseurl }}installing/exim4). + +Note that in development mode mail is handled by mailcatcher by default so +that you can see the mails in a browser - see http://mailcatcher.me/ for more +details. Start mailcatcher by running `bundle exec mailcatcher` in your +application directory. + +### Minimal + +If you just want to get the tests to pass, you will at a minimum need to allow +sending emails via a `sendmail` command (a requirement met, for example, with +`sudo apt-get install exim4`). + +### Detailed + +When an authority receives an email, the email's `reply-to` field is a magic +address which is parsed and consumed by the Rails app. + +To receive such email in a production setup, you will need to configure your +MTA to pipe incoming emails to the Alaveteli script `script/mailin`. Therefore, +you will need to configure your MTA to accept emails to magic addresses, and to +pipe such emails to this script. + +Magic email addresses are of the form: + + <foi+request-3-691c8388@example.com> + +The respective parts of this address are controlled with options in +`config/general.yml`, thus: + + INCOMING_EMAIL_PREFIX = 'foi+' + INCOMING_EMAIL_DOMAIN = 'example.com' + +When you set up your MTA, if there is some error inside Rails, the +email is returned with an exit code 75, which for Exim at least means the MTA +will try again later. Additionally, a stacktrace is emailed to `CONTACT_EMAIL`. + +See [this example]({{ site.baseurl }}exim4) for a possible configuration for Exim (>=1.9). + +A well-configured installation of this code will have had Exim make +a backup copy of the email in a separate mailbox, just in case. + +## Set up configs + +Copy `config/general.yml-example` to `config/general.yml` and edit to your +taste. + +Note that the default settings for frontpage examples are designed to work with +the dummy data shipped with Alaveteli; once you have real data, you should +certainly edit these. + +The default theme is the "Alaveteli" theme. When you run `rails-post-deploy` +(see below), that theme gets installed automatically. + +Finally, copy `config/newrelic.yml-example` to `config/newrelic.yml`. This file +contains configuration information for the New Relic performance management +system. By default, monitoring is switched off by the `agent_enabled: false` +setting. See New Relic's [remote performance analysis](https://github.com/newrelic/rpm) instructions for switching it on +for both local and remote analysis. + + +## Deployment + +In the `alaveteli` directory, run: + + script/rails-post-deploy + +(This will need execute privs so `chmod 755` if necessary.) This sets up +directory structures, creates logs, installs/updates themes, runs database +migrations, etc. You should run it after each new software update. + +One of the things the script does is install dependencies (using `bundle +install`). Note that the first time you run it, part of the `bundle install` +that compiles `xapian-full` takes a *long* time! + +If you want some dummy data to play with, you can try loading the fixtures that +the test suite uses into your development database. You can do this with: + + script/load-sample-data + +Next, create the index for the search engine (Xapian): + + script/rebuild-xapian-index + +If this fails, the site should still mostly run, but it's a core component so +you should really try to get this working. + +## Run the Tests + +Make sure everything looks OK: + + bundle exec rake spec + +If there are failures here, something has gone wrong with the preceding steps +(see the next section for a common problem and workaround). You might be able +to move on to the next step, depending on how serious they are, but ideally you +should try to find out what's gone wrong. + +### glibc bug workaround + +There's a [bug in +glibc](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637239) which causes +Xapian to segfault when running the tests. Although the bug report linked to +claims it's fixed in the current Debian stable, it's not as of version +`2.11.3-2`. + +Until it's fixed (e.g. `libc6 2.13-26` does work), you can get the tests to +pass by setting `export LD_PRELOAD=/lib/libuuid.so.1`. + +## Run the Server + +Run the following to get the server running: + + bundle exec rails server --environment=development + +By default the server listens on all interfaces. You can restrict it to the +localhost interface by adding ` --binding=127.0.0.1` + +The server should have told you the URL to access in your browser to see the +site in action. + +## Administrator privileges + +The administrative interface is at the URL `/admin`. + +Only users with the `super` admin level can access the admin interface. Users +create their own accounts in the usual way, and then administrators can give +them `super` privileges. + +There is an emergency user account which can be accessed via +`/admin?emergency=1`, using the credentials `ADMIN_USERNAME` and +`ADMIN_PASSWORD`, which are set in `general.yml`. To bootstrap the +first `super` level accounts, you will need to log in as the emergency +user. You can disable the emergency user account by setting `DISABLE_EMERGENCY_USER` to `true` in `general.yml`. + +Users with the superuser role also have extra privileges in the website +frontend, such as being able to categorise any request, being able to view +items that have been hidden from the search, and being presented with "admin" +links next to individual requests and comments in the front end. + +It is possible completely to override the administrator authentication by +setting `SKIP_ADMIN_AUTH` to `true` in `general.yml`. + +## Cron jobs and init scripts + +`config/crontab-example` contains the cronjobs run on WhatDoTheyKnow. It's in a +strange templating format they use in mySociety. mySociety render the example +file to reference absolute paths, and then drop it in `/etc/cron.d/` on the +server. + +The `ugly` format uses simple variable substitution. A variable looks like +`!!(*= $this *)!!`. The variables are: + +* `vhost`: part of the path to the directory where the software is + served from. In the mySociety files, it usually comes as + `/data/vhost/!!(*= $vhost *)!!` -- you should replace that whole + port with a path to the directory where your Alaveteli software + installation lives, e.g. `/var/www/` +* `vhost_dir`: the entire path to the directory where the software is + served from. -- you should replace this with a path to the + directory where your Alaveteli software installation lives, + e.g. `/var/www/` +* `vcspath`: the name of the alaveteli checkout, e.g. `alaveteli`. + Thus, `/data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!` might be + replaced with `/var/www/alaveteli` in your cron tab +* `user`: the user that the software runs as +* `site`: a string to identify your alaveteli instance + +There is a rake task that will help to rewrite this file into one that is +useful to you, which can be invoked with: + + bundle exec rake config_files:convert_crontab \ + DEPLOY_USER=deploy \ + VHOST_DIR=/dir/above/alaveteli \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + CRONTAB=config/crontab-example > crontab + +You should change the `DEPLOY_USER`, `VHOST_DIR`, `VCSPATH` and `SITE` +environment variables to match your server and installation. You should also +edit the resulting `crontab` file to customize the `MAILTO` variable. + +One of the cron jobs refers to a script at `/etc/init.d/foi-alert-tracks`. This +is an init script, a copy of which lives in `config/alert-tracks-debian.ugly`. +As with the cron jobs above, replace the variables (and/or bits near the +variables) with paths to your software. You can use the rake task `rake +config_files:convert_init_script` to do this. + +`config/purge-varnish-debian.ugly` is a similar init script, which is optional +and not required if you choose not to run your site behind Varnish (see below). +Either tweak the file permissions to make the scripts executable by your deploy +user, or add the following line to your sudoers file to allow these to be run +by your deploy user (named `deploy` in this case): + + deploy ALL = NOPASSWD: /etc/init.d/foi-alert-tracks, /etc/init.d/foi-purge-varnish + +The cron jobs refer to a program `run-with-lockfile`. See [this +issue](https://github.com/mysociety/alaveteli/issues/112) for a discussion of +where to find this program, and how you might replace it. This [one line +script](https://gist.github.com/3741194) can install this program system-wide. + +## Set up production web server + +It is not recommended to run the website using the default Rails web server. +There are various recommendations here: http://rubyonrails.org/deploy + +We usually use Passenger / mod_rails. The file at `conf/httpd.conf-example` +gives you an example config file for WhatDoTheyKnow. At a minimum, you should +include the following in an Apache configuration file: + + PassengerResolveSymlinksInDocumentRoot on + PassengerMaxPoolSize 6 # Recommend setting this to 3 or less on servers with 512MB RAM + +Under all but light loads, it is strongly recommended to run the server behind +an http accelerator like Varnish. A sample varnish VCL is supplied in +`../conf/varnish-alaveteli.vcl`. + +It's strongly recommended that you run the site over SSL. (Set FORCE_SSL to +true in config/general.yml). For this you will need an SSL certificate for your +domain and you will need to configure an SSL terminator to sit in front of +Varnish. If you're already using Apache as a web server you could simply use +Apache as the SSL terminator. A minimal configuration would look something like +this: + + <VirtualHost *:443> + ServerName www.yourdomain + + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / http://localhost:80/ + ProxyPassReverse / http://localhost:80/ + RequestHeader set X-Forwarded-Proto 'https' + + SSLEngine on + SSLProtocol all -SSLv2 + SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM + + SSLCertificateFile /etc/apache2/ssl/ssl.crt + SSLCertificateKeyFile /etc/apache2/ssl/ssl.key + SSLCertificateChainFile /etc/apache2/ssl/sub.class2.server.ca.pem + SSLCACertificateFile /etc/apache2/ssl/ca.pem + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + + </VirtualHost> + +Notice the line `RequestHeader` that sets the `X-Forwarded-Proto` header. This +is important. This ultimately tells Rails that it's serving a page over https +and so it knows to include that in any absolute urls it serves. + +Some [production server best practice +notes](https://github.com/mysociety/alaveteli/wiki/Production-Server-Best-Practi +ces) are evolving on the wiki. + +## Upgrading Alaveteli + +The developer team policy is that the master branch in git should always +contain the latest stable release. Therefore, in production, you should usually +have your software deployed from the master branch, and an upgrade can be +simply `git pull`. + +Patch version increases (e.g. 1.2.3 → 1.2.**4**) should not require any further +action on your part. + +Minor version increases (e.g. 1.2.4 → 1.**3**.0) will usually require further +action. You should read the `CHANGES.md` document to see what's changed since +your last deployment, paying special attention to anything in the "Updgrading" +sections. + +Any upgrade may include new translations strings, i.e. new or altered messages +to the user that need translating to your locale. You should visit Transifex +and try to get your translation up to 100% on each new release. Failure to do +so means that any new words added to the Alaveteli source code will appear in +your website in English by default. If your translations didn't make it to the +latest release, you will need to download the updated `app.po` for your locale +from Transifex and save it in the `locale/` folder. + +You should always run the script `scripts/rails-post-deploy` after each +deployment. This runs any database migrations for you, plus various other +things that can be automated for deployment. + +## Troubleshooting + +* **Incoming emails aren't appearing in my Alaveteli install** + + First, you need to check that your MTA is delivering relevant + incoming emails to the `script/mailin` command. There are various + ways of setting your MTA up to do this; we have documented one way + of doing it in Exim at `doc/INSTALL-exim4.conf`, including a + command you can use to check that the email routing is set up + correctly. + + Second, you need to test that the mailin script itself is working + correctly, by running it from the command line, First, find a + valid "To" address for a request in your system. You can do this + through your site's admin interface, or from the command line, + like so: + + $ ./script/console + Loading development environment (Rails 2.3.14) + >> InfoRequest.find_by_url_title("why_do_you_have_such_a_fancy_dog").incoming_email + => "request-101-50929748@localhost" + + Now take the source of a valid email (there are some sample emails in + `spec/fixtures/files/`); edit the `To:` header to match this address; + and then pipe it through the mailin script. A non-zero exit code + means there was a problem. For example: + + $ cp spec/fixtures/files/incoming-request-plain.email /tmp/ + $ perl -pi -e 's/^To:.*/To: <request-101-50929748@localhost>/' /tmp/incoming-request-plain.email + $ ./script/mailin < /tmp/incoming-request-plain.email + $ echo $? + 75 + + The `mailin` script emails the details of any errors to + `CONTACT_EMAIL` (from your `general.yml` file). A common problem is + for the user that the MTA runs as not to have write access to + `files/raw_emails/`. + +* **Various tests fail with "*Your PostgreSQL connection does not support + unescape_bytea. Try upgrading to pg 0.9.0 or later.*"** + + You have an old version of `pg`, the ruby postgres driver. In + Ubuntu, for example, this is provided by the package `libdbd-pg-ruby`. + + Try upgrading your system's `pg` installation, or installing the pg + gem with `gem install pg` + +* **Some of the tests relating to mail are failing, with messages like + "*when using TMail should load an email with funny MIME settings' + FAILED*"** + + This sounds like the tests are running using the `production` + environment, rather than the `test` environment, for some reason. + +* **Non-ASCII characters are being displayed as asterisks in my incoming messages** + + We rely on `elinks` to convert HTML email to plain text. + Normally, the encoding should just work, but under some + circumstances it appears that `elinks` ignores the parameters + passed to it from Alaveteli. + + To force `elinks` always to treat input as UTF8, add the following + to `/etc/elinks/elinks.conf`: + + set document.codepage.assume = "utf-8" + set document.codepage.force_assumed = 1 + + You should also check that your locale is set up correctly. See + [this issue followup](https://github.com/mysociety/alaveteli/issues/128#issuecomment-1814845) + for further discussion. + +* **I'm seeing `rake: command not found` when running the post install script** + + The script uses `rake`. + + It may be that the binaries installed by bundler are not put in the + system `PATH`; therefore, in order to run `rake` (needed for + deployments), you may need to do something like: + + ln -s /usr/lib/ruby/gems/1.8/bin/rake /usr/local/bin/ + + + diff --git a/installing/script.md b/installing/script.md new file mode 100644 index 000000000..079d718e9 --- /dev/null +++ b/installing/script.md @@ -0,0 +1,65 @@ +--- +layout: page +title: Installing the easy way +--- + +# Installation script + +<p class="lead"> + If you prefer to use your own server, we've provided an installation script which does most of the work for you. +</p> + +Note that there are [other ways to install Alaveteli]({{ site.baseurl }}installing). + +## Installing with the installation script + +If you have a clean installation of Debian squeeze or Ubuntu precise, you can +use an install script in our commonlib repository to set up a working instance +of Alaveteli. This is not suitable for production (it runs in development mode, +for example) but should set up a functional installation of the site. + +**Warning: only use this script on a newly installed server – it will make +significant changes to your server’s setup, including modifying your nginx +setup, creating a user account, creating a database, installing new packages +etc.** + +To download the script, run the following command: + + curl -O https://raw.github.com/mysociety/commonlib/master/bin/install-site.sh + +If you run this script with `sh install-site.sh`, you'll see its usage message: + + Usage: ./install-site.sh [--default] <SITE-NAME> <UNIX-USER> [HOST] + HOST is only optional if you are running this on an EC2 instance. + --default means to install as the default site for this server, + rather than a virtualhost for HOST. + +In this case `<SITE-NAME>` should be `alaveteli`. `<UNIX-USER>` is the name of +the Unix user that you want to own and run the code. (This user will be created +by the script.) + +The `HOST` parameter is a hostname for the server that will be usable +externally – a virtualhost for this name will be created by the script, unless +you specified the `--default` option. This parameter is optional if you are on +an EC2 instance, in which case the hostname of that instance will be used. + +For example, if you wish to use a new user called `alaveteli` and the hostname +`alaveteli.127.0.0.1.xip.io`, creating a virtualhost just for that hostname, +you could download and run the script with: + + sudo sh install-site.sh alaveteli alaveteli alaveteli.127.0.0.1.xip.io + +([xip.io](http://xip.io/) is a helpful domain for development.) + +Or, if you want to set this up as the default site on an EC2 instance, you +could download the script, make it executable and then invoke it with: + + sudo ./install-site.sh --default alaveteli alaveteli + +When the script has finished, you should have a working copy of the website, +accessible via the hostname you supplied to the script. + +If you have any problems or questions, please ask on the [Alaveteli Google +Group](https://groups.google.com/forum/#!forum/alaveteli-dev) or [report an +issue](https://github.com/mysociety/alaveteli/issues?state=open). + diff --git a/running/admin_manual.md b/running/admin_manual.md new file mode 100644 index 000000000..609ed3bd8 --- /dev/null +++ b/running/admin_manual.md @@ -0,0 +1,301 @@ +--- +layout: page +title: Administrator's guide +--- + +# Alaveteli administrator's guide + +<p class="lead"> + What is it like running an Alaveteli site? This guide explains what you can expect, and the types of problem that you might encounter. It includes examples of how mySociety manages their own <a href="/glossary/#foi" class="glossary">Freedom of Information</a> site, <a href="http://www.whatdotheyknow.com">whatdotheyknow.com</a>. +</p> + +## What's involved? + +The overhead in managing a successful FOI website is quite high. Richard, a +volunteer, wrote a [blog +post](http://www.mysociety.org/2009/10/13/behind-whatdotheyknow/) about some of +this in 2009. + +WhatDoTheyKnow usually has about 3 active volunteers at any one time managing +the support, plus a few other less active people who help out at different +times. + +Administration tasks can be split into **maintenance** and **user support**. +The boundaries of these tasks is in fact quite blurred; the main distinction is +that the former happen exclusively through the web admin interface, whereas the +latter are mediated by email directly with end users (but often result in +actions through the web admin interface). + +In one randomly chosen week in December 2010, the support team acted on 66 +different events, comprising 44 user **support** emails and 22 **maintenance** +tasks. + +Most of the support emails require some time to investigate; some (e.g. those +with legal implications) require quite a lot of policy discussion and debate in +order to address them. Maintenance tasks tend to be much more straightforward +to address, although sometimes they need expert knowledge (e.g. about mail +server bounce messages). + +During that week, the tasks broke down as follows: + +### Regular maintenance tasks + +* 18 misdelivered / undelivered responses (a.k.a. the "Holding Pen") +* 4 requests that are unclassified 21 days after response needing classification +* 2 requests that have been marked as needing admin attention +* 2 things marked as errors (message refused by server - spam, full mailbox, etc) to fix + +### User interaction tasks + +* 16 general, daily admin: i.e. things that resulted in admin actions on the + site (bounces, misdelivered responses, etc) +* 14 items wrongly addressed (i.e. to the support team rather than an authority) +* 6 users needed support using the website (problems finding authorities, or authorities having problems following up) +* 4 users wanted advice about FOI or data protection +* 3 requests to redact personal information +* 2 requests to redact defamatory information + +## Types of user interaction + +There follows a breakdown of the most common kinds of user interaction. It's +intended for use as a guide to the kind of policies and training that a support +team might need to develop. + +### Dealing with email that's not getting through to the authority + +Emails may not get through to the authority in the first place for a few +reasons: + +* The recipient's domain has marked the email as spam and not sent it on +* It's gone into the recipient's spam folder due to their own mail client setup +* The recipient has a mail filter configured in their client that otherwise skips their inbox + +The first reason is the most common. The solution is to send a standard email +to the recipient's IT department to whitelist email from your service (and of +course send a message to the original recipient about this). The Alaveteli +admin interface also has an option to "resend" any particular message. + +An Alaveteli administrator will typically only become aware of this when a +request has become very overdue without any correspondence at all from the +authority. Sometimes the authority's mail server will bounce the email, in +which case it appears in the administrative interface as "needs admin +attention". + +### Requests to take down information + +#### Legal action + +This is where someone tells us that information on the site might be subject to +legal action. The scenario will vary wildly across different legal +jurisdictions. In the UK, this kind of request is most likely to be related to +defamation. + +##### Action + +* Get the notification by email to a central support email address, so there is + a written record +* Act according to standard legal advice (e.g. you may need to temporarily take + down requests while you debate it, even if you think they should stay up; or + you may be able to redact them temporarily rather than take them down) +* Centrally log the entire conversation and the actions you have taken +* Get further legal advice where necessary. For example, you may get a risk + assessment that suggests you can republish the request, or show it with + limited redactions. + +#### Copyright / Commercial + +Public authorities who have not quite understood that their responses are +public sometimes don't like this, and claim copyright. Occasionally other +copyright assertions are made about content, but this is the most common one. +"Commercially sensitive" data might also be considered private information. + +##### Action + +* In the case of threatened legal action, see above. +* Otherwise, in the first instance, treat this as an advocacy case, on the + basis that FOI requests can be made repeatedly by anyone, the data should be + public anyway, and publishing it should actually save the authority money. + +##### Example email to authority + +> As I'm sure you know, our Freedom of Information law is "applicant blind", +> so anyone in the world can request the same document and get a copy of it. +> To save tax payers' money by preventing duplicate requests, and for good +> public relations, we'd advise you not to ask us to take down the +> information or to apply for a license. I would also note that +> <authority_name> has allowed re-use of FOI responses through our +> website since last year, without any trouble. + + +#### Personal data + +This includes everything from inadvertently revealed personal data such as +personally identifying information about benefits claimants to the name of a +user of the site who later develops "Google remorse". + +##### Action + +* Assess request, with reference to local Data Protection laws. Don't + automatically presume in favour of taking something down, but weighing the + nuisance/harm caused to the individual which would be relieved by taking the + material down against the public interest in publishing / continuing to + publish the material. "Sensitive" personal data will typically require a + much higher level of public interest. +* [WhatDoTheyKnow considers](http://www.whatdotheyknow.com/help/privacy#takedown) there to be a + strong public interest in retaining the names of officers or servants of + public authorities +* For users who want their name removed entirely from the site, in the first + instance, try to persuade them not to do so: +* Find out why they want their name removing +* Explain that the site is a permanent archive, and it's hard to remove things + from the Internet once posted +* Find examples of valuable requests they've made, to show why we want to keep + it +* Explain technical difficulties of removal (if relevant) +* With persistent requests, consider changing their account name to abbreviate + their first name to an initial, as this won't confuse existing requests too + much. Where there are grounds of personal safety, name should be removed and + replaced with suitable redaction text. +* Where redaction is hard (e.g. removing a scanned signature from a PDF, ask + them to resend their response with redaction in place. This has a benefit of + training them not to do this in the future, which is a good thing. +* Where redactions take place, it is advisable to add an annotation to the + request + + +### Incorrectly addressed + +Emails that arrive at the support team address, but shouldn't have. Two main types: + +* Users who think the site is a place to contact agencies directly (e.g. people + going though immigration and asylum processes who want to contact the UK + Borders Agency) +* Users who email the support email address rather than using the online form; + usually because they've replied to a system email rather than followed the + link in the message + +#### Action + +Respond to user and point them in the right direction. + +##### Example message: + +> I like to know some information about my EEA2 application which i applied on +> july 2010.i do not get any response yet ...please let me know what i will do. + +##### Example response: + +> You have written to the team responsible for the WhatDoTheyKnow.com website; +> we only run that website and are not part of the UK Government. +> +> As you are asking about your own personal circumstances you need to contact +> the UKBA directly; their contact information is available at: +> +> http://www.bia.homeoffice.gov.uk/contact/contactspage/ +> http://www.ukba.homeoffice.gov.uk/contact/contactspage/contactcentres/ +> +> You might also want to consider contacting your local MP. You could ask your +> local council or the Citizens Advice Bureau if there is an immigration advice +> centre where you are. + +##### Example message: + +> is the greenwaste collection paying for its self? .i suspect due to +> the low numbers of residents taking up the scheme, what is the true +> cost of these collections? is the scheme liable to be scrapped ? + +##### Example response: + +> You've written to the team responsible for the website WhatDoTheyKnow.com +> and not <authority_name> +> +> If you want to make a freedom of information request to them you can do so, +> in public, via our site. To get started click "make a new freedom of +> information request" at: +> +> http://www.whatdotheyknow.com/body/<authority_name> + +### Wants advice + +Two common examples are: + +* A user isn't sure where to direct their request +* Wants to know the best way to ask an authority for all the personal data they + hold about themselves + +##### Example request: + +> I would like to know at this stage under the freedom act can ask +> directly to UK embassies or high commission abroad to disclose some +> information. or I have to contact FCO through this website. + +##### Example response: + +> I would suggest making your request to the FCO as they are they body +> technically subject to the Freedom of Information Act. +> +> When you make your request it will be sent to the FCO's central FOI team they +> will then co-ordinate the response with the relevant parts of their +> organisation. + + +### General assistance required + +Can be for many reasons, e.g. + +* They had withdrawn their request, and an authority had subsequently + replied, marking the request as open again. +* Suggested corrections to authority names / details from users or authorities + themselves +* A reply has been automatically filed under the wrong request + +## Vexatious users + +Some users persistently misuse the website. An alaveteli site should have a +policy on banning users, for example giving them a first warning, informing +them about moderation policy, etc. + +## Mail import errors + +These are currently occurring at a rate of about two a month. Sometimes the +root cause seems to be blocking in the database when two mails are received for +the same request at about the same time, sometimes it just seems to be IO +timeout if the server is busy. When a mail import error occurs, the mail +handler (Exim) is sent an exit code of 75 and so should try to deliver the mail +again. A mail is sent to the support address for the site, indicating that an +error occurred, with the error and the incoming mail as attachments. Usually +Exim will redeliver the mail to the application. On the rare occasion it +doesn't, you can import it manually, by putting the raw mail (as attached to +the error sent to the site support address) in a file without the first "From" +line, and piping the contents of that file into the mail handling script. e.g. +```cat missing_mail.txt | script/mailin``` + +## Censor rules + +Censor rules can be attached to a request or to a user and define bits of text +to be removed (either from the request (and all associated files e.g. incoming +message attachments) or from all requests associated with a user), and some +replacement text. In binary files, the replacement text will always be a series +of 'x' characters identical in length to the text replaced, in order to +preserve file length. The attachment censoring does not work consistently, as +it is difficult to write rules that will match the exact contents of the +underlying file, so always check the results. Make sure to also add censor +rules for the real text and check the "View as HTML" option; this is currently +(Sept 2013) generated from the uncensored PDF or other binary file. + +You can make a censor rule apply as a [regular +expression](http://en.wikipedia.org/wiki/Regular_expression) by checking the +"Is it regexp replacement?" checkbox in the admin interface for censor rules. +Otherwise it will literally just replace any occurrences of the text entered. +Like regular text-based censor rules, regular expression based rules will be +run over binary files related to the request too, so a regular expression that +is quite loose in what it matches may have unexpected consequences if it also +matches the underlying sequence of characters in a binary file. Also, complex +or loose regular expressions can be very expensive to run (in some cases +hanging the application altogether), so please: + +* Restrict your use of them to cases that can't otherwise be easily covered. +* Keep them as simple and specific as possible. + + + diff --git a/running/index.md b/running/index.md new file mode 100644 index 000000000..a8f53eaeb --- /dev/null +++ b/running/index.md @@ -0,0 +1,28 @@ +--- +layout: page +title: Running +--- + +# Running Alaveteli + + +<p class="lead"> + Keeping your Alaveteli site up and running requires some ongoing effort. +</p> + +Alaveteli is not just software. To run a successful +<a href="{{ site.baseurl }}glossary/#foi" class="glossary">Freedom of Information</a> +site, you need to make sure day-to-day tasks get done too. Most Alaveteli sites +are run by a team who allocate some time every day to user support and generally keeping +the project up to date. + +* the [administrator's guide]({{ site.baseurl }}running/admin_manual) describes + what you need to do and know to run your site + +* we've prepared a checklist of + [things to consider]({{ site.baseurl }}running/server) + when setting up your production server + +* see the [different states a request can be in]({{ site.baseurl }}running/states) + + diff --git a/running/server.md b/running/server.md new file mode 100644 index 000000000..95f69b63d --- /dev/null +++ b/running/server.md @@ -0,0 +1,123 @@ +--- +layout: page +title: Production server best practices +--- + +# Production server best practices + +<p class="lead"> + These notes serve as a checklist of things to consider when you're ready + to deploy your Alaveteli site to production. +</p> + + +## Hosting options + +Your production server must be reliable and secure. If you don't run your own +servers already, consider one of these options: + +* Cloud Server +* Virtual Private Server + +In some cases, we can host new Alaveteli projects — if you need help, +ask us about hosting. + +## Cron jobs + +Don't forget to set up the cron jobs as outlined in the +[installation instructions]({{ site.baseurl }}installing/manual_install). +As of October 2011, they rely on a small program created by mySociety called +`run-with-lockfile`. A discussion of where the source for this can be found, +and possible alternatives, lives in +[Alaveteli issue #112](https://github.com/mysociety/alaveteli/issues/112). + +## Webserver configuration + +We recommend running your site behind +[Apache](https://httpd.apache.org) + +[Passenger](https://www.phusionpassenger.com). Refer to the +[installation instructions]({{ site.baseurl }}installing/manual_install) +regarding `PassengerMaxPoolSize`, which you should +experiment with to match your available RAM. It is very unlikely that you'll +ever need a pool larger than [Passenger's +default](http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt) of 6. + +We recommend you run your server behind an HTTP accelerator like +[Varnish](https://www.varnish-cache.org). +Alaveteli ships with a +[sample varnish VCL](https://github.com/mysociety/alaveteli/blob/master/config/varnish-alaveteli.vcl). + +## Security + +You _must_ change all key-related [config settings]({{ site.baseurl }}customising/config) +in `general.yml` from their default values. This includes (but may not be limited to!) +these settings: + +* [`INCOMING_EMAIL_SECRET`]({{ site.baseurl }}customising/config/#incoming_email_secret) +* [`ADMIN_USERNAME`]({{ site.baseurl }}customising/config/#admin_username) +* [`ADMIN_PASSWORD`]({{ site.baseurl }}customising/config/#admin_password) +* [`COOKIE_STORE_SESSION_SECRET`]({{ site.baseurl }}customising/config/#cookie_store_session_secret) +* [`RECAPTCHA_PUBLIC_KEY`]({{ site.baseurl }}customising/config/#recaptcha_public_key) +* [`RECAPTCHA_PRIVATE_KEY`]({{ site.baseurl }}customising/config/#recaptcha_private_key) + +You should consider running the admin part of the site over HTTPS. This can be +achieved with rewrite rules that redirect URLs beginning with `/admin`. + +## Email configuration + +See the application-specific +[email configuration for exim]({{ site.baseurl }}installing/exim4) for +setting up your Mail Transfer Agent (MTA). It is possible to use other MTAs — +if you use a different one, the documentation for exim should provide you with +enough information to get started. If you do use a different one, please add to the +documentation! + +On a live server, you should also consider the following, to increase the +deliverability of your email: + +* Set up [SPF records](http://www.openspf.org/) for your domain +* Set up <a + href="http://en.wikipedia.org/wiki/Feedback_loop_(email)#Feedback_loop_links_f + or_some_email_providers">feedback loops</a> with the main email providers + (Hotmail and Yahoo! are recommended) +* Especially if deploying from Amazon EC2, use an external SMTP relay for + sending outgoing mail. See [Alaveteli EC2 AMI]( {{ site.baseurl }}installing/ami) + for more suggestions. + +## Backup + +Most of the data for the site lives in the production database. The exception +is the raw incoming email data, which is stored on the filesystem, as specified +in the setting +[`RAW_EMAILS_LOCATION`]({{ site.baseurl }}customising/config/#raw_emails_location) +setting in `config/general.yml`. + +Refer to the [Postgres +documentation](http://www.postgresql.org/docs/8.4/static/backup.html) for +database backup strategies. The most common method is to use `pg_dump` to +create a SQL dump of the database, and backup a zipped copy of this. + +Raw emails would be best backed up using an incremental strategy. +[Rsync](http://rsync.samba.org/) is one way of doing this. + +Another belt-and-braces backup strategy is to set up your MTA to copy all +incoming and outgoing mail to a backup mailbox. One way of doing this with exim +is to put the following in your exim config: + + system_filter = ALAVETELI_HOME/config/exim.filter + system_filter_user = ALAVETELI_USER + +And then create a filter file at `ALAVETELI_HOME/config/exim.filter`, with +something like: + + if error_message then finish endif + if $header_to: contains "mydomain.org" + then + unseen deliver "backup@mybackupdomain.org" + endif + + if $sender_address: contains "mydomain.org" + then + unseen deliver "backup@mybackupdomain.org" + endif + diff --git a/running/states.md b/running/states.md new file mode 100644 index 000000000..ccc01df20 --- /dev/null +++ b/running/states.md @@ -0,0 +1,214 @@ +--- +layout: page +title: States of requests +--- + +# States of requests + +<p class="lead"> + A <a href="{{site.baseurl}}glossary/#request" class="glossary">request</a> + passes through different <strong>states</strong> as it is processed. These may + vary from one jurisdiction to another. +</p> + +The request states are defined in the Alaveteli code, and we recommend you use +them (provided they match the <a href="{{ site.baseurl }}glossary/#foi" +class="glossary">FOI law</a> in your own jurisdiction). But if you do need to +customise them, you can — see +<a href="{{ site.baseurl }}customising/themes">Customising the request states</a> for details. + +## WhatDoTheyKnow example + +Requests made on the UK's Alaveteli instance, [WhatDoTheyKnow](http://www.whatdotheyknow.com), may be in any of the following states +(for comparison, Kosovo's instance uses +[slightly different states]({{ site.baseurl }}running/states_informatazyrtare)): + +### States + +<ul class="definitions"> + <li><a href="#waiting_response">waiting_response</a></li> + <li><a href="#waiting_classification">waiting_classification</a></li> + <li><a href="#waiting_response_overdue">waiting_response_overdue</a></li> + <li><a href="#waiting_response_very_overdue">waiting_response_very_overdue</a></li> + <li><a href="#waiting_clarification">waiting_clarification</a></li> + <li><a href="#gone_postal">gone_postal</a></li> + <li><a href="#not_held">not_held</a></li> + <li><a href="#rejected">rejected</a></li> + <li><a href="#successful">successful</a></li> + <li><a href="#partially_successful">partially_successful</a></li> + <li><a href="#internal_review">internal_review</a></li> + <li><a href="#error_message">error_message</a></li> + <li><a href="#requires_admin">requires_admin</a></li> + <li><a href="#user_withdrawn">user_withdrawn</a></li> + <li><a href="#awaiting_description">awaiting_description</a></li> +</ul> + + +<dl class="glossary"> + + <dt> + <a name="waiting_response">waiting_response</a> + </dt> + <dd> + Waiting for the public authority to reply + <ul> + <li>The default initial state</li> + <li>Can't transition here from internal_review</li> + </ul> + </dd> + + <dt> + <a name="waiting_classification">waiting_classification</a> + </dt> + <dd> + Waiting for a classification of a response + <ul> + <li>The default state after receiving a response</li> + </ul> + </dd> + + <dt> + <a name="waiting_response_overdue">waiting_response_overdue</a> + </dt> + <dd> + Waiting for a reply for too long + <ul> + <li>Automatic, if today's date is after the request date + holidays + 20 days</li> + <li>When a user updates / visits an item in this state, thank user and tell them how long they should have to wait</li> + <li>Alert user by email when something becomes overdue</li> + </ul> + </dd> + + <dt> + <a name="waiting_response_very_overdue">waiting_response_very_overdue</a> + </dt> + <dd> + Waiting for a reply for a very long time + <ul> + <li>Automatic, if today's date is after the request date + holidays + (60 days (for schools) or 40 days (everyone else))</li> + <li>When a user updates / visits something in this state, suggest they might want to complain about it; show things they might want to do</li> + <li>Alert user by email when this state happens</li> + </ul> + </dd> + + <dt> + <a name="waiting_clarification">waiting_clarification</a> + </dt> + <dd> + The public authority would like part of the request explained + <ul> + <li>Prompt user to write followup</li> + <li>if a user sends an outgoing message on a request in this state, automatically transitions to {{waiting_response}}</li> + <li>three days after this state change occurs, send reminder to user to action it (assuming user isn't banned)</li> + <li>Can't transition here from internal_review</li> + </ul> + </dd> + + <dt> + <a name="gone_postal">gone_postal</a> + </dt> + <dd> + The public authority would like to / has responded by post + <ul> + <li>If selected, remind user that in most cases authority should respond by email, and encourage followup.</li> + <li>Give most recent authority correspondence email address for user to request postal by private email.</li> + <li>Encourage user to update thread with annotation at later date.</li> + </ul> + </dd> + + <dt> + <a name="not_held">not_held</a> + </dt> + <dd> + The public authority does not have the information requested + <ul> + <li>Suggest user might want to try a different authority, or complain</li> + </ul> + </dd> + + <dt> + <a name="rejected">rejected</a> + </dt> + <dd> + The request was refused by the public authority + <ul> + <li>Show page of possible next steps</li> + </ul> + </dd> + + + <dt> + <a name="successful">successful</a> + </dt> + <dd> + All of the information requested has been received + <ul> + <li>Suggest they add annotations or make a donation</li> + </ul> + </dd> + + + <dt> + <a name="partially_successful">partially_successful</a> + </dt> + <dd> + Some of the information requested has been received + <ul> + <li>Suggest they make a donation; give ideas what to do next</li> + </ul> + </dd> + + <dt> + <a name="internal_review">internal_review</a> + </dt> + <dd> + Waiting for the public authority to complete an internal review of their handling of the request + <ul> + <li>Tell user they should expect a response within 20 days</li> + <li>When sends email to authority, adds “Internal review of” to Subject</li> + <li>Can be transitioned from the followup form</li> + </ul> + </dd> + + <dt> + <a name="error_message">error_message</a> + </dt> + <dd> + Received an error message, such as delivery failure. + <ul> + <li>Thank user for reporting, and suggest they use a form to give new email address for authority if that was the problem</li> + <li>Mark as needs admin attention</li> + </ul> + </dd> + + <dt> + <a name="requires_admin">requires_admin</a> + </dt> + <dd> + A strange reponse, required attention by the WhatDoTheyKnow team + <ul> + <li>a user is confused and doesn't know what state to set, so an admin can intervene</li> + <li>Redirect to form to ask for more information</li> + <li>Mark as needs admin attention</li> + </ul> + </dd> + + <dt> + <a name="user_withdrawn">user_withdrawn</a> + </dt> + <dd> + The requester has abandoned this request for som e reason + <ul> + <li>Prompt user to write message to tell authority</li> + </ul> + </dd> + + <dt> + <a name="awaiting_description">awaiting_description</a> + </dt> + <dd> + This state, awaiting_description, is not really a state but a flag indicating that there is no state. + </dd> + +</dl> + diff --git a/running/states_informatazyrtare.md b/running/states_informatazyrtare.md new file mode 100644 index 000000000..a799358ed --- /dev/null +++ b/running/states_informatazyrtare.md @@ -0,0 +1,217 @@ +--- +layout: page +title: States of requests (InformataZyrtare) +--- + +# States of requests + +<p class="lead"> + A <a href="{{site.baseurl}}glossary/#request" class="glossary">request</a> + passes through different <strong>states</strong> as it is processed. These may + vary from one jurisdiction to another. +</p> + +The request states are defined in the Alaveteli code, and we recommend you use +them (provided they match the <a href="{{ site.baseurl }}glossary/#foi" +class="glossary">FOI law</a> in your own jurisdiction). But if you do need to +customise them, you can — see +<a href="{{ site.baseurl }}customising/themes">Customising the request states</a> for details. + +## InformataZyrtare.org (Kosovo) example + +Requests made on Kosovo's Alaveteli instance, [InformataZyrtare](http://informatazyrtare.org), may be in any of the following states +(for comparison, the UK's instance uses +[slightly different states]({{ site.baseurl }}running/states)): + +### States + +<ul class="definitions"> + <li><a href="#waiting_response">waiting_response</a></li> + <li><a href="#waiting_classification">waiting_classification</a></li> + <li><a href="#waiting_response_overdue">waiting_response_overdue</a></li> + <li><a href="#waiting_clarification">waiting_clarification</a></li> + <li><a href="#not_held">not_held</a></li> + <li><a href="#rejected">rejected</a></li> + <li><a href="#successful">successful</a></li> + <li><a href="#partially_successful">partially_successful</a></li> + <li><a href="#error_message">error_message</a></li> + <li><a href="#requires_admin">requires_admin</a></li> + <li><a href="#deadline_extended">deadline_extended</a></li> + <li><a href="#partial_rejected">partial_rejected</a></li> + <li><a href="#wrong_response">wrong_response</a></li> +</ul> + + +<dl class="glossary"> + + <dt> + <a name="waiting_response">waiting_response</a> + </dt> + <dd> + Waiting for the public authority to reply + <ul> + <li>The default initial state</li> + <li>Can't transition here from internal_review</li> + </ul> + </dd> + + <dt> + <a name="waiting_classification">waiting_classification</a> + </dt> + <dd> + <ul> + <li>The default state after receiving a response</li> + </ul> + </dd> + + <dt> + <a name="waiting_response_overdue">waiting_response_overdue</a> + </dt> + <dd> + Waiting for a reply for too long + <ul> + <li>Automatic, if today's date is after the request date + holidays + 20 days</li> + <li>When a user updates / visits an item in this state, thank user and tell them how long they should have to wait</li> + <li>Alert user by email when something becomes overdue</li> + </ul> + </dd> + + <dt> + <a name="waiting_clarification">waiting_clarification</a> + </dt> + <dd> + The public authority would like part of the request explained + <ul> + <li>Prompt user to write followup</li> + <li>If a user sends an outgoing message on a request in this state, automatically transitions to {{waiting_response}}</li> + <li>Three days after this state change occurs, send reminder to user to action it (assuming user isn't banned)</li> + <li>Can't transition here from internal_review</li> + </ul> + </dd> + + <dt> + <a name="not_held">not_held</a> + </dt> + <dd> + The public authority does not have the information requested + <ul> + <li>Suggest user might want to try a different authority, or complain</li> + </ul> + </dd> + + <dt> + <a name="rejected">rejected</a> + </dt> + <dd> + The request was refused by the public authority + <ul> + <li>Show page of possible next steps</li> + </ul> + </dd> + + <dt> + <a name="successful">successful</a> + </dt> + <dd> + All of the information requested has been received + <ul> + <li>Suggest they add annotations or make a donation </li> + </ul> + </dd> + + <dt> + <a name="partially_successful">partially_successful</a> + </dt> + <dd> + Some of the information requested has been received + <ul> + <li>Suggest they make a donation; give ideas what to do next</li> + </ul> + </dd> + + <dt> + <a name="error_message">error_message</a> + </dt> + <dd> + Received an error message, such as delivery failure. + <ul> + <li>Thank user for reporting, and suggest they use a form to give new email address for authority if that was the problem</li> + <li>Mark as needs admin attention</li> + </ul> + </dd> + + <dt> + <a name="requires_admin">requires_admin</a> + </dt> + <dd> + A strange response, required attention by the InformataZyrtare team + <ul> + <li>A user is confused and doesn't know what state to set, so an admin can intervene </li> + <li>Redirect to form to ask for more information </li> + <li>Mark as needs admin attention</li> + </ul> + </dd> + + <dt> + <a name="deadline_extended">deadline_extended</a> + </dt> + <dd> + <ul> + <li>If the Authority has requested deadline extension.</li> + </ul> + </dd> + + <dt> + <a name="partial_rejected">partial_rejected</a> <em>TBD</em> + </dt> + <dd> + Only part of the request has being refused but the successful request to an information has not been attached + </ul> + </dd> + + <dt> + <a name="wrong_response">wrong_response</a> + </dt> + <dd> + Authority has replied but the response does not correspond to the request + </dd> +</dl> + +<!-- + TODO: muckrock's states here? + +# MuckRock.com + +US FOI site MuckRock.com uses the following states: + +**Draft** +Unfinished request + +**Processing** +The MuckRock team are currently reviewing the request to decide what to do with it. + +This is necessary because a lot of requests have to be mailed or faxed or have signatures, etc. The system requires quite a lot of manual intervention. Over time the plan is to automate more, but this state will still be required at a minimum to indicate that MuckRock is the holdup, not the requester or the agency. + +**Awaiting Response** +Request sent, no reply received yet + +**Fix Required** +If the authority or a MuckRock admin thinks that user needs to clarify or otherwise "fix" the request + +**Payment Required** +In the US, an authority can ask a user to make a payment to cover the costs of the request + +**Rejected** +Request rejected + +**No responsive documents** +Information not held + +**Completed** +Successfully finished request + +**Partially Completed** +Finished request, partly successful + +--> + diff --git a/theme b/theme new file mode 160000 +Subproject 74896339b100b0e1093c598e00d9d2052575675 |