EntryView.py :  » RSS » PenguinTV » PenguinTV-4.1.0 » penguintv » 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 » RSS » PenguinTV 
PenguinTV » PenguinTV 4.1.0 » penguintv » EntryView.py
import logging
import os
import htmllib, HTMLParser
import formatter

import gobject
import gtk
import ptvDB

import html.PTVhtml
import utils
from penguintv import DEFAULT,MANUAL_SEARCH,TAG_SEARCH,MAJOR_DB_OPERATION
import EntryFormatter
import Downloader
import ThreadPool

#states
S_DEFAULT = 0
S_SEARCH  = 1

class EntryView(gobject.GObject):

  __gsignals__ = {
        'link-activated': (gobject.SIGNAL_RUN_FIRST, 
                           gobject.TYPE_NONE, 
                           ([gobject.TYPE_PYOBJECT])),
    'entries-viewed': (gobject.SIGNAL_RUN_FIRST, 
                           gobject.TYPE_NONE, 
                           ([gobject.TYPE_PYOBJECT]))
    }  

  def __init__(self, widget_tree, feed_list_view, entry_list_view, 
         app, main_window, renderer=EntryFormatter.MOZILLA):
    gobject.GObject.__init__(self)
    self._app = app
    self._mm = self._app.mediamanager
    self._main_window = main_window
    self._renderer = renderer
    #self._renderer = EntryFormatter.GTKHTML
    #self._moz_realized = False
    self._state = S_DEFAULT
    self._auth_info = (-1, "","") #user:pass, url
    self._widget_tree = widget_tree
    html_dock = self._widget_tree.get_widget('html_dock')
    
    self._scrolled_window = gtk.ScrolledWindow()
    html_dock.add(self._scrolled_window)
    self._scrolled_window.set_property("hscrollbar-policy",gtk.POLICY_AUTOMATIC)
    self._scrolled_window.set_property("vscrollbar-policy",gtk.POLICY_AUTOMATIC)
    
    #thanks to straw, again
    style = html_dock.get_style().copy()
    self._currently_blank=True
    self._current_entry={}
    self._updater_timer=0
    self._custom_entry = False
    self._convert_newlines = (-1, False)
    self._background_color = "#%.2x%.2x%.2x;" % (
                style.base[gtk.STATE_NORMAL].red / 256,
                style.base[gtk.STATE_NORMAL].blue / 256,
                style.base[gtk.STATE_NORMAL].green / 256)
                
    self._foreground_color = "#%.2x%.2x%.2x;" % (
                style.text[gtk.STATE_NORMAL].red / 256,
                style.text[gtk.STATE_NORMAL].blue / 256,
                style.text[gtk.STATE_NORMAL].green / 256)
                
    self._insensitive_color = "#%.2x%.2x%.2x;" % (
                style.base[gtk.STATE_INSENSITIVE].red / 256,
                style.base[gtk.STATE_INSENSITIVE].blue / 256,
                style.base[gtk.STATE_INSENSITIVE].green / 256)
                
    #for style in [style.fg, style.bg, style.base, style.text, style.mid, style.light, style.dark]:
    #  for category in [gtk.STATE_NORMAL, gtk.STATE_PRELIGHT, gtk.STATE_SELECTED, gtk.STATE_ACTIVE, gtk.STATE_INSENSITIVE]:
    #    print "#%.2x%.2x%.2x;" % (style[category].red / 256, style[category].blue / 256,style[category].green / 256)
    #  print "==========="
        
        #const found in __init__   
        
    self._css = ""
    
    #self.display_custom_entry("<html></html>")
    
    self._entry_formatter = EntryFormatter.EntryFormatter(self._mm)
    self._search_formatter = EntryFormatter.EntryFormatter(self._mm, True)
    #self._auto_mark_viewed = self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/auto_mark_viewed', True)
    
    #signals
    self._handlers = []
    h_id = feed_list_view.connect('no-feed-selected', self.__feedlist_none_selected_cb)
    self._handlers.append((feed_list_view.disconnect, h_id))
    h_id = entry_list_view.connect('no-entry-selected', self.__entrylist_none_selected_cb)
    self._handlers.append((entry_list_view.disconnect, h_id))
    h_id = entry_list_view.connect('entry-selected', self.__entry_selected_cb)
    self._handlers.append((entry_list_view.disconnect, h_id))
    h_id = entry_list_view.connect('search-entry-selected', self.__search_entry_selected_cb)
    self._handlers.append((entry_list_view.disconnect, h_id))
    h_id = self._app.connect('entry-updated', self.__entry_updated_cb)
    self._handlers.append((self._app.disconnect, h_id))
    h_id = self._app.connect('render-ops-updated', self.__render_ops_updated_cb)
    self._handlers.append((self._app.disconnect, h_id))
    h_id = self._app.connect('entries-viewed', self.__entries_viewed_cb)
    self._handlers.append((self._app.disconnect, h_id))
    h_id = self._app.connect('entries-unviewed', self.__entries_viewed_cb)
    self._handlers.append((self._app.disconnect, h_id))
    h_id = self._app.connect('state-changed', self.__state_changed_cb)
    self._handlers.append((self._app.disconnect, h_id))
    h_id = self._app.connect('feed-polled', self.__feed_polled_cb)
    self._handlers.append((self._app.disconnect, h_id))
    
    #h_id = app.connect('setting-changed', self.__setting_changed_cb)
    #self._handlers.append((app.disconnect, h_id))
    
    if self._renderer == EntryFormatter.MOZILLA:
      import html.PTVMozilla
      self._html_widget = html.PTVMozilla.PTVMozilla(self, self._app.db.home, utils.get_share_prefix())
    elif self._renderer == EntryFormatter.GTKHTML:
      import html.PTVGtkHtml
      self._html_widget = html.PTVGtkHtml.PTVGtkHtml(self, self._app.db.home, utils.get_share_prefix())
      
  def get_display_id(self):
    try:
      return self._current_entry['entry_id']
    except:
      return None
    
  def get_bg_color(self):
    return self._background_color
    
  def get_fg_color(self):
    return self._foreground_color
    
  def get_in_color(self):
    return self._insensitive_color
    
  def post_show_init(self):
    html_dock = self._widget_tree.get_widget('html_dock')
    self._html_widget.post_show_init(self._scrolled_window)
    self._html_widget.connect('link-message', self.__link_message_cb)
    self._html_widget.connect('open-uri', self.__open_uri_cb)
    self._USING_AJAX = self._html_widget.is_ajax_ok()
    
    html_dock.show_all()
    
  def __feedlist_none_selected_cb(self, o):
    self.display_item()
    
  def __entrylist_none_selected_cb(self, o):
    self.display_item()
    
  def __entry_selected_cb(self, o, entry_id, feed_id):
    item = self._app.db.get_entry(entry_id)
    media = self._app.db.get_entry_media(entry_id)
    if media:
      item['media']=media
    else:
      item['media']=[]
    #if self._auto_mark_viewed:
    #  if self._app.db.get_flags_for_feed(feed_id) & ptvDB.FF_MARKASREAD:
    #    item['read'] = 1
    self.display_item(item)

  def __search_entry_selected_cb(self, o, entry_id, feed_id, search_query):
    item = self._app.db.get_entry(entry_id)
    media = self._app.db.get_entry_media(entry_id)
    if media:
      item['media']=media
    else:
      item['media']=[]
    self.display_item(item, search_query)
    
  def __entry_updated_cb(self, app, entry_id, feed_id):
    self.update_if_selected(entry_id, feed_id)
    
  def __render_ops_updated_cb(self, app):
    self._convert_newlines = (-1, False)
    self.update_if_selected(self._current_entry['entry_id'], self._current_entry['feed_id'])
    
  def __entries_viewed_cb(self, app, viewlist):
    for feed_id, entrylist in viewlist:
      for e in entrylist:
        self.update_if_selected(e, feed_id)
      
  def __feed_polled_cb(self, app, feed_id, update_data):
    pass
    #FIXME: "custom entry" doesn't really work well
    #if feed_id == self._current_entry['feed_id']:
    #  if update_data['pollfail']:
    #    self.display_custom_entry("<b>"+_("There was an error trying to poll this feed.")+"</b>")
    #  else:
    #    self.undisplay_custom_entry()
    
  #def __setting_changed_cb(self, app, typ, datum, value):
  #  if datum == '/apps/penguintv/auto_mark_viewed':
  #    self._auto_mark_viewed = value
  
  def __link_message_cb(self, o, message):
    if not utils.RUNNING_HILDON:
      self._main_window.display_status_message(message)
  
  def __open_uri_cb(self, o, uri):
    self.emit('link-activated', uri)

  def get_selected(self):
    if len(self._current_entry) == 0:
      return None
    elif not self._currently_blank:
      return self._current_entry['entry_id']
    return None
    
  def progress_update(self, entry_id, feed_id):
    self.update_if_selected(entry_id, feed_id)
  
  def update_if_selected(self, entry_id, feed_id):
    """tests to see if this is the currently-displayed entry, 
    and if so, goes back to the app and asks to redisplay it."""
    #item, progress, message = data
    try:
      if len(self._current_entry) == 0:
        return
    except:
      print "exception"
      return
      
    if entry_id != self._current_entry['entry_id'] or self._currently_blank:
      return  
    #assemble the updated info and display
    item = self._app.db.get_entry(entry_id)
    media = self._app.db.get_entry_media(entry_id)
    if media:
      item['media']=media
    else:
      item['media']=[]

    self.display_item(item)
    
  def display_custom_entry(self, message):
    self._html_widget.render("<html><body>%s</body></html>" % message)
    self._custom_entry = True
    
  def undisplay_custom_entry(self):
    if self._custom_entry:
      message = "<html></html>"
      self._html_widget.render(message)
      self._custom_entry = False
      
  def _unset_state(self):
    self.display_custom_entry("")
  
  def __state_changed_cb(self, app, newstate, data=None):
    d = {DEFAULT: S_DEFAULT,
       MANUAL_SEARCH: S_SEARCH,
       TAG_SEARCH: S_SEARCH,
       #penguintv.ACTIVE_DOWNLOADS: S_DEFAULT,
       MAJOR_DB_OPERATION: S_DEFAULT}
       
    newstate = d[newstate]
    
    if newstate == self._state:
      return
    
    self._unset_state()
    self._state = newstate
  
  def display_item(self, item=None, highlight=""):
    #when a feed is refreshed, the item selection changes from an entry,
    #to blank, and to the entry again.  We used to lose scroll position because of this.
    #Now, scroll position is saved when a blank entry is displayed, and if the next
    #entry is the same id as before the blank, we restore those old values.
    #we have a bool to figure out if the current page is blank, in which case we shouldn't
    #save its scroll values.
    if item:
      self._current_entry = item  
      self._currently_blank = False
      if self._convert_newlines[0] != item['feed_id']:
        self._convert_newlines = (item['feed_id'], 
               self._app.db.get_flags_for_feed(item['feed_id']) & ptvDB.FF_ADDNEWLINES == ptvDB.FF_ADDNEWLINES)
      
      if item['feed_id'] != self._auth_info[0] and self._auth_info[0] != -2:
        feed_info = self._app.db.get_feed_info(item['feed_id'])
        if feed_info['auth_feed']:
          self._auth_info = (item['feed_id'],feed_info['auth_userpass'], feed_info['auth_domain'])
        else:
          self._auth_info = (-2, "","")
    else:
      self._convert_newlines = (-1, False)
      self._currently_blank = True
  
    if self._state == S_SEARCH:
      formatter = self._search_formatter
      if item is not None:
        item['feed_title'] = self._app.db.get_feed_title(item['feed_id'])
    else:
      formatter = self._entry_formatter
      
    if item is None:
      header = """<style type="text/css">
        body { background-color: %s;}</style>""" % (self._background_color,)
    else:
      header = ""
  
    html = self._html_widget.build_header(header)
    
    if item is None:
      html += """<body></body></html>""" 
    else:
      html += "<body>%s</body></html>" % formatter.htmlify_item(item, convert_newlines=self._convert_newlines[1])
  
    #do highlighting for search mode
    html = html.encode('utf-8')
    if len(highlight)>0:
      try:
        highlight = highlight.replace("*","")
        p = EntryFormatter.HTMLHighlightParser(highlight)
        p.feed(html)
        html = p.new_data
      except:
        pass
      
    if self._auth_info[0] >= 0:  
      try:
        p = EntryFormatter.HTMLImgAuthParser(self._auth_info[2], self._auth_info[1])
        p.feed(html)
        html = p.new_data
      except:
        pass
        
    #print html
    
    self._html_widget.render(html, "file:///", self.get_display_id())
      
    if item is not None:    
      gobject.timeout_add(2000, self._do_delayed_set_viewed, item)
    return
    
  def _do_delayed_set_viewed(self, entry):
    if entry == self._current_entry:
      if not self._current_entry['read'] and \
         not self._current_entry['keep'] and \
         len(self._current_entry['media']) == 0:
        self.emit('entries-viewed', [(self._current_entry['feed_id'], [self._current_entry['entry_id']])])
    return False

  def scroll_down(self):
    """ Old straw function, _still_ not used.  One day I might have "space reading" """
    va = self._scrolled_window.get_vadjustment()
    old_value = va.get_value()
    new_value = old_value + va.page_increment
    limit = va.upper - va.page_size
    if new_value > limit:
      new_value = limit
    va.set_value(new_value)
    return new_value > old_value
    
  def finish(self):
    for disconnector, h_id in self._handlers:
      disconnector(h_id)
  
    self._html_widget.finish()
    self._custom_entry = True
    return
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.