--- /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 gobject
+import codecs
+import urllib
+import urllib2
+import cookielib
+import os.path
+import time
+
+from BbsType import bbs_type_judge_uri
+from BbsType import bbs_type_exception
+from HTMLParserEx import HTMLParserEx
+
+GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+ "..", "data")
+GLADE_FILENAME = "submit_window.glade"
+
+cookie_jar = cookielib.CookieJar()
+opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
+
+def open(uri):
+ if not uri:
+ raise ValueError, "parameter must not be empty"
+
+ WinWrap(uri)
+
+
+class ConfirmationHTMLParser(HTMLParserEx):
+
+ def __init__(self):
+ HTMLParserEx.__init__(self)
+ self.message = ""
+ self.inputs = []
+ self.complete = False
+
+ def handle_starttag(self, tag, attr):
+ if tag == "br":
+ self.message += "\n"
+ elif tag == "input":
+ self.inputs.append(dict(attr))
+ elif tag == "meta":
+ attr_dict = dict(attr)
+ if "http-equiv" in attr_dict \
+ and attr_dict["http-equiv"] == "refresh":
+ self.complete = True
+
+ def handle_endtag(self, tag):
+ pass
+
+ def handle_comment(self, comment):
+ print comment.strip()
+
+ def handle_data(self, data):
+ self.message += data
+
+ def handle_charref(self, ref):
+ data = None
+ try:
+ data = unichr(int(ref))
+ except:
+ data = "&#"+ref+";"
+ self.message += data
+
+ def handle_entityref(self, name):
+ if name in htmlentitydefs.name2codepoint:
+ codepoint = htmlentitydefs.name2codepoint[name]
+ self.message += unichr(codepoint)
+ else:
+ self.message += "&"+name+";"
+
+
+class WinWrap:
+
+ def __init__(self, uri):
+ self.uri = uri
+ 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
+
+ glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
+ self.widget_tree = gtk.glade.XML(glade_path)
+ self.window = self.widget_tree.get_widget("submit_window")
+ self.entry_name = self.widget_tree.get_widget("entry_name")
+ self.entry_mail = self.widget_tree.get_widget("entry_mail")
+ self.textbuffer = self.widget_tree.get_widget("textview").get_buffer()
+
+ self.post_dict = {}
+ self.post_dict["bbs"] = self.bbs_type.board
+ self.post_dict["key"] = self.bbs_type.thread
+ self.post_dict["time"] = str(int(time.time()))
+ self.post_dict["hana"] = "mogera"
+ self.post_dict["submit"] = u"\u66f8\u304d\u8fbc\u3080".encode(
+ "cp932", "replace")
+
+ sigdic = {"on_submit_activate": self.on_submit_activate,
+ "on_close_activate": self.on_close_activate}
+
+ self.widget_tree.signal_autoconnect(sigdic)
+
+ def on_close_activate(self, widget):
+ self.window.destroy()
+
+ def on_submit_activate(self, widget):
+ name = self.entry_name.get_text()
+ if self.bbs_type.bbs_type == "2ch" \
+ and self.bbs_type.board == "morningcoffee" \
+ and not name:
+ name = u'\u540d\u7121\u3057\u52df\u96c6\u4e2d\u3002\u3002\u3002'
+ mail = self.entry_mail.get_text()
+ msg = self.textbuffer.get_text(
+ self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
+
+ self.post_dict["FROM"] = name.encode("cp932", "replace")
+ self.post_dict["mail"] = mail.encode("cp932", "replace")
+ self.post_dict["MESSAGE"] = msg.encode("cp932", "replace")
+
+ self.do_submit()
+
+ def do_submit(self):
+ post_encoded = urllib.urlencode(self.post_dict)
+ print post_encoded
+
+ req = urllib2.Request("http://" + self.bbs_type.host + "/test/bbs.cgi",
+ post_encoded)
+ req.add_header("Referer", self.uri)
+
+ res = opener.open(req)
+ self.on_response(res)
+
+ def on_response(self, response):
+ data = response.read()
+
+ p = ConfirmationHTMLParser()
+ p.feed(data.decode("cp932", "replace"))
+ p.close()
+
+ print data.decode("cp932")
+
+ window = gtk.Window()
+ if not p.complete:
+ window.set_default_size(500, 500)
+ textview = gtk.TextView()
+ textview.set_wrap_mode(gtk.WRAP_CHAR)
+ textview.set_editable(False)
+ buf = textview.get_buffer()
+ buf.insert(buf.get_end_iter(), p.message)
+
+ for input in p.inputs:
+ if "type" in input and input["type"] == "submit":
+ button = gtk.Button(input["value"])
+ button.connect("clicked",
+ self.on_button_submit_clicked, p.inputs)
+ anchor = buf.create_child_anchor(buf.get_end_iter())
+ textview.add_child_at_anchor(button, anchor)
+ break
+
+ window.add(textview)
+ window.show_all()
+
+ if p.complete:
+ gobject.timeout_add(2 * 1000, window.destroy)
+
+ def on_button_submit_clicked(self, widget, inputs=None):
+ widget.get_toplevel().destroy()
+ self.post_dict = {}
+ for input in inputs:
+ if "name" in input and "value" in input:
+ name = input["name"]
+ value = input["value"]
+ self.post_dict[name] = value.encode("cp932", "replace")
+
+ self.do_submit()
--- /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="submit_window">
+ <property name="visible">True</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</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="submit">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Submit</property>
+ <property name="label" translatable="yes">_Submit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_submit_activate" last_modification_time="Sat, 26 Aug 2006 00:33:18 GMT"/>
+ <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gnome-stock-mail-snd</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <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="Sat, 26 Aug 2006 00:25:19 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>
+ </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="toolbutton_submit">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Submit</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gnome-stock-mail-snd</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <signal name="clicked" handler="on_toolbutton_submit_clicked" last_modification_time="Fri, 25 Aug 2006 21:49:39 GMT"/>
+ </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="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Name:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Mail:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_mail">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</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_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTextView" id="textview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="editable">True</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">False</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_NONE</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
+ <property name="text" translatable="yes"></property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </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>