添加了下载页的treeview

1 view
Skip to first unread message

lerosua

unread,
Apr 22, 2009, 8:49:00 AM4/22/09
to gmbox-dev
添加了下载页的treeview
右键下载的话,会把下载的文件加到下载页的treeview里。
现在这个下载方式应该只能是暂时的,我觉得应该是下载了就加到那个treeview里,然后在那里统一分配资源下载。
当然那个页也可以扩展成已下载,正在下载等。

更改了__init__里原来几个变量的名字。因为有几个分页,第一个是榜单下载,于是变量基本叫 list_xxx, 第三页是下载管理,于是叫
down_xxx, 第二页是搜索的,打算叫search_xxx,
暂时是这些想法。

崔贵林

unread,
Apr 22, 2009, 10:56:34 AM4/22/09
to gmbo...@googlegroups.com
lerosua:
     仿照你的添加下载列表实现了播放列表的添加。
     更改榜单下载中的试听为自动循环播放。
     改MainWindow为可执行属性
     改gmbox下载目录为top100
     你看看!

2009/4/22 lerosua <ler...@gmail.com>



--
崔贵林 csip
E-mail:  amo...@gmail.com
MSN :  amo...@msn.cn
  Cell  :  13260179436
gmbox.py
MainWindow.py

lerosua

unread,
Apr 22, 2009, 11:02:25 AM4/22/09
to gmbo...@googlegroups.com
hi:

不错,帮你提交了,忘了加MainWindow的执行属性了。下次提交时再改吧。
>#!/usr/bin/env python
># -*- coding: utf-8 -*-
>import re,urllib,urllib2,sys,os,time
>from HTMLParser import HTMLParser
>import thread
>
>reload(sys)
>sys.setdefaultencoding('utf8')
>
>songlists={
>u'华语新歌':('chinese_new_songs_cn',100),
>u'欧美新歌':('ea_new_songs_cn',100),
>u'华语热歌':('chinese_songs_cn',200),
>u'欧美热歌':('ea_songs_cn',200),
>u'日韩热歌':('jk_songs_cn',200),
>u'流行热歌':('pop_songs_cn',100),
>u'摇滚热歌':('rock_songs_cn',100),
>u'嘻哈热歌':('hip-hop_songs_cn',100),
>u'影视热歌':('soundtrack_songs_cn',100),
>u'民族热歌':('ethnic_songs_cn',100),
>u'拉丁热歌':('latin_songs_cn',100),
>u'R&B热歌':('rnb_songs_cn',100),
>u'乡村热歌':('country_songs_cn',100),
>u'民谣热歌':('folk_songs_cn',100),
>u'灵歌热歌':('soul_songs_cn',100),
>u'轻音乐热歌':('easy-listening_songs_cn',100),
>u'爵士蓝调热歌':('jnb_songs_cn',100)
>}
>urltemplate="http://www.google.cn/music/chartlisting?q=%s&cat=song&start=%d"
>
>def unistr(m):
> return unichr(int(m.group(1)))
>def sizeread(size):
> if size>1024*1024:
> return '%0.2fMB' % (float(size)/1024/1024)
> elif size>1024:
> return '%0.2fKB' % (float(size)/1024)
> else:
> return '%dB' % size
>
>class ListParser(HTMLParser):
> def __init__(self):
> HTMLParser.__init__(self)
> self.songlist=[]
> self.songtemplate={
> 'title':'',
> 'artist':'',
> 'id':''}
> self.tmpsong=self.songtemplate.copy()
> (self.isa,self.ispan,self.insongtable,self.tdclass)=(0,0,0,'')
>
> def handle_starttag(self, tag, attrs):
> if tag == 'a':
> self.isa=1
> if self.insongtable and self.tdclass == 'Download BottomBorder':
> for (n,v) in attrs:
> if n=='onclick':
> #self.tmpsong['link']=re.match(r'.*"(.*)".*"(.*)".*',v,re.S).group(1)
> self.tmpsong['id']=re.match(r'.*id%3D(.*?)\\x26.*',v,re.S).group(1)
> if tag == 'table':
> for (n,v) in attrs:
> if n=='id' and v=='song_list':
> self.insongtable=1
> if self.insongtable and tag == 'td':
> for (n,v) in attrs:
> if n=='class':
> self.tdclass=v
> if tag == 'span':
> self.ispan=1
>
> def handle_endtag(self, tag):
> if tag == 'a':
> self.isa=0
> if tag == 'table':
> self.insongtable=0
> if tag == 'span':
> self.ispan=0
>
> def handle_data(self, data):
> if self.insongtable and (self.isa or self.ispan):
> if self.tdclass == 'Title BottomBorder':
> self.tmpsong['title']=data
> elif self.tdclass == 'Artist BottomBorder':
> if self.tmpsong['artist']:
> self.tmpsong['artist']+=u'、'+data
> else:
> self.tmpsong['artist']=data
> elif self.tdclass == 'Download BottomBorder':
> self.songlist.append(self.tmpsong.copy())
> self.tmpsong=self.songtemplate.copy()
>
> def __str__(self):
> return '\n'.join(['Title="%s" Artist="%s" ID="%s"'%
> (song['title'],song['artist'],song['id']) for song in self.songlist])
>
>
>class SongParser(HTMLParser):
> def __init__(self):
> HTMLParser.__init__(self)
> self.url=''
> def handle_starttag(self, tag, attrs):
> if tag == 'a':
> for (n,v) in attrs:
> if n=='href' and re.match(r'/music/top100/url.*',v):
> self.url='http://www.google.cn'+v
> def __str__(self):
> return self.url
>
>
>class Download:
> def __init__(self, remote_uri, local_uri):
> if os.path.exists("top100/"+local_uri):
> print local_uri,u'已存在!'
> else:
> print u'正在下载:',local_uri
> self.T=self.startT=time.time()
> (self.D,self.speed)=(0,0)
> urllib.urlretrieve(remote_uri, "top100/"+local_uri+'.downloading', self.update_progress)
> os.rename("top100/"+local_uri+'.downloading', "top100/"+local_uri)
> os.system('mid3iconv -e gbk "top100/'+local_uri + '"')
> speed=os.stat("top100/"+local_uri).st_size/(time.time()-self.startT)
> print '\r['+''.join(['=' for i in range(50)])+ \
> '] 100.00%% %s/s '%sizeread(speed)
> def update_progress(self, blocks, block_size, total_size):
> if total_size>0 :
> percentage = float(blocks) / (total_size/block_size+1) * 100
> if int(time.time()) != int(self.T):
> self.speed=(blocks*block_size-self.D)/(time.time()-self.T)
> (self.D,self.T)=(blocks*block_size,time.time())
> print '\r['+''.join(['=' for i in range((int)(percentage/2))])+'>'+ \
> ''.join([' ' for i in range((int)(50-percentage/2))])+ \
> ('] %0.2f%% %s/s ' % (percentage,sizeread(self.speed))),
>
>class Listen:
> def __init__(self, remote_uri, local_uri):
> self.remote_uri= remote_uri
> self.local_uri=local_uri
> thread.start_new_thread(self.download,(local_uri,))
> time.sleep(1)
> thread.start_new_thread(self.play,(local_uri,))
>
> def play(self,a):
> os.system('mid3iconv -e gbk "top100/'+self.local_uri+'.cache"')
> os.system('pkill mpg123')
> os.system('mpg123 "top100/'+self.local_uri+'.cache"')
> os.rename('top100/'+self.local_uri+'.cache', 'top100/'+self.local_uri)
>
> def download(self,a):
> print u'正在缓冲:',self.local_uri
> self.T=self.startT=time.time()
> (self.D,self.speed)=(0,0)
> urllib.urlretrieve(self.remote_uri, 'top100/'+self.local_uri+'.cache', self.update_progress)
> speed=os.stat('top100'+self.local_uri).st_size/(time.time()-self.startT)
> print '\r['+''.join(['=' for i in range(50)])+ \
> '] 100.00%% %s/s '%sizeread(speed)
> def update_progress(self, blocks, block_size, total_size):
> if total_size>0 :
> percentage = float(blocks) / (total_size/block_size+1) * 100
> if int(time.time()) != int(self.T):
> self.speed=(blocks*block_size-self.D)/(time.time()-self.T)
> (self.D,self.T)=(blocks*block_size,time.time())
> #print blocks
> #print total_size/block_size
> print '\r['+''.join(['=' for i in range((int)(percentage/2))])+'>'+ \
> ''.join([' ' for i in range((int)(50-percentage/2))])+ \
> ('] %0.2f%% %s/s ' % (percentage,sizeread(self.speed))),
>
>class Lists:
> def __init__(self,stype):
> self.songlist=[]
> if stype in songlists:
> p=ListParser()
> print u'正在获取"'+stype+u'"的歌曲列表',
> sys.stdout.flush()
> for i in range(0,songlists[stype][1],25):
> #for i in range(0,25,25):
> html=urllib2.urlopen(urltemplate%(songlists[stype][0],i)).read()
> p.feed(re.sub(r'&#([0-9]{2,5});',unistr,html))
> print '.',
> sys.stdout.flush()
> self.songlist=p.songlist
> print 'done!'
> else:
> #raise Exception
> print u'未知列表:"'+str(stype)+u'",仅支持以下列表: '+u'、'.join(
> ['"%s"'%key for key in songlists])
>
> def __str__(self):
> return '\n'.join(['Title="%s" Artist="%s" ID="%s"'%
> (song['title'],song['artist'],song['id']) for song in self.songlist]) \
> +u'\n共 '+str(len(self.songlist))+u' 首歌.'
>
> def downone(self,i=0):
> song=self.songlist[i]
> local_uri=song['title']+'-'+song['artist']+'.mp3'
> if os.path.exists('top100/'+local_uri):
> print local_uri,u'已存在!'
> return
> songurl="http://www.google.cn/music/top100/musicdownload?id="+song['id']
> s=SongParser()
>
> try:
> text = urllib2.urlopen(songurl).read()
> except:
> print "Reading URL Error: %s" % local_uri
> return
>
> s.feed(text)
> Download(s.url,local_uri)
>
> def listen(self,start=0):
> for i in range(start,len(self.songlist)):
> song=self.songlist[i]
> local_uri=song['title']+'-'+song['artist']+'.mp3'
> if os.path.exists('top100/'+local_uri):
> os.system('mid3iconv -e gbk "top100/'+local_uri + '"')
> os.system('pkill mpg123')
> os.system('mpg123 "top100/'+local_uri + '"')
> continue
> songurl="http://www.google.cn/music/top100/musicdownload?id="+song['id']
> s=SongParser()
>
> try:
> text = urllib2.urlopen(songurl).read()
> except:
> print "Reading URL Error: %s" % local_uri
> continue
>
> s.feed(text)
> Listen(s.url,local_uri)
> return
>
> def get_title(self,i=0):
> song=self.songlist[i]
> return song['title']
>
> def get_artist(self,i=0):
> song=self.songlist[i]
> return song['artist']
>
> def downall(self):
> for i in range(len(self.songlist)):
> self.downone(i)
>
> def download(self,songids=[]):
> for i in songids:
> self.downone(i)
>
>if __name__ == '__main__':
> l=Lists(u'华语新歌')
> #print l
> #l.download([0,2,6])
> l.downall()
>

>#!/usr/bin/env python
># -*- coding: utf-8 -*-
>
>import os
>import gtk
>import gtk.glade
>import gmbox
>import thread
>import pynotify
>
>(COL_NUM, COL_TITLE, COL_ARTIST,COL_DOWN) = range(4)
>class MainWindow():
> def __init__(self):
>
> self.gladefile="gmbox.glade"
> self.xml=gtk.glade.XML(self.gladefile)
> self.window = self.xml.get_widget("window_main")
> self.notebook = self.xml.get_widget("notebook_top")
> self.notebook.set_show_tabs(False)
>
> dic={"on_pbutton_album_clicked":self.btnAlbum_clicked,
> "on_pbutton_down_clicked": self.btnDown_clicked,
> "on_pbutton_list_clicked": self.btnList_clicked,
> "on_pbutton_searched_clicked": self.btnSearched_clicked,
> "on_pbutton_about_clicked": self.btnAbout_clicked}
> self.xml.signal_autoconnect(dic)
>
> #page 1
> vbox= self.xml.get_widget("vbox_p1")
> hbox = gtk.HBox()
> opt = gtk.combo_box_new_text()
> for slist in gmbox.songlists:
> opt.append_text(slist)
> opt.set_active(0)
> hbox.pack_start(opt, False)
> self.list_button = gtk.Button('获取列表')
> size = self.list_button.size_request()
> self.list_button.set_size_request(size[0]+50, -1)
> opt.set_size_request(size[0]+150, -1)
> self.list_button.connect('clicked', self.doSearch, opt)
> hbox.pack_start(self.list_button, False)
> vbox.pack_start(hbox, False)
>
> scroll = gtk.ScrolledWindow()
> scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
> scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
> self.list_tree = self.getListTreeView()
> self.list_tree.set_rules_hint(True)
> scroll.add(self.list_tree)
> vbox.pack_start(scroll)
>
>
> #page playlist
> playlist_vbox= self.xml.get_widget("vbox_p4")
>
> playlist_scroll = gtk.ScrolledWindow()
> playlist_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
> playlist_scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
> playlist_tree = self.getPlaylistTreeView()
> playlist_tree.set_rules_hint(True)
> playlist_scroll.add(playlist_tree)
> playlist_vbox.pack_start(playlist_scroll)
>
>
> #setup system tray icon
> self.setupSystray()
>
> #page down
> down_vbox= self.xml.get_widget("vbox_p3")
> down_scroll = gtk.ScrolledWindow()
> down_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
> down_scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
> down_tree = self.getDownTreeView()
> down_tree.set_rules_hint(True)
> down_scroll.add(down_tree)
> down_vbox.pack_start(down_scroll)
>
> self.window.set_title("GMBox")
> self.window.set_default_size(800, 600)
> self.window.connect('destroy', gtk.main_quit)
> self.window.show_all();
>
> def setupSystray(self):
> self.systray = gtk.StatusIcon()
> self.systray.set_from_file("systray.png")
> self.systray.connect("activate", self.systrayCb)
> self.systray.connect('popup-menu', self.systrayPopup)
> self.systray.set_tooltip("Click to toggle window visibility")
> self.systray.set_visible(True)
>
> pynotify.init("Some Application or Title")
> self.notification = pynotify.Notification("Title", "body", "dialog-warning")
> self.notification.set_urgency(pynotify.URGENCY_NORMAL)
> self.notification.set_timeout(1)
> return
>
> def systrayCb(self, widget):
> """Check out window's status"""
> if self.window.get_property('visible'):
> self.window.hide()
> else:
> self.window.deiconify()
> self.window.present()
>
> def systrayPopup(self, statusicon, button, activate_time):
> """Create and show popup menu"""
> popup_menu = gtk.Menu()
> restore_item = gtk.MenuItem("Restore")
> restore_item.connect("activate", self.systrayCb)
> quit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
> quit_item.connect("activate", gtk.main_quit)
> popup_menu.append(restore_item)
> popup_menu.append(quit_item)
> popup_menu.show_all()
> time = gtk.get_current_event_time()
> popup_menu.popup(None, None, None, 0, time)
>
>
> def btnAlbum_clicked(self,widget):
> self.notebook.set_current_page(0)
>
> def btnList_clicked(self,widget):
> self.notebook.set_current_page(3)
>
> def btnSearched_clicked(self,widget):
> self.notebook.set_current_page(1)
>
> def btnDown_clicked(self,widget):
> self.notebook.set_current_page(2)
>
> def btnAbout_clicked(self,widget):
> self.notebook.set_current_page(4)
>
> def getDownTreeView(self):
> #依次存入:歌曲编号,歌曲名,歌手,下载状态,下载进度
> self.down_model=gtk.ListStore(str,str,str,str)
> treeview = gtk.TreeView(self.down_model)
> treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_NUM)
> column = gtk.TreeViewColumn("编号", renderer, text=COL_NUM)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_TITLE)
> column = gtk.TreeViewColumn("歌曲", renderer, text=COL_TITLE)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_ARTIST)
> column = gtk.TreeViewColumn("歌手", renderer, text=COL_ARTIST)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_DOWN)
> column = gtk.TreeViewColumn("状态", renderer, text=COL_DOWN)
> column.set_resizable(True)
> treeview.append_column(column)
> return treeview
>
> def downList(self,text):
> """Hold song index and prepare for download"""
> self._songlist = gmbox.Lists(text)
>
> self.list_model.clear()
> for song in self._songlist.songlist:
> self.list_model.append(
> [self._songlist.songlist.index(song)+1,song['title'],song['artist']])
> self.list_button.set_sensitive(True)
>
> def doSearch(self,widget,opt):
> """Begin song list download thread"""
>
> text=opt.get_active_text().decode('utf8')
> self.list_button.set_sensitive(False)
> thread.start_new_thread(self.downList,(text,))
>
> def getListTreeView(self):
> """get hot song list treeview widget"""
> #依次存入:歌曲编号,歌曲名,歌手,专辑,长度,url
> self.list_model = gtk.ListStore(str, str, str)
> #self.list_model.connect("row-changed", self.SaveSongIndex)
>
>
> treeview = gtk.TreeView(self.list_model)
> treeview.connect('button-press-event', self.click_checker)
> treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_NUM)
> column = gtk.TreeViewColumn("编号", renderer, text=COL_NUM)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_TITLE)
> #renderer.set_property('editable', True)
> #renderer.connect("edited", self.on_cell_edited, None)
> column = gtk.TreeViewColumn("歌曲", renderer, text=COL_TITLE)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_ARTIST)
> #renderer.set_property('editable', True)
> #renderer.connect("edited", self.on_cell_edited, None)
> column = gtk.TreeViewColumn("歌手", renderer, text=COL_ARTIST)
> column.set_resizable(True)
> treeview.append_column(column)
>
># renderer = gtk.CellRendererText()
># renderer.set_data("column", COL_ALBUM)
># renderer.set_property('editable', True)
># #renderer.connect("edited", self.on_cell_edited, None)
># column = gtk.TreeViewColumn("专辑", renderer, text=COL_ALBUM)
># column.set_resizable(True)
># treeview.append_column(column)
>#
># renderer = gtk.CellRendererText()
># renderer.set_data("column", COL_SIZE)
># column = gtk.TreeViewColumn("长度", renderer, text=COL_SIZE)
># column.set_resizable(True)
># treeview.append_column(column)
> return treeview
>
>
> def getPlaylistTreeView(self):
> #依次存入:歌曲编号,歌曲名,歌手,专辑,长度,url
> self.playlist_model = gtk.ListStore(str, str, str)
> #self.model.connect("row-changed", self.SaveSongIndex)
>
>
> treeview = gtk.TreeView(self.playlist_model)
> #treeview.connect('button-press-event', self.click_checker)
> treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_NUM)
> column = gtk.TreeViewColumn("编号", renderer, text=COL_NUM)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_TITLE)
> #renderer.set_property('editable', True)
> #renderer.connect("edited", self.on_cell_edited, None)
> column = gtk.TreeViewColumn("歌曲", renderer, text=COL_TITLE)
> column.set_resizable(True)
> treeview.append_column(column)
>
> renderer = gtk.CellRendererText()
> renderer.set_data("column", COL_ARTIST)
> #renderer.set_property('editable', True)
> #renderer.connect("edited", self.on_cell_edited, None)
> column = gtk.TreeViewColumn("歌手", renderer, text=COL_ARTIST)
> column.set_resizable(True)
> treeview.append_column(column)
>
># renderer = gtk.CellRendererText()
># renderer.set_data("column", COL_ALBUM)
># renderer.set_property('editable', True)
># #renderer.connect("edited", self.on_cell_edited, None)
># column = gtk.TreeViewColumn("专辑", renderer, text=COL_ALBUM)
># column.set_resizable(True)
># treeview.append_column(column)
>#
># renderer = gtk.CellRendererText()
># renderer.set_data("column", COL_SIZE)
># column = gtk.TreeViewColumn("长度", renderer, text=COL_SIZE)
># column.set_resizable(True)
># treeview.append_column(column)
> return treeview
>
> def SetupPopup(self):
> time = gtk.get_current_event_time()
>
> popupmenu = gtk.Menu()
> menuitem = gtk.MenuItem('下载')
> menuitem.connect('activate', self.downone)
> popupmenu.append(menuitem)
>
> menuitem = gtk.MenuItem('试听')
> menuitem.connect('activate', self.listen)
> popupmenu.append(menuitem)
>
> menuitem = gtk.MenuItem('添加到播放列表')
> menuitem.connect('activate', self.addToPlaylist)
> popupmenu.append(menuitem)
>
> menuitem = gtk.MenuItem('删除已有下载')
> #menuitem.connect('activate', self.delete, selected)
> popupmenu.append(menuitem)
>
> popupmenu.show_all()
> popupmenu.popup(None, None, None, 0, time)
>
> def downone(self, widget):
>
> selected = self.list_tree.get_selection().get_selected()
> list_model,iter = selected
> num = self.list_model.get_value(iter,COL_NUM)
> artist = self.list_model.get_value(iter, COL_ARTIST)
> title = self.list_model.get_value(iter, COL_TITLE)
> self.down_model.append([num,title,artist,"start"])
>
> self.notification = pynotify.Notification("下载", self._songlist.get_title(self.path[0]), "dialog-warning")
> self.notification.set_timeout(1)
> self.notification.show()
> thread.start_new_thread(self._songlist.downone, (self.path[0],))
>
> def addToPlaylist(self, widget):
>
> selected = self.list_tree.get_selection().get_selected()
> list_model,iter = selected
> num = self.list_model.get_value(iter,COL_NUM)
> artist = self.list_model.get_value(iter, COL_ARTIST)
> title = self.list_model.get_value(iter, COL_TITLE)
> self.playlist_model.append([num,title,artist])
>
> self.notification = pynotify.Notification("添加到播放列表", self._songlist.get_title(self.path[0]), "dialog-warning")
> self.notification.set_timeout(1)
> self.notification.show()
>
> def listen(self, widget):
> self.notification = pynotify.Notification("试听", self._songlist.get_title(self.path[0]), "dialog-warning")
> self.notification.set_timeout(1)
> self.notification.show()
> thread.start_new_thread(self._songlist.listen, (self.path[0],))
>
> def click_checker(self, view, event):
> if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
> #selected,iter = view.get_selection().get_selected()
> #index = selected.get_value(iter, 0)
> #print index
>
> # Here test whether we have songlist, if have, show popup menu
> try:
> if self._songlist:
> self.SetupPopup()
> except:
> pass
>
> x = int(event.x)
> y = int(event.y)
> pth = view.get_path_at_pos(x, y)
>
> if not pth:
> pass
> else:
> self.path, col, cell_x, cell_y = pth
>
>def test():
> print "testing for thread"
>
>
>def main():
> win = MainWindow();
> gtk.gdk.threads_init()
> gtk.main()
>
>
>if __name__ == '__main__':
> main()

Reply all
Reply to author
Forward
0 new messages