Rewrote app to use MySQL instead of sqlite; this will be beneficial for having multiple users and multiple parts of the site. Also redid the home page and added some more content to the bio and projects pages. The contact page also has some content of its own now.

This commit is contained in:
William Brawner 2016-03-06 18:31:27 -06:00
parent b4ecefe5c6
commit f06cabbcc2
15 changed files with 245 additions and 146 deletions

13
admin.py Normal file
View file

@ -0,0 +1,13 @@
from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash, Blueprint
from flask.ext.mysqldb import MySQL
admin = Blueprint('admin', __name__,
template_folder='templates')
@admin.route('/')
def home():
if not session.get('logged_in'):
return redirect(url_for('login'))
else:
return render_template('admin/home.html')

View file

@ -0,0 +1,6 @@
{% extends 'master.html' %}
{% block body %}
<h1 style="border-width: 0px; text-align: center; min-height: 120px; position: relative; overflow: hidden;">
<span id="changing-text">congrats, it worked</span>
</h1>
{% endblock %}

View file

@ -1,12 +1,17 @@
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, \ from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash abort, render_template, flash
from flask.ext.mysqldb import MySQL
from admin import admin
app = Flask(__name__) app = Flask(__name__)
app.config.from_pyfile('config.py') app.config.from_pyfile('config.py')
app.secret_key = app.config['SECRET_KEY']
mysql = MySQL(app)
app.register_blueprint(admin, url_prefix='/admin')
def connect_db(): def connect_db():
return sqlite3.connect(app.config['DATABASE']) return mysql.connection.cursor()
@app.before_request @app.before_request
def before_request(): def before_request():
@ -20,8 +25,8 @@ def teardown_request(exception):
@app.route('/') @app.route('/')
def home(): def home():
cur = g.db.execute('select title, text from entries order by id desc') g.db.execute('SELECT * FROM blog_posts ORDER BY updated_on DESC')
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()] entries = [dict(title=row[1], text=row[2], created=row[3].strftime("%B %d, %Y"), updated=row[4].strftime("%B %d, %Y")) for row in g.db.fetchall()]
return render_template('home.html', entries=entries) return render_template('home.html', entries=entries)
@app.route('/bio') @app.route('/bio')
@ -30,8 +35,8 @@ def bio():
@app.route('/blog') @app.route('/blog')
def blog(): def blog():
cur = g.db.execute('select title, text from entries order by id desc') g.db.execute('SELECT * FROM blog_posts ORDER BY id DESC')
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()] entries = [dict(title=row[1], text=row[2], created=row[3].strftime("%B %d, %Y"), updated=row[4].strftime("%B %d, %Y")) for row in g.db.fetchall()]
return render_template('blog.html', entries=entries) return render_template('blog.html', entries=entries)
@app.route('/projects') @app.route('/projects')
@ -46,11 +51,11 @@ def contact():
def add_entry(): def add_entry():
if not session.get('logged_in'): if not session.get('logged_in'):
abort(401) abort(401)
g.db.execute('insert into entries (title, text) values (?, ?)', g.db.execute('insert into blog_posts (title, text) values (?, ?)',
[request.form['title'], request.form['text']]) [request.form['title'], request.form['text']])
g.db.commit() g.db.commit()
flash('New entry was successfully posted') flash('New entry was successfully posted')
return redirect(url_for('show_entries')) return redirect(url_for('blog'))
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
def login(): def login():
@ -63,14 +68,14 @@ def login():
else: else:
session['logged_in'] = True session['logged_in'] = True
flash('You were logged in') flash('You were logged in')
return redirect(url_for('show_entries')) return redirect(url_for('admin.home'))
return render_template('login.html', error=error) return render_template('login.html', error=error)
@app.route('/logout') @app.route('/logout')
def logout(): def logout():
session.pop('logged_in', None) session.pop('logged_in', None)
flash('You were logged out') flash('You were logged out')
return redirect(url_for('show_entries')) return redirect(url_for('blog'))
if __name__ == '__main__': if __name__ == '__main__':
app.run() app.run()

View file

@ -1,11 +1,10 @@
from flask_site import * from flask_site import *
from contextlib import closing
def init_db(): def init_db():
with closing(connect_db()) as db: with app.app_context():
with app.open_resource('schema.sql', mode='r') as f: with open('/home/billy/flask-site/schema.sql', 'r') as f:
db.cursor().executescript(f.read()) g.db = connect_db()
db.commit() g.db.execute(f.read())
if __name__ == "__main__": if __name__ == "__main__":
init_db() init_db()

View file

@ -1,7 +1,7 @@
drop table if exists entries; CREATE TABLE blog_posts (
create table entries ( id INT( 6 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
id integer primary key autoincrement, title VARCHAR( 500 ) DEFAULT NULL ,
title text not null, text VARCHAR( 10000 ) DEFAULT NULL ,
text text not null created_on DATETIME NOT NULL ,
updated_on TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
); );

View file

@ -3,6 +3,7 @@ body {
margin:0; margin:0;
padding:0; padding:0;
background-color:#fff; background-color:#fff;
overflow-x: hidden;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -21,12 +22,34 @@ pre {
margin: auto; margin: auto;
} }
th {text-align: left;}
td { td {
padding: 5px 20px; padding: 5px 20px;
} }
td ul { td ul {
display: inline-block; display: inline-block;
margin: 5px;
}
input {
background-color: #FFF;
color: #002900;
border: 1px solid #002900;
border-radius: 15px;
padding: 5px;
display: block;
margin: 5px auto;
width: 95%;
max-width: 450px;
text-align: center;
}
input[type='submit'] {
color: #FFFFFF;
background-color: #002900;
max-width: 464px;
cursor: pointer;
} }
#nav { #nav {
@ -145,11 +168,43 @@ td ul {
border-bottom: 1px solid #002900; border-bottom: 1px solid #002900;
} }
#changing-text {
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
left: 0;
right: 0;
}
.section { .section {
border-radius: 40px; border-radius: 40px;
padding:1px 15px 15px 15px; padding:1px 15px 15px 15px;
} }
.blog-entry {
margin: 5px 20px 15px;
padding: 0 20px;
}
.blog-entry:last-of-type {
margin-bottom: 5px;
}
.blog-entry h3, .blog-entry h5, .blog-entry p {
margin: 5px 0;
}
.blog-entry h5 {
font-style: italic;
}
.one-half {
width: 45%;
margin: 0 2.5%;
float: left;
}
.one-third { .one-third {
width: 30%; width: 30%;
margin: 5px 1.5%; margin: 5px 1.5%;
@ -175,6 +230,13 @@ a.insta-link {
display: inline-block; display: inline-block;
float: left; float: left;
position: relative; position: relative;
padding: 10px;
width: 155px;
margin: auto;
}
a.insta-link img {
border-radius: 50%;
} }
a.insta-link span { a.insta-link span {
@ -218,9 +280,6 @@ span.insta-caption {
div#instafeed { div#instafeed {
overflow: hidden; overflow: hidden;
width: 95%;
max-width: 1100px;
margin: 60px auto;
} }
#home img { #home img {
@ -276,6 +335,10 @@ div#instafeed {
margin: 5px auto; margin: 5px auto;
} }
#projects a:hover {
color: #fff;
}
.project { .project {
width:75%%; width:75%%;
margin: 0 auto 10px; margin: 0 auto 10px;
@ -298,22 +361,47 @@ div#instafeed {
border: 1px solid white; border: 1px solid white;
} }
.project-description {
margin: 5px 5px 50px;
overflow: hidden;
float: left;
}
.project-description:last-of-type {
margin: 5px;
}
.project-description h3 {
margin-top: 0;
}
.project-description .project-logo {
border: 1px solid black;
}
.ff-store-link { .ff-store-link {
height: auto; height: auto;
width: 40%; width: 40%;
margin: auto; margin: auto;
max-width: 172px;
} }
.chrome-webstore-link { .chrome-webstore-link {
height: auto; height: auto;
width: 51%; width: 51%;
margin: auto; margin: auto;
max-width: 206px;
} }
.project h4 { .project h4 {
text-align:center; text-align:center;
} }
.logo-link {
float: left;
margin-right: 20px;
}
footer { footer {
display: block; display: block;
width: 100%; width: 100%;
@ -365,35 +453,31 @@ a.social-link:hover, a.social-link:active {
color: #fff; color: #fff;
} }
@media all and (max-width: 1192px) {
div#instafeed {
max-width: 510px;
}
}
@media screen and (max-width:1024px) { @media screen and (max-width:1024px) {
.main-nav, #nav { .main-nav, #nav {
position: absolute; position: absolute;
} }
#menu { #menu {
display:none; display:block;
width:100vw; width:100vw;
position: absolute; position: absolute;
top: 60px; top: 60px;
left: 0; left: 100%;
padding:0; padding:0;
background-color:#002900; background-color:#002900;
float:none; float:none;
-webkit-transition: left 0.5s ease;
transition: left 0.5s ease;
} }
#menu-icon { #menu-icon {
position:absolute; position:absolute;
right:30px; right:30px;
display:inline; display:inline;
height:20px;
width:auto; width:auto;
margin:10px; margin: 2px 10px;
font-size: 24px;
} }
.main-nav li { .main-nav li {
@ -435,9 +519,15 @@ a.social-link:hover, a.social-link:active {
} }
@media all and (max-width: 768px) { @media all and (max-width: 768px) {
div#instafeed { .one-half {
max-width: 340px; width: 95%;
} text-align: center;
}
th, td {
float: left;
clear: left;
margin-left: 20px;
}
} }
@media all and (max-width: 870px) { @media all and (max-width: 870px) {
@ -459,15 +549,3 @@ a.social-link:hover, a.social-link:active {
margin: 5px 5% 40px; margin: 5px 5% 40px;
} }
} }
@media all and (max-width: 596px) {
div#instafeed {
max-width: 340px;
}
}
@media all and (max-width: 414px) {
div#instafeed {
max-width: 170px;
}
}

BIN
static/img/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,6 @@
{% extends 'master.html' %}
{% block body %}
<h1 style="border-width: 0px; text-align: center; min-height: 120px; position: relative; overflow: hidden;">
<span>congrats, it worked</span>
</h1>
{% endblock %}

View file

@ -2,6 +2,7 @@
{% block body %} {% block body %}
<div class="section" id="bio"> <div class="section" id="bio">
<h2>about me</h2> <h2>about me</h2>
<p>extended bio coming soon...</p> <p>I have work experience using HTML, CSS, JavaScript, jQuery, AngularJS, NodeJS, PHP, Laravel, WordPress, Magento. Shopify, Ruby on Rails, Python, Linux, Ubuntu Server 14.04, and I have the Certified System Administrator certification from the Linux Foundation. As far as software goes, I'm proficient in git, GIMP, and vim. All of my learning so far has been from self-study, so I am very independent and self-motivated; little to no direction isnt a problem for me. Im also a very quick learner and Im detail-oriented. I tend to stay up late at night working and wake up early the next day to continue working when I have a big project. I love Open Source software, and I use Arch Linux as my primary operating system. I have made a few minor contributions to open source software, as seen on my GitHub profile. </p>
<p>When I was 16 years old I decided to go on a foreign exchange trip, and I wanted to go to Europe. I wasnt too particular about where exactly though and I ended up going to Finland. Finnish is a very difficult language to learn and the people there are more reserved than most Americans. Add to that mix a nearly 6 month winter with temperatures as low as -24 F (-31 C) and you can see how this was quite a life-changing experience. I left Finland fluent in Spanish and conversational in Finnish. The Finns were rather shy, at least with me, so I spent most of my time with Latin American exchange students and actually met my current fiancée there. When I returned to the US, I finished my last year of high school and then moved to Mexico, precisely for my fiancée, who was only my girlfriend at the time. When I got to Mexico, I had a couple thousand dollars saved up, I had no visas or permissions to work, but I at least spoke Spanish. Within 2 weeks of being there I was able to find work teaching English, and I later found a better teaching position and got my visa situation taken care of. Prior to teaching I had only gained experience in sales and retail, so teaching was a completely new experience for me. It wasnt my favorite thing to do, however, so I decided that I needed to get some more education in order to get into a field that I actually would enjoy. I began to teach myself HTML/CSS, JavaScript, and Python in my free time since Ive always been a tech junkie. At 20 years old, I began my first job in web development, only 4 months after I began studying programming. In the 6 months that I've been there, I've learned PHP, Laravel, WordPress, some Magento, some Ruby on Rails, and Shopify development. I am also conversational in German, since German is a pretty popular language around the tech world from what Ive seen. Im currently 21 years old, I speak English, Spanish, Finnish, and German, and can code in HTML, CSS, JavaScript, PHP, Ruby and Python, am a certified Linux System Administrator, and Id like to think that Ive overcome more difficulties and had more life experiences than most people twice my age have.</p>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -11,12 +11,16 @@
</dl> </dl>
</form> </form>
{% endif %} {% endif %}
<div class=entries> <div class="section">
<h2>blog</h2>
{% for entry in entries %} {% for entry in entries %}
<h2>{{ entry.title }}</h2> <div class="blog-entry">
{{ entry.text|safe }} <h3>{{ entry.title }}</h3>
<h5>{{ entry.updated }}</h5>
<p>{{ entry.text|safe }}</p>
</div>
{% else %} {% else %}
<em>Sorry, I still haven't gotten around to moving my blog posts over!</em> <em>Sorry, I still haven't gotten around to moving my blog posts over!</em>
{% endfor %} {% endfor %}
</div> </div>
{% endblock %} {% endblock %}

View file

@ -1,57 +1,27 @@
{% extends 'master.html' %} {% extends 'master.html' %}
{% block body %} {% block body %}
<h1 style="border-width: 0; text-align: center;"> <div class="section" id="contact">
<span id="changing-text">web developer.</span> <h2>contact</h2>
</h1> <div class="one-half">
<a class="twitter-timeline" href="https://twitter.com/BillyBrawner1" data-widget-id="706308392311136256">Tweets by @BillyBrawner1</a>
<div class="section" id="blog"> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
<h2>from my blog</h2>
</div>
<div class="section" id="projects">
<h2 style="color: #ffffff; border-bottom: 1px solid white;">projects</h2>
<div class="one-third">
<a href="http://wbrawner.com/interval-timer" target="_blank"><img class="project-logo" style="max-width: 102px; border-radius: 50%;" src="{{ url_for('static', filename='img/interval-timer.png') }}"></a>
<h3>interval timer app</h3>
<p>languages/technologies used:</p>
<ul class="project">
<li>English</li>
<li>HTML/CSS</li>
<li>JavaScript</li>
<li>AngularJS</li>
<li>GIMP</li>
</ul>
<a href="https://marketplace.firefox.com/app/interval-timer-1/" target="_blank"><img class="ff-store-link" src="{{ url_for('static', filename='img/ff-marketplace.png') }}"></a>
<a href="https://chrome.google.com/webstore/detail/interval-timer/glhbffeiigldedfpeiccmfdigplkeanm" target="_blank"><img class="chrome-webstore-link" src="{{ url_for('static', filename='img/chrome-webstore.png') }}"></a>
</div> </div>
<div class="one-third"> <div class="one-half">
<a href="http://workout-generator.wbrawner.com/" target="_blank"><img class="project-logo" src="{{ url_for('static', filename='img/workout-generator.png') }}"></a> <!-- Facebook Badge START --><a href="https://www.facebook.com/wpbrawner" title="Billy Brawner" style="font-family: &quot;lucida grande&quot;,tahoma,verdana,arial,sans-serif; font-size: 11px; font-variant: normal; font-style: normal; font-weight: normal; color: #3B5998; text-decoration: none;" target="_TOP">Billy Brawner</a><span style="font-family: &#039;lucida grande&#039;,tahoma,verdana,arial,sans-serif;font-size: 11px;line-height: 16px;font-variant: normal;font-style: normal;font-weight: normal;color: #555555;text-decoration: none;">&nbsp;|&nbsp;</span><a href="https://www.facebook.com/badges/" title="Make your own badge!" style="font-family: &quot;lucida grande&quot;,tahoma,verdana,arial,sans-serif; font-size: 11px; font-variant: normal; font-style: normal; font-weight: normal; color: #3B5998; text-decoration: none;" target="_TOP">Create Your Badge</a><br /><a href="https://www.facebook.com/wpbrawner" title="Billy Brawner" target="_TOP"><img class="img" src="https://badge.facebook.com/badge/1058965332.287.1992111354.png" style="border: 0px;" alt="" /></a><!-- Facebook Badge END -->
<h3>workout generator app</h3> <div id="instafeed">
<p>languages/technologies used:</p> <script type="text/javascript">
<ul class="project"> {% raw %}
<li>English</li> var feed = new Instafeed({
<li>HTML/CSS</li> get: 'user',
<li>JavaScript</li> userId: 2113424423,
<li>JQuery</li> limit: 6,
<li>PHP</li> accessToken: '2113424423.467ede5.2a622e2c959943169a932f91a1972302',
<li>Laravel</li> template: '<a class="insta-link" href="{{link}}" target="_blank"><span class="insta-caption-bg"></span><span class="insta-caption">{{caption}}</span><img class="insta-foto" src="{{image}}" /></a>'
<li>GIMP</li> });
<li>VIM</li> feed.run();
<li>MySQL</li> {% endraw %}
</ul> </script>
</div> </div>
<div class="one-third">
<a href="http://www.sinconsa.com/" target="_blank"><img class="project-logo" src="{{ url_for('static', filename='img/sinconsa.png') }}"></a>
<h3>sinconsa consultores</h3>
<p>languages/technologies used:</p>
<ul class="project">
<li>Spanish</li>
<li>HTML/CSS</li>
<li>JavaScript</li>
<li>JQuery</li>
<li>CPanel</li>
<li>GIMP</li>
<li>VIM</li>
</ul>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -1,14 +1,17 @@
{% extends 'master.html' %} {% extends 'master.html' %}
{% block body %} {% block body %}
<h1 style="border-width: 0; text-align: center;"> <h1 style="border-width: 0px; text-align: center; min-height: 120px; position: relative; overflow: hidden;">
<span id="changing-text">web developer.</span> <span id="changing-text">web developer.</span>
</h1> </h1>
<div class="section" id="blog"> <div class="section" id="blog">
<h2>from my blog</h2> <h2 style="margin-top: 0;">from my blog</h2>
{% for entry in entries %} {% for entry in entries %}
<h3>{{ entry.title }}</h3> <div class="blog-entry">
{{ entry.text|safe }} <h3>{{ entry.title }}</h3>
<h5>{{ entry.updated }}</h5>
<p>{{ entry.text|safe }}</p>
</div>
{% else %} {% else %}
<em>Sorry, I still haven't gotten around to moving my blog posts over!</em> <em>Sorry, I still haven't gotten around to moving my blog posts over!</em>
{% endfor %} {% endfor %}
@ -67,33 +70,33 @@
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td> <th>
current employer: current employer:
</td> </th>
<td> <td>
<a href="http://whiterabbit.is">White Rabbit</a> <a href="http://whiterabbit.is">White Rabbit</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <th>
current occupation: current occupation:
</td> </th>
<td> <td>
web developer web developer
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <th>
previous occupations: previous occupations:
</td> </th>
<td> <td>
cashier, front desk receptionist, gym membership salesman, personal trainer, efl teacher cashier, front desk receptionist, gym membership salesman, personal trainer, efl teacher
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <th>
background: background:
</td> </th>
<td> <td>
<ul> <ul>
<li>13 years old: first time out of the USA - trip to Japan</li> <li>13 years old: first time out of the USA - trip to Japan</li>
@ -103,9 +106,9 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <th>
languages: languages:
</td> </th>
<td> <td>
<ul> <ul>
<li>English</li> <li>English</li>

View file

@ -2,13 +2,9 @@
{% block body %} {% block body %}
<h2>Login</h2> <h2>Login</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %} {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post> <form action="{{ url_for('login') }}" method=post id="login-form">
<dl> <input type="text" name="username" placeholder="username">
<dt>Username: <input type="password" name="password" placeholder="password">
<dd><input type=text name=username> <input type="submit" value="login">
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value=Login>
</dl>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -27,23 +27,22 @@
<div id="nav"></div> <div id="nav"></div>
<nav class="main-nav"> <nav class="main-nav">
<h1><a href="/">william brawner</a></h1> <h1><a href="/">william brawner</a></h1>
<a href="javascript:void(0)" id="menu-icon">menu</a> <a href="javascript:void(0)" id="menu-icon"><i class="fa fa-bars "></i></a>
<ul id="menu"> <ul id="menu">
<li> <li>
<a href="{{ url_for('home') }}">home</a> <a href="{{ url_for('home') }}">home</a>
<div class="glow-border"></div>
</li> </li>
<li> <li>
<a href="{{ url_for('bio') }}">bio</a> <a href="{{ url_for('bio') }}">bio</a>
<div class="glow-border"></div>
</li> </li>
<li> <li>
<a href="{{ url_for('projects') }}">projects</a> <a href="{{ url_for('projects') }}">projects</a>
<div class="glow-border"></div>
</li> </li>
<li>
<a href="{{ url_for('blog') }}">blog</a>
</li>
<li> <li>
<a href="{{ url_for('contact') }}">contact</a> <a href="{{ url_for('contact') }}">contact</a>
<div class="glow-border"></div>
</li> </li>
<li> <li>
{% if not session.logged_in %} {% if not session.logged_in %}
@ -76,11 +75,6 @@
</footer> </footer>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#menu li').hover(function() {
$(this).children('.glow-border').css('opacity', 1)
}, function() {
$(this).children('.glow-border').css('opacity', 0)
})
changeText() changeText()
var minHeight = window.innerHeight - 60 - $('body > footer').height(); var minHeight = window.innerHeight - 60 - $('body > footer').height();
$('.container').css('min-height', minHeight); $('.container').css('min-height', minHeight);
@ -89,20 +83,24 @@
var menuVisible = false; var menuVisible = false;
$('#menu-icon').click(function() { $('#menu-icon').click(function() {
if (menuVisible) { if (menuVisible) {
$('#menu').css({'display':'none'}); $('#menu').css({'left':'100%'});
menuVisible = false; menuVisible = false;
return; return;
} }
$('#menu').css({'display':'block'}); $('#menu').css({'left':'0'});
menuVisible = true; menuVisible = true;
}); });
}); });
var titles = ["certified linux system administrator.","web developer.", "linguist.", "traveller."]; //array of titles to rotate var titles = ["certified linux system administrator.","web developer.", "linguist.", "traveller."];
function changeText() { function changeText() {
var current = $("#changing-text").data("title") || 0; var current = $("#changing-text").data("title") || 0;
$("#changing-text").data("title", current == titles.length -1 ? 0 : current + 1).text(titles[current]) $("#changing-text").data("title", current == titles.length -1 ? 0 : current + 1).text(titles[current])
.fadeIn().delay(2000).fadeOut(500, changeText); .fadeIn().delay(2000).fadeOut(500, changeText);
} }
$(window).resize(function() {
var minHeight = window.innerHeight - 60 - $('body > footer').height();
$('.container').css('min-height', minHeight);
})
</script> </script>
</body> </body>
</html> </html>

View file

@ -1,7 +1,27 @@
{% extends 'master.html' %} {% extends 'master.html' %}
{% block body %} {% block body %}
<div class="section" id="projects"> <div class="section">
<h2>projects</h2> <h2>projects</h2>
<p>extended projects info coming soon...</p> <div class="project-description">
<h3>interval timer app</h3>
<p><a href="http://wbrawner.com/interval-timer" target="_blank" class="logo-link"><img class="project-logo" style="max-width: 102px; border-radius: 50%;" src="{{ url_for('static', filename='img/interval-timer.png') }}"></a>The interval timer app was a little experiment of mine to learn AngularJS and try something new. When I wrote it, I was using FirefoxOS on my phone, and working out from my apartment. While there were apps that ran an interval timer, there was no app that allowed you to customize the intervals for the timer. All of them basically gave you the times and cycles, and you had to comply. I decided that that wasn't good enough for me, so I threw together this app and published it to the Firefox Marketplace. Later, once FirefoxOS was discontinued, I migrated back to Android, and published the app in the Google Chrome Webstore. </p>
<p>The interval timer app is completely open source, but as of this moment, I'm the only contributor. If you're interested, you can find the code on <a href="https://github.com/wbrawner/interval-timer">GitHub</a></p>
<a href="https://marketplace.firefox.com/app/interval-timer-1/" target="_blank"><img class="ff-store-link" src="{{ url_for('static', filename='img/ff-marketplace.png') }}"></a>
<a href="https://chrome.google.com/webstore/detail/interval-timer/glhbffeiigldedfpeiccmfdigplkeanm" target="_blank"><img class="chrome-webstore-link" src="{{ url_for('static', filename='img/chrome-webstore.png') }}"></a>
</div>
<div class="project-description">
<h3>workout generator app</h3>
<p><a href="http://wbrawner.com/workout-generator" target="_blank" class="logo-link"><img class="project-logo" src="{{ url_for('static', filename='img/workout-generator.png') }}"></a>Back when I was first learning Python, I wanted to put my skills to the test, so I did various programming challenges in order to learn new things and practice what I already knew. They were fun, but I wanted to try something that was a little more along the lines of my personal interests. Having grown up in a gym, I figured it would be cool to write up a workout generator. Sure enough, I ended up doing it and got it to be fully functional, on the command line. Most people, however, don't tend to use a command line so it probably would have never gone anywhere. Since my work at the time required I write code in PHP, and sometimes use the Laravel framework, I decided to translate the app and rebuild it as a web app instead of a command line program. All worked well, and I had a running demo of it live on my personal site for some time, but I decided to take it down in favor of moving it back to Python. I personally have a preference for Python, due to it being the first programming language I truly learned, and it's extensive use within Linux.</p>
<p>The workout generator app is also completely open source. Likewise, I'm the only contributor, but I hope to see that change in the future. If you're interested, you can find the code on <a href="https://github.com/wbrawner/workout-generator">GitHub</a>. The old, PHP version written with Laravel is also available on <a href="https://github.com/wbrawner/workoutgenerator-legacy">GitHub</a>.</p>
</div>
<div class="project-description">
<h3>sinconsa consultores</h3>
<p><a href="http://sinconsa.com" target="_blank" class="logo-link"><img class="project-logo" src="{{ url_for('static', filename='img/sinconsa.png') }}"></a>Sinconsa Consultores is a business operated by a friend a former co-worker of mine. This was my very first professional web development project. When I first wrote it, I had a very limited knowledge of web development, and wrote out all 15 or so pages using only HTML, CSS, and a little bit of JavaScript. This was obviously ridiculous, and incredibly inefficient to make updates. With these factors in mind, it made sense to power the website with WordPress, so I was given the opportunity to make the migration.</p>
</div>
<div class="project-description">
<h3>wbrawner</h3>
<p><a href="http://wbrawner.com/" target="_blank" class="logo-link"><img class="project-logo" style="max-width: 102px; border: 0;" src="{{ url_for('static', filename='img/favicon.png') }}"></a>This site that you're looking at right now was also built by yours truly. It began as a basic HTML/CSS single-page website, then I decided to charge it up with WordPress and move a few things to their own pages. The motivation behind this move was that I had been using WordPress quite a bit in my work at the time, so I wanted to learn the ins and outs in order to do my job better. Some time later, I stopped getting so many WordPress tasks and so my desire to learn it faded a bit. I have nothing against WordPress, but I wanted to get back to my Python roots, and have a bit more control over everything running. Thus, I rewrote my website in Python using Flask, not for work or any other professional necessity, but simply for the joy of writing code in a language I'm more familiar with.</p>
<p>I decided to make my personal website open source as well. If you're interested, you can find the code on <a href="https://github.com/wbrawner/flask-site">GitHub</a></p>
</div>
</div> </div>
{% endblock %} {% endblock %}