g3rss.py :  » Network » Rufus-BitTorrent-Client » Rufus_0.7.0_src » 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 » Network » Rufus BitTorrent Client 
Rufus BitTorrent Client » Rufus_0.7.0_src » g3rss.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#-----------------------------------------------------------------------------
# Name:        g3rss.py
# Purpose:     
#
# Author:      d0c 54v4g3, Jeremy Arendt
#
# Created:     2004/23/02
# RCS-ID:      $Id: 
# Copyright:   (c) 2002
# Licence:     See G3.LICENCE.TXT
#-----------------------------------------------------------------------------
import wx
import wx.html as html
import webbrowser
import urlparse
import ConfigParser
from wx.lib.mixins.listctrl import ColumnSorterMixin,ListCtrlAutoWidthMixin
from btconfig import BTConfig
from images import Images
from g3listctrl import *
from feedparser import parse
from string import split
from threading import Thread
from os.path import join,exists

import os
import os.path

if sys.platform == "win32":   
    win32_flag = True
else:
    win32_flag = False

class T_GetFeed(Thread):

    def __init__(self, invokelater, callback, url):
        Thread.__init__(self)
        self.success = False
        self.Callback = callback
        self.InvokeLater = invokelater
        self.url = url
       
    def run(self):
        data = None

        try:
            data = parse(self.url)
        except:
            self.success = False
            return False
        self.success = True

        try:
            self.InvokeLater(self.Callback, data)
        except wx.PyDeadObjectError:
            pass
        return True


class RSSList(G3ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMixin):
    def __init__(self, parent, btconfig, bmps=None, pos=wx.DefaultPosition, size=wx.DefaultSize,
                 style = wx.LC_REPORT | wx.LC_VRULES, onclickfunc=None, ondblclickfunc=None, onurlfunc=None, onbrowfunc=None, oncopyfunc=None):
        G3ListCtrl.__init__(self, parent, btconfig, "RSSList", -1, pos, size, style)
        self.CmdOnClick = onclickfunc
        self.CmdDblClick = ondblclickfunc
        self.CmdURL = onurlfunc
        self.CmdBrowFunc = onbrowfunc
        self.CmdCopyFunc = oncopyfunc
        self.btconfig = btconfig
        ListCtrlAutoWidthMixin.__init__(self)
        ColumnSorterMixin.__init__(self, 2)
        self.itemDataMap = {}
        self.list_rows = {}
        self.previtem = 0 # used to limit html refresh to once a selection
        
        self.col2sort = 1
        self.ascending = False
        
        cols = [ [True, _("Title"), wx.LIST_FORMAT_LEFT, 300],
                 [True, _("URL"), wx.LIST_FORMAT_LEFT, 400],
            ]

        self.InsertColumns(cols)
      
        wx.EVT_LIST_ITEM_ACTIVATED(self, -1, self.OnDblClick)  
        wx.EVT_COMMAND_LEFT_CLICK(self, -1, self.OnClick) # wxMSW
        wx.EVT_LEFT_UP(self, self.OnClick) # wxGTK  

        wx.EVT_COMMAND_RIGHT_CLICK(self, -1, self.OnListRightClick) # wxMSW
        wx.EVT_RIGHT_UP(self, self.OnListRightClick) # wxGTK

    def GetSelectedData(self):
        if self.GetFirstSelected() != -1:
            return self.GetItemData( self.GetFirstSelected() )
        else:
            return None

    def OnDblClick(self, event):
        if self.CmdDblClick:
            key = self.GetSelectedData()
            if self.itemDataMap.has_key(key):
                self.CmdDblClick(key)
        
    def OnClick(self, event):
        if self.CmdOnClick:
            key = self.GetSelectedData()
            if self.itemDataMap.has_key(key) and key != self.previtem:
                self.CmdOnClick(key)
                self.previtem = key

    def OnListRightClick(self, event):
        if not hasattr(self, "_popup_id"):
            self._popup_id = []
            for i in range(0, 2):
                self._popup_id.append(wx.NewId())
            
            wx.EVT_MENU(self, self._popup_id[0], self.MenuOnCopy)
            wx.EVT_MENU(self, self._popup_id[1], self.MenuOnBrowser)

        listmenu = wx.Menu()

        listmenu.Append(self._popup_id[0], _("Copy URL to clipboard"), _("Copy URL to clipboard"))
        listmenu.Append(self._popup_id[1], _("Open URL in Default Browser"), _("Open URL in Default Browser"))
        
        self.PopupMenu(listmenu, self.ScreenToClient(wx.GetMousePosition()))
        listmenu.Destroy()
    

    def MenuOnCopy(self, event):
        if self.CmdCopyFunc:
            key = self.GetSelectedData()
            if self.itemDataMap.has_key(key):
                self.CmdCopyFunc(key)
    
    def MenuOnBrowser(self, event):
        if self.CmdBrowFunc:
            key = self.GetSelectedData()
            if self.itemDataMap.has_key(key):
                self.CmdBrowFunc(key)

    def OnURL(self, event):
        if self.CmdDblClick:
            key = self.GetSelectedData()
            if self.itemDataMap.has_key(key):
                self.CmdDblClick(key)
      
    def GetListCtrl(self):
        return self


    def Populate(self, rowdata):
        self.DeleteAllItems()
        for row in rowdata:
            key = hash(row)
            self.itemDataMap[key] = row
            item_idx = self.InsertRow(key, row)

class HTMLDescrption(html.HtmlWindow):
    def __init__(self, parent, btconfig, addfunc=None):
        html.HtmlWindow.__init__(self, parent, -1, size=(-1,-1), style=wx.SUNKEN_BORDER)
        self.SetBorders(4)
        self.CmdAddFunc = addfunc
        wx.EVT_COMMAND_RIGHT_CLICK(self, -1, self.OnRightClick) # wxMSW
        wx.EVT_RIGHT_UP(self, self.OnRightClick) # wxGTK 

    def OnLinkClicked(self, link):
        if ".torrent" in link.GetHref():
            if self.CmdAddFunc:
                self.CmdAddFunc(link.GetHref())

    def OnRightClick(self, event):
        if not hasattr(self, "htmlpopID1"):   
            self.htmlpopID1 = wx.NewId()
            wx.EVT_MENU(self, self.htmlpopID1, self.OnViewSource)

        htmlmenu = wx.Menu()
        htmlmenu.Append(self.htmlpopID1, _("View Source"), _("View Source"))
        self.PopupMenu(htmlmenu, self.ScreenToClient(wx.GetMousePosition()))
        htmlmenu.Destroy()

    def OnViewSource(self, event):
        import  wx.lib.dialogs

        source = self.GetParser().GetSource()

        dlg = wx.lib.dialogs.ScrolledMessageDialog(self, source, _("HTML Source"))
        dlg.ShowModal()
        dlg.Destroy()


class RSSPanel(wx.Panel):
    def __init__(self, parent, btconfig, path="", pos=wx.DefaultPosition, size=(100,100), 
            bmps = None, addfunc=None):
        wx.Panel.__init__(self, parent, -1)

        if addfunc:
            self.AddTorrent = addfunc

        self.rowdata = []
        self.feeds = []
        self.descriptions = {}
        self.rendering = False
        
        if win32_flag:
            self.rss_file = join(btconfig['path'], "rssfeeds.ini")
        else:
            self.rss_file = join(os.path.expanduser('~/.Rufus'), "rssfeeds.ini")            
            
        self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER)
        self.splitter.SetMinimumPaneSize(40)
        self.htmlpanel = wx.Panel(self.splitter, -1)
        self.listpanel = wx.Panel(self.splitter, -1)
        self.list = RSSList(self.listpanel, btconfig, onclickfunc=self.OnClick, ondblclickfunc=self.OnDblClick, onurlfunc=self.OnURL, onbrowfunc=self.OnBrowser, oncopyfunc=self.OnCopy)
        self.html = HTMLDescrption(self.htmlpanel, btconfig, addfunc=self.AddTorrent)
        self.LoadFeeds() # Get feeds from rss ini
        self.editurl = wx.ComboBox(self, -1, "", size=(200,20), choices=self.feeds)
        if self.feeds:
            self.editurl.SetValue(self.feeds[0])

        self.updatebutt = wx.Button(self, -1, _("Update"))
        amendbutt = wx.Button(self, -1, _("Save/Del"))
        amendbutt.SetToolTipString(_("Save/delete the RSS feed URL"))

        colsizer = wx.FlexGridSizer(2, 1, 0, 0)
        htmlsizer = wx.FlexGridSizer(1, 1, 0, 0)
        listsizer = wx.FlexGridSizer(1, 1, 0, 0)
        topsizer = wx.FlexGridSizer(1, 3, 0, 0)
        topsizer.Add(amendbutt, 0, 0)
        topsizer.Add(self.editurl, 0, wx.EXPAND, 0)
        topsizer.Add(self.updatebutt, 0, 0)
        topsizer.AddGrowableCol(1)
        colsizer.Add(topsizer, 1, wx.EXPAND, 0)
        listsizer.Add(self.list, 1, wx.EXPAND, 0)
        self.listpanel.SetAutoLayout(True)
        self.listpanel.SetSizer(listsizer)
        listsizer.Fit(self.listpanel)
        listsizer.SetSizeHints(self.listpanel)
        listsizer.AddGrowableRow(0)
        listsizer.AddGrowableCol(0)
        htmlsizer.Add(self.html, 0, wx.EXPAND, 0)
        self.htmlpanel.SetAutoLayout(True)
        self.htmlpanel.SetSizer(htmlsizer)
        htmlsizer.Fit(self.htmlpanel)
        htmlsizer.SetSizeHints(self.htmlpanel)
        htmlsizer.AddGrowableRow(0)
        htmlsizer.AddGrowableCol(0)
        self.splitter.SplitHorizontally(self.listpanel, self.htmlpanel, 153)
        colsizer.Add(self.splitter, 1, wx.EXPAND, 1)
        self.SetAutoLayout(True)
        self.SetSizer(colsizer)
        colsizer.Fit(self)
        colsizer.SetSizeHints(self)
        colsizer.AddGrowableRow(1)
        colsizer.AddGrowableCol(0)


        wx.EVT_BUTTON(self, self.updatebutt.GetId(), self.Populate)
        wx.EVT_BUTTON(self, amendbutt.GetId(), self.Amend)
        wx.EVT_SIZE(self, self.OnSize)

    def AddTorrent(self, url):
        print url
    
    def OnSize(self, event):
        self.Layout()
        if self.splitter.GetSashPosition() > 0:
            self.splitter.SetSashPosition(self.splitter.GetSashPosition())
        
    def OnClick(self, key):
        wx.CallAfter(self.RenderHtml, self.RenderHtml(key))
            
    def OnDblClick(self, key):
        desc = self.descriptions.get(key)
        if desc:
            self.AddTorrent(desc[5])

    def OnBrowser(self, key):
        desc = self.descriptions.get(key)
        if desc:
            Thread(target = self._OpenUrl, args = [desc[5]]).start()

    def OnCopy(self, key):
        desc = self.descriptions.get(key)
        if desc:
            clipdata = wx.TextDataObject() 
            clipdata.SetText(desc[5]) 
            wx.TheClipboard.Open() 
            wx.TheClipboard.SetData(clipdata) 
            wx.TheClipboard.Close() 
  
    def OnURL(self, key, type=0):
        wx.CallAfter(self.RenderHtml, self.RenderHtml(key))


    def Amend(self, event):
        item = self.editurl.GetValue()
        key = self.editurl.GetSelection()
        if item != "":
            if item in self.feeds:
                print "Deleting RSS entry %s" % item
                self.feeds.remove(item)
            else:
                print "Adding RSS entry %s" % item
                self.feeds.append(item)

            self.SaveFeeds() ## Save Changes
            self.editurl.Clear()
            self.editurl.SetValue("")
            if self.feeds: # repopulate combobox
                for f in self.feeds:
                    self.editurl.Append(f)


    def GetFeed(self, url):
        #disable update button to stop hammering of RSS feed by user
        self.updatebutt.Enable(False)

        t = T_GetFeed(self.Getdata, "", url)
        t.start()


    def Getdata(self, params, result):
        import time
        time.sleep(0.01)
        self.FeedResults(params, result)


    def FeedResults(self, params, result):
        from html2text import html2text

        self.html.SetPage("")
        self.rowdata = []
        self.descriptions = {}  

        #re-enable update button
        self.updatebutt.Enable(True)

        if result.entries:     

            #feed title
            feedtitle = result.feed.title

            #base URL
            feedlink = result.feed.link
            feedbase = result.feed.title_detail.base

            for entry in result.entries:
##                print entry

                url = "..."
                try:
                    url = entry.enclosures[0].url
                except:
                    url = entry.links[0].href

                titlelink = entry.get('link', "")
                entrytitle = entry.get('title', "")
                entrysummary = entry.get('summary', "")
                fixed_row = html2text(entrytitle)
                row = (fixed_row[:len(fixed_row)-1], url) # removes CR from end of string (thanks to Matias for spotting this one)
                key = hash(row)
                self.rowdata.append(row)
                self.descriptions[key] = feedbase, feedtitle, titlelink, entrytitle , entrysummary, url

            self.list.Populate(self.rowdata)
        else:
            row = (_("No data in RSS feed"),"...")
            key = hash(row)
            self.rowdata.append(row)
            self.list.Populate(self.rowdata)



    def Populate(self, e=None):
        url = self.editurl.GetValue()
        i = 0
        found = False
        while i < self.editurl.GetCount():
            if self.editurl.GetString(i) == url:
                found = True
                break
            i += 1
        
        if not found:
            self.editurl.Insert(url, 0)
        self.GetFeed(url)

    def RenderHtml(self, key):
        desc = self.descriptions.get(key)
        if desc and not self.rendering:
            self.rendering = True
            page =  "<html> \n" \
                   +"<head> \n" \
                   +"    <base href=" + desc[0] + "> \n" \
                   +"</head> \n" \
                   +"<body> \n" \
                   +"       <table width='100%' bgcolor='#cccccc' cellpadding='0' cellspacing='0' border='0'> \n" \
                   +"               <tr><td> \n" \
                   +"                       &nbsp;<font face='Verdana,Sans-serif' size=10pt color='#000000'><a href='" + desc[0] + "'><b>Feed: </b>" + desc[1] + "</a><br> \n" \
                   +"                       &nbsp;<a href='" + desc[2] + "'><b>Title: </b>" + desc[3] + "</a><br></font> \n" \
                   +"               </td><td align='right'> \n" \
                   +"               </td></tr> \n" \
                   +"               <tr bgcolor='#666666' height='1'><td colspan='2'></td></tr> \n" \
                   +"       </table> \n" \
                   +"       <table width='100%' cellpadding='2' cellspacing='2' border='0'><tr><td> \n" \
                   +"               " + desc[4] +" \n" \
                   +"               </td></tr> \n" \
                   +"       </table> \n" \
                   +"       </body> \n" \
                   +"</html> \n"
         self.html.SetPage(page)
        self.rendering = False


    def _OpenUrl(self, url):
        try:
            webbrowser.open_new(url)
        except:
            pass

            
    def OnUrlClick(self, event):
        url = self.tlabels[1].GetLabel()
        url = "http://%s/" % (urlparse.urlparse(url)[1])
        Thread(target = self._OpenUrl, args = [url]).start()


    def SaveFeeds(self):
        print 'Saving RSS Feeds:', self.rss_file
        try:
            cp = ConfigParser.ConfigParser()
            cp.add_section('RSS feeds')
            i = 0
            for f in self.feeds:
               cp.set('RSS feeds', str(i), f)
               i += 1
                   
            file = open(self.rss_file, 'w')
            cp.write(file)
            file.close()
        except IOError, e:
            print "ERROR: writing to RSS ini file -", str(e)
        except:
            print "ERROR: writing to RSS ini file"    

    def LoadFeeds(self):
        if exists(self.rss_file):
            print 'Loading RSS Feeds:', self.rss_file
            try:
                cp = ConfigParser.ConfigParser()
                file = open(self.rss_file, 'r')
                cp.readfp(file)
                items = cp.items('RSS feeds')

                for key, param in items:
                    self.feeds.append(param)

                file.close()
            except IOError, e:
                print "ERROR: accessing rssfeeds.ini - ", str(e)
            except (ConfigParser.MissingSectionHeaderError, ConfigParser.NoSectionError), e:
                print "ERROR: processing rssfeeds.ini - ", str(e)


if __name__ == "__main__":
    _ = lambda x: x # needed for gettext
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, '', size=(800,500))

    ppp = RSSPanel(frame, BTConfig())
    ppp.Show(True)
    frame.Show(True)

    app.MainLoop()

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.