Browse Source

Added check_setup() to app.py (checks required permissions, then shows first time setup), and added more required files

simple_install
dequis 8 years ago
parent
commit
d2bbb7d144
17 changed files with 761 additions and 32 deletions
  1. +4
    -22
      INSTALL
  2. +36
    -1
      app.py
  3. +13
    -0
      board.py
  4. +2
    -1
      config_defaults.py
  5. +186
    -0
      include/boards/css/burichan.css
  6. +155
    -0
      include/boards/css/futaba.css
  7. +138
    -0
      include/boards/css/gurochan.css
  8. +194
    -0
      include/boards/css/photon.css
  9. BIN
      include/boards/locked.gif
  10. BIN
      include/boards/sticky.gif
  11. +1
    -0
      model.py
  12. +0
    -0
      spam.txt
  13. +6
    -0
      templates/boards/footer.html
  14. +0
    -0
      templates/boards/header.html
  15. +2
    -2
      templates/normal_foot_include.html
  16. +2
    -2
      templates/normal_head_include.html
  17. +22
    -4
      wakarimasen.py

+ 4
- 22
INSTALL View File

@@ -1,34 +1,24 @@
Wakarimasen installation guide.

TODO: turn this into a script.
Wakarimasen is still experimental software - use it at your own risk and
if you know how to fix stuff when it breaks.


- Requirements: python2.6, werkzeug, sqlalchemy, jinja2
Fastcgi is highly recommended, but cgi is supported.

- Copy/create a few extra files needed for templates and other stuff:

mkdir -p templates/include/boards/
cp /path/to/wakaba/include/* templates/include/boards/
mkdir -p include/common/css
cp /path/to/wakaba/board/css/* include/common/css
touch spam.txt

- Copy config.py.example to config.py. Edit it and set ADMIN_PASS, SECRET and
SQL_ENGINE. The format for SQL_ENGINE is the following:
SQL_ENGINE. The format for SQL_ENGINE is the following:

SQL_ENGINE = 'mysql://USERNAME:PASSWORD@HOSTNAME/DATABASE'

- Now make sure the shebang line in wakarimasen.py points to the right
python interpreter. If you use suexec for cgi, it must be chmod 755, too.
python interpreter and that the file has execute permissions. If you use suexec
for cgi, it must be chmod 755, too.
Visit

http://example.com/wakarimasen.py

You should get a board not found WakaError. That means cgi is working.
Adding fastcgi support is explained later.
This should open the first time setup page. Enter the ADMIN_PASS here.

- To create a new board called /temp/, copy the base_board directory:

@@ -44,12 +34,4 @@ this to your .htaccess (apache only)

DirectoryIndex wakaba.html

Or .xhtml if you haven't changed PAGE_EXT. You might want to add additional
filenames after wakaba.html (like index.html, index.php, etc) if you put this
.htaccess in the site root. You can also put that htaccess on each individual
board.

- Edit the menu in templates/include/boards/header.html and other templates
as you please.

- Enjoy

+ 36
- 1
app.py View File

@@ -7,7 +7,7 @@ from template import Template
from util import WakaError
from staff_interface import StaffInterface
from staff_tasks import StaffAction
from board import Board
from board import Board, NoBoard
from misc import get_cookie_from_request, kwargs_from_params

def no_task(environ, start_response):
@@ -692,3 +692,38 @@ def not_found(environ, start_response):
start_response('302 Found',
[('Location', MAIN_SITE_URL + environ['PATH_INFO'])])
return []

# Initial setup

def check_setup(environ, start_response):
import os, config
from template import TEMPLATES_DIR

issues = []

if ('DOCUMENT_ROOT' not in environ or 'SCRIPT_NAME' not in environ or
'SERVER_NAME' not in environ):
return ["CGI environment not complete\n"]

full_board_dir = os.path.join(environ['DOCUMENT_ROOT'], config.BOARD_DIR)
if not os.access(full_board_dir, os.W_OK):
issues.append("No write access to DOCUMENT_ROOT+BOARD_DIR (%s)" %
full_board_dir)

script_name_dir = os.path.join(environ['DOCUMENT_ROOT'],
os.path.dirname(environ['SCRIPT_NAME']).lstrip("/"))
if not os.access(script_name_dir, os.W_OK):
issues.append("No write access to DOCUMENT_ROOT+SCRIPT_NAME dir (%s)" %
script_name_dir)

templates_dir = os.path.abspath(TEMPLATES_DIR)
if not os.access(templates_dir, os.W_OK):
issues.append("No write access to templates dir (%s)" % templates_dir)

if issues:
return ["<p>Setup issues found:</p> <ul>"] + \
["<li>%s</li>\n" % x for x in issues] + ["</ul>"]
elif model.Session().query(model.account).count() == 0:
return Template("first_time_setup")
else:
return ["Nothing to do."]

+ 13
- 0
board.py View File

@@ -1706,6 +1706,19 @@ class Board(object):
pub_date=misc.make_date(time.time(), 'http'))\
.render_to_file(rss_file)

class NoOptions(object):
FAVICON = ''

class NoBoard(object):
'''Object that provides the minimal attributes to use a few templates
when no board is defined.'''
name = ''
path = ''
options = NoOptions()

def expand_url(self, url, force_http=False):
return url

# utility functions

def get_page_count(threads, per_page):


+ 2
- 1
config_defaults.py View File

@@ -24,7 +24,8 @@ CHARSET = 'utf-8'
CONVERT_CHARSETS = 1
PAGE_EXT = '.html'
HTACCESS_PATH = './'
WAKABA_VERSION = '3.0.7 + desuchan'
WAKABA_VERSION = ''
WAKARIMASEN_VERSION = '' # we should put something here
ALTERNATE_REDIRECT = 0

SPAM_FILES = ['spam.txt']


+ 186
- 0
include/boards/css/burichan.css View File

@@ -0,0 +1,186 @@
html, body {
font-size:12pt;
background:#EEF2FF;
color:#000000;
}
a {
background:inherit;
color:#34345C;
text-decoration:none;
font-family:sans-serif;
}
a:visited {
background:inherit;
color:#34345C;
text-decoration:none;
font-family:sans-serif;
}
a:hover {
color:#DD0000;
background:inherit;
text-decoration:underline;
font-family:sans-serif;
}
.adminbar {
text-align:right;
background:inherit;
clear:both;
float:right;
}
.logo {
clear:both;
text-align:center;
background:inherit;
font-size:24pt;
color:#AF0A0F;
width:100%;
}
.theader {
background:#0010E0;
color:#FFFFFF;
width:100%;
}
.postarea {
background:inherit;
}
.rules {
font-size:10px;
font-family:sans-serif;
}
.postblock {
background:#9988EE;
color:#000000;
font-weight:800;
}
.footer {
text-align:center;
font-size:10px;
font-family:sans-serif;
}
.passvalid {
background:#9988EE;
text-align:center;
width:100%;
color:#ffffff;
}
.dellist {
background:inherit;
text-align:center;
}
.delbuttons {
background:inherit;
text-align:center;
padding-bottom:4px;

}
.managehead {
background:#0F8FE1;
color:#000000;
font-family:sans-serif;
font-size:14px;
padding:0px;
}
.postlists {
background:#FFFFFF;
width:100%;
padding:0px;
color:#000000;
}
.row1 {
background:#9AD2F6;
font-family:sans-serif;
font-size:12px;
color:#000000;
}
.row2 {
background:#FFFFFF;
font-family:sans-serif;
font-size:12px;
color:#000000;
}
.unkfunc {
color:#789922;
}
.filesize {
font-size:12px;
font-family:sans-serif;
text-decoration:underline;
padding-left:3em;
}
.filetitle {
background:inherit;
font-size:18px;
font-family:serif;
color:#0F0C5D;
font-weight:800;
}
.postername {
background:inherit;
font-size:16px;
font-family:serif;
color:#117743;
font-weight:800;
}
.oldpost {
background:inherit;
font-size:18px;
font-family:serif;
color:#0F0C5D;
font-weight:800;
}
.omittedposts {
background:inherit;
font-size:18px;
font-family:serif;
color:#070707;
font-weight:800;
}
.reply {
background:#D6DAF0;
color:#000000;
font-family:serif;
}
.doubledash {
vertical-align:top;
clear:both;
float:left;
}
.replytitle {
background:inherit;
font-size:18px;
font-family:serif;
color:#0F0C5D;
font-weight:800;
}
.commentpostername {
background:inherit;
font-size:16px;
font-family:serif;
color:#117743;
font-weight:800;
}
.thumbnailmsg {
background:inherit;
font-size:9px;
font-family:sans-serif;
color:#000000;
}

/* Desuchan Page Header */
div.page_header, div#futaba_style_header {margin-bottom:0.5em}
div.page_header {font-family: sans-serif; font-size:75%}
div#futaba_style_header {font-size:85%}
div.page_header #menu_title {display:inline;float:left;padding-right:3em;padding-left:3px;}
div.page_header #menu_title a:hover {background:inherit;color:red}
div.page_header a, div#futaba_style_header a {color: #34345C;text-decoration: none;}
div.page_header a:hover, div#futaba_style_header a:hover {color: #000000; background: #C6DAF0;}
div.page_header ul ul {display: none; background: #D6DAF0}
div.page_header ul {margin:0; padding:0; list-style:none}
div.page_header ul li {float:left; width:13em; text-align:left; background: #D6DAF0;}
div.page_header ul.show, div.page_header ul li:hover ul {display: block; position: absolute; width:13em; z-index:1000;}
div.page_header ul li {display: block; background: #D6DAF0}
div.page_header li a {display: block }
div.page_header ul li {font-weight: bold; text-align: left; padding-left:5px}
div.page_header ul li ul {border:1px solid #000000;margin-left:-5px;padding-right:5px}
div.page_header ul li ul li {font-weight: normal; text-align:left; position:relative;}
div.page_header ul li ul li:hover { background: #C6DAF0; }

+ 155
- 0
include/boards/css/futaba.css View File

@@ -0,0 +1,155 @@
html, body {
background:#FFFFEE;
color:#800000;
}
a {
color:#0000EE;
}
a:hover {
color:#DD0000;
}
.adminbar {
text-align:right;
clear:both;
float:right;
}
.logo {
clear:both;
text-align:center;
font-size:2em;
color:#800000;
width:100%;
}
.theader {
background:#E04000;
text-align:center;
padding:2px;
color:#FFFFFF;
width:100%;
}
.postarea {
}
.rules {
font-size:0.7em;
}
.postblock {
background:#EEAA88;
color:#800000;
font-weight:800;
}
.footer {
text-align:center;
font-size:12px;
font-family:serif;
}
.passvalid {
background:#EEAA88;
text-align:center;
width:100%;
color:#ffffff;
}
.dellist {
font-weight: bold;
text-align:center;
}
.delbuttons {
text-align:center;
padding-bottom:4px;

}
.managehead {
background:#AAAA66;
color:#400000;
padding:0px;
}
.postlists {
background:#FFFFFF;
width:100%;
padding:0px;
color:#800000;
}
.row1 {
background:#EEEECC;
color:#800000;
}
.row2 {
background:#DDDDAA;
color:#800000;
}
.unkfunc {
background:inert;
color:#789922;
}
.filesize {
text-decoration:none;
}
.filetitle {
background:inherit;
font-size:1.2em;
color:#CC1105;
font-weight:800;
}
.postername {
color:#117743;
font-weight:bold;
}
.postertrip {
color:#228854;
}
.oldpost {
color:#CC1105;
font-weight:800;
}
.omittedposts {
color:#707070;
}
.reply {
background:#F0E0D6;
color:#800000;
}
.doubledash {
vertical-align:top;
clear:both;
float:left;
}
.replytitle {
font-size: 1.2em;
color:#CC1105;
font-weight:800;
}
.commentpostername {
color:#117743;
font-weight:800;
}
.thumbnailmsg {
font-size: small;
color:#800000;
}



.abbrev {
color:#707070;
}
.highlight {
background:#F0E0D6;
color:#800000;
border: 2px dashed #EEAA88;
}

/* Desuchan Page Header */
div.page_header, div#futaba_style_header {margin-bottom:0.5em}
div.page_header {font-family: sans-serif; font-size:75%}
div#futaba_style_header {font-size:85%}
div.page_header a, div#futaba_style_header a {color: #34345C;text-decoration: none;}
div.page_header a:hover, div#futaba_style_header a:hover {color: #000000; background: #C6DAF0;}
div.page_header ul ul {display: none; background: #D6DAF0}
div.page_header ul {margin:0; padding:0; list-style:none}
div.page_header ul li {float:left; width:13em; text-align:left; background: #D6DAF0;}
div.page_header ul.show, div.page_header ul li:hover ul {display: block; position: absolute; width:13em; z-index:1000;}
div.page_header ul li {display: block; background: #D6DAF0}
div.page_header li a {display: block }
div.page_header ul li {font-weight: bold; text-align: left; padding-left:5px}
div.page_header ul li ul {border:1px solid #000000;margin-left:-5px;padding-right:5px}
div.page_header ul li ul li {font-weight: normal; text-align:left; position:relative;}
div.page_header ul li ul li:hover { background: #C6DAF0; }

+ 138
- 0
include/boards/css/gurochan.css View File

@@ -0,0 +1,138 @@
html, body {
font-size:10pt;
background:#EDDAD2;
color:#000000;
}
* {
font-family: "Trebuchet MS", Tahoma, Verdana, Arial, sans-serif;
font-size: 10pt;
}
input, textarea {
background-color: #E6CBC0;
border: 1px solid #CA927B;
}
a {
background:inherit;
color:#34345C;
}
a:visited {
background:inherit;
color:#34345C;
}
a:hover {
color:#DD0000;
background:inherit;
}
a.quotelink {
background:inherit;
color:#DD0000;
}
.logo {
clear:both;
text-align:center;
background:inherit;
font-size:24pt;
color:#AF0A0F;
width:100%;
}
.postarea {
background:inherit;
}
.postblock {
background: #D9AF9E;
border: 1px solid #CA927B;
color: black;
font-weight: bold;
padding: 2px 5px 2px 5px;
}
.footer {
text-align:center;
font-size:12px;
}
.unkfunc {
background:inert;
color:#789922;
}
.filesize {
text-decoration:none;
}
.filetitle {
background:inherit;
color:#0F0C5D;
font-weight:800;
}
.postername {
background:inherit;
font-size:11pt;
color:#117743;
font-weight: bold;
}
.postertrip {
background:inherit;
color:#228854;
}
.oldpost {
background:inherit;
color:#0F0C5D;
font-weight:800;
}
.omittedposts {
background:inherit;
color:#070707;
}
.reply {
background:#D9AF9E;
color:#000000;
border:1px solid #CA927B;
}
.replyhl {
background:#D6BAD0;
color:#000000;
}
.doubledash {
vertical-align:top;
clear:both;
float:left;
}
.replytitle {
background:inherit;
font-size:18px;
color:#0F0C5D;
font-weight:800;
}
.commentpostername {
background:inherit;
font-size:11pt;
color:#117743;
font-weight: bold;
}
a.quotejs {
color:#000000;
text-decoration: none;
}
a.quotejs:hover {
font-weight:bold;
}

.adminbar {
text-align: center;
}

/* Desuchan Page Header */
div.page_header, div#futaba_style_header {margin-bottom:0.5em}
div.page_header {font-family: sans-serif; font-size:75%}
div#futaba_style_header {font-size:85%}
div.page_header #menu_title {display:inline;float:left;padding-right:3em;padding-left:3px;}
div.page_header #menu_title a:hover {background:inherit;color:red}
div.page_header a, div#futaba_style_header a {color: #34345C;text-decoration: none;}
div.page_header a:hover, div#futaba_style_header a:hover {color: #000000; background: #C6DAF0;}
div.page_header ul ul {display: none; background: #D6DAF0}
div.page_header ul {margin:0; padding:0; list-style:none}
div.page_header ul li {float:left; width:13em; text-align:left; background: #D6DAF0;}
div.page_header ul.show, div.page_header ul li:hover ul {display: block; position: absolute; width:13em; z-index:1000;}
div.page_header ul li {display: block; background: #D6DAF0}
div.page_header li a {display: block }
div.page_header ul li {font-weight: bold; text-align: left; padding-left:5px}
div.page_header ul li ul {border:1px solid #000000;margin-left:-5px;padding-right:5px}
div.page_header ul li ul li {font-weight: normal; text-align:left; position:relative;}
div.page_header ul li ul li:hover { background: #C6DAF0; }

+ 194
- 0
include/boards/css/photon.css View File

@@ -0,0 +1,194 @@
html, body {
background-color: #EEEEEE;
color: #333333;
font-family: "Trebuchet MS",Trebuchet,serif;
}
a {
color: #FF6600;
}
a:hover {
color: #0066FF;
}
.adminbar {
clear:both;
float:right;
font-size: .8em;
}
.adminbar a {
font-weight: bold;
}
.logo {
clear:both;
text-align:left;
font-size:2em;
font-weight: bold;
color:#FF6600;
/*width:100%;*/
}
.theader, .passvalid {
background:#DDDDDD;
text-align:center;
padding:2px;
color:#2266AA;
clear: both;
font-weight: bold;
margin-bottom: .5em;
border: solid 1px #CCCCCC;
-moz-border-radius: 5px;
}
.postarea {
}
.rules {
font-size:0.7em;
}
.postblock {
background:transparent;
color:#002244;
font-weight:bold;
}
.footer {
text-align:center;
font-size:12px;
font-family:serif;
margin: 2em 0 0 0;
}
.dellist {
font-weight: bold;
text-align:center;
}
.delbuttons {
text-align:center;
padding-bottom:4px;
}
.managehead {
background:#DDDDDD;
color:#002244;
padding:0px;
}
.postlists {
background:#FFFFFF;
width:100%;
padding:0px;
color:#800000;
}
.row1 {
background:#DDDDDD;
color:#002244;
}
.row2 {
background:#CCCCCC;
color:#002244;
}
.unkfunc {
background:inherit;
color:#789922;
}
.reflink {
font-size: .8em;
font-weight: bold;
}
.filesize {
text-decoration:none;
color: #666666;
font-size: .8em;
}
.filetitle {
background:inherit;
font-size:1.2em;
color:#002244;
font-weight:bold;
}
.postername {
color:#004A99;
font-weight:bold;
}
.postertrip {
color:#FF3300;
}
.oldpost {
color:#CC1105;
font-weight:bold;
}
.omittedposts {
color:#666666;
}
.reply {
background:#DDDDDD;
border: solid 1px #CCCCCC;
padding: 0;
margin: 0;
-moz-border-radius: 5px;
}
blockquote {
margin: .5em .5em .5em 1em;
}
blockquote p {
margin: 0;
padding: 0;
}
.reply blockquote {
margin: .5em;
}
.doubledash {
display: none;
vertical-align:top;
clear:both;
float:left;
}
.replytitle {
font-size: 1.2em;
color:#002244;
font-weight:bold;
}
.commentpostername {
color:#004A99;
font-weight:800;
}
.thumbnailmsg {
font-size: .8em;
color:#666666;
}
hr {
border-style: solid none none none;
border-width: 1px;
border-color: #BBBBBB;
}
table {
border-style: none;
}
table td {
border-style: none;
}
.nothumb {
background-color: #FFFFFF;
border-style: dotted;
margin: .3em .5em;
}

.abbrev {
color:#666666;
}
.highlight {
background:#EEDACB;
color:#333333;
border: 2px dashed #EE6600;
}

/* Desuchan Page Header */
div.page_header, div#futaba_style_header {margin-bottom:0.5em}
div.page_header {font-family: sans-serif; font-size:75%}
div#futaba_style_header {font-size:85%}
div.page_header #menu_title {display:inline;float:left;padding-right:3em;padding-left:3px;}
div.page_header #menu_title a:hover {background:inherit;color:red}
div.page_header a, div#futaba_style_header a {color: #34345C;text-decoration: none;}
div.page_header a:hover, div#futaba_style_header a:hover {color: #000000; background: #C6DAF0;}
div.page_header ul ul {display: none; background: #D6DAF0}
div.page_header ul {margin:0; padding:0; list-style:none}
div.page_header ul li {float:left; width:13em; text-align:left; background: #D6DAF0;}
div.page_header ul.show, div.page_header ul li:hover ul {display: block; position: absolute; width:13em; z-index:1000;}
div.page_header ul li {display: block; background: #D6DAF0}
div.page_header li a {display: block }
div.page_header ul li {font-weight: bold; text-align: left; padding-left:5px}
div.page_header ul li ul {border:1px solid #000000;margin-left:-5px;padding-right:5px}
div.page_header ul li ul li {font-weight: normal; text-align:left; position:relative;}
div.page_header ul li ul li:hover { background: #C6DAF0; }

BIN
include/boards/locked.gif View File

Before After
Width: 45  |  Height: 27  |  Size: 1.4 KiB

BIN
include/boards/sticky.gif View File

Before After
Width: 23  |  Height: 24  |  Size: 773 B

+ 1
- 0
model.py View File

@@ -4,6 +4,7 @@ from sqlalchemy import Table, Column, Integer, Text, String, MetaData, Boolean
from sqlalchemy.orm import sessionmaker, mapper, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func
from sqlalchemy.exc import OperationalError

engine = create_engine(config.SQL_ENGINE, pool_size=100, max_overflow=10)
Session = scoped_session(sessionmaker(bind=engine))


+ 0
- 0
spam.txt View File


+ 6
- 0
templates/boards/footer.html View File

@@ -0,0 +1,6 @@
<p class="footer">
- <a href="http://desuchan.net/">wakarimasen</a>
+ <a href="http://wakaba.c3.cx/">wakaba</a>
+ <a href="http://www.2chan.net/">futaba</a>
+ <a href="http://www.1chan.net/futallaby/">futallaby</a>
-</p>

+ 0
- 0
templates/boards/header.html View File


+ 2
- 2
templates/normal_foot_include.html View File

@@ -1,2 +1,2 @@
{% include 'include/boards/footer.html' %}
</body></html>
{% include 'boards/footer.html' %}
</body></html>

+ 2
- 2
templates/normal_head_include.html View File

@@ -40,7 +40,7 @@
{% if thread %}<body class="replypage">{% endif %}
{% if not thread %}<body>{% endif %}

{% include 'include/boards/header.html' %}
{% include 'boards/header.html' %}

<div class="adminbar">
{% for stylesheet in stylesheets %}
@@ -57,4 +57,4 @@
{% if board.options.SHOWTITLEIMG == 2 %}<img src="{{ (board.options.TITLEIMG)|expand_url }}" onclick="this.src=this.src;" alt="{{ board.options.TITLE }}" />{% endif %}
{% if board.options.SHOWTITLEIMG and board.options.SHOWTITLETXT %}<br />{% endif %}
{% if board.options.SHOWTITLETXT %}{{ board.options.TITLE }}{% endif %}
</div><hr />
</div><hr />

+ 22
- 4
wakarimasen.py View File

@@ -13,24 +13,36 @@ import util
import model
import board
import interboard
from board import Board
from board import Board, NoBoard
from util import WakaError, local

@util.headers
def application(environ, start_response):
'''Main routing application'''

local.environ = environ
request = werkzeug.BaseRequest(environ)

task = request.values.get('task', request.values.get('action', ''))
boardname = request.values.get('board', '9001') # temp. default value
boardname = request.values.get('board', '')


environ['waka.task'] = task
environ['waka.boardname'] = boardname
# Indicate "pop-up window" UI style.
environ['waka.fromwindow'] = False
environ['waka.rootpath'] = os.path.join('/', config.BOARD_DIR, '')
environ['waka.board'] = Board(boardname)

if not task and not boardname:
environ['waka.board'] = NoBoard()
return app.check_setup(environ, start_response)

try:
if not boardname:
raise WakaError("No board parameter set")
environ['waka.board'] = Board(boardname)
except WakaError, e:
return app.fffffff(environ, start_response, e)

# the task function if it exists, otherwise no_task()
function = getattr(app, 'task_%s' % task.lower(), app.no_task)
@@ -56,8 +68,14 @@ def main():
# Set up tentative environment variables.
local.environ['waka.rootpath'] \
= os.path.join('/', config.BOARD_DIR, '')
try:
app.init_database()
except model.OperationalError, e:
# CGI-friendly error message
print "Content-Type: text/plain\n"
print "Error initializing database: %s" % e.args[0]
return

app.init_database()
arg = sys.argv[1:] and sys.argv[1] or 'fcgi'
if arg == 'fcgi':
fcgi.WSGIServer(application).run()


Loading…
Cancel
Save