LAMP-C++ avec Django et Mezzanine
Tous les fichiers disponibles dans le repo git -> lien
1) Réseau :
-
Si vous voulez voir votre service/site sur le sous-réseau domestique (192.168.xxx.xxx IP-s), vous devez vous assurer que les adresses IP sont stables. J'ai un routeur qui a un serveur DHCP intégré qui donne les IP-s du sous-réseau domestique aux appareils en fonction de ceux qui se sont connectés en premier. Il y a deux façons de gérer ce problème : vous pouvez configurer le périphérique pour qu'il ait une IP préférée dans le sous-réseau domestique ou vous pouvez configurer les exceptions DHCP sur votre routeur (par exemple, via l'interface Web, 192.168.1.1).
-
Après la configuration (ou au cas où vous n'en auriez pas besoin en fonction de vos préférences de routage), vous pouvez identifier l'adresse IP de votre ordinateur avec ifconfig
-
Mettez à jour /etc/hosts pour avoir une résolution DNS correcte sur votre machine de développement :
#loopback
127.0.0.1 localhost #default
127.0.1.1 MY_PC #if your PC has a name
#home subnet
#192.168.1.2 mysite.com #ethernet IP
192.168.1.10 mysite.com #wifi IP
2) Apache
-
Installez :
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install apache2
-
Remplir les configurations (Apache 2.4 a une configuration différente de, disons, Apache 2.2) :
cd /etc/apache2 && ll
-
apache2.conf, ajouter (wsgi sera nécessaire plus tard) :
# server name
ServerName mysite.com
-
ports.conf :
# sets Apache listen on port 80
Listen *:80
-
sites disponibles/000-default.conf
Je l'ai supprimé après l'avoir sauvegardé. Mon site est visible à la racine de l'url mysite.com/ sans lui.
-
sites-available/mysite.com.conf (exactement avec la partie ".com" !!!):
<VirtualHost 0.0.0.0:80>
# SERVER--------------------------------------
ServerName mysite.com
ServerAlias www.mysite.com
DocumentRoot /path/to/work/www/mysite/
# STATIC-------------------------------------
Alias /robots.txt /path/to/work/www/mysite/static/robots.txt
Alias /favicon.ico /path/to/work/www/mysite/static/favicon.ico
Alias /static/ /path/to/work/www/mysite/static/
# WSGI----------------------------------------
WSGIDaemonProcess mysite.com processes=2 threads=15 display-name=%{GROUP} python-path=/path/to/work/:/home/sdd/work/myproject/:/path/to/work/myproject/mysite/:/path/to/work/myproject/backend/:/path/to/work/www/:/path/to/work/www/mysite/
WSGIProcessGroup mysite.com
WSGIScriptAlias / /path/to/work/www/mysite/wsgi.py/
# DIRECTORIES---------------------------------
<Directory /path/to/work/www/mysite/static/>
Require all granted
Options Indexes FollowSymLinks
</Directory>
<Directory /path/to/work/>
Require all granted
Options Indexes FollowSymLinks
</Directory>
<Directory /path/to/work/www/mysite/>
<Files wsgi.py>
Require all granted
</Files>
Options Indexes FollowSymLinks
</Directory>
# MISC----------------------------------------
# add .py file type for mod_wsgi to start wsgi.py correctly
AddType text/html .py
</VirtualHost>
-
vérifier les droits pour le répertoire de votre site.
-
ajouter votre site :
sudo a2ensite mysite.com
-
redémarrer le service apache2 :
sudo service apache2 restart
-
Vérifiez que Apache2 fonctionne :
ps ax | grep apache2
-
vérifiez qu'apache écoute sur le port 80 sur les connexions de n'importe qui :
sudo netstat -anp | grep apache
Sortie comme :
tcp6 0 0 :::80 :::* LISTEN 1996/apache2
3) mod_wsgi
sudo apt-get install libapache2-mod-wsgi
Après cela, vous devriez avoir wsgi.conf et wsgi.load dans le répertoire /etc/apache2/mods-enabled.
4) Installer Python
sudo apt-get install python
sudo apt-get install python-pip
5) Installer django
sudo pip install Django
6) Installer boost (autoremove m'a aidé à résoudre le problème des paquets cassés, donc juste au cas où) :
sudo apt-get autoremove
sudo apt-get install libboost-all-dev
7) Installez mysql :
lien
Créez un test de base de données, une table hello avec INT id et VARCHAR(100) msg et insérez-y "Hello world ! Si vous êtes novice en matière de mysql, le lien ci-dessus contient des ressources sur la manière d'y parvenir.
À propos, Oracle a créé une interface graphique gratuite pour MySQL, appelée MySQL Workbench, aquí . Vous devez vous inscrire à Oracle (c'est gratuit) pour le télécharger.
Ensuite, il y a les pièces mysql pour Python :
sudo apt-get install libmysqlclient-dev
sudo pip install MySQL-python
Et si quelque chose ne va pas, suivez ceci -> lien
8) Installez Connector/C++ d'Oracle à partir de aquí Les instructions d'installation sont aquí . Ils n'ont pas de paquet .deb pour le moment, donc je l'ai construit à partir des sources, c'était juste 3 commandes Shell et pas de douleur. Vous aurez besoin de l'enregistrement Oracle (c'est gratuit) pour le télécharger.
9) Installer et configurer la Mezzanine
sudo pip install Mezzanine
cd work
mezzanine-project mysite
Le guide d'installation de la mezzanine que vous suggère d'utiliser createdb
y runserver
à partir du wrapper manage.py. Pour la base de données, j'ai utilisé une approche différente et pour le serveur - Apache et non le serveur de développement de Django.
Dans le répertoire mysite, créé par Mezzanine, dans local_config.py :
DATABASES = {
"default": {
# Add "postgresql_psycopg2", "mysql", "sqlite3" or "oracle".
"ENGINE": "django.db.backends.mysql",
# DB name or path to database file if using sqlite3.
"NAME": "your_db_name",
# Not used with sqlite3.
"USER": "your_user",
# Not used with sqlite3.
"PASSWORD": "your_mysql_password",
# Set to empty string for localhost. Not used with sqlite3.
"HOST": "localhost",
# Set to empty string for default. Not used with sqlite3.
"PORT": "3306",
}
}
que d'exécuter
python manage.py syncdb
qui va créer des tables django à côté de votre base de données, créée en (7)
changer ALLOWED_HOSTS dans settings.py dans le répertoire mysite créé par la mezzanine :
ALLOWED_HOSTS = [
'.mysite.com',
'.mysite.com/test'
]
ajoutez ce qui suit à urls.py :
url("^test/$", 'hello.test', name='test'),
directement après urlpatterns += patterns('',
Ceci est nécessaire pour avoir une sortie de service en texte brut sur l'url de mysite/test/ à côté de la page d'accueil de la mezzanine sur l'url de mysite.com.
10) rassembler les fichiers statiques
créez le sous-répertoire /static/ dans votre répertoire mysite s'il n'y en a pas.
il y a un chemins dans la configuration de settings.py (qui est la configuration de django avec quelques addons mezzanine), nous devons vérifier le paramètre STATIC_URL et ajouter le chemin vers les fichiers statiques de django-admin.
STATIC_URL = "/static/"
#additional static files' dirs
STATICFILES_DIRS = (
"/usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin",
)
nous pouvons maintenant rassembler les fichiers statiques en un seul endroit - c'est ce que proposent les auteurs de django pour stocker tout le contenu css, js, txt, etc.
python manage.py collectstatic
11) Maintenant, nous devons remplir le code Python et C++.
-
J'ai la structure de répertoire suivante dans ~/work
:
work
|
+-www
| |
| +-mysite@ [symlink to ../myproject/mysite dir, for apache and neatness]
|
+-mysite
| |
| +-deploy/ [mezzanine deploy stuff]
| +-static/ [static files we collected]
| +-fabfile.py [script that creates mezzanine-project]
| +-hello.py [script for testing service output]
| +-local_settings.py [mezzanine site-specific settings]
| +-settings.py [django settings with mezzanine addon]
| +-manage.py [management script wrapping calls to django admin functions]
| +-urls.py [url patterns]
| +-wsgi.py [wsgi entry point]
| +-gateway.py [in here I import wrapped C++]
| +-__init__.py [to treat dir as python module]
|
+-backend [c++ backend is in separate folder]
|
+-gateway.cpp [Boost.Python wrapping code]
+-hello_mysql.cpp [adapter to DB]
+-gateway_back.o [object file after compilation]
+-hello_mysql.o [object file after compilation]
+-gateway_back.so [this will be a module for python]
+-Makefile [cause Boost.Python works w/ python by an .so object]
+-__init__.py [to import backend into python app]
Ce sont tous les fichiers que vous devrez toucher, à l'exception des configurations d'apache2 en (2) et des configurations de ~/.bashrc & ~/.bash_aliases.
-
Mettez à jour vos variables d'environnement .bashrc PATH pour LD et Python :
# PATH env vars
export PATH=$PATH:/usr/lib/x86_64-linux-gnu
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/lib:/usr/local/lib
export PYTHONPATH = $PYTHONPATH:\
/path/to/work/:\
/path/to/work/myproject/:\
/path/to/work/myproject/mysite/:\
/path/to/work/myproject/backend/:\
/path/to/work/www:\
/path/to/work/www/mysite/
-
Créer un alias dans ~/.bash_aliases pour obtenir 'Hello World' de Shell [optionnel].
alias wget_oq='wget --timeout=3 -O - -q'
hello()
{
if [ "$1" == "get" ] ; then
wget_oq "$2" | cat
fi
}
Et n'oubliez pas de source ~/.bashrc ~/.bash_aliases
!
Après avoir copié-collé le code suivant, vous devriez être en mesure d'obtenir votre 'Hello World' stocké dans MySQL avec la commande hello get mysite.com
-
Écrire du code Python :
-
init .py : vide, placez toute initialisation du module ici si nécessaire
-
wsgi.py :
from __future__ import unicode_literals
import os
import sys
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
sys.path.append( '/path/to/work/myproject/mysite' )
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
-
hello.py : [indiquer ici le WSGIScriptAlias de la configuration apache2].
from django.http import HttpResponse
import gateway
def test(request):
text = str( gateway.Gate().hello() )
return HttpResponse( text, content_type="text/plain" )
def main():
g = gateway.Gate()
s = g.getDefaultQuote()
print s
if __name__ == '__main__':
main()
-
gateway.py :
import sys
import backend.gateway
class Gate(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Gate, cls).__new__(
cls, *args, **kwargs)
return cls._instance
def hello(self):
return backend.gateway.hello()
def main():
g = Gate()
s = g.hello()
print s
if __name__ == '__main__':
main()
-
Écrire du code C++ :
-
gateway_back.cpp :
#include <boost/python.hpp>
extern char const* hello();
BOOST_PYTHON_MODULE(gateway)
{
using namespace boost::python;
def("hello", hello);
}
-
hello_mysql.cpp :
Cette information est tirée de la documentation officielle d'Oracle sur Connector/C++, lien et modifié un peu.
#include <stdlib.h>
#include <iostream>
#include <string>
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
char const* hello()
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
// MySQL IP address and your username
con = driver->connect("tcp://127.0.0.1:3306", "username", "username");
/* Connect to the MySQL test database */
con->setSchema("test"); //your db name
stmt = con->createStatement();
res = stmt->executeQuery("SELECT * from hello;");
string result;
while (res->next()) {
/* Access column data by alias or column name */
result = res->getString("msg"); // field in db with actual 'Hello World'
return result.c_str();
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cerr << "# ERR: SQLException in " << __FILE__;
cerr << "(" << __FUNCTION__ << ") on line "
<< __LINE__ << endl;
cerr << "# ERR: " << e.what();
cerr << " (MySQL error code: " << e.getErrorCode();
cerr << ", SQLState: " << e.getSQLState() << " )" << endl;
}
-
Makefile :
# location of the Python header files
PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)
# location of the Boost Python include files and library
BOOST_INC = /usr/include
BOOST_LIB = /usr/lib/x86_64-linux-gnu
#compile mesh classes
TARGET = gateway
COTARGET = hello_mysql
.PHONY: all clean
all: $(TARGET).so
clean:
rm -rf *.o;
rm $(TARGET).so
# (!!!) broke the string for good formatting @ askubuntu
# important: linking against boost.python, python and connector/c++
# order might be crucial: had to place -lmysqlcppconn at the end
$(TARGET).so: $(TARGET).o $(COTARGET).o
g++ -shared -Wl,--export-dynamic $(TARGET).o $(COTARGET).o
-L$(BOOST_LIB) -lboost_python-py27
-L/usr/lib/python$(PYTHON_VERSION)/config
-lpython$(PYTHON_VERSION) -o $(TARGET).so -lmysqlcppconn
# (!!!) broke the string for good formatting @ askubuntu
# important: boost and python includes
$(TARGET).o: $(TARGET).cpp $(COTARGET).cpp
g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c
$(TARGET).cpp $(COTARGET).cpp
-
construire le code C++ dans gateway_back.so avec make
Shell.
-
dirigez votre navigateur vers l'url ou l'adresse IP que vous avez choisie aux étapes (1) et (2) ou tapez hello get <your url or IP Address>
de la console pour obtenir 'Hello'.
12) Résultat. Maintenant, si tout a été fait correctement et si je n'ai pas manqué quelque chose, vous devriez avoir ce qui suit :
- La page d'accueil par défaut de la mezzanine est très jolie sur www.mysite.com.
- du texte en clair 'hello world' à l'adresse www.mysite.com/test (cette partie est nécessaire si vous voulez créer un service web avec une API à côté du site)
P.S. : que faire ensuite ?
-
vous pouvez utiliser python manage.py collecttemplates
à partir du répertoire mysite pour commencer à travailler sur les modèles de mezzanine
-
vous pouvez vous connecter à votre interface d'administration (mysite/admin) avec votre login/mot de passe mysql.
si on utilisait la méthode par défaut - python manage.py createdb
Mais j'ai essayé de tout faire à ma façon pour que django se synchronise avec mon compte mysql existant et son login/pw. Ce sont les mêmes avec lesquels vous vous connectez au client mysql ou que vous utilisez dans mysql_hello.cpp.
vous pouvez changer le mot de passe de l'administrateur par l'intermédiaire de l'interface web mysite/admin ou par l'intermédiaire de l'interface de l'administrateur. manage.py changepassword your_user_name
commandement.
la gestion de django avec l'utilitaire django-admin et manage.py script est mieux décrite dans les docs officielles de django ->. lien .