#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#    This file is part of arena.
#
#    arena is free software: you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the
#    Free Software Foundation; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
#    License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with arena.  If not, see <http://www.gnu.org/licenses/>.

## @file
#  This file defines settings that affect how arena will work on your site.

import hashlib, time, random

## This class defines global options that affect how arena will work on
#  your site.
class Site:
    # General settings ---------------------------------------------------------
    ## The name of the site
    name = "my site"
    ## The e-mail address of the site administrator
    administrator = "administrator@mysite.com"
    ## The paths to the default icon for the site
    icon = {
        ## The favicon
        "small": "/media/icons/site/logo-small.png",
        ## The icon displayed in the sidebar
        "large": "/media/icons/site/logo3.png"
    }
    ## The default footer used if none is provided by the channel being
    #  displayed
    footer = "Powered by arena."
    ## The default language code if none is provided by the channel being
    #  displayed
    language = "en-US"
    
    # Plugin settings ----------------------------------------------------------
    class Plugins:
        ## The path where plugins are stored.
        path = "Plugins"
        
    # Logging settings ---------------------------------------------------------
    class Logging:
        ## Whether or not logging is enabled
        enabled = True
        ## The folder where log files are placed
        folder = "logs"

    # Database settings --------------------------------------------------------
    class Data:
        ## The main data source provider.  This should be either the name of a 
        #  class which is derived from ADataSource, or a tuple of strings where 
        #  the first specifies the name of the Python module in which the data
        #  source class may be found and the second specifes the name of the 
        #  class.
        #
        #  This data source is used to determine the content providers to use
        #  for each "channel" requested by the client.  Content providers may
        #  also make use of this data source, or they may use another.
        provider = "DataSource.MySQL.Databases", "AMySQLDatabase"
        ## Parameters to pass to the data source provider.  These parameters 
        #  will vary, depending upon the data source provider used above.  They
        #  are passed to the provider when an instance of the class is 
        #  constructed.
        parameters = {
            # The host name or address where the data source is located.
            "host": "localhost",
            # The port to use when connecting to the data source
            "port": 3306,
            # The user name to use when connecting to the data source.
            "user": "_web",
            # The database to use after connecting to the data source.
            "database": "_arena"
        }
        ## The password to use when connecting to the data source provider.  You
        #  should change this, since anyone who views the source for arena will 
        #  know that the value below is the default password value.  For the 
        #  love of all that is holy, do NOT set up your database such that this 
        #  password is the one used!
        password = "password"
        
    # Content settings ---------------------------------------------------------
    class Channels:
        ## The name of the data source category used to store content provider 
        #  information (only change this if you know what you are doing!)
        category = "channels"
        ## The URI query key that is used to specify a channel to load.
        uriQueryKey = "channel"
        
        ## The name of the default channel, if none is requested by the client
        default = "home"
        
        ## The name of the channel used for user authentication; this
        #  channel should specify a content provider that is capable of 
        #  authenticating a user
        authentication = "$site/user/login"
        
        ## The name of the channel used to manage attachments; users must have
        #  a subscription to this channel which allows posting in order to
        #  upload attachments
        attachments = "$site/attach"

    # View settings ------------------------------------------------------------
    class Views:
        ## The path where views can be found
        path = "views"
        ## Whether view output should be cached
        cache = True
        
        ## The URI query key that is used to specify a view provider
        uriProviderQueryKey = "viewProvider"
        
        ## Whether or not Apache's rewrite rules are being used to produce
        #  "clean" URLs (URLs that appear to be paths instead of query strings).
        #  If this value is set to 'True', clean URLs will be generated by the
        #  arena view providers.
        cleanURLs = True
        
        class Error:
            ## The name of the view provider to use for error messages
            provider = "View.PerUser.Arena.Views", "AnArenaView"
            ## Parameters to pass to the view provider
            parameters = {
                "view": "error"
            }

    # Session settings ---------------------------------------------------------
    class Sessions:
        ## The name of the database table used to store session information
        #  (only change this if you know what you are doing!)
        category = "sessions"
        ## The length of time, in seconds, alotted to anonymous visitor sessions
        #  before they expire
        visitorLength = 24 * 60 * 60   # 24 hours
        ## The length of time, in seconds, alotted to authenticated user
        #  sessions before they expire (which will require the user to log in
        #  again)
        userLength = 15 * 60             # 15 minutes
        ## Whether or not user sessions are renewed by activity (this means
        #  that, as long as the user is active on the site within the above time
        #  frame, they will not have to log in again)
        userRenew = True
        ## The odds of running garbage collection on the sessions table.  A
        #  value of 100 (the default) means that, on average, every hundredth
        #  session will begin with a purge of expired session records from the
        #  table.  Since this value is fed to a random number generator, these
        #  odds are only approximate.
        cleanup = 25
        ## The function used to generate session IDs (the MD5 hash value of the
        #  number of seconds since the epoch added to a random fractional
        #  variant).  The function returned by this function should ensure a 
        #  unique session ID; it will be assigned to ASession.identifier, and 
        #  will become the function used to generate new session IDs when they 
        #  are required.  
        @staticmethod
        def identifier():
            return lambda: hashlib.md5(str(time.time() + \
              random.uniform(0, 0.09))).hexdigest()
        
        ## Whether or not to store the session ID in a cookie or assume that it
        #  will be passed as a parameter on the request line
        inCookie = True
        ## The name of the cookie or request parameter used to store the session 
        #  ID
        cookieName = "sid"

    # User settings ------------------------------------------------------------
    class Users:
        ## The name of the database table used to store user information (only
        #  change this if you know what are you doing!)
        category = "users"
        ## The name of the account to use for anonymous site visitors
        anonymous = "visitor"
        ## The name of an administrative account which can never be locked out.
        #  Be certain this account has a STRONG password.
        administrator = "administrator"
        ## The maximum length of time, in seconds between login attempts (in 
        ## other words, how much time can pass between entering a user name and 
        ## a password before the user name must be entered again)
        loginDelayMaximum = 60
        ## The number of failed login attempts before a user account is locked
        lockThreshold = 4
        ## Whether to log the IP addresses of users
        logIP = True

    # Group settings -----------------------------------------------------------
    class Groups:
        ## The name of the database table used to store group information (only
        #  change this if you know what you are doing!)
        category = "user2group"

    # Subscription settings ----------------------------------------------------
    class Subscriptions:
        ## The name of the database table used to store subscription information
        #  (only change this if you know what you are doing!)
        category = "subscriptions"
                
    # Post settings ------------------------------------------------------------
    class Posts:
        ## The category (or table name) where new posts are placed.
        category = "posts"
        
        ## The URI query key that is used to specify a post title to display
        uriTitleQueryKey = "title"
        
        ## Attributes allowed for Markdown-style link and image statements.  
        #  arena extends Markdown to allow reference-style Markdown statements
        #  to specify additional attributes, such as width and height, that
        #  are attached to the HTML tag when the Markdown text is rendered.
        #  Any attribute that is NOT in this list is ignored.  It is probably
        #  a good idea to leave out Javscript event attributes, in order to
        #  prevent a malicious user from inserting Javascript code into a post.
        allowedAttributes = "width", "height", "style"

    # Attachment settings --------------------------------------------------
    class Attachments:
        ## The name of the database table used to store attachment
        #  information (only change this if you know what you are doing!)
        category = "attachments"
        ## Whether or not attachments are allowed
        allowed = True
        ## The maximum size of an attachment, in bytes (2 MB default)
        sizeLimit = 2 * 1024 * 1024
        ## Where attachments are stored on the file system
        storage = {
            "local": "/home/michael/Public/media/attachments",
            "client": "/media/attachments"
        }
        ## Where attachments are temporarily stored (this string is appended 
        #  to the value above unless it begins with a "/")
        tempStorage = "temp"

    # Statistics settings ------------------------------------------------------
    class Statistics:
        ## The name of the database table used to store site statistics (only
        #  change this if you know what you are doing!)
        category = "statistics"
        ## Whether or not to track site statistics
        tracking = True

        ## Which statistics to track
        tracked = [
          "view/last-render-time",    # How long it took to render the last view
          "view/render-time"          # How long it takes to render a view
        ]
