├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── main.py
├── pyprint
├── __init__.py
├── background
│ ├── static
│ │ ├── css
│ │ │ ├── bootstrap-theme.css.map
│ │ │ ├── bootstrap-theme.min.css
│ │ │ ├── bootstrap.css.map
│ │ │ ├── bootstrap.min.css
│ │ │ ├── foundation-icons.css
│ │ │ ├── foundation-icons.eot
│ │ │ ├── foundation-icons.ttf
│ │ │ ├── foundation-icons.woff
│ │ │ └── style.css
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ └── glyphicons-halflings-regular.woff
│ │ └── js
│ │ │ ├── bootstrap.min.js
│ │ │ └── jquery.js
│ └── templates
│ │ ├── add_post.html
│ │ ├── layout.html
│ │ ├── links.html
│ │ ├── login.html
│ │ └── posts.html
├── constants.py
├── database.py
├── handler.py
├── localsettings.example.py
├── models.py
├── settings.py
├── themes
│ ├── __init__.py
│ ├── clean
│ │ ├── __init__.py
│ │ ├── config.py
│ │ ├── static
│ │ │ └── css
│ │ │ │ ├── style.css
│ │ │ │ └── yue.css
│ │ └── templates
│ │ │ ├── diaries.html
│ │ │ ├── feed.xml
│ │ │ ├── index.html
│ │ │ ├── layout.html
│ │ │ ├── links.html
│ │ │ ├── not_found.html
│ │ │ └── post.html
│ ├── default
│ │ ├── static
│ │ │ ├── css
│ │ │ │ ├── akarin.css
│ │ │ │ ├── archives.css
│ │ │ │ ├── foundation-icons.css
│ │ │ │ ├── foundation-icons.eot
│ │ │ │ ├── foundation-icons.ttf
│ │ │ │ ├── foundation-icons.woff
│ │ │ │ ├── layout.css
│ │ │ │ ├── links.css
│ │ │ │ ├── nprogress.css
│ │ │ │ ├── post.css
│ │ │ │ └── yue.css
│ │ │ ├── imgs
│ │ │ │ ├── avatar.jpg
│ │ │ │ ├── banner.jpg
│ │ │ │ └── not_found.jpg
│ │ │ └── js
│ │ │ │ ├── jquery.lazyload.js
│ │ │ │ ├── jquery.min.js
│ │ │ │ ├── jquery.pjax.js
│ │ │ │ └── nprogress.js
│ │ └── templates
│ │ │ ├── archives.html
│ │ │ ├── diaries.html
│ │ │ ├── feed.xml
│ │ │ ├── index.html
│ │ │ ├── layout.html
│ │ │ ├── links.html
│ │ │ ├── not_found.html
│ │ │ ├── pjax_layout.html
│ │ │ └── post.html
│ ├── mdl
│ │ ├── static
│ │ │ ├── css
│ │ │ │ ├── font.css
│ │ │ │ ├── material-scrolltop.css
│ │ │ │ ├── material.min.css
│ │ │ │ ├── style.css
│ │ │ │ └── yue.css
│ │ │ ├── imgs
│ │ │ │ ├── avatar.jpg
│ │ │ │ ├── not_found.gif
│ │ │ │ └── top-arrow.svg
│ │ │ └── js
│ │ │ │ ├── jquery.min.js
│ │ │ │ ├── jquery.pjax.js
│ │ │ │ ├── material-progress.js
│ │ │ │ ├── material-scrolltop.js
│ │ │ │ ├── material.min.js
│ │ │ │ └── material.min.js.map
│ │ └── templates
│ │ │ ├── archives.html
│ │ │ ├── diaries.html
│ │ │ ├── feed.xml
│ │ │ ├── index.html
│ │ │ ├── layout.html
│ │ │ ├── links.html
│ │ │ ├── not_found.html
│ │ │ ├── pjax_layout.html
│ │ │ └── post.html
│ └── none
│ │ └── templates
│ │ ├── diaries.html
│ │ ├── feed.xml
│ │ ├── index.html
│ │ ├── layout.html
│ │ ├── links.html
│ │ ├── not_found.html
│ │ └── post.html
├── utils.py
└── views
│ ├── __init__.py
│ ├── background.py
│ ├── diaries.py
│ ├── links.py
│ ├── others.py
│ └── posts.py
└── requirement.txt
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.db3
3 | .idea
4 | *.db
5 | pyprint/localsettings.py
6 | pyprint/themes/default/static/postimg/*
7 | *.log
8 | .python-version
9 | .DS_Store
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Ricter Zheng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | pyprint
2 | =======
3 |
4 | Blog system just for me
5 |
6 | ### Usage
7 |
8 | git clone https://github.com/RicterZ/pyprint
9 | cd pyprint
10 | python pyprint/models.py
11 | python main.py --port=8888 --address=0.0.0.0
12 |
13 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import tornado.ioloop
2 | import tornado.httpserver
3 | import tornado.options
4 | from tornado.options import options, define
5 |
6 | from pyprint import Application
7 |
8 | define('port', default=8888, help='listen on the port', type=int)
9 | define('address', default='0.0.0.0', help='binding at given address', type=str)
10 |
11 | if __name__ == '__main__':
12 | tornado.options.parse_command_line()
13 | http_server = tornado.httpserver.HTTPServer(Application())
14 | http_server.listen(options.port, address=options.address)
15 | print '[+] PyPrint listening on {address}:{port}'.format(address=options.address,
16 | port=options.port)
17 | tornado.ioloop.IOLoop.instance().start()
18 |
19 |
--------------------------------------------------------------------------------
/pyprint/__init__.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | from hashlib import md5
3 |
4 | # third-part
5 | import tornado.web
6 |
7 | # custom
8 | import views
9 | from settings import *
10 | from models import engine
11 |
12 |
13 | theme_path = os.path.join(os.path.dirname(__file__), 'themes/{theme_name}'.format(theme_name=theme))
14 | background_path = os.path.join(os.path.dirname(__file__), 'background')
15 |
16 | class Application(tornado.web.Application):
17 | def __init__(self):
18 | handlers = views.handlers
19 | handlers.insert(0, (r'/kamisama/static/(.*)', tornado.web.StaticFileHandler,
20 | {'path': os.path.join(background_path, 'static')}))
21 |
22 | settings = dict(
23 | background_template_path=os.path.join(background_path, 'templates'),
24 |
25 | static_path=os.path.join(theme_path, 'static'),
26 | template_path=os.path.join(theme_path, 'templates'),
27 | login_url='/login',
28 | cookie_secret=cookie_secret,
29 |
30 | post_of_page=post_of_page,
31 |
32 | username=username,
33 | email=email,
34 | email_md5=md5(email.lower()).hexdigest(),
35 | motto=motto,
36 | title=title,
37 | disqus_shortname=disqus_shortname,
38 | analytics_code=analytics_code,
39 |
40 | debug=debug,
41 | )
42 |
43 | tornado.web.Application.__init__(self, handlers=handlers, **settings)
44 |
45 |
--------------------------------------------------------------------------------
/pyprint/background/static/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.1.1 (http://getbootstrap.com)
3 | * Copyright 2011-2014 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 |
7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
--------------------------------------------------------------------------------
/pyprint/background/static/css/foundation-icons.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Foundation Icons v 3.0
3 | * Made by ZURB 2013 http://zurb.com/playground/foundation-icon-fonts-3
4 | * MIT License
5 | */
6 |
7 | @font-face {
8 | font-family: "foundation-icons";
9 | src: url("foundation-icons.eot");
10 | src: url("foundation-icons.eot?#iefix") format("embedded-opentype"),
11 | url("foundation-icons.woff") format("woff"),
12 | url("foundation-icons.ttf") format("truetype"),
13 | url("foundation-icons.svg#fontcustom") format("svg");
14 | font-weight: normal;
15 | font-style: normal;
16 | }
17 |
18 | .fi-address-book:before,
19 | .fi-alert:before,
20 | .fi-align-center:before,
21 | .fi-align-justify:before,
22 | .fi-align-left:before,
23 | .fi-align-right:before,
24 | .fi-anchor:before,
25 | .fi-annotate:before,
26 | .fi-archive:before,
27 | .fi-arrow-down:before,
28 | .fi-arrow-left:before,
29 | .fi-arrow-right:before,
30 | .fi-arrow-up:before,
31 | .fi-arrows-compress:before,
32 | .fi-arrows-expand:before,
33 | .fi-arrows-in:before,
34 | .fi-arrows-out:before,
35 | .fi-asl:before,
36 | .fi-asterisk:before,
37 | .fi-at-sign:before,
38 | .fi-background-color:before,
39 | .fi-battery-empty:before,
40 | .fi-battery-full:before,
41 | .fi-battery-half:before,
42 | .fi-bitcoin-circle:before,
43 | .fi-bitcoin:before,
44 | .fi-blind:before,
45 | .fi-bluetooth:before,
46 | .fi-bold:before,
47 | .fi-book-bookmark:before,
48 | .fi-book:before,
49 | .fi-bookmark:before,
50 | .fi-braille:before,
51 | .fi-burst-new:before,
52 | .fi-burst-sale:before,
53 | .fi-burst:before,
54 | .fi-calendar:before,
55 | .fi-camera:before,
56 | .fi-check:before,
57 | .fi-checkbox:before,
58 | .fi-clipboard-notes:before,
59 | .fi-clipboard-pencil:before,
60 | .fi-clipboard:before,
61 | .fi-clock:before,
62 | .fi-closed-caption:before,
63 | .fi-cloud:before,
64 | .fi-comment-minus:before,
65 | .fi-comment-quotes:before,
66 | .fi-comment-video:before,
67 | .fi-comment:before,
68 | .fi-comments:before,
69 | .fi-compass:before,
70 | .fi-contrast:before,
71 | .fi-credit-card:before,
72 | .fi-crop:before,
73 | .fi-crown:before,
74 | .fi-css3:before,
75 | .fi-database:before,
76 | .fi-die-five:before,
77 | .fi-die-four:before,
78 | .fi-die-one:before,
79 | .fi-die-six:before,
80 | .fi-die-three:before,
81 | .fi-die-two:before,
82 | .fi-dislike:before,
83 | .fi-dollar-bill:before,
84 | .fi-dollar:before,
85 | .fi-download:before,
86 | .fi-eject:before,
87 | .fi-elevator:before,
88 | .fi-euro:before,
89 | .fi-eye:before,
90 | .fi-fast-forward:before,
91 | .fi-female-symbol:before,
92 | .fi-female:before,
93 | .fi-filter:before,
94 | .fi-first-aid:before,
95 | .fi-flag:before,
96 | .fi-folder-add:before,
97 | .fi-folder-lock:before,
98 | .fi-folder:before,
99 | .fi-foot:before,
100 | .fi-foundation:before,
101 | .fi-graph-bar:before,
102 | .fi-graph-horizontal:before,
103 | .fi-graph-pie:before,
104 | .fi-graph-trend:before,
105 | .fi-guide-dog:before,
106 | .fi-hearing-aid:before,
107 | .fi-heart:before,
108 | .fi-home:before,
109 | .fi-html5:before,
110 | .fi-indent-less:before,
111 | .fi-indent-more:before,
112 | .fi-info:before,
113 | .fi-italic:before,
114 | .fi-key:before,
115 | .fi-laptop:before,
116 | .fi-layout:before,
117 | .fi-lightbulb:before,
118 | .fi-like:before,
119 | .fi-link:before,
120 | .fi-list-bullet:before,
121 | .fi-list-number:before,
122 | .fi-list-thumbnails:before,
123 | .fi-list:before,
124 | .fi-lock:before,
125 | .fi-loop:before,
126 | .fi-magnifying-glass:before,
127 | .fi-mail:before,
128 | .fi-male-female:before,
129 | .fi-male-symbol:before,
130 | .fi-male:before,
131 | .fi-map:before,
132 | .fi-marker:before,
133 | .fi-megaphone:before,
134 | .fi-microphone:before,
135 | .fi-minus-circle:before,
136 | .fi-minus:before,
137 | .fi-mobile-signal:before,
138 | .fi-mobile:before,
139 | .fi-monitor:before,
140 | .fi-mountains:before,
141 | .fi-music:before,
142 | .fi-next:before,
143 | .fi-no-dogs:before,
144 | .fi-no-smoking:before,
145 | .fi-page-add:before,
146 | .fi-page-copy:before,
147 | .fi-page-csv:before,
148 | .fi-page-delete:before,
149 | .fi-page-doc:before,
150 | .fi-page-edit:before,
151 | .fi-page-export-csv:before,
152 | .fi-page-export-doc:before,
153 | .fi-page-export-pdf:before,
154 | .fi-page-export:before,
155 | .fi-page-filled:before,
156 | .fi-page-multiple:before,
157 | .fi-page-pdf:before,
158 | .fi-page-remove:before,
159 | .fi-page-search:before,
160 | .fi-page:before,
161 | .fi-paint-bucket:before,
162 | .fi-paperclip:before,
163 | .fi-pause:before,
164 | .fi-paw:before,
165 | .fi-paypal:before,
166 | .fi-pencil:before,
167 | .fi-photo:before,
168 | .fi-play-circle:before,
169 | .fi-play-video:before,
170 | .fi-play:before,
171 | .fi-plus:before,
172 | .fi-pound:before,
173 | .fi-power:before,
174 | .fi-previous:before,
175 | .fi-price-tag:before,
176 | .fi-pricetag-multiple:before,
177 | .fi-print:before,
178 | .fi-prohibited:before,
179 | .fi-projection-screen:before,
180 | .fi-puzzle:before,
181 | .fi-quote:before,
182 | .fi-record:before,
183 | .fi-refresh:before,
184 | .fi-results-demographics:before,
185 | .fi-results:before,
186 | .fi-rewind-ten:before,
187 | .fi-rewind:before,
188 | .fi-rss:before,
189 | .fi-safety-cone:before,
190 | .fi-save:before,
191 | .fi-share:before,
192 | .fi-sheriff-badge:before,
193 | .fi-shield:before,
194 | .fi-shopping-bag:before,
195 | .fi-shopping-cart:before,
196 | .fi-shuffle:before,
197 | .fi-skull:before,
198 | .fi-social-500px:before,
199 | .fi-social-adobe:before,
200 | .fi-social-amazon:before,
201 | .fi-social-android:before,
202 | .fi-social-apple:before,
203 | .fi-social-behance:before,
204 | .fi-social-bing:before,
205 | .fi-social-blogger:before,
206 | .fi-social-delicious:before,
207 | .fi-social-designer-news:before,
208 | .fi-social-deviant-art:before,
209 | .fi-social-digg:before,
210 | .fi-social-dribbble:before,
211 | .fi-social-drive:before,
212 | .fi-social-dropbox:before,
213 | .fi-social-evernote:before,
214 | .fi-social-facebook:before,
215 | .fi-social-flickr:before,
216 | .fi-social-forrst:before,
217 | .fi-social-foursquare:before,
218 | .fi-social-game-center:before,
219 | .fi-social-github:before,
220 | .fi-social-google-plus:before,
221 | .fi-social-hacker-news:before,
222 | .fi-social-hi5:before,
223 | .fi-social-instagram:before,
224 | .fi-social-joomla:before,
225 | .fi-social-lastfm:before,
226 | .fi-social-linkedin:before,
227 | .fi-social-medium:before,
228 | .fi-social-myspace:before,
229 | .fi-social-orkut:before,
230 | .fi-social-path:before,
231 | .fi-social-picasa:before,
232 | .fi-social-pinterest:before,
233 | .fi-social-rdio:before,
234 | .fi-social-reddit:before,
235 | .fi-social-skillshare:before,
236 | .fi-social-skype:before,
237 | .fi-social-smashing-mag:before,
238 | .fi-social-snapchat:before,
239 | .fi-social-spotify:before,
240 | .fi-social-squidoo:before,
241 | .fi-social-stack-overflow:before,
242 | .fi-social-steam:before,
243 | .fi-social-stumbleupon:before,
244 | .fi-social-treehouse:before,
245 | .fi-social-tumblr:before,
246 | .fi-social-twitter:before,
247 | .fi-social-vimeo:before,
248 | .fi-social-windows:before,
249 | .fi-social-xbox:before,
250 | .fi-social-yahoo:before,
251 | .fi-social-yelp:before,
252 | .fi-social-youtube:before,
253 | .fi-social-zerply:before,
254 | .fi-social-zurb:before,
255 | .fi-sound:before,
256 | .fi-star:before,
257 | .fi-stop:before,
258 | .fi-strikethrough:before,
259 | .fi-subscript:before,
260 | .fi-superscript:before,
261 | .fi-tablet-landscape:before,
262 | .fi-tablet-portrait:before,
263 | .fi-target-two:before,
264 | .fi-target:before,
265 | .fi-telephone-accessible:before,
266 | .fi-telephone:before,
267 | .fi-text-color:before,
268 | .fi-thumbnails:before,
269 | .fi-ticket:before,
270 | .fi-torso-business:before,
271 | .fi-torso-female:before,
272 | .fi-torso:before,
273 | .fi-torsos-all-female:before,
274 | .fi-torsos-all:before,
275 | .fi-torsos-female-male:before,
276 | .fi-torsos-male-female:before,
277 | .fi-torsos:before,
278 | .fi-trash:before,
279 | .fi-trees:before,
280 | .fi-trophy:before,
281 | .fi-underline:before,
282 | .fi-universal-access:before,
283 | .fi-unlink:before,
284 | .fi-unlock:before,
285 | .fi-upload-cloud:before,
286 | .fi-upload:before,
287 | .fi-usb:before,
288 | .fi-video:before,
289 | .fi-volume-none:before,
290 | .fi-volume-strike:before,
291 | .fi-volume:before,
292 | .fi-web:before,
293 | .fi-wheelchair:before,
294 | .fi-widget:before,
295 | .fi-wrench:before,
296 | .fi-x-circle:before,
297 | .fi-x:before,
298 | .fi-yen:before,
299 | .fi-zoom-in:before,
300 | .fi-zoom-out:before {
301 | font-family: "foundation-icons";
302 | font-style: normal;
303 | font-weight: normal;
304 | font-variant: normal;
305 | text-transform: none;
306 | line-height: 1;
307 | -webkit-font-smoothing: antialiased;
308 | display: inline-block;
309 | text-decoration: inherit;
310 | }
311 |
312 | .fi-address-book:before { content: "\f100"; }
313 | .fi-alert:before { content: "\f101"; }
314 | .fi-align-center:before { content: "\f102"; }
315 | .fi-align-justify:before { content: "\f103"; }
316 | .fi-align-left:before { content: "\f104"; }
317 | .fi-align-right:before { content: "\f105"; }
318 | .fi-anchor:before { content: "\f106"; }
319 | .fi-annotate:before { content: "\f107"; }
320 | .fi-archive:before { content: "\f108"; }
321 | .fi-arrow-down:before { content: "\f109"; }
322 | .fi-arrow-left:before { content: "\f10a"; }
323 | .fi-arrow-right:before { content: "\f10b"; }
324 | .fi-arrow-up:before { content: "\f10c"; }
325 | .fi-arrows-compress:before { content: "\f10d"; }
326 | .fi-arrows-expand:before { content: "\f10e"; }
327 | .fi-arrows-in:before { content: "\f10f"; }
328 | .fi-arrows-out:before { content: "\f110"; }
329 | .fi-asl:before { content: "\f111"; }
330 | .fi-asterisk:before { content: "\f112"; }
331 | .fi-at-sign:before { content: "\f113"; }
332 | .fi-background-color:before { content: "\f114"; }
333 | .fi-battery-empty:before { content: "\f115"; }
334 | .fi-battery-full:before { content: "\f116"; }
335 | .fi-battery-half:before { content: "\f117"; }
336 | .fi-bitcoin-circle:before { content: "\f118"; }
337 | .fi-bitcoin:before { content: "\f119"; }
338 | .fi-blind:before { content: "\f11a"; }
339 | .fi-bluetooth:before { content: "\f11b"; }
340 | .fi-bold:before { content: "\f11c"; }
341 | .fi-book-bookmark:before { content: "\f11d"; }
342 | .fi-book:before { content: "\f11e"; }
343 | .fi-bookmark:before { content: "\f11f"; }
344 | .fi-braille:before { content: "\f120"; }
345 | .fi-burst-new:before { content: "\f121"; }
346 | .fi-burst-sale:before { content: "\f122"; }
347 | .fi-burst:before { content: "\f123"; }
348 | .fi-calendar:before { content: "\f124"; }
349 | .fi-camera:before { content: "\f125"; }
350 | .fi-check:before { content: "\f126"; }
351 | .fi-checkbox:before { content: "\f127"; }
352 | .fi-clipboard-notes:before { content: "\f128"; }
353 | .fi-clipboard-pencil:before { content: "\f129"; }
354 | .fi-clipboard:before { content: "\f12a"; }
355 | .fi-clock:before { content: "\f12b"; }
356 | .fi-closed-caption:before { content: "\f12c"; }
357 | .fi-cloud:before { content: "\f12d"; }
358 | .fi-comment-minus:before { content: "\f12e"; }
359 | .fi-comment-quotes:before { content: "\f12f"; }
360 | .fi-comment-video:before { content: "\f130"; }
361 | .fi-comment:before { content: "\f131"; }
362 | .fi-comments:before { content: "\f132"; }
363 | .fi-compass:before { content: "\f133"; }
364 | .fi-contrast:before { content: "\f134"; }
365 | .fi-credit-card:before { content: "\f135"; }
366 | .fi-crop:before { content: "\f136"; }
367 | .fi-crown:before { content: "\f137"; }
368 | .fi-css3:before { content: "\f138"; }
369 | .fi-database:before { content: "\f139"; }
370 | .fi-die-five:before { content: "\f13a"; }
371 | .fi-die-four:before { content: "\f13b"; }
372 | .fi-die-one:before { content: "\f13c"; }
373 | .fi-die-six:before { content: "\f13d"; }
374 | .fi-die-three:before { content: "\f13e"; }
375 | .fi-die-two:before { content: "\f13f"; }
376 | .fi-dislike:before { content: "\f140"; }
377 | .fi-dollar-bill:before { content: "\f141"; }
378 | .fi-dollar:before { content: "\f142"; }
379 | .fi-download:before { content: "\f143"; }
380 | .fi-eject:before { content: "\f144"; }
381 | .fi-elevator:before { content: "\f145"; }
382 | .fi-euro:before { content: "\f146"; }
383 | .fi-eye:before { content: "\f147"; }
384 | .fi-fast-forward:before { content: "\f148"; }
385 | .fi-female-symbol:before { content: "\f149"; }
386 | .fi-female:before { content: "\f14a"; }
387 | .fi-filter:before { content: "\f14b"; }
388 | .fi-first-aid:before { content: "\f14c"; }
389 | .fi-flag:before { content: "\f14d"; }
390 | .fi-folder-add:before { content: "\f14e"; }
391 | .fi-folder-lock:before { content: "\f14f"; }
392 | .fi-folder:before { content: "\f150"; }
393 | .fi-foot:before { content: "\f151"; }
394 | .fi-foundation:before { content: "\f152"; }
395 | .fi-graph-bar:before { content: "\f153"; }
396 | .fi-graph-horizontal:before { content: "\f154"; }
397 | .fi-graph-pie:before { content: "\f155"; }
398 | .fi-graph-trend:before { content: "\f156"; }
399 | .fi-guide-dog:before { content: "\f157"; }
400 | .fi-hearing-aid:before { content: "\f158"; }
401 | .fi-heart:before { content: "\f159"; }
402 | .fi-home:before { content: "\f15a"; }
403 | .fi-html5:before { content: "\f15b"; }
404 | .fi-indent-less:before { content: "\f15c"; }
405 | .fi-indent-more:before { content: "\f15d"; }
406 | .fi-info:before { content: "\f15e"; }
407 | .fi-italic:before { content: "\f15f"; }
408 | .fi-key:before { content: "\f160"; }
409 | .fi-laptop:before { content: "\f161"; }
410 | .fi-layout:before { content: "\f162"; }
411 | .fi-lightbulb:before { content: "\f163"; }
412 | .fi-like:before { content: "\f164"; }
413 | .fi-link:before { content: "\f165"; }
414 | .fi-list-bullet:before { content: "\f166"; }
415 | .fi-list-number:before { content: "\f167"; }
416 | .fi-list-thumbnails:before { content: "\f168"; }
417 | .fi-list:before { content: "\f169"; }
418 | .fi-lock:before { content: "\f16a"; }
419 | .fi-loop:before { content: "\f16b"; }
420 | .fi-magnifying-glass:before { content: "\f16c"; }
421 | .fi-mail:before { content: "\f16d"; }
422 | .fi-male-female:before { content: "\f16e"; }
423 | .fi-male-symbol:before { content: "\f16f"; }
424 | .fi-male:before { content: "\f170"; }
425 | .fi-map:before { content: "\f171"; }
426 | .fi-marker:before { content: "\f172"; }
427 | .fi-megaphone:before { content: "\f173"; }
428 | .fi-microphone:before { content: "\f174"; }
429 | .fi-minus-circle:before { content: "\f175"; }
430 | .fi-minus:before { content: "\f176"; }
431 | .fi-mobile-signal:before { content: "\f177"; }
432 | .fi-mobile:before { content: "\f178"; }
433 | .fi-monitor:before { content: "\f179"; }
434 | .fi-mountains:before { content: "\f17a"; }
435 | .fi-music:before { content: "\f17b"; }
436 | .fi-next:before { content: "\f17c"; }
437 | .fi-no-dogs:before { content: "\f17d"; }
438 | .fi-no-smoking:before { content: "\f17e"; }
439 | .fi-page-add:before { content: "\f17f"; }
440 | .fi-page-copy:before { content: "\f180"; }
441 | .fi-page-csv:before { content: "\f181"; }
442 | .fi-page-delete:before { content: "\f182"; }
443 | .fi-page-doc:before { content: "\f183"; }
444 | .fi-page-edit:before { content: "\f184"; }
445 | .fi-page-export-csv:before { content: "\f185"; }
446 | .fi-page-export-doc:before { content: "\f186"; }
447 | .fi-page-export-pdf:before { content: "\f187"; }
448 | .fi-page-export:before { content: "\f188"; }
449 | .fi-page-filled:before { content: "\f189"; }
450 | .fi-page-multiple:before { content: "\f18a"; }
451 | .fi-page-pdf:before { content: "\f18b"; }
452 | .fi-page-remove:before { content: "\f18c"; }
453 | .fi-page-search:before { content: "\f18d"; }
454 | .fi-page:before { content: "\f18e"; }
455 | .fi-paint-bucket:before { content: "\f18f"; }
456 | .fi-paperclip:before { content: "\f190"; }
457 | .fi-pause:before { content: "\f191"; }
458 | .fi-paw:before { content: "\f192"; }
459 | .fi-paypal:before { content: "\f193"; }
460 | .fi-pencil:before { content: "\f194"; }
461 | .fi-photo:before { content: "\f195"; }
462 | .fi-play-circle:before { content: "\f196"; }
463 | .fi-play-video:before { content: "\f197"; }
464 | .fi-play:before { content: "\f198"; }
465 | .fi-plus:before { content: "\f199"; }
466 | .fi-pound:before { content: "\f19a"; }
467 | .fi-power:before { content: "\f19b"; }
468 | .fi-previous:before { content: "\f19c"; }
469 | .fi-price-tag:before { content: "\f19d"; }
470 | .fi-pricetag-multiple:before { content: "\f19e"; }
471 | .fi-print:before { content: "\f19f"; }
472 | .fi-prohibited:before { content: "\f1a0"; }
473 | .fi-projection-screen:before { content: "\f1a1"; }
474 | .fi-puzzle:before { content: "\f1a2"; }
475 | .fi-quote:before { content: "\f1a3"; }
476 | .fi-record:before { content: "\f1a4"; }
477 | .fi-refresh:before { content: "\f1a5"; }
478 | .fi-results-demographics:before { content: "\f1a6"; }
479 | .fi-results:before { content: "\f1a7"; }
480 | .fi-rewind-ten:before { content: "\f1a8"; }
481 | .fi-rewind:before { content: "\f1a9"; }
482 | .fi-rss:before { content: "\f1aa"; }
483 | .fi-safety-cone:before { content: "\f1ab"; }
484 | .fi-save:before { content: "\f1ac"; }
485 | .fi-share:before { content: "\f1ad"; }
486 | .fi-sheriff-badge:before { content: "\f1ae"; }
487 | .fi-shield:before { content: "\f1af"; }
488 | .fi-shopping-bag:before { content: "\f1b0"; }
489 | .fi-shopping-cart:before { content: "\f1b1"; }
490 | .fi-shuffle:before { content: "\f1b2"; }
491 | .fi-skull:before { content: "\f1b3"; }
492 | .fi-social-500px:before { content: "\f1b4"; }
493 | .fi-social-adobe:before { content: "\f1b5"; }
494 | .fi-social-amazon:before { content: "\f1b6"; }
495 | .fi-social-android:before { content: "\f1b7"; }
496 | .fi-social-apple:before { content: "\f1b8"; }
497 | .fi-social-behance:before { content: "\f1b9"; }
498 | .fi-social-bing:before { content: "\f1ba"; }
499 | .fi-social-blogger:before { content: "\f1bb"; }
500 | .fi-social-delicious:before { content: "\f1bc"; }
501 | .fi-social-designer-news:before { content: "\f1bd"; }
502 | .fi-social-deviant-art:before { content: "\f1be"; }
503 | .fi-social-digg:before { content: "\f1bf"; }
504 | .fi-social-dribbble:before { content: "\f1c0"; }
505 | .fi-social-drive:before { content: "\f1c1"; }
506 | .fi-social-dropbox:before { content: "\f1c2"; }
507 | .fi-social-evernote:before { content: "\f1c3"; }
508 | .fi-social-facebook:before { content: "\f1c4"; }
509 | .fi-social-flickr:before { content: "\f1c5"; }
510 | .fi-social-forrst:before { content: "\f1c6"; }
511 | .fi-social-foursquare:before { content: "\f1c7"; }
512 | .fi-social-game-center:before { content: "\f1c8"; }
513 | .fi-social-github:before { content: "\f1c9"; }
514 | .fi-social-google-plus:before { content: "\f1ca"; }
515 | .fi-social-hacker-news:before { content: "\f1cb"; }
516 | .fi-social-hi5:before { content: "\f1cc"; }
517 | .fi-social-instagram:before { content: "\f1cd"; }
518 | .fi-social-joomla:before { content: "\f1ce"; }
519 | .fi-social-lastfm:before { content: "\f1cf"; }
520 | .fi-social-linkedin:before { content: "\f1d0"; }
521 | .fi-social-medium:before { content: "\f1d1"; }
522 | .fi-social-myspace:before { content: "\f1d2"; }
523 | .fi-social-orkut:before { content: "\f1d3"; }
524 | .fi-social-path:before { content: "\f1d4"; }
525 | .fi-social-picasa:before { content: "\f1d5"; }
526 | .fi-social-pinterest:before { content: "\f1d6"; }
527 | .fi-social-rdio:before { content: "\f1d7"; }
528 | .fi-social-reddit:before { content: "\f1d8"; }
529 | .fi-social-skillshare:before { content: "\f1d9"; }
530 | .fi-social-skype:before { content: "\f1da"; }
531 | .fi-social-smashing-mag:before { content: "\f1db"; }
532 | .fi-social-snapchat:before { content: "\f1dc"; }
533 | .fi-social-spotify:before { content: "\f1dd"; }
534 | .fi-social-squidoo:before { content: "\f1de"; }
535 | .fi-social-stack-overflow:before { content: "\f1df"; }
536 | .fi-social-steam:before { content: "\f1e0"; }
537 | .fi-social-stumbleupon:before { content: "\f1e1"; }
538 | .fi-social-treehouse:before { content: "\f1e2"; }
539 | .fi-social-tumblr:before { content: "\f1e3"; }
540 | .fi-social-twitter:before { content: "\f1e4"; }
541 | .fi-social-vimeo:before { content: "\f1e5"; }
542 | .fi-social-windows:before { content: "\f1e6"; }
543 | .fi-social-xbox:before { content: "\f1e7"; }
544 | .fi-social-yahoo:before { content: "\f1e8"; }
545 | .fi-social-yelp:before { content: "\f1e9"; }
546 | .fi-social-youtube:before { content: "\f1ea"; }
547 | .fi-social-zerply:before { content: "\f1eb"; }
548 | .fi-social-zurb:before { content: "\f1ec"; }
549 | .fi-sound:before { content: "\f1ed"; }
550 | .fi-star:before { content: "\f1ee"; }
551 | .fi-stop:before { content: "\f1ef"; }
552 | .fi-strikethrough:before { content: "\f1f0"; }
553 | .fi-subscript:before { content: "\f1f1"; }
554 | .fi-superscript:before { content: "\f1f2"; }
555 | .fi-tablet-landscape:before { content: "\f1f3"; }
556 | .fi-tablet-portrait:before { content: "\f1f4"; }
557 | .fi-target-two:before { content: "\f1f5"; }
558 | .fi-target:before { content: "\f1f6"; }
559 | .fi-telephone-accessible:before { content: "\f1f7"; }
560 | .fi-telephone:before { content: "\f1f8"; }
561 | .fi-text-color:before { content: "\f1f9"; }
562 | .fi-thumbnails:before { content: "\f1fa"; }
563 | .fi-ticket:before { content: "\f1fb"; }
564 | .fi-torso-business:before { content: "\f1fc"; }
565 | .fi-torso-female:before { content: "\f1fd"; }
566 | .fi-torso:before { content: "\f1fe"; }
567 | .fi-torsos-all-female:before { content: "\f1ff"; }
568 | .fi-torsos-all:before { content: "\f200"; }
569 | .fi-torsos-female-male:before { content: "\f201"; }
570 | .fi-torsos-male-female:before { content: "\f202"; }
571 | .fi-torsos:before { content: "\f203"; }
572 | .fi-trash:before { content: "\f204"; }
573 | .fi-trees:before { content: "\f205"; }
574 | .fi-trophy:before { content: "\f206"; }
575 | .fi-underline:before { content: "\f207"; }
576 | .fi-universal-access:before { content: "\f208"; }
577 | .fi-unlink:before { content: "\f209"; }
578 | .fi-unlock:before { content: "\f20a"; }
579 | .fi-upload-cloud:before { content: "\f20b"; }
580 | .fi-upload:before { content: "\f20c"; }
581 | .fi-usb:before { content: "\f20d"; }
582 | .fi-video:before { content: "\f20e"; }
583 | .fi-volume-none:before { content: "\f20f"; }
584 | .fi-volume-strike:before { content: "\f210"; }
585 | .fi-volume:before { content: "\f211"; }
586 | .fi-web:before { content: "\f212"; }
587 | .fi-wheelchair:before { content: "\f213"; }
588 | .fi-widget:before { content: "\f214"; }
589 | .fi-wrench:before { content: "\f215"; }
590 | .fi-x-circle:before { content: "\f216"; }
591 | .fi-x:before { content: "\f217"; }
592 | .fi-yen:before { content: "\f218"; }
593 | .fi-zoom-in:before { content: "\f219"; }
594 | .fi-zoom-out:before { content: "\f21a"; }
595 |
--------------------------------------------------------------------------------
/pyprint/background/static/css/foundation-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/css/foundation-icons.eot
--------------------------------------------------------------------------------
/pyprint/background/static/css/foundation-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/css/foundation-icons.ttf
--------------------------------------------------------------------------------
/pyprint/background/static/css/foundation-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/css/foundation-icons.woff
--------------------------------------------------------------------------------
/pyprint/background/static/css/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #333;
3 | }
4 |
5 | header {
6 | background: #4CCA83;
7 | color: #FFF;
8 | border: none;
9 | }
10 |
11 | header > h1 {
12 | margin: 13px 10px;
13 | display: inline-block;
14 | font-size: 1.5em;
15 | }
16 |
17 | header > h2 {
18 | margin: 20px 10px;
19 | float: right;
20 | display: inline-block;
21 | }
22 |
23 | header > ul {
24 | position: absolute;
25 | margin: 0;
26 | padding: 0;
27 | width: 180px;
28 | list-style: none;
29 | background: #333;
30 | margin-top: 1px;
31 | border: none;
32 | }
33 |
34 | .navbar > ul > li {
35 | display: list-item;
36 | }
37 |
38 | .panel-container {
39 | box-shadow: #999 1px 1px 2px 1px inset;
40 | background: #EEE;
41 | padding: 20px;
42 | margin-left: 180px;
43 | margin-top: -20px;
44 | }
45 |
46 | .panel {
47 | border-radius: 0px;
48 | min-height: 500px;
49 | }
50 |
51 | .td-operate {
52 | text-align: center;
53 | }
54 |
55 | .td-operate > a {
56 | color: #333;
57 | }
58 |
59 | .td-title a {
60 | word-break: break-all;
61 | color: #666;
62 | }
63 |
64 | .td-title a:hover {
65 | text-decoration: blink;
66 | color: #35aadc;
67 | }
68 |
69 | .submenu {
70 | padding: 13px 0 13px 15px;
71 | text-decoration: blink;
72 | display: block;
73 | color: #FFF;
74 | font-weight: 600;
75 | }
76 |
77 | .selected-item {
78 | background-color: #35aadc;
79 | }
80 |
81 | .arrow::after {
82 | clear: both;
83 | position: absolute;
84 | right: 0px;
85 | content: " ";
86 | width:0;
87 | height:0;
88 | border-width:10px;
89 | border-style:solid dashed dashed dashed;
90 | border-color:transparent #FFF transparent transparent;
91 | -webkit-transition: margin 400ms;
92 | -moz-transition: margin 400ms;
93 | transition: margin 400ms;
94 | pointer-events: none;
95 | }
96 |
97 | .submenu {
98 | -webkit-transition: background 400ms;
99 | -moz-transition: background 400ms;
100 | transition: background 400ms;
101 | }
102 |
103 | .selected-item + .arrow::after {
104 | margin-top: -46px;
105 | }
106 |
107 | /*.selected-item +*/
108 | .selected-item + a:hover::after{
109 | margin-top: 0;
110 | }
111 |
112 | .submenu:hover {
113 | background-color: #e14d43;
114 | color: #FFF;
115 | text-decoration: blink;
116 | }
117 |
118 | .submenu:hover + .arrow::after {
119 | margin-top: -46px;
120 | pointer-events: none;
121 | }
122 |
123 | .panel-default > .panel-heading {
124 | background-image: none;
125 | background-color: #EEE;
126 | }
127 |
128 | footer {
129 | font-size: 1.2em;
130 | padding-top: 10px;
131 | text-align: center;
132 | color: #FFF;
133 | }
134 |
135 | .login-form {
136 | width: 50%;
137 | margin: 0 auto;
138 | text-align: center;
139 | padding: 20px;
140 | }
141 |
142 | footer a {
143 | color: #FFF;
144 | }
145 |
146 | footer a:hover {
147 | color: #FFF;
148 | }
149 |
150 | .none-style-button {
151 | background: transparent;
152 | border: none;
153 | }
154 |
155 | .alert {
156 | display: none;
157 | }
158 |
159 | .new-post-button {
160 | margin: -5px;
161 | }
162 |
163 |
164 | input,
165 | button,
166 | select,
167 | option,
168 | textarea {
169 | outline: none;
170 | }
171 |
172 | .post-title {
173 | width: 100%;
174 | font-size: 32px;
175 | padding: 4px 10px;
176 | border: 0;
177 | box-shadow: 0 -1px 4px #FFFFFA inset;
178 | -webkit-transition: box-shadow 400ms;
179 | -moz-transition: box-shadow 400ms;
180 | transition: box-shadow 400ms;
181 | color: #6E6868;
182 | background: #FFFFF9;
183 | }
184 |
185 | .post-title:focus {
186 | box-shadow: 0 -1px 12px #DEE inset;
187 | }
188 |
189 | .post-content {
190 | padding: 5px 10px;
191 | width: 100%;
192 | resize: none;
193 | border: none;
194 | height: 400px;
195 | box-shadow: 0 2px 3px #CCC inset;
196 | background: #FFFFF9;
197 | }
198 |
199 | .post-button {
200 | float: right;
201 | margin-top: -35px;
202 | margin-right: 15px;
203 | }
204 |
205 | @media screen and (max-width:980px){
206 | .login-form {
207 | width: 100%;
208 | }
209 |
210 | .td-operate {
211 | display: none;
212 | }
213 |
214 | .td-title {
215 | width: 100%;
216 | }
217 | }
--------------------------------------------------------------------------------
/pyprint/background/static/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/pyprint/background/static/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/pyprint/background/static/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/background/static/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/pyprint/background/templates/add_post.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block navbar %}
4 |
5 |
6 | {% endblock %}
7 |
8 | {% block body %}
9 |
10 |
11 |
12 | New Article
13 |
14 |
15 |
20 |
21 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/background/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Background
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 | Kamisama
19 |
20 | {% block navbar %}
21 | {% endblock %}
22 |
23 |
24 |
25 |
26 | {% block body %}
27 | {% endblock %}
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/pyprint/background/templates/links.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block navbar %}
4 |
5 |
6 | {% endblock %}
7 |
8 | {% block body %}
9 |
10 |
11 | Failed!
12 |
13 |
14 |
15 | Success!
16 |
17 |
18 |
Friends Links
19 |
20 |
35 |
36 |
37 |
38 |
39 |
40 | Name |
41 | Link |
42 | Delete |
43 |
44 |
45 |
46 | {% for link in links %}
47 |
48 | {{ link.name }} |
49 | http://{{ link.url }} |
50 | |
51 |
52 | {% endfor %}
53 |
54 |
55 |
56 |
57 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/background/templates/login.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 |
6 | Login
7 |
8 |
19 |
20 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/background/templates/posts.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block navbar %}
4 |
5 |
6 | {% endblock %}
7 |
8 | {% block body %}
9 |
10 |
11 | Failed!
12 |
13 |
14 |
15 | Success!
16 |
17 |
18 |
19 |
20 |
21 |
22 | Aritlce Title |
23 | Edit |
24 | Delete |
25 |
26 |
27 |
28 | {% for post in posts %}
29 |
30 | {{ post.title }} |
31 | |
32 | |
33 |
34 | {% endfor %}
35 |
36 |
37 |
42 |
43 |
63 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/constants.py:
--------------------------------------------------------------------------------
1 | POST = 'post'
2 | DIARY = 'diary'
3 |
4 | POST_ENUMS = (POST, DIARY, )
--------------------------------------------------------------------------------
/pyprint/database.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy.ext.declarative import declarative_base
2 | from sqlalchemy.orm import scoped_session, sessionmaker
3 | from sqlalchemy import create_engine
4 |
5 | from settings import connect_str
6 |
7 |
8 | engine = create_engine(connect_str, echo=True, pool_recycle=3600)
9 | Base = declarative_base()
10 | db = scoped_session(sessionmaker(bind=engine))
11 |
--------------------------------------------------------------------------------
/pyprint/handler.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 | from jinja2 import Environment, FileSystemLoader, TemplateNotFound
3 |
4 | import database
5 | from utils import markdown, fix_lazy_load, markdown_image
6 |
7 |
8 | class JinjaEnvironment(object):
9 | _flag = None
10 | _jinja_env = None
11 | _background_env = None
12 |
13 | def __new__(cls, *args, **kwargs):
14 | if not 'path' in kwargs:
15 | raise Exception('Path of FileSystemLoader required')
16 |
17 | if not cls._jinja_env and not kwargs['is_background']:
18 | cls._jinja_env = Environment(loader=FileSystemLoader(kwargs['path']))
19 | if not cls._background_env and kwargs['is_background']:
20 | cls._background_env = Environment(loader=FileSystemLoader(kwargs['path']))
21 |
22 | return cls._jinja_env if not kwargs['is_background'] else cls._background_env
23 |
24 |
25 | class JinjaTemplateMixin(object):
26 | """A simple mixin of jinja2
27 |
28 | From: http://bibhas.in/blog/using-jinja2-as-the-template-engine-for-tornado-web-framework/
29 | """
30 | def _render(self, path, template_name, is_background=False, **kwargs):
31 | env = JinjaEnvironment(path=path, is_background=is_background)
32 | env.filters['markdown'] = markdown
33 | env.filters['markdown_image'] = markdown_image
34 | env.filters['fix_lazy_load'] = fix_lazy_load
35 |
36 | try:
37 | template = env.get_template(template_name)
38 | except TemplateNotFound:
39 | raise TemplateNotFound(template_name)
40 | return template.render(settings=self.settings, **kwargs)
41 |
42 | def _jinja2_render(self, template_name, **kwargs):
43 | return self._render(self.settings['template_path'], template_name, **kwargs)
44 |
45 | def _background_render(self, template_name, **kwargs):
46 | return self._render(self.settings['background_template_path'], template_name,
47 | is_background=True, **kwargs)
48 |
49 |
50 | class BaseHandler(tornado.web.RequestHandler, JinjaTemplateMixin):
51 | @property
52 | def orm(self):
53 | return database.db()
54 |
55 | def on_finish(self):
56 | database.db.remove()
57 |
58 | def render(self, template_name, headers=None, **kwargs):
59 | """Override render method
60 | """
61 | if headers:
62 | for key, value in headers.iteritems():
63 | self.set_header(key, value)
64 |
65 | self.set_header('X-Something', 'cHJwcnBycHJwcnBycHJwcnByLmxvbGkuY2x1Yg')
66 | self.set_header('X-Powered-by', 'PyPrint')
67 | self.write(self._jinja2_render(template_name, is_pjax=bool(self.request.headers.get('X-Pjax', None)),
68 | **kwargs))
69 | self.finish()
70 |
71 | def background_render(self, template_name, **kwargs):
72 | self.write(self._background_render(template_name, **kwargs))
73 | self.finish()
74 |
75 | def get_current_user(self):
76 | return self.get_secure_cookie('username')
77 |
--------------------------------------------------------------------------------
/pyprint/localsettings.example.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | ROOT_DIR = os.path.abspath('.')
4 | connect_str = 'sqlite:///{path}'.format(path=os.path.join(ROOT_DIR, 'pyprint.db3'))
5 | cookie_secret = '3F8PhdGMSyuI5AjFM5Da8+/X2mP8XEzHtC/j57v3r6E='
6 |
7 | username = 'admin'
8 | password = 'admin'
--------------------------------------------------------------------------------
/pyprint/models.py:
--------------------------------------------------------------------------------
1 | from datetime import date
2 | from hashlib import md5
3 |
4 | from sqlalchemy import Column, Table
5 | from sqlalchemy import Text, String, Date, Integer, ForeignKey, Enum
6 | from sqlalchemy.orm import relationship
7 |
8 | from database import Base, engine
9 | from constants import POST_ENUMS, POST
10 |
11 |
12 |
13 | posts_tags = Table(
14 | 'posts_tags', Base.metadata,
15 | Column('post_id', Integer, ForeignKey('posts.id')),
16 | Column('tag_id', Integer, ForeignKey('tags.id')),
17 | )
18 |
19 |
20 | class Tag(Base):
21 | __tablename__ = 'tags'
22 |
23 | id = Column(Integer, primary_key=True, autoincrement=True)
24 | slug = Column(String(50), unique=True, nullable=False)
25 |
26 | def __repr__(self):
27 | return '' % self.slug
28 |
29 |
30 | class Post(Base):
31 | __tablename__ = 'posts'
32 |
33 | id = Column(Integer, primary_key=True, autoincrement=True)
34 | title = Column(String(200), unique=True, nullable=False)
35 | tags = relationship('Tag', secondary=posts_tags, backref='posts')
36 | created_time = Column(Date, default=date.today())
37 | content = Column(Text)
38 | type = Column(Enum(*POST_ENUMS), default=POST)
39 | password = Column(String(10), nullable=True)
40 |
41 | def __repr__(self):
42 | return '' % self.title
43 |
44 |
45 | class Link(Base):
46 | __tablename__ = 'links'
47 |
48 | id = Column(Integer, primary_key=True, autoincrement=True)
49 | name = Column(String(100))
50 | url = Column(String(100))
51 |
52 | def __repr__(self):
53 | return '' % self.url
54 |
55 |
56 | class User(Base):
57 | __tablename__ = 'users'
58 |
59 | id = Column(Integer, primary_key=True, autoincrement=True)
60 | username = Column(String(20))
61 | password = Column(String(32))
62 |
63 | def check(self, password):
64 | return self.password == md5(password).hexdigest()
65 |
66 | def __repr__(self):
67 | return '' % self.username
68 |
69 |
70 | metadata = Base.metadata
71 |
72 | if __name__ == "__main__":
73 | metadata.create_all(engine)
74 |
--------------------------------------------------------------------------------
/pyprint/settings.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # website settings
3 | username = 'Ricter'
4 | email = 'RicterZheng@gmail.com'
5 | title = 'Ricter\'s Blog'
6 | motto = u'初心を忘れず'
7 | disqus_shortname = 'ricterblog2'
8 |
9 | # themes name
10 | theme = 'mdl'
11 |
12 | # development
13 | debug = True
14 |
15 |
16 | analytics_code = '''
17 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
18 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
19 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
20 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
21 |
22 | ga('create', 'UA-53662402-1', 'auto');
23 | ga('send', 'pageview');
24 | '''
25 |
26 | post_of_page = 3
27 |
28 |
29 | try:
30 | from localsettings import connect_str, cookie_secret
31 | except ImportError:
32 | raise Exception('Please add connect_str and cookie_secret in localsettings.py')
33 |
34 |
35 | try:
36 | module = __import__('themes.%s.config' % theme, globals(), locals(), ['*'])
37 | for k in dir(module):
38 | locals()[k] = getattr(module, k)
39 | except ImportError:
40 | pass
41 |
--------------------------------------------------------------------------------
/pyprint/themes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/__init__.py
--------------------------------------------------------------------------------
/pyprint/themes/clean/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/clean/__init__.py
--------------------------------------------------------------------------------
/pyprint/themes/clean/config.py:
--------------------------------------------------------------------------------
1 | # Config file of theme
2 |
3 | post_of_page = 16
4 |
--------------------------------------------------------------------------------
/pyprint/themes/clean/static/css/style.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | width: 800px;
3 | margin: 0 auto;
4 | }
5 |
6 | .container {
7 | margin: 0 auto;
8 | }
9 |
10 | .date {
11 | float: right;
12 | }
13 |
14 | input,button,select,textarea{outline:none}
15 |
16 | .name a {
17 | font-size: 48px;
18 | text-decoration: none;
19 | }
20 |
21 | aside {
22 | margin-bottom: 1.2em;
23 | }
24 |
25 | .post-title {
26 | font-size: 2.0em;
27 | }
28 |
29 | .post-title a {
30 | text-decoration: blink;
31 | }
32 |
33 | .center {
34 | display: block;
35 | margin: 0 auto;
36 | text-align: center;
37 | }
38 |
39 | nav.nav {
40 | padding-top: 0.67em;
41 | }
42 |
43 | header > nav > a {
44 | display: inline-block;
45 | padding: 0 12px
46 | }
47 |
48 | .article, .archives {
49 | padding-bottom: 30px;
50 | margin-bottom: 40px;
51 | border-bottom: 2px solid #EEE;
52 | }
53 |
54 | h1,h2,h3,h4,h5,h6 {
55 | font-weight: 100;
56 | }
57 |
58 | .paging {
59 | display: table;
60 | width: 100%;
61 | padding-bottom: 20px;
62 | }
63 |
64 | .next {
65 | float: right;
66 | text-decoration: none;
67 | }
68 |
69 | .prev {
70 | float: left;
71 | text-decoration: none;
72 | }
73 |
74 |
75 | .content {
76 | margin: 0 40px;
77 | }
78 |
79 | .archive {
80 | font-size: 24px;
81 | width: 100%;
82 | white-space: nowrap;
83 | text-overflow: ellipsis;
84 | overflow: hidden;
85 | display: inline-block;
86 | }
87 |
88 | .archive > span {
89 | margin-right: 30px;
90 | }
91 |
92 | .tags {
93 | color: gray;
94 | font-size: 0.9em;
95 | }
96 |
97 | a.tag {
98 | margin: 0 3px;
99 | color: gray;
100 | }
101 |
102 | a.publish {
103 | text-decoration: none;
104 | }
105 |
106 | .pull-right {
107 | float: right;
108 | }
109 |
110 | textarea.post {
111 | resize: vertical;
112 | display: inline-block;
113 | width: 100%;
114 | height: 400px;
115 | border: 3px solid #CCC;
116 | margin-left: -3px;
117 | font-size: 18px;
118 | margin-bottom: 30px;
119 | font-family: "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft YaHei", "SimSun", sans-serif;
120 | }
121 |
122 | @media screen and (max-width: 600px) {
123 | .date {
124 | display: none;
125 | }
126 |
127 | .wrapper {
128 | width: 100%;
129 | }
130 |
131 | .content {
132 | margin: 0;
133 | }
134 | }
135 |
136 | @media screen and (max-width: 980px) {
137 | .wrapper {
138 | width: 100%;
139 | }
140 |
141 | .content {
142 | margin: 0;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/pyprint/themes/clean/static/css/yue.css:
--------------------------------------------------------------------------------
1 | /**
2 | * yue.css
3 | *
4 | * yue.css is designed for readable content.
5 | *
6 | * Copyright (c) 2013 by Hsiaoming Yang.
7 | */
8 |
9 |
10 |
11 | .yue {
12 | font: 400 18px/1.62 "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif;
13 | color: #444443;
14 | }
15 | .yue ::selection {
16 | background-color: rgba(0,0,0,0.2);
17 | }
18 | .yue h1,
19 | .yue h2,
20 | .yue h3,
21 | .yue h4,
22 | .yue h5,
23 | .yue h6 {
24 | font-family: "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft YaHei", "SimSun", sans-serif;
25 | color: #222223;
26 | }
27 | .yue h1 {
28 | font-size: 1.8em;
29 | margin: 0.67em 0;
30 | }
31 | .yue > h1 {
32 | margin-top: 0;
33 | font-size: 2em;
34 | }
35 | .yue h2 {
36 | font-size: 1.5em;
37 | margin: 0.83em 0;
38 | }
39 | .yue h3 {
40 | font-size: 1.17em;
41 | margin: 1em 0;
42 | }
43 | .yue h4,
44 | .yue h5,
45 | .yue h6 {
46 | font-size: 1em;
47 | margin: 1.6em 0 1em 0;
48 | }
49 | .yue h6 {
50 | font-weight: 500;
51 | }
52 | .yue p {
53 | margin-top: 0;
54 | margin-bottom: 1.64em;
55 | }
56 | .yue a {
57 | color: #111;
58 | word-wrap: break-word;
59 | }
60 | .yue a:hover {
61 | color: #555;
62 | }
63 | .yue strong,
64 | .yue b {
65 | font-weight: 700;
66 | color: #222;
67 | }
68 | .yue em,
69 | .yue i {
70 | font-style: italic;
71 | color: #222;
72 | }
73 | .yue img {
74 | max-width: 100%;
75 | height: auto;
76 | margin: 0.2em 0;
77 | }
78 | .yue a img {
79 | /* Remove border on IE */
80 | border: none;
81 | }
82 | .yue figure {
83 | position: relative;
84 | clear: both;
85 | outline: 0;
86 | margin: 10px 0 30px;
87 | padding: 0;
88 | }
89 | .yue figure img {
90 | display: block;
91 | max-width: 100%;
92 | margin: auto;
93 | -webkit-box-sizing: border-box;
94 | -moz-box-sizing: border-box;
95 | box-sizing: border-box;
96 | }
97 | .yue figure figcaption {
98 | position: relative;
99 | width: 100%;
100 | text-align: center;
101 | left: 0;
102 | margin-top: 10px;
103 | font-weight: 400;
104 | font-size: 14px;
105 | color: #666665;
106 | }
107 | .yue figure figcaption a {
108 | text-decoration: none;
109 | color: #666665;
110 | }
111 | .yue hr {
112 | display: block;
113 | width: 14%;
114 | margin: 40px auto 34px;
115 | border: 0 none;
116 | border-top: 3px solid #dededc;
117 | }
118 | .yue blockquote {
119 | margin: 0 0 1.64em 0;
120 | border-left: 3px solid #dadada;
121 | padding-left: 12px;
122 | color: #666664;
123 | }
124 | .yue blockquote a {
125 | color: #666664;
126 | }
127 | .yue ul,
128 | .yue ol {
129 | margin: 0 0 24px 6px;
130 | padding-left: 16px;
131 | }
132 | .yue ul {
133 | list-style-type: square;
134 | }
135 | .yue ol {
136 | list-style-type: decimal;
137 | }
138 | .yue li {
139 | margin-bottom: 0.2em;
140 | }
141 | .yue li ul,
142 | .yue li ol {
143 | margin-top: 0;
144 | margin-bottom: 0;
145 | margin-left: 14px;
146 | }
147 | .yue li ul {
148 | list-style-type: disc;
149 | }
150 | .yue li ul ul {
151 | list-style-type: circle;
152 | }
153 | .yue li p {
154 | margin: 0.4em 0 0.6em;
155 | }
156 | .yue .unstyled {
157 | list-style-type: none;
158 | margin: 0;
159 | padding: 0;
160 | }
161 | .yue code,
162 | .yue tt {
163 | color: #808080;
164 | font-size: 0.96em;
165 | background-color: #f9f9f7;
166 | padding: 1px 2px;
167 | border: 1px solid #dadada;
168 | border-radius: 3px;
169 | font-family: "Inconsolata", "Menlo", monospace;
170 | }
171 | .yue pre {
172 | margin: 1.64em 0;
173 | padding: 7px;
174 | border: none;
175 | border-left: 3px solid #dadada;
176 | padding-left: 10px;
177 | overflow: auto;
178 | line-height: 1.5;
179 | font-size: 0.96em;
180 | font-family: "Inconsolata", "Menlo", monospace;
181 | color: #4c4c4c;
182 | background-color: #f9f9f7;
183 | }
184 | .yue pre code,
185 | .yue pre tt {
186 | color: #4c4c4c;
187 | border: none;
188 | background: none;
189 | padding: 0;
190 | }
191 | .yue table {
192 | width: 100%;
193 | border-collapse: collapse;
194 | border-spacing: 0;
195 | margin-bottom: 1.5em;
196 | font-size: 0.96em;
197 | }
198 | .yue th,
199 | .yue td {
200 | text-align: left;
201 | padding: 4px 8px 4px 10px;
202 | border: 1px solid #dadada;
203 | }
204 | .yue td {
205 | vertical-align: top;
206 | }
207 | .yue tr:nth-child(even) {
208 | background-color: #efefee;
209 | }
210 | .yue iframe {
211 | display: block;
212 | max-width: 100%;
213 | margin-bottom: 30px;
214 | }
215 | .yue figure iframe {
216 | margin: auto;
217 | }
218 | .yue table pre {
219 | margin: 0;
220 | padding: 0;
221 | border: none;
222 | background: none;
223 | }
224 | .yue .highlight td:first-of-type pre {
225 | text-align: right;
226 | color: #aaa;
227 | }
228 | @media (min-width: 1100px) {
229 | .yue blockquote {
230 | margin-left: -24px;
231 | padding-left: 20px;
232 | border-width: 4px;
233 | }
234 | .yue blockquote blockquote {
235 | margin-left: 0;
236 | }
237 | .yue figure figcaption:before {
238 | width: 25%;
239 | margin-left: 75%;
240 | border-top: 1px solid #dededc;
241 | display: block;
242 | content: "";
243 | margin-bottom: 10px;
244 | }
245 | .yue figure figcaption {
246 | position: absolute;
247 | left: -172px;
248 | width: 150px;
249 | top: 0;
250 | text-align: right;
251 | margin-top: 0;
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/diaries.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | {% for diary in diaries %}
6 | -
7 | {{ diary.title }}
8 | {{ diary.created_time }}
9 |
10 | {% endfor %}
11 |
12 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ settings.username }}
4 | {{ settings.title }}
5 | {{ posts[0].created_time if posts }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | http://{{ url }}
14 |
15 | {% for post in posts %}
16 |
17 | {{ post.title }}
18 | http://{{ url }}/articles/{{ post.title }}
19 | http://{{ url }}/articles/{{ post.title }}
20 | {{ post.created_time }}
21 |
22 |
23 | {% endfor %}
24 |
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | {% for post in data.posts %}
6 | -
7 | {{ post.title }}
8 | {{ post.created_time }}
9 |
10 | {% endfor %}
11 |
12 |
13 |
17 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ title }} - {{ settings.title }}
9 |
10 |
11 |
12 |
13 |
14 | {{ settings.username }}
15 | {{ settings.motto }}
16 |
22 |
23 |
24 |
25 | {% block body %}
26 | {% endblock %}
27 |
28 |
33 |
34 |
37 |
38 |
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/links.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 |
4 | {% block body %}
5 |
6 | About Me
7 |
8 |
9 | 咱是 Ricter,学院倒数前十常驻,生物专业,目前休学,坐标帝都
10 | 安全研究员/CTF 赛棍/Python 渣渣开发者/前端苦手
11 | 勾搭咱第一标准是头像要萌,反正咱没 cp
12 | 哪里能找到我呢=口=..
13 | Email: RicterZheng@gmail.com
14 | QQ: r@loli.club
15 | Github: https://github.com/RicterZ
16 | Twitter: @RicterZ
17 | Weibo: @Ricter(名字经常换
18 | 另外打个广告
19 | 一个叫做 ACG Hacker 的群,总之就是喜欢 ACG 的黑阔的样子,ACG 圈的可以随便加,Hacker 的话头像要萌
20 | 再次强调..加群头像不萌一定会被拒绝,另外太中二的男孩子不要,欢迎妹子>/////<
21 | 反正群主日下来 i-ab、acgzone、bilibili、C站之类的网站一堆(咱不是群主
22 | 群号:
23 | 00110101 00110111 00110011 00110010 00110100 00111000 00110011 00110101
24 | 00110100 01100100 00110100 01100001 00110101 00110111 00110111 00110110
25 | 00110101 01100001 00110111 00110111 00110101 00110111 00110111 00110111
26 | 00110100 00110001 00110100 00110111 00110111 00111001 00110111 01100001
27 | 00110101 01100001 00110101 00110001 00110111 00111000 00110110 01100100
28 | 00110100 01100011 00110100 00110111 00110101 00110111 00110111 01100001
29 | 00110100 00110001 00110100 01100001 00110100 00110100 00110011 00110001
30 | 00110101 01100001 00110101 00110001 00110100 00110001 00110111 00110101
31 | 00110101 01100001 00110101 00110100 00110100 00111000 00110011 00110100
32 | 00110100 00110001 00110110 01100100 00110100 01100011 00110110 01100100
33 | 00110100 00110010 00110101 00110100 00110100 00111001 00110111 00110111
34 | 00110101 00110111 00110011 00110001 00110110 00110110 00110011 00110110
35 | 00110100 00110010 00110111 00110110 00110011 00110000 00110110 01100010
36 | 00110100 01100010 00110100 00110100 00110011 01100100 00110011 01100100
37 | 能解的开吧反正不难(ry
38 |
39 |
40 | My Friends
41 |
42 |
43 | {% for link in links %}
44 | - {{ link.name }}
45 | {% else %}
46 | I am alone ..
47 | {% endfor %}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
62 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/not_found.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 | Baka ..
5 |
6 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/clean/templates/post.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 |
4 | {% block body %}
5 |
6 |
10 |
11 |
12 | {{ post.content|markdown }}
13 |
14 |
15 | {% if post.tags %}
16 | Tagged in:
17 | {% for tag in post.tags %}
18 | {{ tag.slug }}
19 | {% if not loop.last %} / {% endif %}
20 | {% endfor %}
21 |
22 | {% endif %}
23 |
24 |
25 |
28 |
29 | {% if post.type == 'post' %}
30 |
38 | {% endif %}
39 | {% endblock %}
40 |
41 |
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/akarin.css:
--------------------------------------------------------------------------------
1 | article.not-found {
2 | text-align: center;
3 | }
4 |
5 | article.not-found > h3 {
6 | font-weight: 100;
7 | }
8 |
9 | article.not-found > img {
10 | width: 300px;
11 | margin: 0 auto;
12 | }
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/archives.css:
--------------------------------------------------------------------------------
1 | ul.posts-group > li {
2 | display: block;
3 | }
4 |
5 | ul.posts-group > li > h2 {
6 | font-weight: 100;
7 | }
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/foundation-icons.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Foundation Icons v 3.0
3 | * Made by ZURB 2013 http://zurb.com/playground/foundation-icon-fonts-3
4 | * MIT License
5 | */
6 |
7 | @font-face {
8 | font-family: "foundation-icons";
9 | src: url("foundation-icons.eot");
10 | src: url("foundation-icons.eot?#iefix") format("embedded-opentype"),
11 | url("foundation-icons.woff") format("woff"),
12 | url("foundation-icons.ttf") format("truetype"),
13 | url("foundation-icons.svg#fontcustom") format("svg");
14 | font-weight: normal;
15 | font-style: normal;
16 | }
17 |
18 | .fi-address-book:before,
19 | .fi-alert:before,
20 | .fi-align-center:before,
21 | .fi-align-justify:before,
22 | .fi-align-left:before,
23 | .fi-align-right:before,
24 | .fi-anchor:before,
25 | .fi-annotate:before,
26 | .fi-archive:before,
27 | .fi-arrow-down:before,
28 | .fi-arrow-left:before,
29 | .fi-arrow-right:before,
30 | .fi-arrow-up:before,
31 | .fi-arrows-compress:before,
32 | .fi-arrows-expand:before,
33 | .fi-arrows-in:before,
34 | .fi-arrows-out:before,
35 | .fi-asl:before,
36 | .fi-asterisk:before,
37 | .fi-at-sign:before,
38 | .fi-background-color:before,
39 | .fi-battery-empty:before,
40 | .fi-battery-full:before,
41 | .fi-battery-half:before,
42 | .fi-bitcoin-circle:before,
43 | .fi-bitcoin:before,
44 | .fi-blind:before,
45 | .fi-bluetooth:before,
46 | .fi-bold:before,
47 | .fi-book-bookmark:before,
48 | .fi-book:before,
49 | .fi-bookmark:before,
50 | .fi-braille:before,
51 | .fi-burst-new:before,
52 | .fi-burst-sale:before,
53 | .fi-burst:before,
54 | .fi-calendar:before,
55 | .fi-camera:before,
56 | .fi-check:before,
57 | .fi-checkbox:before,
58 | .fi-clipboard-notes:before,
59 | .fi-clipboard-pencil:before,
60 | .fi-clipboard:before,
61 | .fi-clock:before,
62 | .fi-closed-caption:before,
63 | .fi-cloud:before,
64 | .fi-comment-minus:before,
65 | .fi-comment-quotes:before,
66 | .fi-comment-video:before,
67 | .fi-comment:before,
68 | .fi-comments:before,
69 | .fi-compass:before,
70 | .fi-contrast:before,
71 | .fi-credit-card:before,
72 | .fi-crop:before,
73 | .fi-crown:before,
74 | .fi-css3:before,
75 | .fi-database:before,
76 | .fi-die-five:before,
77 | .fi-die-four:before,
78 | .fi-die-one:before,
79 | .fi-die-six:before,
80 | .fi-die-three:before,
81 | .fi-die-two:before,
82 | .fi-dislike:before,
83 | .fi-dollar-bill:before,
84 | .fi-dollar:before,
85 | .fi-download:before,
86 | .fi-eject:before,
87 | .fi-elevator:before,
88 | .fi-euro:before,
89 | .fi-eye:before,
90 | .fi-fast-forward:before,
91 | .fi-female-symbol:before,
92 | .fi-female:before,
93 | .fi-filter:before,
94 | .fi-first-aid:before,
95 | .fi-flag:before,
96 | .fi-folder-add:before,
97 | .fi-folder-lock:before,
98 | .fi-folder:before,
99 | .fi-foot:before,
100 | .fi-foundation:before,
101 | .fi-graph-bar:before,
102 | .fi-graph-horizontal:before,
103 | .fi-graph-pie:before,
104 | .fi-graph-trend:before,
105 | .fi-guide-dog:before,
106 | .fi-hearing-aid:before,
107 | .fi-heart:before,
108 | .fi-home:before,
109 | .fi-html5:before,
110 | .fi-indent-less:before,
111 | .fi-indent-more:before,
112 | .fi-info:before,
113 | .fi-italic:before,
114 | .fi-key:before,
115 | .fi-laptop:before,
116 | .fi-layout:before,
117 | .fi-lightbulb:before,
118 | .fi-like:before,
119 | .fi-link:before,
120 | .fi-list-bullet:before,
121 | .fi-list-number:before,
122 | .fi-list-thumbnails:before,
123 | .fi-list:before,
124 | .fi-lock:before,
125 | .fi-loop:before,
126 | .fi-magnifying-glass:before,
127 | .fi-mail:before,
128 | .fi-male-female:before,
129 | .fi-male-symbol:before,
130 | .fi-male:before,
131 | .fi-map:before,
132 | .fi-marker:before,
133 | .fi-megaphone:before,
134 | .fi-microphone:before,
135 | .fi-minus-circle:before,
136 | .fi-minus:before,
137 | .fi-mobile-signal:before,
138 | .fi-mobile:before,
139 | .fi-monitor:before,
140 | .fi-mountains:before,
141 | .fi-music:before,
142 | .fi-next:before,
143 | .fi-no-dogs:before,
144 | .fi-no-smoking:before,
145 | .fi-page-add:before,
146 | .fi-page-copy:before,
147 | .fi-page-csv:before,
148 | .fi-page-delete:before,
149 | .fi-page-doc:before,
150 | .fi-page-edit:before,
151 | .fi-page-export-csv:before,
152 | .fi-page-export-doc:before,
153 | .fi-page-export-pdf:before,
154 | .fi-page-export:before,
155 | .fi-page-filled:before,
156 | .fi-page-multiple:before,
157 | .fi-page-pdf:before,
158 | .fi-page-remove:before,
159 | .fi-page-search:before,
160 | .fi-page:before,
161 | .fi-paint-bucket:before,
162 | .fi-paperclip:before,
163 | .fi-pause:before,
164 | .fi-paw:before,
165 | .fi-paypal:before,
166 | .fi-pencil:before,
167 | .fi-photo:before,
168 | .fi-play-circle:before,
169 | .fi-play-video:before,
170 | .fi-play:before,
171 | .fi-plus:before,
172 | .fi-pound:before,
173 | .fi-power:before,
174 | .fi-previous:before,
175 | .fi-price-tag:before,
176 | .fi-pricetag-multiple:before,
177 | .fi-print:before,
178 | .fi-prohibited:before,
179 | .fi-projection-screen:before,
180 | .fi-puzzle:before,
181 | .fi-quote:before,
182 | .fi-record:before,
183 | .fi-refresh:before,
184 | .fi-results-demographics:before,
185 | .fi-results:before,
186 | .fi-rewind-ten:before,
187 | .fi-rewind:before,
188 | .fi-rss:before,
189 | .fi-safety-cone:before,
190 | .fi-save:before,
191 | .fi-share:before,
192 | .fi-sheriff-badge:before,
193 | .fi-shield:before,
194 | .fi-shopping-bag:before,
195 | .fi-shopping-cart:before,
196 | .fi-shuffle:before,
197 | .fi-skull:before,
198 | .fi-social-500px:before,
199 | .fi-social-adobe:before,
200 | .fi-social-amazon:before,
201 | .fi-social-android:before,
202 | .fi-social-apple:before,
203 | .fi-social-behance:before,
204 | .fi-social-bing:before,
205 | .fi-social-blogger:before,
206 | .fi-social-delicious:before,
207 | .fi-social-designer-news:before,
208 | .fi-social-deviant-art:before,
209 | .fi-social-digg:before,
210 | .fi-social-dribbble:before,
211 | .fi-social-drive:before,
212 | .fi-social-dropbox:before,
213 | .fi-social-evernote:before,
214 | .fi-social-facebook:before,
215 | .fi-social-flickr:before,
216 | .fi-social-forrst:before,
217 | .fi-social-foursquare:before,
218 | .fi-social-game-center:before,
219 | .fi-social-github:before,
220 | .fi-social-google-plus:before,
221 | .fi-social-hacker-news:before,
222 | .fi-social-hi5:before,
223 | .fi-social-instagram:before,
224 | .fi-social-joomla:before,
225 | .fi-social-lastfm:before,
226 | .fi-social-linkedin:before,
227 | .fi-social-medium:before,
228 | .fi-social-myspace:before,
229 | .fi-social-orkut:before,
230 | .fi-social-path:before,
231 | .fi-social-picasa:before,
232 | .fi-social-pinterest:before,
233 | .fi-social-rdio:before,
234 | .fi-social-reddit:before,
235 | .fi-social-skillshare:before,
236 | .fi-social-skype:before,
237 | .fi-social-smashing-mag:before,
238 | .fi-social-snapchat:before,
239 | .fi-social-spotify:before,
240 | .fi-social-squidoo:before,
241 | .fi-social-stack-overflow:before,
242 | .fi-social-steam:before,
243 | .fi-social-stumbleupon:before,
244 | .fi-social-treehouse:before,
245 | .fi-social-tumblr:before,
246 | .fi-social-twitter:before,
247 | .fi-social-vimeo:before,
248 | .fi-social-windows:before,
249 | .fi-social-xbox:before,
250 | .fi-social-yahoo:before,
251 | .fi-social-yelp:before,
252 | .fi-social-youtube:before,
253 | .fi-social-zerply:before,
254 | .fi-social-zurb:before,
255 | .fi-sound:before,
256 | .fi-star:before,
257 | .fi-stop:before,
258 | .fi-strikethrough:before,
259 | .fi-subscript:before,
260 | .fi-superscript:before,
261 | .fi-tablet-landscape:before,
262 | .fi-tablet-portrait:before,
263 | .fi-target-two:before,
264 | .fi-target:before,
265 | .fi-telephone-accessible:before,
266 | .fi-telephone:before,
267 | .fi-text-color:before,
268 | .fi-thumbnails:before,
269 | .fi-ticket:before,
270 | .fi-torso-business:before,
271 | .fi-torso-female:before,
272 | .fi-torso:before,
273 | .fi-torsos-all-female:before,
274 | .fi-torsos-all:before,
275 | .fi-torsos-female-male:before,
276 | .fi-torsos-male-female:before,
277 | .fi-torsos:before,
278 | .fi-trash:before,
279 | .fi-trees:before,
280 | .fi-trophy:before,
281 | .fi-underline:before,
282 | .fi-universal-access:before,
283 | .fi-unlink:before,
284 | .fi-unlock:before,
285 | .fi-upload-cloud:before,
286 | .fi-upload:before,
287 | .fi-usb:before,
288 | .fi-video:before,
289 | .fi-volume-none:before,
290 | .fi-volume-strike:before,
291 | .fi-volume:before,
292 | .fi-web:before,
293 | .fi-wheelchair:before,
294 | .fi-widget:before,
295 | .fi-wrench:before,
296 | .fi-x-circle:before,
297 | .fi-x:before,
298 | .fi-yen:before,
299 | .fi-zoom-in:before,
300 | .fi-zoom-out:before {
301 | font-family: "foundation-icons";
302 | font-style: normal;
303 | font-weight: normal;
304 | font-variant: normal;
305 | text-transform: none;
306 | line-height: 1;
307 | -webkit-font-smoothing: antialiased;
308 | display: inline-block;
309 | text-decoration: inherit;
310 | }
311 |
312 | .fi-address-book:before { content: "\f100"; }
313 | .fi-alert:before { content: "\f101"; }
314 | .fi-align-center:before { content: "\f102"; }
315 | .fi-align-justify:before { content: "\f103"; }
316 | .fi-align-left:before { content: "\f104"; }
317 | .fi-align-right:before { content: "\f105"; }
318 | .fi-anchor:before { content: "\f106"; }
319 | .fi-annotate:before { content: "\f107"; }
320 | .fi-archive:before { content: "\f108"; }
321 | .fi-arrow-down:before { content: "\f109"; }
322 | .fi-arrow-left:before { content: "\f10a"; }
323 | .fi-arrow-right:before { content: "\f10b"; }
324 | .fi-arrow-up:before { content: "\f10c"; }
325 | .fi-arrows-compress:before { content: "\f10d"; }
326 | .fi-arrows-expand:before { content: "\f10e"; }
327 | .fi-arrows-in:before { content: "\f10f"; }
328 | .fi-arrows-out:before { content: "\f110"; }
329 | .fi-asl:before { content: "\f111"; }
330 | .fi-asterisk:before { content: "\f112"; }
331 | .fi-at-sign:before { content: "\f113"; }
332 | .fi-background-color:before { content: "\f114"; }
333 | .fi-battery-empty:before { content: "\f115"; }
334 | .fi-battery-full:before { content: "\f116"; }
335 | .fi-battery-half:before { content: "\f117"; }
336 | .fi-bitcoin-circle:before { content: "\f118"; }
337 | .fi-bitcoin:before { content: "\f119"; }
338 | .fi-blind:before { content: "\f11a"; }
339 | .fi-bluetooth:before { content: "\f11b"; }
340 | .fi-bold:before { content: "\f11c"; }
341 | .fi-book-bookmark:before { content: "\f11d"; }
342 | .fi-book:before { content: "\f11e"; }
343 | .fi-bookmark:before { content: "\f11f"; }
344 | .fi-braille:before { content: "\f120"; }
345 | .fi-burst-new:before { content: "\f121"; }
346 | .fi-burst-sale:before { content: "\f122"; }
347 | .fi-burst:before { content: "\f123"; }
348 | .fi-calendar:before { content: "\f124"; }
349 | .fi-camera:before { content: "\f125"; }
350 | .fi-check:before { content: "\f126"; }
351 | .fi-checkbox:before { content: "\f127"; }
352 | .fi-clipboard-notes:before { content: "\f128"; }
353 | .fi-clipboard-pencil:before { content: "\f129"; }
354 | .fi-clipboard:before { content: "\f12a"; }
355 | .fi-clock:before { content: "\f12b"; }
356 | .fi-closed-caption:before { content: "\f12c"; }
357 | .fi-cloud:before { content: "\f12d"; }
358 | .fi-comment-minus:before { content: "\f12e"; }
359 | .fi-comment-quotes:before { content: "\f12f"; }
360 | .fi-comment-video:before { content: "\f130"; }
361 | .fi-comment:before { content: "\f131"; }
362 | .fi-comments:before { content: "\f132"; }
363 | .fi-compass:before { content: "\f133"; }
364 | .fi-contrast:before { content: "\f134"; }
365 | .fi-credit-card:before { content: "\f135"; }
366 | .fi-crop:before { content: "\f136"; }
367 | .fi-crown:before { content: "\f137"; }
368 | .fi-css3:before { content: "\f138"; }
369 | .fi-database:before { content: "\f139"; }
370 | .fi-die-five:before { content: "\f13a"; }
371 | .fi-die-four:before { content: "\f13b"; }
372 | .fi-die-one:before { content: "\f13c"; }
373 | .fi-die-six:before { content: "\f13d"; }
374 | .fi-die-three:before { content: "\f13e"; }
375 | .fi-die-two:before { content: "\f13f"; }
376 | .fi-dislike:before { content: "\f140"; }
377 | .fi-dollar-bill:before { content: "\f141"; }
378 | .fi-dollar:before { content: "\f142"; }
379 | .fi-download:before { content: "\f143"; }
380 | .fi-eject:before { content: "\f144"; }
381 | .fi-elevator:before { content: "\f145"; }
382 | .fi-euro:before { content: "\f146"; }
383 | .fi-eye:before { content: "\f147"; }
384 | .fi-fast-forward:before { content: "\f148"; }
385 | .fi-female-symbol:before { content: "\f149"; }
386 | .fi-female:before { content: "\f14a"; }
387 | .fi-filter:before { content: "\f14b"; }
388 | .fi-first-aid:before { content: "\f14c"; }
389 | .fi-flag:before { content: "\f14d"; }
390 | .fi-folder-add:before { content: "\f14e"; }
391 | .fi-folder-lock:before { content: "\f14f"; }
392 | .fi-folder:before { content: "\f150"; }
393 | .fi-foot:before { content: "\f151"; }
394 | .fi-foundation:before { content: "\f152"; }
395 | .fi-graph-bar:before { content: "\f153"; }
396 | .fi-graph-horizontal:before { content: "\f154"; }
397 | .fi-graph-pie:before { content: "\f155"; }
398 | .fi-graph-trend:before { content: "\f156"; }
399 | .fi-guide-dog:before { content: "\f157"; }
400 | .fi-hearing-aid:before { content: "\f158"; }
401 | .fi-heart:before { content: "\f159"; }
402 | .fi-home:before { content: "\f15a"; }
403 | .fi-html5:before { content: "\f15b"; }
404 | .fi-indent-less:before { content: "\f15c"; }
405 | .fi-indent-more:before { content: "\f15d"; }
406 | .fi-info:before { content: "\f15e"; }
407 | .fi-italic:before { content: "\f15f"; }
408 | .fi-key:before { content: "\f160"; }
409 | .fi-laptop:before { content: "\f161"; }
410 | .fi-layout:before { content: "\f162"; }
411 | .fi-lightbulb:before { content: "\f163"; }
412 | .fi-like:before { content: "\f164"; }
413 | .fi-link:before { content: "\f165"; }
414 | .fi-list-bullet:before { content: "\f166"; }
415 | .fi-list-number:before { content: "\f167"; }
416 | .fi-list-thumbnails:before { content: "\f168"; }
417 | .fi-list:before { content: "\f169"; }
418 | .fi-lock:before { content: "\f16a"; }
419 | .fi-loop:before { content: "\f16b"; }
420 | .fi-magnifying-glass:before { content: "\f16c"; }
421 | .fi-mail:before { content: "\f16d"; }
422 | .fi-male-female:before { content: "\f16e"; }
423 | .fi-male-symbol:before { content: "\f16f"; }
424 | .fi-male:before { content: "\f170"; }
425 | .fi-map:before { content: "\f171"; }
426 | .fi-marker:before { content: "\f172"; }
427 | .fi-megaphone:before { content: "\f173"; }
428 | .fi-microphone:before { content: "\f174"; }
429 | .fi-minus-circle:before { content: "\f175"; }
430 | .fi-minus:before { content: "\f176"; }
431 | .fi-mobile-signal:before { content: "\f177"; }
432 | .fi-mobile:before { content: "\f178"; }
433 | .fi-monitor:before { content: "\f179"; }
434 | .fi-mountains:before { content: "\f17a"; }
435 | .fi-music:before { content: "\f17b"; }
436 | .fi-next:before { content: "\f17c"; }
437 | .fi-no-dogs:before { content: "\f17d"; }
438 | .fi-no-smoking:before { content: "\f17e"; }
439 | .fi-page-add:before { content: "\f17f"; }
440 | .fi-page-copy:before { content: "\f180"; }
441 | .fi-page-csv:before { content: "\f181"; }
442 | .fi-page-delete:before { content: "\f182"; }
443 | .fi-page-doc:before { content: "\f183"; }
444 | .fi-page-edit:before { content: "\f184"; }
445 | .fi-page-export-csv:before { content: "\f185"; }
446 | .fi-page-export-doc:before { content: "\f186"; }
447 | .fi-page-export-pdf:before { content: "\f187"; }
448 | .fi-page-export:before { content: "\f188"; }
449 | .fi-page-filled:before { content: "\f189"; }
450 | .fi-page-multiple:before { content: "\f18a"; }
451 | .fi-page-pdf:before { content: "\f18b"; }
452 | .fi-page-remove:before { content: "\f18c"; }
453 | .fi-page-search:before { content: "\f18d"; }
454 | .fi-page:before { content: "\f18e"; }
455 | .fi-paint-bucket:before { content: "\f18f"; }
456 | .fi-paperclip:before { content: "\f190"; }
457 | .fi-pause:before { content: "\f191"; }
458 | .fi-paw:before { content: "\f192"; }
459 | .fi-paypal:before { content: "\f193"; }
460 | .fi-pencil:before { content: "\f194"; }
461 | .fi-photo:before { content: "\f195"; }
462 | .fi-play-circle:before { content: "\f196"; }
463 | .fi-play-video:before { content: "\f197"; }
464 | .fi-play:before { content: "\f198"; }
465 | .fi-plus:before { content: "\f199"; }
466 | .fi-pound:before { content: "\f19a"; }
467 | .fi-power:before { content: "\f19b"; }
468 | .fi-previous:before { content: "\f19c"; }
469 | .fi-price-tag:before { content: "\f19d"; }
470 | .fi-pricetag-multiple:before { content: "\f19e"; }
471 | .fi-print:before { content: "\f19f"; }
472 | .fi-prohibited:before { content: "\f1a0"; }
473 | .fi-projection-screen:before { content: "\f1a1"; }
474 | .fi-puzzle:before { content: "\f1a2"; }
475 | .fi-quote:before { content: "\f1a3"; }
476 | .fi-record:before { content: "\f1a4"; }
477 | .fi-refresh:before { content: "\f1a5"; }
478 | .fi-results-demographics:before { content: "\f1a6"; }
479 | .fi-results:before { content: "\f1a7"; }
480 | .fi-rewind-ten:before { content: "\f1a8"; }
481 | .fi-rewind:before { content: "\f1a9"; }
482 | .fi-rss:before { content: "\f1aa"; }
483 | .fi-safety-cone:before { content: "\f1ab"; }
484 | .fi-save:before { content: "\f1ac"; }
485 | .fi-share:before { content: "\f1ad"; }
486 | .fi-sheriff-badge:before { content: "\f1ae"; }
487 | .fi-shield:before { content: "\f1af"; }
488 | .fi-shopping-bag:before { content: "\f1b0"; }
489 | .fi-shopping-cart:before { content: "\f1b1"; }
490 | .fi-shuffle:before { content: "\f1b2"; }
491 | .fi-skull:before { content: "\f1b3"; }
492 | .fi-social-500px:before { content: "\f1b4"; }
493 | .fi-social-adobe:before { content: "\f1b5"; }
494 | .fi-social-amazon:before { content: "\f1b6"; }
495 | .fi-social-android:before { content: "\f1b7"; }
496 | .fi-social-apple:before { content: "\f1b8"; }
497 | .fi-social-behance:before { content: "\f1b9"; }
498 | .fi-social-bing:before { content: "\f1ba"; }
499 | .fi-social-blogger:before { content: "\f1bb"; }
500 | .fi-social-delicious:before { content: "\f1bc"; }
501 | .fi-social-designer-news:before { content: "\f1bd"; }
502 | .fi-social-deviant-art:before { content: "\f1be"; }
503 | .fi-social-digg:before { content: "\f1bf"; }
504 | .fi-social-dribbble:before { content: "\f1c0"; }
505 | .fi-social-drive:before { content: "\f1c1"; }
506 | .fi-social-dropbox:before { content: "\f1c2"; }
507 | .fi-social-evernote:before { content: "\f1c3"; }
508 | .fi-social-facebook:before { content: "\f1c4"; }
509 | .fi-social-flickr:before { content: "\f1c5"; }
510 | .fi-social-forrst:before { content: "\f1c6"; }
511 | .fi-social-foursquare:before { content: "\f1c7"; }
512 | .fi-social-game-center:before { content: "\f1c8"; }
513 | .fi-social-github:before { content: "\f1c9"; }
514 | .fi-social-google-plus:before { content: "\f1ca"; }
515 | .fi-social-hacker-news:before { content: "\f1cb"; }
516 | .fi-social-hi5:before { content: "\f1cc"; }
517 | .fi-social-instagram:before { content: "\f1cd"; }
518 | .fi-social-joomla:before { content: "\f1ce"; }
519 | .fi-social-lastfm:before { content: "\f1cf"; }
520 | .fi-social-linkedin:before { content: "\f1d0"; }
521 | .fi-social-medium:before { content: "\f1d1"; }
522 | .fi-social-myspace:before { content: "\f1d2"; }
523 | .fi-social-orkut:before { content: "\f1d3"; }
524 | .fi-social-path:before { content: "\f1d4"; }
525 | .fi-social-picasa:before { content: "\f1d5"; }
526 | .fi-social-pinterest:before { content: "\f1d6"; }
527 | .fi-social-rdio:before { content: "\f1d7"; }
528 | .fi-social-reddit:before { content: "\f1d8"; }
529 | .fi-social-skillshare:before { content: "\f1d9"; }
530 | .fi-social-skype:before { content: "\f1da"; }
531 | .fi-social-smashing-mag:before { content: "\f1db"; }
532 | .fi-social-snapchat:before { content: "\f1dc"; }
533 | .fi-social-spotify:before { content: "\f1dd"; }
534 | .fi-social-squidoo:before { content: "\f1de"; }
535 | .fi-social-stack-overflow:before { content: "\f1df"; }
536 | .fi-social-steam:before { content: "\f1e0"; }
537 | .fi-social-stumbleupon:before { content: "\f1e1"; }
538 | .fi-social-treehouse:before { content: "\f1e2"; }
539 | .fi-social-tumblr:before { content: "\f1e3"; }
540 | .fi-social-twitter:before { content: "\f1e4"; }
541 | .fi-social-vimeo:before { content: "\f1e5"; }
542 | .fi-social-windows:before { content: "\f1e6"; }
543 | .fi-social-xbox:before { content: "\f1e7"; }
544 | .fi-social-yahoo:before { content: "\f1e8"; }
545 | .fi-social-yelp:before { content: "\f1e9"; }
546 | .fi-social-youtube:before { content: "\f1ea"; }
547 | .fi-social-zerply:before { content: "\f1eb"; }
548 | .fi-social-zurb:before { content: "\f1ec"; }
549 | .fi-sound:before { content: "\f1ed"; }
550 | .fi-star:before { content: "\f1ee"; }
551 | .fi-stop:before { content: "\f1ef"; }
552 | .fi-strikethrough:before { content: "\f1f0"; }
553 | .fi-subscript:before { content: "\f1f1"; }
554 | .fi-superscript:before { content: "\f1f2"; }
555 | .fi-tablet-landscape:before { content: "\f1f3"; }
556 | .fi-tablet-portrait:before { content: "\f1f4"; }
557 | .fi-target-two:before { content: "\f1f5"; }
558 | .fi-target:before { content: "\f1f6"; }
559 | .fi-telephone-accessible:before { content: "\f1f7"; }
560 | .fi-telephone:before { content: "\f1f8"; }
561 | .fi-text-color:before { content: "\f1f9"; }
562 | .fi-thumbnails:before { content: "\f1fa"; }
563 | .fi-ticket:before { content: "\f1fb"; }
564 | .fi-torso-business:before { content: "\f1fc"; }
565 | .fi-torso-female:before { content: "\f1fd"; }
566 | .fi-torso:before { content: "\f1fe"; }
567 | .fi-torsos-all-female:before { content: "\f1ff"; }
568 | .fi-torsos-all:before { content: "\f200"; }
569 | .fi-torsos-female-male:before { content: "\f201"; }
570 | .fi-torsos-male-female:before { content: "\f202"; }
571 | .fi-torsos:before { content: "\f203"; }
572 | .fi-trash:before { content: "\f204"; }
573 | .fi-trees:before { content: "\f205"; }
574 | .fi-trophy:before { content: "\f206"; }
575 | .fi-underline:before { content: "\f207"; }
576 | .fi-universal-access:before { content: "\f208"; }
577 | .fi-unlink:before { content: "\f209"; }
578 | .fi-unlock:before { content: "\f20a"; }
579 | .fi-upload-cloud:before { content: "\f20b"; }
580 | .fi-upload:before { content: "\f20c"; }
581 | .fi-usb:before { content: "\f20d"; }
582 | .fi-video:before { content: "\f20e"; }
583 | .fi-volume-none:before { content: "\f20f"; }
584 | .fi-volume-strike:before { content: "\f210"; }
585 | .fi-volume:before { content: "\f211"; }
586 | .fi-web:before { content: "\f212"; }
587 | .fi-wheelchair:before { content: "\f213"; }
588 | .fi-widget:before { content: "\f214"; }
589 | .fi-wrench:before { content: "\f215"; }
590 | .fi-x-circle:before { content: "\f216"; }
591 | .fi-x:before { content: "\f217"; }
592 | .fi-yen:before { content: "\f218"; }
593 | .fi-zoom-in:before { content: "\f219"; }
594 | .fi-zoom-out:before { content: "\f21a"; }
595 |
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/foundation-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/css/foundation-icons.eot
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/foundation-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/css/foundation-icons.ttf
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/foundation-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/css/foundation-icons.woff
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/layout.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | header{
7 | width:100%;
8 | padding:50px 0 20px;
9 | background-size:cover;
10 | background-image:linear-gradient(to top,rgba(0,0,0,0.8) 0,rgba(0,0,0,0.0001) 100%),url(/static/imgs/banner.jpg);
11 | box-shadow:0 6px 10px #666;margin-bottom:60px;
12 | }
13 |
14 | .avatar {
15 | box-shadow: 0 0 10px #000;
16 | width: 150px;
17 | height: 150px;
18 | margin: 20px auto;
19 | overflow: hidden;
20 | border: 4px solid #FFF;
21 | border-radius: 100%;
22 | background: #FFF;
23 | -webkit-transition: -webkit-transform 400ms;
24 | -moz-transition: -moz-transform 400ms;
25 | transition: transform 400ms;
26 | }
27 | .avatar:hover {
28 | -webkit-transform:rotate(30deg);
29 | -moz-transform:rotate(30deg);
30 | transform:rotate(30deg);
31 | }
32 | .avatar img{
33 | height: 100%;
34 | margin: 0;
35 | }
36 |
37 | header > .title {
38 | text-align: center;
39 | }
40 |
41 | .title h1, .title a, .title address, .nav li, .nav a {
42 | color: #CCC;
43 | text-decoration: none;
44 | }
45 |
46 | header > .title > h1 {
47 | margin: 0;
48 | padding: 0;
49 | font-size: 1.4em;
50 | font-weight: 100;
51 | }
52 |
53 | ul.nav {
54 | text-align: center;
55 | padding: 0;
56 | margin: 0;
57 | }
58 |
59 | .nav li {
60 | display: inline-block;
61 | padding: 0 10px;
62 | }
63 |
64 | .nav li > a:hover {
65 | color: #EEE;
66 | }
67 |
68 | footer{
69 | bottom:0;
70 | position:relative;
71 | border-top:#D1DADF 1px solid;
72 | background:#F1F1F1;
73 | padding:36px;
74 | margin-top:60px;
75 | text-align:center;
76 | }
77 |
78 | footer *{
79 | color:#BBC7CC;
80 | font-weight:100;
81 | text-decoration: none;
82 | }
83 |
84 | footer .rss{
85 | color: #666;
86 | font-size:23px;
87 | position:absolute;
88 | padding: 1px;
89 | top:-15px;
90 | left:50%;
91 | margin-left:-15px;
92 | display:block;
93 | width:25px;
94 | height:25px;
95 | border-radius:100%;
96 | background:#FFF;
97 | border:1px solid #D1DADF;
98 | line-height: 10px;
99 | -webkit-transition:box-shadow 400ms;
100 | -moz-transition:box-shadow 400ms;
101 | transition:box-shadow 400ms;
102 | }
103 |
104 | p.footer {
105 | margin-bottom: 0;
106 | }
107 |
108 | footer .rss:hover{
109 | box-shadow:0 0 12px #D1DADF;
110 | }
111 |
112 | footer .friends{
113 | font-size:smaller;
114 | }
115 |
116 | .hide {
117 | visibility: hidden;
118 | }
119 |
120 | .wrapper {
121 | width:60%;
122 | max-width:980px;
123 | margin:0 auto;
124 | }
125 |
126 | .pull-right {
127 | float: right;
128 | }
129 |
130 | @media screen and (max-width:980px){
131 | .wrapper {width:96%;}
132 | }
133 |
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/links.css:
--------------------------------------------------------------------------------
1 | p.about-me {
2 | padding: 0 16px;
3 | }
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/nprogress.css:
--------------------------------------------------------------------------------
1 | /* Make clicks pass-through */
2 | #nprogress {
3 | pointer-events: none;
4 | }
5 |
6 | #nprogress .bar {
7 | background: #29d;
8 |
9 | position: fixed;
10 | z-index: 1031;
11 | top: 0;
12 | left: 0;
13 |
14 | width: 100%;
15 | height: 4px;
16 | }
17 |
18 | /* Fancy blur effect */
19 | #nprogress .peg {
20 | display: block;
21 | position: absolute;
22 | right: 0px;
23 | width: 100px;
24 | height: 100%;
25 | box-shadow: 0 0 20px #29d, 0 0 5px #29d;
26 | opacity: 1.0;
27 |
28 | -webkit-transform: rotate(3deg) translate(0px, -4px);
29 | -ms-transform: rotate(3deg) translate(0px, -4px);
30 | transform: rotate(3deg) translate(0px, -4px);
31 | }
32 |
33 | /* Remove these to get rid of the spinner */
34 |
35 | /*
36 | #nprogress .spinner {
37 | display: block;
38 | position: fixed;
39 | z-index: 1031;
40 | top: 15px;
41 | right: 15px;
42 | }
43 |
44 | #nprogress .spinner-icon {
45 | width: 18px;
46 | height: 18px;
47 | box-sizing: border-box;
48 |
49 | border: solid 2px transparent;
50 | border-top-color: #29d;
51 | border-left-color: #29d;
52 | border-radius: 50%;
53 |
54 | -webkit-animation: nprogress-spinner 400ms linear infinite;
55 | animation: nprogress-spinner 400ms linear infinite;
56 | }
57 | */
58 | .nprogress-custom-parent {
59 | overflow: hidden;
60 | position: relative;
61 | }
62 |
63 | .nprogress-custom-parent #nprogress .spinner,
64 | .nprogress-custom-parent #nprogress .bar {
65 | position: absolute;
66 | }
67 |
68 | @-webkit-keyframes nprogress-spinner {
69 | 0% { -webkit-transform: rotate(0deg); }
70 | 100% { -webkit-transform: rotate(360deg); }
71 | }
72 | @keyframes nprogress-spinner {
73 | 0% { transform: rotate(0deg); }
74 | 100% { transform: rotate(360deg); }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/post.css:
--------------------------------------------------------------------------------
1 | .wrapper > article {
2 | padding-bottom: 60px;
3 | }
4 |
5 |
6 | .wrapper > article > h1.title {
7 | text-align: center;
8 | font-weight: 100;
9 | font-size: 2.4em;
10 | }
11 |
12 | .wrapper > article > h1.title > a {
13 | color: #333;
14 | }
15 |
16 | .wrapper > article > h1.title > a:hover {
17 | color: #999;
18 | }
19 |
20 | .wrapper > article > aside {
21 | text-align: center;
22 | }
23 |
24 | .post-comments {
25 | margin-top: 30px;
26 | }
27 |
28 | .post-tags {
29 | margin-top: 20px;
30 | }
31 |
32 | .post-tags > em {
33 | color: #666;
34 | }
--------------------------------------------------------------------------------
/pyprint/themes/default/static/css/yue.css:
--------------------------------------------------------------------------------
1 | /**
2 | * yue.css
3 | *
4 | * yue.css is designed for readable content.
5 | *
6 | * Copyright (c) 2013 by Hsiaoming Yang.
7 | */
8 |
9 |
10 |
11 | .yue {
12 | font: 400 18px/1.62 "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif;
13 | color: #444443;
14 | }
15 | .yue ::selection {
16 | background-color: rgba(0,0,0,0.2);
17 | }
18 | .yue h1,
19 | .yue h2,
20 | .yue h3,
21 | .yue h4,
22 | .yue h5,
23 | .yue h6 {
24 | font-family: "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft YaHei", "SimSun", sans-serif;
25 | color: #222223;
26 | }
27 | .yue h1 {
28 | font-size: 1.8em;
29 | margin: 0.67em 0;
30 | }
31 | .yue > h1 {
32 | margin-top: 0;
33 | font-size: 2em;
34 | }
35 | .yue h2 {
36 | font-size: 1.5em;
37 | margin: 0.83em 0;
38 | }
39 | .yue h3 {
40 | font-size: 1.17em;
41 | margin: 1em 0;
42 | }
43 | .yue h4,
44 | .yue h5,
45 | .yue h6 {
46 | font-size: 1em;
47 | margin: 1.6em 0 1em 0;
48 | }
49 | .yue h6 {
50 | font-weight: 500;
51 | }
52 | .yue p {
53 | margin-top: 0;
54 | margin-bottom: 1.64em;
55 | }
56 | .yue a {
57 | color: #111;
58 | word-wrap: break-word;
59 | }
60 | .yue a:hover {
61 | color: #555;
62 | }
63 | .yue strong,
64 | .yue b {
65 | font-weight: 700;
66 | color: #222;
67 | }
68 | .yue em,
69 | .yue i {
70 | font-style: italic;
71 | color: #222;
72 | }
73 | .yue img {
74 | max-width: 100%;
75 | height: auto;
76 | margin: 0.2em 0;
77 | }
78 | .yue a img {
79 | /* Remove border on IE */
80 | border: none;
81 | }
82 | .yue figure {
83 | position: relative;
84 | clear: both;
85 | outline: 0;
86 | margin: 10px 0 30px;
87 | padding: 0;
88 | }
89 | .yue figure img {
90 | display: block;
91 | max-width: 100%;
92 | margin: auto;
93 | -webkit-box-sizing: border-box;
94 | -moz-box-sizing: border-box;
95 | box-sizing: border-box;
96 | }
97 | .yue figure figcaption {
98 | position: relative;
99 | width: 100%;
100 | text-align: center;
101 | left: 0;
102 | margin-top: 10px;
103 | font-weight: 400;
104 | font-size: 14px;
105 | color: #666665;
106 | }
107 | .yue figure figcaption a {
108 | text-decoration: none;
109 | color: #666665;
110 | }
111 | .yue hr {
112 | display: block;
113 | width: 14%;
114 | margin: 40px auto 34px;
115 | border: 0 none;
116 | border-top: 3px solid #dededc;
117 | }
118 | .yue blockquote {
119 | margin: 0 0 1.64em 0;
120 | border-left: 3px solid #dadada;
121 | padding-left: 12px;
122 | color: #666664;
123 | }
124 | .yue blockquote a {
125 | color: #666664;
126 | }
127 | .yue ul,
128 | .yue ol {
129 | margin: 0 0 24px 6px;
130 | padding-left: 16px;
131 | }
132 | .yue ul {
133 | list-style-type: square;
134 | }
135 | .yue ol {
136 | list-style-type: decimal;
137 | }
138 | .yue li {
139 | margin-bottom: 0.2em;
140 | }
141 | .yue li ul,
142 | .yue li ol {
143 | margin-top: 0;
144 | margin-bottom: 0;
145 | margin-left: 14px;
146 | }
147 | .yue li ul {
148 | list-style-type: disc;
149 | }
150 | .yue li ul ul {
151 | list-style-type: circle;
152 | }
153 | .yue li p {
154 | margin: 0.4em 0 0.6em;
155 | }
156 | .yue .unstyled {
157 | list-style-type: none;
158 | margin: 0;
159 | padding: 0;
160 | }
161 | .yue code,
162 | .yue tt {
163 | color: #808080;
164 | font-size: 0.96em;
165 | background-color: #f9f9f7;
166 | padding: 1px 2px;
167 | border: 1px solid #dadada;
168 | border-radius: 3px;
169 | font-family: "Inconsolata", "Menlo", monospace;
170 | }
171 | .yue pre {
172 | margin: 1.64em 0;
173 | padding: 7px;
174 | border: none;
175 | border-left: 3px solid #dadada;
176 | padding-left: 10px;
177 | overflow: auto;
178 | line-height: 1.5;
179 | font-size: 0.96em;
180 | font-family: "Inconsolata", "Menlo", monospace;
181 | color: #4c4c4c;
182 | background-color: #f9f9f7;
183 | }
184 | .yue pre code,
185 | .yue pre tt {
186 | color: #4c4c4c;
187 | border: none;
188 | background: none;
189 | padding: 0;
190 | }
191 | .yue table {
192 | width: 100%;
193 | border-collapse: collapse;
194 | border-spacing: 0;
195 | margin-bottom: 1.5em;
196 | font-size: 0.96em;
197 | }
198 | .yue th,
199 | .yue td {
200 | text-align: left;
201 | padding: 4px 8px 4px 10px;
202 | border: 1px solid #dadada;
203 | }
204 | .yue td {
205 | vertical-align: top;
206 | }
207 | .yue tr:nth-child(even) {
208 | background-color: #efefee;
209 | }
210 | .yue iframe {
211 | display: block;
212 | max-width: 100%;
213 | margin-bottom: 30px;
214 | }
215 | .yue figure iframe {
216 | margin: auto;
217 | }
218 | .yue table pre {
219 | margin: 0;
220 | padding: 0;
221 | border: none;
222 | background: none;
223 | }
224 | .yue .highlight td:first-of-type pre {
225 | text-align: right;
226 | color: #aaa;
227 | }
228 | @media (min-width: 1100px) {
229 | .yue blockquote {
230 | margin-left: -24px;
231 | padding-left: 20px;
232 | border-width: 4px;
233 | }
234 | .yue blockquote blockquote {
235 | margin-left: 0;
236 | }
237 | .yue figure figcaption:before {
238 | width: 25%;
239 | margin-left: 75%;
240 | border-top: 1px solid #dededc;
241 | display: block;
242 | content: "";
243 | margin-bottom: 10px;
244 | }
245 | .yue figure figcaption {
246 | position: absolute;
247 | left: -172px;
248 | width: 150px;
249 | top: 0;
250 | text-align: right;
251 | margin-top: 0;
252 | }
253 | }
--------------------------------------------------------------------------------
/pyprint/themes/default/static/imgs/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/imgs/avatar.jpg
--------------------------------------------------------------------------------
/pyprint/themes/default/static/imgs/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/imgs/banner.jpg
--------------------------------------------------------------------------------
/pyprint/themes/default/static/imgs/not_found.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/default/static/imgs/not_found.jpg
--------------------------------------------------------------------------------
/pyprint/themes/default/static/js/jquery.lazyload.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Lazy Load - jQuery plugin for lazy loading images
3 | *
4 | * Copyright (c) 2007-2013 Mika Tuupola
5 | *
6 | * Licensed under the MIT license:
7 | * http://www.opensource.org/licenses/mit-license.php
8 | *
9 | * Project home:
10 | * http://www.appelsiini.net/projects/lazyload
11 | *
12 | * Version: 1.9.3
13 | *
14 | */
15 |
16 | (function($, window, document, undefined) {
17 | var $window = $(window);
18 |
19 | $.fn.lazyload = function(options) {
20 | var elements = this;
21 | var $container;
22 | var settings = {
23 | threshold : 0,
24 | failure_limit : 0,
25 | event : "scroll",
26 | effect : "show",
27 | container : window,
28 | data_attribute : "alt",
29 | skip_invisible : true,
30 | appear : null,
31 | load : null,
32 | placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
33 | };
34 |
35 | function update() {
36 | var counter = 0;
37 |
38 | elements.each(function() {
39 | var $this = $(this);
40 | if (settings.skip_invisible && !$this.is(":visible")) {
41 | return;
42 | }
43 | if ($.abovethetop(this, settings) ||
44 | $.leftofbegin(this, settings)) {
45 | /* Nothing. */
46 | } else if (!$.belowthefold(this, settings) &&
47 | !$.rightoffold(this, settings)) {
48 | $this.trigger("appear");
49 | /* if we found an image we'll load, reset the counter */
50 | counter = 0;
51 | } else {
52 | if (++counter > settings.failure_limit) {
53 | return false;
54 | }
55 | }
56 | });
57 |
58 | }
59 |
60 | if(options) {
61 | /* Maintain BC for a couple of versions. */
62 | if (undefined !== options.failurelimit) {
63 | options.failure_limit = options.failurelimit;
64 | delete options.failurelimit;
65 | }
66 | if (undefined !== options.effectspeed) {
67 | options.effect_speed = options.effectspeed;
68 | delete options.effectspeed;
69 | }
70 |
71 | $.extend(settings, options);
72 | }
73 |
74 | /* Cache container as jQuery as object. */
75 | $container = (settings.container === undefined ||
76 | settings.container === window) ? $window : $(settings.container);
77 |
78 | /* Fire one scroll event per scroll. Not one scroll event per image. */
79 | if (0 === settings.event.indexOf("scroll")) {
80 | $container.bind(settings.event, function() {
81 | return update();
82 | });
83 | }
84 |
85 | this.each(function() {
86 | var self = this;
87 | var $self = $(self);
88 |
89 | self.loaded = false;
90 |
91 | /* If no src attribute given use data:uri. */
92 | if ($self.attr("src") === undefined || $self.attr("src") === false) {
93 | if ($self.is("img")) {
94 | $self.attr("src", settings.placeholder);
95 | }
96 | }
97 |
98 | /* When appear is triggered load original image. */
99 | $self.one("appear", function() {
100 | if (!this.loaded) {
101 | if (settings.appear) {
102 | var elements_left = elements.length;
103 | settings.appear.call(self, elements_left, settings);
104 | }
105 | $("
")
106 | .bind("load", function() {
107 |
108 | var original = $self.attr(settings.data_attribute);
109 | $self.hide();
110 | if ($self.is("img")) {
111 | $self.attr("src", original);
112 | } else {
113 | $self.css("background-image", "url('" + original + "')");
114 | }
115 | $self[settings.effect](settings.effect_speed);
116 |
117 | self.loaded = true;
118 |
119 | /* Remove image from array so it is not looped next time. */
120 | var temp = $.grep(elements, function(element) {
121 | return !element.loaded;
122 | });
123 | elements = $(temp);
124 |
125 | if (settings.load) {
126 | var elements_left = elements.length;
127 | settings.load.call(self, elements_left, settings);
128 | }
129 | })
130 | .attr("src", $self.attr(settings.data_attribute));
131 | }
132 | });
133 |
134 | /* When wanted event is triggered load original image */
135 | /* by triggering appear. */
136 | if (0 !== settings.event.indexOf("scroll")) {
137 | $self.bind(settings.event, function() {
138 | if (!self.loaded) {
139 | $self.trigger("appear");
140 | }
141 | });
142 | }
143 | });
144 |
145 | /* Check if something appears when window is resized. */
146 | $window.bind("resize", function() {
147 | update();
148 | });
149 |
150 | /* With IOS5 force loading images when navigating with back button. */
151 | /* Non optimal workaround. */
152 | if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
153 | $window.bind("pageshow", function(event) {
154 | if (event.originalEvent && event.originalEvent.persisted) {
155 | elements.each(function() {
156 | $(this).trigger("appear");
157 | });
158 | }
159 | });
160 | }
161 |
162 | /* Force initial check if images should appear. */
163 | $(document).ready(function() {
164 | update();
165 | });
166 |
167 | return this;
168 | };
169 |
170 | /* Convenience methods in jQuery namespace. */
171 | /* Use as $.belowthefold(element, {threshold : 100, container : window}) */
172 |
173 | $.belowthefold = function(element, settings) {
174 | var fold;
175 |
176 | if (settings.container === undefined || settings.container === window) {
177 | fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
178 | } else {
179 | fold = $(settings.container).offset().top + $(settings.container).height();
180 | }
181 |
182 | return fold <= $(element).offset().top - settings.threshold;
183 | };
184 |
185 | $.rightoffold = function(element, settings) {
186 | var fold;
187 |
188 | if (settings.container === undefined || settings.container === window) {
189 | fold = $window.width() + $window.scrollLeft();
190 | } else {
191 | fold = $(settings.container).offset().left + $(settings.container).width();
192 | }
193 |
194 | return fold <= $(element).offset().left - settings.threshold;
195 | };
196 |
197 | $.abovethetop = function(element, settings) {
198 | var fold;
199 |
200 | if (settings.container === undefined || settings.container === window) {
201 | fold = $window.scrollTop();
202 | } else {
203 | fold = $(settings.container).offset().top;
204 | }
205 |
206 | return fold >= $(element).offset().top + settings.threshold + $(element).height();
207 | };
208 |
209 | $.leftofbegin = function(element, settings) {
210 | var fold;
211 |
212 | if (settings.container === undefined || settings.container === window) {
213 | fold = $window.scrollLeft();
214 | } else {
215 | fold = $(settings.container).offset().left;
216 | }
217 |
218 | return fold >= $(element).offset().left + settings.threshold + $(element).width();
219 | };
220 |
221 | $.inviewport = function(element, settings) {
222 | return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
223 | !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
224 | };
225 |
226 | /* Custom selectors for your convenience. */
227 | /* Use as $("img:below-the-fold").something() or */
228 | /* $("img").filter(":below-the-fold").something() which is faster */
229 |
230 | $.extend($.expr[":"], {
231 | "below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
232 | "above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
233 | "right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
234 | "left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
235 | "in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
236 | /* Maintain BC for couple of versions. */
237 | "above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
238 | "right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
239 | "left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
240 | });
241 |
242 | })(jQuery, window, document);
--------------------------------------------------------------------------------
/pyprint/themes/default/static/js/nprogress.js:
--------------------------------------------------------------------------------
1 | /* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
2 | * @license MIT */
3 |
4 | ;(function(root, factory) {
5 |
6 | if (typeof define === 'function' && define.amd) {
7 | define(factory);
8 | } else if (typeof exports === 'object') {
9 | module.exports = factory();
10 | } else {
11 | root.NProgress = factory();
12 | }
13 |
14 | })(this, function() {
15 | var NProgress = {};
16 |
17 | NProgress.version = '0.1.6';
18 |
19 | var Settings = NProgress.settings = {
20 | minimum: 0.08,
21 | easing: 'ease',
22 | positionUsing: '',
23 | speed: 200,
24 | trickle: true,
25 | trickleRate: 0.02,
26 | trickleSpeed: 800,
27 | showSpinner: true,
28 | barSelector: '[role="bar"]',
29 | spinnerSelector: '[role="spinner"]',
30 | parent: 'body',
31 | template: ''
32 | };
33 |
34 | /**
35 | * Updates configuration.
36 | *
37 | * NProgress.configure({
38 | * minimum: 0.1
39 | * });
40 | */
41 | NProgress.configure = function(options) {
42 | var key, value;
43 | for (key in options) {
44 | value = options[key];
45 | if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
46 | }
47 |
48 | return this;
49 | };
50 |
51 | /**
52 | * Last number.
53 | */
54 |
55 | NProgress.status = null;
56 |
57 | /**
58 | * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
59 | *
60 | * NProgress.set(0.4);
61 | * NProgress.set(1.0);
62 | */
63 |
64 | NProgress.set = function(n) {
65 | var started = NProgress.isStarted();
66 |
67 | n = clamp(n, Settings.minimum, 1);
68 | NProgress.status = (n === 1 ? null : n);
69 |
70 | var progress = NProgress.render(!started),
71 | bar = progress.querySelector(Settings.barSelector),
72 | speed = Settings.speed,
73 | ease = Settings.easing;
74 |
75 | progress.offsetWidth; /* Repaint */
76 |
77 | queue(function(next) {
78 | // Set positionUsing if it hasn't already been set
79 | if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
80 |
81 | // Add transition
82 | css(bar, barPositionCSS(n, speed, ease));
83 |
84 | if (n === 1) {
85 | // Fade out
86 | css(progress, {
87 | transition: 'none',
88 | opacity: 1
89 | });
90 | progress.offsetWidth; /* Repaint */
91 |
92 | setTimeout(function() {
93 | css(progress, {
94 | transition: 'all ' + speed + 'ms linear',
95 | opacity: 0
96 | });
97 | setTimeout(function() {
98 | NProgress.remove();
99 | next();
100 | }, speed);
101 | }, speed);
102 | } else {
103 | setTimeout(next, speed);
104 | }
105 | });
106 |
107 | return this;
108 | };
109 |
110 | NProgress.isStarted = function() {
111 | return typeof NProgress.status === 'number';
112 | };
113 |
114 | /**
115 | * Shows the progress bar.
116 | * This is the same as setting the status to 0%, except that it doesn't go backwards.
117 | *
118 | * NProgress.start();
119 | *
120 | */
121 | NProgress.start = function() {
122 | if (!NProgress.status) NProgress.set(0);
123 |
124 | var work = function() {
125 | setTimeout(function() {
126 | if (!NProgress.status) return;
127 | NProgress.trickle();
128 | work();
129 | }, Settings.trickleSpeed);
130 | };
131 |
132 | if (Settings.trickle) work();
133 |
134 | return this;
135 | };
136 |
137 | /**
138 | * Hides the progress bar.
139 | * This is the *sort of* the same as setting the status to 100%, with the
140 | * difference being `done()` makes some placebo effect of some realistic motion.
141 | *
142 | * NProgress.done();
143 | *
144 | * If `true` is passed, it will show the progress bar even if its hidden.
145 | *
146 | * NProgress.done(true);
147 | */
148 |
149 | NProgress.done = function(force) {
150 | if (!force && !NProgress.status) return this;
151 |
152 | return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
153 | };
154 |
155 | /**
156 | * Increments by a random amount.
157 | */
158 |
159 | NProgress.inc = function(amount) {
160 | var n = NProgress.status;
161 |
162 | if (!n) {
163 | return NProgress.start();
164 | } else {
165 | if (typeof amount !== 'number') {
166 | amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);
167 | }
168 |
169 | n = clamp(n + amount, 0, 0.994);
170 | return NProgress.set(n);
171 | }
172 | };
173 |
174 | NProgress.trickle = function() {
175 | return NProgress.inc(Math.random() * Settings.trickleRate);
176 | };
177 |
178 | /**
179 | * Waits for all supplied jQuery promises and
180 | * increases the progress as the promises resolve.
181 | *
182 | * @param $promise jQUery Promise
183 | */
184 | (function() {
185 | var initial = 0, current = 0;
186 |
187 | NProgress.promise = function($promise) {
188 | if (!$promise || $promise.state() == "resolved") {
189 | return this;
190 | }
191 |
192 | if (current == 0) {
193 | NProgress.start();
194 | }
195 |
196 | initial++;
197 | current++;
198 |
199 | $promise.always(function() {
200 | current--;
201 | if (current == 0) {
202 | initial = 0;
203 | NProgress.done();
204 | } else {
205 | NProgress.set((initial - current) / initial);
206 | }
207 | });
208 |
209 | return this;
210 | };
211 |
212 | })();
213 |
214 | /**
215 | * (Internal) renders the progress bar markup based on the `template`
216 | * setting.
217 | */
218 |
219 | NProgress.render = function(fromStart) {
220 | if (NProgress.isRendered()) return document.getElementById('nprogress');
221 |
222 | addClass(document.documentElement, 'nprogress-busy');
223 |
224 | var progress = document.createElement('div');
225 | progress.id = 'nprogress';
226 | progress.innerHTML = Settings.template;
227 |
228 | var bar = progress.querySelector(Settings.barSelector),
229 | perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
230 | parent = document.querySelector(Settings.parent),
231 | spinner;
232 |
233 | css(bar, {
234 | transition: 'all 0 linear',
235 | transform: 'translate3d(' + perc + '%,0,0)'
236 | });
237 |
238 | if (!Settings.showSpinner) {
239 | spinner = progress.querySelector(Settings.spinnerSelector);
240 | spinner && removeElement(spinner);
241 | }
242 |
243 | if (parent != document.body) {
244 | addClass(parent, 'nprogress-custom-parent');
245 | }
246 |
247 | parent.appendChild(progress);
248 | return progress;
249 | };
250 |
251 | /**
252 | * Removes the element. Opposite of render().
253 | */
254 |
255 | NProgress.remove = function() {
256 | removeClass(document.documentElement, 'nprogress-busy');
257 | removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent')
258 | var progress = document.getElementById('nprogress');
259 | progress && removeElement(progress);
260 | };
261 |
262 | /**
263 | * Checks if the progress bar is rendered.
264 | */
265 |
266 | NProgress.isRendered = function() {
267 | return !!document.getElementById('nprogress');
268 | };
269 |
270 | /**
271 | * Determine which positioning CSS rule to use.
272 | */
273 |
274 | NProgress.getPositioningCSS = function() {
275 | // Sniff on document.body.style
276 | var bodyStyle = document.body.style;
277 |
278 | // Sniff prefixes
279 | var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
280 | ('MozTransform' in bodyStyle) ? 'Moz' :
281 | ('msTransform' in bodyStyle) ? 'ms' :
282 | ('OTransform' in bodyStyle) ? 'O' : '';
283 |
284 | if (vendorPrefix + 'Perspective' in bodyStyle) {
285 | // Modern browsers with 3D support, e.g. Webkit, IE10
286 | return 'translate3d';
287 | } else if (vendorPrefix + 'Transform' in bodyStyle) {
288 | // Browsers without 3D support, e.g. IE9
289 | return 'translate';
290 | } else {
291 | // Browsers without translate() support, e.g. IE7-8
292 | return 'margin';
293 | }
294 | };
295 |
296 | /**
297 | * Helpers
298 | */
299 |
300 | function clamp(n, min, max) {
301 | if (n < min) return min;
302 | if (n > max) return max;
303 | return n;
304 | }
305 |
306 | /**
307 | * (Internal) converts a percentage (`0..1`) to a bar translateX
308 | * percentage (`-100%..0%`).
309 | */
310 |
311 | function toBarPerc(n) {
312 | return (-1 + n) * 100;
313 | }
314 |
315 |
316 | /**
317 | * (Internal) returns the correct CSS for changing the bar's
318 | * position given an n percentage, and speed and ease from Settings
319 | */
320 |
321 | function barPositionCSS(n, speed, ease) {
322 | var barCSS;
323 |
324 | if (Settings.positionUsing === 'translate3d') {
325 | barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
326 | } else if (Settings.positionUsing === 'translate') {
327 | barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
328 | } else {
329 | barCSS = { 'margin-left': toBarPerc(n)+'%' };
330 | }
331 |
332 | barCSS.transition = 'all '+speed+'ms '+ease;
333 |
334 | return barCSS;
335 | }
336 |
337 | /**
338 | * (Internal) Queues a function to be executed.
339 | */
340 |
341 | var queue = (function() {
342 | var pending = [];
343 |
344 | function next() {
345 | var fn = pending.shift();
346 | if (fn) {
347 | fn(next);
348 | }
349 | }
350 |
351 | return function(fn) {
352 | pending.push(fn);
353 | if (pending.length == 1) next();
354 | };
355 | })();
356 |
357 | /**
358 | * (Internal) Applies css properties to an element, similar to the jQuery
359 | * css method.
360 | *
361 | * While this helper does assist with vendor prefixed property names, it
362 | * does not perform any manipulation of values prior to setting styles.
363 | */
364 |
365 | var css = (function() {
366 | var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
367 | cssProps = {};
368 |
369 | function camelCase(string) {
370 | return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
371 | return letter.toUpperCase();
372 | });
373 | }
374 |
375 | function getVendorProp(name) {
376 | var style = document.body.style;
377 | if (name in style) return name;
378 |
379 | var i = cssPrefixes.length,
380 | capName = name.charAt(0).toUpperCase() + name.slice(1),
381 | vendorName;
382 | while (i--) {
383 | vendorName = cssPrefixes[i] + capName;
384 | if (vendorName in style) return vendorName;
385 | }
386 |
387 | return name;
388 | }
389 |
390 | function getStyleProp(name) {
391 | name = camelCase(name);
392 | return cssProps[name] || (cssProps[name] = getVendorProp(name));
393 | }
394 |
395 | function applyCss(element, prop, value) {
396 | prop = getStyleProp(prop);
397 | element.style[prop] = value;
398 | }
399 |
400 | return function(element, properties) {
401 | var args = arguments,
402 | prop,
403 | value;
404 |
405 | if (args.length == 2) {
406 | for (prop in properties) {
407 | value = properties[prop];
408 | if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
409 | }
410 | } else {
411 | applyCss(element, args[1], args[2]);
412 | }
413 | }
414 | })();
415 |
416 | /**
417 | * (Internal) Determines if an element or space separated list of class names contains a class name.
418 | */
419 |
420 | function hasClass(element, name) {
421 | var list = typeof element == 'string' ? element : classList(element);
422 | return list.indexOf(' ' + name + ' ') >= 0;
423 | }
424 |
425 | /**
426 | * (Internal) Adds a class to an element.
427 | */
428 |
429 | function addClass(element, name) {
430 | var oldList = classList(element),
431 | newList = oldList + name;
432 |
433 | if (hasClass(oldList, name)) return;
434 |
435 | // Trim the opening space.
436 | element.className = newList.substring(1);
437 | }
438 |
439 | /**
440 | * (Internal) Removes a class from an element.
441 | */
442 |
443 | function removeClass(element, name) {
444 | var oldList = classList(element),
445 | newList;
446 |
447 | if (!hasClass(element, name)) return;
448 |
449 | // Replace the class name.
450 | newList = oldList.replace(' ' + name + ' ', ' ');
451 |
452 | // Trim the opening and closing spaces.
453 | element.className = newList.substring(1, newList.length - 1);
454 | }
455 |
456 | /**
457 | * (Internal) Gets a space separated list of the class names on the element.
458 | * The list is wrapped with a single space on each end to facilitate finding
459 | * matches within the list.
460 | */
461 |
462 | function classList(element) {
463 | return (' ' + (element.className || '') + ' ').replace(/\s+/gi, ' ');
464 | }
465 |
466 | /**
467 | * (Internal) Removes an element from the DOM.
468 | */
469 |
470 | function removeElement(element) {
471 | element && element.parentNode && element.parentNode.removeChild(element);
472 | }
473 |
474 | return NProgress;
475 | });
476 |
477 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/archives.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 |
9 | {% for group in posts_groups %}
10 | -
11 |
{{ group.year }}
12 |
13 | {% for post in group.posts %}
14 |
15 | {% endfor %}
16 |
17 |
18 | {% endfor %}
19 |
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/diaries.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 |
9 | {% for diary in diaries %}
10 |
11 | {% endfor %}
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ settings.username }}
4 | {{ settings.title }}
5 | {{ posts[0].created_time if posts }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | http://{{ url }}
14 |
15 | {% for post in posts %}
16 |
17 | {{ post.title }}
18 | http://{{ url }}/articles/{{ post.title|urlencode }}
19 | http://{{ url }}/articles/{{ post.title|urlencode }}
20 | {{ post.created_time }}
21 |
22 |
23 | {% endfor %}
24 |
25 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/index.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 |
8 | {% block body %}
9 | {% for post in data.posts %}
10 |
11 |
12 |
15 |
16 | {{ post.content|markdown }}
17 |
18 |
19 | {% if post.tags %}
20 | Tagged in:
21 | {% for tag in post.tags %}
22 | {{ tag.slug }}
23 | {% if not loop.last %} / {% endif %}
24 | {% endfor %}
25 |
26 | {% endif %}
27 |
28 |
29 | {% endfor %}
30 |
34 | {% endblock %}
35 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ title }} - {{ settings.title }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
32 | {% block head %}
33 | {% endblock %}
34 |
35 |
36 |
37 |
38 |
39 |

40 |
41 |
47 |
55 |
56 |
57 |
58 | {% block body %}
59 | {% endblock %}
60 |
61 |
62 |
73 |
74 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/links.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 |
8 | {% block body %}
9 |
10 | About me
11 |
19 |
20 | My Friends
21 |
22 |
23 | {% for link in links %}
24 | - {{ link.name }}
25 | {% else %}
26 | I am alone ..
27 | {% endfor %}
28 |
29 |
30 |
31 |
32 |
33 |
41 | {% endblock %}
42 |
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/not_found.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | 你在看哪里!?
6 |
7 |
8 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/pjax_layout.html:
--------------------------------------------------------------------------------
1 | {{ title }} - {{ settings.title }}
2 |
10 |
11 | {% block body %}
12 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/default/templates/post.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 |
8 | {% block body %}
9 |
10 |
11 |
14 |
15 | {{ post.content|markdown }}
16 |
17 |
18 | {% if post.tags %}
19 | Tagged in:
20 | {% for tag in post.tags %}
21 | {{ tag.slug }}
22 | {% if not loop.last %} / {% endif %}
23 | {% endfor %}
24 |
25 | {% endif %}
26 |
27 |
30 |
31 | {% if post.type == 'post' %}
32 |
40 | {% endif %}
41 | {% endblock %}
42 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/css/font.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Material Icons';
3 | font-style: normal;
4 | font-weight: 400;
5 | src: local('Material Icons'), local('MaterialIcons-Regular'), url(https://fonts.gstatic.com/s/materialicons/v7/2fcrYFNaTjcS6g4U3t-Y5StnKWgpfO2iSkLzTz-AABg.ttf) format('truetype');
6 | }
7 |
8 | .material-icons {
9 | font-family: 'Material Icons';
10 | font-weight: normal;
11 | font-style: normal;
12 | font-size: 24px;
13 | line-height: 1;
14 | letter-spacing: normal;
15 | text-transform: none;
16 | display: inline-block;
17 | word-wrap: normal;
18 | }
19 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/css/material-scrolltop.css:
--------------------------------------------------------------------------------
1 | /**
2 | * material-scrolltop
3 | *
4 | * Author: Bartholomej
5 | * Website: https://github.com/bartholomej/material-scrolltop
6 | * Docs: https://github.com/bartholomej/material-scrolltop
7 | * Repo: https://github.com/bartholomej/material-scrolltop
8 | * Issues: https://github.com/bartholomej/material-scrolltop/issues
9 | */
10 |
11 | .material-scrolltop {
12 | z-index: 999;
13 | display: block;
14 | position: fixed;
15 | width: 0;
16 | height: 0;
17 | bottom: 23px;
18 | right: 23px;
19 | padding: 0;
20 | overflow: hidden;
21 | outline: none;
22 | border: none;
23 | border-radius: 2px;
24 | box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
25 | cursor: hand;
26 | border-radius: 50%;
27 | background: #888;
28 | -webkit-transition: all 0.3s cubic-bezier(0.25, 0.25, 0, 1);
29 | -ms-transition: all 0.3s cubic-bezier(0.25, 0.25, 0, 1);
30 | -moz-transition: all 0.3s cubic-bezier(0.25, 0.25, 0, 1);
31 | -o-transition: all 0.3s cubic-bezier(0.25, 0.25, 0, 1);
32 | transition: all 0.3s cubic-bezier(0.25, 0.25, 0, 1);
33 | }
34 |
35 | .material-scrolltop:hover {
36 | background-color: #888;
37 | text-decoration: none;
38 | box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5), 0 3px 15px rgba(0, 0, 0, 0.5);
39 | }
40 |
41 | .material-scrolltop::before {
42 | position: absolute;
43 | top: 50%;
44 | left: 50%;
45 | -webkit-transform: translate(-50%, -50%);
46 | -ms-transform: translate(-50%, -50%);
47 | -moz-transform: translate(-50%, -50%);
48 | -o-transform: translate(-50%, -50%);
49 | transform: translate(-50%, -50%);
50 | content: "";
51 | width: 0;
52 | border-radius: 100%;
53 | background: #999;
54 | }
55 |
56 | .material-scrolltop:active::before {
57 | width: 120%;
58 | padding-top: 120%;
59 | -webkit-transition: all 0.2s ease-out;
60 | -ms-transition: all 0.2s ease-out;
61 | -moz-transition: all 0.2s ease-out;
62 | -o-transition: all 0.2s ease-out;
63 | transition: all 0.2s ease-out;
64 | }
65 |
66 | .material-scrolltop.reveal {
67 | width: 56px;
68 | height: 56px;
69 | }
70 |
71 | .material-scrolltop span {
72 | display: block;
73 | font-size: 25px;
74 | color: #fff;
75 | }
76 |
77 | .material-scrolltop,
78 | .material-scrolltop::before {
79 | background-image: url(/static/imgs/top-arrow.svg);
80 | background-position: center 50%;
81 | background-repeat: no-repeat;
82 | }
83 | /*# sourceMappingURL=material-scrolltop.css.map */
84 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/css/style.css:
--------------------------------------------------------------------------------
1 |
2 | .avatar {
3 | overflow: hidden;
4 | /* border: 4px solid #FFF; */
5 | margin: 20px auto;
6 | box-shadow: 0 0 10px #000;
7 | width: 120px;
8 | border-radius: 50%;
9 | -webkit-transition: -webkit-transform 400ms;
10 | -moz-transition: -moz-transform 400ms;
11 | transition: transform 400ms;
12 | }
13 |
14 |
15 | .avatar:hover {
16 | -webkit-transform:rotate(390deg);
17 | -moz-transform:rotate(390deg);
18 | transform:rotate(390deg);
19 | }
20 |
21 | .avatar img {
22 | width: 100%;
23 | border-radius: 50%;
24 | }
25 |
26 | .email {
27 | text-decoration: blink;
28 | }
29 |
30 | .email i {
31 | text-align: center;
32 | font-size: 1.1em;
33 | display: block;
34 | }
35 |
36 | .motto {
37 | margin: auto;
38 | font-size: 1.5em;
39 | text-align: center;
40 | }
41 |
42 | .mdl-navigation > a {
43 | font-weight: 600;
44 | }
45 |
46 | blockquote:before, blockquote:after {
47 | display: none;
48 | }
49 |
50 | .navbar {
51 | z-index: 1;
52 | position: fixed;
53 | }
54 |
55 |
56 | .yue p, .yue ul, .yue ol, .yue blockquote {
57 | font-size: 1.0em;
58 | }
59 |
60 | .yue code {
61 | font-size: 0.8em;
62 | }
63 |
64 | .pull-right {
65 | float: right;
66 | }
67 |
68 | .hide {
69 | display: none
70 | }
71 |
72 | h1.year {
73 | font-weight: 600;
74 | font-size: 2.0em;
75 | }
76 |
77 | .container {
78 | word-break: break-all;
79 | margin: auto;
80 | padding-top: 60px;
81 | }
82 |
83 | .time {
84 | padding-bottom: 20px;
85 | }
86 |
87 | hr.post {
88 | width: 100%;
89 | border: 0;
90 | height: 1px;
91 | background-image: -webkit-linear-gradient(left, rgba(228,228,228,0), rgba(228,228,228,0.75), rgba(228,228,228,0));
92 | background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
93 | background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
94 | background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
95 | margin: 40px 0;
96 | }
97 |
98 | .progress-bar {
99 | width: 100%;
100 | position: absolute;
101 | top: 0;
102 | z-index: 999;
103 | display: none;
104 | }
105 |
106 | .mdl-nav {
107 | color: #666;
108 | font-size: 0.8em;
109 | padding: 16px 40px 0;
110 | position: absolute;
111 | bottom: 0;
112 | }
113 |
114 | .mdl-nav a {
115 | text-decoration: blink;
116 | color: #666;
117 | }
118 |
119 | .not-found {
120 | padding-top: 60px;
121 | }
122 |
123 | .mdl-layout__container {
124 | position: static;
125 | }
126 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/css/yue.css:
--------------------------------------------------------------------------------
1 | /**
2 | * yue.css
3 | *
4 | * yue.css is designed for readable content.
5 | *
6 | * Copyright (c) 2013 by Hsiaoming Yang.
7 | */
8 |
9 |
10 |
11 | .yue {
12 | font: 400 18px/1.62 "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif;
13 | color: #444443;
14 | }
15 | .yue ::selection {
16 | background-color: rgba(0,0,0,0.2);
17 | }
18 | .yue h1,
19 | .yue h2,
20 | .yue h3,
21 | .yue h4,
22 | .yue h5,
23 | .yue h6 {
24 | font-family: "Georgia", "Xin Gothic", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft YaHei", "SimSun", sans-serif;
25 | color: #222223;
26 | }
27 | .yue h1 {
28 | font-size: 1.8em;
29 | margin: 0.67em 0;
30 | }
31 | .yue > h1 {
32 | margin-top: 0;
33 | font-size: 2em;
34 | }
35 | .yue h2 {
36 | font-size: 1.5em;
37 | margin: 0.83em 0;
38 | }
39 | .yue h3 {
40 | font-size: 1.17em;
41 | margin: 1em 0;
42 | }
43 | .yue h4,
44 | .yue h5,
45 | .yue h6 {
46 | font-size: 1em;
47 | margin: 1.6em 0 1em 0;
48 | }
49 | .yue h6 {
50 | font-weight: 500;
51 | }
52 | .yue p {
53 | margin-top: 0;
54 | margin-bottom: 1.64em;
55 | }
56 | .yue a {
57 | color: #111;
58 | word-wrap: break-word;
59 | }
60 | .yue a:hover {
61 | color: #555;
62 | }
63 | .yue strong,
64 | .yue b {
65 | font-weight: 700;
66 | color: #222;
67 | }
68 | .yue em,
69 | .yue i {
70 | font-style: italic;
71 | color: #222;
72 | }
73 | .yue img {
74 | max-width: 100%;
75 | height: auto;
76 | margin: 0.2em 0;
77 | }
78 | .yue a img {
79 | /* Remove border on IE */
80 | border: none;
81 | }
82 | .yue figure {
83 | position: relative;
84 | clear: both;
85 | outline: 0;
86 | margin: 10px 0 30px;
87 | padding: 0;
88 | }
89 | .yue figure img {
90 | display: block;
91 | max-width: 100%;
92 | margin: auto;
93 | -webkit-box-sizing: border-box;
94 | -moz-box-sizing: border-box;
95 | box-sizing: border-box;
96 | }
97 | .yue figure figcaption {
98 | position: relative;
99 | width: 100%;
100 | text-align: center;
101 | left: 0;
102 | margin-top: 10px;
103 | font-weight: 400;
104 | font-size: 14px;
105 | color: #666665;
106 | }
107 | .yue figure figcaption a {
108 | text-decoration: none;
109 | color: #666665;
110 | }
111 | .yue hr {
112 | display: block;
113 | width: 14%;
114 | margin: 40px auto 34px;
115 | border: 0 none;
116 | border-top: 3px solid #dededc;
117 | }
118 | .yue blockquote {
119 | margin: 0 0 1.64em 0;
120 | border-left: 3px solid #dadada;
121 | padding-left: 12px;
122 | color: #666664;
123 | }
124 | .yue blockquote a {
125 | color: #666664;
126 | }
127 | .yue ul,
128 | .yue ol {
129 | margin: 0 0 24px 6px;
130 | padding-left: 16px;
131 | }
132 | .yue ul {
133 | list-style-type: square;
134 | }
135 | .yue ol {
136 | list-style-type: decimal;
137 | }
138 | .yue li {
139 | margin-bottom: 0.2em;
140 | }
141 | .yue li ul,
142 | .yue li ol {
143 | margin-top: 0;
144 | margin-bottom: 0;
145 | margin-left: 14px;
146 | }
147 | .yue li ul {
148 | list-style-type: disc;
149 | }
150 | .yue li ul ul {
151 | list-style-type: circle;
152 | }
153 | .yue li p {
154 | margin: 0.4em 0 0.6em;
155 | }
156 | .yue .unstyled {
157 | list-style-type: none;
158 | margin: 0;
159 | padding: 0;
160 | }
161 | .yue code,
162 | .yue tt {
163 | color: #808080;
164 | font-size: 0.96em;
165 | background-color: #f9f9f7;
166 | padding: 1px 2px;
167 | border: 1px solid #dadada;
168 | border-radius: 3px;
169 | font-family: "Inconsolata", "Menlo", monospace;
170 | }
171 | .yue pre {
172 | margin: 1.64em 0;
173 | padding: 7px;
174 | border: none;
175 | border-left: 3px solid #dadada;
176 | padding-left: 10px;
177 | overflow: auto;
178 | line-height: 1.5;
179 | font-size: 0.96em;
180 | font-family: "Inconsolata", "Menlo", monospace;
181 | color: #4c4c4c;
182 | background-color: #f9f9f7;
183 | }
184 | .yue pre code,
185 | .yue pre tt {
186 | color: #4c4c4c;
187 | border: none;
188 | background: none;
189 | padding: 0;
190 | }
191 | .yue table {
192 | width: 100%;
193 | border-collapse: collapse;
194 | border-spacing: 0;
195 | margin-bottom: 1.5em;
196 | font-size: 0.96em;
197 | }
198 | .yue th,
199 | .yue td {
200 | text-align: left;
201 | padding: 4px 8px 4px 10px;
202 | border: 1px solid #dadada;
203 | }
204 | .yue td {
205 | vertical-align: top;
206 | }
207 | .yue tr:nth-child(even) {
208 | background-color: #efefee;
209 | }
210 | .yue iframe {
211 | display: block;
212 | max-width: 100%;
213 | margin-bottom: 30px;
214 | }
215 | .yue figure iframe {
216 | margin: auto;
217 | }
218 | .yue table pre {
219 | margin: 0;
220 | padding: 0;
221 | border: none;
222 | background: none;
223 | }
224 | .yue .highlight td:first-of-type pre {
225 | text-align: right;
226 | color: #aaa;
227 | }
228 | @media (min-width: 1100px) {
229 | .yue blockquote {
230 | margin-left: -24px;
231 | padding-left: 20px;
232 | border-width: 4px;
233 | }
234 | .yue blockquote blockquote {
235 | margin-left: 0;
236 | }
237 | .yue figure figcaption:before {
238 | width: 25%;
239 | margin-left: 75%;
240 | border-top: 1px solid #dededc;
241 | display: block;
242 | content: "";
243 | margin-bottom: 10px;
244 | }
245 | .yue figure figcaption {
246 | position: absolute;
247 | left: -172px;
248 | width: 150px;
249 | top: 0;
250 | text-align: right;
251 | margin-top: 0;
252 | }
253 | }
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/imgs/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/mdl/static/imgs/avatar.jpg
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/imgs/not_found.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicterZ/pyprint/de96f4e4684f35dafd57f521ba6acb55e80f990e/pyprint/themes/mdl/static/imgs/not_found.gif
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/imgs/top-arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/js/material-progress.js:
--------------------------------------------------------------------------------
1 | var componentHandler = (function() {
2 | 'use strict';
3 |
4 | var registeredComponents_ = [];
5 | var createdComponents_ = [];
6 | var downgradeMethod_ = 'mdlDowngrade_';
7 | var componentConfigProperty_ = 'mdlComponentConfigInternal_';
8 |
9 | /**
10 | * Searches registered components for a class we are interested in using.
11 | * Optionally replaces a match with passed object if specified.
12 | * @param {string} name The name of a class we want to use.
13 | * @param {Object=} optReplace Optional object to replace match with.
14 | * @return {Object | boolean}
15 | * @private
16 | */
17 | function findRegisteredClass_(name, optReplace) {
18 | for (var i = 0; i < registeredComponents_.length; i++) {
19 | if (registeredComponents_[i].className === name) {
20 | if (optReplace !== undefined) {
21 | registeredComponents_[i] = optReplace;
22 | }
23 | return registeredComponents_[i];
24 | }
25 | }
26 | return false;
27 | }
28 |
29 | /**
30 | * Returns an array of the classNames of the upgraded classes on the element.
31 | * @param {HTMLElement} element The element to fetch data from.
32 | * @return {Array}
33 | * @private
34 | */
35 | function getUpgradedListOfElement_(element) {
36 | var dataUpgraded = element.getAttribute('data-upgraded');
37 | // Use `['']` as default value to conform the `,name,name...` style.
38 | return dataUpgraded === null ? [''] : dataUpgraded.split(',');
39 | }
40 |
41 | /**
42 | * Returns true if the given element has already been upgraded for the given
43 | * class.
44 | * @param {HTMLElement} element The element we want to check.
45 | * @param {string} jsClass The class to check for.
46 | * @return boolean
47 | * @private
48 | */
49 | function isElementUpgraded_(element, jsClass) {
50 | var upgradedList = getUpgradedListOfElement_(element);
51 | return upgradedList.indexOf(jsClass) !== -1;
52 | }
53 |
54 | /**
55 | * Searches existing DOM for elements of our component type and upgrades them
56 | * if they have not already been upgraded.
57 | * @param {!string=} optJsClass the programatic name of the element class we
58 | * need to create a new instance of.
59 | * @param {!string=} optCssClass the name of the CSS class elements of this
60 | * type will have.
61 | */
62 | function upgradeDomInternal(optJsClass, optCssClass) {
63 | if (optJsClass === undefined && optCssClass === undefined) {
64 | for (var i = 0; i < registeredComponents_.length; i++) {
65 | upgradeDomInternal(registeredComponents_[i].className,
66 | registeredComponents_[i].cssClass);
67 | }
68 | } else {
69 | var jsClass = /** @type {!string} */ (optJsClass);
70 | if (optCssClass === undefined) {
71 | var registeredClass = findRegisteredClass_(jsClass);
72 | if (registeredClass) {
73 | optCssClass = registeredClass.cssClass;
74 | }
75 | }
76 |
77 | var elements = document.querySelectorAll('.' + optCssClass);
78 | for (var n = 0; n < elements.length; n++) {
79 | upgradeElementInternal(elements[n], jsClass);
80 | }
81 | }
82 | }
83 |
84 | /**
85 | * Upgrades a specific element rather than all in the DOM.
86 | * @param {HTMLElement} element The element we wish to upgrade.
87 | * @param {!string=} optJsClass Optional name of the class we want to upgrade
88 | * the element to.
89 | */
90 | function upgradeElementInternal(element, optJsClass) {
91 | // Verify argument type.
92 | if (!(typeof element === 'object' && element instanceof Element)) {
93 | throw new Error('Invalid argument provided to upgrade MDL element.');
94 | }
95 | var upgradedList = getUpgradedListOfElement_(element);
96 | var classesToUpgrade = [];
97 | // If jsClass is not provided scan the registered components to find the
98 | // ones matching the element's CSS classList.
99 | if (!optJsClass) {
100 | var classList = element.classList;
101 | registeredComponents_.forEach(function (component) {
102 | // Match CSS & Not to be upgraded & Not upgraded.
103 | if (classList.contains(component.cssClass) &&
104 | classesToUpgrade.indexOf(component) === -1 &&
105 | !isElementUpgraded_(element, component.className)) {
106 | classesToUpgrade.push(component);
107 | }
108 | });
109 | } else if (!isElementUpgraded_(element, optJsClass)) {
110 | classesToUpgrade.push(findRegisteredClass_(optJsClass));
111 | }
112 |
113 | // Upgrade the element for each classes.
114 | for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {
115 | registeredClass = classesToUpgrade[i];
116 | if (registeredClass) {
117 | // Mark element as upgraded.
118 | upgradedList.push(registeredClass.className);
119 | element.setAttribute('data-upgraded', upgradedList.join(','));
120 | var instance = new registeredClass.classConstructor(element);
121 | instance[componentConfigProperty_] = registeredClass;
122 | createdComponents_.push(instance);
123 | // Call any callbacks the user has registered with this component type.
124 | for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {
125 | registeredClass.callbacks[j](element);
126 | }
127 |
128 | if (registeredClass.widget) {
129 | // Assign per element instance for control over API
130 | element[registeredClass.className] = instance;
131 | }
132 | } else {
133 | throw new Error(
134 | 'Unable to find a registered component for the given class.');
135 | }
136 |
137 | var ev = document.createEvent('Events');
138 | ev.initEvent('mdl-componentupgraded', true, true);
139 | element.dispatchEvent(ev);
140 | }
141 | }
142 |
143 | /**
144 | * Upgrades a specific list of elements rather than all in the DOM.
145 | * @param {HTMLElement | Array | NodeList | HTMLCollection} elements
146 | * The elements we wish to upgrade.
147 | */
148 | function upgradeElementsInternal(elements) {
149 | if (!Array.isArray(elements)) {
150 | if (typeof elements.item === 'function') {
151 | elements = Array.prototype.slice.call(elements);
152 | } else {
153 | elements = [elements];
154 | }
155 | }
156 | for (var i = 0, n = elements.length, element; i < n; i++) {
157 | element = elements[i];
158 | if (element instanceof HTMLElement) {
159 | if (element.children.length > 0) {
160 | upgradeElementsInternal(element.children);
161 | }
162 | upgradeElementInternal(element);
163 | }
164 | }
165 | }
166 |
167 | /**
168 | * Registers a class for future use and attempts to upgrade existing DOM.
169 | * @param {Object} config An object containing:
170 | * {constructor: Constructor, classAsString: string, cssClass: string}
171 | */
172 | function registerInternal(config) {
173 | var newConfig = {
174 | 'classConstructor': config.constructor,
175 | 'className': config.classAsString,
176 | 'cssClass': config.cssClass,
177 | 'widget': config.widget === undefined ? true : config.widget,
178 | 'callbacks': []
179 | };
180 |
181 | registeredComponents_.forEach(function(item) {
182 | if (item.cssClass === newConfig.cssClass) {
183 | throw new Error('The provided cssClass has already been registered.');
184 | }
185 | if (item.className === newConfig.className) {
186 | throw new Error('The provided className has already been registered');
187 | }
188 | });
189 |
190 | if (config.constructor.prototype
191 | .hasOwnProperty(componentConfigProperty_)) {
192 | throw new Error(
193 | 'MDL component classes must not have ' + componentConfigProperty_ +
194 | ' defined as a property.');
195 | }
196 |
197 | var found = findRegisteredClass_(config.classAsString, newConfig);
198 |
199 | if (!found) {
200 | registeredComponents_.push(newConfig);
201 | }
202 | }
203 |
204 | /**
205 | * Allows user to be alerted to any upgrades that are performed for a given
206 | * component type
207 | * @param {string} jsClass The class name of the MDL component we wish
208 | * to hook into for any upgrades performed.
209 | * @param {!Function} callback The function to call upon an upgrade. This
210 | * function should expect 1 parameter - the HTMLElement which got upgraded.
211 | */
212 | function registerUpgradedCallbackInternal(jsClass, callback) {
213 | var regClass = findRegisteredClass_(jsClass);
214 | if (regClass) {
215 | regClass.callbacks.push(callback);
216 | }
217 | }
218 |
219 | /**
220 | * Upgrades all registered components found in the current DOM. This is
221 | * automatically called on window load.
222 | */
223 | function upgradeAllRegisteredInternal() {
224 | for (var n = 0; n < registeredComponents_.length; n++) {
225 | upgradeDomInternal(registeredComponents_[n].className);
226 | }
227 | }
228 |
229 | /**
230 | * Finds a created component by a given DOM node.
231 | *
232 | * @param {!Element} node
233 | * @return {*}
234 | */
235 | function findCreatedComponentByNodeInternal(node) {
236 | for (var n = 0; n < createdComponents_.length; n++) {
237 | var component = createdComponents_[n];
238 | if (component.element_ === node) {
239 | return component;
240 | }
241 | }
242 | }
243 |
244 | /**
245 | * Check the component for the downgrade method.
246 | * Execute if found.
247 | * Remove component from createdComponents list.
248 | *
249 | * @param {*} component
250 | */
251 | function deconstructComponentInternal(component) {
252 | if (component &&
253 | component[componentConfigProperty_]
254 | .classConstructor.prototype
255 | .hasOwnProperty(downgradeMethod_)) {
256 | component[downgradeMethod_]();
257 | var componentIndex = createdComponents_.indexOf(component);
258 | createdComponents_.splice(componentIndex, 1);
259 |
260 | var upgrades = component.element_.dataset.upgraded.split(',');
261 | var componentPlace = upgrades.indexOf(
262 | component[componentConfigProperty_].classAsString);
263 | upgrades.splice(componentPlace, 1);
264 | component.element_.dataset.upgraded = upgrades.join(',');
265 |
266 | var ev = document.createEvent('Events');
267 | ev.initEvent('mdl-componentdowngraded', true, true);
268 | component.element_.dispatchEvent(ev);
269 | }
270 | }
271 |
272 | /**
273 | * Downgrade either a given node, an array of nodes, or a NodeList.
274 | *
275 | * @param {*} nodes
276 | */
277 | function downgradeNodesInternal(nodes) {
278 | var downgradeNode = function(node) {
279 | deconstructComponentInternal(findCreatedComponentByNodeInternal(node));
280 | };
281 | if (nodes instanceof Array || nodes instanceof NodeList) {
282 | for (var n = 0; n < nodes.length; n++) {
283 | downgradeNode(nodes[n]);
284 | }
285 | } else if (nodes instanceof Node) {
286 | downgradeNode(nodes);
287 | } else {
288 | throw new Error('Invalid argument provided to downgrade MDL nodes.');
289 | }
290 | }
291 |
292 | // Now return the functions that should be made public with their publicly
293 | // facing names...
294 | return {
295 | upgradeDom: upgradeDomInternal,
296 | upgradeElement: upgradeElementInternal,
297 | upgradeElements: upgradeElementsInternal,
298 | upgradeAllRegistered: upgradeAllRegisteredInternal,
299 | registerUpgradedCallback: registerUpgradedCallbackInternal,
300 | register: registerInternal,
301 | downgradeElements: downgradeNodesInternal
302 | };
303 | })();
304 |
305 | window.addEventListener('load', function() {
306 | 'use strict';
307 |
308 | /**
309 | * Performs a "Cutting the mustard" test. If the browser supports the features
310 | * tested, adds a mdl-js class to the element. It then upgrades all MDL
311 | * components requiring JavaScript.
312 | */
313 | if ('classList' in document.createElement('div') &&
314 | 'querySelector' in document &&
315 | 'addEventListener' in window && Array.prototype.forEach) {
316 | document.documentElement.classList.add('mdl-js');
317 | componentHandler.upgradeAllRegistered();
318 | } else {
319 | componentHandler.upgradeElement =
320 | componentHandler.register = function() {};
321 | }
322 | });
323 |
324 | function MaterialProgress(element) {
325 | 'use strict';
326 |
327 | this.element_ = element;
328 |
329 | // Initialize instance.
330 | this.init();
331 | }
332 |
333 | /**
334 | * Store constants in one place so they can be updated easily.
335 | * @enum {string | number}
336 | * @private
337 | */
338 | MaterialProgress.prototype.Constant_ = {
339 | };
340 |
341 | /**
342 | * Store strings for class names defined by this component that are used in
343 | * JavaScript. This allows us to simply change it in one place should we
344 | * decide to modify at a later date.
345 | * @enum {string}
346 | * @private
347 | */
348 | MaterialProgress.prototype.CssClasses_ = {
349 | INDETERMINATE_CLASS: 'mdl-progress__indeterminate'
350 | };
351 |
352 | MaterialProgress.prototype.setProgress = function(p) {
353 | 'use strict';
354 |
355 | if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {
356 | return;
357 | }
358 |
359 | this.progressbar_.style.width = p + '%';
360 | };
361 |
362 | MaterialProgress.prototype.setBuffer = function(p) {
363 | 'use strict';
364 |
365 | this.bufferbar_.style.width = p + '%';
366 | this.auxbar_.style.width = (100 - p) + '%';
367 | };
368 |
369 | /**
370 | * Initialize element.
371 | */
372 | MaterialProgress.prototype.init = function() {
373 | 'use strict';
374 |
375 | if (this.element_) {
376 | var el = document.createElement('div');
377 | el.className = 'progressbar bar bar1';
378 | this.element_.appendChild(el);
379 | this.progressbar_ = el;
380 |
381 | el = document.createElement('div');
382 | el.className = 'bufferbar bar bar2';
383 | this.element_.appendChild(el);
384 | this.bufferbar_ = el;
385 |
386 | el = document.createElement('div');
387 | el.className = 'auxbar bar bar3';
388 | this.element_.appendChild(el);
389 | this.auxbar_ = el;
390 |
391 | this.progressbar_.style.width = '0%';
392 | this.bufferbar_.style.width = '100%';
393 | this.auxbar_.style.width = '0%';
394 |
395 | this.element_.classList.add('is-upgraded');
396 | }
397 | };
398 |
399 | /*
400 | * Downgrade the component
401 | */
402 | MaterialProgress.prototype.mdlDowngrade_ = function() {
403 | 'use strict';
404 | while (this.element_.firstChild) {
405 | this.element_.removeChild(this.element_.firstChild);
406 | }
407 | };
408 |
409 | // The component registers itself. It can assume componentHandler is available
410 | // in the global scope.
411 | componentHandler.register({
412 | constructor: MaterialProgress,
413 | classAsString: 'MaterialProgress',
414 | cssClass: 'mdl-js-progress',
415 | widget: true
416 | });
--------------------------------------------------------------------------------
/pyprint/themes/mdl/static/js/material-scrolltop.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Material-scrollTop
3 | *
4 | * Author: Bartholomej
5 | * Website: https://github.com/bartholomej/material-scrollTop
6 | * Docs: https://github.com/bartholomej/material-scrollTop
7 | * Repo: https://github.com/bartholomej/material-scrollTop
8 | * Issues: https://github.com/bartholomej/material-scrollTop/issues
9 | */
10 | (function($) {
11 | function mScrollTop(element, settings) {
12 | var _ = this,
13 | breakpoint;
14 | var scrollTo = 0;
15 |
16 | _.btnClass = '.material-scrolltop';
17 | _.revealClass = 'reveal';
18 | _.btnElement = $(_.btnClass);
19 |
20 | _.initial = {
21 | revealElement: 'body',
22 | revealPosition: 'top',
23 | padding: 0,
24 | duration: 600,
25 | easing: 'swing',
26 | onScrollEnd: false
27 | };
28 |
29 | _.options = $.extend({}, _.initial, settings);
30 |
31 | _.revealElement = $(_.options.revealElement);
32 | breakpoint = _.options.revealPosition !== 'bottom' ? _.revealElement.offset().top : _.revealElement.offset().top + _.revealElement.height();
33 | scrollTo = element.offsetTop + _.options.padding;
34 |
35 | $(document).scroll(function() {
36 | if (breakpoint < $(document).scrollTop()) {
37 | _.btnElement.addClass(_.revealClass);
38 | } else {
39 | _.btnElement.removeClass(_.revealClass);
40 | }
41 | });
42 |
43 | _.btnElement.click(function() {
44 | $('body').animate({
45 | scrollTop: scrollTo
46 | }, _.options.duration, _.options.easing, _.options.onScrollEnd);
47 | return false;
48 | });
49 |
50 | }
51 |
52 | $.fn.materialScrollTop = function() {
53 | var _ = this,
54 | opt = arguments[0],
55 | l = _.length,
56 | i = 0;
57 | if (typeof opt == 'object' || typeof opt == 'undefined') {
58 | _[i].materialScrollTop = new mScrollTop(_[i], opt);
59 | }
60 | return _;
61 | };
62 | }(jQuery));
63 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/archives.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 |
9 | {% for group in posts_groups %}
10 | -
11 |
{{ group.year }}
12 |
13 | {% for post in group.posts %}
14 |
15 | {% endfor %}
16 |
17 |
18 | {% endfor %}
19 |
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/diaries.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 |
9 | {% for diary in diaries %}
10 |
11 | {% endfor %}
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ settings.username }}
4 | {{ settings.title }}
5 | {{ posts[0].created_time if posts }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | http://{{ url }}
14 |
15 | {% for post in posts %}
16 |
17 | {{ post.title }}
18 | http://{{ url }}/posts/{{ post.title|urlencode }}
19 | http://{{ url }}/posts/{{ post.title|urlencode }}
20 | {{ post.created_time }}
21 | {% if post.password == "" or post.password == None %}
22 |
23 | {% else %}
24 |
25 | {% endif %}
26 |
27 | {% endfor %}
28 |
29 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/index.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 | {% for post in data.posts %}
9 |
10 |
11 |
14 | {% if post.password == "" or post.password == None %}
15 |
16 | {{ post.content|markdown }}
17 |
18 |
19 | {% if post.tags %}
20 | Tagged in:
21 | {% for tag in post.tags %}
22 | {{ tag.slug }}
23 | {% if not loop.last %} / {% endif %}
24 | {% endfor %}
25 |
26 | {% endif %}
27 |
28 | {% else %}
29 |
30 | Password protected
31 |
32 | {% endif %}
33 |
34 |
35 | {% if not loop.last %}
36 |
37 | {% endif %}
38 | {% endfor %}
39 |
43 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ title }} - {{ settings.title }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% block head %}{% endblock %}
17 |
18 |
19 |
20 |
21 |
22 |
56 |
57 |
58 |
59 |
89 |
90 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/links.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 |
8 | {% block body %}
9 |
10 | About me
11 |
19 |
20 | My Friends
21 |
22 |
23 | {% for link in links %}
24 | - {{ link.name }}: {{ link.url }}
25 | {% else %}
26 | I am alone ..
27 | {% endfor %}
28 |
29 |
30 |
31 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/not_found.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | 你在看哪里!?
6 |
7 |
8 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/pjax_layout.html:
--------------------------------------------------------------------------------
1 | {{ title }} - {{ settings.title }}
2 |
3 | {% block body %}
4 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/mdl/templates/post.html:
--------------------------------------------------------------------------------
1 | {% if is_pjax %}
2 | {% extends "pjax_layout.html" %}
3 | {% else %}
4 | {% extends "layout.html" %}
5 | {% endif %}
6 |
7 | {% block body %}
8 |
9 |
10 |
13 |
14 | {{ post.content|markdown }}
15 |
16 |
17 | {% if post.tags %}
18 | Tagged in:
19 | {% for tag in post.tags %}
20 | {{ tag.slug }}
21 | {% if not loop.last %} / {% endif %}
22 | {% endfor %}
23 |
24 | {% endif %}
25 |
26 |
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/diaries.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | {% for diary in diaries %}
6 | -
7 | {{ diary.title }}
8 | {{ diary.created_time }}
9 |
10 | {% endfor %}
11 |
12 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ settings.username }}
4 | {{ settings.title }}
5 | {{ posts[0].created_time if posts }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | http://{{ url }}
14 |
15 | {% for post in posts %}
16 |
17 | {{ post.title }}
18 | http://{{ url }}/articles/{{ post.title }}
19 | http://{{ url }}/articles/{{ post.title }}
20 | {{ post.created_time }}
21 |
22 |
23 | {% endfor %}
24 |
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 | {% for post in data.posts %}
5 |
6 | {{ post.title }}
7 |
8 |
9 | Posted at {{ post.created_time }}
10 | ======================
11 | {{ post.content|markdown_image }}
12 |
13 |
14 |
------------------------------------------
15 | {% endfor %}
16 | << Newer
17 | Older >>
18 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ title }} - {{ settings.title }}
7 |
31 |
32 |
33 |
34 | {{ settings.username }} - {{ settings.motto }}
35 |
36 |
37 |
------------------------------------------
38 | Posts
39 | Diary
40 | Links
41 | RSS
42 |
------------------------------------------
43 | {% block body %}
44 | {% endblock %}
45 |
------------------------------------------
46 | {{ settings.username }} © 2015 • All rights reserved
47 |
50 |
51 |
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/links.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 |
4 | {% block body %}
5 | My Friends
6 |
11 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/not_found.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 | Baka
5 | {% endblock %}
--------------------------------------------------------------------------------
/pyprint/themes/none/templates/post.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
5 | {{ post.title }}
6 |
7 |
8 | Posted at {{ post.created_time }}
9 | ======================
10 | {{ post.content|markdown_image }}
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyprint/utils.py:
--------------------------------------------------------------------------------
1 | import re
2 | import cgi
3 | from markdown import markdown as md
4 |
5 |
6 | class Storage(dict):
7 | def __getattr__(self, item):
8 | return self[item]
9 |
10 | def __setattr__(self, key, value):
11 | self[key] = value
12 |
13 |
14 | def get_host(url):
15 | return '/'.join(url.split('/')[2:-1])
16 |
17 |
18 | def markdown(content):
19 | return md(content)
20 |
21 |
22 | def markdown_image(content):
23 | content = cgi.escape(content)
24 | return re.sub('!\[(.*?)\]\((.*?)\)', '
', content)
25 |
26 |
27 | def fix_lazy_load(content):
28 | return re.sub(r'
', '
', content)
29 |
--------------------------------------------------------------------------------
/pyprint/views/__init__.py:
--------------------------------------------------------------------------------
1 | from posts import ListPostsHandler, ListPostsByTagHandler, RetrievePostHandler, ArchiveHandler, FeedHandler
2 | from links import ListLinksHandler
3 | from others import AkarinHandler, NotFoundHandler, HitokotoHandler
4 | from background import SignInHandler, ManagePostHandler, AddLinkHandler, AddPostHandler
5 | from diaries import RetrieveDiaryHandler, ListDiariesHandler
6 |
7 |
8 | handlers = [
9 | # posts.py
10 | (r'/', ListPostsHandler),
11 | (r'/page/([\d]+)?', ListPostsHandler),
12 | (r'/posts/(.*)', RetrievePostHandler),
13 | (r'/tags/(.*)', ListPostsByTagHandler),
14 | (r'/archives', ArchiveHandler),
15 | (r'/feed', FeedHandler),
16 |
17 | # diaries.py
18 | (r'/diaries', ListDiariesHandler),
19 | (r'/diaries/(.*)', RetrieveDiaryHandler),
20 |
21 | # links.py
22 | (r'/links', ListLinksHandler),
23 |
24 | # background
25 | (r'/login', SignInHandler),
26 | (r'/kamisama/posts', ManagePostHandler),
27 | (r'/kamisama/posts/add', AddPostHandler),
28 | (r'/kamisama/links', AddLinkHandler),
29 |
30 | # others.py
31 | (r'/akarin', AkarinHandler),
32 | (r'/hitokoto', HitokotoHandler),
33 | (r'/(.*)', NotFoundHandler),
34 | ]
35 |
--------------------------------------------------------------------------------
/pyprint/views/background.py:
--------------------------------------------------------------------------------
1 | import tornado.web
2 | from datetime import date
3 | from sqlalchemy.orm.exc import NoResultFound
4 |
5 | from pyprint.handler import BaseHandler
6 | from pyprint.models import User, Link, Post
7 |
8 |
9 | class SignInHandler(BaseHandler):
10 | def get(self):
11 | return self.background_render('login.html')
12 |
13 | def post(self):
14 | username = self.get_argument('username', None)
15 | password = self.get_argument('password', None)
16 |
17 | if username and password:
18 | try:
19 | user = self.orm.query(User).filter(User.username == username).one()
20 | except NoResultFound:
21 | return self.redirect('/login')
22 | if user.check(password):
23 | self.set_secure_cookie('username', user.username)
24 | self.redirect('/kamisama/posts')
25 |
26 | return self.redirect('/login')
27 |
28 |
29 | class ManagePostHandler(BaseHandler):
30 | @tornado.web.authenticated
31 | def get(self):
32 | posts = self.orm.query(Post.title, Post.id).order_by(Post.id.desc()).all()
33 | self.background_render('posts.html', posts=posts)
34 |
35 | @tornado.web.authenticated
36 | def post(self):
37 | action = self.get_argument('action', None)
38 | if action == 'del':
39 | post_id = self.get_argument('id', 0)
40 | if post_id:
41 | post = self.orm.query(Post).filter(Post.id == post_id).one()
42 | self.orm.delete(post)
43 | self.orm.commit()
44 |
45 |
46 | class AddPostHandler(BaseHandler):
47 | @tornado.web.authenticated
48 | def get(self):
49 | self.background_render('add_post.html', post=None)
50 |
51 | @tornado.web.authenticated
52 | def post(self):
53 | title = self.get_argument('title', None)
54 | content = self.get_argument('content', None)
55 | tags = self.get_argument('tags', '').strip().split(',')
56 | if not title or not content:
57 | return self.redirect('/kamisama/posts/add')
58 |
59 | post = self.orm.query(Post.title).filter(Post.title == title).all()
60 | if post:
61 | return self.write('')
62 | self.orm.add(Post(title=title, content=content, created_time=date.today()))
63 | self.orm.commit()
64 | return self.redirect('/kamisama/posts')
65 |
66 |
67 | class AddLinkHandler(BaseHandler):
68 | @tornado.web.authenticated
69 | def get(self):
70 | links = self.orm.query(Link).all()
71 | self.background_render('links.html', links=links)
72 |
73 | @tornado.web.authenticated
74 | def post(self):
75 | action = self.get_argument('action', None)
76 | if action == 'add':
77 | name = self.get_argument('name', '')
78 | url = self.get_argument('url', '')
79 | if not name or not url:
80 | return self.redirect('/kamisama/links')
81 | self.orm.add(Link(name=name, url=url))
82 | self.orm.commit()
83 | return self.redirect('/kamisama/links')
84 |
85 | elif action == 'del':
86 | link_id = self.get_argument('id', 0)
87 | if link_id:
88 | link = self.orm.query(Link).filter(Link.id == link_id).one()
89 | self.orm.delete(link)
90 | self.orm.commit()
91 |
--------------------------------------------------------------------------------
/pyprint/views/diaries.py:
--------------------------------------------------------------------------------
1 | #coding: utf-8
2 | import tornado.web
3 | from sqlalchemy import and_
4 | from sqlalchemy.orm.exc import NoResultFound
5 | from pyprint.handler import BaseHandler
6 | from pyprint.models import Post
7 | from pyprint.constants import DIARY
8 |
9 |
10 | class ListDiariesHandler(BaseHandler):
11 | def get(self):
12 | diaries = self.orm.query(Post.title, Post.created_time).filter(Post.type == DIARY)\
13 | .order_by(Post.created_time.desc()).all()
14 | return self.render('diaries.html', title='Diaries', diaries=diaries)
15 |
16 |
17 | class RetrieveDiaryHandler(BaseHandler):
18 | def get(self, title):
19 | password = self.get_argument('pass', None)
20 |
21 | try:
22 | post = self.orm.query(Post).filter(and_(Post.title == title, Post.type == 'diary')).one()
23 | except NoResultFound:
24 | return self.redirect('/akarin')
25 |
26 | if post.password and not password == post.password:
27 | raise tornado.web.HTTPError(403, 'Password Protected')
28 |
29 | return self.render('post.html', title=post.title, post=post)
30 |
--------------------------------------------------------------------------------
/pyprint/views/links.py:
--------------------------------------------------------------------------------
1 | from pyprint.handler import BaseHandler
2 | from pyprint.models import Link
3 |
4 |
5 | class ListLinksHandler(BaseHandler):
6 | def get(self):
7 | return self.render('links.html', title='Links & About', links=self.orm.query(Link).all())
--------------------------------------------------------------------------------
/pyprint/views/others.py:
--------------------------------------------------------------------------------
1 | import urllib2
2 | from pyprint.handler import BaseHandler
3 |
4 |
5 | class AkarinHandler(BaseHandler):
6 | def get(self):
7 | return self.render('not_found.html', title='404 Not Found')
8 |
9 |
10 | class NotFoundHandler(BaseHandler):
11 | def get(self, path):
12 | return self.redirect('/akarin')
13 |
14 |
15 | class HitokotoHandler(BaseHandler):
16 | def get(self):
17 | hitokoto_url = 'http://api.hitokoto.us/rand?encode=js&charset=utf-8'
18 | self.write(urllib2.urlopen(hitokoto_url).read())
19 |
--------------------------------------------------------------------------------
/pyprint/views/posts.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | import tornado.web
3 |
4 | from itertools import groupby
5 |
6 | from sqlalchemy.orm.exc import NoResultFound
7 | from sqlalchemy import and_
8 | from pyprint.handler import BaseHandler
9 | from pyprint.models import Post, Tag
10 | from pyprint.utils import get_host
11 | from pyprint import constants
12 |
13 | from pyprint.settings import post_of_page
14 |
15 |
16 | class ListPostsHandler(BaseHandler):
17 | def get(self, page=1):
18 | page = int(page) if int(page) else 1
19 |
20 | posts = self.orm.query(Post).filter(Post.type == constants.POST)\
21 | .order_by(Post.created_time.desc()).limit(post_of_page).offset(
22 | (page - 1) * post_of_page).all()
23 |
24 | return self.render('index.html', title=u'初心を忘れず', data={
25 | 'preview': page - 1,
26 | 'next': page + 1,
27 | 'posts': posts
28 | })
29 |
30 |
31 | class RetrievePostHandler(BaseHandler):
32 | def get(self, title):
33 | password = self.get_argument('pass', None)
34 |
35 | try:
36 | post = self.orm.query(Post).filter(and_(Post.title == title, Post.type == 'post')).one()
37 | except NoResultFound:
38 | return self.redirect('/akarin')
39 |
40 | if post.password and not password == post.password:
41 | raise tornado.web.HTTPError(403, 'Password Protected')
42 |
43 | return self.render('post.html', title=post.title, post=post)
44 |
45 |
46 | class ListPostsByTagHandler(BaseHandler):
47 | def get(self, slug):
48 | try:
49 | tag = self.orm.query(Tag).filter(Tag.slug == slug).one()
50 | except NoResultFound:
51 | return self.redirect('/akarin')
52 |
53 | posts = [post for post in tag.posts if post.type == constants.POST]
54 | return self.render('index.html', title='Tag: %s' % tag.slug, data={
55 | 'preview': 0,
56 | 'next': 0,
57 | 'posts': posts,
58 | })
59 |
60 |
61 | class ArchiveHandler(BaseHandler):
62 | def get(self):
63 | posts = self.orm.query(Post.title, Post.created_time).\
64 | filter(Post.type == constants.POST).order_by(Post.created_time.desc()).all()
65 |
66 | posts_groups = [{'year': year, 'posts': list(posts)} for year, posts in
67 | groupby(posts, key=lambda p: p.created_time.year)]
68 |
69 | return self.render('archives.html', title='Archives', posts_groups=posts_groups)
70 |
71 |
72 | class FeedHandler(BaseHandler):
73 | def get(self):
74 | posts = self.orm.query(Post).filter(Post.type == constants.POST).order_by(
75 | Post.created_time.desc()).limit(3).all()
76 | headers = {
77 | 'Content-Type': 'application/xml',
78 | }
79 | return self.render('feed.xml', posts=posts,
80 | url=get_host(self.request.full_url()), headers=headers)
81 |
--------------------------------------------------------------------------------
/requirement.txt:
--------------------------------------------------------------------------------
1 | tornado>=4.0
2 | sqlalchemy>=0.9.7
3 | jinja2>=2.7.3
4 | MySQL-python==1.2.5
5 | markdown==2.4.1
6 |
--------------------------------------------------------------------------------