library.py :  » IDE » PIDA » pida-0.6beta3 » pida-plugins » library » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida plugins » library » library.py
# -*- coding: utf-8 -*- 

# Copyright (c) 2007 The PIDA Project

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.

import os
import gzip
import tempfile
import threading
import xml.sax
import xml.dom.minidom as minidom

xml.sax.handler.feature_external_pes = False

import gtk
import gobject
from kiwi.ui.objectlist import ObjectTree,Column

# PIDA Imports
from pida.core.service import Service
from pida.core.features import FeaturesConfig
from pida.core.commands import CommandsConfig
from pida.core.events import EventsConfig
from pida.core.actions import ActionsConfig
from pida.core.actions import (TYPE_NORMAL,TYPE_MENUTOOL,TYPE_RADIO
                               TYPE_REMEMBER_TOGGLE)

from pida.ui.views import PidaGladeView,WindowConfig

from pida.utils.gthreads import GeneratorTask,AsyncTask

# locale
from pida.core.locale import Locale
locale = Locale('library')
_ = locale.gettext

class LibraryView(PidaGladeView):

    key = 'library.list'
    
    _columns = [
        Column('title', expand=True, sorted=True)
    ]

    gladefile = 'library_viewer'
    locale = locale
    icon_name = 'gtk-library'
    label_text = _('Documentation')

    def create_ui(self):
        self.books_list.set_columns(self._columns)
        self.contents_tree.set_columns(self._columns)
        self.books_list.set_headers_visible(False)
        self.contents_tree.set_headers_visible(False)

    def fetch_books(self):
        self.books_list.clear()
        self.contents_tree.clear()
        task = GeneratorTask(fetch_books, self.add_book)
        task.start()

    def add_book(self, item):
        self.books_list.append(item)

    def on_books_list__double_click(self, ol, item):
        self.contents_tree.clear()
        if item is not None:
            task = AsyncTask(self.load_book, self.book_loaded)
            task.start()

    def on_contents_tree__double_click(self, ot, item):
        self.svc.browse_file("file://%s" %item.path)

    def load_book(self):
        item = self.books_list.get_selected()
        return item.load()
        
    def book_loaded(self, bookmarks):
        self.contents_tree.clear()
        task = GeneratorTask(bookmarks.get_subs, self.add_bookmark)
        task.start()
        self.view_book.set_current_page(1)

    def add_bookmark(self, bookmark, parent):
        self.contents_tree.append(parent, bookmark)

    def on_refresh_button__clicked(self, button):
        self.fetch_books()

    def can_be_closed(self):
        self.svc.get_action('show_library').set_active(False)


class LibraryActions(ActionsConfig):

    def create_actions(self):
        LibraryWindowConfig.action = self.create_action(
            'show_library',
            TYPE_REMEMBER_TOGGLE,
            _('Documentation Library'),
            _('Show the documentation library'),
            '',
            self.on_show_library,
            '<Shift><Control>r',
        )

        self.create_action(
            'show_browser',
            TYPE_REMEMBER_TOGGLE,
            _('Documentation Browser'),
            _('Documentation Browser'),
            '',
            self.on_show_browser,
        )

    def on_show_library(self, action):
        if action.get_active():
            self.svc.show_library()
        else:
            self.svc.hide_library()

    def on_show_browser(self, action):
        if action.get_active():
            self.svc.show_browser()
        else:
            self.svc.hide_browser()

def fetch_books():
    dirs = ['/usr/share/gtk-doc/html',
            '/usr/share/devhelp/books',
            os.path.expanduser('~/.devhelp/books')]
    
    use_gzip = True#self.opts.book_locations__use_gzipped_book_files
    for dir in dirs:
        for book in fetch_directory(dir):
            yield book

def fetch_directory(directory):
    if os.path.exists(directory):
        for name in os.listdir(directory):
            path = os.path.join(directory, name)
            if os.path.exists(path):
                load_book = Book(path, True)
                yield load_book





class TitleHandler(xml.sax.handler.ContentHandler):

    def __init__(self):
        self.title = _('untitled')
        self.is_finished = False

    def startElement(self, name, attributes):
        self.title = attributes['title']
        self.is_finished = True


class Book(object):

    def __init__(self, path, include_gz=True):
        self.directory = path
        self.key = path
        self.name = os.path.basename(path)
        self.bookmarks = None
        try:
            self.short_load()
        except (OSError, IOError):
            pass

    def has_load(self):
        return self.bookmarks is not None

    def short_load(self):
        config_path = None
        path = self.directory
        if not os.path.isdir(path):
            return
        for name in os.listdir(path):
            if name.endswith('.devhelp'):
                config_path = os.path.join(path, name)
                break
            elif name.endswith('.devhelp.gz'):
                gz_path = os.path.join(path, name)
                f = gzip.open(gz_path, 'rb', 1)
                gz_data = f.read()
                f.close()
                fd, config_path = tempfile.mkstemp()
                os.write(fd, gz_data)
                os.close(fd)
                break
        self.title = None
        if config_path:
            parser = xml.sax.make_parser()
            parser.setFeature(xml.sax.handler.feature_external_ges, 0)
            handler = TitleHandler()
            parser.setContentHandler(handler)
            f = open(config_path)
            for line in f:
                try:
                    parser.feed(line)
                except:
                    raise
                if handler.is_finished:
                    break
            f.close()
            self.title = handler.title
        if not self.title:
            self.title = os.path.basename(path)

    def load(self):
        config_path = None
        path = self.directory
        for name in os.listdir(path):
            if name.endswith('.devhelp'):
                config_path = os.path.join(path, name)
                break
            elif name.endswith('.devhelp.gz'):
                gz_path = os.path.join(path, name)
                f = gzip.open(gz_path, 'rb', 1)
                gz_data = f.read()
                f.close()
                fd, config_path = tempfile.mkstemp()
                os.write(fd, gz_data)
                os.close(fd)
                break
        if config_path and os.path.exists(config_path):
            dom = minidom.parse(config_path)
            main = dom.documentElement
            book_attrs = dict(main.attributes)
            for attr in book_attrs:
                setattr(self, attr, book_attrs[attr].value)
            self.chapters = dom.getElementsByTagName('chapters')[0]
            self.root = os.path.join(self.directory, self.link)
            self.bookmarks = self.get_bookmarks()
        else:
            for index in ['index.html']:
                indexpath = os.path.join(path, index)
                if os.path.exists(indexpath):
                    self.root = indexpath
                    break
                self.root = indexpath

        self.key = path
        return self.get_bookmarks()

    def get_bookmarks(self):
        root = BookMark(self.chapters, self.directory)
        root.name = self.title
        root.path = self.root
        return root


class BookMark(object):

    def __init__(self, node, root_path):
        try:
            self.name = node.attributes['name'].value
        except:
            self.name = None
        self.title = self.name
        try:
            self.path = os.path.join(root_path, node.attributes['link'].value)
        except:
            self.path = None
        self.key = self.path
        self.subs = []
        for child in self._get_child_subs(node):
            bm = BookMark(child, root_path)
            self.subs.append(bm)

    def _get_child_subs(self, node):
        return [n for n in node.childNodes if n.nodeType == 1]

    def get_subs(self, parent=None):
        if parent is None:
            aparent = self
        else:
            aparent = parent
        for sub in aparent.subs:
            yield sub, parent
            for csub in self.get_subs(sub):
                yield csub
                
    def __iter__(self):
            yield None, sub

class LibraryWindowConfig(WindowConfig):
    key = LibraryView.key
    label_text = LibraryView.label_text

class LibraryFeaturesConfig(FeaturesConfig):
    def subscribe_all_foreign(self):
        self.subscribe_foreign('window', 'window-config',
            LibraryWindowConfig)

# Service class
class Library(Service):
    """Describe your Service Here""" 

    actions_config = LibraryActions
    features_config = LibraryFeaturesConfig

    def start(self):
        self._view = LibraryView(self)
        bclass = self.boss.cmd('browseweb', 'get_web_browser')
        self._browser = bclass(self)
        self._browser.label_text = _('Documentation')
        self._browser.connect_closed(self._on_close_clicked)
        self._has_loaded = False

    def show_library(self):
        self.boss.cmd('window', 'add_view', paned='Plugin', view=self._view)
        if not self._has_loaded:
            self._has_loaded = True
            self._view.fetch_books()

    def hide_library(self):
        self.boss.cmd('window', 'remove_view', view=self._view)

    def _on_close_clicked(self, button):
        self.get_action('show_browser').set_active(False)

    def show_browser(self):
        self.boss.cmd('window', 'add_view', paned='Terminal',
                      view=self._browser)

    def hide_browser(self):
        self.boss.cmd('window', 'remove_view', view=self._browser)

    def ensure_browser_visible(self):
        if not self.get_action('show_browser').get_active():
            self.get_action('show_browser').set_active(True)
        self.boss.cmd('window', 'present_view', view=self._browser)

    def browse_file(self, url):
        self.ensure_browser_visible()
        self._browser.fetch(url)

    def stop(self):
        if self.get_action('show_library').get_active():
            self.hide_library()
        if self.get_action('show_browser').get_active():
            self.hide_browser()


# Required Service attribute for service loading
Service = Library



# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.