|
Dedicat a en Enric, al Febrer de 2017
|
Tot està per fer i tot és possible |
Aplicació "llista de la compra"
Inici
Vull fer una aplicació per mòbil que em serveixi com "llista de la compra".
És clar que jo llegiré la llista des el meu mòbil al super,
però pot ser que la Carme hi posi productes des el seu ordinador.
Així, el client ens convé que sigui un browser.
Això ens indica que el servidor tindrà un "node".
El servidor ha de tenir una base de dades per mantenir la llista entre re-inicis del servidor,
pero igual en tenim prou amb un fitxer de texte.
Això ens empeny cap un Linux i el Raspberry que tinc a casa sempre engegat.
Com que treballarem conjuntament amb en Enric, ens cal tenir el codi a github.
Detalls
Les operacion bàsiques que em calen son :
- mostrar quins productes s'han de comprar
- afegir un producte
- esborrar un producte
Passos inicials i organitzacio
- anem a
github i fem un
repositori nou per aquest projecte
- al servidor (linux en un Raspberry) fem un directori pel projecte i hi posem el README :
pi@odin:~/llisco $ echo "# llista_compra" >> README.md
- preparem el repositori :
pi@odin:~/llisco $ git init ; crea ".git"
Initialized empty Git repository in /home/pi/llisco/.git/
- posem un "gitignore" :
pi@odin:~/llisco $ cp ../semafor/.gitignore .
- posem el projecte inicial a github :
pi@odin:~/llisco $ git add README.md ; afegir al projecte
pi@odin:~/llisco $ git commit -m "first commit"
[master (root-commit) 7af67c6] first commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
pi@odin:~/llisco $ git remote add origin https://github.com/sebastianet/llista_compra.git
pi@odin:~/llisco $ git push -u origin master
Username for 'https://github.com': sebastianet
Password for 'https://sebastianet@github.com':
Counting objects: 3, done.
Writing objects: 100% (3/3), 221 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/sebastianet/llista_compra.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
- afegim en Enric com colaborador en aquest projecte :
- select
repository
- click "Settings" at right
- click "Collaborators" al top left
- enter collaborator name/nick : enricsarra
- ara en Enric s'ha de baixar el projecte inicial :
git clone https://github.com/sebastianet/llista_compra.git
- després de modificar un fitxer, README.md per exemple, ha de fer
git commit -am "he modificat README.md"
git push -u origin master
- els propers dies, s'ha de baixar el codi modificat, fer-hi quelcom i tornar-lo :
git pull origin master ; agafar el projecte
modificar quelcom
git commit -am "he modificat no-se-que" ; reflectir els canvis
git push -u origin master ; compartir-lo
Si no volem posar usr/pwd cada cop que fem "push", podem modificar "./.git/config" per contenir
[remote "origin"]
url = https://{myuser:mypwd@}github.com/sebastianet/llista_compra.git
- al codi de JS li calen moduls, que instalarem amb el npm - el configurem :
pi@odin:~/llisco $ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See 'npm help json' for definitive documentation on these fields and exactly what they do.
Use 'npm install <pkg> --save' afterwards to install a package and save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (llisco)
version: (1.0.0)
description:
entry point: (1_llisco.js)
test command:
git repository: (https://github.com/sebastianet/llista_compra.git)
keywords:
author:
license: (ISC)
About to write to /home/pi/llisco/package.json:
{
"name": "llisco",
"version": "1.0.0",
"description": "This project wants to implement a \"shoping list\" application.
The clients are computers or mobile phones using a browser.
The server is a NODE application, running on a Raspberry machine at home. Data is stored in a \"sqlite\" data base.
Project details are reflected in page http://usuaris.tinet.cat/sag/llisco.htm Sebastia, 20170225, 10:20",
"main": "1_llisco.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sebastianet/llista_compra.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/sebastianet/llista_compra/issues"
},
"homepage": "https://github.com/sebastianet/llista_compra#readme"
}
Is this ok? (yes)
Per veure quins moduls tenim fins ara, fem servir la comanda "npm list"
- com que el projecte fera servir express i altres packages, els instalem :
pi@odin:~/llisco $ npm install express --save
sudo npm install express-session --save
sudo npm install body-parser --save
sudo npm install morgan --save
Com que la instalació es local (no hem posat "-g"), el modul es posa al directori "node_modules", que ha de estar a ".gitignore" :
# Dependency directories
node_modules
Actualitzem software
Verifiquem moduls
pi@odin:~/llisco $ npm ls --depth=0 ; display local modules
llisco@1.0.0 /home/pi/llisco
âââ body-parser@1.16.1 extraneous ; sudo npm remove body-parser
âââ express@4.14.1
âââ express-session@1.15.1 extraneous ; means "not in package.json"
âââ morgan@1.8.1 extraneous
âââ sqlite3@3.1.8 extraneous
npm ERR! extraneous: body-parser@1.16.1 /home/pi/llisco/node_modules/body-parser
npm ERR! extraneous: express-session@1.15.1 /home/pi/llisco/node_modules/express-session
npm ERR! extraneous: morgan@1.8.1 /home/pi/llisco/node_modules/morgan
npm ERR! extraneous: sqlite3@3.1.8 /home/pi/llisco/node_modules/sqlite3
pi@odin:~/llisco $ npm ls -g --depth=0 ; display global modules, under /usr/lib/node_modules
/usr/lib
âââ node@0.0.0
âââ npm@4.3.0
BBDD : sqlite
sqlite commands
See
dot commands
- create table
# sqlite3 llista_de_la_compra.db
sqlite> create table tbl_llisco( numid integer, producte varchar(20) ) ;
sqlite> .quit
Or using
python :
pi@odin:~/llisco $ cat 8_sqlite_1_crear_taula.py
#!/usr/bin/env python
import sqlite3
# name of the sqlite database file
sqlite_file = '/home/pi/llisco/my_bbdd/llista_de_la_compra.db'
# name of the table to be created
table_name = 'tbl_llisco'
# Connecting to the database file
conn = sqlite3.connect(sqlite_file)
cur = conn.cursor()
# Create a new table with 2 columns
cur.execute('CREATE TABLE '+table_name+' (numid integer PRIMARY KEY, producte text NOT NULL)')
# Committing changes and closing the connection to the database file
conn.commit()
conn.close()
- delete table
pi@odin:~/llisco/my_bbdd $ sqlite3 llista_de_la_compra.db
SQLite version 3.8.7.1 2014-10-29 13:59:56
Enter ".help" for usage hints.
sqlite> .tables
t_llisco tbl_llisco
sqlite> drop table t_llisco ;
sqlite> .tables
tbl_llisco
sqlite>
- fill table
(url)
The code is :
pi@odin:~/llisco $ cat 8_sqlite_2_omplir_taula.sh
sqlite3 /home/pi/llisco/my_bbdd/llista_de_la_compra.db < /home/pi/llisco/my_bbdd/insert-data.sql
pi@odin:~/llisc
Result :
# sqlite3 llista_de_la_compra.db < insert-data.sql
# vi insert-data.sql
insert into tbl_llisco values(1,'2 Kg de mandarines');
insert into tbl_llisco values(2,'1 pot de guacamole');
- display
contents :
The code is :
#!/usr/bin/env python
import sqlite3
conn=sqlite3.connect( 'llista_de_la_compra.db' )
curs=conn.cursor()
print "\nEntire database contents:\n"
for row in curs.execute("SELECT * FROM tbl_llisco""):
print row
conn.close()
The result is an output like this :
pi@odin:~/llisco $ ./8_sqlite_3_mostrar_contingut.py
Entire database contents, table tbl_llisco:
(1, u'2 Kg de mandarines')
(2, u'1 pot de guacamole')
Accés a sqlite des nodejs
Instalem el package :
npm install sqlite3 --build-from-source --save ; skip searching for pre-compiled binaries, and force a build from source
Comprovem que funciona :
pi@odin:~/llisco $ cat 8_sqlite_4_prova_lectura_des_node.js
var sqlite3 = require('sqlite3').verbose();
var file = "/home/pi/llisco/my_bbdd/llista_de_la_compra.db";
var db = new sqlite3.Database(file);
db.all("SELECT numid,producte FROM tbl_llisco", function(err, rows) {
rows.forEach(function (row) {
console.log( row.numid, row.producte );
})
});
db.close();
El resultat és :
pi@odin:~/llisco $ node 8_sqlite_4_prova_lectura_des_node.js
1 '2 Kg de mandarines'
2 '1 pot de guacamole'
sqlite API
w3resource :
sqlite3.verbose()
Sets the execution mode to verbose to produce long stack traces.
There is no way to reset this.
Database#close([callback])
Closes the database.
If provided, the callback function will be called when the database was closed successfully or when an error occurred.
Disseny
How to store user data in client page
Les nostres dades son en una base de dades amb un index.
Si el client ha de poder esborrar un element de la llista des el seu browser "client",
és que li hem de passar el index junt amb el texte.
On guardar-lo ?
És millor usar atributs data-XXX en els tags html.
Per més informació, busca HTML5 custom data attributes
Closures
El scope és fonamental.
Les funcions en javascript que fan referencia a variables independents són closures.
Cada closure té un scope, on estan definides les variables que s'usen localment.
La execució de la funció es fa en el scope en que s'ha creat.
És a dir que aquestes funcions recorden l'entorn en que es van crear.
URL
selectors jQuery
Client / Server syntax
El $.ajax(get....) es una funcio jquery que acaba creant un http get
El client podria ser una invocacio de curl des de la command line
El app.get () es una ruta express que es cridada com a efecte de l'arribada d'un http get
La convenció {req,res,next} de la crida és parafernàlia express, o connect si vols ser més precís
req, res, next
Call next() to invoke the next middleware in the stack
The following
callback is executed for requests to /secret whether using GET, POST, PUT, DELETE, or any other HTTP request method:
app.all( '/secret', function ( req, res, next ) {
console.log( 'Accessing the secret section ...' )
next() // pass control to the next handler
});
Fitxers del projecte
0_engega_app_llista_compra.sh - shell per engegar el servidor i deixar-lo en background
1_llisco.js - codi de la aplicacio "llista de la compra"
8_sqlite_1_crear_taula.py - crear la taula (buida)
8_sqlite_2_omplir_taula.sh - omplir la taula
8_sqlite_3_mostrar_contingut.py - mostrar el contingut de la taula
8_sqlite_4_prova_lectura_des_node.js - llegir la taula des nodejs i posar les dades a un html
9_comandes_git.txt - resum de comandes per manegar el repositori compartit a github
.gitignore - fitxers que hi ha aqui que no es guarden al repositori
package.json - packages que li calen al projecte
README.ms - project description for the external world
La del Pere
Pere's
project - quina canya !
Instalació RSPI
pi@odin:~/pere/llista_compra $ sudo git clone https://github.com/palbcn/shoplist.git
Cloning into 'shoplist'...
remote: Counting objects: 49, done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 49 (delta 20), reused 45 (delta 16), pack-reused 0
Unpacking objects: 100% (49/49), done.
Checking connectivity... done.
pi@odin:~/pere/llista_compra $ cd shoplist/
pi@odin:~/pere/llista_compra/shoplist $ sudo npm install
pi@odin:~/pere/llista_compra/shoplist $ npm ls --depth=0
shoplist@1.0.0 /home/pi/pere/llista_compra/shoplist
âââ body-parser@1.16.1
âââ bower@1.8.0
âââ browser-sync@2.18.8
âââ cookie-parser@1.4.3
âââ express@4.14.1
âââ express-session@1.15.1
âââ morgan@1.8.1
âââ passport@0.3.2
âââ UNMET DEPENDENCY sqlite3@~3.1.8
npm ERR! missing: sqlite3@~3.1.8, required by shoplist@1.0.0
Instalació W500
Install
git for windows,
read a
book,
get a
tool
Get code :
C:\sebas\miscosas\node\pere> git clone https://github.com/palbcn/shoplist.git
Cloning into 'shoplist'...
remote: Counting objects: 49, done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 49 (delta 20), reused 45 (delta 16), pack-reused 0
Unpacking objects: 100% (49/49), done.
Install modules :
C:\sebas\miscosas\node\pere> npm install + nom update
npm install jquery
npm install -g bower // install global
npm install body-parser --save // update "package.json"
Run Pere's code :
C:\sebas\miscosas\node\pere\shoplist> node server
Shop List Server is now open for e-business
at localhost: 60784
My fixes :
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
Links of the project
- express
API
- command-line
shell for sqlite
- sqlite access from python
tutorial {Sebastian Raschka}
- FireFox add-on :
sqlite-manager : show "Menu Bar" and go under "Tools" !
- en Enric li agrada el
responsive web design.
Fer servir "responsive design mode" del inspector del Firefox o el "device toolbar" de les developer tools de Chrome
- jo soc mes de
single-page application
- similar JS project :
semafor
-
tools that help to detect errors and potential problems in your JavaScript code :
JS hint,
JS lint