From 95b3ca839a9400a70d030035901b7320ff69a6ef Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 20 Dec 2012 09:22:24 -0600 Subject: [PATCH] added improved scripts/setup-web2py-nginx-uwsgi-ubuntu.sh, thanks Niphlod --- VERSION | 2 +- gluon/contrib/__init__.py | 1 + gluon/contrib/feedparser.py | 4 +- gluon/contrib/heroku.py | 2 +- gluon/contrib/paymentech.py | 12 +++-- gluon/dal.py | 8 ++-- gluon/html.py | 4 +- gluon/http.py | 1 - gluon/sqlhtml.py | 6 +-- gluon/tools.py | 12 ++--- gluon/winservice.py | 2 +- scripts/cpdb.py | 1 - scripts/setup-web2py-nginx-uwsgi-ubuntu.sh | 51 +++++++++++++--------- scripts/sync_languages.py | 7 ++- 14 files changed, 60 insertions(+), 53 deletions(-) diff --git a/VERSION b/VERSION index 0ab6d8c8..22b2146f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.3.2 (2012-12-20 09:02:23) dev +Version 2.3.2 (2012-12-20 09:21:27) dev diff --git a/gluon/contrib/__init__.py b/gluon/contrib/__init__.py index e69de29b..8b137891 100644 --- a/gluon/contrib/__init__.py +++ b/gluon/contrib/__init__.py @@ -0,0 +1 @@ + diff --git a/gluon/contrib/feedparser.py b/gluon/contrib/feedparser.py index f8075c90..2ef24a9d 100755 --- a/gluon/contrib/feedparser.py +++ b/gluon/contrib/feedparser.py @@ -3487,7 +3487,7 @@ def _parse_date_rfc822(dt): # If the year is 2 digits, assume everything in the 90's is the 1990's if m['year'] < 100: m['year'] += (1900, 2000)[m['year'] < 90] - stamp = datetime.datetime(*[m[i] for i in + stamp = datetime.datetime(*[m[i] for i in ('year', 'month', 'day', 'hour', 'minute', 'second')]) # Use the timezone information to calculate the difference between @@ -3699,7 +3699,7 @@ def convert_to_utf8(http_headers, data): u'application/xml-external-parsed-entity') text_content_types = (u'text/xml', u'text/xml-external-parsed-entity') if (http_content_type in application_content_types) or \ - (http_content_type.startswith(u'application/') and + (http_content_type.startswith(u'application/') and http_content_type.endswith(u'+xml')): acceptable_content_type = 1 rfc3023_encoding = http_encoding or xml_encoding or u'utf-8' diff --git a/gluon/contrib/heroku.py b/gluon/contrib/heroku.py index 704b6c45..d641eba9 100644 --- a/gluon/contrib/heroku.py +++ b/gluon/contrib/heroku.py @@ -17,7 +17,7 @@ ADAPTERS['postgres'] = HerokuPostgresAdapter def get_db(name = None, pool_size=10): if not name: - names = [n for n in os.environ.keys() + names = [n for n in os.environ.keys() if n[:18]+n[-4:]=='HEROKU_POSTGRESQL__URL'] if names: name = names[0] diff --git a/gluon/contrib/paymentech.py b/gluon/contrib/paymentech.py index b2a79b9d..a0323d75 100644 --- a/gluon/contrib/paymentech.py +++ b/gluon/contrib/paymentech.py @@ -70,7 +70,7 @@ class PaymenTech(object): ################################################################# # Notes for web2py implementations # - ################################################################# + ################################################################# # A recommended model for handling payments @@ -87,7 +87,7 @@ class PaymenTech(object): PAYMENTECH_TARGET = PAYMENTECH_HOST = PAYMENTECH_API_URL = - + # The following table would allow passing data with web2py and to # update records with the webservice authorization output by using # the DAL @@ -102,10 +102,10 @@ class PaymenTech(object): # # # Send the authorization request to the webservice # result = mypaymentech.charge(myrow.as_dict()) - # + # # # Update the db record with the webservice response # myrow.update_record(**result) - + db.define_table("paymentech", Field("account"), Field("exp", comment="Must be of the mmyyyy form"), @@ -302,7 +302,7 @@ class PaymenTech(object): tx_ref_num = order_id = None conn = httplib.HTTPS(self.host) conn.putrequest('POST', self.api_url) - + if self.development: content_type = "PTI56" else: @@ -340,5 +340,3 @@ class PaymenTech(object): dom.getElementsByTagName('CustomerRefNum')[0].firstChild.data return result - - diff --git a/gluon/dal.py b/gluon/dal.py index 08e41303..79b78e53 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -6853,7 +6853,7 @@ class DAL(object): self._adapter = ADAPTERS[self._dbname](**kwargs) types = ADAPTERS[self._dbname].types # copy so multiple DAL() possible - self._adapter.types = copy.copy(types) + self._adapter.types = copy.copy(types) if bigint_id: if 'big-id' in types and 'reference' in types: self._adapter.types['id'] = types['big-id'] @@ -7200,7 +7200,7 @@ def index(): fields = list(fields) + list(common_fields) table_class = args_get('table_class',Table) - table = table_class(self, tablename, *fields, **args) + table = table_class(self, tablename, *fields, **args) table._actual = True self[tablename] = table # must follow above line to handle self references @@ -7747,10 +7747,10 @@ class Table(object): def __call__(self, key=DEFAULT, **kwargs): for_update = kwargs.get('_for_update',False) if '_for_update' in kwargs: del kwargs['_for_update'] - + orderby = kwargs.get('_orderby',None) if '_orderby' in kwargs: del kwargs['_orderby'] - + if not key is DEFAULT: if isinstance(key, Query): record = self._db(key).select( diff --git a/gluon/html.py b/gluon/html.py index 7c88d435..78946060 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -520,7 +520,7 @@ class XmlComponent(object): c = self['_class'] classes = (set(c.split()) if c else set()) - set(name.split()) self['_class'] = ' '.join(classes) if classes else None - return self + return self class XML(XmlComponent): """ @@ -1487,7 +1487,7 @@ class A(DIV): (self['callback'], self['target'] or '', d) self['_href'] = self['_href'] or '#null' elif self['cid']: - pre = self['pre_call'] + ';' if self['pre_call'] else '' + pre = self['pre_call'] + ';' if self['pre_call'] else '' self['_onclick'] = '%sweb2py_component("%s","%s");%sreturn false;' % \ (pre,self['_href'], self['cid'], d) return DIV.xml(self) diff --git a/gluon/http.py b/gluon/http.py index c0dc1f9e..62ef7227 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -154,4 +154,3 @@ def redirect(location='', how=303, client_side=False): from gluon import current if client_side and current.request.ajax: raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'}) - diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index a808276f..dad281e4 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -269,7 +269,7 @@ jQuery.fn.grow_input = function() { function pe(ul, e) { var new_line = ml(ul); rel(ul); - new_line.appendTo(ul); + new_line.appendTo(ul); new_line.find(":text").focus(); return false; } @@ -761,7 +761,7 @@ def formstyle_bootstrap(form, fields): # For password fields, which are wrapped in a CAT object. if isinstance(controls, CAT) and isinstance(controls[0], INPUT): controls[0].add_class('input-xlarge') - + if isinstance(controls, SELECT): controls.add_class('input-xlarge') @@ -1789,7 +1789,7 @@ class SQLFORM(FORM): if not ( '/'.join(str(a) for a in args) == '/'.join(request.args) or URL.verify(request,user_signature=user_signature, - hash_vars=False) or + hash_vars=False) or (request.args(len(args))=='view' and not logged)): session.flash = T('not authorized') redirect(referrer) diff --git a/gluon/tools.py b/gluon/tools.py index 4da8e42c..929f39f3 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1959,9 +1959,9 @@ class Auth(object): onaccept = self.settings.login_onaccept if log is DEFAULT: log = self.messages.login_log - + onfail = self.settings.login_onfail - + user = None # default # do we use our own login form, or from a central source? @@ -2117,7 +2117,7 @@ class Auth(object): session._auth_next = None next = replace_id(next, form) redirect(next, client_side=True) - + table_user[username].requires = old_requires return form elif user: @@ -3016,7 +3016,7 @@ class Auth(object): if user_id: user = self.table_user()[user_id] else: - user = self.user + user = self.user return self.settings.create_user_groups % user def has_membership(self, group_id=None, user_id=None, role=None): @@ -4690,7 +4690,7 @@ class Wiki(object): rows_page = 25 def markmin_render(self, page): - html = MARKMIN(page.body, extra=self.extra, + html = MARKMIN(page.body, extra=self.extra, url=True, environment=self.env, autolinks=lambda link: expand_one(link, {})).xml() html += DIV(_class='w2p_wiki_tags', @@ -5053,7 +5053,7 @@ class Wiki(object): return self.not_authorized() db = self.auth.db slugs=db(db.wiki_page.id>0).select(db.wiki_page.id,db.wiki_page.slug) - options=[OPTION(row.slug,_value=row.id) for row in slugs] + options=[OPTION(row.slug,_value=row.id) for row in slugs] options.insert(0, OPTION('',_value='')) form = SQLFORM.factory(Field("slug", default=current.request.args(1), requires=(IS_SLUG(), diff --git a/gluon/winservice.py b/gluon/winservice.py index 9f35c877..c5ee76b2 100644 --- a/gluon/winservice.py +++ b/gluon/winservice.py @@ -171,7 +171,7 @@ class Web2pyCronService(Web2pyService): opt_mod = self._exe_args_ options = __import__(opt_mod, [], [], '') global_settings.global_settings.web2py_crontype = 'external' - if options.scheduler: # -K + if options.scheduler: # -K apps = [app.strip() for app in options.scheduler.split( ',') if check_existent_app(options, app.strip())] else: diff --git a/scripts/cpdb.py b/scripts/cpdb.py index 0a2bb7f8..c5d00fbf 100644 --- a/scripts/cpdb.py +++ b/scripts/cpdb.py @@ -1,4 +1,3 @@ - import os import sys from collections import deque diff --git a/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh b/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh index 88e5c602..e70b6605 100644 --- a/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh +++ b/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh @@ -1,19 +1,24 @@ +#!/bin/bash echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh' -echo 'Requires Ubuntu 12.04 and installs Nginx + uWSGI + Web2py' - +echo 'Requires Ubuntu > 12.04 and installs Nginx + uWSGI + Web2py' +# Check if user has root privileges +if [[ $EUID -ne 0 ]]; then + echo "You must run the script as root or using sudo" + exit 1 +fi # Get Web2py Admin Password echo -e "Web2py Admin Password: \c " read PW # Upgrade and install needed software apt-get update apt-get -y upgrade -apt-get -y dist-upgrade apt-get autoremove apt-get autoclean apt-get -y install nginx-full -apt-get -y install build-essential python-dev libxml2-dev python-pip +apt-get -y install build-essential python-dev libxml2-dev python-pip unzip pip install --upgrade pip -pip install --upgrade uwsgi +PIPPATH=`which pip` +$PIPPATH install --upgrade uwsgi # Create configuration file /etc/nginx/sites-available/web2py echo 'server { listen 80; @@ -37,11 +42,16 @@ echo 'server { } } server { - listen 443; + listen 443 default_server ssl; server_name $hostname; - ssl on; ssl_certificate /etc/nginx/ssl/web2py.crt; ssl_certificate_key /etc/nginx/ssl/web2py.key; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA; + ssl_protocols SSLv3 TLSv1; + keepalive_timeout 70; location / { #uwsgi_pass 127.0.0.1:9001; uwsgi_pass unix:///tmp/web2py.socket; @@ -49,21 +59,24 @@ server { uwsgi_param UWSGI_SCHEME $scheme; uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; } - + }' >/etc/nginx/sites-available/web2py - + ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py rm /etc/nginx/sites-enabled/default mkdir /etc/nginx/ssl cd /etc/nginx/ssl -openssl genrsa -out web2py.key 1024 -openssl req -batch -new -key web2py.key -out web2py.csr -openssl x509 -req -days 1780 -in web2py.csr -signkey web2py.key -out web2py.crt - + +openssl genrsa 1024 > web2py.key +chmod 400 web2py.key +openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt +openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info + + # Prepare folders for uwsgi sudo mkdir /etc/uwsgi sudo mkdir /var/log/uwsgi - + # Create configuration file /etc/uwsgi/web2py.xml echo ' /tmp/web2py.socket @@ -84,11 +97,11 @@ echo ' 0 0 -1 -1 -1 python /home/www-data/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o ' >/etc/uwsgi/web2py.xml - + #Create a configuration file for uwsgi in emperor-mode #for Upstart in /etc/init/uwsgi-emperor.conf echo '# Emperor uWSGI script - + description "uWSGI Emperor" start on runlevel [2345] stop on runlevel [06] @@ -104,7 +117,6 @@ respawn exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log ' > /etc/init/uwsgi-emperor.conf # Install Web2py -apt-get -y install unzip mkdir /home/www-data cd /home/www-data wget http://web2py.com/examples/static/web2py_src.zip @@ -117,11 +129,10 @@ cd /home/www-data/web2py sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)" start uwsgi-emperor /etc/init.d/nginx restart - + ## you can reload uwsgi with # restart uwsgi-emperor ## and stop it with # stop uwsgi-emperor ## to reload web2py only (without restarting uwsgi) -# touch /etc/uwsgi/web2py.xml - +# touch /etc/uwsgi/web2py.xml \ No newline at end of file diff --git a/scripts/sync_languages.py b/scripts/sync_languages.py index b3212d5b..76087d46 100755 --- a/scripts/sync_languages.py +++ b/scripts/sync_languages.py @@ -43,13 +43,13 @@ def sync_main(file, apps): data = eval(langfile.read()) finally: langfile.close() - + d = sync_language(d, data) path = 'applications/%s/' % apps[-1] file1 = os.path.join(path, 'languages', '%s.py' % file) - + f = open(file1, 'w') try: f.write('# coding: utf8\n') @@ -61,7 +61,7 @@ def sync_main(file, apps): f.write('}\n') finally: f.close() - + oapps = reversed(apps[:-1]) for app in oapps: path2 = 'applications/%s/' % app @@ -75,4 +75,3 @@ if __name__ == "__main__": apps = sys.argv[2:] sync_main(file, apps) - \ No newline at end of file