<commit_before>#!/usr/bin/env python

"""
Imposter - Another weblog app
Copyright (c) 2010 by <NAME> <<EMAIL>>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

   1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials provided
   with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This is the admin application code for Imposter. It's used for editing
content, and every action requires a logged-in user.

"""

from __future__ import with_statement
from flask import Flask, request, session, abort, \
     redirect, url_for, render_template, flash
from functools import wraps
from database import DB
from models import User, Tag, Format, Status, Post
from datetime import datetime
from sqlalchemy.sql import and_
from helpers import encrypt, slugify

import re
import config as cfg

#---------------------------------------------------------------------------
# INITIALIZATION

db_session = DB(cfg.ADMIN_DATABASE).get_session()
app = Flask(__name__)
app.config.from_object(cfg)

#---------------------------------------------------------------------------
# SHORTCUT FUNCTIONS

def login_required(fun):
    """Decorator for functions which require an authorized user"""
    @wraps(fun)
    def decorated_function(*args, **kwargs):
        """Decorated function"""
        if not session.get('user_id'):
            return login()
        return fun(*args, **kwargs)

    return decorated_function

def get_tag(value):
    """Retrieve Tag object based on given String

    If no such Tag object exists, return a new Tag object.
    """
    tag = Tag.query.filter(Tag.value==value).first()
    if tag is None:
        return Tag(value)
    return tag

def get_format(value):
    """Retrieve Format object based on given String"""
    query = Format.query.filter(Format.value==value)
    return query.one()

def get_status(value):
    """Retrieve Status object based on given String"""
    query = Status.query.filter(Status.value==value)
    return query.one()

def get_post(post_id):
    """ Retrieve Post object based on given Post id"""
    post = Post.query.filter(and_(Post.user_id==session['user_id'],
                                  Post.id=='%d' % post_id)).first()
    if post is None:
        abort(404)

    return post

#---------------------------------------------------------------------------
# VIEWS

@app.route('/login/', methods=['POST'])
def login():
    """Check user credentials and initialize session"""
    error = None
    if request.method == 'POST':
        hashedpassword = encrypt(request.form['password'])
        userquery = User.query.filter(and_(
            User.username=='%s' % request.form['username'],
            User.password=='%s' % hashedpassword))

        if userquery.count() == 1:
            user = userquery.first()
            session['username'] = user.username
            session['user_id'] = user.id
            flash('You were logged in')
            return redirect(url_for('index'))

        error = 'Unknown user'
    return render_template(os.path.join('admin', 'login.html'), error=error)

@app.route('/logout/')
@login_required
def logout():
    """Clear the session"""
    session.clear()
    flash('You were logged out')
    return redirect(url_for('index'))

@app.route('/')
@login_required
def index():
    """The front page of this application"""
    posts = db_session.query(Post).filter(
        Post.user_id==session['user_id'])
    return render_template(os.path.join('admin', 'index.html'), posts=posts)

@app.route('/edit/')
@app.route('/edit/<int:post_id>/')
@login_required
def edit_post(post_id=None):
    """Render form to edit a Post"""
    formats = db_session.query(Format).all()
    statuses = db_session.query(Status).all()
    post = None

    if post_id:
        post = get_post(post_id)

    return render_template(os.path.join('admin', 'edit_post.html'),
                           post=post,
                           formats=formats,
                           statuses=statuses)

@app.route('/save/', methods=['POST'])
@app.route('/save/<int:post_id>/', methods=['POST'])
@login_required
def save_post(post_id=None):
    """Save changed Post content to database or save new Post"""
    message = 'Post updated'

    if post_id is None:
        post = Post(request.form['title'], request.form['text'])
        post.status_id = 1
        post.user_id = session['user_id']
        post.createdate = datetime.now()
    else:
        post = get_post(post_id)

    post.title = request.form['title']
    post.content = request.form['text']
    post.lastmoddate = datetime.now()
    post.format = get_format(request.form['format'])

    # update pubdate
    if request.form['status'] == 'public' and \
           unicode(post.status) != 'public':
        post.pubdate = datetime.now()

    post.status = get_status(request.form['status'])

    sep = re.compile('\s*,\s*')
    post.tags = [get_tag(tag) for tag \<commit_msg>. implement frontend-a-like get_route . add cfg to g. There must be a more elegant way to do this, but it works for now :)<commit_after>#!/usr/bin/env python

"""
Imposter - Another weblog app
Copyright (c) 2010 by <NAME> <<EMAIL>>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

   1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials provided
   with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This is the admin application code for Imposter. It's used for editing
content, and every action requires a logged-in user.

"""

from __future__ import with_statement
from flask import Flask, g, request, session, abort, redirect, url_for, \
     render_template, send_from_directory, flash
from functools import wraps
from database import DB
from models import User, Tag, Format, Status, Post
from datetime import datetime
from sqlalchemy.sql import and_
from helpers import encrypt, slugify

import os
import re
import config as cfg

#---------------------------------------------------------------------------
# INITIALIZATION

db_session = DB(cfg.ADMIN_DATABASE).get_session()
app = Flask(__name__, static_path=None)
app.config.from_object(cfg)

#---------------------------------------------------------------------------
# SHORTCUT FUNCTIONS

def login_required(fun):
    """Decorator for functions which require an authorized user"""
    @wraps(fun)
    def decorated_function(*args, **kwargs):
        """Decorated function"""
        if not session.get('user_id'):
            return login()
        return fun(*args, **kwargs)

    return decorated_function

def get_tag(value):
    """Retrieve Tag object based on given String

    If no such Tag object exists, return a new Tag object.
    """
    tag = Tag.query.filter(Tag.value==value).first()
    if tag is None:
        return Tag(value)
    return tag

def get_format(value):
    """Retrieve Format object based on given String"""
    query = Format.query.filter(Format.value==value)
    return query.one()

def get_status(value):
    """Retrieve Status object based on given String"""
    query = Status.query.filter(Status.value==value)
    return query.one()

def get_post(post_id):
    """ Retrieve Post object based on given Post id"""
    post = Post.query.filter(and_(Post.user_id==session['user_id'],
                                  Post.id=='%d' % post_id)).first()
    if post is None:
        abort(404)

    return post

def get_route(function):
    """Return complete route based on configuration and routes"""
    return '/%s%s' % (cfg.ADMIN_PREFIX, cfg.ADMIN_ROUTES[function])

#---------------------------------------------------------------------------
# VIEWS

@app.route(get_route('static_files'))
def static(filename):
    """Send static files such as style sheets, JavaScript, etc."""
    static_path = os.path.join(app.root_path, 'templates', 'admin', 'static')
    app.logger.debug(static_path)
    return send_from_directory(static_path, filename)

@app.route(get_route('login'), methods=['POST'])
def login():
    """Check user credentials and initialize session"""
    g.cfg = cfg
    error = None
    if request.method == 'POST':
        hashedpassword = encrypt(request.form['password'])
        userquery = User.query.filter(and_(
            User.username=='%s' % request.form['username'],
            User.password=='%s' % hashedpassword))

        if userquery.count() == 1:
            user = userquery.first()
            session['username'] = user.username
            session['user_id'] = user.id
            flash('You were logged in')
            return redirect(url_for('index'))

        error = 'Unknown user'
    return render_template(os.path.join('admin', 'login.html'), error=error)

@app.route(get_route('logout'))
@login_required
def logout():
    """Clear the session"""
    session.clear()
    flash('You were logged out')
    return redirect(url_for('index'))

@app.route(get_route('index'))
@login_required
def index():
    """The front page of this application"""
    g.cfg = cfg
    posts = db_session.query(Post).filter(
        Post.user_id==session['user_id'])
    return render_template(os.path.join('admin', 'index.html'), posts=posts)

@app.route(get_route('new_post'))
@app.route(get_route('edit_post'))
@login_required
def edit_post(post_id=None):
    """Render form to edit a Post"""
    g.cfg = cfg
    formats = db_session.query(Format).all()
    statuses = db_session.query(Status).all()
    post = None

    if post_id:
        post = get_post(post_id)

    return render_template(os.path.join('admin', 'edit_post.html'),
                           post=post,
                           formats=formats,
                           statuses=statuses)

@app.route(get_route('save_new_post'), methods=['POST'])
@app.route(get_route('save_post'), methods=['POST'])
@login_required
def save_post(post_id=None):
    """Save changed Post content to database or save new Post"""
    g.cfg = cfg
    message = 'Post updated'

    if post_id is None:
        post = Post(request.form['title'], request.form['text'])
        post.status_id = 1
        post.user_id = session['user_id']
        post.createdate = datetime.now()
    else:
        post = get_post(post_id)

    post.title = request.form['title']
    post.content = request.form['text']
    post.lastmoddate = datetime.now()
    post.format = get_format(request.form['format'])

    # update pubdate
    if request.form['status'] == 'public' and \
           unicode(post.status) != 'public':
        post.pubdate = datetime.now()

    post.status = get_status(request.form['status'])

    sep = re.compile('\s*,\s*')
    post.tags = [get_tag(tag) for tag \
{'fraction_non_alphanumeric': 0.1448395490026019, 'fraction_numerical': 0.0017346053772766695, 'mean_word_length': 2.9330232558139535, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2901256', 'n_tokens_mistral': 3621, 'n_tokens_neox': 3473, 'n_words': 1155}