mirror of
https://github.com/jessebot/tiny_personal_website.git
synced 2025-10-01 01:48:43 +00:00
commit
bbfca9a18b
12 changed files with 164 additions and 102 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,3 +3,6 @@ legacy
|
|||
config/config.yaml
|
||||
config.yaml
|
||||
front_end/images/private/*
|
||||
front_end/images/defcon23.JPG
|
||||
front_end/images/swag.gif
|
||||
front_end/images/favicon_jessebot.ico
|
||||
|
|
38
README.md
38
README.md
|
@ -1,10 +1,36 @@
|
|||
bootstrap_bottle
|
||||
================
|
||||
tiny_personal_website
|
||||
=====================
|
||||
|
||||
Basic bottle driven website with a bootstrap frontend.
|
||||
This is a Python based CMS for a small personal website. The back end uses
|
||||
the bottle web framework and the front end is bootstrap. YAML is used for site
|
||||
specific configurations.
|
||||
|
||||
Configuration stored in confg/config.yaml.sample
|
||||
|
||||
The website is located at http://jessebot.com
|
||||
Setup
|
||||
-----
|
||||
|
||||
1. Clone this github repo into your desired webroot.
|
||||
|
||||
2. You can configure everything (e.g. the webroot absolute path, your photo,
|
||||
quote, etc) by renaming `config/config.yaml.sample` to `config.yaml` and
|
||||
replacing all the sample data with your own real data.
|
||||
|
||||
3. The website assumes you're running on a Linux server with apache. I use the
|
||||
[mod_wsgi](https://github.com/GrahamDumpleton/mod_wsgi) apache module to
|
||||
deliver this content.
|
||||
..* In `config/example.com.conf` I have an example apache
|
||||
virutal host config. I recommend creating a special user and group for this
|
||||
website to run as.
|
||||
..* There is also a mandatory `config/wsgi.conf` you'll need to put in your
|
||||
apache config. You may also need to modify permissions for the socket file if
|
||||
you are running CentOS/RHEL, which will live in `/var/run/http`.
|
||||
|
||||
4. All changes to HTML, CSS, JS, Python, or your core YAML will require an
|
||||
apache restart.
|
||||
|
||||
|
||||
Sample Site
|
||||
-----------
|
||||
|
||||
The website this is based off of is http://jessebot.com
|
||||
|
||||
The socket file (CentOS/RHEL) is in /var/run.
|
||||
|
|
|
@ -8,6 +8,6 @@ sys.path.append(os.path.dirname(__file__))
|
|||
# ... build or import your bottle application here ...
|
||||
# Do NOT use bottle.run() with mod_wsgi
|
||||
|
||||
import jessebot
|
||||
import web_routes
|
||||
|
||||
application = bottle.default_app()
|
|
@ -2,25 +2,27 @@ Globals:
|
|||
# absolute path required
|
||||
web_root: '/var/www/html'
|
||||
# favicon, can take any image type
|
||||
favicon: 'favicon.ico'
|
||||
favicon: 'favicon_smile.gif'
|
||||
# domain name, or whatever you want the tab in the browser to say
|
||||
website_title: 'example.com'
|
||||
# the default image shown at the front of the page
|
||||
profile_image: 'my_picture.JPG'
|
||||
profile_image: 'my_picture.png'
|
||||
# Your name
|
||||
profile_name: 'Jesse'
|
||||
profile_name: 'Bob Smith'
|
||||
# Quote of any sort you'd like
|
||||
profile_quote: "The internet is great."
|
||||
profile_quote: "The internet is great. Please enjoy this sample webpage."
|
||||
# Full URL to your github
|
||||
github_URL: 'https://github.com/jessebot'
|
||||
# complete google doc sharing URL, assuming this is public
|
||||
resume_google_doc: 'https://docs.google.com/document/d/blahblahblah'
|
||||
# in your google doc, you can go to download as and right click copy that
|
||||
# URL, or you can host a live copy at another URL
|
||||
resume_pdf_download: 'https://docs.google.com/document/d/blahpdfblahblahblah'
|
||||
resume_docx_download: 'https://docs.google.com/document/d/1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc/export?format=docx&id=1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc'
|
||||
resume_pdf_download: 'https://docs.google.com/document/d/blahblahblah/export?format=pdf'
|
||||
resume_docx_download: 'https://docs.google.com/document/d/blahblahblah/export?format=docx'
|
||||
# Boolean, if set to True, will generate new panel with below info
|
||||
optional_panel: True
|
||||
# this could be social media, other conent, whatever suits you!
|
||||
extra_box_title: "Linux Newbie Class"
|
||||
extra_box_image: "penguin_copy.png"
|
||||
extra_box_link_title: "How To Unix/Linux"
|
||||
extra_box_URL: "http://howtonix.info/"
|
||||
opt_panel_title: "Linux Newbie Class"
|
||||
opt_panel_image: "penguin_copy.png"
|
||||
opt_panel_button_text: "How To Unix/Linux"
|
||||
opt_panel_URL: "http://howtonix.info/"
|
||||
|
|
13
config/example.com.conf
Normal file
13
config/example.com.conf
Normal file
|
@ -0,0 +1,13 @@
|
|||
<VirtualHost *:80>
|
||||
ServerName example.com
|
||||
ServerAdmin example_user@gmail.com
|
||||
WSGIDaemonProcess example_process_name user=example_user group=example_group processes=1 threads=5
|
||||
WSGIScriptAlias / /path/to/web/root/adapter.wsgi
|
||||
|
||||
<Directory /path/to/web/root>
|
||||
WSGIProcessGroup example_group
|
||||
WSGIApplicationGroup %{GLOBAL}
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Directory>
|
||||
</VirtualHost>
|
1
config/wsgi.conf
Normal file
1
config/wsgi.conf
Normal file
|
@ -0,0 +1 @@
|
|||
LoadModule wsgi_module modules/mod_wsgi.so
|
|
@ -6,9 +6,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon_jessebot.ico">
|
||||
<link rel="icon" type="image/x-icon" href="/images/{{favicon}}">
|
||||
|
||||
<title>JesseBot.com</title>
|
||||
<title>{{browser_tab_title}}</title>
|
||||
|
||||
<!-- Custom styles for this template -->
|
||||
<link href="css/starter-template.css" rel="stylesheet">
|
||||
|
@ -20,7 +20,5 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="starter-template">
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
<div class="panel-body">
|
||||
<div class="row featurette">
|
||||
<div class="col-md-5 tinyPad">
|
||||
<img class="featurette-image img-responsive img-circle" src="/images/defcon23.JPG">
|
||||
<img class="featurette-image img-responsive img-circle" src="/images/{{main_pic}}">
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<h2 class="featurette-heading"><br /><span class="text-muted">Hi, I'm</span> Jesse.</h2>
|
||||
<p class="lead">I'm a DevOps Engineer that loves Linux, the internet, and Python.</p>
|
||||
<h2 class="featurette-heading"><br /><span class="text-muted">Hi, I'm</span> {{name}}.</h2>
|
||||
<p class="lead">{{header_quotation}}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,38 +39,40 @@
|
|||
<div class="col-md-6 morePad">
|
||||
<img src="/images/docs.png">
|
||||
<div class="btn-group">
|
||||
<a href="https://docs.google.com/document/d/1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc/edit?pli=1" class="btn btn-primary btn-lg">Resume</a>
|
||||
<a href="{{gdoc_URL}}" class="btn btn-primary btn-lg">Resume</a>
|
||||
<button type="button" class="btn btn-primary btn-lg dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="https://docs.google.com/document/d/1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc/export?format=pdf&id=1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc">Download .PDF</a></li>
|
||||
<li><a href="{{resume_pdf_download_URL}}">Download .PDF</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="https://docs.google.com/document/d/1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc/export?format=docx&id=1t-xBYBxyUbDKUKQFIY1_r0GnjCMIUAyelfnyIhTK2Uc">Download .Docx</a></li>
|
||||
<li><a href="{{resume_docx_download_URL}}">Download .Docx</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p><img src="/images/githubcat.png"><a href="http://github.com/jessebot" class="btn btn-primary btn-lg" role="button">GitHub</a></p>
|
||||
<p><img src="/images/githubcat.png"><a href="{{GitHub_URL}}" class="btn btn-primary btn-lg" role="button">GitHub</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
|
||||
Linux Newbie Class
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseThree" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<h2><p><img src="/images/penguin_copy.png"> <a href="http://howtonix.info" class="btn btn-primary btn-lg" role="button">How To *n?x</a></p></h2>
|
||||
% if optional_panel:
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
|
||||
{{optional_panel_title}}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseThree" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<h2><p><img src="/images/{{optional_panel_pic}}"> <a href="{{optional_panel_button_URL}}" class="btn btn-primary btn-lg" role="button">{{optional_panel_button_text}}</a></p></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% end
|
||||
% include('footer.tpl')
|
||||
|
|
BIN
front_end/images/favicon_smile.gif
Normal file
BIN
front_end/images/favicon_smile.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 93 B |
BIN
front_end/images/my_picture.png
Normal file
BIN
front_end/images/my_picture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 MiB |
60
jessebot.py
60
jessebot.py
|
@ -1,60 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# production web routing bottle file
|
||||
|
||||
import bottle
|
||||
from bottle import redirect, request, response, route
|
||||
from bottle import run, static_file, template
|
||||
import logging
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
|
||||
def get_global_variable(global_variable):
|
||||
""" gets global variable given string variable name"""
|
||||
with open('./config/config.yaml', 'r') as f:
|
||||
doc = yaml.load(f)
|
||||
txt = doc["Globals"][global_variable]
|
||||
return txt
|
||||
|
||||
|
||||
# Grab site specific information
|
||||
WEB_ROOT = get_global_variable('web_root')
|
||||
TITLE = get_global_variable('web_title')
|
||||
|
||||
# set logging
|
||||
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
|
||||
logging.info("logging config loaded")
|
||||
# full path to HTML templates
|
||||
bottle.TEMPLATE_PATH.insert(0,
|
||||
'{0}/front_end/html_templates/'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/')
|
||||
def index():
|
||||
return template('index')
|
||||
|
||||
|
||||
@route('/hate')
|
||||
def hate():
|
||||
return template('hate')
|
||||
|
||||
|
||||
@route('/photo')
|
||||
@route('/photo/')
|
||||
def photo():
|
||||
redirect('http://photo.jessebot.com')
|
||||
|
||||
|
||||
@route('/images/<filename>')
|
||||
def images(filename):
|
||||
return static_file(filename, root='{0}/front_end/images'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/js/<filename>')
|
||||
def js(filename):
|
||||
return static_file(filename, root='{0}/front_end/js'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/css/<filename>')
|
||||
def css(filename):
|
||||
return static_file(filename, root='{0}/front_end/css'.format(WEB_ROOT))
|
77
web_routes.py
Executable file
77
web_routes.py
Executable file
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/python
|
||||
# production web routing bottle file
|
||||
|
||||
import bottle
|
||||
from bottle import redirect, request, response, route
|
||||
from bottle import run, static_file, template
|
||||
import logging
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
|
||||
def get_global_variable(global_variable):
|
||||
""" gets global variable given string variable name"""
|
||||
with open('./config/config.yaml', 'r') as f:
|
||||
doc = yaml.load(f)
|
||||
txt = doc["Globals"][global_variable]
|
||||
return txt
|
||||
|
||||
|
||||
# Grab site specific information
|
||||
WEB_ROOT = get_global_variable('web_root')
|
||||
# set logging
|
||||
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
|
||||
logging.info("logging config loaded")
|
||||
# full path to HTML templates
|
||||
bottle.TEMPLATE_PATH.insert(0,
|
||||
'{0}/front_end/html_templates/'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/')
|
||||
def index():
|
||||
favicon = get_global_variable('favicon')
|
||||
browser_tab_title = get_global_variable('website_title')
|
||||
main_pic = get_global_variable('profile_image')
|
||||
name = get_global_variable('profile_name')
|
||||
header_quotation = get_global_variable('profile_quote')
|
||||
GitHub_URL = get_global_variable('github_URL')
|
||||
gdoc_URL = get_global_variable('resume_google_doc')
|
||||
resume_pdf_download_URL = get_global_variable('resume_pdf_download')
|
||||
resume_docx_download_URL = get_global_variable('resume_docx_download')
|
||||
optional_panel = get_global_variable('optional_panel')
|
||||
optional_panel_title = get_global_variable('opt_panel_title')
|
||||
optional_panel_pic = get_global_variable('opt_panel_image')
|
||||
optional_panel_button_text = get_global_variable('opt_panel_button_text')
|
||||
optional_panel_button_URL = get_global_variable('opt_panel_URL')
|
||||
return template('index', favicon=favicon,
|
||||
browser_tab_title=browser_tab_title, main_pic=main_pic,
|
||||
name=name, header_quotation=header_quotation,
|
||||
GitHub_URL=GitHub_URL, gdoc_URL=gdoc_URL,
|
||||
resume_pdf_download_URL=resume_pdf_download_URL,
|
||||
resume_docx_download_URL=resume_docx_download_URL,
|
||||
optional_panel=optional_panel,
|
||||
optional_panel_title=optional_panel_title,
|
||||
optional_panel_pic=optional_panel_pic,
|
||||
optional_panel_button_text=optional_panel_button_text,
|
||||
optional_panel_button_URL=optional_panel_button_URL)
|
||||
|
||||
|
||||
@route('/images/<filename>')
|
||||
def images(filename):
|
||||
return static_file(filename, root='{0}/front_end/images'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/js/<filename>')
|
||||
def js(filename):
|
||||
return static_file(filename, root='{0}/front_end/js'.format(WEB_ROOT))
|
||||
|
||||
|
||||
@route('/css/<filename>')
|
||||
def css(filename):
|
||||
return static_file(filename, root='{0}/front_end/css'.format(WEB_ROOT))
|
||||
|
||||
|
||||
# example of how to create another route to something else
|
||||
@route('/hate')
|
||||
def hate():
|
||||
return template('hate')
|
Loading…
Add table
Add a link
Reference in a new issue