removed lots of junk from scripts folder
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
import time
|
||||
import sys
|
||||
import urllib2
|
||||
import urllib2
|
||||
|
||||
n = int(sys.argv[1])
|
||||
url = sys.argv[2]
|
||||
headers = {"Accept-Language": "en"}
|
||||
req = urllib2.Request(url, None, headers)
|
||||
|
||||
t0 = time.time()
|
||||
for k in xrange(n):
|
||||
data = urllib2.urlopen(req).read()
|
||||
print (time.time() - t0) / n
|
||||
if n == 1:
|
||||
print data
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
||||
datafile = open(filename, 'r')
|
||||
try:
|
||||
data = '\n' + datafile.read()
|
||||
finally:
|
||||
datafile.close()
|
||||
SPACE = '\n ' if '-n' in sys.argv[1:] else ' '
|
||||
|
||||
data = re.compile('(?<!\:)//(?P<a>.*)').sub('/* \g<a> */', data)
|
||||
data = re.compile('[ ]+').sub(' ', data)
|
||||
data = re.compile('\s*{\s*').sub(' {' + SPACE, data)
|
||||
data = re.compile('\s*;\s*').sub(';' + SPACE, data)
|
||||
data = re.compile(',\s*').sub(', ', data)
|
||||
data = re.compile('\s*\*/\s*').sub('*/' + SPACE, data)
|
||||
data = re.compile('\s*}\s*').sub(SPACE + '}\n', data)
|
||||
data = re.compile('\n\s*\n').sub('\n', data)
|
||||
data = re.compile(';\s+/\*').sub('; /*', data)
|
||||
data = re.compile('\*/\s+/\*').sub(' ', data)
|
||||
data = re.compile('[ ]+\n').sub('\n', data)
|
||||
data = re.compile('\n\s*/[\*]+(?P<a>.*?)[\*]+/', re.DOTALL).sub(
|
||||
'\n/*\g<a>*/\n', data)
|
||||
data = re.compile('[ \t]+(?P<a>\S.+?){').sub(' \g<a>{', data)
|
||||
data = data.replace('}', '}\n')
|
||||
|
||||
print data
|
||||
@@ -1,67 +0,0 @@
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
def cleancss(text):
|
||||
text = re.compile('\s+').sub(' ', text)
|
||||
text = re.compile('\s*(?P<a>,|:)\s*').sub('\g<a> ', text)
|
||||
text = re.compile('\s*;\s*').sub(';\n ', text)
|
||||
text = re.compile('\s*\{\s*').sub(' {\n ', text)
|
||||
text = re.compile('\s*\}\s*').sub('\n}\n\n', text)
|
||||
return text
|
||||
|
||||
|
||||
def cleanhtml(text):
|
||||
text = text.lower()
|
||||
r = re.compile('\<script.+?/script\>', re.DOTALL)
|
||||
scripts = r.findall(text)
|
||||
text = r.sub('<script />', text)
|
||||
r = re.compile('\<style.+?/style\>', re.DOTALL)
|
||||
styles = r.findall(text)
|
||||
text = r.sub('<style />', text)
|
||||
text = re.compile(
|
||||
'<(?P<tag>(input|meta|link|hr|br|img|param))(?P<any>[^\>]*)\s*(?<!/)>')\
|
||||
.sub('<\g<tag>\g<any> />', text)
|
||||
text = text.replace('\n', ' ')
|
||||
text = text.replace('>', '>\n')
|
||||
text = text.replace('<', '\n<')
|
||||
text = re.compile('\s*\n\s*').sub('\n', text)
|
||||
lines = text.split('\n')
|
||||
(indent, newlines) = (0, [])
|
||||
for line in lines:
|
||||
if line[:2] == '</': indent = indent - 1
|
||||
newlines.append(indent * ' ' + line)
|
||||
if not line[:2] == '</' and line[-1:] == '>' and \
|
||||
not line[-2:] in ['/>', '->']: indent = indent + 1
|
||||
text = '\n'.join(newlines)
|
||||
text = re.compile(
|
||||
'\<div(?P<a>( .+)?)\>\s+\</div\>').sub('<div\g<a>></div>', text)
|
||||
text = re.compile('\<a(?P<a>( .+)?)\>\s+(?P<b>[\w\s\(\)\/]+?)\s+\</a\>').sub('<a\g<a>>\g<b></a>', text)
|
||||
text = re.compile('\<b(?P<a>( .+)?)\>\s+(?P<b>[\w\s\(\)\/]+?)\s+\</b\>').sub('<b\g<a>>\g<b></b>', text)
|
||||
text = re.compile('\<i(?P<a>( .+)?)\>\s+(?P<b>[\w\s\(\)\/]+?)\s+\</i\>').sub('<i\g<a>>\g<b></i>', text)
|
||||
text = re.compile('\<span(?P<a>( .+)?)\>\s+(?P<b>[\w\s\(\)\/]+?)\s+\</span\>').sub('<span\g<a>>\g<b></span>', text)
|
||||
text = re.compile('\s+\<br(?P<a>.*?)\/\>').sub('<br\g<a>/>', text)
|
||||
text = re.compile('\>(?P<a>\s+)(?P<b>[\.\,\:\;])').sub('>\g<b>\g<a>', text)
|
||||
text = re.compile('\n\s*\n').sub('\n', text)
|
||||
for script in scripts:
|
||||
text = text.replace('<script />', script, 1)
|
||||
for style in styles:
|
||||
text = text.replace('<style />', cleancss(style), 1)
|
||||
return text
|
||||
|
||||
|
||||
def read_file(filename):
|
||||
f = open(filename, 'r')
|
||||
try:
|
||||
return f.read()
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
for file in sys.argv[1:]:
|
||||
data = read_file(file)
|
||||
open(file+'.bak2', 'w').write(data)
|
||||
if file[-4:] == '.css':
|
||||
data = cleancss(data)
|
||||
if file[-5:] == '.html':
|
||||
data = cleanhtml(data)
|
||||
open(file, 'w').write(data)
|
||||
@@ -1,17 +0,0 @@
|
||||
import re
|
||||
|
||||
|
||||
def cleanjs(text):
|
||||
text = re.sub('\s*}\s*', '\n}\n', text)
|
||||
text = re.sub('\s*{\s*', ' {\n', text)
|
||||
text = re.sub('\s*;\s*', ';\n', text)
|
||||
text = re.sub('\s*,\s*', ', ', text)
|
||||
text = re.sub('\s*(?P<a>[\+\-\*/\=]+)\s*', ' \g<a> ', text)
|
||||
lines = text.split('\n')
|
||||
text = ''
|
||||
indent = 0
|
||||
for line in lines:
|
||||
rline = line.strip()
|
||||
if rline:
|
||||
pass
|
||||
return text
|
||||
@@ -1,3 +1,6 @@
|
||||
"""
|
||||
converts a static file to a web2py view. needs work
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
@@ -97,6 +100,4 @@ def convert(source, destination,prefix='imported'):
|
||||
os.makedirs(os.path.split(fullname)[0])
|
||||
open(fullname,'w').write(views[name])
|
||||
|
||||
|
||||
|
||||
convert(sys.argv[1],sys.argv[2])
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
This script will update untranslated messages in target from source (target and source are both language files)
|
||||
Usage:
|
||||
this can be used as first step when creating language file for new but very similar language
|
||||
or if you want update your app from welcome app of newer web2py version
|
||||
or in non-standard scenarios when you work on target and from any reason you have partial translation in source
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.join(*__file__.split(os.sep)[:-2] or ['.']))
|
||||
|
||||
from gluon.languages import update_from_langfile
|
||||
import argparse
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Use to set untranslated messages in the translation file from another one.')
|
||||
parser.add_argument(
|
||||
'-t', '--target',
|
||||
required=True,
|
||||
dest="target",
|
||||
help="Specify language file (rw) where untranslated messages will be updated if possible"
|
||||
)
|
||||
parser.add_argument(
|
||||
'-s', '--source',
|
||||
required=True,
|
||||
dest="source",
|
||||
help="Specify language file (ro) where seek for translations"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
update_from_langfile(args.target, args.source)
|
||||
|
||||
print '%s was updated.' % args.target
|
||||
@@ -1,103 +0,0 @@
|
||||
import glob
|
||||
import os
|
||||
import zipfile
|
||||
import sys
|
||||
import re
|
||||
from BeautifulSoup import BeautifulSoup as BS
|
||||
|
||||
|
||||
def head(styles):
|
||||
title = '<title>{{=response.title or request.application}}</title>'
|
||||
items = '\n'.join(["{{response.files.append(URL(request.application,'static','%s'))}}" % (style) for style in styles])
|
||||
loc = """<style>
|
||||
div.flash {
|
||||
position: absolute;
|
||||
float: right;
|
||||
padding: 10px;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
opacity: 0.75;
|
||||
margin: 10px 10px 10px 10px;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
color: #fff;
|
||||
font-size: 11pt;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background: black;
|
||||
border: 2px solid #fff;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
z-index: 2;
|
||||
}
|
||||
div.error {
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
</style>"""
|
||||
return "\n%s\n%s\n{{include 'web2py_ajax.html'}}\n%s" % (title, items, loc)
|
||||
|
||||
|
||||
def content():
|
||||
return """<div class="w2p_flash">{{=response.flash or ''}}</div>{{include}}"""
|
||||
|
||||
|
||||
def process(folder):
|
||||
indexfile = open(os.path.join(folder, 'index.html'), 'rb')
|
||||
try:
|
||||
soup = BS(indexfile.read())
|
||||
finally:
|
||||
indexfile.close()
|
||||
styles = [x['href'] for x in soup.findAll('link')]
|
||||
soup.find('head').contents = BS(head(styles))
|
||||
try:
|
||||
soup.find(
|
||||
'h1').contents = BS('{{=response.title or request.application}}')
|
||||
soup.find('h2').contents = BS(
|
||||
"{{=response.subtitle or '=response.subtitle'}}")
|
||||
except:
|
||||
pass
|
||||
for match in (soup.find('div', id='menu'),
|
||||
soup.find('div', {'class': 'menu'}),
|
||||
soup.find('div', id='nav'),
|
||||
soup.find('div', {'class': 'nav'})):
|
||||
if match:
|
||||
match.contents = BS('{{=MENU(response.menu)}}')
|
||||
break
|
||||
done = False
|
||||
for match in (soup.find('div', id='content'),
|
||||
soup.find('div', {'class': 'content'}),
|
||||
soup.find('div', id='main'),
|
||||
soup.find('div', {'class': 'main'})):
|
||||
if match:
|
||||
match.contents = BS(content())
|
||||
done = True
|
||||
break
|
||||
if done:
|
||||
page = soup.prettify()
|
||||
page = re.compile("\s*\{\{=response\.flash or ''\}\}\s*", re.MULTILINE)\
|
||||
.sub("{{=response.flash or ''}}", page)
|
||||
print page
|
||||
else:
|
||||
raise Exception("Unable to convert")
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print """USAGE:
|
||||
1) start a new web2py application
|
||||
2) Download a sample free layout from the web into the static/ folder of
|
||||
your web2py application (make sure a sample index.html is there)
|
||||
3) run this script with
|
||||
|
||||
python layout_make.py /path/to/web2py/applications/app/static/
|
||||
> /path/to/web2py/applications/app/views/layout.html
|
||||
"""
|
||||
elif not os.path.exists(sys.argv[1]):
|
||||
print 'Folder %s does not exist' % sys.argv[1]
|
||||
else:
|
||||
process(sys.argv[1])
|
||||
@@ -1,116 +0,0 @@
|
||||
import os
|
||||
import glob
|
||||
import zipfile
|
||||
import urllib
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
def copytree(src, dst):
|
||||
names = os.listdir(src)
|
||||
ignored_names = set()
|
||||
errors = []
|
||||
if not os.path.exists(dst):
|
||||
os.makedirs(dst)
|
||||
for name in names:
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
if os.path.isdir(srcname):
|
||||
copytree(srcname, dstname)
|
||||
else:
|
||||
shutil.copy2(srcname, dstname)
|
||||
|
||||
class W2PInstance(object):
|
||||
|
||||
SOURCES = {'stable':'http://web2py.com/examples/static/web2py_src.zip',
|
||||
'nightly':'http://web2py.com/examples/static/nightly/web2py_src.zip',
|
||||
'trunk':'https://github.com/web2py/web2py/archive/master.zip'}
|
||||
|
||||
def __init__(self,path):
|
||||
self.path = path
|
||||
|
||||
def warn(self,message="system going down soon"):
|
||||
apps = glob.glob(os.path.join(self.path,'applications','*'))
|
||||
for app in apps:
|
||||
if os.path.isdir(app):
|
||||
open(os.path.join(app,'notifications.txt'),'w').write(message)
|
||||
|
||||
def install(self,source='stable'):
|
||||
if not os.path.exists(self.path):
|
||||
os.mkdir(self.path)
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
link = self.SOURCES[source]
|
||||
srcfile = os.path.join(tmpdir,'web2py_src.zip')
|
||||
print 'downloading...'
|
||||
open(srcfile,'wb').write(urllib.urlopen(link).read())
|
||||
print 'extracing...'
|
||||
zipfile.ZipFile(srcfile,'r').extractall(tmpdir)
|
||||
print 'copying...'
|
||||
copytree(os.path.join(tmpdir,'web2py'),self.path)
|
||||
|
||||
def upgrade(self,source='stable'):
|
||||
self.install(source)
|
||||
|
||||
def upgrade_tmp(self,source,common=False):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
link = self.SOURCES[source]
|
||||
srcfile = os.path.join(tmpdir,'web2py_src.zip')
|
||||
print 'copying production...'
|
||||
copytree(self.path,os.path.join(tmpdir,'web2py'))
|
||||
tmpdir_web2py = os.path.join(tmpdir,'web2py')
|
||||
tmp_web2py = W2PInstance(tempdir_web2py)
|
||||
tmp_web2py.clear_sessions()
|
||||
tmp_web2py.clear_cache()
|
||||
tmp_web2py.clear_error()
|
||||
print 'downloading...'
|
||||
open(srcfile,'wb').write(urllib.urlopen(link).read())
|
||||
print 'extracing...'
|
||||
zipfile.ZipFile(srcfile,'r').extractall(tmpdir)
|
||||
print 'running tests...'
|
||||
try:
|
||||
olddir = os.getcwd()
|
||||
os.chdir(tempdir_web2py)
|
||||
ret = os.system("PYTHONPATH=. python -m unittest -v gluon.tests")
|
||||
# eventually start web2py and run functional tests
|
||||
finally:
|
||||
os.chrid(olddir)
|
||||
if ret:
|
||||
sys.exit(ret and 1)
|
||||
copytree(os.path.join(tmpdir,'web2py'),self.path)
|
||||
|
||||
def clear_sessions(self):
|
||||
files = glob.glob(os.path.join(self.path,'applications','*','sessions','*'))
|
||||
for file in files:
|
||||
try:
|
||||
os.unlink(file)
|
||||
except:
|
||||
pass
|
||||
|
||||
def clear_cache(self):
|
||||
files = glob.glob(os.path.join(self.path,'applications','*','cache','*'))
|
||||
for file in files:
|
||||
try:
|
||||
os.unlink(file)
|
||||
except:
|
||||
pass
|
||||
|
||||
def clear_errors(self):
|
||||
files = glob.glob(os.path.join(self.path,'applications','*','errors','*'))
|
||||
for file in files:
|
||||
try:
|
||||
os.unlink(file)
|
||||
except:
|
||||
pass
|
||||
|
||||
web2py = W2PInstance('/Users/massimodipierro/Downloads/web2py')
|
||||
#web2py.install()
|
||||
web2py.clear_sessions()
|
||||
|
||||
"""
|
||||
{{
|
||||
import os
|
||||
_notifications = os.path.join(request.folder,'notifications.txt')
|
||||
if os.path.exixts(_notifications):
|
||||
response.flash = response.flash or open(_notifications).read()
|
||||
pass
|
||||
}}
|
||||
"""
|
||||
@@ -1,115 +0,0 @@
|
||||
user nginx nginx;
|
||||
worker_processes 1;
|
||||
|
||||
error_log /var/log/nginx/error_log info;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main
|
||||
'$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'"$gzip_ratio"';
|
||||
|
||||
client_header_timeout 10m;
|
||||
client_body_timeout 10m;
|
||||
send_timeout 10m;
|
||||
|
||||
connection_pool_size 256;
|
||||
client_header_buffer_size 1k;
|
||||
large_client_header_buffers 4 2k;
|
||||
request_pool_size 4k;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1100;
|
||||
gzip_buffers 4 8k;
|
||||
gzip_types text/plain;
|
||||
|
||||
output_buffers 1 32k;
|
||||
postpone_output 1460;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
keepalive_timeout 75 20;
|
||||
|
||||
ignore_invalid_headers on;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
index index.html;
|
||||
|
||||
server {
|
||||
listen 127.0.0.1;
|
||||
server_name localhost;
|
||||
|
||||
access_log /var/log/nginx/localhost.access_log main;
|
||||
error_log /var/log/nginx/localhost.error_log info;
|
||||
|
||||
root /var/www/localhost/htdocs;
|
||||
}
|
||||
|
||||
# SSL example
|
||||
server {
|
||||
listen 127.0.0.1:443;
|
||||
server_name localhost;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/ssl/nginx/nginx-server.pem;
|
||||
ssl_client_certificate /etc/ssl/nginx/cacert.pem;
|
||||
ssl_certificate_key /etc/ssl/nginx/nginx.key;
|
||||
ssl_verify_client optional;
|
||||
|
||||
access_log /var/log/nginx/localhost.ssl_access_log main;
|
||||
error_log /var/log/nginx/localhost.ssl_error_log info;
|
||||
|
||||
root /var/www/localhost/htdocs;
|
||||
|
||||
set $web2pyroot /home/Desktop/source/michelecomitini-facebookaccess;
|
||||
|
||||
|
||||
location /pki/ {
|
||||
root /var/www/localhost/html;
|
||||
}
|
||||
|
||||
location ~* ^/(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ {
|
||||
alias $web2pyroot/applications/$1/static/$2;
|
||||
expires max;
|
||||
}
|
||||
|
||||
location / {
|
||||
include /etc/nginx/scgi_params;
|
||||
scgi_pass 127.0.0.1:4000;
|
||||
|
||||
#Module ngx_http_ssl_module supports the following built-in variables:
|
||||
|
||||
#$ssl_cipher returns the cipher suite being used for the currently established SSL/TLS connection
|
||||
#$ssl_client_serial returns the serial number of the client certificate for the currently established SSL/TLS connection — if applicable, i.e., if client authentication is activated in the connection
|
||||
#$ssl_client_s_dn returns the subject Distinguished Name (DN) of the client certificate for the currently established SSL/TLS connection — if applicable, i.e., if client authentication is activated in the connection
|
||||
#$ssl_client_i_dn returns the issuer DN of the client certificate for the currently established SSL/TLS connection — if applicable, i.e., if client authentication is activated in the connection
|
||||
#$ssl_protocol returns the protocol of the currently established SSL/TLS connection — depending on the configuration and client available options it's one of SSLv2, SSLv3 or TLSv1
|
||||
#$ssl_session_id the Session ID of the established secure connection — requires Nginx version greater or equal to 0.8.20
|
||||
#$ssl_client_cert
|
||||
#$ssl_client_raw_cert
|
||||
#$ssl_client_verify takes the value "SUCCESS" when the client certificate is successfully verified
|
||||
scgi_param SSL_PROTOCOL $ssl_protocol;
|
||||
scgi_param HTTPS on;
|
||||
scgi_param SSL_CIPHER $ssl_cipher;
|
||||
scgi_param SSL_CLIENT_SERIAL $ssl_client_serial;
|
||||
scgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
|
||||
scgi_param SSL_CLIENT_I_DN $ssl_client_i_dn;
|
||||
scgi_param SSL_SESSION_ID $ssl_session_id;
|
||||
scgi_param SSL_CLIENT_CERT $ssl_client_cert;
|
||||
scgi_param SSL_CLIENT_RAW_CERT $ssl_client_raw_cert;
|
||||
scgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Use to update official_top_level_domains in gluon/validators.py
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import operator
|
||||
import urllib2
|
||||
|
||||
LIMIT = 70
|
||||
PREFIX = ' '
|
||||
TLDS_URL = 'http://data.iana.org/TLD/tlds-alpha-by-domain.txt'
|
||||
|
||||
resp = urllib2.urlopen(TLDS_URL)
|
||||
content = resp.read()
|
||||
|
||||
valid_lines = [a.strip().lower() for a in content.split('\n') if a.strip() and a.strip()[0] != '#']
|
||||
valid_lines += ['localhost']
|
||||
|
||||
print 'Fetched TLDs are %s' % len(valid_lines)
|
||||
|
||||
results = [list(g) for k, g in itertools.groupby(sorted(valid_lines), key=operator.itemgetter(0))]
|
||||
|
||||
output = []
|
||||
line = "'%s', "
|
||||
|
||||
for a in results:
|
||||
output.append('%s# %s' % (PREFIX, a[-1][0]))
|
||||
thisline = PREFIX
|
||||
for c in a:
|
||||
newline = thisline + line % c
|
||||
if len(newline) > 70:
|
||||
output.append(thisline[:-1])
|
||||
thisline = PREFIX + line % c
|
||||
else:
|
||||
thisline += line % c
|
||||
if thisline:
|
||||
output.append(thisline[:-1])
|
||||
|
||||
print '[\n' + '\n'.join(output)[:-1] + '\n]'
|
||||
@@ -1,220 +0,0 @@
|
||||
from service import ServiceBase
|
||||
import os, sys, time, subprocess, atexit
|
||||
from signal import SIGTERM
|
||||
|
||||
class LinuxService(ServiceBase):
|
||||
def __init__(self, name, label, stdout='/dev/null', stderr='/dev/null'):
|
||||
ServiceBase.__init__(self, name, label, stdout, stderr)
|
||||
self.pidfile = '/tmp/%s.pid' % name
|
||||
self.config_file = '/etc/%s.conf' % name
|
||||
|
||||
def daemonize(self):
|
||||
"""
|
||||
do the UNIX double-fork magic, see Stevens' "Advanced
|
||||
Programming in the UNIX Environment" for details (ISBN 0201563177)
|
||||
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
|
||||
"""
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit first parent
|
||||
sys.exit(0)
|
||||
except OSError, e:
|
||||
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
return
|
||||
|
||||
# decouple from parent environment
|
||||
os.chdir("/")
|
||||
os.setsid()
|
||||
os.umask(0)
|
||||
|
||||
# do second fork
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit from second parent
|
||||
sys.exit(0)
|
||||
except OSError, e:
|
||||
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
return
|
||||
|
||||
# redirect standard file descriptors
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
si = file('/dev/null', 'r')
|
||||
so = file(self.stdout or '/dev/null', 'a+')
|
||||
se = file(self.stderr or '/dev/null', 'a+')
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
|
||||
def getpid(self):
|
||||
# Check for a pidfile to see if the daemon already runs
|
||||
try:
|
||||
pf = file(self.pidfile,'r')
|
||||
pid = int(pf.read().strip())
|
||||
pf.close()
|
||||
except IOError:
|
||||
pid = None
|
||||
|
||||
return pid
|
||||
|
||||
def status(self):
|
||||
pid = self.getpid()
|
||||
if pid:
|
||||
return 'Service running with PID %s.' % pid
|
||||
else:
|
||||
return 'Service is not running.'
|
||||
|
||||
def check_permissions(self):
|
||||
if not os.geteuid() == 0:
|
||||
return (False, 'This script must be run with root permissions.')
|
||||
else:
|
||||
return (True, '')
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Start the daemon
|
||||
"""
|
||||
pid = self.getpid()
|
||||
|
||||
if pid:
|
||||
message = "Service already running under PID %s\n"
|
||||
sys.stderr.write(message % self.pidfile)
|
||||
return
|
||||
|
||||
# Start the daemon
|
||||
self.daemonize()
|
||||
self.run()
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stop the daemon
|
||||
"""
|
||||
pid = self.getpid()
|
||||
|
||||
if not pid:
|
||||
message = "Service is not running\n"
|
||||
sys.stderr.write(message)
|
||||
return # not an error in a restart
|
||||
|
||||
# Try killing the daemon process
|
||||
try:
|
||||
while 1:
|
||||
os.kill(pid, SIGTERM)
|
||||
time.sleep(0.5)
|
||||
except OSError, err:
|
||||
err = str(err)
|
||||
if err.find("No such process") > 0:
|
||||
if os.path.exists(self.pidfile):
|
||||
os.remove(self.pidfile)
|
||||
else:
|
||||
print str(err)
|
||||
return
|
||||
|
||||
def restart(self):
|
||||
"""
|
||||
Restart the daemon
|
||||
"""
|
||||
self.stop()
|
||||
self.start()
|
||||
|
||||
def run(self):
|
||||
atexit.register(self.terminate)
|
||||
|
||||
args = self.load_configuration()[0]
|
||||
stdout = open(self.stdout, 'a+')
|
||||
stderr = open(self.stderr, 'a+')
|
||||
process = subprocess.Popen(args, stdout=stdout, stderr=stderr)
|
||||
file(self.pidfile,'w+').write("%s\n" % process.pid)
|
||||
process.wait()
|
||||
|
||||
self.terminate()
|
||||
|
||||
def terminate(self):
|
||||
try:
|
||||
os.remove(self.pidfile)
|
||||
except:
|
||||
pass
|
||||
|
||||
def install(self):
|
||||
env = self.detect_environment()
|
||||
src_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'service.py')
|
||||
|
||||
# make sure this script is executable
|
||||
self.run_command('chmod', '+x', src_path)
|
||||
|
||||
# link this daemon to the service directory
|
||||
dest_path = env['rc.d-path'] + self.name
|
||||
os.symlink(src_path, dest_path)
|
||||
|
||||
# start the service at boot
|
||||
install_command = self.get_service_installer_command(env)
|
||||
result = self.run_command(*install_command)
|
||||
self.start()
|
||||
|
||||
def uninstall(self):
|
||||
self.stop()
|
||||
env = self.detect_environment()
|
||||
|
||||
# stop the service from autostarting
|
||||
uninstall_command = self.get_service_uninstaller_command(env)
|
||||
result = self.run_command(*uninstall_command)
|
||||
|
||||
# remove link to the script from the service directory
|
||||
path = env['rc.d-path'] + self.name
|
||||
os.remove(path)
|
||||
|
||||
def detect_environment(self):
|
||||
"""
|
||||
Returns a dictionary of command/path to the required command-line applications.
|
||||
One key is 'dist' which will either be 'debian' or 'redhat', which is the best
|
||||
guess as to which Linux distribution the current system is based on.
|
||||
"""
|
||||
check_for = [
|
||||
'chkconfig',
|
||||
'service',
|
||||
'update-rc.d',
|
||||
'rpm',
|
||||
'dpkg',
|
||||
]
|
||||
|
||||
env = dict()
|
||||
for cmd in check_for:
|
||||
result = self.run_command('which', cmd)
|
||||
if result[0]:
|
||||
env[cmd] = result[0].replace('\n', '')
|
||||
|
||||
if 'rpm' in env:
|
||||
env['dist'] = 'redhat'
|
||||
env['rc.d-path'] = '/etc/rc.d/init.d/'
|
||||
elif 'dpkg' in env:
|
||||
env['dist'] = 'debian'
|
||||
env['rc.d-path'] = '/etc/init.d/'
|
||||
else:
|
||||
env['dist'] = 'unknown'
|
||||
env['rc.d-path'] = '/dev/null/'
|
||||
|
||||
return env
|
||||
|
||||
def get_service_installer_command(self, env):
|
||||
"""
|
||||
Returns list of args required to set a service to run on boot.
|
||||
"""
|
||||
if env['dist'] == 'redhat':
|
||||
cmd = env['chkconfig']
|
||||
return [cmd, self.name, 'on']
|
||||
else:
|
||||
cmd = env['update-rc.d']
|
||||
return [cmd, self.name, 'defaults']
|
||||
|
||||
def get_service_uninstaller_command(self, env):
|
||||
"""
|
||||
Returns list of arge required to stop a service from running at boot.
|
||||
"""
|
||||
if env['dist'] == 'redhat':
|
||||
cmd = env['chkconfig']
|
||||
return [cmd, self.name, 'off']
|
||||
else:
|
||||
cmd = env['update-rc.d']
|
||||
return [cmd, self.name, 'remove']
|
||||
@@ -1,201 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, time, subprocess
|
||||
|
||||
class Base:
|
||||
def run_command(self, *args):
|
||||
"""
|
||||
Returns the output of a command as a tuple (output, error).
|
||||
"""
|
||||
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return p.communicate()
|
||||
|
||||
class ServiceBase(Base):
|
||||
def __init__(self, name, label, stdout=None, stderr=None):
|
||||
self.name = name
|
||||
self.label = label
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
self.config_file = None
|
||||
|
||||
def load_configuration(self):
|
||||
"""
|
||||
Loads the configuration required to build the command-line string
|
||||
for running web2py. Returns a tuple (command_args, config_dict).
|
||||
"""
|
||||
s = os.path.sep
|
||||
|
||||
default = dict(
|
||||
python = 'python',
|
||||
web2py = os.path.join(s.join(__file__.split(s)[:-3]), 'web2py.py'),
|
||||
http_enabled = True,
|
||||
http_ip = '0.0.0.0',
|
||||
http_port = 8000,
|
||||
https_enabled = True,
|
||||
https_ip = '0.0.0.0',
|
||||
https_port = 8001,
|
||||
https_key = '',
|
||||
https_cert = '',
|
||||
password = '<recycle>',
|
||||
)
|
||||
|
||||
config = default
|
||||
if self.config_file:
|
||||
try:
|
||||
f = open(self.config_file, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
for line in lines:
|
||||
fields = line.split('=', 1)
|
||||
if len(fields) == 2:
|
||||
key, value = fields
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
config[key] = value
|
||||
except:
|
||||
pass
|
||||
|
||||
web2py_path = os.path.dirname(config['web2py'])
|
||||
os.chdir(web2py_path)
|
||||
|
||||
args = [config['python'], config['web2py']]
|
||||
interfaces = []
|
||||
ports = []
|
||||
|
||||
if config['http_enabled']:
|
||||
ip = config['http_ip']
|
||||
port = config['http_port']
|
||||
interfaces.append('%s:%s' % (ip, port))
|
||||
ports.append(port)
|
||||
if config['https_enabled']:
|
||||
ip = config['https_ip']
|
||||
port = config['https_port']
|
||||
key = config['https_key']
|
||||
cert = config['https_cert']
|
||||
if key != '' and cert != '':
|
||||
interfaces.append('%s:%s:%s:%s' % (ip, port, key, cert))
|
||||
ports.append(ports)
|
||||
if len(interfaces) == 0:
|
||||
sys.exit('Configuration error. Must have settings for http and/or https')
|
||||
|
||||
password = config['password']
|
||||
if not password == '<recycle>':
|
||||
from gluon import main
|
||||
for port in ports:
|
||||
main.save_password(password, port)
|
||||
|
||||
password = '<recycle>'
|
||||
|
||||
args.append('-a "%s"' % password)
|
||||
|
||||
interfaces = ';'.join(interfaces)
|
||||
args.append('--interfaces=%s' % interfaces)
|
||||
|
||||
if 'log_filename' in config.keys():
|
||||
log_filename = config['log_filename']
|
||||
args.append('--log_filename=%s' % log_filename)
|
||||
|
||||
return (args, config)
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def restart(self):
|
||||
pass
|
||||
|
||||
def status(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
|
||||
def install(self):
|
||||
pass
|
||||
|
||||
def uninstall(self):
|
||||
pass
|
||||
|
||||
def check_permissions(self):
|
||||
"""
|
||||
Does the script have permissions to install, uninstall, start, and stop services?
|
||||
Return value must be a tuple (True/False, error_message_if_False).
|
||||
"""
|
||||
return (False, 'Permissions check not implemented')
|
||||
|
||||
class WebServerBase(Base):
|
||||
def install(self):
|
||||
pass
|
||||
|
||||
def uninstall(self):
|
||||
pass
|
||||
|
||||
|
||||
def get_service():
|
||||
service_name = 'web2py'
|
||||
service_label = 'web2py Service'
|
||||
|
||||
if sys.platform == 'linux2':
|
||||
from linux import LinuxService as Service
|
||||
elif sys.platform == 'darwin':
|
||||
# from mac import MacService as Service
|
||||
sys.exit('Mac OS X is not yet supported.\n')
|
||||
elif sys.platform == 'win32':
|
||||
# from windows import WindowsService as Service
|
||||
sys.exit('Windows is not yet supported.\n')
|
||||
else:
|
||||
sys.exit('The following platform is not supported: %s.\n' % sys.platform)
|
||||
|
||||
service = Service(service_name, service_label)
|
||||
return service
|
||||
|
||||
if __name__ == '__main__':
|
||||
service = get_service()
|
||||
is_root, error_message = service.check_permissions()
|
||||
if not is_root:
|
||||
sys.exit(error_message)
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
command = sys.argv[1]
|
||||
if command == 'start':
|
||||
service.start()
|
||||
elif command == 'stop':
|
||||
service.stop()
|
||||
elif command == 'restart':
|
||||
service.restart()
|
||||
elif command == 'status':
|
||||
print service.status() + '\n'
|
||||
elif command == 'run':
|
||||
service.run()
|
||||
elif command == 'install':
|
||||
service.install()
|
||||
elif command == 'uninstall':
|
||||
service.uninstall()
|
||||
elif command == 'install-apache':
|
||||
# from apache import Apache
|
||||
# server = Apache()
|
||||
# server.install()
|
||||
sys.exit('Configuring Apache is not yet supported.\n')
|
||||
elif command == 'uninstall-apache':
|
||||
# from apache import Apache
|
||||
# server = Apache()
|
||||
# server.uninstall()
|
||||
sys.exit('Configuring Apache is not yet supported.\n')
|
||||
else:
|
||||
sys.exit('Unknown command: %s' % command)
|
||||
else:
|
||||
print 'Usage: %s [command] \n' % sys.argv[0] + \
|
||||
'\tCommands:\n' + \
|
||||
'\t\tstart Starts the service\n' + \
|
||||
'\t\tstop Stop the service\n' + \
|
||||
'\t\trestart Restart the service\n' + \
|
||||
'\t\tstatus Check if the service is running\n' + \
|
||||
'\t\trun Run service is blocking mode\n' + \
|
||||
'\t\t (Press Ctrl + C to exit)\n' + \
|
||||
'\t\tinstall Install the service\n' + \
|
||||
'\t\tuninstall Uninstall the service\n' + \
|
||||
'\t\tinstall-apache Install as an Apache site\n' + \
|
||||
'\t\tuninstall-apache Uninstall from Apache\n'
|
||||
@@ -1,11 +0,0 @@
|
||||
# install virtualenv
|
||||
easy_install virtualenv
|
||||
python virtualenv.py w2env
|
||||
# install missing modules
|
||||
w2env/bin/easy_install -U pysqlite hashlib
|
||||
# donwload web2py and unpack
|
||||
wget http://web2py.com/examples/static/web2py_src.zip
|
||||
unzip web2py_src.zip
|
||||
cd web2py
|
||||
# start web2py using command-line script
|
||||
w2env/bin/python web2py.py -i 0.0.0.0 -p 8123 -a 'adminpasswd'
|
||||
@@ -1,462 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Description : Installation and basic configuration of web2py, uWSGI, Redmine,
|
||||
# Unicorn, Nginx and PostgreSQL.
|
||||
# Usage : Copy the script in /home/username and run it as root, you may
|
||||
# need to allow exectuion (chmod +x). Ex.:
|
||||
# sudo ./setup-ubuntu-12-04-redmine-unicorn-web2py-uwsgi-nginx.sh
|
||||
# File : setup-ubuntu-12-04-redmine-unicorn-web2py-uwsgi-nginx.sh
|
||||
# Author : Richard V?zina
|
||||
# Email : ml.richard.vezina@gmail.com
|
||||
# Copyright : Richard V?zina
|
||||
# Date : ven 28 d?c 2012 13:27:11 EST
|
||||
# Disclaimers : This script is provided "as is", without warranty of any kind.
|
||||
# Licence : CC BY-NC 2.5 CA
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
echo 'setup-ubuntu-12-04-redmine-unicorn-web2py-uwsgi-nginx.sh'
|
||||
echo 'Requires Ubuntu = 12.04 (May works with 12.10 not tested) and installs Redmine + Unicorn + Web2py + uWSGI + Nginx + PostgreSQL'
|
||||
# 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
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# We concentrate here user prompts!!
|
||||
# Get Redmine Postgres Database Password
|
||||
echo -e "Redmine Postgres Database Password: \c "
|
||||
read REDMINEPASSWORD
|
||||
# Get Web2py Admin Password
|
||||
echo -e "Web2py Admin Password: \c "
|
||||
read PW
|
||||
|
||||
cd ~
|
||||
openssl genrsa 1024 > self_signed.key
|
||||
chmod 400 self_signed.key
|
||||
openssl req -new -x509 -nodes -sha1 -days 1780 -key self_signed.key > self_signed.cert
|
||||
openssl x509 -noout -fingerprint -text < self_signed.cert > self_signed.info
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
apt-get update
|
||||
apt-get -y upgrade
|
||||
apt-get autoremove
|
||||
apt-get autoclean
|
||||
apt-get -y install postgresql
|
||||
apt-get -y install nginx-full
|
||||
apt-get -y install build-essential python-dev libxml2-dev python-pip unzip
|
||||
apt-get -y install ruby1.9.3 # Ref.: http://askubuntu.com/questions/137485/rails-3-not-using-rvm
|
||||
apt-get -y install libpq-dev # Required for gem1.9.3 install pg Ref.: http://stackoverflow.com/questions/6040583/unable-to-install-pg-gem-on-ubuntu-cant-find-the-libpq-fe-h-header
|
||||
|
||||
gem1.9.3 install rails --no-rdoc --no-ri # For testing (faster) --no-rdoc --no-ri
|
||||
gem1.9.3 install unicorn --no-rdoc --no-ri # For testing (faster) --no-rdoc --no-ri
|
||||
gem1.9.3 install pg --no-rdoc --no-ri # For testing (faster) --no-rdoc --no-ri
|
||||
cd /opt
|
||||
wget http://rubyforge.org/frs/download.php/76627/redmine-2.2.0.tar.gz
|
||||
wget http://rubyforge.org/frs/download.php/76628/redmine-2.2.0.tar.gz.md5
|
||||
md5sum --check redmine-2.2.0.tar.gz.md5 > redmine_md5_checked_successfully
|
||||
if [ -f redmine_md5_checked_successfully ]
|
||||
then
|
||||
tar xvfz redmine-2.2.0.tar.gz
|
||||
rm redmine_md5_checked_successfully
|
||||
else
|
||||
echo "Redmine md5 check sum failed..."
|
||||
exit 1
|
||||
fi
|
||||
cd redmine-2.2.0
|
||||
bundle install --without development test rmagick sqlite mysql
|
||||
mkdir /var/www
|
||||
ln -s /opt/redmine-2.2.0/public /var/www/redmine
|
||||
chown -R www-data.www-data /var/www
|
||||
chown -R www-data.www-data /opt/redmine-2.2.0/public
|
||||
# To avoid prompt during execution of the script use psql instead of createuser
|
||||
#echo "Enter a postgres redmine user password twice:"
|
||||
#createuser -P -S -D -R -l -e redmine
|
||||
# createuser switch: -P --pwprompt -S --no-superuser -D --no-createdb -R --no-createrole -l --login -e --echo
|
||||
sudo -u postgres psql -c "CREATE ROLE redmine LOGIN; ALTER ROLE redmine WITH ENCRYPTED PASSWORD '$REDMINEPASSWORD';"
|
||||
# createdb wouldn't work without having root password
|
||||
#createdb -U postgres -w -E UTF8 -O redmine -e redmine
|
||||
# createdb switch: -U username --username=username -w --no-password -E Encoding -O owner --owner=owner -e --echo
|
||||
sudo -u postgres psql -c "CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;"
|
||||
cd /opt/redmine-2.2.0/config
|
||||
# Here we change related to an issue with new rails version as far as I understand
|
||||
# Ref1.: http://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_in_a_sub-URI # Preferred solution used
|
||||
# Ref2.: http://www.redmine.org/issues/12102 # JS and CSS was not working until I add this line 'RedmineApp::Application.routes.default_scope = { :path => "/redmine", :shallow_path => "/redmine" }' before 'RedmineApp::Application.initialize!'
|
||||
cp environment.rb environment.rb_original # Backup default environment.rb
|
||||
sed '/RedmineApp::Application.initialize!/c \RedmineApp::Application.routes.default_scope = { :path => "/redmine", :shallow_path => "/redmine" }\nRedmineApp::Application.initialize!\nRedmine::Utils::relative_url_root = "/redmine"' environment.rb_original > environment.rb
|
||||
# Now we configure Redmine database access
|
||||
#nano database.yml
|
||||
# paste :
|
||||
echo 'production:
|
||||
adapter: postgresql
|
||||
database: redmine
|
||||
host: localhost
|
||||
username: redmine
|
||||
password: "'$REDMINEPASSWORD'"
|
||||
encoding: utf8' > database.yml
|
||||
rake generate_secret_token
|
||||
RAILS_ENV=production rake db:migrate
|
||||
RAILS_ENV=production rake redmine:load_default_data
|
||||
mkdir /opt/redmine-2.2.0/tmp/pids
|
||||
#mkdir /opt/redmine-2.2.0/log # if not there
|
||||
cd /opt/redmine-2.2.0/config
|
||||
# Create Unicorn specific Redmine config in /opt/redmine-2.2.0/config/unicorn.rb
|
||||
echo '#unicorn.rb Starts here
|
||||
worker_processes 1
|
||||
working_directory "/opt/redmine-2.2.0" # needs to be the correct directory for redmine
|
||||
|
||||
# This loads the application in the master process before forking
|
||||
# worker processes
|
||||
# Read more about it here:
|
||||
# http://unicorn.bogomips.org/Unicorn/Configurator.html
|
||||
preload_app true
|
||||
timeout 45
|
||||
|
||||
# This is where we specify the socket.
|
||||
# We will point the upstream Nginx module to this socket later on
|
||||
listen "/tmp/unicorn_rails.socket", :backlog => 64 #directory structure needs to be created.
|
||||
pid "/opt/redmine-2.2.0/tmp/pids/unicorn_rails.pid" # make sure this points to a valid directory. Make sure it is named the same as the real process name in order to allow init.d script start-stop-daemon command to kill unicorn process properly
|
||||
|
||||
# Set the path of the log files inside the log folder of the testapp
|
||||
stderr_path "/opt/redmine-2.2.0/log/unicorn_rails.stderr.log"
|
||||
stdout_path "/opt/redmine-2.2.0/log/unicorn_rails.stdout.log"
|
||||
|
||||
before_fork do |server, worker|
|
||||
# This option works in together with preload_app true setting
|
||||
# What is does is prevent the master process from holding
|
||||
# the database connection
|
||||
defined?(ActiveRecord::Base) and
|
||||
ActiveRecord::Base.connection.disconnect!
|
||||
end
|
||||
|
||||
after_fork do |server, worker|
|
||||
# Here we are establishing the connection after forking worker
|
||||
# processes
|
||||
defined?(ActiveRecord::Base) and
|
||||
ActiveRecord::Base.establish_connection
|
||||
# change below if your redmine instance is running differently
|
||||
worker.user('\''www-data'\'', '\''www-data'\'') if Process.euid == 0
|
||||
end
|
||||
#unicorn.rb Ends here' > unicorn.rb
|
||||
chown www-data:www-data unicorn.rb
|
||||
chown -R www-data:www-data /opt/redmine-2.2.0/tmp
|
||||
mkdir /etc/unicorn
|
||||
# Set some config for Unicorn in /etc/unicorn/redmine
|
||||
echo 'RAILS_ROOT=/opt/redmine-2
|
||||
RAILS_ENV=production' > /etc/unicorn/redmine
|
||||
# Create a Unicorn Redmine start script in /etc/init.d/redmine
|
||||
echo '#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: redmine
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: redmine initscript
|
||||
# Description: This script startup unicorn server and redmine and should
|
||||
# be placed in /etc/init.d.
|
||||
### END INIT INFO
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Author: Richard V?zina <ml.richard.vezina@gmail.com>
|
||||
# Base on Ubuntu 12.04 : /etc/init.d/skeleton
|
||||
# ven 21 d?c 2012 11:08:31 EST
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
APP=/opt/redmine-2.2.0/
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="Unicorn and Redmine"
|
||||
NAME=unicorn_rails
|
||||
DAEMON=/usr/local/bin/$NAME
|
||||
DAEMON_ARGS=" -E production -c $APP/config/unicorn.rb -D"
|
||||
PIDFILE=/opt/redmine-2.2.0/tmp/pids/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/redmine
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don'\''t delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave '\''force-reload'\'' as an alias for '\''restart'\''.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# '\''force-reload'\'' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:' > /etc/init.d/redmine
|
||||
chmod +x /etc/init.d/redmine
|
||||
# Backup default Nginx site and replace it
|
||||
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default_original
|
||||
rm /etc/nginx/sites-available/default
|
||||
# Create configuration file /etc/nginx/sites-available/default
|
||||
echo 'upstream unicorn_server {
|
||||
# This is the socket we configured in unicorn.rb
|
||||
server unix:/tmp/unicorn_rails.socket
|
||||
fail_timeout=0;
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
#return 301 https://192.168.1.126$request_uri; # http://$hostname$request_uri; # idem #http://wiki.nginx.org/Pitfalls#Taxing_Rewrites
|
||||
charset utf-8;
|
||||
server_name localhost; # $hostname;
|
||||
root /var/www;
|
||||
access_log /var/log/nginx/yoursite.access.log;
|
||||
error_log /var/log/nginx/yoursite.error.log;
|
||||
#to enable correct use of response.static_version
|
||||
location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ {
|
||||
alias /home/www-data/web2py/applications/$1/static/$2;
|
||||
expires max;
|
||||
}
|
||||
location ~^\/(?!redmine(.*)) {
|
||||
#uwsgi_pass 127.0.0.1:9001;
|
||||
uwsgi_pass unix:///tmp/web2py.socket;
|
||||
include uwsgi_params;
|
||||
uwsgi_param UWSGI_SCHEME $scheme;
|
||||
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
}
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
|
||||
if (!-f $request_filename) {
|
||||
proxy_pass http://unicorn_server;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 443 default_server ssl;
|
||||
charset utf-8;
|
||||
server_name localhost; # $hostname;
|
||||
root /var/www;
|
||||
ssl_certificate /etc/nginx/ssl/self_signed.cert;
|
||||
ssl_certificate_key /etc/nginx/ssl/self_signed.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 ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ {
|
||||
alias /home/www-data/web2py/applications/$1/static/$2;
|
||||
expires max;
|
||||
}
|
||||
location ~^\/(?!redmine(.*)) {
|
||||
#uwsgi_pass 127.0.0.1:9001;
|
||||
uwsgi_pass unix:///tmp/web2py.socket;
|
||||
include uwsgi_params;
|
||||
uwsgi_param UWSGI_SCHEME $scheme;
|
||||
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
}
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
|
||||
if (!-f $request_filename) {
|
||||
proxy_pass http://unicorn_server;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}' >/etc/nginx/sites-available/default
|
||||
|
||||
#ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py
|
||||
#rm /etc/nginx/sites-enabled/default
|
||||
|
||||
# We copy ssl files we previously created
|
||||
if [ -f /etc/nginx/ssl ]
|
||||
then
|
||||
cp ~/self_signed.* /etc/nginx/ssl/
|
||||
rm ~/self_signed.*
|
||||
else
|
||||
mkdir /etc/nginx/ssl
|
||||
cp ~/self_signed.* /etc/nginx/ssl/
|
||||
rm ~/self_signed.*
|
||||
fi
|
||||
|
||||
pip install setuptools --no-use-wheel --upgrade
|
||||
PIPPATH=`which pip`
|
||||
$PIPPATH install --upgrade uwsgi
|
||||
|
||||
# Prepare folders for uwsgi
|
||||
sudo mkdir /etc/uwsgi
|
||||
sudo mkdir /var/log/uwsgi
|
||||
|
||||
# Create configuration file /etc/uwsgi/web2py.xml
|
||||
echo '<uwsgi>
|
||||
<socket>/tmp/web2py.socket</socket>
|
||||
<pythonpath>/home/www-data/web2py/</pythonpath>
|
||||
<mount>/=wsgihandler:application</mount>
|
||||
<master/>
|
||||
<processes>4</processes>
|
||||
<harakiri>60</harakiri>
|
||||
<reload-mercy>8</reload-mercy>
|
||||
<cpu-affinity>1</cpu-affinity>
|
||||
<stats>/tmp/stats.socket</stats>
|
||||
<max-requests>2000</max-requests>
|
||||
<limit-as>512</limit-as>
|
||||
<reload-on-as>256</reload-on-as>
|
||||
<reload-on-rss>192</reload-on-rss>
|
||||
<uid>www-data</uid>
|
||||
<gid>www-data</gid>
|
||||
<cron>0 0 -1 -1 -1 python /home/www-data/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o</cron>
|
||||
<no-orphans/>
|
||||
</uwsgi>' > /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]
|
||||
##
|
||||
#remove the comments in the next section to enable static file compression for the welcome app
|
||||
#in that case, turn on gzip_static on; on /etc/nginx/nginx.conf
|
||||
##
|
||||
#pre-start script
|
||||
# python /home/www-data/web2py/web2py.py -S welcome -R scripts/zip_static_files.py
|
||||
# chown -R www-data:www-data /home/www-data/web2py/*
|
||||
#end script
|
||||
respawn
|
||||
exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log
|
||||
' > /etc/init/uwsgi-emperor.conf
|
||||
# Install Web2py
|
||||
mkdir /home/www-data
|
||||
cd /home/www-data
|
||||
wget http://web2py.com/examples/static/web2py_src.zip
|
||||
unzip web2py_src.zip
|
||||
rm web2py_src.zip
|
||||
chown -R www-data:www-data web2py
|
||||
cd /home/www-data/web2py
|
||||
mv handlers/wsgihandler.py wsgihandler.py
|
||||
sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)"
|
||||
/etc/init.d/redmine start
|
||||
start uwsgi-emperor
|
||||
/etc/init.d/nginx restart
|
||||
ufw allow 80 # Or check your firewall configuration
|
||||
@@ -1,96 +0,0 @@
|
||||
#
|
||||
# Author: Christopher Steel
|
||||
# Organization: Voice of Access
|
||||
# Date: 2010-11-24
|
||||
# License: Same as Web2py, MIT / GNU
|
||||
# Email: Christopher DOT Steel AT Voice of Access DOT org
|
||||
#
|
||||
# This script will :
|
||||
# download and install virtualenv
|
||||
# start a virtual environment
|
||||
# move into the virtual environment
|
||||
# download and install latest stable version of web2py
|
||||
# start web2py in the virtual environment
|
||||
#
|
||||
# To disactivate the virtual environment, shut down web2py
|
||||
# and type 'disactivate' at the command line.
|
||||
#
|
||||
# Testing:
|
||||
# OS X
|
||||
# should work on POSIX systems
|
||||
#
|
||||
# Usage:
|
||||
# create a directory to hold your virtual environments, for example
|
||||
# /home/user_name/virtual_environments
|
||||
# place this script in the directory and make it executable
|
||||
# chmod +x web2py-install-virtualenv.sh
|
||||
customize the variables below to meet your needs
|
||||
# execute from terminal
|
||||
# ./web2py-install-virtualenv.sh
|
||||
# relax...
|
||||
|
||||
################ VARIABLES
|
||||
# Change to reflect version changes etc.
|
||||
#
|
||||
# name for your virtual environment
|
||||
ENV=VIRTUAL_ENV
|
||||
# version to install
|
||||
APP_NAME=virtualenv
|
||||
VER=1.5.1
|
||||
DIR=${APP_NAME}-${VER}
|
||||
EXT=tar.gz
|
||||
ARCHIVE=${APP_NAME}-${VER}.${EXT}
|
||||
# md5 sum, see end of url from pypi
|
||||
MD5_SUM=3daa1f449d5d2ee03099484cecb1c2b7
|
||||
################
|
||||
#
|
||||
echo 'downloading' ${ARCHIVE}
|
||||
echo '================================'
|
||||
echo `wget http://pypi.python.org/packages/source/v/virtualenv/${ARCHIVE}`
|
||||
md5 ${ARCHIVE}
|
||||
echo 'MD5 ('${ARCHIVE}') =' ${MD5_SUM}
|
||||
echo 'unarchive' ${ARCHIVE}
|
||||
echo '================================='
|
||||
tar xvfz ${ARCHIVE}
|
||||
|
||||
echo ' comparing md5 sums'
|
||||
echo '================================='
|
||||
md5 ${ARCHIVE}
|
||||
echo 'MD5 ('${ARCHIVE}') =' ${MD5_SUM}
|
||||
|
||||
#echo 'installing compatibility modules'
|
||||
#echo '================================'
|
||||
#virtualenv/bin/easy_install -U pysqlite hashlib
|
||||
|
||||
#echo 'Installing distribute'
|
||||
#echo '====================='
|
||||
#echo 'Creating Environment'
|
||||
#echo '====================='
|
||||
#echo `python ./${DIRAPP_NAME}-${VER}/virtualenv.py --distribute ${ENV}`
|
||||
|
||||
echo 'Start virtual environment'
|
||||
echo '========================='
|
||||
virtualenv --no-site-packages ${ENV}
|
||||
|
||||
RUN_THIS='source ${ENV}/bin/activate'
|
||||
`echo source ${ENV}/bin/activate`
|
||||
|
||||
echo 'Moving into virtual environment directory'
|
||||
echo '========================================='
|
||||
cd ${ENV}
|
||||
|
||||
echo 'downloading web2py'
|
||||
echo '=================='
|
||||
wget http://web2py.com/examples/static/web2py_src.zip
|
||||
unzip web2py_src.zip
|
||||
cd web2py
|
||||
|
||||
echo 'to deactivate your virtual environment'
|
||||
echo 'shutdown web2py and then type "deactivate"'
|
||||
echo '=========================================='
|
||||
read -p "Press any key to start web2py…"
|
||||
|
||||
|
||||
echo 'starting web2py'
|
||||
echo '==============='
|
||||
../bin/python2.5 web2py.py
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
crontab -e
|
||||
* 3 * * * root path/to/this/file
|
||||
"""
|
||||
|
||||
USER = 'www-data'
|
||||
TMPFILENAME = 'web2py_src_update.zip'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import urllib
|
||||
import zipfile
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'nightly':
|
||||
version = 'http://web2py.com/examples/static/nightly/web2py_src.zip'
|
||||
else:
|
||||
version = 'http://web2py.com/examples/static/web2py_src.zip'
|
||||
|
||||
realpath = os.path.realpath(__file__)
|
||||
path = os.path.dirname(os.path.dirname(os.path.dirname(realpath)))
|
||||
os.chdir(path)
|
||||
try:
|
||||
old_version = open('web2py/VERSION', 'r').read().strip()
|
||||
except IOError:
|
||||
old_version = ''
|
||||
open(TMPFILENAME, 'wb').write(urllib.urlopen(version).read())
|
||||
new_version = zipfile.ZipFile(TMPFILENAME).read('web2py/VERSION').strip()
|
||||
if new_version > old_version:
|
||||
os.system('sudo -u %s unzip -o %s' % (USER, TMPFILENAME))
|
||||
os.system('apachectl restart | apache2ctl restart')
|
||||
@@ -1,41 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
sys.path.append(os.path.join(os.path.split(__file__)[0],'..'))
|
||||
from gluon.html import CODE
|
||||
|
||||
def main(path):
|
||||
models = glob.glob(os.path.join(path,'models','*.py'))
|
||||
controllers = glob.glob(os.path.join(path,'controllers','*.py'))
|
||||
views = glob.glob(os.path.join(path,'views','*.html'))
|
||||
modules = glob.glob(os.path.join(path,'modules','*.py'))
|
||||
models.sort()
|
||||
controllers.sort()
|
||||
views.sort()
|
||||
modules.sort()
|
||||
print '<html><body>'
|
||||
print '<h1>Models</h1>'
|
||||
for filename in models:
|
||||
print '<h2>%s</h2>' % filename[len(path):]
|
||||
print CODE(open(filename).read(),language='web2py').xml()
|
||||
print '<h1>Layout Views</h1>'
|
||||
for filename in views:
|
||||
print '<h2>%s</h2>' % filename[len(path):]
|
||||
print CODE(open(filename).read(),language='html').xml()
|
||||
print '<h1>Controllers and Views</h1>'
|
||||
for filename in controllers:
|
||||
print '<h2>%s</h2>' % filename[len(path):]
|
||||
print CODE(open(filename).read(),language='web2py')
|
||||
views = glob.glob(os.path.join(path,'views','*','*.html'))
|
||||
views.sort()
|
||||
for filename in views:
|
||||
print '<h2>%s</h2>' % filename[len(path):]
|
||||
print CODE(open(filename).read(),language='html').xml()
|
||||
print '<h1>Modules</h1>'
|
||||
for filename in modules:
|
||||
print '<h2>%s</h2>' % filename[len(path):]
|
||||
print CODE(open(filename).read(),language='python').xml()
|
||||
print '</body></html>'
|
||||
|
||||
if __name__=='__main__':
|
||||
main(sys.argv[1])
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
## launch with python web2py.py -S myapp -R scripts/zip_static_files.py
|
||||
|
||||
|
||||
import os
|
||||
import gzip
|
||||
|
||||
|
||||
def zip_static(filelist=[]):
|
||||
tsave = 0
|
||||
for fi in filelist:
|
||||
extension = os.path.splitext(fi)
|
||||
extension = len(extension) > 1 and extension[1] or None
|
||||
if not extension or extension not in ALLOWED_EXTS:
|
||||
print 'skipping %s' % os.path.basename(fi)
|
||||
continue
|
||||
fstats = os.stat(fi)
|
||||
atime, mtime = fstats.st_atime, fstats.st_mtime
|
||||
gfi = fi + '.gz'
|
||||
if os.path.isfile(gfi):
|
||||
zstats = os.stat(gfi)
|
||||
zatime, zmtime = zstats.st_atime, zstats.st_mtime
|
||||
if zatime == atime and zmtime == mtime:
|
||||
print 'skipping %s, already gzipped to the latest version' % os.path.basename(fi)
|
||||
continue
|
||||
print 'gzipping %s to %s' % (
|
||||
os.path.basename(fi), os.path.basename(gfi))
|
||||
f_in = open(fi, 'rb')
|
||||
f_out = gzip.open(gfi, 'wb')
|
||||
f_out.writelines(f_in)
|
||||
f_out.close()
|
||||
f_in.close()
|
||||
os.utime(gfi, (atime, mtime))
|
||||
saved = fstats.st_size - os.stat(gfi).st_size
|
||||
tsave += saved
|
||||
|
||||
print 'saved %s KB' % (int(tsave) / 1000.0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
ALLOWED_EXTS = ['.css', '.js']
|
||||
static_path = os.path.abspath(os.path.join(request.folder, 'static'))
|
||||
filelist = []
|
||||
for root, dir, files in os.walk(static_path):
|
||||
for file in files:
|
||||
filelist.append(os.path.join(root, file))
|
||||
|
||||
zip_static(filelist)
|
||||
Reference in New Issue
Block a user