Gwibber 的饭否插件

UPDATE (on 9/8/2012),在 GitHub 上也保存了一个代码分支

UPDATE (on 6/19/2009),同步更新到版本分支 bzr340。为饭否插件添加了转发、收藏、删除功能。 DEB 安装包下载, gwibber_1.2.0-bzr340-fanfou-0ubuntu1_all.deb

UPDATE (on 6/5/2009),提供 DEB 安装包下载, gwibber_1.2.0-bzr339-fanfou-0ubuntu1_all.deb (Update on 6/19/2009 已有新版本放出)。

UPDATE (on 6/2/2009),更新 Fanfou Protocol 代码分支 ,现已支持 Gwibber 1.20 版本。

UPDATE (on 5/2/2009),最简单的使用 Fanfou Protocol 代码分支的方法是获取代码后,直接进入 bin 目录,执行,
python .gwibber
UPDATE (on 3/9/2009),在 Launchpad 的 Gwibber 代码库中设立了一个 Fanfou Protocol 代码分支。现在可以直接通过以下命令来获取该分支的代码了。
bzr branch lp:~liang.zhao/gwibber/fanfou-protocol

花了一个下午,终于完成了 Gwibber 的饭否插件。

多亏饭否的 API 设计与 Twitter 保持了一定程度的一致性,使得我这个 Python 的入门级选手也能够在 Twitter 插件的基础上,改改弄弄,把饭否插件啃下来。废话不说,直接上效果图。

用户配置界面
用户配置界面,可以对饭否发送、接收信息,也实现了饭否新的搜索功能
用户信息查看界面
用户信息查看界面
用户搜索结果界面
用户搜索结果界面
做了些简单测试,功能基本正常。只是查看用户信息页面,在同时开启 Twitter 和饭否的前提下,Gwibber 会根据用户 ID 自动搜索两边数据。这个功能有点恼人——特别是该 ID 如果在两个系统里属于不同用户时。尚不清楚这个自动搜索功能是 Gwibber 原本自带的,还是因为我那基于 Twitter 的豆瓣插件的问题。有待进一步观察。此问题已确认为 Gwibber 自带问题,并已在 0.9 版中解决。

终于写到具体的配置了。所有配置都是基于 Ubuntu 实现,其他的系统请自行调整。

第一步:下载 0.8 版0.9 版 fanfou.py,改名为 fanfou.py,复制到以下目录(需 sudo 权限)。理论上,应该能复制到 ~/ 目录下,只是尚未找到 Gwibber 下 Python 文件所对应的那个本地目录——一声叹息啊……只好 sudo 绝招出动。
/usr/share/pyshared/gwibber/microblog

第二步:修改目录中的 __init__.py 文件(同样需要 sudo)。按照以下代码中的注释,加入相应内容。
import operator, traceback, can
import twitter, jaiku, identica, laconica, pownce
import digg, flickr, brightkite, rss, pingfm, facebook
# 加入下一行,以便调用 fanfou 的代码
import fanfou
 
#...
 
PROTOCOLS = {
  "jaiku": jaiku,
  "digg": digg,
  "twitter": twitter,
  "facebook": facebook,
  # 在 PROTOCOLS 中加入 fanfou 协议
  "fanfou": fanfou,
  #...
}
第三步:修改 /usr/share/gwibber/ui/preferences.glade 文件(sudo 到底了……)。将 preferences.glade 拖到底部,在 之后,插入以下代码:
<widget class="GtkDialog" id="dialog_fanfou">
    <property name="border_width">5</property>
    <property name="window_position">center-on-parent</property>
    <property name="type_hint">dialog</property>
    <child internal-child="vbox">
      <widget class="GtkVBox" id="dialog-vbox2">
        <property name="visible">True</property>
        <property name="spacing">2</property>
        <child>
          <widget class="GtkVBox" id="vbox3">
            <property name="visible">True</property>
            <property name="spacing">10</property>
            <child>
              <widget class="GtkFrame" id="frameAccount">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">none</property>
                <child>
                  <widget class="GtkAlignment" id="alignment1">
                    <property name="visible">True</property>
                    <property name="top_padding">10</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkTable" id="table1">
                        <property name="visible">True</property>
                        <property name="n_rows">2</property>
                        <property name="n_columns">2</property>
                        <property name="column_spacing">5</property>
                        <property name="row_spacing">5</property>
                        <child>
                          <widget class="GtkLabel" id="label10">
                            <property name="visible">True</property>
                            <property name="label" translatable="yes">Username:</property>
                          </widget>
                        </child>
                        <child>
                          <widget class="GtkLabel" id="label11">
                            <property name="visible">True</property>
                            <property name="label" translatable="yes">Password:</property>
                          </widget>
                          <packing>
                            <property name="top_attach">1</property>
                            <property name="bottom_attach">2</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkEntry" id="fanfou_username">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                          </widget>
                          <packing>
                            <property name="left_attach">1</property>
                            <property name="right_attach">2</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkEntry" id="fanfou_password">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="visibility">False</property>
                          </widget>
                          <packing>
                            <property name="left_attach">1</property>
                            <property name="right_attach">2</property>
                            <property name="top_attach">1</property>
                            <property name="bottom_attach">2</property>
                          </packing>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label6">
                    <property name="visible">True</property>
                    <property name="label" translatable="yes"><b>Account Information</b></property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkFrame" id="frameStatus">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">none</property>
                <child>
                  <widget class="GtkAlignment" id="alignment4">
                    <property name="visible">True</property>
                    <property name="top_padding">10</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkVBox" id="vbox5">
                        <property name="visible">True</property>
                        <child>
                          <widget class="GtkCheckButton" id="fanfou_receive_enabled">
                            <property name="label" translatable="yes">_Receive Messages</property>
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="receives_default">False</property>
                            <property name="use_underline">True</property>
                            <property name="draw_indicator">True</property>
                          </widget>
                          <packing>
                            <property name="position">0</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkCheckButton" id="fanfou_send_enabled">
                            <property name="label" translatable="yes">_Send Messages</property>
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="receives_default">False</property>
                            <property name="use_underline">True</property>
                            <property name="draw_indicator">True</property>
                          </widget>
                          <packing>
                            <property name="position">1</property>
                          </packing>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label8">
                    <property name="visible">True</property>
                    <property name="label" translatable="yes"><b>Account Status</b></property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkFrame" id="frameAppearance">
                <property name="visible">True</property>
                <property name="label_xalign">0</property>
                <property name="shadow_type">none</property>
                <child>
                  <widget class="GtkAlignment" id="alignment5">
                    <property name="visible">True</property>
                    <property name="top_padding">10</property>
                    <property name="left_padding">12</property>
                    <child>
                      <widget class="GtkHBox" id="hbox3">
                        <property name="visible">True</property>
                        <child>
                          <widget class="GtkLabel" id="label12">
                            <property name="visible">True</property>
                            <property name="label" translatable="yes">Message Color:</property>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="position">0</property>
                          </packing>
                        </child>
                        <child>
                          <widget class="GtkColorButton" id="fanfou_message_color">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="receives_default">True</property>
                            <property name="color">#000000000000</property>
                          </widget>
                          <packing>
                            <property name="expand">False</property>
                            <property name="fill">False</property>
                            <property name="padding">5</property>
                            <property name="position">1</property>
                          </packing>
                        </child>
                      </widget>
                    </child>
                  </widget>
                </child>
                <child>
                  <widget class="GtkLabel" id="label9">
                    <property name="visible">True</property>
                    <property name="label" translatable="yes"><b>Appearance</b></property>
                    <property name="use_markup">True</property>
                  </widget>
                  <packing>
                    <property name="type">label_item</property>
                  </packing>
                </child>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="position">2</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
        <child internal-child="action_area">
          <widget class="GtkHButtonBox" id="dialog-action_area2">
            <property name="visible">True</property>
            <child>
              <widget class="GtkButton" id="fanfou_btndelete">
                <property name="label">gtk-delete</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="fanfou_btnclose">
                <property name="label">gtk-close</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="pack_type">end</property>
            <property name="position">0</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
自此,全部完成,重新启动即可。如果你觉得用 sudo 修改系统存在风险的话,可以从网上下一份 Gwibber 的代码拷贝,直接在源代码上修改,运行……