Use a uri for communicating with modules.
--- /dev/null
+# Copyright (C) 2006 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import re
+
+from bbs_type_exception import BbsTypeError
+
+
+_base_reg_expr = re.compile("http://(?P<host>[^./]+\.2ch\.net)/(?P<board>[^/]+)/$")
+_cgi_reg_expr = re.compile("http://(?P<host>[^./]+\.2ch\.net)/test/read.cgi/(?P<board>[^/]+)/(?P<thread>[^/]+)/.*")
+
+
+class Type2ch:
+
+ def __init__(self, host=None, board=None, thread=None, uri=None):
+ if uri:
+ self._parse_uri(uri)
+ else:
+ if not host or not board:
+ raise BbsTypeError, "host and board, or uri must be specified"
+ self.uri = uri
+ self.host = host
+ self.board = board
+ self.thread = thread
+
+ def _parse_uri(self, uri):
+ self.uri = uri
+ self.bbs_type = None
+ self.host = None
+ self.board = None
+ self.thread = None
+
+ m = _base_reg_expr.match(self.uri)
+ if m:
+ self.bbs_type = "2ch"
+ self.host = m.group("host")
+ self.board = m.group("board")
+ else:
+ m = _cgi_reg_expr.match(self.uri)
+ if m:
+ self.bbs_type = "2ch"
+ self.host = m.group("host")
+ self.board = m.group("board")
+ self.thread = m.group("thread")
+
+ def is_board(self):
+ return not self.thread
+
+ def is_thread(self):
+ return self.thread
+
+ def clone_with_thread(self, thread):
+ if not thread:
+ raise ValueError, "parameter must not be empty"
+ return Type2ch(self.host, self.board, thread)
+
+ def get_uri_base(self):
+ return "http://" + self.host + "/" + self.board + "/"
+
+ def get_subject_txt_uri(self):
+ return self.get_uri_base() + "subject.txt"
+
+ def get_dat_uri(self):
+ if not self.thread:
+ raise BbsTypeError, "not specified thread"
+ return self.get_uri_base() + "dat/" + self.thread + ".dat"
+
+ def get_thread_uri(self):
+ if not self.thread:
+ raise BbsTypeError, "not specified thread"
+ return "http://" + self.host + "/test/read.cgi/" + \
+ self.board + "/" + self.thread + "/"
--- /dev/null
+# Copyright (C) 2006 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+class BbsTypeError(Exception):
+
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
--- /dev/null
+# Copyright (C) 2006 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from bbs_type_2ch import Type2ch
+from bbs_type_exception import BbsTypeError
+
+def get_type(uri):
+ bbs = Type2ch(uri=uri)
+ if bbs.bbs_type:
+ return bbs
+
+ raise BbsTypeError, \
+ "Not found a fit bbs type for the uri: " + uri
class GetRemote(threading.Thread):
- def __init__(self, bbs, board, on_end):
+ def __init__(self, bbs, board, uri, on_end):
super(GetRemote, self).__init__()
self.bbs = bbs
self.board = board
+ self.uri = uri
self.on_end = on_end
def run(self):
print "start get subject.txt"
- subjecttxt, lastmod = \
- subjecttxtfile.get_subjecttxt(self.bbs, self.board)
+ subjecttxt, lastmod = subjecttxtfile.get_subjecttxt(
+ self.bbs, self.board, self.uri)
datalist = load_idxfiles(self.bbs, self.board)
merge_subjecttxt(subjecttxt, datalist)
gobject.idle_add(self.on_end, datalist, lastmod)
from threadlistmodel import ThreadListModel
import windowlist
-import brdlist_window
-import brdlist
GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
"..", "data")
GLADE_FILENAME = "board_window.glade"
-def open_board(bbs, board):
- if not bbs:
+def open_board(uri):
+ if not uri:
raise ValueError, "parameter must not be empty"
- key = "/" + bbs + "/" + board
- winwrap = windowlist.get_window(key)
+ winwrap = windowlist.get_window(uri)
if winwrap:
# already opened
winwrap.window.present()
pass
else:
- win_wrap = WinWrap(bbs, board)
- windowlist.window_created(key, win_wrap)
+ win_wrap = WinWrap(uri)
+ windowlist.window_created(uri, win_wrap)
class WinWrap:
- def __init__(self, bbs, board):
- self.bbs = bbs
- self.board = board
+ def __init__(self, uri):
+ from BbsType import bbs_type_judge_uri
+ self.bbs_type = bbs_type_judge_uri.get_type(uri)
+ self.bbs = self.bbs_type.bbs_type
+ self.host = self.bbs_type.host
+ self.board = self.bbs_type.board
+ self.uri = self.bbs_type.uri
+
glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
self.widget_tree = gtk.glade.XML(glade_path)
self.window = self.widget_tree.get_widget("board_window")
- title = brdlist.get(bbs, board, "name")
- if title:
- self.window.set_title(title)
+ self.window.set_title(self.uri)
self.treeview = self.widget_tree.get_widget("treeview")
self.treeview.set_model(ThreadListModel())
self.on_treeview_button_press_event,
"on_close_activate":
self.on_close_activate,
- "on_show_board_list_activate":
- self.on_show_board_list_activate,
"on_popup_menu_open_activate": self.on_open_thread}
self.widget_tree.signal_autoconnect(sigdic)
def on_close_activate(self, widget):
self.window.destroy()
- def on_show_board_list_activate(self, widget):
- brdlist_window.open_brdlist(self.bbs)
-
def on_load_local_activate(self, widget):
t = board_data.LoadLocal(self.bbs, self.board, self.update_datastore)
t.start()
def on_get_remote_activate(self, widget):
- t = board_data.GetRemote(self.bbs, self.board, self.update_datastore)
+ t = board_data.GetRemote(
+ self.bbs, self.board, self.bbs_type.get_subject_txt_uri(),
+ self.update_datastore)
t.start()
def on_column_clicked(self, treeviewcolumn, column_name):
iter, ThreadListModel.column_names.index("title"))
print thread + ':"' + title + '"', "activated"
- thread_window.open_thread(self.bbs, self.board, thread)
+ bbs_type_for_thread = self.bbs_type.clone_with_thread(thread)
+ thread_window.open_thread(bbs_type_for_thread.get_thread_uri())
def on_treeview_button_press_event(self, widget, event):
if event.button == 3:
+++ /dev/null
-# Copyright (C) 2006 by Aiwota Programmer
-# aiwotaprog@tetteke.tk
-#
-# 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os.path
-import ConfigParser
-import gconf
-
-import config
-
-# key: bbs id, value: board dict
-# board dict:: key: board id ,value: attr dict
-# attr dict:: key: attr name, value attr value
-# /apps/hage1/boards
-# /2ch
-# /morningcoffee
-# /host
-# /name
-# /ainotane
-# /host
-# /name
-
-brd_list = None
-key_root = None
-
-def get(bbs, board, attr):
- if not bbs or not board or not attr:
- raise ValueError, "parameter must not be empty"
-
- if brd_list and \
- bbs in brd_list and brd_list[bbs] and \
- board in brd_list[bbs] and brd_list[bbs][board] and \
- attr in brd_list[bbs][board]:
- return brd_list[bbs][board][attr]
- else:
- raise RuntimeError, \
- "brdlist.get: "+bbs+"::"+board+"::"+attr+" not found"
-
-def split_key(key):
- """Returns (bbs, board, attribute)"""
- global key_root
-
- if not key:
- print "no key"
- return None, None, None
- if not key.startswith(key_root+"/"):
- print "invalid key", key
- return None, None, None
- key_unpref = key[len(key_root+"/"):]
- list = key_unpref.split("/", 2)
- bbs = None
- board = None
- attr = None
- if len(list) > 0:
- bbs = list[0]
- if len(list) > 1:
- board = list[1]
- if len(list) > 2:
- attr = list[2]
- return bbs, board, attr
-
-def remove_attr(bbs, board, attr):
- if not bbs or not board or not attr:
- return
-
- if brd_list and bbs in brd_list and board in brd_list[bbs] \
- and attr in brd_list[bbs][board]:
- print "delete", bbs, board, attr
- del brd_list[bbs][board][attr]
- if not brd_list[bbs][board]:
- print "delete", bbs, board
- del brd_list[bbs][board]
- if not brd_list[bbs]:
- print "delete", bbs
- del brd_list[bbs]
-
-def modify_attr(bbs, board, attr, value):
- if not bbs or not board or not attr:
- return
-
- global brd_list
-
- if not brd_list:
- print "create root brd_list"
- brd_list = {}
- if bbs not in brd_list or not brd_list[bbs]:
- print "create", bbs
- brd_list[bbs] = {}
- if board not in brd_list[bbs] or not brd_list[bbs][board]:
- #print "create", bbs, board
- brd_list[bbs][board] = {}
-
- #print "modified", attr, value
- brd_list[bbs][board][attr] = str(value)
-
-def key_changed_callback(client, cnxn_id, entry, user_data = None):
- print "notify", cnxn_id, entry.key
-
- bbs, board, attr = split_key(entry.key)
- if not bbs or not board or not attr:
- print "key is not /apps/{appname}/boards/{bbs}/{board}/{attr}"
- return
-
- if not entry.value:
- # entry.key is unset
- print "unset"
- remove_attr(bbs, board, attr)
- elif entry.value.type != gconf.VALUE_STRING:
- # entry value is invalid type
- print "invalid type"
- remove_attr(bbs, board, attr)
- else:
- # entry.key is modified, or new
- value = entry.value.to_string()
- print "modified or new", value
- modify_attr(bbs, board, attr, value)
-
-def init():
- global key_root
-
- key_root = "/apps/" + config.APPNAME.lower() + "/boards"
- client = gconf.client_get_default()
-
- # init
- print "init brd_list for gconf"
- for bbs_dir in client.all_dirs(key_root):
- for board_dir in client.all_dirs(bbs_dir):
- # host
- key = board_dir + "/host"
- value = client.get_string(key)
- if value:
- bbs, board, attr = split_key(key)
- modify_attr(bbs, board, attr, value)
- # name
- key = board_dir + "/name"
- value = client.get_string(key)
- if value:
- bbs, board, attr = split_key(key)
- modify_attr(bbs, board, attr, value)
-
- # register notification
- print "register gconf notification"
- client.add_dir(key_root, gconf.CLIENT_PRELOAD_NONE)
- client.notify_add(key_root, key_changed_callback)
+++ /dev/null
-# Copyright (C) 2006 by Aiwota Programmer
-# aiwotaprog@tetteke.tk
-#
-# 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gtk.glade
-import os.path
-import gconf
-
-import windowlist
-import board_window
-import config
-
-GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
- "..", "data")
-GLADE_FILENAME = "brdlist_window.glade"
-
-def open_brdlist(bbs):
- if not bbs:
- raise ValueError, "parameter must not be empty"
-
- key = "/" + bbs
- winwrap = windowlist.get_window(key)
- if winwrap:
- winwrap.window.present()
- else:
- win_wrap = WinWrap(bbs)
- windowlist.window_created(key, win_wrap)
-
-
-class WinWrap:
-
- def __init__(self, bbs):
- self.bbs = bbs
-
- glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
- self.widget_tree = gtk.glade.XML(glade_path)
-
- self.window = self.widget_tree.get_widget("brdlist_window")
- self.treeview = self.widget_tree.get_widget("treeview")
- self.model = gtk.ListStore(str, str, str)
- self.treeview.set_model(self.model)
-
- renderer = gtk.CellRendererText()
- column_names = ["id", "host", "name"]
- for i in range(3):
- self.treeviewcolumn = gtk.TreeViewColumn(column_names[i],
- renderer, text=i)
- self.treeviewcolumn.set_sort_column_id(i)
- self.treeviewcolumn.set_resizable(True)
- self.treeviewcolumn.set_reorderable(True)
- self.treeview.append_column(self.treeviewcolumn)
-
- self.treeview.connect("row-activated", self.on_row_activated)
-
- sigdict = {"on_close_activate": self.on_close_activate,
- "on_quit_activate": self.on_quit_activate}
- self.widget_tree.signal_autoconnect(sigdict)
-
- self.build_list()
-
- def build_list(self):
- key_root = "/apps/" + config.APPNAME.lower() + "/boards/" + self.bbs
- client = gconf.client_get_default()
-
- # init
- for board_dir in client.all_dirs(key_root):
- bbs_dir, board = os.path.split(board_dir)
- # host
- key = board_dir + "/host"
- host = client.get_string(key)
- # name
- key = board_dir + "/name"
- name = client.get_string(key)
- if board and host and name:
- self.modify(board, host, name)
-
- def modify(self, board, name, host):
- self.model.append([board, name, host])
-
- def on_close_activate(self, widget):
- self.window.destroy()
-
- def on_quit_activate(self, widget):
- gtk.main_quit()
-
- def on_row_activated(self, widget, path, view_column):
- model = widget.get_model()
- if model:
- iter = model.get_iter(path)
- if iter:
- board = model.get_value(iter, 0)
- self.open_board(board)
-
- def open_board(self, board):
- board_window.open_board(self.bbs, board)
import board_window
import thread_window
-import brdlist_window
dbus_interface_name = "tk.tetteke.Hage1"
dbus.service.Object.__init__(self, bus_name, object_path)
@dbus.service.method(dbus_interface_name)
- def open_board(self, bbs, board):
- board_window.open_board(bbs, board)
+ def open_board(self, uri):
+ board_window.open_board(uri)
@dbus.service.method(dbus_interface_name)
- def open_thread(self, bbs, board, thread):
- thread_window.open_thread(bbs, board, thread)
-
- @dbus.service.method(dbus_interface_name)
- def open_brdlist(self, bbs):
- brdlist_window.open_brdlist(bbs)
+ def open_thread(self, uri):
+ thread_window.open_thread(uri)
import time
import config
-import brdlist
REG_EXPR_HTTPDATE = re.compile("((?:Mon)|(?:Tue)|(?:Wed)|(?:Thu)|(?:Fri)|(?:Sat)|(?:Sun)), (\d{2}) ((?:Jan)|(?:Feb)|(?:Mar)|(?:Apr)|(?:May)|(?:Jun)|(?:Jul)|(?:Aug)|(?:Sep)|(?:Oct)|(?:Nov)|(?:Dec)) (\d{4}) (\d{2}):(\d{2}):(\d{2}) GMT")
WDAY_DICT = {"Mon":0, "Tue":1, "Wed":2, "Thu":3, "Fri":4, "Sat":5, "Sun":6}
def get_logs_dir_path():
return os.path.join(config.get_config_dir_path(), "logs")
-def get_board_base_url(bbs, board):
- """
- Note: this function uses brdlist.get function, so brdlist.init function
- should have been called before this function is called
- """
- # if parameter is empty, raise ValueError
- if not bbs or not board:
- raise ValueError, "parameter must not be empty"
-
- return "http://" + brdlist.get(bbs, board, "host") + "/" + board + "/"
-
-def get_thread_dat_url(bbs, board, thread):
- """Returns thread dat url"""
-
- # if parameter is empty, raise ValueError
- if not bbs or not board or not thread:
- raise ValueError, "parameter must not be empty"
-
- return get_board_base_url(bbs, board) + "dat/" + thread + ".dat"
-
def get_thread_dat_path(bbs, board, thread):
"""Returns thread dat file path
import codecs
import urllib
from misc import get_board_subjecttxt_path
-from misc import get_board_subjecttxt_url
from misc import get_board_idx_path
REG_EXPR = re.compile("(?P<id>.*).dat<>(?P<title>.*)\((?P<res>\d*)\)")
analyze_subjecttxt(subjecttxt_encoded.decode("cp932", "replace"), func)
-def get_subjecttxt(bbs, board):
- u = urllib.urlopen(get_board_subjecttxt_url(bbs, board))
+def get_subjecttxt(bbs, board, uri):
+ u = urllib.urlopen(uri)
subjecttxt_encoded = u.read()
info = u.info()
import idxfile
import windowlist
import board_window
-import brdlist_window
GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
"..", "data")
GLADE_FILENAME = "thread_window.glade"
-def open_thread(bbs, board, thread):
- if not bbs or not board or not thread:
+def open_thread(uri):
+ if not uri:
raise ValueError, "parameter must not be empty"
- key = "/" + bbs + "/" + board + "/" + thread
- winwrap = windowlist.get_window(key)
+ winwrap = windowlist.get_window(uri)
if winwrap:
# already opened
winwrap.window.present()
pass
else:
- win_wrap = WinWrap(bbs, board, thread)
- windowlist.window_created(key, win_wrap)
+ win_wrap = WinWrap(uri)
+ windowlist.window_created(uri, win_wrap)
class WinWrap:
- def __init__(self, bbs, board, thread):
- self.bbs = bbs
- self.board = board
- self.thread = thread
+ def __init__(self, uri):
+ from BbsType import bbs_type_judge_uri
+ from BbsType import bbs_type_exception
+ self.bbs_type = bbs_type_judge_uri.get_type(uri)
+ if not self.bbs_type.is_thread():
+ raise bbs_type_exception.BbsTypeError, \
+ "the uri does not represent thread: " + uri
+ self.bbs = self.bbs_type.bbs_type
+ self.board = self.bbs_type.board
+ self.thread = self.bbs_type.thread
+ self.host = self.bbs_type.host
+ self.uri = self.bbs_type.uri
self.size = 0
self.num = 0
self.title = None
"on_close_activate": self.on_close_activate,
"on_quit_activate": self.on_quit_activate,
"on_show_board_activate": self.on_show_board_activate,
- "on_show_board_list_activate":
- self.on_show_board_list_activate,
"on_thread_window_destroy": self.on_thread_window_destroy}
self.widget_tree.signal_autoconnect(sigdic)
gtk.main_quit()
def on_show_board_activate(self, widget):
- board_window.open_board(self.bbs, self.board)
-
- def on_show_board_list_activate(self, widget):
- brdlist_window.open_brdlist(self.bbs)
+ board_window.open_board(self.bbs_type.get_uri_base())
def http_get_dat(self, on_get_res):
- datfile_url = misc.get_thread_dat_url(self.bbs, self.board, self.thread)
+ datfile_url = self.bbs_type.get_dat_uri()
idx_dic = idxfile.load_idx(self.bbs, self.board, self.thread)
lastmod = idx_dic["lastModified"]
<widget class="GtkMenu" id="file1_menu">
<child>
- <widget class="GtkMenuItem" id="show_board_list">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Show _Board List</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_show_board_list_activate" last_modification_time="Sun, 20 Aug 2006 12:50:27 GMT"/>
- <accelerator key="B" modifiers="GDK_SHIFT_MASK" signal="activate"/>
- </widget>
- </child>
-
- <child>
<widget class="GtkImageMenuItem" id="load_local">
<property name="visible">True</property>
<property name="label" translatable="yes">_Load Local</property>
<accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image8">
+ <widget class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="stock">gtk-disconnect</property>
<property name="icon_size">1</property>
<accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image9">
+ <widget class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
+++ /dev/null
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-<requires lib="bonobo"/>
-
-<widget class="GnomeApp" id="brdlist_window">
- <property name="visible">True</property>
- <property name="title" translatable="yes">brdlist_window</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">600</property>
- <property name="default_height">600</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="enable_layout_config">True</property>
-
- <child internal-child="dock">
- <widget class="BonoboDock" id="bonobodock1">
- <property name="visible">True</property>
- <property name="allow_floating">True</property>
-
- <child>
- <widget class="BonoboDockItem" id="bonobodockitem1">
- <property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
-
- <child>
- <widget class="GtkMenuBar" id="menubar1">
- <property name="visible">True</property>
-
- <child>
- <widget class="GtkMenuItem" id="file1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_FILE_TREE</property>
-
- <child>
- <widget class="GtkMenu" id="file1_menu">
-
- <child>
- <widget class="GtkImageMenuItem" id="close">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_CLOSE_ITEM</property>
- <signal name="activate" handler="on_close_activate" last_modification_time="Sun, 20 Aug 2006 13:05:11 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkSeparatorMenuItem" id="separator4">
- <property name="visible">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="quit">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_EXIT_ITEM</property>
- <signal name="activate" handler="on_quit_activate" last_modification_time="Sun, 20 Aug 2006 13:06:42 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="edit1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_EDIT_TREE</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="view1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_VIEW_TREE</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="help1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_HELP_TREE</property>
-
- <child>
- <widget class="GtkMenu" id="help1_menu">
-
- <child>
- <widget class="GtkImageMenuItem" id="about1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_ABOUT_ITEM</property>
- <signal name="activate" handler="on_about1_activate" last_modification_time="Sun, 20 Aug 2006 09:25:15 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="placement">BONOBO_DOCK_TOP</property>
- <property name="band">0</property>
- <property name="position">0</property>
- <property name="offset">0</property>
- <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
- </packing>
- </child>
-
- <child>
- <widget class="BonoboDockItem" id="bonobodockitem2">
- <property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_OUT</property>
-
- <child>
- <widget class="GtkToolbar" id="toolbar1">
- <property name="visible">True</property>
- <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
- <property name="tooltips">True</property>
- <property name="show_arrow">True</property>
-
- <child>
- <widget class="GtkToolButton" id="toolbutton1">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">New File</property>
- <property name="stock_id">gtk-new</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- <property name="is_important">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkToolButton" id="toolbutton2">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Open File</property>
- <property name="stock_id">gtk-open</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- <property name="is_important">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkToolButton" id="toolbutton3">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Save File</property>
- <property name="stock_id">gtk-save</property>
- <property name="visible_horizontal">True</property>
- <property name="visible_vertical">True</property>
- <property name="is_important">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="placement">BONOBO_DOCK_TOP</property>
- <property name="band">1</property>
- <property name="position">0</property>
- <property name="offset">0</property>
- <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="treeview">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">True</property>
- <property name="reorderable">True</property>
- <property name="enable_search">True</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child internal-child="appbar">
- <widget class="GnomeAppBar" id="appbar1">
- <property name="visible">True</property>
- <property name="has_progress">True</property>
- <property name="has_status">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-</widget>
-
-</glade-interface>
</child>
<child>
- <widget class="GtkMenuItem" id="show_board_list">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Show Board List</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_show_board_list_activate" last_modification_time="Mon, 21 Aug 2006 03:30:53 GMT"/>
- </widget>
- </child>
-
- <child>
<widget class="GtkImageMenuItem" id="refresh">
<property name="visible">True</property>
<property name="label" translatable="yes">_Refresh</property>
from Hage1 import thread_window
from Hage1 import board_window
-from Hage1 import brdlist_window
-from Hage1 import brdlist
from Hage1 import config
from Hage1 import dbus_object
dbus_object.dbus_interface_name = "tk.tetteke.Hage1"
def usage():
- print """usage: hage1 [-s bbs | -b board | -t thread]
--s, --bbs bbs : bbs id
--b, --board board : board id, ignored if bbs is empty
--t, --thread thread : thread id, ignored if bbs and board is empty"""
+ print """usage: hage1 uri"""
def getoption():
- bbs = None
- board = None
- thread = None
-
try:
opts, args = getopt.getopt(
- sys.argv[1:], "hs:b:t:", ["help", "bbs=", "board=", "thread="])
+ sys.argv[1:], "h", ["help"])
except getopt.GetoptError, msg:
print msg
usage()
if option in ("-h", "--help"):
usage()
sys.exit()
- elif option in ("-s", "--bbs"):
- bbs = value
- elif option in ("-b", "--board"):
- board = value
- elif option in ("-t", "--thread"):
- thread = value
-
- return bbs, board, thread
+ return args
+
if __name__ == "__main__":
# get option
- bbs, board, thread = getoption()
+ uris = getoption()
# check if an instance exists
session_bus = dbus.SessionBus()
gobject.threads_init()
config.APPNAME = APPNAME
- # init brdlist after setting config.APPNAME
- brdlist.init()
-
- if not bbs:
- brdlist_window.open_brdlist("2ch")
- elif not board:
- brdlist_window.open_brdlist(bbs)
- elif not thread:
- board_window.open_board(bbs, board)
- else:
- thread_window.open_thread(bbs, board, thread)
-
- gtk.main()
+ # open some windows
+ if uris:
+ from Hage1.BbsType import bbs_type_judge_uri
+ from Hage1.BbsType import bbs_type_exception
+ for uri in uris:
+ try:
+ bbs_type = bbs_type_judge_uri.get_type(uri)
+ if bbs_type.is_board():
+ board_window.open_board(uri)
+ thread_window.open_thread(uri)
+ except bbs_type_exception.BbsTypeError, msg:
+ print msg
+ gtk.main()
else:
# the instance exists. send message and exit.
proxy_object = session_bus.get_object(dbus_bus_name, dbus_object_path)
iface = dbus.Interface(proxy_object, dbus_object.dbus_interface_name)
- if not bbs:
- iface.open_brdlist("2ch")
- elif not board:
- iface.open_brdlist(bbs)
- elif not thread:
- iface.open_board(bbs, board)
- else:
- iface.open_thread(bbs, board, thread)
+ # open some windows
+ if uris:
+ from Hage1.BbsType import bbs_type_judge_uri
+ from Hage1.BbsType import bbs_type_exception
+ for uri in uris:
+ try:
+ bbs_type = bbs_type_judge_uri.get_type(uri)
+ if bbs_type.is_board():
+ iface.open_board(uri)
+ iface.open_thread(uri)
+ except bbs_type_exception.BbsTypeError, msg:
+ print msg