Skip to content
Permalink
Browse files

Edit project structure (MLH#6)

* Update project structure

- Change `views` to `controllers`
- Change `guides` to `tutorial`
- Update documenation, fixing names and links

* Add folders for layouts and partials

* Fix modules name
  • Loading branch information...
nlaz committed Mar 1, 2019
1 parent 74a31e9 commit 0007be188cb69b4840122fc3352a796913e66ea2
@@ -2,5 +2,5 @@ include app/schema.sql
graft app/static
graft app/templates
graft app/models
graft app/views
graft app/controllers
global-exclude *.pyc
@@ -79,7 +79,6 @@ You will see the build errors and warnings in the console.
* [Flask](http://flask.pocoo.org/) - A microframework for Python web applications
* [Flask Blueprints](http://flask.pocoo.org/docs/1.0/blueprints/) - A Flask extension for making modular applications
* [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/2.3/) - A Flask extension that adds ORM support for your data models.
* [Flask-Misaka](https://flask-misaka.readthedocs.io) - A Flask extension that supports rendering markdown into HTML.
* [Werkzeug](http://werkzeug.pocoo.org/) - A Flask framework that implements WSGI for handling requests.
* [Bootstrap 4](https://getbootstrap.com/) - An open source design system for HTML, CSS, and JS.
* [Jinja2](http://jinja.pocoo.org/docs/2.10/) - A templating language for Python, used by Flask.
@@ -90,4 +89,4 @@ We enforce a Code of Conduct for all maintainers and contributors of this Guide.

# License

The Hackathon Starter Kit is open source software [licensed as MIT](https://github.com/MLH/github-hackathon-starter/blob/master/LICENSE.md).
The Hackathon Starter Kit is open source software [licensed as MIT](https://github.com/MLH/mlh-hackathon-flask-starter/blob/master/LICENSE.md).
@@ -1,7 +1,7 @@
import os

from flask import Flask, render_template
from . import settings, views, models
from . import settings, controllers, models
from .extensions import db

project_dir = os.path.dirname(os.path.abspath(__file__))
@@ -26,9 +26,9 @@ def register_extensions(app):

def register_blueprints(app):
"""Register Flask blueprints."""
app.register_blueprint(views.home.blueprint)
app.register_blueprint(views.auth.blueprint)
app.register_blueprint(views.guides.blueprint)
app.register_blueprint(controllers.home.blueprint)
app.register_blueprint(controllers.auth.blueprint)
app.register_blueprint(controllers.tutorial.blueprint)
return None

def register_errorhandlers(app):
@@ -0,0 +1,4 @@
"""Controllers package"""
from . import auth
from . import tutorial
from . import home
@@ -48,13 +48,3 @@ def get_current_user():
g.user = None
else:
g.user = User.query.filter_by(id=user_id).first()

def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth.login'))

return view(**kwargs)

return wrapped_view
File renamed without changes.
@@ -2,49 +2,28 @@
from flask import redirect, render_template, request
from flask import g, Blueprint, flash, url_for, session

from app.views.auth import login_required
from app.services.github import GitHub

blueprint = Blueprint('guides', __name__, url_prefix='/guides')
blueprint = Blueprint('tutorial', __name__, url_prefix='/tutorial')

@blueprint.route('/requesting')
def requesting():
search = request.args.get('query', '')
if not 'access_token' in session:
flash('This tutorial needs an authenticated user to make the request. Please sign in with your GitHub account.', 'danger')
return render_template('guides/requesting.html')
return render_template('tutorial/requesting.html')

github = GitHub(access_token=session['access_token'])
results1 = github.get('/user/starred')
results2 = github.get('/search/repositories', { 'q': search } )
results2 = results2.get('items', [])

return render_template('guides/requesting.html',
return render_template('tutorial/requesting.html',
tutorial1 = results1[:5],
tutorial2 = results2[:5],
query = search
)

@blueprint.route('/searching')
def searching():
return render_template('guides/searching.html')

@blueprint.route('/search')
def search():
search = request.args.get('query')

if search is None or search == '':
flash('Please include a valid search query.', 'danger')
return redirect(url_for('guides.requesting'))
if not 'access_token' in session:
flash('This example needs an authenticated user to make the request. Please sign in with your GitHub account.', 'danger')
return redirect(url_for('guides.requesting'))

github = GitHub(access_token=session['access_token'])
starred = github.get('/user/starred')

return render_template('guides/requesting.html', starred=repos['items'][:5], query=search)

@blueprint.route('/star', methods=['POST'])
def star():
repo = request.form['full_name']
@@ -56,4 +35,4 @@ def star():
github = GitHub(access_token=session['access_token'])
github.delete('/user/starred/' + repo)

return redirect(url_for('guides.fetching'))
return redirect(url_for('tutorial.fetching'))
@@ -1,4 +1,4 @@
"""Database module"""
"""Extensions module - Set up for additional libraries can go in here."""
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
@@ -1,7 +1,5 @@
import requests, json

from flask import flash

api_url = 'https://api.github.com'
authorize_url = 'https://github.com/login/oauth/authorize'
token_url = 'https://github.com/login/oauth/access_token'
@@ -1,4 +1,4 @@
"""Settings configuration."""
"""Settings configuration - Configuration for environment variables can go in here."""

import os
from dotenv import load_dotenv
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,9 +1,9 @@
{% extends 'layout.html' %}
{% extends "layouts/layout.html" %}

{% block content %}
<div class='container py-5 my-5 text-muted text-center'>
<h1 class='h5'>This isn't the page you are looking for.</h1>
<div class="container py-5 my-5 text-muted text-center">
<h1 class="h5">This isn't the page you are looking for.</h1>
<p>We couldn't find this page. Please check your URL or go back home.<p>
<a href='/' class='btn btn-primary'>Go back home</a>
<a href="/" class="btn btn-primary">Go back home</a>
</div>
{% endblock %}
@@ -1,9 +1,9 @@
{% extends 'layout.html' %}
{% extends "layouts/layout.html" %}

{% block content %}
<div class='container py-5 my-5 text-muted text-center'>
<h1 class='h5'>This isn't the page you are looking for.</h1>
<div class="container py-5 my-5 text-muted text-center">
<h1 class="h5">This isn't the page you are looking for.</h1>
<p>We couldn't find this page. Please check your URL or go back home.<p>
<a href='/' class='btn btn-primary'>Go back home</a>
<a href="/" class="btn btn-primary">Go back home</a>
</div>
{% endblock %}
@@ -1,9 +1,9 @@
{% extends 'layout.html' %}
{% extends "layouts/layout.html" %}

{% block content %}
<div class='container py-5 my-5 text-muted text-center'>
<h1 class='h5'>Oops, Something went wrong.</h1>
<div class="container py-5 my-5 text-muted text-center">
<h1 class="h5">Oops, Something went wrong.</h1>
<p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p>
<a href='/' class='btn btn-primary'>Go back home</a>
<a href="/" class="btn btn-primary">Go back home</a>
</div>
{% endblock %}
@@ -1,9 +1,9 @@
{% extends "layout.html" %}
{% extends "layouts/layout.html" %}

{% block header %}
<div class="bg-gray-light border-bottom border-gray-light">
<div class="container text-center py-5 mb-4">
<img src="{{ url_for('static', filename='logo.png') }}" class="w-100" style="max-width:120px;" />
<img src="{{ url_for('static', filename='img/logo.png') }}" class="w-100" style="max-width:120px;" />
<div class="mt-3 mb-4">
<h1 class="h1 mb-0">Hackathon Flask Starter</h1>
<h2 class="h4 text-gray font-weight-light">Build your hackathon project faster.</h2>
@@ -17,7 +17,7 @@ <h2 class="h4 text-gray font-weight-light">Build your hackathon project faster.<

{% block content %}
<div class="text-gray-light text-center py-5 my-5">
<p class="lead">Edit <code>views/</code> to update how to receive and reply to requests.</p>
<p class="lead">Edit <code>controllers/</code> to update how to receive and reply to requests.</p>
<p class="lead">Edit <code>templates/</code> to update the layout and styling.</p>
<p class="lead">Edit <code>models/</code> to update how the data is stored.</p>
</div>
@@ -1,26 +1,24 @@
<!DOCTYPE html>
<html lang='en'>
<html lang="en">
<head>
{% block head %}
<meta charset='utf-8'>
<meta charset="utf-8">
<title>My Hackathon Project</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" >
<link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}" >
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" >
<link rel="stylesheet" href="{{ url_for('static', filename='colors.css') }}" >
{% endblock %}
</head>
<body>
{% include 'nav.html' %}
{% include "partials/header.html" %}

{% include 'flash.html' %}
{% include "partials/flash.html" %}

{% block header %}{% endblock %}

{% block content %}{% endblock %}

{% block footer %}{% endblock %}
{% include "partials/footer.html" %}

<!-- Scripts for Bootstrap -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" ></script>
File renamed without changes.
@@ -0,0 +1,3 @@
{% block footer %}
{# Add a global footer here if you like #}
{% endblock %}
@@ -14,7 +14,7 @@
Tutorials
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ url_for('guides.requesting' )}}">Requesting Data</a>
<a class="dropdown-item" href="{{ url_for('tutorial.requesting' )}}">Requesting Data</a>
</div>
</li>
{% if g.user %}
@@ -1,9 +1,9 @@
{% extends "layout.html" %}
{% extends "layouts/layout.html" %}

{% block header %}
<div class="bg-dark text-light">
<div class="container text-center py-5 mb-4">
<img src="{{ url_for('static', filename='logo.png') }}" class="w-100" style="max-width:120px;" />
<img src="{{ url_for('static', filename='img/logo.png') }}" class="w-100" style="max-width:120px;" />
<div class="mt-3 mb-4">
<h1 class="h1 mb-0">{% block title %}{% endblock %}</h1>
<h2 class="h4 font-weight-light text-gray-light">{% block subtitle %}{% endblock %}</h2>
File renamed without changes.
@@ -1,5 +1,5 @@
{% extends "guides/base.html" %}
{% from "guides/repo.html" import render_repo with context %}
{% extends "tutorial/base.html" %}
{% from "tutorial/repo.html" import render_repo with context %}

{% block title %}Requesting Data{% endblock %}
{% block subtitle %}Learn how to retrieve data from GitHub.{% endblock %}
@@ -42,7 +42,7 @@ <h5 class="py-1 m-0">Searching GitHub</h5>
</code></pre>
<p class="mt-4">As a result, you should be able to search for GitHub projects below:</p>
<div class="text-center mx-auto mb-3">
<form action="{{ url_for('guides.requesting') }}" method="get" class="d-flex">
<form action="{{ url_for('tutorial.requesting') }}" method="get" class="d-flex">
<input name="query" class="form-control form-control-sm" value="{{ query }}" placeholder="Search for repos" />
<button type="submit" class="btn btn-primary btn-sm ml-1">Search</button>
</form>

This file was deleted.

@@ -92,7 +92,7 @@ mlh-hackathon-flask-starter/
├── build/
├── docs/
└── app/
├── views/
├── controllers/
│ ├── auth.py
│ ├── github.py
│ └── public.py
@@ -129,7 +129,7 @@ The tradeoff is that you have to go through the [GitHub OAuth flow](https://deve
4. Your app sends a request for the user access token.
5. Your app uses GitHub's API with the stored access token.

The code that handles this process is contained in `views/auth.py` and `services/github.py`.
The code that handles this process is contained in `controllers/auth.py` and `services/github.py`.
To use this authentication technique you need to create a new GitHub OAuth app. [Instructions listed below](#github-oauth).

## Fetching Data
@@ -144,7 +144,7 @@ $ python
... Prints out results from GitHub
```

These type of requests can be made inside of your views to fetch and store data for your application. For example, you might make a request to GitHub's API and display it [directly in HTML](/github). Depending on your needs, you can also store this data to your database to use later.
These type of requests can be made inside of your controllers to fetch and store data for your application. For example, you might make a request to GitHub's API and display it [directly in HTML](/github). Depending on your needs, you can also store this data to your database to use later.

To make things simple, we provide a service for GitHub-related requests, which will handle user authentication. Here is that [service in action](https://github.com/MLH/github-hackathon-starter/blob/master/app/views/github.py).

@@ -160,7 +160,7 @@ static/
└── style.css
```

The `style.css` file is a good place to add custom CSS. The `markdown.min.css` handles some default styling for the markdown guides for the project. Add any of your CSS or JavaScript in this folder.
The `style.css` file is a good place to add custom CSS. Add any of your CSS or JavaScript in this folder.

## Saving to a Database

0 comments on commit 0007be1

Please sign in to comment.
You can’t perform that action at this time.