Table des matières
Flask, Bootstrap, SolR, pròba de concèpte
Flask e Bootstrap e Solr
La tòca es d'integrar una requesta cap a SolR, dins un site Web enregat per Flask, un sitonel escrich en Python. Puèi lo vestit del site es adornat amb Bootstrap, la libraria javascript e las fuèlhas d'estíl polidas e estandard.
Las formas son geridas per la libraria WTForms, los comptes d'usagièrs son creats dins una basa de donadas SqlLite3. Es possible de se marcar mas i a pas de securitat contra los webots marrits e sannaires (pas encara de reCAPTCHA). Un administrator dins la reira botiga pòt eventualament enregistrar los mantenaires amb un accès dirèct a la basa.
La forma de cèrca
Es tras que simple, lo gabarit «templates/solr.html» es apelat amb una rota e un objècte solrForm li es passat. Aprèp lo gabarit foncciona amb lo formalisme de Flask ex:
{% %} per ecriure una estructura de blòc {{ variabla }} per invocar una variabla Python passada {% for result in form.search(): %} <li class="list-group-item">{{ result['title'] }}</li> {% endfor %}
App.py code Python
#!/usr/home/admin/envs/monflaskr/bin/python # -*- coding: utf-8 -*- """ Server ~~~~~~ """ import os import sys import pysolr from flask import Flask, render_template, request, redirect, url_for, session,g from flask_bootstrap import Bootstrap from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from flask_wtf import FlaskForm from wtforms import StringField, BooleanField, PasswordField from wtforms.validators import InputRequired, Email, Length, AnyOf from urlparse import urlparse, urljoin from werkzeug.security import generate_password_hash, check_password_hash ############################################################################### # C O N F I G # reload(sys) sys.setdefaultencoding('utf8') app = Flask(__name__) app.config['SECRET_KEY'] = 'Agadou dou dou PousselananaEtMoulKfé' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////usr/home/admin/flask/dca/login.db' app.config['SOLR_URI'] = 'http://vertigo.acc.fr:8983/solr/gettingstarted/' Bootstrap(app) ############################################################################### # instanciation & initialization # db = SQLAlchemy(app) login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login' ############################################################################### # O B J E C T S # class Solr: db = pysolr.Solr('http://vertigo.acc.fr:8983/solr/gettingstarted/', timeout=10) def search(self, textToSearch): return self.db.search(textToSearch) def getResults(self, text): results = self.solrSearch(text) return "{0}".format(len(results)) class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(15),unique = True) email = db.Column(db.String(15), unique= True) password = db.Column(db.String(80)) @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) ############################################################################### # F O R M S # # class LoginForm(FlaskForm): username = StringField('nom ou surnom', validators=[InputRequired(), Length(min=4, max=15)] ) password = PasswordField('mot de passe', validators=[InputRequired(), Length(min=4, max=80)] ) remember = BooleanField('se rappeler de moi') class RegisterForm(FlaskForm): email = StringField('email', validators=[InputRequired(), Email(message='adresse de courriel incorrecte'), Length(max=50)]) username = StringField('nom ou surnom', validators=[InputRequired(), Length(min=4, max=15)] ) password = PasswordField('mot de passe', validators=[InputRequired(), Length(min=8, max=80)] ) class SolrForm(FlaskForm): textToFind = StringField('mot ou phrase', validators=[InputRequired(), Length(min=4, max=512)] ) solr = Solr() def search(self): return self.solr.search(self.textToFind.data) ############################################################################### # R O U T E S # ####### # / # @app.route('/') def index(): return render_template('index.html') ####### # login # @app.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user: if check_password_hash(user.password,form.password.data): login_user(user, remember=form.remember.data) return redirect(url_for('dashboard')) return '<h1>Invalid user name or password</h1>' # return '<h1>' + form.username.data + ' ' + form.password.data + '</h1>' return render_template('login.html', form=form) ####### # signup # @app.route('/signup', methods=['GET','POST']) def signup(): form = RegisterForm() if form.validate_on_submit(): hashed_password = generate_password_hash(form.password.data, method='sha256') new_user = User(username=form.username.data, password=hashed_password, email=form.email.data) db.session.add(new_user) db.session.commit() return '<h1>Un nouvel utilisateur a été créé !</h1>' return render_template('signup.html', form=form) ####### # logout # @app.route('/logout') def logout(): logout_user() return redirect(url_for('index')) ####### # dashboard # @app.route('/dashboard') @login_required def dashboard(): return render_template('dashboard.html', name = current_user.username) ####### # solrrouted # @app.route('/solrrouted', methods=['GET', 'POST']) @login_required def solrrouted(): form = SolrForm() if form.validate_on_submit(): return render_template('solr.html',form=form) else: return render_template('solr.html',form=form) ############################################################################### # # R U N A P P L I C A T I O N # if __name__ == '__main__': app.run(host='0.0.0.0' ,debug=True)
solr.html
{% extends "bootstrap/base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %} SolR {% endblock %} {% block styles %} {{super()}} <link rel="stylesheet" href="{{url_for('.static', filename='solr.css')}}"> {% endblock %} {% block content %} <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Rajòl</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="/">Accueil</a></li> <li><a href="{{ url_for('dashboard') }}">Dashboard</a></li> <li><a href="{{ url_for('logout') }}">Se déconnecter</a></li> </ul> <!-- <form class="navbar-form navbar-right"> <input type="text" class="form-control" placeholder="Cercar ..."> </form> --> </div> </div> </nav> <div class="container-fluid"> <form class="form-signin solr_size", method="POST", action="/solrrouted"> <h2 class="form-signin-heading">Entrez un mot</h2> {{ form.hidden_tag() }} {{ wtf.form_field(form.textToFind) }} <button class="btn btn-lg btn-primary btn-block" type="submit">Soumettre</button> </form> <ul class="list-group solr_size"> {% for result in form.search(): %} <li class="list-group-item">{{ result['title'] }}</li> {% endfor %} </ul> </div> {% endblock %}
Execucion
Dintrar dins l'environament virtual python
[admin@vertigo] ~% source envs/monflaskr/bin/activate.csh
Enregar lo servidor
[monflaskr] [admin@vertigo] ~/flask/dca/start% python app.py .... 'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and ' * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) * Restarting with stat /usr/home/admin/envs/monflaskr/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py:839: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning. 'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and ' * Debugger is active! * Debugger pin code: 203-655-219
URL del site
Lo pòrt es 5000. Als administrators de se petaçar per fargar un environament de produccion.
http://monexemple.com:5000