Commit 866a9680 authored by mitshel's avatar mitshel
Browse files

Небольшой рефакторинг модуля sopdscfg.py и как результат изменения в основных...

Небольшой рефакторинг модуля sopdscfg.py и как результат изменения в основных файлах sopds.cgi и sopds-scan.py.
В sopds-scan.py доступны опции -c --config
parent 70debb8c
Loading
Loading
Loading
Loading
+52 −35
Original line number Diff line number Diff line
@@ -3,18 +3,61 @@

import os
import sopdsdb
import sopdscfg
import sopdsparse
import zipfile
import time
import datetime
import sopdscfg


##########################################################################
# Считываем параметры командной строки
# пример возможных параметров
# sopds-scan.py <--scanfull | --scanlast | --scan | -s> [ [-c <configfile>]
#
# -s, --scan, --scanfull  - Полное пересканирование всех файлов библиотеки (по умолчанию)
# --scanlast              - Обрабатываются только файлы с датой поздней, чем дата последнего сканирования (не сделано)
# -v, --verbose           - Включить вывод отладочной информации
# -c <configfile>         - Указывается путь к файлу конфигурации

from optparse import OptionParser
from sys import argv

t1=datetime.timedelta(seconds=time.time())

parser=OptionParser(conflict_handler="resolve", version="sopds-scan.py. Version 0.01a", add_help_option=True, usage='sopds-scan.py [options]', description='sopds-scan.py: Simple OPDS Scanner - programm for scan your e-books directory and store data to MYSQL database.')
parser.add_option('-s','--scan','--scanfull', action='store_true', dest='scanfull', default=True, help='Full rescan all stored files.')
parser.add_option('-l','--scanlast', action='store_false', dest='scanfull', default=True, help='Scan files from date after last scan.')
parser.add_option('-v','--verbose', action='store_true', dest='verbose', default=False, help='Enable verbose output')
parser.add_option('-c','--config',dest='configfile',default='',help='Config file pargh')
(options,arguments)=parser.parse_args()

SCAN_FULL=options.scanfull
VERBOSE=options.verbose
CFG_FILE=options.configfile

if CFG_FILE=='':
   cfg=sopdscfg.cfgreader()
else:
   cfg=sopdscfg.cfgreader(CFG_FILE)

if VERBOSE:
        print('Options set: scanfull =',SCAN_FULL,', verbose =',VERBOSE,', configfile =',cfg.CONFIGFILE)

#############################################################################
#
# Переменные для сбора статистики
#
books_added   = 0
books_skipped = 0
arch_scanned = 0
arch_skipped = 0
books_in_archives = 0

#############################################################################
#
# Вспомогательные функции
#
def processfile(db,fb2,name,full_path,file,archive=0):
    global books_added
    global books_skipped
@@ -22,7 +65,7 @@ def processfile(db,fb2,name,full_path,file,archive=0):

    (n,e)=os.path.splitext(name)
    if e.lower() in extensions_set:
       rel_path=os.path.relpath(full_path,sopdscfg.ROOT_LIB)
       rel_path=os.path.relpath(full_path,cfg.ROOT_LIB)

       if VERBOSE:
          print("Attempt to add book: ",rel_path," - ",name,"...",end=" ")
@@ -33,12 +76,12 @@ def processfile(db,fb2,name,full_path,file,archive=0):
          title=''
          genre=''
          lang=''
          if e.lower()=='.fb2' and sopdscfg.FB2PARSE:
          if e.lower()=='.fb2' and cfg.FB2PARSE:
             if isinstance(file, str):
                f=open(file,'rb')
             else:
                f=file
             fb2.parse(f,sopdscfg.FB2HSIZE)
             fb2.parse(f,cfg.FB2HSIZE)
             f.close()
             if len(fb2.genre.getvalue())>0:
                genre=fb2.genre.getvalue()[0].strip(' \'\"')
@@ -76,7 +119,7 @@ def processzip(db,fb2,name,full_path,file):
    global arch_scanned
    global arch_skipped

    rel_path=os.path.relpath(full_path,sopdscfg.ROOT_LIB)
    rel_path=os.path.relpath(full_path,cfg.ROOT_LIB)
    if sopdscfg.ZIPRESCAN or db.zipisscanned(rel_path)==0:
       z = zipfile.ZipFile(file, 'r')
       filelist = z.namelist()
@@ -94,53 +137,27 @@ def processzip(db,fb2,name,full_path,file):
       if VERBOSE:
          print('Skip ZIP archive: ',full_path,'. Already scanned.')

##########################################################################
# Считываем параметры командной строки
# пример возможных параметров
# sopds-scan.py <--scanfull | --scanlast | --scan | -s> [ [-c <configfile>]
#
# -s, --scan, --scanfull  - Полное пересканирование всех файлов библиотеки
# --scanlast              - Обрабатываются только файлы с датой поздней, чем дата последнего сканирования
# -v, --verbose           - Включить вывод отладочной информации
# -c <configfile>         - Указывается путь к файлу конфигурации

from optparse import OptionParser
from sys import argv

t1=datetime.timedelta(seconds=time.time())

parser=OptionParser(conflict_handler="resolve", version="sopds-scan.py. Version 0.01a", add_help_option=True, usage='sopds-scan.py [options]', description='sopds-scan.py: Simple OPDS Scanner - programm for scan your books directory and store data to MYSQL database.')
parser.add_option('-s','--scan','--scanfull', action='store_true', dest='scanfull', default=True, help='Full rescan all stored files.')
parser.add_option('-l','--scanlast', action='store_false', dest='scanfull', default=True, help='Scan files from date after last scan.')
parser.add_option('-v','--verbose', action='store_true', dest='verbose', default=False, help='Enable verbose output')
(options,arguments)=parser.parse_args()

SCAN_FULL=options.scanfull
VERBOSE=options.verbose

if VERBOSE:
        print('Options set: scanfull =',SCAN_FULL,', verbose =',VERBOSE,', configfile =',sopdscfg.CFG_PATH)

###########################################################################
# Основной код программы
#
opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
opdsdb.openDB()
if VERBOSE:
   opdsdb.printDBerr()

fb2parser=sopdsparse.fb2parser()

extensions_set={x for x in sopdscfg.EXT_LIST}
extensions_set={x for x in cfg.EXT_LIST}
if VERBOSE:
   print(extensions_set)

for full_path, dirs, files in os.walk(sopdscfg.ROOT_LIB):
for full_path, dirs, files in os.walk(cfg.ROOT_LIB):
  for name in files:
    file=os.path.join(full_path,name)
    (n,e)=os.path.splitext(name)
    if (e.lower() == '.zip'):
       if sopdscfg.ZIPSCAN:
       if cfg.ZIPSCAN:
          processzip(opdsdb,fb2parser,name,full_path,file)
    else:
       processfile(opdsdb,fb2parser,name,full_path,file)
+37 −27
Original line number Diff line number Diff line
@@ -13,6 +13,16 @@ import io
import locale
import time

#######################################################################
#
# Парсим конфигурационный файл
#
cfg=sopdscfg.cfgreader()

#######################################################################
#
# Вспомогательные функции
#
def translit(s):
   """Russian translit: converts 'привет'->'privet'"""
   assert s is not str, "Error: argument MUST be string"
@@ -31,20 +41,20 @@ def header(charset='utf-8'):
   enc_print()
   enc_print('<?xml version="1.0" encoding="'+charset+'"?>')
   enc_print('<feed xmlns="http://www.w3.org/2005/Atom" xmlns:opds="http://opds-spec.org/">')
   enc_print('<id>'+sopdscfg.SITE_ID+'</id>')
   enc_print('<title>'+sopdscfg.SITE_TITLE+'</title>')
   enc_print('<id>'+cfg.SITE_ID+'</id>')
   enc_print('<title>'+cfg.SITE_TITLE+'</title>')
   enc_print('<updated>'+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'</updated>')
   enc_print('<icon>'+sopdscfg.SITE_ICON+'</icon>')
   enc_print('<author><name>'+sopdscfg.SITE_AUTOR+'</name><uri>'+sopdscfg.SITE_URL+'</uri><email>'+sopdscfg.SITE_EMAIL+'</email></author>')
   enc_print('<icon>'+cfg.SITE_ICON+'</icon>')
   enc_print('<author><name>'+cfg.SITE_AUTOR+'</name><uri>'+cfg.SITE_URL+'</uri><email>'+cfg.SITE_EMAIL+'</email></author>')

def footer():
   enc_print('</feed>')

def main_menu():
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   dbinfo=opdsdb.getdbinfo()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="/"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="/"/>')
   enc_print('<entry>')
   enc_print('<title>По каталогам</title>')
   enc_print('<content type="text">Каталогов: %s, книг: %s.</content>'%(dbinfo[2][0],dbinfo[0][0]))
@@ -94,11 +104,11 @@ if type_value==0:
# Выбрана сортировка "По каталогам"
#
elif type_value==1:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="sopds.cgi?id=0"/>')
   for (item_type,item_id,item_name,item_path,reg_date,item_title,item_genre) in opdsdb.getitemsincat(slice_value,sopdscfg.MAXITEMS,page_value):
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="sopds.cgi?id=0"/>')
   for (item_type,item_id,item_name,item_path,reg_date,item_title,item_genre) in opdsdb.getitemsincat(slice_value,cfg.MAXITEMS,page_value):
       if item_type==1:
          id='01'+str(item_id)
       elif item_type==2:
@@ -134,12 +144,12 @@ elif type_value==1:
# Выбрана сортировка "По авторам" - выбор по первой букве автора
#
elif type_value==2:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="sopds.cgi?id=0"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="sopds.cgi?id=0"/>')
   for (letter,cnt) in opdsdb.getauthor_letters():
       if sopdscfg.SPLITAUTHORS==0 or cnt<=sopdscfg.SPLITAUTHORS:
       if cfg.SPLITAUTHORS==0 or cnt<=cfg.SPLITAUTHORS:
          id='05'
       else:
          id='03'
@@ -163,14 +173,14 @@ elif type_value==2:
# Выбрана сортировка "По авторам" - выбор по двум первым буквам автора
#
elif type_value==3:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   if slice_value==0:
      letter=""
   else:
      letter=chr(slice_value)
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   for (letters,cnt) in opdsdb.getauthor_2letters(letter):
       if len(letters)==0:
         id='050000'
@@ -192,10 +202,10 @@ elif type_value==3:
# Выбрана сортировка "По Жанрам"
#
elif type_value==4:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   id='04'
   for (genre,cnt) in opdsdb.getgenres():
       enc_print('<entry>')
@@ -212,7 +222,7 @@ elif type_value==4:
# Выдача списка авторов
#
if type_value==5:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   if slice_value==0:
      letters=""
@@ -221,8 +231,8 @@ if type_value==5:
   else:
      letters=chr(slice_value)
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+sopdscfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   for (author_id,first_name, last_name,cnt) in opdsdb.getauthorsbyl(letters,sopdscfg.MAXITEMS,page_value):
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" title="'+cfg.SITE_MAINTITLE+'" href="sopds.cgi?id=00"/>')
   for (author_id,first_name, last_name,cnt) in opdsdb.getauthorsbyl(letters,cfg.MAXITEMS,page_value):
       id='06'+str(author_id)
       enc_print('<entry>')
       enc_print('<title>'+last_name+' '+first_name+'</title>')
@@ -244,10 +254,10 @@ if type_value==5:
# Выдача списка книг по автору
#
if type_value==6:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   header()
   for (book_id,book_name,book_path,reg_date,book_title,book_genre) in opdsdb.getbooksforautor(slice_value,sopdscfg.MAXITEMS,page_value):
   for (book_id,book_name,book_path,reg_date,book_title,book_genre) in opdsdb.getbooksforautor(slice_value,cfg.MAXITEMS,page_value):
       id='07'+str(book_id)
       enc_print('<entry>')
       enc_print('<title>'+book_title+'</title>')
@@ -279,10 +289,10 @@ if type_value==6:
#
elif type_value==7:
   id='07'+str(slice_value)
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   header()
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" href="sopds.cgi?id=0" title="'+sopdscfg.SITE_MAINTITLE+'"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=navigation" rel="start" href="sopds.cgi?id=0" title="'+cfg.SITE_MAINTITLE+'"/>')
   enc_print('<link type="application/atom+xml;profile=opds-catalog;kind=acquisition" rel="self" href="sopds.cgi?id='+id+'"/>')
   (book_name,book_path,reg_date,format,title,cat_type)=opdsdb.getbook(slice_value)
   id='08'+str(slice_value)
@@ -310,10 +320,10 @@ elif type_value==7:
# Выдача файла книги
#
elif type_value==8:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   (book_name,book_path,reg_date,format,title,cat_type)=opdsdb.getbook(slice_value)
   full_path=os.path.join(sopdscfg.ROOT_LIB,book_path)
   full_path=os.path.join(cfg.ROOT_LIB,book_path)
   transname=translit(book_name)
   # HTTP Header
   enc_print('Content-Type:application/octet-stream; name="'+book_name+'"')
@@ -346,10 +356,10 @@ elif type_value==8:
# Выдача файла книги в ZIP формате
#
elif type_value==9:
   opdsdb=sopdsdb.opdsDatabase(sopdscfg.DB_NAME,sopdscfg.DB_USER,sopdscfg.DB_PASS,sopdscfg.DB_HOST,sopdscfg.ROOT_LIB)
   opdsdb=sopdsdb.opdsDatabase(cfg.DB_NAME,cfg.DB_USER,cfg.DB_PASS,cfg.DB_HOST,cfg.ROOT_LIB)
   opdsdb.openDB()
   (book_name,book_path,reg_date,format,title,cat_type)=opdsdb.getbook(slice_value)
   full_path=os.path.join(sopdscfg.ROOT_LIB,book_path)
   full_path=os.path.join(cfg.ROOT_LIB,book_path)
   transname=translit(book_name)
   # HTTP Header
   enc_print('Content-Type:application/zip; name="'+book_name+'"')
+45 −42
Original line number Diff line number Diff line
@@ -16,50 +16,53 @@ CFG_PATH=CFG_PATH_DEFAULT
###########################################################################
# Считываем конфигурацию из конфигурационного файла
# используем модуль configparser

import configparser

class cfgreader:
   def __init__(self,configfile=CFG_PATH):
       config=configparser.ConfigParser()
       #config.read(CFG_PATH)
config.readfp(codecs.open(CFG_PATH,"r","utf-8"))
       self.CONFIGFILE=configfile
       config.readfp(codecs.open(self.CONFIGFILE,"r","utf-8"))

       CFG_S_GLOBAL='global'
NAME=config.get(CFG_S_GLOBAL,'name')
ROOT_URL=config.get(CFG_S_GLOBAL,'root_url')
DB_NAME=config.get(CFG_S_GLOBAL,'db_name')
DB_USER=config.get(CFG_S_GLOBAL,'db_user')
DB_PASS=config.get(CFG_S_GLOBAL,'db_pass')
DB_HOST=config.get(CFG_S_GLOBAL,'db_host')
DB_CHARSET=config.get(CFG_S_GLOBAL,'db_charset')
ROOT_LIB=os.path.abspath(config.get(CFG_S_GLOBAL,'root_lib'))
FORMATS=config.get(CFG_S_GLOBAL,'formats')
DUBLICATES=config.getboolean(CFG_S_GLOBAL,'dublicates')
FB2PARSE=config.getboolean(CFG_S_GLOBAL,'fb2parse')
ZIPSCAN=config.getboolean(CFG_S_GLOBAL,'zipscan')
ZIPRESCAN=config.getboolean(CFG_S_GLOBAL,'ziprescan')
       self.NAME=config.get(CFG_S_GLOBAL,'name')
       self.ROOT_URL=config.get(CFG_S_GLOBAL,'root_url')
       self.DB_NAME=config.get(CFG_S_GLOBAL,'db_name')
       self.DB_USER=config.get(CFG_S_GLOBAL,'db_user')
       self.DB_PASS=config.get(CFG_S_GLOBAL,'db_pass')
       self.DB_HOST=config.get(CFG_S_GLOBAL,'db_host')
       self.DB_CHARSET=config.get(CFG_S_GLOBAL,'db_charset')
       self.ROOT_LIB=os.path.abspath(config.get(CFG_S_GLOBAL,'root_lib'))
       self.FORMATS=config.get(CFG_S_GLOBAL,'formats')
       self.DUBLICATES=config.getboolean(CFG_S_GLOBAL,'dublicates')
       self.FB2PARSE=config.getboolean(CFG_S_GLOBAL,'fb2parse')
       self.ZIPSCAN=config.getboolean(CFG_S_GLOBAL,'zipscan')
       self.ZIPRESCAN=config.getboolean(CFG_S_GLOBAL,'ziprescan')
       fb2hsize=config.get(CFG_S_GLOBAL,'fb2hsize')
       maxitems=config.get(CFG_S_GLOBAL,'maxitems')
       splitauthors=config.get(CFG_S_GLOBAL,'splitauthors')
       if maxitems.isdigit():
   MAXITEMS=int(maxitems)
          self.MAXITEMS=int(maxitems)
       else:
   MAXITEMS=50
          self.MAXITEMS=50
       if fb2hsize.isdigit():
   FB2HSIZE=int(fb2hsize)
          self.FB2HSIZE=int(fb2hsize)
       else:
          FB2HSIZE=0
       if splitauthors.isdigit():
   SPLITAUTHORS=int(splitauthors)
          self.SPLITAUTHORS=int(splitauthors)
       else:
   SPLITAUTHORS=0
          self.SPLITAUTHORS=0

EXT_LIST=FORMATS.lower().split()
       self.EXT_LIST=self.FORMATS.lower().split()

       CFG_S_SITE='site'
SITE_ID=config.get(CFG_S_SITE,'id')
SITE_TITLE=config.get(CFG_S_SITE,'title')
SITE_ICON=config.get(CFG_S_SITE,'icon')
SITE_AUTOR=config.get(CFG_S_SITE,'autor')
SITE_URL=config.get(CFG_S_SITE,'url')
SITE_EMAIL=config.get(CFG_S_SITE,'email')
SITE_MAINTITLE=config.get(CFG_S_SITE,'main_title')
       self.SITE_ID=config.get(CFG_S_SITE,'id')
       self.SITE_TITLE=config.get(CFG_S_SITE,'title')
       self.SITE_ICON=config.get(CFG_S_SITE,'icon')
       self.SITE_AUTOR=config.get(CFG_S_SITE,'autor')
       self.SITE_URL=config.get(CFG_S_SITE,'url')
       self.SITE_EMAIL=config.get(CFG_S_SITE,'email')
       self.SITE_MAINTITLE=config.get(CFG_S_SITE,'main_title')