Commit 1662f54b authored by Pietro Albini's avatar Pietro Albini

Merge branch 'master' into derivate

parents 9169ee8a 0cfce749
...@@ -136,17 +136,12 @@ Per eseguire il sito in locale, è possibile eseguire questo comando (una volta ...@@ -136,17 +136,12 @@ Per eseguire il sito in locale, è possibile eseguire questo comando (una volta
dentro il virtualenv o con il sito installato globalmente): dentro il virtualenv o con il sito installato globalmente):
``` ```
uitwww run -d -p 8000 uitwww run -d -p 8000 data/
``` ```
Esso avvierà un'istanza in debug-mode (*da non eseguire in produzione!!!*), che Esso avvierà un'istanza in debug-mode (*da non eseguire in produzione!!!*), che
ascolta su [localhost:8000][localhost]. Se si vuole attivare anche la cache ascolta su [localhost:8000][localhost], usando `data/` come directory in cui
statica, bisogna aggiungere come argomento il path della directory che la dovrà salvare i file necessari al suo funzionamento.
contenere:
```
uitwww run -d -p 8000 path/to/cache
```
## Generazione di una build ## Generazione di una build
......
// Override default text selection color
::selection {
background: lighten($ubuntu-orange, 10%);
color: #fff;
}
a {
&::selection,
& *::selection {
background: $warm-grey;
color: #fff;
}
}
// Remove unwanted "x"es from search box (webkit and ie)
input[type=text]::-ms-clear { display: none; width: 0; height: 0; }
input[type=text]::-ms-reveal { display: none; width: 0; height: 0; }
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration { display: none; }
// Fix some paddings
div.row {
padding: 40px 40px 20px 40px;
&:last-child {
@extend .no-border;
}
&.row-quote blockquote {
padding-top: 20px;
}
}
div.inner-wrapper {
padding-bottom: 0;
}
a {
color: #dd4814;
}
// Define backgrounds
body {
background-image: url("images/background-paper.png");
&.community-page {
background: url("images/background-dotted.png") repeat scroll 0 0 #F5F6F7;
}
}
header.banner {
margin-bottom: 0;
nav {
overflow: visible !important;
height: 44px;
ul li a {
line-height: 17px;
font-weight: 400 !important;
}
}
nav.nav-primary {
ul li a {
border-left: 1px solid lighten($ubuntu-orange, 10%) !important;
&:hover {
background: #e1662f !important;
}
&:active, &.active {
background: #b83a10 !important;
}
}
div.logo {
top: 0;
height: 44px;
margin-left: 0;
a {
font-size: 1.4em;
font-weight: 500;
color: #fff;
&:hover, &:active, &:focus {
text-decoration: none;
}
}
}
}
&.inverted {
background: $light-grey;
margin-bottom: 20px;
z-index: 0 !important;
nav {
height: 45px;
}
.nav-primary {
ul {
border-color: lighten($light-grey, 10%);
margin-top: 1px;
li {
&, &:last-child {
border-color: darken($light-grey, 5%);
}
a {
&:link,
&:visited {
border-color: lighten($light-grey, 7%) !important;
color: darken($warm-grey, 10%);
}
&:hover {
background: #fff !important;
color: lighten($cool-grey, 7%) !important;
}
}
}
}
a.active, a:active {
border-color:darken($light-grey, 5%);
background:darken($light-grey, 5%) !important;
}
}
}
}
div.logo {
overflow: visible !important;
div.website-selector {
position: absolute;
display: none;
width: 250px;
z-index: 3;
top: 44px;
left: -30px;
background: rgba(0, 0, 0, 0);
ol {
padding: 0.4em 0;
width: 100%;
background: #fff;
border: 1px solid #d5d5d5;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
font-size: 15px !important;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
li {
margin: 0;
font-size: 15px;
padding: 0 1.2em;
a {
width: 100%;
display: block;
padding: 0.3em 0;
color: #333 !important;
font-size: 15px !important;
&:hover, &.active {
color: #dd4814 !important;
}
}
&.website-selector-footer {
text-align: center;
a.social {
background-image: url("images/common/social.png");
height: 18px;
width: 18px;
padding: 0;
margin: 10px 6px;
display: inline-block;
&.facebook {
background-position: 0 0;
&:hover {
background-position: 0 36px;
}
}
&.twitter {
background-position: 54px 0;
&:hover {
background-position: 54px 36px;
}
}
&.gplus {
background-position: 36px 0;
&:hover {
background-position: 36px 36px;
}
}
&.youtube {
background-position: 18px 0;
&:hover {
background-position: 18px 36px;
}
}
}
}
}
&:before {
height: 10px;
width: 100%;
background: #000;
}
}
}
&:hover div.website-selector {
display: block;
}
}
nav.nav-secondary {
border-left: none;
border-right: none;
border-color: #dfdcd9;
ul {
li a {
margin-top: 8px;
&.active {
color: #dd4814 !important;
font-weight: 300 !important;
}
}
&.breadcrumb li {
margin: 0;
a.breadcrumb-link {
margin-right: 0 !important;
&:after {
content: "›";
margin-left: 3px;
}
}
}
}
}
nav.nav-footer {
width: 984px;
margin: auto;
display: flex;
& > div {
flex: 1;
padding: 0 10px;
border-left: 1px dotted #333;
h2 {
padding-bottom: 0;
}
ul li {
margin-bottom: 0;
line-height: 17px;
a {
font-size: 0.75em;
color: #333;
}
}
&:first-child {
padding-left: 0;
border-left: 0;
}
&:last-child {
padding-right: 0;
}
}
}
footer {
background: #ececec !important;
hr {
border: 0;
border-bottom: 1px solid #d8d8d8;
margin: 1.5em 0;
}
}
// Responsiveness
@media all and (max-width: $site-max-width) {
div.wrapper {
width: 100% !important;
}
}
.inner-wrapper {
box-shadow: 0 2px 3px #c9c9c9;
}
// A bit of style for buttons
a.button--primary, a.button--secondary {
margin: 0 0 0.75em 0;
font-size: 1.1em;
padding: 8px 17px !important;
border-radius: 3px;
}
// Import Vanilla Framework // Import Vanilla Framework
@import "../../node_modules/vanilla-framework/scss/build.scss"; @import "../../node_modules/ubuntuit-vanilla-theme/scss/theme";
@import "../../node_modules/ubuntu-vanilla-theme/scss/theme"; @include ubuntuit-vanilla-theme;
@include ubuntu-vanilla-theme;
// Import backports from web-style-guide // Import backports from web-style-guide
@import "wsg-backports.scss"; @import "wsg-backports.scss";
// Import Ubuntu-it common customizations
@import "ubuntuit.scss";
// Import Ubuntu-it website's customizations // Import Ubuntu-it website's customizations
@import "www.scss"; @import "www.scss";
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
"gulp-postcss": "~5.1.8", "gulp-postcss": "~5.1.8",
"gulp": "~3.9.0", "gulp": "~3.9.0",
"autoprefixer": "~5.2.0", "autoprefixer": "~5.2.0",
"vanilla-framework": "0.0.50", "ubuntuit-vanilla-theme": "git+http://code.ubuntu-it.org/ubuntu-it-web/ubuntuit-vanilla-theme.git",
"ubuntu-vanilla-theme": "0.0.7",
"gulp-concat": "~2.6.0", "gulp-concat": "~2.6.0",
"gulp-uglify": "~1.2.0", "gulp-uglify": "~1.2.0",
"gulp-sass": "~2.1.0" "gulp-sass": "~2.1.0"
......
wheel==0.26.0 wheel==0.26.0
setuptools==19.4
...@@ -27,6 +27,12 @@ PYTHON = "python3" ...@@ -27,6 +27,12 @@ PYTHON = "python3"
PROJECT = "uitwww" PROJECT = "uitwww"
# This is because invoke can't keep backward compatibility...
_invoke_v = invoke.__version__.split(".")
if int(_invoke_v[0]) == 0 and int(_invoke_v[1]) <= 12:
invoke.task = invoke.ctask
def create_env(name, requirements=False, self=False, force=False): def create_env(name, requirements=False, self=False, force=False):
"""Create a new virtual environment""" """Create a new virtual environment"""
path = os.path.join(BASE, "build", "envs", name) path = os.path.join(BASE, "build", "envs", name)
...@@ -48,7 +54,7 @@ def create_env(name, requirements=False, self=False, force=False): ...@@ -48,7 +54,7 @@ def create_env(name, requirements=False, self=False, force=False):
@invoke.task @invoke.task
def clean(): def clean(ctx):
"""Clean all the build things""" """Clean all the build things"""
for dir in "build", "%s.egg-info" % PROJECT: for dir in "build", "%s.egg-info" % PROJECT:
path = os.path.join(BASE, dir) path = os.path.join(BASE, dir)
...@@ -104,7 +110,7 @@ def clean(): ...@@ -104,7 +110,7 @@ def clean():
@invoke.task @invoke.task
def assets(watch=False): def assets(ctx, watch=False):
"""Build the assets""" """Build the assets"""
node_bin = "%s/node_modules/.bin" % BASE node_bin = "%s/node_modules/.bin" % BASE
...@@ -122,13 +128,13 @@ def assets(watch=False): ...@@ -122,13 +128,13 @@ def assets(watch=False):
@invoke.task(pre=[assets]) @invoke.task(pre=[assets])
def devel(): def devel(ctx):
"""Setup the development environment""" """Setup the development environment"""
create_env("devel", self=True, force=True) create_env("devel", self=True, force=True)
@invoke.task(pre=[assets]) @invoke.task(pre=[assets])
def build(): def build(ctx):
"""Create a new build""" """Create a new build"""
env = create_env("build", requirements=True) env = create_env("build", requirements=True)
......
# Source code of the Ubuntu-it website # Source code of the Ubuntu-it website
# Copyright (C) 2015 Pietro Albini <pietroalbini@ubuntu.com> # Copyright (C) 2015-2016 Pietro Albini <pietroalbini@ubuntu.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published # it under the terms of the GNU Affero General Public License as published
...@@ -14,21 +14,47 @@ ...@@ -14,21 +14,47 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import flask import flask
from uitwww import pages from . import pages
from . import cache
def create_app(cache_path=None): def create_app(data_path):
"""Create a new instance of the application""" """Create a new instance of the application"""
app = flask.Flask(__name__, static_url_path="/+assets") app = flask.Flask(__name__, static_url_path="/+assets")
app.config["DATA_PATH"] = data_path
# Apply the static cache thing app.config["CACHE_PATH"] = os.path.join(data_path, "cache")
if cache_path is not None:
app.config["CACHE_PATH"] = cache_path
cache.install_cache(app) cache.install_cache(app)
app.register_blueprint(pages.prepare_blueprint(app)) app.register_blueprint(pages.prepare_blueprint(app))
pages.prepare_navbar(app) pages.prepare_navbar(app)
@app.errorhandler(404)
def not_found(error):
return flask.render_template("404.html")
return app return app
def init_data_directory(data_path):
"""Initialize the data directory"""
src_directory = os.path.dirname(os.path.abspath(__file__))
# Create all the directories
dirs = ["", "cache"]
for dir in dirs:
os.makedirs(os.path.join(data_path, dir), exist_ok=True)
# Initialize the cache
static_dirs = {"static": "+assets"}
for src, dest in static_dirs.items():
dest = os.path.join(data_path, "cache", dest)
# Create the correct symlink
if os.path.exists(dest):
os.remove(dest)
os.symlink(os.path.join(src_directory, src), dest)
# Source code of the Ubuntu-it website # Source code of the Ubuntu-it website
# Copyright (C) 2015 Pietro Albini <pietroalbini@ubuntu.com> # Copyright (C) 2015-2016 Pietro Albini <pietroalbini@ubuntu.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published # it under the terms of the GNU Affero General Public License as published
...@@ -29,16 +29,20 @@ def cli(): ...@@ -29,16 +29,20 @@ def cli():
@cli.command("run") @cli.command("run")
@click.argument("cache", required=False, default=None) @click.argument("data")
@click.option("-g", "--gunicorn-config", default=None, help="Path to a" @click.option("-g", "--gunicorn-config", default=None, help="Path to a"
"gunicorn config file") "gunicorn config file")
@click.option("-p", "--port", default=8000, help="Bind that port") @click.option("-p", "--port", default=8000, help="Bind that port")
@click.option("--public", help="Make available to the public", is_flag=True) @click.option("--public", help="Make available to the public", is_flag=True)
@click.option("-w", "--workers", help="Number of workers to start", default=3) @click.option("-w", "--workers", help="Number of workers to start", default=3)
@click.option("-d", "--debug", help="Enable debug mode", is_flag=True) @click.option("-d", "--debug", help="Enable debug mode", is_flag=True)
def run(cache, gunicorn_config, port, public, workers, debug): def run(data, gunicorn_config, port, public, workers, debug):
# Create the application instance # Create the application instance
app = uitwww.create_app(cache) src_directory = os.path.dirname(os.path.abspath(__file__))
uitwww.init_data_directory(data)
app = uitwww.create_app(data)
app.wsgi_app = utils.ReverseProxied(app.wsgi_app) app.wsgi_app = utils.ReverseProxied(app.wsgi_app)
host = "127.0.0.1" host = "127.0.0.1"
...@@ -48,7 +52,7 @@ def run(cache, gunicorn_config, port, public, workers, debug): ...@@ -48,7 +52,7 @@ def run(cache, gunicorn_config, port, public, workers, debug):
# In debug mode, run the flask builtin webserver # In debug mode, run the flask builtin webserver
if debug: if debug:
extra_files = [ extra_files = [
os.path.join(os.path.dirname(__file__), "navbar.json"), os.path.join(src_directory, "navbar.json"),
] ]
app.run(debug=True, port=port, host=host, extra_files=extra_files) app.run(debug=True, port=port, host=host, extra_files=extra_files)
......
# Source code of the Ubuntu-it website # Source code of the Ubuntu-it website
# Copyright (C) 2015 Pietro Albini <pietroalbini@ubuntu.com> # Copyright (C) 2015-2016 Pietro Albini <pietroalbini@ubuntu.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published # it under the terms of the GNU Affero General Public License as published
...@@ -29,7 +29,7 @@ def enable(func): ...@@ -29,7 +29,7 @@ def enable(func):
def remove(path, recursive=False): def remove(path, recursive=False):
"""Remove a path from the cache""" """Remove a path from the cache"""
app = flask.current_app app = flask.current_app
path = os.path.join(app.cache_path, path) path = os.path.join(app.config["CACHE_PATH"], path)
try: try:
if os.path.isdir(path): if os.path.isdir(path):
...@@ -45,6 +45,10 @@ def remove(path, recursive=False): ...@@ -45,6 +45,10 @@ def remove(path, recursive=False):
def after_request(response): def after_request(response):
"""Hook meant to be executed after a request""" """Hook meant to be executed after a request"""
# Don't do anything if the page hasn't an endpoint
if flask.request.endpoint is None:
return response
app = flask.current_app app = flask.current_app
# Get the function for the current app # Get the function for the current app
...@@ -66,11 +70,11 @@ def after_request(response): ...@@ -66,11 +70,11 @@ def after_request(response):
if status != 200 or method != "GET": if status != 200 or method != "GET":
return result return result
# Normalize the page url
if url.endswith("/"): if url.endswith("/"):
url += "index.html" url += "index.html"
else: elif "." not in url:
url += ".html" url += ".html"
if url.startswith("/"): if url.startswith("/"):
url = url[1:] # Remove / at the start url = url[1:] # Remove / at the start
...@@ -82,13 +86,6 @@ def after_request(response): ...@@ -82,13 +86,6 @@ def after_request(response):
return response return response
def before_request():
"""Hook meant to be executed before a request"""
# TODO: implement the cache
pass
def install_cache(app): def install_cache(app):
"""Install the cache on a specific app""" """Install the cache on a specific app"""
app.before_request(before_request)
app.after_request(after_request) app.after_request(after_request)
{# Source code of the Ubuntu-it website
# Copyright (C) 2016 Pietro Albini <pietroalbini@ubuntu.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; witout even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "layout.html" %}
{% block title %} Pagina non trovata {% endblock %}
{% block content %}
<div class="row row-hero">
<div class="twelve-col">
<h2>Questa pagina non esiste</h2>
<p>
Beh, ovviamente <i>questa</i> pagina esiste. Ma la pagina che hai
richiesto non esiste. Infatti, questa pagina è qui solo per dirti
che la pagina che stai cercando non esiste.
</p>
<p>
Se questa pagina esisteva in passato e non la trovi più
<a href="http://forum.ubuntu-it.org/viewforum.php?f=45&sid=855a03444972c626fb2d486b42d05469">
segnalacelo
</a> che provvederemo a sistemare il prima possibile!
</p>
</div>
</div>
{% endblock %}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment