on master help sign in
New Theme, Pix-art.

First commit

commitd740e7384a95c6a7d80e5f492f4dd7edb312175e authorCqoicebordel <Cqoicebordel@users.noreply.github.com> dateSun 15 Feb 2015, 19:09 (12 years ago) parent3ff269c
22 files changed+1182
Makefile+1 searx/static/themes/pix-art/css/style.css+1 searx/static/themes/pix-art/img/favicon.png searx/static/themes/pix-art/img/preference-icon-pixel.png searx/static/themes/pix-art/img/search-icon-pixel.png searx/static/themes/pix-art/img/searx-pixel.png searx/static/themes/pix-art/img/searx_logo.svg+203 searx/static/themes/pix-art/js/searx.js+49 searx/static/themes/pix-art/less/definitions.less+119 searx/static/themes/pix-art/less/mixins.less+27 searx/static/themes/pix-art/less/search.less+56 searx/static/themes/pix-art/less/style.less+438 searx/templates/pix-art/about.html+65 searx/templates/pix-art/base.html+28 searx/templates/pix-art/index.html+12 searx/templates/pix-art/preferences.html+82 searx/templates/pix-art/result_templates/default.html+13 searx/templates/pix-art/result_templates/images.html+6 searx/templates/pix-art/results.html+44 searx/templates/pix-art/search.html+9 searx/templates/pix-art/stats.html+22 searx/webapp.py+7
Makefile+1
@@ -51,6 +51,7 @@ styles:
5151 @lessc -x searx/static/themes/courgette/less/style-rtl.less > searx/static/themes/courgette/css/style-rtl.css
5252 @lessc -x searx/static/less/bootstrap/bootstrap.less > searx/static/css/bootstrap.min.css
5353 @lessc -x searx/static/themes/oscar/less/oscar/oscar.less > searx/static/themes/oscar/css/oscar.min.css
54+ @lessc -x searx/static/themes/pix-art/less/style.less > searx/static/themes/pix-art/css/style.css
5455
5556grunt:
5657 @grunt --gruntfile searx/static/themes/oscar/gruntfile.js
searx/static/themes/pix-art/css/style.cssnew file+1
@@ -0,0 +1 @@
1+html{font-family:sans-serif;font-size:.9em;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;color:#444;padding:0;margin:0}body,#container{padding:0;margin:0}canvas{image-rendering:optimizeSpeed;image-rendering:-moz-crisp-edges;image-rendering:-webkit-optimize-contrast;image-rendering:optimize-contrast;image-rendering:pixelated;-ms-interpolation-mode:nearest-neighbor;width:32px;height:32px}#container{width:100%;position:absolute;top:0}.search{padding:0;margin:0}#search_wrapper{position:relative;width:50em;padding:10px}.center #search_wrapper{margin-left:auto;margin-right:auto}.q{background:none repeat scroll 0 0 #fff;border:1px solid #3498db;color:#222;font-size:16px;height:28px;margin:0;outline:medium none;padding:2px;padding-left:8px;padding-right:0 !important;width:100%;z-index:2}#search_submit{position:absolute;top:13px;right:1px;padding:0;border:0;background:url('../img/search-icon-pixel2.png') no-repeat;background-size:24px 24px;opacity:.8;width:24px;height:30px;font-size:0}@media screen and (max-width:50em){#search_wrapper{width:90%;clear:both;overflow:hidden}}.row{max-width:800px;margin:20px auto;text-align:justify}.row h1{font-size:3em;margin-top:50px}.row p{padding:0 10px;max-width:700px}.row h3,.row ul{margin:4px 8px}.hmarg{margin:0 20px;border:1px solid #3498db;padding:4px 10px}a:link.hmarg{color:#3498db}a:visited.hmarg{color:#3498db}a:active.hmarg{color:#3498db}a:hover.hmarg{color:#3498db}.top_margin{margin-top:60px}.center{text-align:center}h1{font-size:5em}div.title{background:url('../img/searx-pixel.png') no-repeat;width:100%;min-height:80px;background-position:center}div.title h1{visibility:hidden}input[type="submit"]{padding:2px 6px;margin:2px 4px;display:inline-block;background:#3498db;color:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border:0;cursor:pointer}input[type="checkbox"]{visibility:hidden}fieldset{margin:8px;border:1px solid #3498db}#categories{margin:0 10px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox_container{display:inline-block;position:relative;margin:0 3px;padding:0}.checkbox_container input{display:none}.checkbox_container label,.engine_checkbox label{cursor:pointer;padding:4px 10px;margin:0;display:block;text-transform:capitalize;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox_container input[type="checkbox"]:checked+label{background:#3498db;color:#fff}.engine_checkbox{padding:4px}label.allow{background:#e74c3c;padding:4px 8px;color:#fff;display:none}label.deny{background:#2ecc71;padding:4px 8px;color:#444;display:inline}.engine_checkbox input[type="checkbox"]:checked+label:nth-child(2)+label{display:none}.engine_checkbox input[type="checkbox"]:checked+label.allow{display:inline}a{text-decoration:none;color:#1a11be}a:visited{color:#8e44ad}.engines{color:#888}.small_font{font-size:.8em}.small p{margin:2px 0}.right{float:right}.invisible{display:none}.left{float:left}.highlight{color:#094089}.content .highlight{color:#000}.percentage{position:relative;width:300px}.percentage div{background:#444}table{width:100%}td{padding:0 4px}tr:hover{background:#ddd}#results{margin:auto;padding:0;width:50em;margin-bottom:20px}#search_url{margin-top:8px}#search_url input{border:1px solid #888;padding:4px;color:#444;width:14em;display:block;margin:4px;font-size:.8em}#preferences{top:10px;padding:0;border:0;background:url('../img/preference-icon-pixel.png') no-repeat;background-size:28px 28px;opacity:.8;width:28px;height:30px;display:block}#preferences *{display:none}#pagination{clear:both}#pagination br{clear:both}#apis{margin-top:8px;clear:both}#categories_container{position:relative}@media screen and (max-width:50em){#results{margin:auto;padding:0;width:90%}.checkbox_container{display:block;width:90%}.checkbox_container label{border-bottom:0}.preferences_container{display:none;postion:fixed !important;top:100px;right:0}}@media screen and (max-width:75em){div.title h1{font-size:1em}html.touch #categories{width:95%;height:30px;text-align:left;overflow-x:scroll;overflow-y:hidden;-webkit-overflow-scrolling:touch}html.touch #categories #categories_container{width:1000px;width:-moz-max-content;width:-webkit-max-content;width:max-content}html.touch #categories #categories_container .checkbox_container{display:inline-block;width:auto}#categories{font-size:90%;clear:both}#categories .checkbox_container{margin-top:2px;margin:auto}#categories{font-size:90%;clear:both}#categories .checkbox_container{margin-top:2px;margin:auto}#apis{display:none}#search_url{display:none}}.favicon{float:left;margin-right:4px;margin-top:2px}.preferences_back{background:none repeat scroll 0 0 #3498db;border:0 none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;cursor:pointer;display:inline-block;margin:2px 4px;padding:4px 6px}.preferences_back a{color:#fff}.hidden{opacity:0;overflow:hidden;font-size:.8em;position:absolute;bottom:-20px;width:100%;text-position:center;background:white;transition:opacity 1s ease}#categories_container:hover .hidden{transition:opacity 1s ease;opacity:.8}
searx/static/themes/pix-art/img/favicon.pngnew file

Binary file not shown.

searx/static/themes/pix-art/img/preference-icon-pixel.pngnew file

Binary file not shown.

searx/static/themes/pix-art/img/search-icon-pixel.pngnew file

Binary file not shown.

searx/static/themes/pix-art/img/searx-pixel.pngnew file

Binary file not shown.

searx/static/themes/pix-art/img/searx_logo.svgnew file+203
@@ -0,0 +1,203 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+
4+<svg
5+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6+ xmlns:cc="http://creativecommons.org/ns#"
7+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8+ xmlns:svg="http://www.w3.org/2000/svg"
9+ xmlns="http://www.w3.org/2000/svg"
10+ xmlns:xlink="http://www.w3.org/1999/xlink"
11+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13+ width="744.09448819"
14+ height="1052.3622047"
15+ id="svg2"
16+ version="1.1"
17+ inkscape:version="0.48.4 r9939"
18+ sodipodi:docname="searx_logo.svg"
19+ inkscape:export-filename="/home/a/magnif.png"
20+ inkscape:export-xdpi="203.1774"
21+ inkscape:export-ydpi="203.1774">
22+ <defs
23+ id="defs4">
24+ <linearGradient
25+ inkscape:collect="always"
26+ id="linearGradient3857">
27+ <stop
28+ style="stop-color:#ffffff;stop-opacity:1;"
29+ offset="0"
30+ id="stop3859" />
31+ <stop
32+ style="stop-color:#ffffff;stop-opacity:0;"
33+ offset="1"
34+ id="stop3861" />
35+ </linearGradient>
36+ <linearGradient
37+ id="linearGradient3790">
38+ <stop
39+ style="stop-color:#a9a9a9;stop-opacity:1;"
40+ offset="0"
41+ id="stop3792" />
42+ <stop
43+ style="stop-color:#000000;stop-opacity:1;"
44+ offset="1"
45+ id="stop3794" />
46+ </linearGradient>
47+ <radialGradient
48+ inkscape:collect="always"
49+ xlink:href="#linearGradient3790"
50+ id="radialGradient3798"
51+ cx="294.45947"
52+ cy="208.37973"
53+ fx="294.45947"
54+ fy="208.37973"
55+ r="107.58125"
56+ gradientUnits="userSpaceOnUse" />
57+ <linearGradient
58+ inkscape:collect="always"
59+ xlink:href="#linearGradient3857"
60+ id="linearGradient3865"
61+ x1="120.68947"
62+ y1="239.61774"
63+ x2="120.68947"
64+ y2="602.17517"
65+ gradientUnits="userSpaceOnUse" />
66+ <linearGradient
67+ inkscape:collect="always"
68+ xlink:href="#linearGradient3790"
69+ id="linearGradient3912"
70+ x1="186.74416"
71+ y1="354.42426"
72+ x2="255.84358"
73+ y2="254.35953"
74+ gradientUnits="userSpaceOnUse"
75+ gradientTransform="matrix(1.2227304,0,0,0.89945099,-289.31433,113.40259)" />
76+ <filter
77+ inkscape:collect="always"
78+ id="filter4024"
79+ x="-0.12996517"
80+ width="1.2599303"
81+ y="-0.14709377"
82+ height="1.2941875">
83+ <feGaussianBlur
84+ inkscape:collect="always"
85+ stdDeviation="6.4759344"
86+ id="feGaussianBlur4026" />
87+ </filter>
88+ <filter
89+ inkscape:collect="always"
90+ id="filter3983"
91+ x="-1.0608404"
92+ width="3.1216809"
93+ y="-0.31017202"
94+ height="1.620344">
95+ <feGaussianBlur
96+ inkscape:collect="always"
97+ stdDeviation="9.392858"
98+ id="feGaussianBlur3985" />
99+ </filter>
100+ </defs>
101+ <sodipodi:namedview
102+ id="base"
103+ pagecolor="#ffffff"
104+ bordercolor="#666666"
105+ borderopacity="1.0"
106+ inkscape:pageopacity="0.0"
107+ inkscape:pageshadow="2"
108+ inkscape:zoom="1.979899"
109+ inkscape:cx="30.708726"
110+ inkscape:cy="948.08556"
111+ inkscape:document-units="px"
112+ inkscape:current-layer="layer1"
113+ showgrid="false"
114+ inkscape:window-width="1364"
115+ inkscape:window-height="663"
116+ inkscape:window-x="0"
117+ inkscape:window-y="30"
118+ inkscape:window-maximized="0"
119+ showguides="true"
120+ inkscape:guide-bbox="true" />
121+ <metadata
122+ id="metadata7">
123+ <rdf:RDF>
124+ <cc:Work
125+ rdf:about="">
126+ <dc:format>image/svg+xml</dc:format>
127+ <dc:type
128+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
129+ <dc:title />
130+ </cc:Work>
131+ </rdf:RDF>
132+ </metadata>
133+ <g
134+ inkscape:label="Layer 1"
135+ inkscape:groupmode="layer"
136+ id="layer1">
137+ <path
138+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
139+ d="m 70.523181,34.870671 c -7.11959,15.242893 -10.17798,31.779192 -8.22563,48.814566 5.01677,43.774133 41.675309,79.324503 91.536109,95.162893 -6.62576,-22.40752 -5.34093,-44.9362 2.6395,-65.84431 C 108.73618,98.821131 74.828141,70.195435 70.523181,34.870671 z"
140+ id="path3814-0-7"
141+ inkscape:connector-curvature="0" />
142+ <path
143+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
144+ d="m 303.77876,36.21406 c 7.11959,15.242893 10.17798,31.779192 8.22563,48.814566 -5.01677,43.774134 -41.67531,79.324504 -91.53611,95.162894 6.62576,-22.40752 5.34093,-44.9362 -2.6395,-65.84431 47.73698,-14.18269 81.64502,-42.808386 85.94998,-78.13315 z"
145+ id="path3814-0"
146+ inkscape:connector-curvature="0" />
147+ <path
148+ transform="matrix(0.6556593,-0.75505688,0.75505688,0.6556593,0,0)"
149+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
150+ d="m -5.0905523,259.06055 18.4167573,0 c 6.220455,0 11.228257,16.68196 11.228257,37.40349 l 0,172.83701 c 0,20.72153 -5.007802,37.40349 -11.228257,37.40349 l -18.4167573,0 c -6.2204547,0 -11.2282577,-16.68196 -11.2282577,-37.40349 l 0,-172.83701 c 0,-20.72153 5.007803,-37.40349 11.2282577,-37.40349 z"
151+ id="rect3804" />
152+ <path
153+ sodipodi:type="arc"
154+ style="fill:url(#radialGradient3798);fill-opacity:1;fill-rule:nonzero;stroke:none"
155+ id="path2987"
156+ sodipodi:cx="294.45947"
157+ sodipodi:cy="208.37973"
158+ sodipodi:rx="107.58125"
159+ sodipodi:ry="107.58125"
160+ d="m 402.04073,208.37973 a 107.58125,107.58125 0 1 1 -215.16251,0 107.58125,107.58125 0 1 1 215.16251,0 z"
161+ transform="translate(-107.07617,-60.609153)" />
162+ <path
163+ sodipodi:type="arc"
164+ style="fill:url(#linearGradient3865);fill-opacity:1;fill-rule:nonzero;stroke:none"
165+ id="path3757"
166+ sodipodi:cx="131.82491"
167+ sodipodi:cy="299.29346"
168+ sodipodi:rx="101.52033"
169+ sodipodi:ry="101.52033"
170+ d="m 233.34524,299.29346 a 101.52033,101.52033 0 1 1 -203.040667,0 101.52033,101.52033 0 1 1 203.040667,0 z"
171+ transform="matrix(0.76865672,0,0,0.76865672,85.80266,-82.535889)" />
172+ <path
173+ sodipodi:type="arc"
174+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
175+ id="path3800"
176+ sodipodi:cx="183.34268"
177+ sodipodi:cy="156.35687"
178+ sodipodi:rx="27.274118"
179+ sodipodi:ry="27.274118"
180+ d="m 210.6168,156.35687 a 27.274118,27.274118 0 1 1 -54.54824,0 27.274118,27.274118 0 1 1 54.54824,0 z"
181+ transform="translate(5,-7.1428572)" />
182+ <path
183+ sodipodi:type="arc"
184+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
185+ id="path3802"
186+ sodipodi:cx="197.9899"
187+ sodipodi:cy="203.32896"
188+ sodipodi:rx="5.5558391"
189+ sodipodi:ry="5.5558391"
190+ d="m 203.54574,203.32896 a 5.5558391,5.5558391 0 1 1 -11.11168,0 5.5558391,5.5558391 0 1 1 11.11168,0 z"
191+ transform="translate(1.4847712,-63.564549)" />
192+ <rect
193+ style="fill:#ffffff;fill-opacity:0.82211531000000004;fill-rule:nonzero;stroke:none;filter:url(#filter4024)"
194+ id="rect3916"
195+ width="2.2392972"
196+ height="159.43797"
197+ x="19.525793"
198+ y="337.8396"
199+ rx="2.8666623"
200+ ry="9.0007057"
201+ transform="matrix(0.74466525,-0.84318084,0.84318084,0.74466525,-35.543204,-26.349917)" />
202+ </g>
203+</svg>
searx/static/themes/pix-art/js/searx.jsnew file+49
@@ -0,0 +1,49 @@
1+if(searx.autocompleter) {
2+ window.addEvent('domready', function() {
3+ new Autocompleter.Request.JSON('q', '/autocompleter', {
4+ postVar:'q',
5+ postData:{
6+ 'format': 'json'
7+ },
8+ ajaxOptions:{
9+ timeout: 5 // Correct option?
10+ },
11+ 'minLength': 4,
12+ 'selectMode': false,
13+ cache: true,
14+ delay: 300
15+ });
16+ });
17+}
18+
19+(function (w, d) {
20+ 'use strict';
21+ function addListener(el, type, fn) {
22+ if (el.addEventListener) {
23+ el.addEventListener(type, fn, false);
24+ } else {
25+ el.attachEvent('on' + type, fn);
26+ }
27+ }
28+
29+ function placeCursorAtEnd() {
30+ if (this.setSelectionRange) {
31+ var len = this.value.length * 2;
32+ this.setSelectionRange(len, len);
33+ }
34+ }
35+
36+ addListener(w, 'load', function () {
37+ var qinput = d.getElementById('q');
38+ if (qinput !== null && qinput.value === "") {
39+ addListener(qinput, 'focus', placeCursorAtEnd);
40+ qinput.focus();
41+ }
42+ });
43+
44+ if (!!('ontouchstart' in window)) {
45+ document.getElementsByTagName("html")[0].className += " touch";
46+ }
47+
48+})(window, document);
49+
searx/static/themes/pix-art/less/definitions.lessnew file+119
@@ -0,0 +1,119 @@
1+/*
2+ * searx, A privacy-respecting, hackable metasearch engine
3+ *
4+ * To change the colors of the site, simple edit this variables
5+ */
6+
7+/// Basic Colors
8+
9+@color-base: #3498DB;
10+@color-base-dark: #2980B9;
11+@color-base-light: #ECF0F1;
12+@color-highlight: #094089;
13+@color-black: #000000;
14+
15+/// General
16+
17+@color-font: #444;
18+@color-font-light: #888;
19+
20+@color-red: #C0392B;
21+
22+@color-url-font: #1a11be;
23+@color-url-visited-font: #8E44AD;
24+@results-width: 50em;
25+
26+
27+/// Start-Screen
28+
29+// hmarg
30+@color-hmarg-border: @color-base;
31+@color-hmarg-font: @color-base;
32+@color-hmarg-font-hover: @color-base;
33+
34+
35+/// Search-Input
36+
37+@color-search-border: @color-base;
38+@color-search-background: #FFF;
39+@color-search-font: #222;
40+
41+/// Autocompleter
42+
43+@color-autocompleter-choices-background: #FFF;
44+@color-autocompleter-choices-border: @color-base;
45+@color-autocompleter-choices-border-left-right: @color-base;
46+@color-autocompleter-choices-border-bottom: @color-base;
47+
48+@color-autocompleter-choices-font: #444;
49+
50+/// Answers
51+@color-answers-border: @color-base-dark;
52+
53+// Selected
54+@color-autocompleter-selected-background: #444;
55+@color-autocompleter-selected-font: #FFF;
56+@color-autocompleter-selected-queried-font: #9FCFFF;
57+
58+/// Categories
59+
60+@color-categories-item-selected: @color-base;
61+@color-categories-item-selected-font: #FFF;
62+
63+@color-categories-item-border-selected: @color-base-dark;
64+@color-categories-item-border-unselected: #E8E7E6;
65+@color-categories-item-border-unselected-hover: @color-base;
66+
67+
68+/// Results
69+
70+@color-suggestions-button-background: @color-base;
71+@color-suggestions-button-font: #FFF;
72+
73+@color-download-button-background: @color-base;
74+@color-download-button-font: #FFF;
75+
76+@color-result-search-background: @color-base-light;
77+
78+@color-result-definition-border: gray;
79+@color-result-torrent-border: lightgray;
80+@color-result-top-border: #E8E7E6;
81+
82+// Link to result
83+@color-result-link-font: @color-base-dark;
84+@color-result-link-visited-font: @color-url-visited-font;
85+
86+// Url to result
87+@color-result-url-font: @color-red;
88+
89+// Publish Date
90+@color-result-publishdate-font: @color-font-light;
91+
92+// Images
93+@color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
94+@color-result-image-span-font: #FFF;
95+
96+// Search-URL
97+@color-result-search-url-border: #888;
98+@color-result-search-url-font: #444;
99+
100+
101+/// Settings
102+
103+@color-settings-fieldset: @color-base;
104+@color-settings-tr-hover: #DDD;
105+
106+// Labels
107+@color-settings-label-allowed-background: #E74C3C;
108+@color-settings-label-allowed-font: #FFF;
109+
110+@color-settings-label-deny-background: #2ECC71;
111+@color-settings-label-deny-font: @color-font;
112+
113+@color-settings-return-background: @color-base;
114+@color-settings-return-font: #FFF;
115+
116+/// Other
117+
118+@color-engines-font: @color-font-light;
119+@color-percentage-div-background: #444;
searx/static/themes/pix-art/less/mixins.lessnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * searx, A privacy-respecting, hackable metasearch engine
3+ */
4+
5+// Mixins
6+
7+.text-size-adjust (@property: 100%) {
8+ -webkit-text-size-adjust: @property;
9+ -ms-text-size-adjust: @property;
10+ -moz-text-size-adjust: @property;
11+ text-size-adjust: @property;
12+}
13+
14+.rounded-corners (@radius: 4px) {
15+ -webkit-border-radius: @radius;
16+ -moz-border-radius: @radius;
17+ border-radius: @radius;
18+}
19+
20+.user-select () {
21+ -webkit-touch-callout: none;
22+ -webkit-user-select: none;
23+ -khtml-user-select: none;
24+ -moz-user-select: none;
25+ -ms-user-select: none;
26+ user-select: none;
27+}
searx/static/themes/pix-art/less/search.lessnew file+56
@@ -0,0 +1,56 @@
1+/*
2+ * searx, A privacy-respecting, hackable metasearch engine
3+ */
4+
5+.search {
6+ padding: 0;
7+ margin: 0;
8+}
9+
10+#search_wrapper {
11+ position: relative;
12+ width: @results-width;
13+ padding: 10px;
14+}
15+
16+.center #search_wrapper {
17+ margin-left: auto;
18+ margin-right: auto;
19+}
20+
21+.q {
22+ background: none repeat scroll 0 0 @color-search-background;
23+ border: 1px solid @color-search-border;
24+ color: @color-search-font;
25+ font-size: 16px;
26+ height: 28px;
27+ margin: 0;
28+ outline: medium none;
29+ padding: 2px;
30+ padding-left: 8px;
31+ padding-right: 0px !important;
32+ width: 100%;
33+ z-index: 2;
34+}
35+
36+#search_submit {
37+ position: absolute;
38+ top: 13px;
39+ right: 1px;
40+ padding: 0;
41+ border: 0;
42+ background: url('../img/search-icon-pixel.png') no-repeat;
43+ background-size: 24px 24px;
44+ opacity: 0.8;
45+ width: 24px;
46+ height: 30px;
47+ font-size: 0;
48+}
49+
50+@media screen and (max-width: @results-width) {
51+ #search_wrapper {
52+ width: 90%;
53+ clear:both;
54+ overflow: hidden
55+ }
56+}
searx/static/themes/pix-art/less/style.lessnew file+438
@@ -0,0 +1,438 @@
1+/*
2+ * searx, A privacy-respecting, hackable metasearch engine
3+ *
4+ * To convert "style.less" to "style.css" run: $make styles
5+ */
6+
7+@import "definitions.less";
8+
9+@import "mixins.less";
10+
11+
12+// Main LESS-Code
13+
14+html {
15+ font-family: sans-serif;
16+ font-size: 0.9em;
17+ .text-size-adjust;
18+ color: @color-font;
19+ padding: 0;
20+ margin: 0;
21+}
22+
23+body, #container {
24+ padding: 0;
25+ margin: 0;
26+}
27+
28+canvas {
29+ image-rendering: optimizeSpeed;
30+ image-rendering: -moz-crisp-edges;
31+ image-rendering: -webkit-optimize-contrast;
32+ image-rendering: optimize-contrast;
33+ image-rendering: pixelated;
34+ -ms-interpolation-mode: nearest-neighbor;
35+ width:32px;
36+ height:32px;
37+}
38+
39+#container {
40+ width: 100%;
41+ position: absolute;
42+ top: 0;
43+}
44+
45+// Search-Field
46+
47+@import "search.less";
48+
49+// Autocompleter
50+
51+
52+.row {
53+ max-width: 800px;
54+ margin: 20px auto;
55+ text-align: justify;
56+
57+ h1 {
58+ font-size: 3em;
59+ margin-top: 50px;
60+ }
61+
62+ p {
63+ padding: 0 10px;
64+ max-width: 700px;
65+ }
66+
67+ h3,ul {
68+ margin: 4px 8px;
69+ }
70+}
71+
72+.hmarg {
73+ margin: 0 20px;
74+ border: 1px solid @color-hmarg-border;
75+ padding: 4px 10px;
76+}
77+
78+a {
79+ &:link.hmarg {
80+ color: @color-hmarg-font;
81+ }
82+
83+ &:visited.hmarg {
84+ color: @color-hmarg-font;
85+ }
86+
87+ &:active.hmarg {
88+ color: @color-hmarg-font-hover;
89+ }
90+
91+ &:hover.hmarg {
92+ color: @color-hmarg-font-hover;
93+ }
94+}
95+
96+.top_margin {
97+ margin-top: 60px;
98+}
99+
100+.center {
101+ text-align: center;
102+}
103+
104+h1 {
105+ font-size: 5em;
106+}
107+
108+div.title {
109+ background: url('../img/searx-pixel.png') no-repeat;
110+ width: 100%;
111+ min-height: 80px;
112+ background-position: center;
113+
114+ h1 {
115+ visibility: hidden;
116+ }
117+}
118+
119+input[type="submit"] {
120+ padding: 2px 6px;
121+ margin: 2px 4px;
122+ display: inline-block;
123+ background: @color-download-button-background;
124+ color: @color-download-button-font;
125+ .rounded-corners;
126+ border: 0;
127+ cursor: pointer;
128+}
129+
130+input[type="checkbox"] {
131+ visibility: hidden;
132+}
133+
134+fieldset {
135+ margin: 8px;
136+ border: 1px solid @color-settings-fieldset;
137+}
138+
139+#categories {
140+ margin: 0 10px;
141+ .user-select;
142+}
143+
144+.checkbox_container {
145+ display: inline-block;
146+ position: relative;
147+ margin: 0 3px;
148+ padding: 0px;
149+
150+ input {
151+ display: none;
152+ }
153+}
154+
155+.checkbox_container label, .engine_checkbox label {
156+ cursor: pointer;
157+ padding: 4px 10px;
158+ margin: 0;
159+ display: block;
160+ text-transform: capitalize;
161+ .user-select;
162+}
163+
164+.checkbox_container input[type="checkbox"]:checked + label {
165+ background: @color-categories-item-selected;
166+ color: @color-categories-item-selected-font;
167+}
168+
169+.engine_checkbox {
170+ padding: 4px;
171+}
172+
173+label {
174+ &.allow {
175+ background: @color-settings-label-allowed-background;
176+ padding: 4px 8px;
177+ color: @color-settings-label-allowed-font;
178+ display: none;
179+ }
180+
181+ &.deny {
182+ background: @color-settings-label-deny-background;
183+ padding: 4px 8px;
184+ color: @color-settings-label-deny-font;
185+ display: inline;
186+ }
187+}
188+
189+.engine_checkbox input[type="checkbox"]:checked + label {
190+ &:nth-child(2) + label {
191+ display: none;
192+ }
193+
194+ &.allow {
195+ display: inline;
196+ }
197+}
198+
199+a {
200+ text-decoration: none;
201+ color: @color-url-font;
202+
203+ &:visited {
204+ color: @color-url-visited-font;
205+ }
206+}
207+
208+.engines {
209+ color: @color-engines-font;
210+}
211+
212+.small_font {
213+ font-size: 0.8em;
214+}
215+
216+.small p {
217+ margin: 2px 0;
218+}
219+
220+.right {
221+ float: right;
222+}
223+
224+.invisible {
225+ display: none;
226+}
227+
228+.left {
229+ float: left;
230+}
231+
232+.highlight {
233+ color: @color-highlight;
234+}
235+
236+.content .highlight {
237+ color: @color-black;
238+}
239+
240+.percentage {
241+ position: relative;
242+ width: 300px;
243+
244+ div {
245+ background: @color-percentage-div-background;
246+ }
247+}
248+
249+table {
250+ width: 100%;
251+}
252+
253+td {
254+ padding: 0 4px;
255+}
256+
257+tr {
258+ &:hover {
259+ background: @color-settings-tr-hover;
260+ }
261+}
262+
263+#results {
264+ margin: auto;
265+ padding: 0;
266+ width: @results-width;
267+ margin-bottom: 20px;
268+}
269+
270+#search_url {
271+ margin-top: 8px;
272+
273+ input {
274+ border: 1px solid @color-result-search-url-border;
275+ padding: 4px;
276+ color: @color-result-search-url-font;
277+ width: 14em;
278+ display: block;
279+ margin: 4px;
280+ font-size: 0.8em;
281+ }
282+}
283+
284+#preferences {
285+ top: 10px;
286+ padding: 0;
287+ border: 0;
288+ background: url('../img/preference-icon-pixel.png') no-repeat;
289+ background-size: 28px 28px;
290+ opacity: 0.8;
291+ width: 28px;
292+ height: 30px;
293+ display: block;
294+
295+ * {
296+ display: none;
297+ }
298+}
299+
300+#pagination {
301+ clear: both;
302+
303+ br {
304+ clear: both;
305+ }
306+}
307+
308+#apis {
309+ margin-top: 8px;
310+ clear: both;
311+}
312+
313+#categories_container {
314+ position: relative;
315+}
316+
317+@media screen and (max-width: @results-width) {
318+
319+ #results {
320+ margin: auto;
321+ padding: 0;
322+ width: 90%;
323+ }
324+
325+ .checkbox_container {
326+ display: block;
327+ width: 90%;
328+ //float: left;
329+
330+ label {
331+ border-bottom: 0;
332+ }
333+ }
334+
335+ .preferences_container {
336+ display: none;
337+ postion: fixed !important;
338+ top: 100px;
339+ right: 0px;
340+ }
341+
342+}
343+
344+@media screen and (max-width: 75em) {
345+
346+ div.title {
347+
348+ h1 {
349+ font-size: 1em;
350+ }
351+ }
352+
353+ html.touch #categories {
354+ width: 95%;
355+ height: 30px;
356+ text-align: left;
357+ overflow-x: scroll;
358+ overflow-y: hidden;
359+ -webkit-overflow-scrolling: touch;
360+
361+ #categories_container {
362+ width: 1000px;
363+ width: -moz-max-content;
364+ width: -webkit-max-content;
365+ width: max-content;
366+
367+ .checkbox_container {
368+ display: inline-block;
369+ width: auto;
370+ }
371+ }
372+ }
373+
374+ #categories {
375+ font-size: 90%;
376+ clear: both;
377+
378+ .checkbox_container {
379+ margin-top: 2px;
380+ margin: auto;
381+ }
382+ }
383+
384+ #categories {
385+ font-size: 90%;
386+ clear: both;
387+
388+ .checkbox_container {
389+ margin-top: 2px;
390+ margin: auto;
391+ }
392+ }
393+
394+ #apis {
395+ display: none;
396+ }
397+
398+ #search_url {
399+ display: none;
400+ }
401+}
402+
403+.favicon {
404+ float: left;
405+ margin-right: 4px;
406+ margin-top: 2px;
407+}
408+
409+.preferences_back {
410+ background: none repeat scroll 0 0 @color-settings-return-background;
411+ border: 0 none;
412+ .rounded-corners;
413+ cursor: pointer;
414+ display: inline-block;
415+ margin: 2px 4px;
416+ padding: 4px 6px;
417+
418+ a {
419+ color: @color-settings-return-font;
420+ }
421+}
422+
423+.hidden {
424+ opacity: 0;
425+ overflow: hidden;
426+ font-size: 0.8em;
427+ position: absolute;
428+ bottom: -20px;
429+ width: 100%;
430+ text-position: center;
431+ background: white;
432+ transition: opacity 1s ease;
433+}
434+
435+#categories_container:hover .hidden {
436+ transition: opacity 1s ease;
437+ opacity: 0.8;
438+}
searx/templates/pix-art/about.htmlnew file+65
@@ -0,0 +1,65 @@
1+{% extends 'pix-art/base.html' %}
2+{% block content %}
3+<div class="row"{% if rtl %} dir="ltr"{% endif %}>
4+ <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
5+
6+ <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
7+ </p>
8+ <h2>Why use Searx?</h2>
9+ <ul>
10+ <li>Searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
11+ <li>Searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
12+ <li>Searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
13+ </ul>
14+ <p>If you do care about privacy, want to be a conscious user, or otherwise believe
15+ in digital freedom, make Searx your default search engine or run it on your own server</p>
16+
17+<h2>Technical details - How does it work?</h2>
18+
19+<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
20+inspired by the <a href="http://seeks-project.info/">seeks project</a>.<br />
21+It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, if Searx used from the search bar it performs GET requests.<br />
22+Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
23+</p>
24+
25+<h2>How can I make it my own?</h2>
26+
27+<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
28+<br />The more decentralized Internet is the more freedom we have!</p>
29+
30+
31+<h2>More about searx</h2>
32+
33+<ul>
34+ <li><a href="https://github.com/asciimoo/searx">github</a></li>
35+ <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
36+ <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
37+ <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
38+ <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
39+</ul>
40+
41+
42+<hr />
43+
44+<h2 id="faq">FAQ</h2>
45+
46+<h3>How to add to firefox?</h3>
47+<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
48+
49+<h2 id="dev_faq">Developer FAQ</h2>
50+
51+<h3>New engines?</h3>
52+<ul>
53+ <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
54+ <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
55+</ul>
56+<p>Don't forget to restart searx after config edit!</p>
57+
58+<h3>Installation/WSGI support?</h3>
59+<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
60+
61+<h3>How to debug engines?</h3>
62+<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
63+
64+</div>
65+{% endblock %}
searx/templates/pix-art/base.htmlnew file+28
@@ -0,0 +1,28 @@
1+<!DOCTYPE html>
2+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3+ <head>
4+ <meta charset="UTF-8" />
5+ <meta name="description" content="Searx - a privacy-respecting, hackable metasearch engine" />
6+ <meta name="keywords" content="searx, search, search engine, metasearch, meta search" />
7+ <meta name="generator" content="searx/{{ searx_version }}">
8+ <meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=1" />
9+ <title>{% block title %}{% endblock %}searx</title>
10+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" type="text/css" media="screen" />
11+ <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}?v=2" />
12+ {% block styles %}
13+ {% endblock %}
14+ {% block meta %}{% endblock %}
15+ {% block head %}
16+ {% endblock %}
17+ </head>
18+ <body>
19+ <div id="container">
20+ {% block content %}
21+ {% endblock %}
22+ <script type="text/javascript">
23+ searx = {};
24+ </script>
25+ <script src="{{ url_for('static', filename='js/searx.js') }}" ></script>
26+ </div>
27+ </body>
28+</html>
searx/templates/pix-art/index.htmlnew file+12
@@ -0,0 +1,12 @@
1+{% extends "pix-art/base.html" %}
2+{% block content %}
3+<div class="center">
4+ <div class="title"><h1><img src="{{ url_for('static', filename='img/searx-pixel.png') }}" alt="Searx Logo"/></h1></div>
5+ {% include 'pix-art/search.html' %}
6+ <p class="top_margin">
7+ <a href="{{ url_for('about') }}" class="hmarg">{{ _('about') }}</a>
8+ <a href="{{ url_for('preferences') }}" class="hmarg">{{ _('preferences') }}</a>
9+ </p>
10+</div>
11+{% endblock %}
12+
searx/templates/pix-art/preferences.htmlnew file+82
@@ -0,0 +1,82 @@
1+{% extends "default/base.html" %}
2+{% block head %} {% endblock %}
3+{% block content %}
4+<div class="row">
5+ <h2>{{ _('Preferences') }}</h2>
6+
7+ <form method="post" action="{{ url_for('preferences') }}" id="search_form">
8+ <fieldset>
9+ <legend>{{ _('Search language') }}</legend>
10+ <p>
11+ <select name='language'>
12+ <option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Automatic') }}</option>
13+ {% for lang_id,lang_name,country_name in language_codes | sort(attribute=1) %}
14+ <option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} ({{ country_name }}) - {{ lang_id }}</option>
15+ {% endfor %}
16+ </select>
17+ </p>
18+ </fieldset>
19+ <fieldset>
20+ <legend>{{ _('Interface language') }}</legend>
21+ <p>
22+ <select name='locale'>
23+ {% for locale_id,locale_name in locales.items() | sort %}
24+ <option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
25+ {% endfor %}
26+ </select>
27+ </p>
28+ </fieldset>
29+ <fieldset>
30+ <legend>{{ _('Method') }}</legend>
31+ <p>
32+ <select name='method'>
33+ <option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
34+ <option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
35+ </select>
36+ </p>
37+ </fieldset>
38+ <fieldset>
39+ <legend>{{ _('Themes') }}</legend>
40+ <p>
41+ <select name="theme">
42+ {% for name in themes %}
43+ <option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
44+ {% endfor %}
45+ </select>
46+ </p>
47+ </fieldset>
48+ <fieldset>
49+ <legend>{{ _('Currently used search engines') }}</legend>
50+
51+ <table>
52+ <tr>
53+ <th>{{ _('Engine name') }}</th>
54+ <th>{{ _('Allow') }} / {{ _('Block') }}</th>
55+ </tr>
56+ {% for (categ,search_engines) in categs %}
57+ {% for search_engine in search_engines %}
58+
59+ {% if not search_engine.private %}
60+ <tr>
61+ <td>{{ search_engine.name }} ({{ shortcuts[search_engine.name] }})&lrm;</td>
62+ <td class="engine_checkbox">
63+ <input type="checkbox" id="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}" name="engine_{{ search_engine.name }}__{{ categ }}"{% if (search_engine.name, categ) in blocked_engines %} checked="checked"{% endif %} />
64+ <label class="allow" for="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Allow') }}</label>
65+ <label class="deny" for="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Block') }}</label>
66+ </td>
67+ </tr>
68+ {% endif %}
69+ {% endfor %}
70+ {% endfor %}
71+ </table>
72+ </fieldset>
73+ <p class="small_font">{{ _('These settings are stored in your cookies, this allows us not to store this data about you.') }}
74+ <br />
75+ {{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }}
76+ </p>
77+
78+ <input type="submit" value="{{ _('save') }}" />
79+ <div class="{% if rtl %}left{% else %}right{% endif %} preferences_back"><a href="{{ url_for('index') }}">{{ _('back') }}</a></div>
80+ </form>
81+</div>
82+{% endblock %}
searx/templates/pix-art/result_templates/default.htmlnew file+13
@@ -0,0 +1,13 @@
1+<a href="{{ result.url }}" title="{{ result.title | striptags }}">
2+ <canvas id="canvas-{{ pageno }}-{{ index }}" class="icon" width="16" height="16"></canvas>
3+</a>
4+<script type="text/javascript">
5+var img{{ pageno }}_{{ index }} = new Image();
6+img{{ pageno }}_{{ index }}.src = 'http://{{ result.url | extract_domain }}/favicon.ico';
7+
8+img{{ pageno }}_{{ index }}.onload = function () {
9+ var can{{ pageno }}_{{ index }} = document.getElementById('canvas-{{ pageno }}-{{ index }}');
10+ var ctx = can{{ pageno }}_{{ index }}.getContext("2d");
11+ ctx.drawImage(img{{ pageno }}_{{ index }}, 0, 0, 16, 16);
12+};
13+</script>
searx/templates/pix-art/result_templates/images.htmlnew file+6
@@ -0,0 +1,6 @@
1+<div class="image_result">
2+ <p>
3+ <a href="{{ result.img_src }}"><img src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}" /></a>
4+ <span class="url"><a href="{{ result.url }}" class="small_font">{{ _('original context') }}</a></span>
5+ </p>
6+</div>
searx/templates/pix-art/results.htmlnew file+44
@@ -0,0 +1,44 @@
1+{% extends "pix-art/base.html" %}
2+{% block title %}{{ q }} - {% endblock %}
3+{% block meta %}{% endblock %}
4+{% block content %}
5+<div class="preferences_container right"><a href="{{ url_for('preferences') }}" id="preferences"><span>preferences</span></a></div>
6+<div class="small search center">
7+ {% include 'pix-art/search.html' %}
8+</div>
9+<div id="results">
10+ {% for result in results %}
11+ {% set index = loop.index %}
12+ {% include 'pix-art/result_templates/default.html' %}
13+ {% endfor %}
14+
15+ {% if paging %}
16+ <div id="pagination">
17+ {% if pageno > 1 %}
18+ <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
19+ <div class="{% if rtl %}right{% else %}left{% endif %}">
20+ <input type="hidden" name="q" value="{{ q }}" />
21+ {% for category in selected_categories %}
22+ <input type="hidden" name="category_{{ category }}" value="1"/>
23+ {% endfor %}
24+ <input type="hidden" name="pageno" value="{{ pageno-1 }}" />
25+ <input type="submit" value="<< {{ _('previous page') }}" />
26+ </div>
27+ </form>
28+ {% endif %}
29+ <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
30+ <div class="{% if rtl %}left{% else %}right{% endif %}">
31+ {% for category in selected_categories %}
32+ <input type="hidden" name="category_{{ category }}" value="1"/>
33+ {% endfor %}
34+ <input type="hidden" name="q" value="{{ q }}" />
35+ <input type="hidden" name="pageno" value="{{ pageno+1 }}" />
36+ <input type="submit" value="{{ _('next page') }} >>" />
37+ </div>
38+ </form>
39+
40+ <br />
41+ </div>
42+ {% endif %}
43+</div>
44+{% endblock %}
searx/templates/pix-art/search.htmlnew file+9
@@ -0,0 +1,9 @@
1+<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form">
2+ <div id="search_wrapper">
3+ <input type="text" placeholder="{{ _('Search for...') }}" id="q" class="q" name="q" tabindex="1" size="100" {% if q %}value="{{ q }}"{% endif %}/>
4+ <input type="submit" value="search" id="search_submit" />
5+ {% for category in categories %}
6+ <input type="hidden" name="category_{{ category }}" value="1"/>
7+ {% endfor %}
8+ </div>
9+</form>
searx/templates/pix-art/stats.htmlnew file+22
@@ -0,0 +1,22 @@
1+{% extends "default/base.html" %}
2+{% block head %} {% endblock %}
3+{% block content %}
4+<h2>{{ _('Engine stats') }}</h2>
5+
6+{% for stat_name,stat_category in stats %}
7+<div class="left">
8+ <table>
9+ <tr colspan="3">
10+ <th>{{ stat_name }}</th>
11+ </tr>
12+ {% for engine in stat_category %}
13+ <tr>
14+ <td>{{ engine.name }}</td>
15+ <td>{{ '%.02f'|format(engine.avg) }}</td>
16+ <td class="percentage"><div style="width: {{ engine.percentage }}%">&nbsp;</div></td>
17+ </tr>
18+ {% endfor %}
19+ </table>
20+</div>
21+{% endfor %}
22+{% endblock %}
searx/webapp.py+7
@@ -29,6 +29,7 @@ import hashlib
2929
3030from datetime import datetime, timedelta
3131from urllib import urlencode
32+from urlparse import urlparse
3233from werkzeug.contrib.fixers import ProxyFix
3334from flask import (
3435 Flask, request, render_template, url_for, Response, make_response,
@@ -178,6 +179,12 @@ def code_highlighter(codelines, language=None):
178179 return html_code
179180
180181
182+# Extract domain from url
183+@app.template_filter('extract_domain')
184+def extract_domain(url):
185+ return urlparse(url)[1]
186+
187+
181188def get_base_url():
182189 if settings['server']['base_url']:
183190 hostname = settings['server']['base_url']