Project

General

Profile

Setup And Install

Below are instructions for how to run your own instance of TextCritical.

Install Prerequisites

To run TextCritical, you will need:

You might want to setup a virtual environment to run the app in:

cd ~/venv/
virtualenv textcritical

You can install django, lxml, Genshi and Grappelli by running the build script target "install_dependencies":

ant install_dependencies

To install KindleGen, install the kindlgegen binary in your path such as /usr/local/bin. You can get it using wget:

wget http://kindlegen.s3.amazonaws.com/kindlegen_linux_2.6_i386_v2_9.tar.gz

Install TextCritical App Code

Check out the source code from https://github.com/LukeMurphey/textcritical_net

Copy start_here_settings.py to settings.py (under the src directory). Update the settings.py file per your host.

Configure and Initialize Database

Specify a database in settings.py unless you intend to use SQLite.

After configuring the database, initialize the database (from the src directory):

python .\manage.py makemigrations
python .\manage.py migrate

Import Works

You will need to import the works into the library in order to have something for the site to provide access to. The easy way to do this is to use a prebuilt library. The more difficult way is to import the works yourself.

Using Existing Library

To use an existing library, copy the library.sqlite file to the server. By default, it should be placed in the src directory.

Importing Works

If you want to import works manually, then following the steps below.

First, initialize the library database.

python manage.py migrate --database library
python manage.py migrate --database textcritical

Next, download the relevant works. The Perseus works can be obtained from Perseus.tufts.edu. Make sure to get the classics library. Decompress the archive.

Start the import process by running the following command, substituting "/Users/Luke/Perseus_Directory" with the location where you placed the files:

python manage.py batch_import_perseus -d "/Users/Luke/Perseus_Directory" 

The import process may take a while (it takes about 70 minutes on a Core i7 with 8 GB of RAM). Make sure to set DEBUG to False before running the import. Otherwise, memory consumption will grow until the import completes.

Indexing Works

You'll need to index the works for the search engine to work properly.

After importing the works, run the following:

python manage.py make_search_indexes -c

Start Web Server

For production installs, you ought to use a production web-server like Apache. For development, you can use the built in Django web-server:

python manage.py runserver 0.0.0.0:8080

Alternatively, you can use the included CherryPy server which should be good enough for production use. To use it, start "run_server.py" after setting WEB_SERVER_ADDRESS and WEB_SERVER_PORT in settings.py; example below:

# The address and port to use when using the built-in web-server
WEB_SERVER_ADDRESS = '0.0.0.0' # Use '127.0.0.1' to serve content to localhost only
WEB_SERVER_PORT    = 8080

You can use lighttpd to serve as a reverse proxy to CherryPy. Below is a lighttpd config that will proxy to CherryPy or the Django web-server:

# Define the location of text critical here:
var.textcriticalpath = "/Users/lmurphey/Documents/SP/Workspace/TextCritical.com" 

# This is IP of the web-server:
var.proxyserver = "127.0.0.1" 

# This is the port that Django server is running on:
var.proxyport = 8080

# This is the port to run the web-server on:
var.serverport = 8081

server.modules = ( "mod_proxy" )

$HTTP["url"] !~ "^/media/" {
    proxy.server = ( "" =>
                           ( ( 
                               "host" => var.proxyserver,
                               "port" => var.proxyport
                           ) )
                   )
}

server.document-root = var.textcriticalpath + "/src" 

server.port = var.serverport

mimetype.assign = (
  ".html" => "text/html", 
  ".txt" => "text/plain",
  ".jpg" => "image/jpeg",
  ".png" => "image/png",
  ".css" => "text/css",
  ".js" => "application/javascript"  
)

Upgrading

If you are upgrading an existing install from one of the older versions that supported Django 1.5, then you will need to do several things.

First, install Django 1.8:

pip install Django==1.8.6

Next, migrate the database:

python manage.py migrate
When you upgrade a TextCritical instance, you may need to clear some caches including:
  • The web cache
  • The cache eBooks (in /media/files)

The cache of eBooks can be rebuilt by running the Django commands make_epubs and make_mobi.

Common Setup Issues

Syncdb Fails Saying it couldn't create "django_content_type"

This has something to do with database routing. It can be solved by adding the following to the settings.py file and re-running syncdb:

DATABASE_ROUTING = []

Once syncdb succeeds, delete this line.

Reference: https://code.djangoproject.com/ticket/16039

Syncdb Fails When Creating Superuser

You just installed Django's auth system, which means you don't have any superusers defined.                                                 
Would you like to create one now? (yes/no): yes                                                                                             
Traceback (most recent call last):                                                                                                          
  File "manage.py", line 10, in <module>                                                                                                    
    execute_from_command_line(sys.argv)                                                                                                     
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line                  
    utility.execute()                                                                                                                       
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute                                    
    self.fetch_command(subcommand).run_from_argv(self.argv)                                                                                 
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv                                  
    self.execute(*args, **options.__dict__)                                                                                                 
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute                                        
    output = self.handle(*args, **options)                                                                                                  
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 371, in handle                                         
    return self.handle_noargs(**options)                                                                                                    
  File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 110, in handle_noargs                       
    emit_post_sync_signal(created_models, verbosity, interactive, db)                                                                       
  File "/usr/local/lib/python2.7/site-packages/django/core/management/sql.py", line 189, in emit_post_sync_signal                           
    interactive=interactive, db=db)                                                                                                         
  File "/usr/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 172, in send                                            
    response = receiver(signal=self, sender=sender, **named)                                                                                
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/management/__init__.py", line 73, in create_superuser                    
    call_command("createsuperuser", interactive=True, database=db)                                                                          
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 150, in call_command                               
    return klass.execute(*args, **defaults)                                                                                                 
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute                                        
    output = self.handle(*args, **options)                                                                                                  
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 70, in handle              
    default_username = get_default_username()                                                                                               
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/management/__init__.py", line 105, in get_default_username               
    default_username = get_system_username()                                                                                                
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/management/__init__.py", line 85, in get_system_username                 
    return getpass.getuser().decode(locale.getdefaultlocale()[1])                                                                           
TypeError: decode() argument 1 must be string, not None   

You may need to set your locale by running the following before running syncdb:

export LC_ALL="en_US.UTF-8" 

Delete the auth_users table and do another syncdb to try again.

Reference: https://code.djangoproject.com/ticket/16017

"__init__() keywords must be strings" when running Perseus Importer

This is caused by a known bug in Python 2.6 in which unicode arguments are not handled correctly. Upgrading to Python 2.7 resolves the issue.

Cannot migrate database

If you are on an older database that doesn't already have the migrations table, then you might have issues where you cannot run migrations. That is, the following fails:

python manage.py migrate --database library

You can run the following to flag migration as complete for tables that exist:

python manage.py migrate --fake-initial --database library

It important to recall that each database needs to be migrated individually (see https://strongarm.io/blog/multiple-databases-in-django/).