Subversion Repositories basico

Rev

Rev 229 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: database.py
# Author: Tomás Vírseda
# License: GPL v3
# Description: Database service

import os
from os.path import basename
import json
import glob
from cgi import escape

from basico.core.env import LPATH
from basico.core.service import Service

SEP = os.path.sep

class Database(Service):
    def initialize(self):
        '''
        Setup AppLogic Service
        '''

        self.sapnotes = {}
        self.stats = {}
        self.stats['maincomp'] = {}
        self.stats['cats'] = {}
        self.stats['component'] = set()
        self.stats['category'] = set()
        self.stats['priority'] = set()
        self.stats['type'] = set()
        self.stats['version'] = set()
        #FIXME self.stats['releaseon'] = set()


    def store(self, sapnote, html):
        CACHE_DIR = self.get_var('CACHE', 'local')
        FSAPNOTE = CACHE_DIR + sapnote + '.xml'

        try:
            f = open(FSAPNOTE, 'w')
            f.write(html)
            f.close()
            self.debug("\tSAP Note %s stored in %s" % (sapnote, FSAPNOTE))
        except Exception as error:
            self.log.error(error)


    def get_sapnote_content(self, sid):
        CACHE_DIR = self.get_var('CACHE', 'local')
        FSAPNOTE = CACHE_DIR + sid + '.xml'
        content = open(FSAPNOTE, 'r').read()
        return content


    def is_saved(self, sid):
        metadata = self.get_sapnote_metadata(sid)
        if metadata is None:
            return False
        else:
            return True


    def is_valid(self, sid):
        valid = True
        for ch in sid:
            if not ch.isdigit():
                return False
        return valid


    def is_stored(self, sid):
        CACHE_DIR = self.get_var('CACHE', 'local')
        fsapnote = CACHE_DIR + sid + '.xml'
        stored = os.path.exists(fsapnote)

        return stored


    def build_stats(self, bag=None):
        if bag is None:
            bag = self.sapnotes
        self.dstats = {}
        self.compstats = {}
        allcollections = set()

        for sid in bag:
            try:
                collections = self.sapnotes[sid]['collections']
                for collection in collections:
                    allcollections.add(collection)
            except: pass

            #COMMENT Components
            compkey = self.sapnotes[sid]['componentkey']
            comptxt = self.sapnotes[sid]['componenttxt']
            component = escape("%s (%s)" % (compkey, comptxt))
            sep = compkey.find('-')
            if sep > 0:
                maincomp = compkey[0:sep]
            else:
                maincomp = compkey

            #COMMENT Categories
            category = escape(self.sapnotes[sid]['category'])
            try:
                cont = self.stats['cats'][category]
                self.stats['cats'][category] = cont + 1
            except:
                self.stats['cats'][category] = 1

            #COMMENT Build all (sub)keys from given component key
            #COMMENT useful for display stats with pygal
            compkeys = compkey.split('-')
            total = len(compkeys)
            key = ''
            i = 0
            for subkey in compkeys:
                key = key + '-' + subkey
                if key[:1] == '-':
                    key = key[1:]

                # update stats
                try:
                    count = self.compstats[key]
                    self.compstats[key] = count + 1
                except Exception as error:
                    self.compstats[key] = 1

            try:
                cont = self.stats['maincomp'][maincomp]
                self.stats['maincomp'][maincomp] = cont + 1
            except:
                self.stats['maincomp'][maincomp] = 1

            category = escape(self.sapnotes[sid]['category'])
            priority = escape(self.sapnotes[sid]['priority'])
            ntype = escape(self.sapnotes[sid]['type'])
            version = escape(self.sapnotes[sid]['version'])
            releaseon = escape(self.sapnotes[sid]['releaseon'])
            self.stats['component'].add(component)
            self.stats['category'].add(category)
            self.stats['priority'].add(priority)
            self.stats['type'].add(ntype)
            self.stats['version'].add(version)
            #FIXME self.stats['releaseon'].add(releaseon)
            #FIXME self.stats[''].add(version)


    def add(self, sapnote):
        sid = sapnote['id']
        self.sapnotes[sid] = sapnote


    def add_list(self, sapnotes):
        for sapnote in sapnotes:
            self.add(sapnote)


    def get_notes(self):
        '''
        Return all sapnotes
        '''

        return self.sapnotes


    def get_notes_by_node(self, key, value):
        '''
        Return a set of sapnotes which matches with an specific key/value
        '''

        bag = set()
        sapnotes = self.get_notes()
        for sapnote in sapnotes:
            if key.startswith('component') or \
               key in ['category', 'priority', 'type']:
                if sapnotes[sapnote][key].startswith(value):
                    bag.add(sapnote)
            elif key == 'collection':
                if len(value) == 0:
                    try:
                        collections = sapnotes[sapnote]['collections']
                        if len(collections) > 0:
                            bag.add(sapnote)
                    except:
                        pass
                else:
                    try:
                        if value in sapnotes[sapnote]['collections']:
                            bag.add(sapnote)
                    except:
                        pass
            elif key in ['date-year', 'date-month', 'date-day']:
                if len(value) == 6:
                    value = value[0:4] + '-' + value[4:6]
                elif len(value) == 8:
                    value = value[0:4] + '-' + value[4:6] + '-' + value[6:8]

                if sapnotes[sapnote]['feedupdate'].startswith(value):
                    bag.add(sapnote)
            else:
                pass

        return bag


    def get_total(self):
        '''
        Return total sapnotes
        '''

        return len(self.sapnotes)


    def load_notes(self):
        '''
        If notes.json exists, load notes
        '''

        try:
            fnotes = self.get_file('SAP')
            with open(fnotes, 'r') as fp:
                self.sapnotes = json.load(fp)
                self.debug ("Loaded %d notes" % len(self.sapnotes))
        except Exception as error:
            self.debug("SAP Notes database not found. Creating a new one")
            self.save_notes()


    def get_sapnote_metadata(self, sid):
        sid = self.normalize_sid(sid)

        try:
            return self.sapnotes[sid]
        except KeyError as error:
            self.debug("SAP Note %s doesn't exist in the database" % sid)
            return None


    def get_title(self, sid):
        title = ''
        metadata = self.get_sapnote_metadata(sid)
        if metadata is not None:
            title = metadata['title']

        return title


    def save_notes(self, bag={}, export_path=None):
        '''
        Save SAP Notes to json database file
        '''

        if export_path is None:
            export_path = self.get_file('SAP')

        if len(bag) == 0:
            bag = self.get_notes()

        fdb = open(export_path, 'w')
        json.dump(bag, fdb)
        fdb.close()
        self.debug ("Saved %d notes to %s" % (len(bag), export_path))


    def set_bookmark(self, lsid):
        for sid in lsid:
            self.sapnotes[sid]['bookmark'] = True
            self.debug("SAP Note %s bookmarked: True" % sid)
        self.save_notes()


    def set_no_bookmark(self, lsid):
        for sid in lsid:
            self.sapnotes[sid]['bookmark'] = False
            self.debug("SAP Note %s bookmarked: False" % sid)
        self.save_notes()


    def is_bookmark(self, sapnote):
        try:
            return self.sapnotes[sapnote]['bookmark']
        except:
            return False

    def get_collections(self, sid):
        try:
            return self.sapnotes[sid]['collections']
        except:
            return []


    def search(self, term):
        bag = []

        for sid in self.get_notes():
            values = []
            sapnote = self.sapnotes[sid]
            for key in sapnote:
                # ~ self.debug(key)
                values.append(str(sapnote[key]))
            text = ' '.join(values)
            if term.upper() in text.upper():
                bag.append(sapnote['id'])
        self.debug("Found term '%s' in %d SAP Notes" % (term, len(bag)))
        return bag


    def normalize_sid(self, sid):
        if isinstance(sid, int):
            sid = "0"*(10 - len(str(sid))) + str(sid)
        elif isinstance(sid, str):
            sid = "0"*(10 - len(sid)) + sid

        return sid


    def set_collections(self, sid, collections):
        if sid != '0000000000':
            sid = self.normalize_sid(sid)
            self.sapnotes[sid]['collections'] = collections
            self.debug("SAP Note %s in collections: %s" % (sid, collections))
            self.save_notes()


    def delete(self, sapnote):
        deleted = False
        try:
            del (self.sapnotes[sapnote])
            deleted = True
            self.debug("SAP Note %s deleted" % sapnote)
            self.save_notes()
        except:
            deleted = False

        return deleted


    def run(self):
        self.load_notes()
        self.build_stats()


    def end(self):
        self.save_notes()