Diary?

2007-10-04
Thu

(20:11)

世界樹の迷宮の続編が出るようだ。今年の冬に発売らしいが、ちょっとまてその時期俺多分死にかけてるぞ。まあ死にかけていても買うしやるけどね。

しかし前作とディレクターが違うってのが少し心配ではある。一応、前作でストーリーを書いてた人でまったくの外様ってわけでもないので、杞憂かもしれないけど。

(21:46)

前にも書いた気がするけど俺は引責辞任と言う言葉はおかしいと思っていて、これはどう考えても無責任辞任だろう。責任を取るってのは自分のしでかしたことに収集をつけることを指すはずで、本来なら辞めるのは一通りのことをやってからだろうし、そもそもそんだけの能力があったら辞める必要もないと思う。

(23:42)

昨日書いたアレを Tkinter で GUI バージョンにしてみた。あと mpg321 でも OK っぽかったのでそっちを使うように変更。例によって超手抜きだ。

#!/usr/bin/env python
 
##################################
####### Utility functions ########
##################################
import feedparser
import re
import urllib2
from htmllib import HTMLParser
from formatter import AbstractFormatter, NullWriter
 
def get_mp3_url_and_text(url):
  print 'getting %s ...' % (url)
  text = urllib2.urlopen(url).read()
  url = get_mp3_url(text)
  transscript = get_text(text)
  return url, transscript
 
def get_mp3_url(text):
  parser = HTMLParser(AbstractFormatter(NullWriter()))
  parser.feed(text)
  for i in parser.anchorlist:
    if i.endswith('.mp3'):
      return i
  else:
    raise Exception('mp3 url has not found.')
 
def get_text(text):
  transscript = []
  flag = False
  for line in text.replace('\r\n', '\n').replace('\r', '\n').split('\n'):
    if 'articleheadline' in line:
      flag = True
    if flag:
      transscript.append(trim_tag(line))
    if flag and '<script type="text/javascript" language="JavaScript">' in line: break
  return re.sub('\n+', '\n', '\n'.join(transscript))
 
def trim_tag(text):
  return re.sub(r'<.+?>', '', text).replace('&nbsp;', ' ').replace('&lt;', '<').replace('&gt;', '>').replace('&amp;', '&')
 
def get_entries():
  try:
    feed = feedparser.parse('http://www.voanews.com/specialenglish/customCF/RecentStoriesRSS.cfm?keyword=TopStories')
    for v in feed.entries:
      yield v.link, v.title
  except Exception, e:
    import traceback
    traceback.print_exc()
 
############################
###### Player Thread ######
############################
import subprocess
import threading
 
class PlayerThread(threading.Thread):
  def __init__(self, url):
    threading.Thread.__init__(self)
    self.proc = None
    self.pid = None
    self.url = url
    
  def run(self):
    self.proc = subprocess.Popen(['mpg321', '-q', self.url])
    self.pid = self.proc.pid
    self.proc.wait()
    return
  
  def stop(self):
    if self.pid == None: return
    subprocess.call(['kill', '-KILL', str(self.pid)])
    self.pid = None
 
########################
####### Tkinter ########
########################
 
from Tkinter import *
from ScrolledText import ScrolledText
 
class Application(Frame):
  def say_hi(self):
    print "hi there, everyone!"
 
  def createWidgets(self):
    self.widgets = []
    for link, title in get_entries():
      self.widgets.append(self.new_widget(link, title))
    self.quit = Button(self)
    self.quit["text"] = "QUIT"
    self.quit["fg"]   = "red"
    self.quit["command"] =  self.exit
    self.quit.pack({"side": "left"})
    self.script = ScrolledText(self, height=10)
    self.script.pack({"side": "bottom"})
    self.player = None
  
  def new_widget(self, url, title):
    btn = Button(self)
    btn["text"] = title
    btn["command"] = lambda: self.listen(url)
    btn.pack({"side": "top"})
    return btn
  
  def listen(self, url):
    self.stop()
    source, transscript = get_mp3_url_and_text(url)
    self.script.delete('1.0', self.script.index(END))
    #self.script.config(state=NORMAL)
    self.script.insert(END, transscript)
    #self.script.config(state=DISABLED)
    self.player = PlayerThread(source)
    self.player.start()
  
  def stop(self):
    if self.player != None and self.player.isAlive():
      self.player.stop()
      self.player.join()
  
  def exit(self):
    self.stop()
    self.master.quit()
  
  def __init__(self, master=None):
    Frame.__init__(self, master)
    self.pack()
    self.createWidgets()
 
if __name__ == '__main__':
  root = Tk()
  app = Application(master=root)
  app.mainloop()
  root.destroy()

Tkinter、便利っちゃ便利なんだけど面倒な部分もあるし何より資料が少ない。 Python のオフィシャルにはメカニズムに関する物しかなくて、基本的には「Tcl/Tk のマニュアル読んでそこから Python の Tkinter モジュールにラッピングしろ、対応付けの説明はしたぞ」って感じ。なので、こればっかりは Python のオフィシャルに期待するわけには行かないなあ。

現状では見てくれとトランススクリプトの読み易さが非常に可哀想な事になっているので、そこんところは改良が必要だな。というか、 PyGtk か PyQt でやった方が良かったかも知れん。

Creative Commons
この怪文書はクリエイティブ・コモンズ・ライセンスの元でライセンスされています。引用した文章など Kuwata Chikara に著作権のないものについては、それらの著作権保持者に帰属します。