Problem:
(postgres)-# create database "newdb" WITH ENCODING = 'UTF8' LC_CTYPE='en_US.utf8' LC_COLLATE='en_US.utf8' TEMPLATE template0;
createdb: database creation failed: ERROR: encoding UTF8 does not match locale en_US
DETAIL: The chosen LC_CTYPE setting requires encoding LATIN1.
1 2 3 |
(postgres)-# create database "newdb" WITH ENCODING = 'UTF8' LC_CTYPE='en_US.utf8' LC_COLLATE='en_US.utf8' TEMPLATE template0;
createdb: database creation failed: ERROR: encoding UTF8 does not match locale en_US
DETAIL: The chosen LC_CTYPE setting requires encoding LATIN1.
|
Check what locales you have
# locale -a
C
C.UTF-8
en_US
en_US.iso88591
POSIX
1 2 3 4 5 6 |
# locale -a
C
C.UTF-8
en_US
en_US.iso88591
POSIX
|
If locales are not installed:
# apt-get install debconf
1 |
# apt-get install debconf
|
To add en_US.UTF8, run:
# dpkg-reconfigure locales
1 |
# dpkg-reconfigure locales
|
And select the locales you want (en_US.UTF8)
Now:
# locale -a
C
C.UTF-8
en_US
en_US.iso88591
en_US.utf8
POSIX
1 2 3 4 5 6 7 |
# locale -a
C
C.UTF-8
en_US
en_US.iso88591
en_US.utf8
POSIX
|
You need to restart postgres:
# /usr/lib/postgresql/8.4/bin/pg_ctl restart -D /var/lib/postgresql/8.4/main
1 |
# /usr/lib/postgresql/8.4/bin/pg_ctl restart -D /var/lib/postgresql/8.4/main
|
Now rerun:
(postgres)-# create database "newdb" WITH ENCODING = 'UTF8' LC_CTYPE='en_US.utf8' LC_COLLATE='en_US.utf8' TEMPLATE template0;
1 |
(postgres)-# create database "newdb" WITH ENCODING = 'UTF8' LC_CTYPE='en_US.utf8' LC_COLLATE='en_US.utf8' TEMPLATE template0;
|
Spent a bit too long fixing a sudo problem right after an apt-get upgrade on a Debian machine.
The original problem:
# sudo ls
sudo: unable to initialize PAM: No such file or directory
1 2 |
# sudo ls
sudo: unable to initialize PAM: No such file or directory
|
Sudo errors are logged with syslog by default. Some message should be in one of the /var/log/xx.log files. If you don’t know which, run
# cd /var/log
# grep pam *.log
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_load_conf_file: unable to open /etc/pam.d/common-session-noninteractive
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_init_handlers: error reading /etc/pam.d/sudo
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_init_handlers: [Critical error - immediate abort]
auth.log:Nov 21 22:35:14 mach sudo: PAM pam_start: failed to initialize handlers
auth.log:Nov 21 22:35:14 mach sudo: PAM pam_end: NULL pam handle passed
1 2 3 4 5 6 7 |
# cd /var/log
# grep pam *.log
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_load_conf_file: unable to open /etc/pam.d/common-session-noninteractive
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_init_handlers: error reading /etc/pam.d/sudo
auth.log:Nov 21 22:35:14 mach sudo: PAM _pam_init_handlers: [Critical error - immediate abort]
auth.log:Nov 21 22:35:14 mach sudo: PAM pam_start: failed to initialize handlers
auth.log:Nov 21 22:35:14 mach sudo: PAM pam_end: NULL pam handle passed
|
One configuration file was missing. This PAM debian page told me what the file was supposed to contain. Somehow that file was not created in the upgrade.
# cat /etc/pam.d/common-session-noninteractive
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
1 2 3 4 5 |
# cat /etc/pam.d/common-session-noninteractive
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
|
Fixed.
Last Friday I came back from a 10 day road trip driving from San Francisco to Seattle, and coming back with the Amtrak Coast Starlight train – as I mentioned earlier.
I used Foursquare a bit more than usual (about 50 checkings over 10 days) and took a lot of pictures of rocks, landscapes, forests, the ocean, etc.
I started making a simple mashups to visualize the overall itinerary I ended up doing.
View full screen (Pink bubbles have photos. Blue bubbles are the checkins on the way to Seattle. Yellow bubbles are the checkins on the way back to San Francisco.)
I have photos on Flickr.
Some highlights:
- 1990 miles / 3200 km driven from SF to Seattle in 8 days.
- Very nice weather except the day I drived through Crater Lake, which I could not see at all because of the fog.
- Not many tourists or anyone on the roads end of October.
- I loved all the coastal areas, and especially the Olympic National Park.
- I ended up staying in campgrounds most of the nights, in the middle of a forest or close to the ocean, with barely anyone around. That was awesome.
- It’s not easy to find the cheap / non-RV campgrounds where you can put a tent or just sleep in the car.
- All the roads were surprisingly well maintained (I’m too used to the bad roads of south SF).
- I really liked the cities of Bend and Portland in Oregon. Seattle, WA… not as much but that was at the end of my trip. Redding, CA was weird.
- I think I expected a bit more from the train trip (23 hours from Seattle to San Francisco). That was really comfortable but as I was into a good book, and we were going through areas I had driven across, I did not pay much attention to the landscape.
I put the code for the mashup on github.
- Install the packages:
% pip install FormAlchemy fa.query GeoFormAlchemy
1 |
% pip install FormAlchemy fa.query GeoFormAlchemy
|
- You have now more templates available:
% paster create --list-templates
basic_package: A basic setuptools-enabled package
geo_fa: Pylons application template with GeoFormAlchemy support
mapfish: MapFish application template
mapfish_client: MapFish client plugin template
paste_deploy: A web application deployed through paste.deploy
pylons: Pylons application template
pylons_fa: Pylons application template with formalchemy support
pylons_minimal: Pylons minimal application template
1 2 3 4 5 6 7 8 9 |
% paster create --list-templates
basic_package: A basic setuptools-enabled package
geo_fa: Pylons application template with GeoFormAlchemy support
mapfish: MapFish application template
mapfish_client: MapFish client plugin template
paste_deploy: A web application deployed through paste.deploy
pylons: Pylons application template
pylons_fa: Pylons application template with formalchemy support
pylons_minimal: Pylons minimal application template
|
- You can run the command to add some of the GeoFormAlchemy or the formalchemy support to your project:
% paster create -t geo_fa
1 |
% paster create -t geo_fa
|
Keep the default values except for the first one
Enter admin_controller (Add formalchemy's admin controller) [False]: True
1 |
Enter admin_controller (Add formalchemy's admin controller) [False]: True
|
And answer no unless you want to overrite a file:
Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
1 2 |
Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
|
- If you do not run the paster create command, you’ll have to add those files directly:
- Add the file
myapp/controllers/admin.py
- Add the file
myapp/forms/__init__.py
- Add the template files in (on githhub-FormAlchemy and github-GeoFormAlchemy)
myapp/templates/forms/ fieldset.mako, fieldset_readonly.mako, grid.mako, grid_readonly.mako, map.mako, map_js.mako, restfieldset.mako
- Modify
myapp/config/routing.py
- Add the admin controller
myapp/controllers/admin.py
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta
log = logging.getLogger(__name__)
class AdminControllerBase(BaseController):
model = model # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
def Session(self): # Session factory
return meta.Session
## customize the query for a model listing
# def get_page(self):
# if self.model_name == 'Foo':
# return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
# return super(AdminControllerBase, self).get_page()
AdminController = ModelsController(AdminControllerBase,
prefix_name='admin',
member_name='model',
collection_name='models',
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta
log = logging.getLogger(__name__)
class AdminControllerBase(BaseController):
model = model # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
def Session(self): # Session factory
return meta.Session
## customize the query for a model listing
# def get_page(self):
# if self.model_name == 'Foo':
# return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
# return super(AdminControllerBase, self).get_page()
AdminController = ModelsController(AdminControllerBase,
prefix_name='admin',
member_name='model',
collection_name='models',
)
|
- Modify
myapp/config/routing.py
### In myapp/config/routing.py
# Map the /admin url to FA's AdminController
# Map static files
map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
# Index page
map.connect('admin', '/admin', controller='admin', action='models')
map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
# Models
map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
1 2 3 4 5 6 7 8 9 |
### In myapp/config/routing.py
# Map the /admin url to FA's AdminController
# Map static files
map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
# Index page
map.connect('admin', '/admin', controller='admin', action='models')
map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
# Models
map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
|
-
myapp/forms/__init__.py
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer
from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer
fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
def render(self, name, **kwargs):
return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
pass
class Grid(tables.Grid):
pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer
from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer
fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
def render(self, name, **kwargs):
return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
pass
class Grid(tables.Grid):
pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
|
- To test, restart you server, and open and refresh
/admin
. Unless you’ve added models in your
myapp/models/__init__.py
, you won’t see any link to the models.
Adding a model to the Admin view
myapp/model/my_app_points.py
was defined as such
###myapp/model/my_app_points.py
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base
class MyAppPoint(Base, GeometryTableMixIn):
autoload_with = Session.bind
__tablename__ = 'my_app_point'
__table_args__ = {
"autoload_with": Session.bind,
"autoload": True,
}
way = GeometryColumn(Point(srid=900913))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
###myapp/model/my_app_points.py
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base
class MyAppPoint(Base, GeometryTableMixIn):
autoload_with = Session.bind
__tablename__ = 'my_app_point'
__table_args__ = {
"autoload_with": Session.bind,
"autoload": True,
}
way = GeometryColumn(Point(srid=900913))
|
I’d get an error by importing that class in
myapp/model/__init__.py
from myapp.models.my_app_points import MyAppPoint
1 |
from myapp.models.my_app_points import MyAppPoint
|
would lead to that error:
sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>
1 2 3 |
sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>
|
Modifying myapp/model/__init__.py by adding Base.metadata.bind = engine at the end of init_model(engine) did not work.
The solution I found after checking the formalchemy code was to modify the myapp/controllers/admin.py and pass a list of the model classes to list in the web admin view.
###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint
list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
model = list_models # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
1 2 3 4 5 6 7 |
###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint
list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
model = list_models # where your SQLAlchemy mappers are
forms = forms # module containing FormAlchemy fieldsets definitions
|
And finally you can add something like that at the end of your
myapp/forms/__init__.py
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
('map_srid', 900913),
('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
('zoom', 14)
])
1 2 3 4 5 6 7 8 |
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
('map_srid', 900913),
('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
('zoom', 14)
])
|
Sources: mapfish-geoformalchemy,
