Support custom stylesheets: /etc/butterfly/style.[s]css and ~/.butterfly/style.[s]css with scss import support. References #20

This commit is contained in:
Florian Mounier
2014-05-05 12:03:21 +02:00
parent 34c6718d8c
commit bbd216fe3f
26 changed files with 547 additions and 193 deletions

View File

@@ -19,13 +19,13 @@ module.exports = (grunt) ->
expand: true
cwd: 'sass/'
src: '*.sass'
dest: 'sass/scss/'
dest: 'butterfly/scss/'
ext: '.scss'
sass:
butterfly:
expand: true
cwd: 'sass/scss'
cwd: 'butterfly/scss'
src: '*.scss'
dest: 'butterfly/static/'
ext: '.css'
@@ -75,4 +75,4 @@ module.exports = (grunt) ->
grunt.registerTask 'default', [
'coffeelint', 'coffee',
'sass_to_scss', 'sass',
'uglify', 'cssmin']
'uglify']

View File

@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__version__ = '1.4.5'
__version__ = '1.5.0'
import os

View File

@@ -93,6 +93,30 @@ class Index(Route):
return self.render('index.html')
@url(r'/style.css')
class Style(Route):
def get(self):
default_style = os.path.join(
os.path.dirname(__file__), 'static', 'main.css')
css = utils.get_style()
self.set_header("Content-Type", "text/css")
if css:
self.write(css)
else:
with open(default_style) as s:
while True:
data = s.read(16384)
if data:
self.write(data)
else:
break
self.finish()
@url(r'/ws(?:/user/([^/]+))?/?(?:/wd/(.+))?')
class TermWebSocket(Route, tornado.websocket.WebSocketHandler):

View File

@@ -0,0 +1,16 @@
@include termcolor(0, #2e3436);
@include termcolor(1, #cc0000);
@include termcolor(2, #4e9a06);
@include termcolor(3, #c4a000);
@include termcolor(4, #3465a4);
@include termcolor(5, #75507b);
@include termcolor(6, #06989a);
@include termcolor(7, #d3d7cf);
@include termcolor(8, #555753);
@include termcolor(9, #ef2929);
@include termcolor(10, #8ae234);
@include termcolor(11, #fce94f);
@include termcolor(12, #729fcf);
@include termcolor(13, #ad7fa8);
@include termcolor(14, #34e2e2);
@include termcolor(15, #eeeeec);

View File

@@ -0,0 +1,13 @@
$fg: #fff !default;
$bg: #000 !default;
$st: 00, 95, 135, 175, 215, 255;
@for $i from 0 through 215{
$r: nth($st, 1 + floor(($i / 36) % 6));
$g: nth($st, 1 + floor(($i / 6) % 6));
$b: nth($st, 1 + $i % 6);
@include termcolor($i + 16, rgb($r, $g, $b));}
@for $i from 0 through 23{
$l: 8 + $i * 10;
@include termcolor($i + 232, rgb($l, $l, $l));}
@include termcolor(256, $bg);
@include termcolor(257, $fg);

View File

@@ -0,0 +1,20 @@
$shadow: 0 !default;
$shadow-alpha: 0 !default;
$bg: #110f13;
$fg: #f4ead5;
#wrapper{
background-color: $bg;}
.terminal{
background-color: $bg;
color: $fg;}
@mixin termcolor($i, $color){
.bg-color-#{$i}{
background-color: $color;
&.reverse-video{
color: $color !important;}}
.fg-color-#{$i}{
color: $color;
&.reverse-video{
background-color: $color !important;}
@if $shadow != 0{
text-shadow: 0 0 $shadow rgba($color, $shadow-alpha);}}}

View File

@@ -0,0 +1,6 @@
$fg: #fff !default;
$shadow-alpha: 0 !default;
.focus .cursor{
transition: 300ms;}
.cursor.reverse-video{
box-shadow: 0 0 $shadow-alpha $fg;}

10
butterfly/scss/_font.scss Normal file
View File

@@ -0,0 +1,10 @@
$weights: (ExtraLight 100) (Light 300) (Regular 400) (Medium 500) (Semibold 600) (Bold 700) (Black 900);
@each $weight in $weights{
$weight_name: nth($weight, 1);
@font-face{
font-family: "SourceCodePro";
src: url("/static/fonts/SourceCodePro-#{$weight_name}.otf") format("woff");
font-weight: nth($weight, 2);}}
body{
font-family: "SourceCodePro";
line-height: 1.2;}

28
butterfly/scss/_fx.scss Normal file
View File

@@ -0,0 +1,28 @@
$fg: #fff !default;
$shadow: 6px;
$shadow-alpha: .5;
.terminal{
text-shadow: 0 0 $shadow rgba($fg, $shadow-alpha);
transition: 200ms;
&.bell{
-webkit-filter: blur(2px);}
&.skip{
-webkit-filter: sepia(1);}
&.selection{
-webkit-filter: unquote("saturate(2)");}
&.dead{
-webkit-filter: unquote("grayscale(1)");
&:after{
content: "CLOSED";
font-size: 15em;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(-45deg);
opacity: .2;
font-weight: 900;}}}

View File

@@ -0,0 +1,11 @@
html, body{
height: 100%;
margin: 0;
padding: 0;
line-height: 1.2;}
#wrapper{
height: 100%;
overflow: hidden;
white-space: nowrap;}
.terminal{
outline: none;}

View File

@@ -0,0 +1,15 @@
$fg: #fff !default;
$bg: #000 !default;
.bold{
font-weight: bold;}
.underline{
text-decoration: underline;}
.blink{
text-decoration: blink;}
.invisible{
visibility: hidden;}
.reverse-video{
color: $bg;
background-color: $fg;}
.blur .cursor.reverse-video{
background: none;}

8
butterfly/scss/main.scss Normal file
View File

@@ -0,0 +1,8 @@
@import 'font';
@import 'layout';
@import 'fx';
@import 'colors';
@import '16_colors';
@import '256_colors';
@import 'cursor';
@import 'term_styles';

View File

@@ -1,56 +1,58 @@
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-ExtraLight.otf") format("woff");
src: url("/static/fonts/SourceCodePro-ExtraLight.otf") format("woff");
font-weight: 100; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Light.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Light.otf") format("woff");
font-weight: 300; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Regular.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Regular.otf") format("woff");
font-weight: 400; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Medium.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Medium.otf") format("woff");
font-weight: 500; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Semibold.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Semibold.otf") format("woff");
font-weight: 600; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Bold.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Bold.otf") format("woff");
font-weight: 700; }
@font-face {
font-family: "SourceCodePro";
src: url("fonts/SourceCodePro-Black.otf") format("woff");
src: url("/static/fonts/SourceCodePro-Black.otf") format("woff");
font-weight: 900; }
body {
font-family: "SourceCodePro";
line-height: 1.2; }
html, body {
height: 100%;
font-family: "SourceCodePro";
margin: 0;
padding: 0;
line-height: 1.2; }
#wrapper {
height: 100%;
background-color: #110f13;
overflow: hidden;
white-space: nowrap; }
.terminal {
outline: none;
background-color: #110f13;
color: #f4ead5;
text-shadow: 0 0 6px rgba(244, 234, 213, 0.5);
outline: none; }
.terminal {
text-shadow: 0 0 6px rgba(255, 255, 255, 0.5);
transition: 200ms; }
.terminal.bell {
-webkit-filter: blur(2px); }
@@ -75,35 +77,12 @@ html, body {
opacity: 0.2;
font-weight: 900; }
.line {
overflow: visible; }
.line .inline-html {
white-space: normal; }
#wrapper {
background-color: #110f13; }
.focus .cursor {
transition: 300ms; }
.cursor.reverse-video {
box-shadow: 0 0 10px #f4ead5; }
.bold {
font-weight: bold; }
.underline {
text-decoration: underline; }
.blink {
text-decoration: blink; }
.invisible {
visibility: hidden; }
.reverse-video {
color: #110f13;
background-color: #f4ead5; }
.blur .cursor.reverse-video {
background: none; }
.terminal {
background-color: #110f13;
color: #f4ead5; }
.bg-color-0 {
background-color: #2e3436; }
@@ -2942,3 +2921,28 @@ html, body {
text-shadow: 0 0 6px rgba(244, 234, 213, 0.5); }
.fg-color-257.reverse-video {
background-color: #f4ead5 !important; }
.focus .cursor {
transition: 300ms; }
.cursor.reverse-video {
box-shadow: 0 0 0.5 #f4ead5; }
.bold {
font-weight: bold; }
.underline {
text-decoration: underline; }
.blink {
text-decoration: blink; }
.invisible {
visibility: hidden; }
.reverse-video {
color: #110f13;
background-color: #f4ead5; }
.blur .cursor.reverse-video {
background: none; }

5
butterfly/static/main.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -10,7 +10,7 @@
<link rel="shortcut icon" href="{{ static_url('images/favicon.png') }}">
<title>Butterfly</title>
<link href="{{ static_url('main.css') }}" rel="stylesheet">
<link href="/style.css" rel="stylesheet">
</head>
<body spellcheck="false">

View File

@@ -25,6 +25,44 @@ import re
log = getLogger('butterfly')
def get_style():
style = None
for ext in ['css', 'scss', 'sass']:
for fn in [
'/etc/butterfly/style',
os.path.expanduser('~/.butterfly/style')]:
if os.path.exists('%s.%s' % (fn, ext)):
style = '%s.%s' % (fn, ext)
if style is None:
return
if style.endswith('.sass'):
log.error('SASS syntax is not yet supported (see: '
'https://github.com/hcatlin/libsass/issues/16'
') please use SCSS')
return
if style.endswith('.scss'):
scss_path = os.path.join(
os.path.dirname(__file__), 'scss')
try:
import sass
except:
log.error('You must install libsass to use sass '
'(pip install libsass)')
return
try:
return sass.compile(filename=style, include_paths=[scss_path])
except sass.CompileError:
log.error('Unable to compile style.scss', exc_info=True)
return
with open(style) as s:
return s.read()
def parse_cert(cert):
user = None

36
sass/_16_colors.sass Normal file
View File

@@ -0,0 +1,36 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Here are the 16 "normal" colors for theming */
+termcolor(0, #2e3436)
+termcolor(1, #cc0000)
+termcolor(2, #4e9a06)
+termcolor(3, #c4a000)
+termcolor(4, #3465a4)
+termcolor(5, #75507b)
+termcolor(6, #06989a)
+termcolor(7, #d3d7cf)
+termcolor(8, #555753)
+termcolor(9, #ef2929)
+termcolor(10, #8ae234)
+termcolor(11, #fce94f)
+termcolor(12, #729fcf)
+termcolor(13, #ad7fa8)
+termcolor(14, #34e2e2)
+termcolor(15, #eeeeec)

36
sass/_256_colors.sass Normal file
View File

@@ -0,0 +1,36 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$fg: #fff !default
$bg: #000 !default
/* Here are the 240 xterm colors */
/* See http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg */
$st: 00, 95, 135, 175, 215, 255
@for $i from 0 through 215
$r: nth($st, 1 + floor(($i / 36) % 6))
$g: nth($st, 1 + floor(($i / 6) % 6))
$b: nth($st, 1 + $i % 6)
+termcolor($i + 16, rgb($r, $g, $b))
@for $i from 0 through 23
$l: 8 + $i * 10
+termcolor($i + 232, rgb($l, $l, $l))
+termcolor(256, $bg)
+termcolor(257, $fg)

44
sass/_colors.sass Normal file
View File

@@ -0,0 +1,44 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$shadow: 0 !default
$shadow-alpha: 0 !default
$bg: #110f13
$fg: #f4ead5
#wrapper
background-color: $bg
.terminal
background-color: $bg
color: $fg
=termcolor($i, $color)
.bg-color-#{$i}
background-color: $color
&.reverse-video
color: $color !important
.fg-color-#{$i}
color: $color
&.reverse-video
background-color: $color !important
@if $shadow != 0
text-shadow: 0 0 $shadow rgba($color, $shadow-alpha)

25
sass/_cursor.sass Normal file
View File

@@ -0,0 +1,25 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$fg: #fff !default
$shadow-alpha: 0 !default
.focus .cursor
transition: 300ms
.cursor.reverse-video
box-shadow: 0 0 $shadow-alpha $fg

30
sass/_font.sass Normal file
View File

@@ -0,0 +1,30 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$weights: (ExtraLight 100) (Light 300) (Regular 400) (Medium 500) (Semibold 600) (Bold 700) (Black 900)
@each $weight in $weights
$weight_name: nth($weight, 1)
@font-face
font-family: "SourceCodePro"
src: url("/static/fonts/SourceCodePro-#{$weight_name}.otf") format("woff")
font-weight: nth($weight, 2)
body
font-family: "SourceCodePro"
line-height: 1.2

51
sass/_fx.sass Normal file
View File

@@ -0,0 +1,51 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$fg: #fff !default
$shadow: 6px
$shadow-alpha: .5
.terminal
text-shadow: 0 0 $shadow rgba($fg, $shadow-alpha)
transition: 200ms
&.bell
-webkit-filter: blur(2px)
&.skip
-webkit-filter: sepia(1)
&.selection
-webkit-filter: unquote("saturate(2)")
&.dead
-webkit-filter: unquote("grayscale(1)")
&:after
content: "CLOSED"
font-size: 15em
display: flex
justify-content: center
align-items: center
position: fixed
top: 0
left: 0
width: 100%
height: 100%
transform: rotate(-45deg)
opacity: .2
font-weight: 900

30
sass/_layout.sass Normal file
View File

@@ -0,0 +1,30 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
html, body
height: 100%
margin: 0
padding: 0
line-height: 1.2
#wrapper
height: 100%
overflow: hidden
white-space: nowrap
.terminal
outline: none

40
sass/_term_styles.sass Normal file
View File

@@ -0,0 +1,40 @@
/* *-* coding: utf-8 *-* */
/* This file is part of butterfly */
/* butterfly Copyright (C) 2014 Florian Mounier */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU 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; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$fg: #fff !default
$bg: #000 !default
.bold
font-weight: bold
.underline
text-decoration: underline
.blink
text-decoration: blink
.invisible
visibility: hidden
.reverse-video
color: $bg
background-color: $fg
.blur .cursor.reverse-video
background: none

View File

@@ -15,148 +15,11 @@
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
$weights: (ExtraLight 100) (Light 300) (Regular 400) (Medium 500) (Semibold 600) (Bold 700) (Black 900)
@each $weight in $weights
$weight_name: nth($weight, 1)
@font-face
font-family: "SourceCodePro"
src: url("fonts/SourceCodePro-#{$weight_name}.otf") format("woff")
font-weight: nth($weight, 2)
$bg: #110f13
$fg: #f4ead5
$shadow: 6px
$shadow-alpha: .5
html, body
height: 100%
font-family: "SourceCodePro"
margin: 0
padding: 0
line-height: 1.2
#wrapper
height: 100%
background-color: $bg
overflow: hidden
white-space: nowrap
.terminal
outline: none
background-color: $bg
color: $fg
text-shadow: 0 0 $shadow rgba($fg, $shadow-alpha)
transition: 200ms
&.bell
-webkit-filter: blur(2px)
&.skip
-webkit-filter: sepia(1)
&.selection
-webkit-filter: unquote("saturate(2)")
&.dead
-webkit-filter: unquote("grayscale(1)")
&:after
content: "CLOSED"
font-size: 15em
display: flex
justify-content: center
align-items: center
position: fixed
top: 0
left: 0
width: 100%
height: 100%
transform: rotate(-45deg)
opacity: .2
font-weight: 900
.line
overflow: visible
.inline-html
white-space: normal
.focus .cursor
transition: 300ms
.cursor.reverse-video
box-shadow: 0 0 10px $fg
/* Terminal styles */
.bold
font-weight: bold
.underline
text-decoration: underline
.blink
text-decoration: blink
.invisible
visibility: hidden
.reverse-video
color: $bg
background-color: $fg
.blur .cursor.reverse-video
background: none
=termcolor($i, $color)
.bg-color-#{$i}
background-color: $color
&.reverse-video
color: $color !important
.fg-color-#{$i}
color: $color
&.reverse-video
background-color: $color !important
text-shadow: 0 0 $shadow rgba($color, $shadow-alpha)
+termcolor(0, #2e3436)
+termcolor(1, #cc0000)
+termcolor(2, #4e9a06)
+termcolor(3, #c4a000)
+termcolor(4, #3465a4)
+termcolor(5, #75507b)
+termcolor(6, #06989a)
+termcolor(7, #d3d7cf)
+termcolor(8, #555753)
+termcolor(9, #ef2929)
+termcolor(10, #8ae234)
+termcolor(11, #fce94f)
+termcolor(12, #729fcf)
+termcolor(13, #ad7fa8)
+termcolor(14, #34e2e2)
+termcolor(15, #eeeeec)
$st: 00, 95, 135, 175, 215, 255
@for $i from 0 through 215
$r: nth($st, 1 + floor(($i / 36) % 6))
$g: nth($st, 1 + floor(($i / 6) % 6))
$b: nth($st, 1 + $i % 6)
+termcolor($i + 16, rgb($r, $g, $b))
@for $i from 0 through 23
$l: 8 + $i * 10
+termcolor($i + 232, rgb($l, $l, $l))
/* ?? */
+termcolor(256, $bg)
+termcolor(257, $fg)
@import 'font'
@import 'layout'
@import 'fx'
@import 'colors'
@import '16_colors'
@import '256_colors'
@import 'cursor'
@import 'term_styles'

View File

@@ -27,10 +27,11 @@ options = dict(
install_requires=["tornado>=3.2", "pyOpenSSL"],
package_data={
'butterfly': [
'scss/*.scss',
'static/fonts/*',
'static/images/favicon.png',
'static/stylesheets/main.css',
'static/javascripts/main.js',
'static/main.css',
'static/main.min.js',
'templates/index.html'
]
},