diff -Nru kita2-1.90.0/COPYRIGHT kita2-1.90.4/COPYRIGHT --- kita2-1.90.0/COPYRIGHT 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/COPYRIGHT 2008-03-29 22:28:52.000000000 +0900 @@ -0,0 +1,20 @@ +Copyright (c) 2008 Hideki Ikemoto + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru kita2-1.90.0/README.ja kita2-1.90.4/README.ja --- kita2-1.90.0/README.ja 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/README.ja 2008-07-11 21:44:00.000000000 +0900 @@ -0,0 +1,27 @@ +Kita - 2ch client for KDE + +KDE用2ちゃんねるブラウザの開発版です。 + +ライセンスはMITライセンスです。 + +* 前提条件 + +KDEのRubyバインディングであるKorundum/QtRubyが必要です。 +一般的にはkdebindingsパッケージに含まれています。 + +* インストール + +特に作業は必要ありません。 + +* 実行 + +./kita.rb + +* 開発環境 + +openSUSE 10.3 ++ Qt 3.3.8 ++ KDE 3.5.7 ++ KDevelop 3.4.1 + +Hideki Ikemoto diff -Nru kita2-1.90.0/accountpage.rb kita2-1.90.4/accountpage.rb --- kita2-1.90.0/accountpage.rb 2007-12-31 15:26:26.000000000 +0900 +++ kita2-1.90.4/accountpage.rb 2008-04-10 22:17:15.000000000 +0900 @@ -1,6 +1,6 @@ # Form implementation generated from reading ui file 'accountpage.ui' # -# Created: 月 12月 31 15:25:25 2007 +# Created: 木 4月 10 22:07:20 2008 # by: The QtRuby User Interface Compiler (rbuic) # # WARNING! All changes made in this file will be lost! @@ -11,6 +11,7 @@ attr_reader :textLabel1 attr_reader :id_line attr_reader :password_line + attr_reader :autologin_check def initialize(parent = nil, name = nil, fl = 0) @@ -20,9 +21,11 @@ setName("AccountPage") end - @AccountPageLayout = Qt::VBoxLayout.new(self, 11, 6, 'AccountPageLayout') + @AccountPageLayout = Qt::GridLayout.new(self, 1, 1, 11, 6, 'AccountPageLayout') - @layout2 = Qt::HBoxLayout.new(nil, 0, 6, 'layout2') + @layout8 = Qt::HBoxLayout.new(nil, 0, 6, 'layout8') + + @layout7 = Qt::VBoxLayout.new(nil, 0, 6, 'layout7') @layout1 = Qt::GridLayout.new(nil, 1, 1, 0, 6, 'layout1') @@ -41,12 +44,17 @@ @password_line = Qt::LineEdit.new(self, "password_line") @layout1.addWidget(@password_line, 1, 1) - @layout2.addLayout(@layout1) - @spacer2 = Qt::SpacerItem.new(40, 20, Qt::SizePolicy::Expanding, Qt::SizePolicy::Minimum) - @layout2.addItem(@spacer2) - @AccountPageLayout.addLayout(@layout2) + @layout7.addLayout(@layout1) + + @autologin_check = Qt::CheckBox.new(self, "autologin_check") + @layout7.addWidget(@autologin_check) + @layout8.addLayout(@layout7) + @spacer2 = Qt::SpacerItem.new(197, 20, Qt::SizePolicy::Expanding, Qt::SizePolicy::Minimum) + @layout8.addItem(@spacer2) + + @AccountPageLayout.addLayout(@layout8, 0, 0) @spacer1 = Qt::SpacerItem.new(20, 290, Qt::SizePolicy::Minimum, Qt::SizePolicy::Expanding) - @AccountPageLayout.addItem(@spacer1) + @AccountPageLayout.addItem(@spacer1, 1, 0) languageChange() resize( Qt::Size.new(430, 480).expandedTo(minimumSizeHint()) ) clearWState( WState_Polished ) @@ -60,6 +68,7 @@ setCaption(trUtf8("Form1")) @textLabel2.setText( trUtf8("Password") ) @textLabel1.setText( trUtf8("Account ID") ) + @autologin_check.setText( trUtf8("自動ログインを有効にする") ) end protected :languageChange diff -Nru kita2-1.90.0/accountpage.ui kita2-1.90.4/accountpage.ui --- kita2-1.90.0/accountpage.ui 2007-12-31 15:26:26.000000000 +0900 +++ kita2-1.90.4/accountpage.ui 2008-04-10 22:17:15.000000000 +0900 @@ -15,13 +15,13 @@ Form1 - + unnamed - + - layout2 + layout8 @@ -29,39 +29,57 @@ - layout1 + layout7 - + unnamed - + - textLabel2 - - - Password + layout1 + + + unnamed + + + + textLabel2 + + + Password + + + + + textLabel1 + + + Account ID + + + + + id_line + + + + + password_line + + + - + - textLabel1 + autologin_check - Account ID - - - - - id_line - - - - - password_line + 自動ログインを有効にする - + @@ -75,14 +93,14 @@ - 40 + 197 20 - + spacer1 @@ -99,7 +117,7 @@ - + diff -Nru kita2-1.90.0/board.rb kita2-1.90.4/board.rb --- kita2-1.90.0/board.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/board.rb 2008-04-07 22:52:56.000000000 +0900 @@ -48,13 +48,27 @@ def initialize @name_hash = {} + @url_hash = {} end - def register(url, name) + def register_name(url, name) @name_hash[url] = name end + def register_url(type, id, url) + if @url_hash.member?([type, id]) + false + else + @url_hash[[type, id]] = url + true + end + end + def get_name(url) @name_hash[url] end + + def get_url(type, id) + @url_hash[[type, id]] + end end diff -Nru kita2-1.90.0/boardlistview.rb kita2-1.90.4/boardlistview.rb --- kita2-1.90.0/boardlistview.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/boardlistview.rb 2008-04-24 13:57:46.000000000 +0900 @@ -24,8 +24,11 @@ slots 'show_board(QListViewItem*)' slots 'context_menu(QListViewItem*,const QPoint&,int)' - POPUP_COPY_URL = 0 - POPUP_COPY_TITLE_AND_URL = 1 + POPUP_OPEN_WITH_WEB_BROWSER = 0 + POPUP_COPY_URL = 1 + POPUP_COPY_TITLE_AND_URL = 2 + POPUP_ADD_TO_FAVORITE = 3 + POPUP_DELETE_FROM_FAVORITE = 4 COLUMN_TITLE = 0 COLUMN_URL = 1 @@ -73,8 +76,12 @@ board_name = Regexp.last_match[2] next unless Util.board_url?(board_url) + board_id = Util.board_url_to_board_id(board_url) + board_type = Util.board_url_to_board_type_name(board_url) + board = Board.new(board_url, board_name) - BoardManager.instance.register(board_url, board_name) + BoardManager.instance.register_name(board_url, board_name) + BoardManager.instance.register_url(board_type, board_id, board_url) current_group.push(board) if current_group end } @@ -91,14 +98,20 @@ } } - BoardManager.instance.register("http://jbbs.livedoor.jp/computer/18420/", "Kita板") + kitabbs_url = "http://jbbs.livedoor.jp/computer/18420/" + BoardManager.instance.register_name(kitabbs_url, "Kita板") + BoardManager.instance.register_url("jbbs.livedoor.jp", "computer_18420", kitabbs_url) KDE::ListViewItem.new(self, "Kita板", "http://jbbs.livedoor.jp/computer/18420/") + + @favorite_item = KDE::ListViewItem.new(self, "お気に入り") + load_favorites end def show_board(item) return if item == nil board_url = item.text(COLUMN_URL) + return if board_url == nil ViewMediator.show_board(board_url) end @@ -110,11 +123,19 @@ board_title = item.text(COLUMN_TITLE) popup = KDE::PopupMenu.new + popup.insertItem("ウェブブラウザで開く", POPUP_OPEN_WITH_WEB_BROWSER) popup.insertItem("Copy URL", POPUP_COPY_URL) popup.insertItem("Copy title and URL", POPUP_COPY_TITLE_AND_URL) + if item.parent == @favorite_item then + popup.insertItem("お気に入りから削除", POPUP_DELETE_FROM_FAVORITE) + else + popup.insertItem("お気に入りに追加", POPUP_ADD_TO_FAVORITE) + end clipboard = Qt::Application.clipboard case popup.exec(pos) + when POPUP_OPEN_WITH_WEB_BROWSER + $app.invokeBrowser(board_url) when POPUP_COPY_URL clipboard.setText(board_url, Qt::Clipboard::Clipboard) clipboard.setText(board_url, Qt::Clipboard::Selection) @@ -122,6 +143,37 @@ cliptext = board_title + "\n" + board_url clipboard.setText(cliptext, Qt::Clipboard::Clipboard) clipboard.setText(cliptext, Qt::Clipboard::Selection) + when POPUP_ADD_TO_FAVORITE + add_to_favorite(board_url) + when POPUP_DELETE_FROM_FAVORITE + delete_from_favorite(item, board_url) + end + end + + def add_to_favorite(board_url) + board_type = Util.board_url_to_board_type_name(board_url) + board_id = Util.board_url_to_board_id(board_url) + registered = FavoriteBoards.instance.register(board_type, board_id) + + if registered then + board_name = BoardManager.instance.get_name(board_url) + KDE::ListViewItem.new(@favorite_item, board_name, board_url) end end + + def delete_from_favorite(item, board_url) + board_type = Util.board_url_to_board_type_name(board_url) + board_id = Util.board_url_to_board_id(board_url) + FavoriteBoards.instance.delete(board_type, board_id) + + @favorite_item.takeItem(item) + end + + def load_favorites + FavoriteBoards.instance.each {|type, id| + board_url = BoardManager.instance.get_url(type, id) + board_name = BoardManager.instance.get_name(board_url) + KDE::ListViewItem.new(@favorite_item, board_name, board_url) + } + end end diff -Nru kita2-1.90.0/boardlistwidget.rb kita2-1.90.4/boardlistwidget.rb --- kita2-1.90.0/boardlistwidget.rb 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/boardlistwidget.rb 2008-04-24 22:52:46.000000000 +0900 @@ -0,0 +1,70 @@ +# Copyright (c) 2008 Hideki Ikemoto +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +class BoardListWidget < Qt::Widget + slots 'load_board_list()' + slots 'search()' + + COLUMN_TITLE = 0 + + def initialize(parent) + super(parent) + + layout = Qt::VBoxLayout.new(self) + + @search_line = Qt::LineEdit.new(self) + layout.addWidget(@search_line) + connect(@search_line, SIGNAL("textChanged(const QString&)"), self, SLOT("search()")) + + @list = BoardListView.new(self) + layout.addWidget(@list) + end + + def load_board_list + @list.load_board_list + end + + def search + str = @search_line.text + regexp = Regexp.new(str, Regexp::IGNORECASE) + + categoryItem = @list.firstChild + while categoryItem + matched = false + boardItem = categoryItem.firstChild + while boardItem + title = boardItem.text(0) + + if title.match(regexp) then + boardItem.setVisible(true) + matched = true + else + boardItem.setVisible(false) + end + + boardItem = boardItem.nextSibling + end + + categoryItem.setVisible(matched) + categoryItem = categoryItem.nextSibling + end + end +end diff -Nru kita2-1.90.0/config.rb kita2-1.90.4/config.rb --- kita2-1.90.0/config.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/config.rb 2008-09-22 23:38:14.000000000 +0900 @@ -49,4 +49,59 @@ @config.writeEntry("Password", password) @config.sync end + + def auto_login + @config.setGroup("Account") + @config.readBoolEntry("AutoLogin") + end + + def auto_login=(flag) + @config.setGroup("Account") + @config.writeEntry("AutoLogin", flag) + @config.sync + end + + def default_name + @config.setGroup("Write") + @config.readEntry("DefaultName") + end + + def default_name=(name) + @config.setGroup("Write") + @config.writeEntry("DefaultName", name) + @config.sync + end + + def default_mail + @config.setGroup("Write") + @config.readEntry("DefaultMail") + end + + def default_mail=(mail) + @config.setGroup("Write") + @config.writeEntry("DefaultMail", mail) + @config.sync + end + + def kotehan + @config.setGroup("Write") + @config.readListEntry("Kotehan") + end + + def kotehan=(list) + @config.setGroup("Write") + @config.writeEntry("Kotehan", list) + @config.sync + end + + def thread_font + @config.setGroup("Face") + @config.readFontEntry("ThreadFont") + end + + def thread_font=(font) + @config.setGroup("Face") + @config.writeEntry("ThreadFont", font) + @config.sync + end end diff -Nru kita2-1.90.0/const.rb kita2-1.90.4/const.rb --- kita2-1.90.0/const.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/const.rb 2008-09-22 23:38:14.000000000 +0900 @@ -22,15 +22,13 @@ module Const Default_Style_Sheet = "div.res_title {\n" + - " font-size: 12px;\n" + " white-spece: nowrap;\n" + " padding-bottom: 0.2em;\n" + "}" + "div.res_body {\n" + - " font-size: 12px;\n" + " margin-left: 3em;\n" + " padding-bottom: 1.8em;\n" + "}" - Version = "1.90.0" + Version = "1.90.4" end diff -Nru kita2-1.90.0/dat.rb kita2-1.90.4/dat.rb --- kita2-1.90.0/dat.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/dat.rb 2008-09-21 23:07:37.000000000 +0900 @@ -23,7 +23,7 @@ attr_accessor :num, :name, :mail, :date, :body, :id def to_html - html = "
#{num} " + html = "
#{num} " if mail != nil && mail.length != 0 then html += "名前:#{name} : " else @@ -35,10 +35,24 @@ html end + def to_plain + text = "#{num} 名前:#{Util::to_plain(name)} #{date}\n" + text += Util::to_plain(@body) + + text + end + def parse_body - @body.gsub(/h?t?tp:\/\/([-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/) {|matched| + body = @body.gsub(/h?t?tp:\/\/([-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/) {|matched| "#{matched}" } + body = body.gsub(/([^<]+)<\/a>/) {|matched| + "#{$2}" + } + body = body.gsub(/([^<]+)<\/a>/) {|matched| + "#{$2}" + } + body end end @@ -55,7 +69,11 @@ begin str = Downloader::load_dat(@dat_url) rescue - str = Downloader::download_dat(@dat_url) + begin + str = Downloader::download_dat(@dat_url) + rescue Net::ProtoRetriableError + str = Downloader::download_maru(@dat_url) + end end parse(str) @@ -69,8 +87,10 @@ def parse(str) case Util.board_type(@dat_url) - when Util::TYPE_2CH, Util::TYPE_MACHIBBS, Util::TYPE_UNKNOWN + when Util::TYPE_2CH, Util::TYPE_UNKNOWN parse_2ch(str) + when Util::TYPE_MACHIBBS + parse_machibbs(str) when Util::TYPE_JBBS parse_jbbs(str) end @@ -87,7 +107,26 @@ comment.mail = items[1] comment.date = items[2] comment.body = items[3] - @thread_name = items[4] if items[4] != nil + @thread_name = items[4] if items[4] != nil && i == 0 + + @comments.push(comment) + } + + save_index + end + + def parse_machibbs(str) + str.each_with_index {|line, i| + line.chomp! + items = line.split(/<>/) + + comment = Comment.new + comment.num = items[0] + comment.name = items[1] + comment.mail = items[2] + comment.date = items[3] + comment.body = items[4] + @thread_name = items[5] if items[5] != nil && items[5] != "" @comments.push(comment) } @@ -106,7 +145,7 @@ comment.mail = items[2] comment.date = items[3] comment.body = items[4] - @thread_name = items[5] if items[5] != nil + @thread_name = items[5] if items[5] != nil && items[5] != "" comment.id = items[6] @comments.push(comment) @@ -125,7 +164,7 @@ index_path = Util.dat_url_to_index_path(@dat_url) config = KDE::Config.new(index_path) - config.writeEntry("ThreadName", @thread_name) + config.writeEntry("ThreadName", @thread_name) if @thread_name config.writeEntry("ResNum", @comments.size) config.sync end @@ -133,7 +172,19 @@ def body(num) @comments[num-1].body end + + def to_plain(num) + if @comments[num-1] == nil then return "" end + @comments[num-1].to_plain + end end class DatManager + def self.delete_dat(dat_url) + dat_path = Util.dat_url_to_dat_path(dat_url) + index_path = Util.dat_url_to_index_path(dat_url) + + File::delete(dat_path) + File::delete(index_path) + end end diff -Nru kita2-1.90.0/debian/changelog kita2-1.90.4/debian/changelog --- kita2-1.90.0/debian/changelog 2008-10-09 23:48:53.000000000 +0900 +++ kita2-1.90.4/debian/changelog 2008-10-09 23:48:54.000000000 +0900 @@ -1,3 +1,11 @@ +kita2 (1.90.4-0ubuntu1) intrepid; urgency=low + + * New upstream release + - Accomodated new server specifications + * Bump up Standards-Version to 3.8.0 + + -- Mitsuya Shibata Thu, 09 Oct 2008 22:59:04 +0900 + kita2 (1.90.0-0ubuntu1) hardy; urgency=low * Initial release (LP: #188940) diff -Nru kita2-1.90.0/debian/control kita2-1.90.4/debian/control --- kita2-1.90.0/debian/control 2008-10-09 23:48:53.000000000 +0900 +++ kita2-1.90.4/debian/control 2008-10-09 23:48:54.000000000 +0900 @@ -4,7 +4,7 @@ Maintainer: Ubuntu MOTU Developers XSBC-Original-Maintainer: Mitsuya Shibata Build-Depends: debhelper (>= 5) -Standards-Version: 3.7.3 +Standards-Version: 3.8.0 Package: kita2 Architecture: all diff -Nru kita2-1.90.0/debian/docs kita2-1.90.4/debian/docs --- kita2-1.90.0/debian/docs 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/debian/docs 2008-10-09 23:48:54.000000000 +0900 @@ -0,0 +1 @@ +README.ja diff -Nru kita2-1.90.0/debian/watch kita2-1.90.4/debian/watch --- kita2-1.90.0/debian/watch 2008-10-09 23:48:53.000000000 +0900 +++ kita2-1.90.4/debian/watch 2008-10-09 23:48:54.000000000 +0900 @@ -1,6 +1,7 @@ # Compulsory line, this is a version 3 file version=3 -http://sourceforge.jp/projects/kita/files/ \ - http://prdownloads.sourceforge.jp/kita/.*/kita2-(.*)\.tar\.gz +opts="downloadurlmangle=s/sourceforge/iij.dl.sourceforge/;s/downloads\///;s/projects\///" \ + http://sourceforge.jp/projects/kita/releases/ \ + /projects/kita/downloads/.*/kita2-(.*)\.tar\.gz debian uupdate diff -Nru kita2-1.90.0/download.rb kita2-1.90.4/download.rb --- kita2-1.90.0/download.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/download.rb 2008-04-13 21:50:11.000000000 +0900 @@ -23,13 +23,16 @@ require 'fileutils' require 'uri' require 'nkf' +require 'time' +require 'zlib' +require 'stringio' require 'const.rb' USER_AGENT = "Monazilla/1.00 (Kita/#{Const::Version})" module Downloader - def Downloader.download_menu_list + def self.download_menu_list str = nil open("http://menu.2ch.net/bbsmenu.html") {|f| sjis_str = f.read @@ -41,7 +44,7 @@ str end - def Downloader.load_menu_list + def self.load_menu_list dir = ENV['HOME'] + "/.kita/cache/2ch" str = nil @@ -51,7 +54,7 @@ str end - def Downloader.download_subject_txt_jbbs(url) + def self.download_subject_txt_jbbs(url) str = nil open(url, "User-Agent" => USER_AGENT) {|f| @@ -66,7 +69,7 @@ str end - def Downloader.download_subject_txt(url) + def self.download_subject_txt(url) str = nil open(url, "User-Agent" => USER_AGENT) {|f| @@ -80,21 +83,69 @@ str end - def Downloader.download_dat(dat_url) + def self.download_dat(dat_url) str = nil - open(dat_url, - "User-Agent" => USER_AGENT) {|f| - raw_str = f.read + date = nil + + Net::HTTP.start(URI.parse(dat_url).host, 80) {|http| + header = { + "Accept-Encoding" => "gzip", + "User-Agent" => USER_AGENT + } + response = http.get(URI.parse(dat_url).path, header) + raise Net::ProtoRetriableError if response.code == '302' + + if response['Content-Encoding'] == "gzip" then + gzipped_str = response.body + gzipped_str_io = StringIO.new(gzipped_str) + raw_str = Zlib::GzipReader.new(gzipped_str_io).read + else + raw_str = response.body + end + str = Util.to_utf8(raw_str, Util.board_type(dat_url)) + + date = response['Date'] + } + + dir = Util.dat_url_to_dat_dir_path(dat_url) + dat_file_name = Util.dat_url_to_dat_file_name(dat_url) + save_date(dir, dat_file_name + ".idx", date) + save(dir, dat_file_name, str) + str + end + + def self.download_maru(dat_url) + str = nil + date = nil + offlaw_path = Util.dat_url_to_offlaw_path(dat_url) + + Net::HTTP.start(URI.parse(dat_url).host, 80) {|http| + header = { + "Accept-Encoding" => "gzip", + "User-Agent" => USER_AGENT + } + response = http.get(offlaw_path, header) + + gzipped_str = response.body + gzipped_str_io = StringIO.new(gzipped_str) + raw_str = Zlib::GzipReader.new(gzipped_str_io).read str = Util.to_utf8(raw_str, Util.board_type(dat_url)) + + # remove '+OK ..../1024K\tLocation: temp/\n' + index = str.index(/\n/) + str = str[index+1..-1] + + date = response['Date'] } dir = Util.dat_url_to_dat_dir_path(dat_url) dat_file_name = Util.dat_url_to_dat_file_name(dat_url) + save_date(dir, dat_file_name + ".idx", date) save(dir, dat_file_name, str) str end - def Downloader.load_dat(dat_url) + def self.load_dat(dat_url) dir = Util.dat_url_to_dat_dir_path(dat_url) dat_file_name = Util.dat_url_to_dat_file_name(dat_url) str = nil @@ -105,10 +156,19 @@ str end - def Downloader.save(dir, file, str) + def self.save(dir, file, str) FileUtils.mkdir_p(dir) File.open(dir + "/" + file, "w") {|f| f.puts(str) } end + + def self.save_date(dir, file, date_str) + time = Time::parse(date_str).to_i + + FileUtils.mkdir_p(dir) + config = KDE::Config.new(dir + "/" + file) + config.writeEntry("Date", time) + config.sync + end end diff -Nru kita2-1.90.0/facepage.rb kita2-1.90.4/facepage.rb --- kita2-1.90.0/facepage.rb 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/facepage.rb 2008-09-22 23:38:14.000000000 +0900 @@ -0,0 +1,38 @@ +# Form implementation generated from reading ui file 'facepage.ui' +# +# Created: 月 9月 22 23:23:59 2008 +# by: The QtRuby User Interface Compiler (rbuic) +# +# WARNING! All changes made in this file will be lost! + +class FacePage < Qt::Widget + + attr_reader :thread_font_requester + + + def initialize(parent = nil, name = nil, fl = 0) + super + + if name.nil? + setName("FacePage") + end + + + @thread_font_requester = KDE::FontRequester.new(self, "thread_font_requester") + @thread_font_requester.setGeometry( Qt::Rect.new(10, 10, 200, 30) ) + languageChange() + resize( Qt::Size.new(429, 480).expandedTo(minimumSizeHint()) ) + clearWState( WState_Polished ) + end + + # + # Sets the strings of the subwidgets using the current + # language. + # + def languageChange() + setCaption(trUtf8("Form1")) + end + protected :languageChange + + +end diff -Nru kita2-1.90.0/facepage.ui kita2-1.90.4/facepage.ui --- kita2-1.90.0/facepage.ui 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/facepage.ui 2008-09-22 23:38:14.000000000 +0900 @@ -0,0 +1,36 @@ + +FacePage + + + FacePage + + + + 0 + 0 + 429 + 480 + + + + Form1 + + + + thread_font_requester + + + + 10 + 10 + 200 + 30 + + + + + + + kfontrequester.h + + diff -Nru kita2-1.90.0/favoriteboards.rb kita2-1.90.4/favoriteboards.rb --- kita2-1.90.0/favoriteboards.rb 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/favoriteboards.rb 2008-04-19 00:01:18.000000000 +0900 @@ -0,0 +1,71 @@ +# Copyright (c) 2008 Hideki Ikemoto +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require 'singleton' + +class FavoriteBoards + include Singleton + + def initialize + load + end + + def load + @favorites = [] + + conf_path = ENV['HOME'] + "/.kita/favorite_board" + return unless File.exist?(conf_path) + + File::open(conf_path).each_line {|line| + line.chomp! + type, id = line.split(",") + @favorites.push([type, id]) + } + end + + def register(type, id) + @favorites.push([type, id]) + + conf_path = ENV['HOME'] + "/.kita/favorite_board" + File::open(conf_path, "w") {|file| + @favorites.each {|type, id| + file.puts "#{type},#{id}" + } + } + end + + def delete(type, id) + @favorites.delete([type, id]) + + conf_path = ENV['HOME'] + "/.kita/favorite_board" + File::open(conf_path, "w") {|file| + @favorites.each {|type, id| + file.puts "#{type},#{id}" + } + } + end + + def each + @favorites.each {|favorite| + yield favorite + } + end +end diff -Nru kita2-1.90.0/htmlpart.rb kita2-1.90.4/htmlpart.rb --- kita2-1.90.0/htmlpart.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/htmlpart.rb 2008-09-23 22:22:35.000000000 +0900 @@ -20,9 +20,16 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class KitaHTMLPart < KDE::HTMLPart + slots 'slotOnURL(const QString&)' + POPUP_WRITE_RES = 0 POPUP_WRITE_RES_WITH_QUOTE = 1 + def initialize(parent) + super + connect(self, SIGNAL("onURL(const QString&)"), self, SLOT("slotOnURL(const QString&)")) + end + def set_view(view) @thread_view = view end @@ -37,14 +44,26 @@ case popup.exec(Qt::Cursor::pos()) when POPUP_WRITE_RES - @thread_view.show_write_dialog_with_str(">>" + num + "\n") + @thread_view.show_write_dialog_with_str(">>" + num.to_s + "\n") when POPUP_WRITE_RES_WITH_QUOTE res = @thread_view.body(num) res = res.gsub(/(^|
)/, "\n> ")[1..-1] @thread_view.show_write_dialog_with_str(res) end + elsif url[0..3] == "#res" then + num = url[4..-1].to_i + gotoAnchor("res#{num}") else $app.invokeBrowser(url) end end + + def slotOnURL(url) + if url && url[0..3] == "#res" then + num = url[4..-1].to_i + node = nodeUnderMouse() + plain = Util::to_plain(@thread_view.to_plain(num)) + node.setTitle(DOM::DOMString.new(plain)) + end + end end バイナリー・ファイル/tmp/p0GUPKyvT1/kita2-1.90.0/kita.pngと/tmp/OBeOb8WPSi/kita2-1.90.4/kita.pngは違います diff -Nru kita2-1.90.0/kita.rb kita2-1.90.4/kita.rb --- kita2-1.90.0/kita.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/kita.rb 2008-09-22 23:38:14.000000000 +0900 @@ -40,11 +40,15 @@ require 'writedialog.rb' require 'threadtabwidget.rb' require 'accountpage.rb' +require 'writepage.rb' require 'preferencedialog.rb' require 'config.rb' require 'account.rb' require 'htmlpart.rb' require 'boardtabwidget.rb' +require 'favoriteboards.rb' +require 'boardlistwidget.rb' +require 'facepage.rb' class ViewMediator def ViewMediator.thread_tab_widget=(tab_widget) @@ -85,6 +89,9 @@ $app = KDE::UniqueApplication.new $main_window = MainWindow.new(0) +pixmap = Qt::Pixmap.new +pixmap.load("kita.png") +$main_window.setIcon(pixmap) $main_window.resize(800, 600) $main_window.show diff -Nru kita2-1.90.0/mainwindow.rb kita2-1.90.4/mainwindow.rb --- kita2-1.90.0/mainwindow.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/mainwindow.rb 2008-04-24 22:52:46.000000000 +0900 @@ -37,7 +37,7 @@ hsplit = Qt::Splitter.new(main_widget) main_layout.addWidget(hsplit) - @board_list_view = BoardListView.new(hsplit) + @board_list_widget = BoardListWidget.new(hsplit) vsplit = Qt::Splitter.new(Qt::Splitter::Vertical, hsplit) @@ -52,13 +52,17 @@ setup_menu statusBar.show + + if Config.instance.auto_login + login + end end def setup_menu menu_bar = menuBar() file_menu = Qt::PopupMenu.new(self) menu_bar.insertItem("&File", file_menu) - file_menu.insertItem("Load Board List", @board_list_view, + file_menu.insertItem("Load Board List", @board_list_widget, SLOT("load_board_list()")) file_menu.insertItem("Login", self, SLOT("login()")) @@ -92,6 +96,11 @@ account = Account.instance account.login(user_id, password) + if account.session_id =~ /^ERROR:/ then + show_status("ログインに失敗しました。") + else + show_status("ログインに成功しました。") + end end def show_thread @@ -106,8 +115,11 @@ end end + def show_status(msg) + statusBar.message(msg) + end + def copy ViewMediator.copy end end - diff -Nru kita2-1.90.0/preferencedialog.rb kita2-1.90.4/preferencedialog.rb --- kita2-1.90.0/preferencedialog.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/preferencedialog.rb 2008-09-22 23:38:14.000000000 +0900 @@ -26,9 +26,16 @@ super(KDE::DialogBase::IconList, 0, parent, "settings") @general_vbox = addVBoxPage("General", nil, KDE::SmallIcon("configure", 32)) + + @face_vbox = addVBoxPage("外観", nil, KDE::SmallIcon("configure", 32)) + @face_page = FacePage.new(@face_vbox) + @account_vbox = addVBoxPage("Account", nil, KDE::SmallIcon("identity", 32)) @account_page = AccountPage.new(@account_vbox) + @write_vbox = addVBoxPage("Write", nil, KDE::SmallIcon("edit", 32)) + @write_page = WritePage.new(@write_vbox) + connect(self, SIGNAL("okClicked()"), self, SLOT("save_config()")) load_config @@ -36,16 +43,31 @@ def load_config config = Config.instance + @face_page.thread_font_requester.setFont(config.thread_font) @account_page.id_line.text = config.user_id @account_page.password_line.text = config.password + @account_page.autologin_check.setChecked(config.auto_login) + @write_page.default_name_line.text = config.default_name + @write_page.default_mail_line.text = config.default_mail + @write_page.kotehan_edit.text = config.kotehan.join("\n") end def save_config id = @account_page.id_line.text password = @account_page.password_line.text + auto_login = @account_page.autologin_check.checked + default_name = @write_page.default_name_line.text + default_mail = @write_page.default_mail_line.text + kotehan = @write_page.kotehan_edit.text.split("\n").grep(/^.+$/) + thread_font = @face_page.thread_font_requester.font config = Config.instance + config.thread_font = thread_font config.user_id = id config.password = password + config.auto_login = auto_login + config.default_name = default_name + config.default_mail = default_mail + config.kotehan = kotehan end end バイナリー・ファイル/tmp/p0GUPKyvT1/kita2-1.90.0/read.pngと/tmp/OBeOb8WPSi/kita2-1.90.4/read.pngは違います diff -Nru kita2-1.90.0/thread_info.rb kita2-1.90.4/thread_info.rb --- kita2-1.90.0/thread_info.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/thread_info.rb 2008-04-13 22:42:16.000000000 +0900 @@ -20,11 +20,11 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class ThreadInfo - attr_reader :url, :title, :res_num, :open_time, :speed + attr_reader :dat_url, :title, :res_num, :open_time, :speed attr_reader :read_num - def initialize(url, title, res_num, open_time, speed) - @url = url + def initialize(dat_url, title, res_num, open_time, speed) + @dat_url = dat_url @title = title @res_num = res_num @open_time = open_time @@ -34,12 +34,10 @@ end def load_index - board_name = URI.parse(@url).path.split("/")[1] - dat_file_name = URI.parse(@url).path.split("/")[3] - dir = ENV['HOME'] + "/.kita/cache/2ch/" + board_name + dat_file_name = Util.dat_url_to_dat_file_name(@dat_url) + dir = Util.dat_url_to_dat_dir_path(@dat_url) config = KDE::Config.new(dir + "/" + dat_file_name + ".idx") - @read_num = config.readEntry("ResNum") + @read_num = config.readNumEntry("ResNum") end end - diff -Nru kita2-1.90.0/threadlistview.rb kita2-1.90.4/threadlistview.rb --- kita2-1.90.0/threadlistview.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/threadlistview.rb 2008-04-24 15:34:44.000000000 +0900 @@ -22,22 +22,32 @@ class ThreadListView < Qt::Widget slots 'show_thread(QListViewItem*)' slots 'search()' + slots 'filter(bool)' slots 'context_menu(QListViewItem*,const QPoint&,int)' slots 'remove_self()' + slots 'reload()' SUBJECT_TXT_REGEXP1 = /((\d+)\.cgi),(.*)\((\d+)\)/ SUBJECT_TXT_REGEXP2 = /((\d+)\.dat)<>(.*)\((\d+)\)/ - COLUMN_NO = 0 - COLUMN_SEARCH = 1 - COLUMN_TITLE = 2 - COLUMN_RESNUM = 3 - COLUMN_READNUM = 4 - COLUMN_OPENTIME = 5 - COLUMN_SPEED = 6 - COLUMN_URL = 7 - - POPUP_COPY_URL = 0 - POPUP_COPY_TITLE_AND_URL = 1 + COLUMN_MARK = 0 + COLUMN_NO = 1 + COLUMN_SEARCH = 2 + COLUMN_TITLE = 3 + COLUMN_RESNUM = 4 + COLUMN_READNUM = 5 + COLUMN_UNREADNUM = 6 + COLUMN_OPENTIME = 7 + COLUMN_SPEED = 8 + COLUMN_URL = 9 + COLUMN_MARKORDER = 10 + + ORDER_UNREAD = "0" + ORDER_READ = "1" + ORDER_NORMAL = "2" + + POPUP_OPEN_WITH_WEB_BROWSER = 0 + POPUP_COPY_URL = 1 + POPUP_COPY_TITLE_AND_URL = 2 def initialize(parent) super(parent) @@ -52,9 +62,23 @@ tool_layout.addWidget(@search_button) connect(@search_button, SIGNAL("clicked()"), self, SLOT("search()")) - connect(@search_line, SIGNAL("returnPressed()"), + connect(@search_line, SIGNAL("textChanged(const QString&)"), self, SLOT("search()")) + @filter_button = Qt::ToolButton.new(self) + @filter_button.setPixmap(KDE::SmallIcon("filter")) + @filter_button.setToggleButton(true) + @filter_button.setEnabled(false) + tool_layout.addWidget(@filter_button) + connect(@filter_button, SIGNAL("toggled(bool)"), + self, SLOT("filter(bool)")) + + @reload_button = Qt::ToolButton.new(self) + @reload_button.setPixmap(KDE::SmallIcon("reload")) + @reload_button.setEnabled(false) + tool_layout.addWidget(@reload_button) + connect(@reload_button, SIGNAL("clicked()"), self, SLOT("reload()")) + @close_button = Qt::ToolButton.new(self) @close_button.setPixmap(KDE::SmallIcon("fileclose")) @close_button.setEnabled(false) @@ -69,15 +93,17 @@ connect(@list, SIGNAL("contextMenuRequested(QListViewItem*,const QPoint&,int)"), self, SLOT("context_menu(QListViewItem*,const QPoint&,int)")) + @list.addColumn("") @list.addColumn("No.") @list.addColumn(" ") @list.addColumn("Thread name") @list.addColumn("Res") @list.addColumn("Read") + @list.addColumn("Unread") @list.addColumn("Open time") @list.addColumn("Thread speed") # @list.addColumn("Thread url") - @list.setSorting(-1) +# @list.setSorting(-1) @list.setAllColumnsShowFocus(true) @list.header.setStretchEnabled(true, COLUMN_TITLE) @@ -107,7 +133,7 @@ dat_file_name = Regexp.last_match(1) open_time = Time::at(Regexp.last_match(2).to_i) title = Regexp.last_match(3) - num = Regexp.last_match(4) + num = Regexp.last_match(4).to_i speed = num.to_i / ((Time::now - open_time) / 86400.0) dat_url = Util.make_dat_url(@board_url, dat_file_name) @@ -120,14 +146,25 @@ prev_item = nil thread_list.each_with_index {|thread, i| - item = KDE::ListViewItem.new(@list, prev_item) - item.setText(COLUMN_NO, (i+1).to_s) + item = ThreadListViewItem.new(@list, prev_item) + item.setText(COLUMN_NO, "%4s" % (i+1)) item.setText(COLUMN_TITLE, thread.title) - item.setText(COLUMN_RESNUM, thread.res_num) - item.setText(COLUMN_READNUM, thread.read_num) if thread.read_num + item.setText(COLUMN_RESNUM, "%4s" % thread.res_num) + item.setText(COLUMN_READNUM, "%4s" % thread.read_num) if thread.read_num != 0 + item.setText(COLUMN_UNREADNUM, "%4s" % (thread.res_num - thread.read_num)) if thread.read_num != 0 item.setText(COLUMN_OPENTIME, thread.open_time.strftime("%y/%m/%d %H:%M")) item.setText(COLUMN_SPEED, thread.speed.to_s) - item.setText(COLUMN_URL, thread.url) + item.setText(COLUMN_URL, thread.dat_url) + + if thread.res_num > thread.read_num && thread.read_num != 0 then + item.setPixmap(COLUMN_MARK, Qt::Pixmap.new("unread.png")) + item.setText(COLUMN_MARKORDER, ORDER_UNREAD) + elsif thread.res_num == thread.read_num then + item.setPixmap(COLUMN_MARK, Qt::Pixmap.new("read.png")) + item.setText(COLUMN_MARKORDER, ORDER_READ) + else + item.setText(COLUMN_MARKORDER, ORDER_NORMAL) + end prev_item = item } @@ -149,9 +186,27 @@ str = @search_line.text if str == @prev_search_text search_next - else + elsif str != "" search_new(str) @prev_search_text = str + @filter_button.setOn(true) + filter(true) + else + search_clear + @filter_button.setOn(false) + end + end + + def filter(on) + it = Qt::ListViewItemIterator.new(@list) + while it.current do + item = it.current + if on && ! item.pixmap(COLUMN_SEARCH) then + item.setVisible(false) + else + item.setVisible(true) + end + it += 1 end end @@ -163,7 +218,8 @@ it = Qt::ListViewItemIterator.new(@list) while it.current do item = it.current - item.setText(COLUMN_SEARCH, "") + item.setPixmap(COLUMN_SEARCH, Qt::Pixmap.new) + it += 1 end end @@ -175,7 +231,7 @@ regexp = Regexp.new(str, Regexp::IGNORECASE) while it.current do item = it.current - item.setText(COLUMN_SEARCH, "") # clear + item.setPixmap(COLUMN_SEARCH, Qt::Pixmap.new) # clear title = item.text(COLUMN_TITLE) if title.match(regexp) then @@ -209,11 +265,14 @@ thread_title = item.text(COLUMN_TITLE) popup = KDE::PopupMenu.new + popup.insertItem("ウェブブラウザで開く", POPUP_OPEN_WITH_WEB_BROWSER) popup.insertItem("Copy URL", POPUP_COPY_URL) popup.insertItem("Copy title and URL", POPUP_COPY_TITLE_AND_URL) clipboard = Qt::Application.clipboard case popup.exec(pos) + when POPUP_OPEN_WITH_WEB_BROWSER + $app.invokeBrowser(thread_url) when POPUP_COPY_URL clipboard.setText(thread_url, Qt::Clipboard::Clipboard) clipboard.setText(thread_url, Qt::Clipboard::Selection) @@ -232,8 +291,28 @@ @board_url end + def reload + show_board(@board_url) + end + def enable_buttons @search_button.setEnabled(true) + @filter_button.setEnabled(true) + @reload_button.setEnabled(true) @close_button.setEnabled(true) end end + +class ThreadListViewItem < KDE::ListViewItem + def compare(item, col, ascending) + case col + when ThreadListView::COLUMN_MARK + key1 = key(ThreadListView::COLUMN_MARKORDER, ascending) + key2 = item.key(ThreadListView::COLUMN_MARKORDER, ascending) + + key1.to_i <=> key2.to_i + else + key(col, ascending) <=> item.key(col, ascending) + end + end +end diff -Nru kita2-1.90.0/threadview.rb kita2-1.90.4/threadview.rb --- kita2-1.90.0/threadview.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/threadview.rb 2008-09-22 23:38:14.000000000 +0900 @@ -21,8 +21,10 @@ class ThreadView < Qt::Widget slots 'reload()' + slots 'delete()' slots 'show_write_dialog()' slots 'remove_self()' + slots 'search()' attr_reader :dat_url @@ -40,12 +42,23 @@ buttons_layout.addWidget(@write_button) connect(@write_button, SIGNAL("clicked()"), self, SLOT("show_write_dialog()")) + @search_line = Qt::LineEdit.new(self) + @search_line.setEnabled(false) + buttons_layout.addWidget(@search_line) + connect(@search_line, SIGNAL("returnPressed()"), self, SLOT("search()")) + @reload_button = Qt::ToolButton.new(self) @reload_button.setPixmap(KDE::SmallIcon("reload")) @reload_button.setEnabled(false) buttons_layout.addWidget(@reload_button) connect(@reload_button, SIGNAL("clicked()"), self, SLOT("reload()")) + @delete_button = Qt::ToolButton.new(self) + @delete_button.setPixmap(KDE::SmallIcon("edittrash")) + @delete_button.setEnabled(false) + buttons_layout.addWidget(@delete_button) + connect(@delete_button, SIGNAL("clicked()"), self, SLOT("delete()")) + spacer = Qt::SpacerItem.new(30, 20, Qt::SizePolicy::Expanding, Qt::SizePolicy::Minimum) @@ -75,11 +88,15 @@ ViewMediator.set_url(Util.dat_url_to_thread_url(dat_url)) enable_buttons + @html_part.view().setFocus() end def write(dat) + config = Config.instance @html_part.begin() @html_part.write("") dat.each {|comment| @@ -91,7 +108,9 @@ def enable_buttons @write_button.setEnabled(true) + @search_line.setEnabled(true) @reload_button.setEnabled(true) + @delete_button.setEnabled(true) @close_button.setEnabled(true) end @@ -102,10 +121,21 @@ write(dat) end + def delete + if Qt::MessageBox::warning(self, + "Kita", + "スレッドのログを削除します。よろしいですか?", + Qt::MessageBox::Ok, + Qt::MessageBox::Cancel | Qt::MessageBox::Default) == + Qt::MessageBox::Ok then + DatManager::delete_dat(@dat_url) + end + end + def show_write_dialog dialog = WriteDialog.instance dialog.dat_url = @dat_url - dialog.thread_name = Util.truncate_str(thread_name, 20) + dialog.thread_name = thread_name dialog.board_name = BoardManager.instance.get_name(Util.dat_url_to_board_url(@dat_url)) dialog.show dialog @@ -128,6 +158,10 @@ @dat.body(num) end + def to_plain(num) + @dat.to_plain(num) + end + def copy selected_text = @html_part.selectedText return if selected_text == nil @@ -136,4 +170,30 @@ clipboard = Qt::Application.clipboard clipboard.setText(selected_text, Qt::Clipboard::Clipboard) end + + def search + str = @search_line.text + if str == @prev_search_text + search_next + elsif str != "" + search_new(str) + @prev_search_text = str + else + search_clear + end + end + + def search_next + @html_part.findTextNext() + @search_line.setFocus() + end + + def search_new(str) + @html_part.findTextBegin() + @html_part.findText(str, 0) + end + + def search_clear + @html_part.findTextBegin() + end end バイナリー・ファイル/tmp/p0GUPKyvT1/kita2-1.90.0/unread.pngと/tmp/OBeOb8WPSi/kita2-1.90.4/unread.pngは違います diff -Nru kita2-1.90.0/util.rb kita2-1.90.4/util.rb --- kita2-1.90.0/util.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/util.rb 2008-09-21 23:07:37.000000000 +0900 @@ -44,6 +44,19 @@ return TYPE_UNKNOWN end + def self.board_url_to_board_type_name(board_url) + case self.board_type(board_url) + when TYPE_2CH + "2ch" + when TYPE_MACHIBBS + "machibbs" + when TYPE_JBBS + "jbbs.livedoor.jp" + when TYPE_UNKNOWN + "?" + end + end + def self.board_url?(url) url_2ch = %r|http://.*\.2ch\.net/.*| url_bbspink = %r|http://.*\.bbspink\.com/.*| @@ -80,6 +93,22 @@ end end + def self.build_jbbs_post_str(name, mail, body, board_id, thread_id, server_time) + str = "" + + str += "submit=%8F%91%82%AB%8D%9E%82%DE" + + str += "&BBS=" + board_id.split("/")[1] + str += "&KEY=" + thread_id + str += "&DIR=" + board_id.split("/")[0] + str += "&NAME=" + CGI.escape(NKF.nkf("-Wsx", name)) # UTF-8 -> SJIS with JISX0201 + str += "&MAIL=" + CGI.escape(NKF.nkf("-Wsx", mail)) # UTF-8 -> SJIS with JISX0201 + str += "&MESSAGE=" + CGI.escape(NKF.nkf("-Wsx", body)) # UTF-8 -> SJIS with JISX0201 + str += "&TIME=" + server_time.to_i.to_s + + str + end + def self.build_post_str(name, mail, body, board_id, thread_id, server_time, session_id) str = "" @@ -88,7 +117,6 @@ str += "&mail=" + CGI.escape(NKF.nkf("-Wsx", mail)) # UTF-8 -> SJIS with JISX0201 str += "&MESSAGE=" + CGI.escape(NKF.nkf("-Wsx", body)) # UTF-8 -> SJIS with JISX0201 str += "&bbs=" + board_id - str += "&hana=mogera" str += "&key=" + thread_id str += "&time=" + server_time.to_i.to_s str += "&sid=" + session_id if session_id @@ -98,8 +126,10 @@ def self.dat_url_to_dat_file_name(url) case self.board_type(url) - when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + when TYPE_2CH, TYPE_UNKNOWN URI.parse(url).path.split("/")[3] + when TYPE_MACHIBBS + URI.parse(url).path.split("/")[4] + ".dat" when TYPE_JBBS URI.parse(url).path.split("/")[5] end @@ -112,15 +142,24 @@ def self.dat_url_to_board_id(url) case self.board_type(url) - when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + when TYPE_2CH, TYPE_UNKNOWN URI.parse(url).path.split("/")[1] + when TYPE_MACHIBBS + URI.parse(url).path.split("/")[3] when TYPE_JBBS URI.parse(url).path.split("/")[3] + "/" + URI.parse(url).path.split("/")[4] end end def self.dat_url_to_write_url(url) - "http://#{URI.parse(url).host}/test/bbs.cgi" + case self.board_type(url) + when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + "http://#{URI.parse(url).host}/test/bbs.cgi" + when TYPE_JBBS + board_id = self.dat_url_to_board_id(url) + thread_id = self.dat_url_to_thread_id(url) + "http://#{URI.parse(url).host}/bbs/write.cgi/#{board_id}/#{thread_id}/" + end end def self.dat_url_to_board_url(url) @@ -128,24 +167,39 @@ "http://#{URI.parse(url).host}/#{board_id}/" end + # http://jbbs.livedoor.jp/bbs/rawmode.cgi/computer/18420/1103791337/ + # -> http://jbbs.livedoor.jp/bbs/read.cgi/computer/18420/1103791337/ def self.dat_url_to_thread_url(url) - board_id = self.dat_url_to_board_id(url) - thread_id = self.dat_url_to_thread_id(url) - "http://#{URI.parse(url).host}/test/read.cgi/#{board_id}/#{thread_id}/" + case self.board_type(url) + when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + board_id = self.dat_url_to_board_id(url) + thread_id = self.dat_url_to_thread_id(url) + "http://#{URI.parse(url).host}/test/read.cgi/#{board_id}/#{thread_id}/" + when TYPE_JBBS + board_id = self.dat_url_to_board_id(url) + thread_id = self.dat_url_to_thread_id(url) + "http://#{URI.parse(url).host}/bbs/read.cgi/#{board_id}/#{thread_id}/" + end end - def self.dat_url_to_index_path(dat_url) + def self.dat_url_to_dat_path(dat_url) dir = self.dat_url_to_dat_dir_path(dat_url) dat_file_name = self.dat_url_to_dat_file_name(dat_url) - dir + "/" + dat_file_name + ".idx" + dir + "/" + dat_file_name + end + + def self.dat_url_to_index_path(dat_url) + self.dat_url_to_dat_path(dat_url) + ".idx" end def self.dat_url_to_dat_dir_path(dat_url) board_id = self.dat_url_to_board_id(dat_url) case self.board_type(dat_url) - when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + when TYPE_2CH, TYPE_UNKNOWN ENV['HOME'] + "/.kita/cache/2ch/" + board_id + when TYPE_MACHIBBS + ENV['HOME'] + "/.kita/cache/machibbs/" + board_id when TYPE_JBBS ENV['HOME'] + "/.kita/cache/#{URI.parse(dat_url).host}/" + board_id.tr('/', '_') end @@ -165,10 +219,21 @@ "http://#{URI.parse(url).host}/#{board_id}/dat/#{thread_id}.dat" end + def self.dat_url_to_offlaw_path(dat_url) + thread_id = self.dat_url_to_thread_id(dat_url) + board_id = self.dat_url_to_board_id(dat_url) + session_id = CGI.escape(Account.instance.session_id) + "/test/offlaw.cgi?raw=0.0&bbs=#{board_id}&key=#{thread_id}&sid=#{session_id}" + end + def self.make_dat_url(board_url, dat_file_name) case self.board_type(board_url) - when TYPE_2CH, TYPE_MACHIBBS, TYPE_UNKNOWN + when TYPE_2CH, TYPE_UNKNOWN board_url + "dat/" + dat_file_name + when TYPE_MACHIBBS + board_id = self.board_url_to_board_id(board_url) + thread_id = dat_file_name.split("\.")[0] + "http://#{URI.parse(board_url).host}/bbs/offlaw.cgi/#{board_id}/#{thread_id}/" when TYPE_JBBS board_id = self.board_url_to_board_id(board_url) thread_id = dat_file_name.split("\.")[0] @@ -184,7 +249,7 @@ ret += char count += 1 } - ret += "…" + ret += "…" if str.size != ret.size ret end @@ -196,4 +261,24 @@ NKF.nkf("-Ewx", raw_str) # EUC-JP -> UTF-8 with JISX0201 end end + + def self.server_time(dat_url) + index_path = dat_url_to_index_path(dat_url) + + config = KDE::Config.new(index_path) + config.readEntry("Date") + end + + def self.to_plain(html) + text = html.gsub("
", "\n") + text.gsub!("", "") + text.gsub!("", "") + text.gsub!("<", "<") + text.gsub!(">", ">") + text.gsub!("&", "&"); + text.gsub!(/]+>([^<]*)<\/a>/) {|matched| + $1 + } + text + end end diff -Nru kita2-1.90.0/writedialog.rb kita2-1.90.4/writedialog.rb --- kita2-1.90.0/writedialog.rb 2008-02-01 23:25:33.000000000 +0900 +++ kita2-1.90.4/writedialog.rb 2008-09-17 22:59:42.000000000 +0900 @@ -40,8 +40,17 @@ def show super - @name_line.text = "" - @mail_line.text = "" + index_path = Util.dat_url_to_index_path(@dat_url) + config = KDE::Config.new(index_path) + names = config.readListEntry("Names") + kotehan = Config.instance.kotehan + + @name_combo.clear + @name_combo.insertItem(Config.instance.default_name) + @name_combo.insertStringList(kotehan) + @name_combo.insertStringList(names) + + @mail_line.text = Config.instance.default_mail @body_edit.text = "" @sage_checkbox.setChecked(false) @ok_button.setEnabled(false) @@ -55,24 +64,49 @@ @write_url = Util.dat_url_to_write_url(dat_url) end + def board_name + @board_name_label.text + end + def board_name=(board_name) @board_name_label.text = board_name end + def thread_name + @thread_name + end + def thread_name=(thread_name) - @thread_name_label.text = thread_name + @thread_name = thread_name + @thread_name_label.text = Util.truncate_str(thread_name, 20) + Qt::ToolTip::add(@thread_name_label, thread_name) end def post - name = @name_line.text + name = @name_combo.currentText mail = @mail_line.text body = @body_edit.text - server_time = Time::now + server_time = Util.server_time(@dat_url) - post_str = Util.build_post_str(name, mail, body, - @board_id, @thread_id, server_time, - Account.instance.session_id) + save_name(name) + save_log(board_name(), thread_name(), Util.dat_url_to_thread_url(@dat_url), + name, mail, body) + + post_str = "" + case Util.board_type(@board_url) + when Util::TYPE_2CH, Util::TYPE_MACHIBBS, Util::TYPE_UNKNOWN + post_str = Util.build_post_str(name, mail, body, + @board_id, @thread_id, server_time, + Account.instance.session_id) + post_2ch(post_str) + when Util::TYPE_JBBS + post_str = Util.build_jbbs_post_str(name, mail, body, + @board_id, @thread_id, server_time) + post_jbbs(post_str) + end + end + def post_jbbs(post_str) response_body = nil cookies = [] Net::HTTP.start(URI.parse(@write_url).host, 80) {|http| @@ -83,6 +117,24 @@ response = http.post(URI.parse(@write_url).path, post_str, header) + response_body = NKF.nkf("-Ewx", response.body) # EUC -> UTF-8 with JISX0201 + } + + accept + end + + def post_2ch(post_str) + response_body = nil + cookies = [] + Net::HTTP.start(URI.parse(@write_url).host, 80) {|http| + header = { + "Content-Type" => "application/x-www-form-urlencoded", + "Referer" => @board_url, + "User-Agent" => USER_AGENT + } + response = http.post(URI.parse(@write_url).path, + post_str, header) + response_body = NKF.nkf("-Swx", response.body) # SJIS -> UTF-8 with JISX0201 response.get_fields("Set-Cookie").each {|cookie| @@ -93,11 +145,24 @@ return unless response_body && response_body.match(//) + name_cmp = " "application/x-www-form-urlencoded", "Referer" => @board_url, - "Cookie" => cookies.join(";") + "Cookie" => cookies.join(";"), + "User-Agent" => USER_AGENT } response = http.post(URI.parse(@write_url).path, post_str, header) @@ -108,6 +173,34 @@ accept end + def save_log(board_name, thread_name, thread_url, name, mail, body) + log_path = ENV['HOME'] + "/.kita/write.log" + + open(log_path, "a") {|io| + io.puts "Date : #{Time::now.to_s}" + io.puts "Board : #{board_name}" + io.puts "Thread : #{thread_name}" + io.puts "URL : #{thread_url}" + io.puts "Name : #{name}" + io.puts "Mail : #{mail}" + io.puts + io.puts body + io.puts "--------------------" + } + end + + def save_name(name) + return if name == nil || name.empty? + + index_path = Util.dat_url_to_index_path(@dat_url) + config = KDE::Config.new(index_path) + + names = config.readListEntry("Names") || [] + names.push(name) unless names.include?(name) + config.writeEntry("Names", names) + config.sync + end + def set_sage(on) if on == true @mail_stack = @mail_line.text diff -Nru kita2-1.90.0/writedialogbase.rb kita2-1.90.4/writedialogbase.rb --- kita2-1.90.0/writedialogbase.rb 2008-01-13 23:50:21.000000000 +0900 +++ kita2-1.90.4/writedialogbase.rb 2008-02-08 00:58:15.000000000 +0900 @@ -1,6 +1,6 @@ # Form implementation generated from reading ui file 'writedialogbase.ui' # -# Created: 日 1月 13 23:42:19 2008 +# Created: 金 2月 8 00:49:53 2008 # by: The QtRuby User Interface Compiler (rbuic) # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,7 @@ attr_reader :thread_name_title attr_reader :thread_name_label attr_reader :name_title - attr_reader :name_line + attr_reader :name_combo attr_reader :mail_title attr_reader :mail_line attr_reader :sage_checkbox @@ -30,9 +30,7 @@ end setSizeGripEnabled(true) - @WriteDialogBaseLayout = Qt::GridLayout.new(self, 1, 1, 11, 6, 'WriteDialogBaseLayout') - - @layout = Qt::VBoxLayout.new(nil, 0, 6, 'layout') + @WriteDialogBaseLayout = Qt::VBoxLayout.new(self, 11, 6, 'WriteDialogBaseLayout') @layout1 = Qt::HBoxLayout.new(nil, 0, 6, 'layout1') @@ -49,28 +47,31 @@ @thread_name_label = Qt::Label.new(self, "thread_name_label") @layout1.addWidget(@thread_name_label) - @layout.addLayout(@layout1) + @WriteDialogBaseLayout.addLayout(@layout1) - @layout2 = Qt::HBoxLayout.new(nil, 0, 6, 'layout2') + @layout8 = Qt::HBoxLayout.new(nil, 0, 6, 'layout8') @name_title = Qt::Label.new(self, "name_title") - @layout2.addWidget(@name_title) + @layout8.addWidget(@name_title) - @name_line = Qt::LineEdit.new(self, "name_line") - @layout2.addWidget(@name_line) + @name_combo = Qt::ComboBox.new(false, self, "name_combo") + @name_combo.setSizePolicy( Qt::SizePolicy.new(7, 0, 0, 0, @name_combo.sizePolicy().hasHeightForWidth()) ) + @name_combo.setEditable( true ) + @name_combo.setAutoCompletion( true ) + @layout8.addWidget(@name_combo) @mail_title = Qt::Label.new(self, "mail_title") - @layout2.addWidget(@mail_title) + @layout8.addWidget(@mail_title) @mail_line = Qt::LineEdit.new(self, "mail_line") - @layout2.addWidget(@mail_line) + @layout8.addWidget(@mail_line) @sage_checkbox = Qt::CheckBox.new(self, "sage_checkbox") - @layout2.addWidget(@sage_checkbox) - @layout.addLayout(@layout2) + @layout8.addWidget(@sage_checkbox) + @WriteDialogBaseLayout.addLayout(@layout8) @body_edit = Qt::TextEdit.new(self, "body_edit") - @layout.addWidget(@body_edit) + @WriteDialogBaseLayout.addWidget(@body_edit) @layout3 = Qt::HBoxLayout.new(nil, 0, 6, 'layout3') @@ -88,9 +89,7 @@ @cancel_button = Qt::PushButton.new(self, "cancel_button") @cancel_button.setAutoDefault( true ) @layout3.addWidget(@cancel_button) - @layout.addLayout(@layout3) - - @WriteDialogBaseLayout.addLayout(@layout, 0, 0) + @WriteDialogBaseLayout.addLayout(@layout3) languageChange() resize( Qt::Size.new(473, 334).expandedTo(minimumSizeHint()) ) clearWState( WState_Polished ) diff -Nru kita2-1.90.0/writedialogbase.ui kita2-1.90.4/writedialogbase.ui --- kita2-1.90.0/writedialogbase.ui 2008-01-13 23:50:21.000000000 +0900 +++ kita2-1.90.4/writedialogbase.ui 2008-02-08 00:58:15.000000000 +0900 @@ -18,206 +18,210 @@ true - + unnamed - + - layout + layout1 - + unnamed - + - layout1 + board_name_title + + + + 0 + 5 + 0 + 0 + + + + 板: + + + + + board_name_label + + + boardName + + + + + thread_name_title + + + + 0 + 5 + 0 + 0 + + + + スレッド: + + + + + thread_name_label + + + threadName + + + + + + + layout8 + + + + unnamed + + + + name_title + + + 名前 + + + + + name_combo + + + + 7 + 0 + 0 + 0 + + + + true + + + true + + + + + mail_title + + + メール + + + + + mail_line + + + + + sage_checkbox + + + sage + + + + + + + body_edit + + + + + layout3 + + + + unnamed + + + 0 + + + 6 + + + + help_button + + + &Help + + + F1 + + + true + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + ok_button + + + &OK + + + + + + true + + + true + + + + + cancel_button + + + &Cancel + + + + + + true - - - unnamed - - - - board_name_title - - - - 0 - 5 - 0 - 0 - - - - 板: - - - - - board_name_label - - - boardName - - - - - thread_name_title - - - - 0 - 5 - 0 - 0 - - - - スレッド: - - - - - thread_name_label - - - threadName - - - - - - - layout2 - - - - unnamed - - - - name_title - - - 名前 - - - - - name_line - - - - - mail_title - - - メール - - - - - mail_line - - - - - sage_checkbox - - - sage - - - - - - - body_edit - - - - - layout3 - - - - unnamed - - - 0 - - - 6 - - - - help_button - - - &Help - - - F1 - - - true - - - - - spacer1 - - - Horizontal - - - Expanding - - - - 20 - 20 - - - - - - ok_button - - - &OK - - - - - - true - - - true - - - - - cancel_button - - - &Cancel - - - - - - true - - - - + - + diff -Nru kita2-1.90.0/writepage.rb kita2-1.90.4/writepage.rb --- kita2-1.90.0/writepage.rb 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/writepage.rb 2008-09-17 22:59:42.000000000 +0900 @@ -0,0 +1,71 @@ +# Form implementation generated from reading ui file 'writepage.ui' +# +# Created: 水 9月 17 22:55:12 2008 +# by: The QtRuby User Interface Compiler (rbuic) +# +# WARNING! All changes made in this file will be lost! + +class WritePage < Qt::Widget + + attr_reader :textLabel1 + attr_reader :default_name_line + attr_reader :textLabel1_2 + attr_reader :default_mail_line + attr_reader :textLabel2 + attr_reader :kotehan_edit + + + def initialize(parent = nil, name = nil, fl = 0) + super + + if name.nil? + setName("WritePage") + end + + @WritePageLayout = Qt::VBoxLayout.new(self, 11, 6, 'WritePageLayout') + + @layout2 = Qt::HBoxLayout.new(nil, 0, 6, 'layout2') + + @textLabel1 = Qt::Label.new(self, "textLabel1") + @layout2.addWidget(@textLabel1) + + @default_name_line = Qt::LineEdit.new(self, "default_name_line") + @layout2.addWidget(@default_name_line) + @WritePageLayout.addLayout(@layout2) + + @layout1 = Qt::HBoxLayout.new(nil, 0, 6, 'layout1') + + @textLabel1_2 = Qt::Label.new(self, "textLabel1_2") + @layout1.addWidget(@textLabel1_2) + + @default_mail_line = Qt::LineEdit.new(self, "default_mail_line") + @layout1.addWidget(@default_mail_line) + @WritePageLayout.addLayout(@layout1) + + @layout3 = Qt::HBoxLayout.new(nil, 0, 6, 'layout3') + + @textLabel2 = Qt::Label.new(self, "textLabel2") + @layout3.addWidget(@textLabel2) + + @kotehan_edit = Qt::TextEdit.new(self, "kotehan_edit") + @layout3.addWidget(@kotehan_edit) + @WritePageLayout.addLayout(@layout3) + languageChange() + resize( Qt::Size.new(600, 499).expandedTo(minimumSizeHint()) ) + clearWState( WState_Polished ) + end + + # + # Sets the strings of the subwidgets using the current + # language. + # + def languageChange() + setCaption(trUtf8("Form1")) + @textLabel1.setText( trUtf8("デフォルトの名前") ) + @textLabel1_2.setText( trUtf8("デフォルトのメールアドレス") ) + @textLabel2.setText( trUtf8("コテハン") ) + end + protected :languageChange + + +end diff -Nru kita2-1.90.0/writepage.ui kita2-1.90.4/writepage.ui --- kita2-1.90.0/writepage.ui 1970-01-01 09:00:00.000000000 +0900 +++ kita2-1.90.4/writepage.ui 2008-09-17 22:59:42.000000000 +0900 @@ -0,0 +1,94 @@ + +WritePage + + + WritePage + + + + 0 + 0 + 600 + 499 + + + + Form1 + + + + unnamed + + + + layout2 + + + + unnamed + + + + textLabel1 + + + デフォルトの名前 + + + + + default_name_line + + + + + + + layout1 + + + + unnamed + + + + textLabel1_2 + + + デフォルトのメールアドレス + + + + + default_mail_line + + + + + + + layout3 + + + + unnamed + + + + textLabel2 + + + コテハン + + + + + kotehan_edit + + + + + + + +