#!/usr/bin/env python

#    This program 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.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY 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 this program.  If not, see <http://www.gnu.org/licenses/>.

#  FeedReaderScreenlet (c) Whise 2007 
#  FeedReaderPlusScreenlet (c) chiptdev 2010

import screenlets
from screenlets import utils
from screenlets.options import StringOption , BoolOption , IntOption , FileOption , DirectoryOption , ListOption , AccountOption , TimeOption , FontOption, ColorOption , ImageOption
from screenlets import DefaultMenuItem
import pango
import gobject
import gtk
import os
import time
import calendar

import feedparser


MIN = 60
HOUR = 60 * MIN
DAY = 24 * HOUR
WEEK = 7 * DAY

rtime_quantities = [WEEK, DAY, HOUR, MIN]
rtime_labels = ['week', 'day', 'hour', 'min']

def relative_time_str(ref_sec, time_sec):
    """ returns a string describing time passed since a reference time """
    diff = int(ref_sec) - int(time_sec)
    if diff < 0:
        return '-'

    rts = ''

    for i in range(len(rtime_quantities)):
        prelen = len(rts)
        qt = rtime_quantities[i]
        if diff / qt > 0:
            if prelen > 0:
                rts += ', '
            rts += str(diff / qt) + ' ' + rtime_labels[i]
            if diff / qt > 1:
                rts += 's'
            diff -= (diff / qt) * qt

        if prelen > 0:
            return rts + ' ago'

    if len(rts) > 0:
        return rts + ' ago'
    else:
        return '< 1 min ago'

#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

def tdoc(obj):
	obj.__doc__ = _(obj.__doc__)
	return obj

@tdoc
class FeedReaderPlusScreenlet (screenlets.Screenlet):
	"""Customizable RSS Feed Reader"""
	
	# default meta-info for Screenlets (should be removed and put into metainfo)
	__name__	= 'FeedReaderPlusScreenlet'
	__version__	= '1.0.4'
	__author__	= 'Helder Fraga aka Whise (initial), Branko Daljevic aka chiptdev (v1.0)' 
	__requires__ = [ 'python-feedparser' ]
	__desc__	= __doc__	# set description to docstring of class

	# editable options (options that are editable through the UI)


	__timeout_update = None
        __timeout_periodic = None
        _periodic_interval = 100 #in ms
        periodic_counter = 0
	update_interval = 5
	feed_url = "http://rss.slashdot.org/Slashdot/slashdot"
	color_odd = (0, 0, 0, 0.9)
	color_even = (0, 0, 0, 0.9)
	color_title = (0.0, 0.0, 0.0, 1)
	color_text = (1,1,1,1)
	color_back = (1.0, 1.0, 1.0, 0.65)
	color_hover = (0, 0, 1.0, 0.65)
        color_new = (1, 0, 0, 0.65)
	font = "FreeSans"
	font_title = "FreeSans"
	show_shadow = True
	expanded = True
	hover = False
	number = 0
	feed_number = 10
        display_count = 10
        lines_per_title = 2
        link_type = 'item'
        tooltip_mode = 'description'
        new_hl_mode = 'until moused over'
        mouseover_delay = 2
        show_publish_mode = 'relative'
        feed_title = 'Feed Reader'
        feed_link = ''
        custom_title = ''
	feeds_mini = []
	feeds_full = []
	links = []
        prev_links = []
        publish_time = []
        prev_publish_time = []
        new_flag = []
        prev_new_flag = []
        feed_error = False
        show_feed_error = False
        check_updated = True
        fh_etag = None
        fh_modified = None
	
        curr_latest_publish = None
        prev_latest_publish = None
	mouse_is_over = False
	selected = -1
	mousesel = 0
        right_click_sel = -1
        hover_time = 0
        tooltip_showing = False
        date_height = 12
        base_width = 235

	# constructor
	def __init__ (self, **keyword_args):
		#call super (width/height MUST match the size of graphics in the theme)
		screenlets.Screenlet.__init__(self, width=235, height=200, 
			uses_theme=False,ask_on_option_override = False,  **keyword_args)
		# set theme
		#self.theme_name = "default"
		# add option group
                self.add_options_group(_('Style'), _('Style'))
		self.add_options_group(_('Options'), _('Options'))
		# add editable option to the group

		self.add_option(StringOption(_('Options'), 'feed_url', 
			self.feed_url, _('Feed URL'), 
			_('Feed URL')), realtime=False)

		self.add_option(IntOption(_('Options'), 'update_interval', 
			self.update_interval, _('Update interval'), 
			_('The interval for refreshing RSS feed (in minutes)'), min=1, max=60))

		self.add_option(IntOption(_('Options'),'feed_number', 
			self.feed_number, _('Number of titles to display'), 
			_('Number of item titles to display'), 
			min=1, max=50))

                self.add_option(IntOption(_('Options'), 'lines_per_title',
                        self.lines_per_title, _('Lines per title'),
                        _('Number of lines of text to use to display each item '
                        'in screenlet'), min=1, max=5))

                self.add_option(StringOption(_('Options'), 'link_type',
                        self.link_type, _('Link type'), 
                        _('Which link is followed when you click on an item'),
                        ['item', 'feed', 'off']))

                self.add_option(StringOption(_('Options'), 'tooltip_mode',
                        self.tooltip_mode, _('Tooltips'), 
                        _('Disable or specify the content of tooltips'),
                        ['description', 'full title', 'off']))

                self.add_option(StringOption(_('Options'), 'new_hl_mode',
                        self.new_hl_mode, _('Highlight new items'),
                        _('Specify whether to highlight new items and when they '
                        'should stop being considered new'),
                        ['until next update', 'until clicked',
                         'until moused over', 'off']))

                self.add_option(IntOption(_('Options'), 'mouseover_delay',
                        self.mouseover_delay, _('Mouse over delay'),
                        _('Amount of time in seconds needed for the mouse to '
                        'hover over an item before displaying tooltips and '
                        'losing new status'), min=0, max=15))

                self.add_option(StringOption(_('Options'), 'show_publish_mode',
                        self.show_publish_mode, _('Publish time display'),
                        _('How to display publish times for feed items'),
                        ['full: 12 hour', 'full: 24 hour', 'relative', 'off']))

                self.add_option(StringOption(_('Options'), 'custom_title',
                        self.custom_title, _('Custom feed title'), 
                        _('Custom text to display in the top bar to identify '
                        'the feed.  Leave blank for default pulled from feed')))

                self.add_option(BoolOption(_('Options'), 'check_updated',
                        self.check_updated, _('Server side update checking'),
                        _('Use ETags and Last-Modified headers to allow server '
                        'to not send feed if there have been no changes since '
                        'last fetch')))

		self.add_option(FontOption(_('Style'),'font_title', 
			self.font_title, _('Title Font'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_title', 
			self.color_title, _('Title Color'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_back', 
			self.color_back, _('Title Background Color'), 
			''))

		self.add_option(FontOption(_('Style'),'font', 
			self.font, _('Text Font'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_text', 
			self.color_text, _('Text Color'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_even', 
			self.color_even, _('Even row Color'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_odd', 
			self.color_odd, _('Odd row Color'), 
			''))

		self.add_option(ColorOption(_('Style'),'color_hover', 
			self.color_hover, _('Hover Color'), 
			''))

                self.add_option(ColorOption(_('Style'),'color_new',
                        self.color_new, _('New Item Color'),
                        ''))

                self.add_option(IntOption(_('Style'), 'base_width',
                        self.base_width, _('Base Width'),
                        _('Width of the screenlet in pixels at 1.0x scale'),
                        min=50, max=gtk.gdk.screen_width()))

		self.add_option(BoolOption(_('Style'),'show_shadow', 
			self.show_shadow, _('Show Shadow'), '',))

		self.add_option(BoolOption(_('Options'),'expanded', 
			self.expanded, _('Expanded'), '',hidden=True))

                self.__timeout_periodic = gobject.timeout_add(self._periodic_interval, self.periodic)


	def __setattr__(self, name, value):
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
		screenlets.Screenlet.__setattr__(self, name, value)
		if name == 'feed_number' or name == 'lines_per_title' or \
                        name == 'show_publish_mode':
                    if name == 'feed_number':
                        self.get_feeds()
                    calc_height = 20 + self.display_count * self.hpixels_per_item() + 30
                    if self.height != calc_height:
                        self.height = calc_height
                        self.redraw_canvas()
		if name == "update_interval":
                    if value > 0:
                        self.__dict__['update_interval'] = value
                        if self.__timeout_update:
                            gobject.source_remove(self.__timeout_update)
                        self.__timeout_update = gobject.timeout_add(
                                int(value * 60000), self.refresh_feed)
                    else:
                        self.__dict__['update_interval'] = 1
                        pass
		if name == 'feed_url':
                    self.refresh_feed()
                if name == 'base_width':
                    self.width = self.base_width
                    self.redraw_canvas()


	# ONLY FOR TESTING!!!!!!!!!
	def init_options_from_metadata (self):
		"""Try to load metadata-file with options. The file has to be named
		like the Screenlet, with the extension ".xml" and needs to be placed
		in the Screenlet's personal directory. 
		NOTE: This function always uses the metadata-file relative to the 
			  Screenlet's location, not the ones in SCREENLETS_PATH!!!"""
		print __file__
		p = __file__.rfind('/')
		mypath = __file__[:p]
		print mypath
		self.add_options_from_file( mypath + '/' + \
			self.__class__.__name__ + '.xml')



        def hpixels_per_item(self):
            if self.show_publish_mode == 'off':
                return 15 * self.lines_per_title
            else:
                return 15 * self.lines_per_title + self.date_height


	def on_after_set_atribute(self,name, value):
		"""Called after setting screenlet atributes"""
		
		pass

	def on_before_set_atribute(self,name, value):
		"""Called before setting screenlet atributes"""
		
		pass


	def on_create_drag_icon (self):
		"""Called when the screenlet's drag-icon is created. You can supply
		your own icon and mask by returning them as a 2-tuple."""
		return (None, None)

	def on_composite_changed(self):
		"""Called when composite state has changed"""
		pass

	def on_drag_begin (self, drag_context):
		"""Called when the Screenlet gets dragged."""
		pass
	
	def on_drag_enter (self, drag_context, x, y, timestamp):
		"""Called when something gets dragged into the Screenlets area."""
		pass
	
	def on_drag_leave (self, drag_context, timestamp):
		"""Called when something gets dragged out of the Screenlets area."""
		pass

	def on_drop (self, x, y, sel_data, timestamp):
		"""Called when a selection is dropped on this Screenlet."""
		return False
		
	def on_focus (self, event):
		"""Called when the Screenlet's window receives focus."""
		pass
	
	def on_hide (self):
		"""Called when the Screenlet gets hidden."""
		pass
	
	def on_init (self):
		"""Called when the Screenlet's options have been applied and the 
		screenlet finished its initialization. If you want to have your
		Screenlet do things on startup you should use this handler."""
		
		# add menu items
                self.add_menuitem('mark_all_read', _('Mark all as read'))
                self.add_menuitem('mark_read', _('Mark as read'))
                self.add_menuitem('mark_new', _('Mark as new'))
		self.add_default_menuitems()

		self.get_feeds()

                calc_height = 20 + self.display_count * self.hpixels_per_item() + 30
                self.height = calc_height
                self.width = self.base_width
                self.redraw_canvas()

	def on_key_down(self, keycode, keyvalue, event):
		"""Called when a keypress-event occured in Screenlet's window."""
		#key = gtk.gdk.keyval_name(event.keyval)
		
		pass
	
	def on_load_theme (self):
		"""Called when the theme is reloaded (after loading, before redraw)."""
		pass
	
	def on_menuitem_select (self, id):
		"""Called when a menuitem is selected."""
                if id == 'mark_all_read':
                    for i in range(len(self.new_flag)):
                        self.new_flag[i] = False
                elif id == 'mark_read' and self.right_click_sel >= 0:
                    self.new_flag[self.right_click_sel] = False
                elif id == 'mark_new' and self.right_click_sel >= 0:
                    self.new_flag[self.right_click_sel] = True

                if id.startswith('mark_'):
                    self.redraw_canvas()
	
	def on_mouse_down (self, event):
		"""Called when a buttonpress-event occured in Screenlet's window. 
		Returning True causes the event to be not further propagated."""
		x = event.x / self.scale
		y = event.y / self.scale
                click = -1
                if y > (30):
                    click = int((y - 30) / self.hpixels_per_item())

		if event.button == 1:
                    if y < 30:
                        if event.type == gtk.gdk._2BUTTON_PRESS: 
                            self.expanded = not self.expanded
                            self.redraw_canvas()
                    elif self.expanded:
                        if self.link_type == 'item':
                            link = self.links[click]
                        elif self.link_type == 'feed':
                            link = self.feed_link
                        if self.link_type != 'off':
                            os.system('xdg-open ' + link + ' &')

                        if self.new_flag[click] == True:
                            self.new_flag[click] = False
                            self.hide_tooltip()
                            self.redraw_canvas()
                elif event.button == 3 and self.expanded:
                    self.right_click_sel = click
				
		return False
	
	def on_mouse_enter (self, event):
		"""Called when the mouse enters the Screenlet's window."""
		pass

		
	def on_mouse_leave (self, event):
		"""Called when the mouse leaves the Screenlet's window."""
                self.__dict__['selected'] = -1
                self.hover_time = 0
                self.tooltip_shown = False
		self.hide_tooltip()
		self.redraw_canvas()

	def on_mouse_move(self, event):
		"""Called when the mouse moves in the Screenlet's window."""
		x = event.x / self.scale
		y = event.y / self.scale
		if y > (30) and self.expanded:
                    self.__dict__['mousesel'] = int((y - 30) / self.hpixels_per_item())
                else:
                    self.__dict__['mousesel'] = -1
    
                calc_height = 20 + self.display_count * self.hpixels_per_item() + 30
                if self.selected != self.mousesel or y > calc_height:
                    if self.mousesel == -1:
                        self.__dict__['selected'] = -1
                    self.hover_time = 0
                    self.tooltip_shown = False
                    self.hide_tooltip()
                    self.redraw_canvas()	

	def on_mouse_up (self, event):
		"""Called when a buttonrelease-event occured in Screenlet's window. 
		Returning True causes the event to be not further propagated."""
		return False
	
	def on_quit (self):
		"""Callback for handling destroy-event. Perform your cleanup here!"""
		
		return True
		
	def on_realize (self):
		""""Callback for handling the realize-event."""
	
	def on_scale (self):
		"""Called when Screenlet.scale is changed."""
		pass
	
	def on_scroll_up (self):
		"""Called when mousewheel is scrolled up (button4)."""
                #the whole focus handling is screwy.  Resize regardless of focus
                if self.resize_on_scroll and not self.has_focus:  
                    self.scale += 0.1

	def on_scroll_down (self):
		"""Called when mousewheel is scrolled down (button5)."""
                if self.resize_on_scroll and not self.has_focus:  
                    self.scale -= 0.1
	
	def on_show (self):
		"""Called when the Screenlet gets shown after being hidden."""
		pass
	
	def on_switch_widget_state (self, state):
		"""Called when the Screenlet enters/leaves "Widget"-state."""
		pass
	
	def on_unfocus (self, event):
		"""Called when the Screenlet's window loses focus."""
		pass

        def periodic(self):
            self.periodic_counter += 1

            if self.selected >= 0 and self.selected <= len(self.new_flag) - 1:
                self.hover_time += self._periodic_interval

                #lose new status after delay
                if self.new_hl_mode == 'until moused over' and \
                        self.new_flag[self.selected] and \
                        self.hover_time >= (self.mouseover_delay * 1000):
                    self.new_flag[self.selected] = False
                #show tooltip after delay
                if self.tooltip_mode != 'off' and \
                        self.tooltip_shown == False and \
                        self.hover_time >= (self.mouseover_delay * 1000):
                    entry_summary = self.feeds_full[self.selected]
                    if self.tooltip_mode == 'full title':
                        entry_summary = self.feeds_mini[self.selected]
                    try:
                        if self.x > gtk.gdk.screen_width()/2:
                            self.show_tooltip(entry_summary, self.x - 300, self.y + self.mousey)
                        else:
                            self.show_tooltip(entry_summary, self.x+(235*self.scale), self.y + self.mousey)
                        self.tooltip_shown = True
                    except:pass

            #Flash error message in title bar if can't retrieve feed
            if self.feed_error and self.periodic_counter >= 20:
                self.periodic_counter = 0
                self.show_feed_error = not self.show_feed_error
                self.redraw_canvas()
            #redraw canvas every minute in relative publish time mode to 
            #keep time values accurate
            elif self.show_publish_mode == 'relative' and \
                    self.periodic_counter >= 600:
                self.periodic_counter = 0
                self.redraw_canvas()

            return True


	def refresh_feed(self):
		"""Redraw canvas to update the feed, used by the timeout function"""
		print("Refreshing feed...")
		self.get_feeds()
		self.redraw_canvas()
		print("Refresh done")
		return True

	def get_feeds(self):
            """Get the summary and title of the selected feed"""
            if len(self.custom_title.strip()) > 0:
                feed_label = self.custom_title
            else:
                feed_label = self.feed_title
            print('Retrieving feed (' + feed_label + ')...')

            self.prev_links = self.links
            self.prev_publish_time = self.publish_time
            self.prev_new_flag = self.new_flag

            url = str(self.feed_url)
            if self.check_updated:
                f = feedparser.parse(url, etag=self.fh_etag, 
                                     modified=self.fh_modified)
                if f.get('status', -1) == 304:
                    print('No update - done (' + feed_label + ')')
                    self.feed_error = False
                    return
            else:
                f = feedparser.parse(url)

            if f.feed.has_key('title') or len(f.entries) > 0:
                self.feed_error = False
            else:
                print('Error: empty feed returned (' + feed_label + ')')
                print('  http status: ' + str(f.get('status', -1)))
                self.feed_error = True
                return

            if self.check_updated:
                self.fh_etag = f.get('etag', None)
                self.fh_modified = f.get('modified', None)

            self.feed_title = f.feed.get('title', self.feed_title)
            self.feed_link = f.feed.get('link', self.feed_link)

            self.feeds_mini = []
            self.feeds_full = []
            self.links = []
            self.publish_time = []
            self.new_flag = []

            self.prev_latest_publish = self.curr_latest_publish
            self.hover_time = 0

            try:
                no_titles = True
                no_summaries = True
                no_links = True
                no_dates = True

                self.display_count = self.feed_number
                if len(f.entries) < self.display_count:
                    self.display_count = len(f.entries)

                for i in range(self.display_count):
                    self.feeds_mini.append(f.entries[i].get('title', ''))
                    self.feeds_full.append(f.entries[i].get('summary', ''))
                    self.links.append(f.entries[i].get('link', ''))

                    ts = 0
                    if f.entries[i].has_key('date_parsed'):
                        ts = calendar.timegm(f.entries[i].date_parsed)
                    self.publish_time.append(ts)

                    item_new_flag = False
                    if self.prev_latest_publish != None and \
                            ts > self.prev_latest_publish:
                        item_new_flag = True
                    elif self.new_hl_mode == 'until clicked' or \
                            self.new_hl_mode == 'until moused over':
                        #See if previous new status should remain
                        for j in range(len(self.prev_new_flag)):
                            if ts == self.prev_publish_time[j] and \
                                    f.entries[i].link == self.prev_links[j]:
                                item_new_flag = self.prev_new_flag[j]
                                break
                    self.new_flag.append(item_new_flag)

                    if self.curr_latest_publish == None or \
                            ts > self.curr_latest_publish:
                        self.curr_latest_publish = ts

                    if len(self.feeds_mini[i]) > 0: no_titles = False
                    if len(self.feeds_full[i]) > 0: no_summaries = False
                    if len(self.links[i]) > 0: no_links = False
                    if self.publish_time[i] > 0: no_dates = False

                if no_titles:
                    print('Warning: feed is completely missing item titles')
                if no_summaries:
                    print('Warning: feed is completely missing item '
                          'descriptions')
                if no_links:
                    print('Warning: feed is completely missing item links')
                if no_dates:
                    self.show_publish_mode = 'off'
                    print('Warning: feed is completely missing publish '
                          'times.  Publish time display is disabled and new '
                          'item status handling will not work')
                print('Retrieval done (' + feed_label + ')')
            except Exception as ex: 
                print('!!!Exception during retrieval (' + feed_label + ')')
                print(str(type(ex)) + ': ' + str(ex))


        #!!
        #Override to fix issue
        def draw_text(self, ctx, text, x, y,  font, size, width, maxlines = 0, alignment = None, justify = False,weight = 0, ellipsize = pango.ELLIPSIZE_NONE):
                """Draws text"""
                ctx.save()
                ctx.translate(x, y)
                if self.p_layout == None :

                        self.p_layout = ctx.create_layout()
                else:

                        ctx.update_layout(self.p_layout)
                if self.p_fdesc == None:self.p_fdesc = pango.FontDescription()
                else: pass
                self.p_fdesc.set_family_static(font)
                self.p_fdesc.set_size(size * pango.SCALE)
                self.p_fdesc.set_weight(weight)
                self.p_layout.set_font_description(self.p_fdesc)
                self.p_layout.set_width(width * pango.SCALE)
                if alignment != None:self.p_layout.set_alignment(alignment)
                self.p_layout.set_justify(justify)
                self.p_layout.set_ellipsize(ellipsize)
                self.p_layout.set_text(text)

                #Fit text to a certain number of lines if specified 
                olen = len(text)
                if maxlines > 0 and self.p_layout.get_line_count() > maxlines:
                    cut = 2
                    pos = olen / cut

                    while olen / cut > 1:
                        cut = cut * 2
                        self.p_layout.set_text(text[0:pos])
                        if self.p_layout.get_line_count() > maxlines:
                            pos = pos - olen / cut
                        else:
                            pos = pos + olen / cut

                    chopped = text[0:pos] + "..."
                    self.p_layout.set_text(chopped)
                    while self.p_layout.get_line_count() > maxlines:
                        chopped = chopped[:len(chopped) - 4] + "..."
                        self.p_layout.set_text(chopped)

                ctx.show_layout(self.p_layout)
                ctx.restore()


	def on_draw (self, ctx):
		"""In here we draw"""
                curr_time = int(time.time())
		ctx.scale(self.scale, self.scale)
		y = 0

		if self.expanded:
			if self.show_shadow:self.draw_shadow(ctx, 0, 0, self.width-12, self.height-15,6,[0,0,0,0.3])	
		else:
			if self.show_shadow:self.draw_shadow(ctx, 0, 0, self.width-12,40-5,6,[0,0,0,0.3])	
		ctx.translate(10,10)

		ctx.set_source_rgba(self.color_back[0],self.color_back[1],self.color_back[2],self.color_back[3])
		self.draw_rounded_rectangle(ctx,0,y,5,self.width-20,20,round_bottom_right= False,round_bottom_left= False)
		ctx.set_source_rgba(self.color_title[0],self.color_title[1],self.color_title[2],self.color_title[3])
                if self.feed_error and self.show_feed_error:
                    displayed_title = '***Error retrieving feed'
                elif len(self.custom_title.strip()) > 0:
                    displayed_title = self.custom_title
                else:
                    displayed_title = self.feed_title
		self.draw_text(ctx, displayed_title, 14, y+2, self.font_title.split(' ')[0], 10, self.width - 20 -14, 1, pango.ALIGN_LEFT)

		if self.expanded:
			ctx.rotate(3.14)
			self.draw_triangle(ctx,-15,-(y+17),10,10)
			ctx.rotate(-3.14)
			
		else:
			ctx.rotate(3.14/2)
			self.draw_triangle(ctx,3,-(y+15),10,10)
			ctx.rotate(-3.14/2)
		ctx.translate(0,20)			
		if self.expanded :
			x = 0
			
			for app in range(self.display_count):
		
                                if self.mousesel == x and self.mouse_is_over:
                                    ctx.set_source_rgba(self.color_hover[0],self.color_hover[1],self.color_hover[2],self.color_hover[3])
                                    self.__dict__['selected'] = x
                                elif self.new_hl_mode != 'off' and \
                                        len(self.new_flag) > 0 and \
                                        self.new_flag[app]:
                                    ctx.set_source_rgba(self.color_new[0],self.color_new[1],self.color_new[2],self.color_new[3])
				elif x % 2:
                                    ctx.set_source_rgba(self.color_even[0],self.color_even[1],self.color_even[2],self.color_even[3])
				else:
                                    ctx.set_source_rgba(self.color_odd[0],self.color_odd[1],self.color_odd[2],self.color_odd[3])
				

				if self.display_count - 1 == app:
                                    self.draw_rounded_rectangle(ctx, 0, y, 5, self.width - 20, self.hpixels_per_item(), round_top_right= False,round_top_left= False)	
				else:
                                    self.draw_rectangle(ctx, 0, y, self.width -20, self.hpixels_per_item())

				ctx.set_source_rgba(self.color_text[0],self.color_text[1],self.color_text[2],self.color_text[3])

				try:
                                    self.draw_text(ctx, self.feeds_mini[app], 5, y+2, self.font.split(' ')[0], 8, self.width-22, self.lines_per_title, pango.ALIGN_LEFT)
				except:pass

                                try:
                                    pt = self.publish_time[app]
                                    if self.show_publish_mode == 'full: 12 hour':
                                        time_text = time.strftime(
                                            '%a %b %d, %I:%M%p', 
                                             time.localtime(pt))
                                    elif self.show_publish_mode == 'full: 24 hour':
                                        time_text = time.strftime(
                                            '%a %b %d, %H:%M', 
                                            time.localtime(pt))
                                    elif self.show_publish_mode == 'relative':
                                        time_text = relative_time_str(curr_time, pt)

                                    if self.show_publish_mode != 'off':
                                        self.draw_text(ctx, time_text, -5, y + 15 * self.lines_per_title, self.font.split(' ')[0], 7, self.width-22, 1, pango.ALIGN_RIGHT)
                                except:pass

				x = x + 1
				y = y + self.hpixels_per_item()
			
			

	def on_draw_shape (self, ctx):
		self.on_draw(ctx)
	
# If the program is run directly or passed as an argument to the python
# interpreter then create a Screenlet instance and show it
if __name__ == "__main__":
	# create new session
	import screenlets.session
	screenlets.session.create_session(FeedReaderPlusScreenlet)

