views:

196

answers:

2

I have a little program that goes to news aggregater's, gets the hrefs, and returns in a window. I want to have multiple windows open if multiple sites are choosen, right now, it will only go to the first one in a list, and completes perfectly. I assume I am not passing the the contents of the list properly to the next step in my program.

import wx
import urllib2
from BeautifulSoup import BeautifulSoup
import re
from pyparsing import makeHTMLTags, originalTextFor, SkipTo, Combine
import wx
import wx.html
global P

siteDict = {0:'http://www.reddit.com', 1:'http://www.digg.com',2:'http://www.stumbleupon.com', 3:'news.google.com'}

class citPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)
        allSites = ['Reddit', 'Digg', 'StumbleUpon', 'Google News']
        wx.StaticText(self, -1, "Choose the Sites you would like Charlie to Visit:", (45, 15))      
        self.sitList = wx.CheckListBox(self, 20, (60, 50), wx.DefaultSize, allSites)

class nextButton(wx.Button):
    def __init__(self, parent, id, label, pos):
        wx.Button.__init__(self, parent, id, label, pos)

class checkList(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(400, 300))
        self.panel = citPanel(self, -1)
        nextButton(self.panel, 30, 'Ok', (275, 50))
        self.Bind(wx.EVT_BUTTON, self.Clicked)       
        self.Centre()
        self.Show(True)

    def Clicked(self, event):
        checkedItems = [i for i in range(self.panel.sitList.GetCount()) if self.panel.sitList.IsChecked(i)]
        print checkedItems
        r = [siteDict[k] for k in checkedItems]
        print r
        for each in r:
            pre = '<HTML><head><title>Page title</title></head>'
            post = '</HTML>'
            site = urllib2.urlopen(each)
            html=site.read()
            soup = BeautifulSoup(html)
            tags = soup.findAll('a')

            soup1 = BeautifulSoup(''.join(str(t) for t in tags))
            print soup1.prettify()

            aTag,aEnd = makeHTMLTags("A")

            aTag = originalTextFor(aTag)
            aEnd = originalTextFor(aEnd)

            aLink = aTag + SkipTo(aEnd) + aEnd
            aLink.setParseAction(lambda tokens : ''.join(tokens))

            links = aLink.searchString(html)

            out = []
            out.append(pre)
            out.extend(['  '+lnk[0] for lnk in links])
            out.append(post)

            P= '\n'.join(out)
            print type(P)

            print P




            class MyHtmlFrame(wx.Frame):
                def __init__(self, parent, title):
                    wx.Frame.__init__(self, parent, -1, title)
                    html = wx.html.HtmlWindow(self)
                    if "gtk2" in wx.PlatformInfo:
                        html.SetStandardFonts()

                    html.SetPage(P)


            app = wx.PySimpleApp()
            frm = MyHtmlFrame(None, "Charlie")
            frm.Show()
            app.MainLoop()


    #event.Skip()




    #self.Destroy()



app = wx.App()



checkList(None, -1, 'Charlie')
app.MainLoop()

I have some print statements mixed in for debugging. So, any help, much appreciated. Also, if they all ended up on the same window, that would be fine too. Just trying to get past the only doing the first one

A: 

I am not familiar with WxPython but it appears that you have two MainLoops running.
I got your program to open two windows when I commented out the two lines as shown below:

        class MyHtmlFrame(wx.Frame):
            def __init__(self, parent, title):
                wx.Frame.__init__(self, parent, -1, title)
                html = wx.html.HtmlWindow(self)
                if "gtk2" in wx.PlatformInfo:
                    html.SetStandardFonts()

                html.SetPage(P)


        #app = wx.PySimpleApp()
        frm = MyHtmlFrame(None, "Charlie")
        frm.Show()
        #app.MainLoop()
DoR
Did it open one from each site? Even with the two lines commented out, there is the original window, the wxpython stdout/stdin windows, and the first checked site. Even if two are checked, only one shows
Kevin
Yes it opens a window for each site for me.
DoR
+1  A: 

Eeek! You're defining your MyHTMLFrame class -inside- an event handler function (not a good idea).

I can't run the script as I don't have the module PyParsing (always make samples that have as little dependencies as possible...)

Therefore, I'm not sure if this code runs, but it should give you the general idea. Here is the code modified, I've only changed a bit after the clicked() function

    def Clicked(self, event):
        checkedItems = [i for i in range(self.panel.sitList.GetCount()) if self.panel.sitList.IsChecked(i)]
        print checkedItems
        r = [siteDict[k] for k in checkedItems]
        print r
        for each in r:
            pre = '<HTML><head><title>Page title</title></head>'
            post = '</HTML>'
            site = urllib2.urlopen(each)
            html=site.read()
            soup = BeautifulSoup(html)
            tags = soup.findAll('a')

            soup1 = BeautifulSoup(''.join(str(t) for t in tags))
            print soup1.prettify()

            aTag,aEnd = makeHTMLTags("A")

            aTag = originalTextFor(aTag)
            aEnd = originalTextFor(aEnd)

            aLink = aTag + SkipTo(aEnd) + aEnd
            aLink.setParseAction(lambda tokens : ''.join(tokens))

            links = aLink.searchString(html)

            out = []
            out.append(pre)
            out.extend(['  '+lnk[0] for lnk in links])
            out.append(post)

            P= '\n'.join(out)
            print type(P)

            print P

            # create the html frame, pass it in your string
            frm = MyHtmlFrame(None, "Charlie", P)
            frm.Show()



class MyHtmlFrame(wx.Frame):
def __init__(self, parent, title, page):  # pass it in the page variable
    wx.Frame.__init__(self, parent, -1, title)
    html = wx.html.HtmlWindow(self)
    if "gtk2" in wx.PlatformInfo:
        html.SetStandardFonts()

    html.SetPage(page)



app = wx.App()

checkList(None, -1, 'Charlie') 
checkList.Show()   # show first frame, which opens other windows
app.MainLoop()

ugh I hate indenting by 4 spaces to start code in StackOverflow. Hope this works for you!

Steven Sproat
I agree with you on the four spaces. That seemed to do it. I am new to everything, so I tend to hit up against walls pertaining to syntax and the pythonic way of doing things, thanks
Kevin
Glad to help. I found the best way to get used to wx is just by playing with it more and more, eventually everything will "click" :)
Steven Sproat