pax_global_header00006660000000000000000000000064136264573070014527gustar00rootroot0000000000000052 comment=e2754fac48fb1aded78b364f37fe36a8ba77791c tdiary-core-5.1.1/000077500000000000000000000000001362645730700137555ustar00rootroot00000000000000tdiary-core-5.1.1/.coveralls.yml000066400000000000000000000000271362645730700165470ustar00rootroot00000000000000service_name: travis-citdiary-core-5.1.1/.dockerignore000066400000000000000000000000601362645730700164250ustar00rootroot00000000000000.bundle .htpasswd vendor/bundle public/assets/* tdiary-core-5.1.1/.editorconfig000066400000000000000000000001051362645730700164260ustar00rootroot00000000000000root = true [*.rb] indent_size = 3 indent_style = tab tab_width = 3 tdiary-core-5.1.1/.gitignore000066400000000000000000000003211362645730700157410ustar00rootroot00000000000000.bundle .htpasswd coverage coverage.* data/* !data/.htaccess log pkg tmp rdoc index.rdf tdiary.conf vendor/bundle/ spec/reports doc/*.html .rspec .ruby-version /Gemfile.local spec/javascripts/lib node_modules tdiary-core-5.1.1/.travis.yml000066400000000000000000000011461362645730700160700ustar00rootroot00000000000000language: ruby sudo: false services: memcache rvm: - 2.4.7 - 2.5.7 - 2.6.5 - 2.7.0 - ruby-head matrix: allow_failures: - rvm: ruby-head cache: bundler: true directories: - node_modules # ignored --deployment option bundler_args: "--without server --jobs=3 --retry=3" before_install: - "echo 'gemspec' > Gemfile.local" - gem update bundler before_script: - npm install script: if [ $TEST_MODE = "gem" ] ; then bundle exec tdiary test ; else bundle exec rake spec jasmine:ci test ; fi env: - TEST_MODE=rack - TEST_MODE=gem notifications: irc: "irc.freenode.org#tdiary" tdiary-core-5.1.1/.vscode/000077500000000000000000000000001362645730700153165ustar00rootroot00000000000000tdiary-core-5.1.1/.vscode/launch.json000066400000000000000000000005521362645730700174650ustar00rootroot00000000000000{ "version": "0.2.0", "configurations": [ { "name": "tDiary server", "type": "Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/bin/tdiary", "args": [ "server" ], "useBundler": true } ] } tdiary-core-5.1.1/ChangeLog000066400000000000000000003725111362645730700155400ustar00rootroot000000000000002020-02-29 Tada, Tadashi * release 5.1.1 2020-02-27 Tada, Tadashi * category.rb: add an option to sort reverse the category list 2020-02-25 Tada, Tadashi * amazon.rb: check access_key and secret_key are specified 2019-11-29 Tada, Tadashi * release 5.1.0 2019-11-24 Tada, Tadashi * amazon.rb: update to use PA-API v5 2019-08-17 Tada, Tadashi * sort commants by date on a new comment added 2019-08-15 HIGUCHI Daisuke (VDR dai) * amazon.rb: support HTTP Found response and discard wrong stored cache 2019-06-29 SHIBATA Hiroshi * release 5.0.14 2019-05-15 Tada, Tadashi * update jQuery to 3.4.1 * amazon.rb: fix default image to https 2019-04-03 Tada, Tadashi * release 5.0.13 2019-04-02 Tada, Tadashi * fix: support extentions (cf.tdiary-contrib) assets paths again 2019-03-29 Tada, Tadashi * release 5.0.12 2019-03-27 Tada, Tadashi * stop to support ruby 2.3 2019-03-12 SHIBATA Hiroshi * remove sprockets dependency 2019-03-19 Tada, Tadashi * amazon plugin: use https resource on amazon image 2018-12-29 Tada, Tadashi * release 5.0.11 2018-09-29 SHIBATA Hiroshi * release 5.0.10 2018-06-29 Tada, Tadashi * release 5.0.9 2018-06-21 Tada, Tadashi * amp.rb: fix converting img to amp-img tags when parametes have '>' chars * dropdown_calendar.rb: jump to link made by html_anchor plugin using js * amazon.rb: catch Net::HTTPExceptions and log the reason 2018-03-29 Tada, Tadashi * release 5.0.8 2018-01-10 Tada, Tadashi * fix insecure errors by autoload in amazon.rb 2017-12-29 Tada, Tadashi * release 5.0.7 2017-12-27 Tada, Tadashi * fix insecure errors in some plugins using DiaryContainer 2017-12-22 Tada, Tadashi * change document links to GitHub Wiki 2017-09-29 Tada, Tadashi * release 5.0.6 2017-09-19 Tada, Tadashi * fix incompatibirity between bundler 1.15 and 1.16 (#646) 2017-06-29 Tada, Tadashi * release 5.0.5 2017-06-22 Tada, Tadashi * update jQuery and jQuery UI 2017-06-15 Tada, Tadashi * plugin/amp.rb: fix error on the day was empty 2017-03-29 Tada, Tadashi * release 5.0.4 2017-03-02 MATSUOKA Kohei * amp.rb, extend plugin callback (add_amp_header_proc, add_amp_body_enter_proc) 2017-02-09 TADA Tadashi * fix: ignore @css by theme location in tdiary.conf 2017-01-20 TADA Tadashi * support ruby 2.4.0 * drop ruby 2.1 2017-01-16 TADA Tadashi * insert theme location (local or online) into @theme in tdiary.conf 2017-01-04 TADA Tadashi * heroku/Gemfile.local: change some gem source to "https" instead of "github" 2016-12-29 MATSUOKA Kohei * release 5.0.3 2016-12-16 TADA Tadashi * remove misc/theme_convert 2016-12-13 MATSUOKA Kohei * amp.rb: remove script tag 2016-12-11 MATSUOKA Kohei * amp.rb, views/amp.rhtml: support amp (Accelerated Mobile Pages) 2016-11-16 TADA Tadashi * category.rb, category-legacy.rb: fix error about here documents 2016-09-29 TADA Tadashi * update some documents: add using Gemfile.local * release 5.0.2 2016-08-23 TADA Tadashi * base.css, default.css: define img.right and img.left after img.photo 2016-06-30 TADA Tadashi * skip loading octokit on production mode in Rakefile 2016-06-29 TADA Tadashi * move preview plugin from contrib * release 5.0.1 2016-05-12 MATSUOKA Kohei * plugin.rb: support asynchronous JavaScript loading * remove sprockets from release package 2016-05-09 TADA Tadashi * theme/base.css: set width of dropdown list of draft plugin 2016-04-26 TADA Tadashi * heroku/tdiary.conf: use MONGODB_URI environment variable instead of MONGOLAB_URI 2016-04-19 MATSUOKA Kohei * Dockerfile: support docker 2016-04-01 TADA Tadashi * category.rb: enable to call category_list and category_dropdown_list plugins in diary header 2016-03-29 MATSUOKA Kohei * release 5.0.0 2016-03-22 TADA Tadashi * index.rb, update.rb: set magic comment ascii-8bit to show all error messages 2016-03-16 TADA Tadashi * rename category_legacy.rb to category-legacy.rb 2016-03-10 TADA Tadashi * style/wiki.rb: untaint plugin code when syntax checking 2016-03-09 TADA Tadashi * replace category.rb plugin by contrib/category-lite.rb plugin * kill secure mode (ignore @secure variable in tdiary.conf and more) 2016-01-26 TADA Tadashi * title_tag.rb: print only diary name when diary has no subtitles 2016-01-19 TADA Tadashi * delete config.ru for Heroku (use default one) 2016-01-08 TADA Tadashi * title_tag.rb: support category-lite plugin 2016-01-05 TADA Tadashi * system_update.rb, README.md: enable deploy master branch to heroku 2016-01-05 MATSUOKA Kohei * support heroku on master branch 2015-12-31 TADA Tadashi * application.rb: fix error when @index or @update specified with URL in tdiary.conf 2015-12-29 MATSUOKA Kohei * release 4.2.1 2015-12-25 MATSUOKA Kohei * revert 61b7b6: writing dependency in gemspec, see #527 2015-12-25 TADA Tadashi * default.css: more adjust CSS for mobile devices 2015-12-08 MATSUOKA Kohei * fix #494 authentication error by omniauth and rack::session::pool 2015-12-01 MATSUOKA Kohei * enable to write TDiary::Application settings in tdiary.conf (@index, @update, @options['base_url']) 2015-11-26 MATSUOKA Kohei * move gems dependency from Gemfile to .gemspec * specify spec.files without git command * remove specs from gem 2015-09-29 SHIBATA Hiroshi * release 4.2.0 2015-06-29 MATSUOKA Kohei * release 4.1.3 * Gemfile: use rack 1.6.4 which sepatates params with ';'. see #485 2015-05-05 MATSUOKA Kohei * catch TDiary::ForceRedirect exception from 90migrate.rb at startup 2015-04-22 TADA Tadashi * add full path of lib into LOAD_PATH, fix #481 #483 2015-03-29 MATSUOKA Kohei * release 4.1.2 2015-03-15 MATSUOKA Kohei * use omniauth automatically if omniauth gem loaded * support some auth providers (twitter, facebook, google, github) 2015-02-25 MATSUOKA Kohei * support ruby-2.2 and unsupport ruby-1.9.3 2015-02-19 TADA Tadashi * enable to specify multiple twitter user in OmniAuth 2015-02-02 TADA Tadashi * Gemfile: work around about rack 1.6 not separate params with ';'. see #485 2015-01-28 TADA Tadashi * use Rack::Session::Dalli automatically if dalli gem loaded 2015-01-27 TADA Tadashi * plugin/00default.rb: fix #482 by another code: bad url of og:image 2015-01-26 TADA Tadashi * accept external JavaScript or CSS URL without scheme * plugin/theme_online.rb: support another theme site by options 2015-01-24 TADA Tadashi * plugin/comment_mail-smtp.rb: use Mail gem instead of Net::SMTP * plugin/comment_ajax.rb: set theme_url into js 2015-01-21 MATSUOKA Kohei * add add_startup_proc plugin interface * plugin/makerss.rb: create rdf on startup 2015-01-19 TADA Tadashi * plugin/amazon.rb: retry by returning error from rpaproxy 2015-01-10 MATSUOKA Kohei * diary_container.rb: add the model to get diary directoly without using CGI * Gemfile: use webrick server as default (to use other server, write in Gemfile.local) * cli.rb: add --log option to tdiary server command 2014-12-29 MATSUOKA Kohei * release 4.1.1 2014-12-27 MATSUOKA Kohei * lib/tdiary/application.rb: fix #442: call extensions setup before the core setup * lib/tdiary/application/extensions/omniauth.rb: fix error with base_dir * lib/tdiary/rack/auth/omniauth.rb: remove github authentication 2014-12-22 SHIBATA Hiroshi * lib/tdiary.rb: fixed load path of additional gems 2014-12-16 TADA Tadashi * plugin/category.rb: fix error on update running on ruby 1.9.3 2014-11-29 TADA Tadashi * release 4.1.0 2014-11-26 TADA Tadashi * misc/plugin/category.rb: support plugin storage * misc/plugin/disp_referrer.rb: unsupport nora library * misc/plugin/recent_comment3.rb: fix error on tree view mode 2014-11-10 TADA Tadashi * misc/plugin/makerss.rb: support plugin storage 2014-10-17 TADA Tadashi * implement plugin storage in IO class 2014-09-05 TADA Tadashi * style/wiki.rb: fix #437: error when 'a' element with some attr in plugin notation 2014-08-29 TADA Tadashi * release 4.0.5 2014-08-27 zunda * plugin/weather.rb: Change Japanese translation for few clouds 2014-08-12 zunda * plugin/weather.rb: Change Japanese translation for few clouds 2014-07-25 zunda * plugin/weather.rb: Add a Japanese translation to Scattered Clouds 2014-06-14 zunda * plugin/weather.rb: Add a translation for `few clouds' 2014-05-29 TADA Tadashi * release 4.0.4 2014-05-08 TADA Tadashi * fix error on image when edit mode #412 * remove mobile link discovery tag because it is obsolete. * add default OGP 2014-02-21 TADA Tadashi * add theme_online plugin #291 2013-03-20 SHIBATA Hiroshi * misc/style/gfm/gfm_style.rb: bugfix #268, #269. fixed broken rule of autolink replacements. 2013-03-13 TADA Tadashi * tdiary/server.rb: fix js not load * alert of old ruby version for end of ruby 1.8 2013-03-10 SHIBATA Hiroshi * tdiary/io/cache/redis.rb: added Redis cache store. 2013-02-10 MATSUOKA Kohei * tdiary/view.rb, js/comment_ajax.js: post comment with ajax. * tdiary/request.rb: implement TDiary::Request#xhr? 2013-02-07 MATSUOKA Kohei fixed #260: tDiary.document_root returns current directory in the CGI/FastCGI 2013-02-06 MATSUOKA Kohei fixed #250: disable Rack::Reloader except development environment 2013-02-06 TADA Tadashi fixed #259: return path under tDiary.document_root only not fullpath 2013-02-01 MATSUOKA Kohei * misc/plugin/makerss.rb: puts rss file to the public directory if the Rack environment 2013-01-30 MATSUOKA Kohei * tdiary.rb: add TDiary::document_root to return static contents directory 2013-01-29 SHIBATA Hiroshi * release 3.2.1 2013-01-22 SHIBATA Hiroshi * misc/plugin/recent_comment3.rb: directory matching condition discarded to ambiguous pattern. 2013-01-20 SHIBATA Hiroshi * misc/plugin/recent_comment3.rb: guard to overwrite empty data when exists data. 2013-01-19 SHIBATA Hiroshi * skel/show.rhtml, tdiary/base.rb, tdiary/dispatcher/update_main.rb: remove unnecessary skelton. 2013-01-18 MATSUOKA Kohei * plugin/05referer.rb: record up to 10,000 of the volatile referer 2013-01-16 MATSUOKA Kohei * tdiary/base.rb: enable plugin cache again, except blogkit * config.ru ValidRequestPath after Rack::File to return public contents 2013-01-15 MATSUOKA Kohei * tdiayr.rb, tdiary/base.rb, tdiary/dispatcher/index_main.rb, tdiary/plugin.rb: run ValidRequestPath after Rack::File to return public contents 2013-01-14 SHIBATA Hiroshi * tdiary.rb, tdiary/server.rb, tdiary/application.rb, tdiary/tasks/server.rake: moved strandalone_cgi_server to core function: experimental 2013-01-13 SHIBATA Hiroshi * misc/style/gfm/gfm_style.rb, tdiary/core_ext.rb, skel/diary.rhtml: enabled to display emoji when day mode. * misc/plugin/*/recent_trackback3.rb: remove trackback information 2013-01-13 KITAITI Makoto * misc/paas/sqale/Gemfile, doc/INSTALL-paas.md: added sqale docs. 2013-01-12 MATSUOKA Kohei * spec/core/plugin_spec.rb: add spec for TDiary::Plugin 2013-01-12 SHIBATA Hiroshi * tdiary.rb, tdiary/base.rb, tdiary/view.rb: implement to singleton logger class * tdiary/compatible.rb, tdiary/style.rb: compatible.rb is only backward or forward compatible methods. * vendor/json_pure*, vendor/rdtool*: update bundled gems. 2013-01-06 SHIBATA Hiroshi * tdiary.rb, tdiary/*: restructured TDiary* classes 2013-01-05 SHIBATA Hiroshi * tdiary.rb, tdiary/*: restructured DiaryBase class. * tdiary/diary_base.rb, tdiary/style/tdiary_style.rb, tdiary/style/wiki_style.rb, misc/style/gfm/gfm_style.rb: move common methods into DiaryBase, implement SectionBase module. * misc/style/gfm/gfm_style.rb: ignored intra emphasis. 2012-12-29 SHIBATA Hiroshi * misc/plugin/title_tag.rb: added nil guard for case of subtitle is nil 2012-12-27 TADA Tadashi * misc/standalone_cgi/bin/server: change bind address to any (0.0.0.0) and add option '-b' 2012-11-18 SHIBATA Hiroshi * .travis.yml: tweak ignore and exclude option * spec/acceptance/*: accept capybara-2.0.0 ways 2012-11-12 SHIBATA Hiroshi * misc/style/gfm/gfm_style.rb: integrate twitter-autolink. 2012-11-06 SHIBATA Hiroshi * tdiary/tasks/release.rake: integrate release task. 2012-11-03 SHIBATA Hiroshi * misc/style/gfm/gfm_style.rb: ignored to expand url strings in plugin syntax. 2012-10-29 SHIBATA Hiroshi * Release 3.2.0 2012-10-11 SHIBATA Hiroshi * .travis.yml, spec/acceptance_helper.rb: tweak RDB and memcached specs. * tdiary/io/cache/{file, memcached}.rb: added store/restore interface for plugin. 2012-10-06 SHIBATA Hiroshi * tdiary/00default.rb: support to embedded external javascripts. * misc/plugin/category_autocomplete.rb, js/category_autocomplete.js: added category_autocomplete.js, thanks for tamoot 2012-10-02 SHIBATA Hiroshi * tdiary/io/rdb.rb: support auto migration for database * misc/style/gfm/gfm_style.rb: support Emoji 2012-09-25 SHIBATA Hiroshi * spec/acceptance_helper.rb: enable running specs with rdb. 2012-09-16 SHIBATA Hiroshi * tdiary/tasks/db.rake: added task for rdb import from default. 2012-08-24 MATSUOKA Kohei * tdiary.conf.sample: set default @data_path 2012-08-19 SHIBATA Hiroshi * plugin/00default.rb: upgrade jQuery-1.8 * vendor/*: upgrade json_pure-1.7.4, rdtool-0.6.37 2012-08-06 SHIBATA Hiroshi * tdiary/rack/assets/precompile.rb: CoffeeScript auto compile in rack middleware. 2012-08-03 TADA Tadashi * plugin/calendar3.rb: fix typo of js file name #187 2012-07-29 TADA Tadashi * Release 3.1.4. 2012-07-03 hb * tdiary/rack/valid_request_path.rb: response body is empty for HEAD request. 2012-06-20 hb * tdiary/config.rb: fixed base_url_auto when script_name is empty. 2012-06-14 SHIBATA Hiroshi * tdiary/io/rdb.rb: fixed unsaved style when using RdbIO. 2012-06-12 TADA Tadashi * ja/disp_referer.rb: maintained about google image search. 2012-06-09 TADA Tadashi * title_tag.rb: fixed error on empty subtitle. 2012-05-20 MATSUOKA Kohei * tdiary/rack/valid_request_path.rb: validate PATH_INFO in rack 2012-05-18 MATSUOKA Kohei * Rakefile: add task heroku:install 2012-05-17 MATSUOKA Kohei * Rakefile: add task auth:password:create 2012-05-12 MATSUOKA Kohei * config.ru, tdiary/rack/auth/omniauth.rb: integrate omniauth for authentication 2012-04-29 TADA Tadashi * Release 3.1.3. 2012-04-25 TADA Tadashi * title_tag.rb: a little modify of title tag. 2012-04-17 TADA Tadashi * highlight.{js,rb}: set section title function back. 2012-04-17 SHIBATA Hiroshi * tdiary/io/heroku.rb: memoize cache_path for HerokuIO 2012-04-14 SHIBATA Hiroshi * vendor/{json_pure-1.6.6,rdtool-0.6.33}: update latest gem version. * tdiary/io/{default,heroku}.rb, tdiary/io/cache/*: split cache mecanism from IO files. 2012-03-28 SHIBATA Hiroshi * tdiary.rb, tdiary/io/default.rb: separate cache methods, now File cache is implerement to DefaultIO class. * tdiary/io/heroku.rb: implements to diary's cache using memcached. 2012-03-27 hb * misc/plugin/image.rb, misc/plugin/en/image.rb, js/image.js: added Drag and Drop upload field. #40 2012-03-23 SHIBATA Hiroshi * tdiary.rb, tdiary/config.rb, tdiary/io/default.rb, plugin/*.rb: move restore/store methods depending File I/O to DefaultIO. * tdiary/io/heroku.rb, spec/fixtures/tdiary.conf.heroku: added HerokuIO. support running to www.heroku.com. 2012-02-28 SHIBATA Hiroshi * tdiary.rb: handled security error when tmp directory is nothing. * misc/style/gfm/gfm_style.rb: support code highlighting with pygments. * Rakefile, spec/spec_helper.rb: added ci_reporter. 2012-02-25 SHIBATA Hiroshi * tdiary/io/base.rb: fix initialize style.path. 2012-02-23 SHIBATA Hiroshi * tdiary/io/base.rb: support multiple directories for style file. * theme/**/*.css: converted utf-8. * plugin/00default.rb, js/02edit.{js,coffee}: auto expand textarea size. 2012-02-19 SHIBATA Hiroshi * misc/style/gfm/gfm_style.rb: fix plugin syntax error in gfm_style. 2012-02-17 SHIBATA Hiroshi * tdiary/io/base.rb, tdiary/*_style.rb: restructured style file path. * misc/style/gfm/gfm_style.rb: added Github Flavored Markdown style. 2012-01-10 TADA Tadashi * amazon.rb: changed required API version to 2011-08-01. #134 2012-01-29 TADA Tadashi * Release 3.1.2. 2012-01-22 SHIBATA Hiroshi * misc/plugins/amazon.rb: more lazy loading. 2012-01-14 SHIBATA Hiroshi * misc/plugins/amazon.rb, misc/plugins/amazon/amazonimg.rb: use autoload when require REXML, because REXML loading was so heavy. 2012-01-11 TADA Tadashi * plugin/title_tag.rb: fixed over escape in title element. #127 2012-01-10 TADA Tadashi * fixed incorrect version number (2011->2012). 2012-01-08 SHIBATA Hiroshi * tdiary/plugin.rb, Rakefile: support CoffeeScript, enabled dynamic compile when running on Rack mode. 2012-01-06 TADA Tadashi * plugin/amazon.rb: show an error message when API timeouted. 2012-01-05 TADA Tadashi * filter/antispamservice.rb: discontinued using Net::HTTP.version_1_1. 2011-12-13 TADA Tadashi * plugin/image.rb: set correct image size when size parameter has under 2 items. #119 2011-11-03 TADA Tadashi * plugin/disp_referrer.rb: suppressed Encoding::CompatibilityError error. 2011-11-02 TADA Tadashi * plugin/ping.rb: discontinued using Net::HTTP.version_1_1. * plugin/weather.rb: discontinued using Net::HTTP.version_1_1. 2011-10-30 SHIBATA Hiroshi * tdiary/dispatcher/index_main.rb: bugfix http header when status is NOT_MODIFIED. 2011-10-29 TADA Tadashi * theme/conf.css: fixed invalid element: div.help-icon to span.help.icon. * Release 3.1.1. 2011-10-23 Kazuhiko * misc/plugin/amazon.rb: support more contries - China, Italy and Spain. 2011-10-18 TADA Tadashi * plugin/amazon.rb: supported AssociateTags for each country. #104 2011-10-04 Kazuhiko * tdiary/config.rb: preload more transcodes that can be used in kw.rb plugin or sending a notification email. * misc/plugin/kw.rb: use the default key if the key is missing. use Shift_JIS instead of sjis as the encoding name. load NKF library out of method definitions. 2011-09-26 Kazuhiko * update.fcgi: initial commit. * index.fcgi, misc/lib/fcgi_patch.rb: monkey patching FCGI::each_cgi so that we can accept both UTF-8 input and Shift_JIS input. 2011-09-14 SHIBATA Hiroshi * tdiary/config.rb: do not encode when string is already utf-8 encoding. 2011-09-13 Kazuhiko * tdiary/config.rb (to_native): fix a typo that may cause NoMethodError, pointed out by hsbt. 2011-09-12 Kazuhiko * tdiary/config.rb (to_native): fix a mistake in 631e228 that may cause nil return value. 2011-09-08 Kazuhiko * tdiary/lang/ja.rb, tdiary/lang/zh.rb: replace invalid or undefined characters in String#encode to avoid exceptions. 2011-09-07 Kazuhiko * tdiary/config.rb, tdiary/lang/en.rb, tdiary/lang/ja.rb, tdiary/lang/zh.rb: define to_native method in Config class instead of each language file. * tdiary/lang/ja.rb (to_native): move 'require' to the top of this file because to_native can be called in $SAFE=4 environment. * tdiary/compatible.rb: mark tainted objects as untrusted too to prevent SecurityError in Ruby 1.9, patch by Kazuhiro NISHIYAMA . 2011-09-06 Kazuhiko * tdiary.rb, update.rb: handle encoding properly in mobile mode. * tdiary/lang/ja.rb (to_native): support ASCII-8BIT and broken UTF-8 input. 2011-09-04 TADA Tadashi * plugin/00default.rb: apply plugin for subtitle when generating subtitle elements. 2011-08-28 SHIBATA Hiroshi * tdiary/compatible.rb: remove String#encode, affects json_pure gems. 2011-08-25 SHIBATA Hiroshi * re-bundle json_pure * tdiary/compatible.rb, tdiary/referer_manager.rb, tdiary.rb: check to Encoding class defined. 2011-08-19 TADA Tadashi * theme/default: fixed: deleted background image from gustav. 2011-08-17 TADA Tadashi * misc/plugin/footnote.rb: initialized variables to fix error on category page. #89 2011-08-09 TADA Tadashi * js/01conf.js: reloaded after savng when csrf_protection plugin only. #79 2011-08-05 hb * misc/plugin/image.rb, js/image.js: upload/delete image in ajax. 2011-08-01 hb * misc/plugin/image.rb: supported multiple upload. 2011-07-31 TADA Tadashi * misc/plugin/my-ex.rb: fixed error when tb-show.rb disabled. 2011-07-29 TADA Tadashi * js/00default.js: fixed over escape in makePluginTag(). * Release 3.1.0. 2011-07-28 TADA Tadashi * js/01conf.js: reloaded after savng when sp plugin only. #76 2011-07-26 TADA Tadashi * plugin/00default.rb: added js_url method lile theme_url. * misc/plugin/disp_referrer.rb: ignored encoding error (workaround). thanks arton. #74 2011-07-22 TADA Tadashi * skel/header.rb, skel/footer.rb: added div.whole-content inside body. * rename theme/default to theme/tdiary2. * added new theme default for tDiary 3.1. 2011-07-18 TADA Tadashi * plugin/00default.rb: replaced sub to lines. * js/01conf.js: fixed: lost CR/LF in textarea. 2011-07-06 TADA Tadashi * specified id attr for conf form element. 2011-07-05 TADA Tadashi * saved preferences in ajax. 2011-07-03 SHIBATA Hiroshi * merge tdiary-request. use Rack like interface when cgi mode. 2011-06-29 MATSUOKA Kohei * vendor/json_pure-1.5.3: added json_pure library to use to_json method. #58 * tdiary/compatible.rb: added String#encoding to avoid NoMethodError. 2011-06-25 TADA Tadashi * plugin/image.rb, js/image.js: using jQuery to insert image tags. #54 * plugin/image.rb: fixed encoding error on ruby 1.9. * skel/update.rhtml.zh: removed garbage tags. * js/category.js: changed cursor when hover. 2011-06-25 MATSUOKA Kohei * js/highlight.js: fixed XSS vulnerability. #59 2011-06-21 TADA Tadashi * added vendor/imagesize. * plugin/image.rb: using ImageSize class getting image type and size. #56 2011-06-20 MATSUOKA Kohei * plugin/highlight.rb, js/highlight.js: rewrited on jQuery. #38, #53 2011-06-20 TADA Tadashi * plugin/image.rb, js/image.rb: ported to jQuery. #54 2011-06-18 TADA Tadashi * plugin/00default.rb: added query string to javascripts for disable browser cache. 2011-06-16 TADA Tadashi * plugin/amazon.rb: preferences for using bit.ly. #47 * js/00default.js: set $tDiary.blogkit to false in default. #48 2011-06-13 TADA Tadashi * plugin/js/disp_referrer.rb: maintained some search engines. 2011-06-12 TADA Tadashi * js/00default.js, js/category.js: fixed: running on MSIE(8) or Firefox(4). 2011-06-11 TADA Tadashi * plugin/category.rb, js/category.js: dropdown list style on edit support. * plugin/00default.rb: sorted javascripts by file name. 2011-06-06 TADA Tadashi * avoid duplicate loading of javascript files. * plugin/category.rb, js/category.js: splitted js file and rewrited on jQuery. 2011-06-06 OGAWA KenIchi * plugin/pre_wrap.rb: fixed error about invalid selector. 2011-06-02 TADA Tadashi * replaced div elements into span for better HTML. #35 * inserted some ids into update form. 2011-05-28 SHIBATA Hiroshi * added tdiary/io, moved to DefaultIO, PStoreIO. * added core_ext.rb, extract core extension in tdiary.rb * extract IOBase class in tdiary.rb, added tdiary/io/base.rb. * partision a tdiary.rb, now tdiary/config.rb, tdiary/plugin.rb. 2011-05-20 TADA Tadashi * supported ruby 1.9 on list.rb. 2011-05-17 TADA Tadashi * changed Plugin#add_js_setting to Array because old ruby's hash is not hold order. * added description of using js. 2011-05-17 TADA Tadashi * added Plugin#enable_js and Plugin#add_js_setting method for inserting javascripts. * added $tDiary and $tDiary.plugin object into javascript. * added amazon.js for using amzn.to shoten service. Close #32. 2011-05-06 SHIBATA Hiroshi * plugin/05referer.rb, misc/plugin/a.rb: bugfix, backward compatibility. 2011-04-29 TADA Tadashi * Release 3.0.2. 2011-04-27 TADA Tadashi * recent_rss.rb: fixed security error. 2011-04-25 TADA Tadashi * deleted PingBack sending and receiving feature. 2011-04-19 TADA Tadashi * converted some en documents to HTML. 2011-04-11 SHIBATA Hiroshi * index.fcgi: workaround untaint LOAD_PATH for rubygems library path is always tainted. * README, doc/*: rewrite README, and i18n documentation moved. 2011-04-07 SHIBATA Hiroshi * index.rb, update.rb: added 'type' headed instead of 'Content-Type' when running cgi.rb 2011-04-06 SHIBATA Hiroshi * tdiary.rb: untaint external load_path. thanks tamoot. 2011-04-03 SHIBATA Hiroshi * plugin/00default.rb: bug fix for navi_user_edit, unshown prev/next day anchor. 2011-03-31 SHIBATA Hiroshi * plugin/05referer.rb, tdiary/{tdiary.rb, defaultio.rb}: bug fix for 1.8.6 compatibility. 2011-03-22 KADO Masanori * tdiary.rb, skel/diary.rhtml: add comment_leave_proc. 2011-03-21 TADA Tadashi * deleted TrackBack sending and receiving feature. 2011-03-20 SHIBATA Hiroshi * tdiary/wiki_style.rb: fixed bug, WikiDiary#add_section. 2011-03-05 SHIBATA Hiroshi * tdiary/tdiary_style.rb: fix 1.8 backward compatibility. thx tamoot. 2011-03-03 SHIBATA Hiroshi * tdiary.rb: remove old redirect action for apache ErrorDocutment. 2011-02-27 SHIBATA Hiroshi * tdiary.rb: remove ruby 1.6 backward compatibility. 2011-02-22 SHIBATA Hiroshi * tdiary/{defaultio.rb, compatible.rb}, tdiary.rb, plugin/*.rb: remove 1.8 backward compatibility. 2011-02-20 SHIBATA Hiroshi * tdiary.rb, tdiary.conf.rack: removed tdiary.conf.rack, now used tdiary.conf only. * spec/**/*_spec.rb, spec/spec_helper.rb: rewrite spec setup. 2011-02-18 KADO Masanori * plugin/00default.rb: use jQuery in all mode: Closes #8 * plugin/00default.rb: update jQuery from 1.4 to 1.5 2011-02-18 TADA Tadashi * skel/preview*: removed westing . 2011-01-30 SHIBATA Hiroshi * misc/lib/compatible.rb: move to tdiary/compatible.rb 2011-01-18 SHIBATA Hiroshi * tdiary/wiki_style.rb, test/wiki_style_test.rb: applied patch #168 2011-01-17 SHIBATA Hiroshi * Capfile, tdiary/deploy.rb: added deployment task with Capistrano 2011-01-05 TADA Tadashi * tdiary/dispatch.rb: fixed error on image.rb uploading image files. 2011-01-03 TADA Tadashi * plugin/00default.rb: generated CSRF protection key automatically. * misc/plugin/kw.rb: specified UTF-8 to searching by google. 2010-11-17 tamoot * tdiary/dispatcher.rb: deleted an over CR/LF. 2010-11-14 SHIBATA Hiroshi * misc/lib/compatible.rb: use Enumerable for String#each and String#to_a in Ruby 1.9. 2010-10-26 SHIBATA Hiroshi * tdiary/dispatcher.rb: fixed header error on commented. 2010-10-08 TADA Tadashi * require_jquery method for plugin. 2010-10-06 Kazuhiko * tdiary.rb: fixed Encoding error on illegal referer. 2010-10-05 SHIBATA Hiroshi * index.fcgi: fix error for mobile phone in Ruby 1.9.2 2010-09-21 TADA Tadashi * supported X-Frame-Options header. 2010-09-20 TADA Tadashi * Release 3.0.1. 2010-09-08 KADO Masanori * tdiary.rb: revert 500173f. and fix the error of blog-category. * index.rb: fix the error of tsukkomi from mobile phone. 2010-08-28 SHIBATA Hiroshi * Release 3.0.0 at RubyKaigi2010 2010-08-24 MATSUOKA Kohei * plugin/05referer.rb: ignore an invalid referer. (non-ASCII character) 2010-08-22 SHIBATA Hiroshi * misc/lib/compatible.rb: added String#lines, check convert to Enumerator in method_missing. * misc/plugin/category.rb: fix bug. called String#map in make_anchor. * plugin/00default.rb: fic bug. called String#collect in comment_mail_mime. 2010-08-20 TADA Tadashi * misc/plugin/makerss.rb: checked 'A little modify' when the diary is older over a month. 2010-06-15 SHIBATA Hiroshi * misc/lib/compatible.rb, spec/core/compatible_spec.rb: convert encoding first time only. thx machu. 2010-05-16 SHIBATA Hiroshi * plugin/00default.rb, plugin/{ja,en,zh}/00default.rb: added recommended filter setting. 2010-04-30 SHIBATA Hiroshi * misc/style/rd/rd_style.rb: applied patch #190, thx kumaryu. 2010-04-25 SHIBATA Hiroshi * tdiary/filter/spam.rb: revert r3619. and fix debug message. * tdiary/filter/spam.rb: added IP based DNSBL filter. 2010-04-21 TADA Tadashi * added Config#smartphone? calling CGI::smartphone?. And alias as iphone?. 2010-04-20 TADA Tadashi * added CGI#smartphone? for some SmartPhone's user agent. 2010-04-06 TADA Tadashi * theme/base.css: adjusted some styles for amazon plugin. 2010-03-30 TADA Tadashi * skel/update.rhtml*: changed element of top of div.caption to h2. * theme/base.css: added style of profile plugin. 2010-03-29 TADA Tadashi * skel/header.rhtml: added 'class="update"' into body element when update mode. 2010-03-27 TADA Tadashi * theme/base.css: added style for amazon plugin. 2010-03-26 TADA Tadashi * plugin/00default.rb: loading jQuery 1.4 via googleapi to Edit and Preference pages. * js/00default.js: added default loading js file. 2010-01-12 SHIBATA Hiroshi * doc/README.html: fixed supported ruby version. * doc/HOWTO-make-theme.html, INSTALL.html: s/GPL/GPL2 * doc/*.html, *.css: fixed old mail address. 2010-01-05 Kazuhiko * misc/lib/hikidoc.rb: sync with hikidoc rev.126. * misc/lib/compatible.rb: define CGI::ENV so as to avoid "Insecure operation `[]' at level 4" exception. * misc/lib/compatible.rb: define Encoding::CompatibilityError for ruby 1.8.x because it appears in rescue clauses. * skel/footer.rhtml: disypal RUBY_RELEASE_DATE instead of RUBY_PATCHLEVEL if RUBY_PATCH_LEVEL is missing. 2009-12-09 Kazuhiko * skel/i.header.rhtml: invoke header_proc without embedding its result. * plugin/00default.rb: fix mobile_navi according to navi_user integration. 2009-12-04 TADA Tadashi * plugin/00default.rb: fixed bug of no saved referer under new navi_user plugin. 2009-11-24 SHIBATA Hiroshi * tdiary.rb, plugin/00default.rb, plugin/{ja,en,zh}/00default.rb: change logger implementation. * tdiary.rb, plugin/00default.rb: change implemention of navi_user_day to navi_user.rb. 2009-08-26 Kazuhiko * tdiary/filter/default.rb: match on ASCII-8BIT encoding because incoming referer and/or configured non_referer can be non-UTF8 encoding. * index.rb, update.rb: call $:.unshift only if it is required, otherwise the same path is added by each request in FastCGI mode. 2009-08-17 zunda * tdiary.rb, tdiary/defaultio.rb: modified to let style raise BadStyleError 2009-08-17 Kazuhiko * misc/lib/compatible.rb (PStore::load): auto convert ASCII_8BIT pstore data (created by Ruby-1.8) to UTF-8 in Ruby-1.9. * skel/tdiary.rconf: force encoding all String in 'ASCII-8BIT' to get the same dump format on both Ruby-1.8 and Ruby-1.9. 2009-08-09 Kazuhiko * tdiary.rb (TDiary::TDiaryBase::load_plugins): reuse existing Plugin instance if possible. (TDiary::Plugin::initialize): use Object#instance_variable_set instead of Kernel.eval. 2009-08-05 Kazuhiko * tdiary.rb (TDiary::Plugin::disp_referer): add encoding flag in regexp. 2009-08-03 TADA Tadashi * release 2.3.3. 2009-07-31 Kazuhiko * tdiary.rb: dirty workaround to avoid recursive sort that causes SecurityError in @secure=true environment since http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=16081 2009-07-28 Kazuhiko * skel/footer.rhtml: display fcgi information in footer. 2009-07-21 Kazuhiko * index.fcgi: initial commit based on the code by Akinori Musha and moriq. 2009-06-21 SHIBATA Hiroshi * tdiary.rb: uses FileUtils::mkdir_p when create log directory. 2009-06-20 SHIBATA Hiroshi * tdiary.conf.sample, tdiary.conf.beginner: added some referer engine. 2009-05-28 SHIBATA Hiroshi * plugin/00default.rb: revert AutoPagerize support when day mode. 2009-05-21 SHIBATA Hiroshi * plugin/00default.rb, skel/diary.rhtml: support AutoPagerize. 2009-05-14 SHIBATA Hiroshi * tdiary.conf.sample: delete obsolete referer. 2009-05-08 TADA Tadashi * release 2.3.2. 2009-05-02 TADA Tadashi * tdiary.rb: fixed bug in Comment#shorten. 2009-05-01 TADA Tadashi * plugin/05referer.rb: fixed Encoding::CompatibilityError in referer_load. thanks valda. 2009-04-28 TADA Tadashi * plugin/05referer.rb: opened reading mode of *.tdr file to 'rb'. 2009-04-27 SHIBATA Hiroshi * tdiary/lang/ja.rb: added encoding flag from a regexp. (revert r3424) 2009-04-26 SHIBATA Hiroshi * tdiary/defaultio.rb: applied patch #112. thx kakutani. 2009-04-26 TADA Tadashi * tdiary/lang/ja.rb: removed encoding flag from a regexp. * skel/plugin_error.rhtml: added stack trace. * plugin/05referer.rb: force encoded to ASCII-8BIT in load_referer. * misc/lib/compatible.rb: added dummy String#encode on ruby 1.8. * plugin/00default.rb: added layout support plugins : brr and brl. 2009-04-10 SHIBATA Hiroshi * skel/update.rhtml: applied patch #78, thx kakutani. 2009-03-30 SHIBATA Hiroshi * misc/migrate.rb: replace defout to stdout. defout is obsolete. 2009-03-21 TADA Tadashi * plugin/ja/00default.rb: fixed typo. 2009-03-10 TADA Tadashi * plugin/00default: moved mail encoding point after all text builded. * skel/mail.rtxt.*: changed encoding to UTF-8. 2009-02-28 TADA Tadashi * tdiary/defaultio.rb: sorted by date before saving. 2009-02-26 TADA Tadashi * tdiary.rb, misc/lib/compatible.rb: fixed warning on ruby 1.9.1. 2009-02-24 TADA Tadashi * enable migration on ruby 1.9.1. * forced reloading after migration. 2009-02-12 TADA Tadashi * tdiary.rb, compatible.rb: added suport code against $SAFE BUG of ruby 1.9.1. This is a temporally patch. 2009-01-29 TADA Tadashi * tdiary.rb: enabled 'require' in plugins on ruby 1.9.1 but it dosen't works well yet. 2009-01-20 TADA Tadashi * index.rb, update.rb: caught NameError on Encoding::default_external=. 2009-01-18 SHIBATA Hiroshi * tdiary.conf.beginner: fix some plugin of header and footer. 2009-01-15 SHIBATA Hiroshi * add "mixi-mobile-converter" to mobile user agent. 2009-01-08 SHIBATA Hiroshi * deleted encoding parameter in File::open. 2009-01-07 SHIBATA Hiroshi * plugin/00default.rb: added to_native for cookie name. 2009-01-07 TADA Tadashi * tdiary.rb: supported secure mode in load_cgi_conf, but dose not works on secure mode... 2009-01-04 TADA Tadashi * supported ruby 1.9.1 more, but it dose not work well. 2008-12-16 TADA Tadashi * index.rb, update.rb: String#size -> String#bytesize. * plugin/ja/05referer.rb: escaped backslash more. 2008-12-07 TADA Tadashi * tdiary/filter/default.rb, tdiary/defaultio.rb, tdiary.rb, plugin/00default.rb: added encoding to File::open's parameter. But it dosen't work yet. 2008-12-07 SHIBATA Hiroshi * misc/lib/compatible.rb: add compatible.rb 2008-12-07 SHIBATA Hiroshi * **/*.rb: insert magic comment. 2008-11-17 SHIBATA Hiroshi * index.rb, update.rb: replaced $defout to $stdout. ($defout is obsolete in ruby1.8) 2008-10-31 SHIBATA Hiroshi * plugin/00default.rb: escaped comment_form_text. thx fudan. 2008-10-26 SHIBATA Hiroshi * plugin/90migrate.rb: fixed error when a.dat is not exist. 2008-10-25 TADA Tadashi * tdiary.conf.beginner: 'update.cgi' -> 'update.rb' 2008-10-19 TADA Tadashi * release 2.3.1. 2008-10-18 TADA Tadashi * plugin/90migrate.rb: supported a.dat (a.rb plugin's dictionary). 2008-09-04 TADA Tadashi * tdiary.rb: fixed #119: Insecure error in CGI::https? when runnning on secure mode. 2008-08-18 TADA Tadashi * misc/lib/hikidoc.rb: replaced HikiDoc library by 0.0.2. 2008-08-08 Kazuhiko * plugin/90migrate.rb: fix typos to convert category cache correctly. set @conf.tdiary_version just after converting tdiary.conf to prevent converting twice. 2008-08-05 TADA Tadashi * defaultio.rb: detected error of no style file. * plugin/00default.rb: fixed #104, error on no existent day. 2008-08-01 TADA Tadashi * tdiary.rb, 00default.rb: set @date starting with plugin running. 2008-07-18 TADA Tadashi * index.rb, tdiary.rb, skel/search.rhtml: added site search template. 2008-07-14 SHIBATA Hiroshi * plugin/60sf.rb: fix #114. thx KAKUTANI Shintaro. 2008-07-11 SHIBATA Hiroshi * plugin/50sp.rb: fix #113. thx KAKUTANI Shintaro. 2008-07-10 SHIBATA Hiroshi * plugin/50sp.rb, 60sf.rb: fix #111. thx KAKUTANI Shintaro. 2008-07-08 SHIBATA Hiroshi * tdiary.rb, plugin/00default.rb: use device-width accessed by iPhone/iPod touch. 2008-07-05 SHIBATA Hiroshi * tdiary.rb, index.rb: raise 404 error when bot access to no existent diary. * tdiary.rb, plugin/00default.rb: support iPhone/iPod touch. 2008-07-05 KURODA Hiraku * fixed error when volatile.tdr is not exist. 2008-07-02 SHIBATA Hiroshi * merge from Test_SelectFilter. 2008-07-01 SHIBATA Hiroshi * misc/filter/plugin/antispamservice.rb: fix key verify condition. * misc/filter/antispam.rb, misc/filter/plugin/antispam.rb, misc/filter/plugin/*/antispam.rb: rename antispam to antispamservice. 2008-06-25 SHIBATA Hiroshi * plugin/00default.rb: escape double quotation in title attribute of subtitle anchor. 2008-06-24 SHIBATA Hiroshi * plugin/00default.rb: added title attribute in subtitle anchor. 2008-06-23 TADA Tadashi * skel/footer.rhtml: using rescue on display to RUBY_PATCHLEVEL. 2008-06-23 SHIBATA Hiroshi * tdiary.rb: add 'Semulator', 'Vemulator', 'J-EMULATOR' and 'emobile' to mobile user agent. * skel/footer.rhtml: display RUBY_PATCHLEVEL in footer. 2008-06-15 SHIBATA Hiroshi * misc/filter/antispam.rb, misc/filter/plugin/antispam.rb, misc/filter/plugin/*/antispam.rb: delete antispam.enable option. 2008-06-15 SHIBATA Hiroshi * plugin/10spamfilter.rb, plugin/*/10spamfilter.rb, tdiary.rb: integrate logger and spamfilter debug log. 2008-06-15 SHIBATA Hiroshi * tdiary.rb: changed logger path option. 2008-06-09 TADA Tadashi * self converting to UTF-8. thanks kazuhiko. * tdiary/lang/*.rb: added migrate_to_utf8 method. * tdiary/defaultio.rb: added migration code to utf-8. * skel/tdiary.rconf added tdiary_veersion. * plugin/90migrate.rb: added. 2008-06-02 SHIBATA Hiroshi * misc/migrate.rb: fix undefined class/module convert in PStore. thx KURODA Hiraku. 2008-05-31 SHIBATA Hiroshi * tdiary.rb: added logger. 2008-05-24 SHIBATA Hiroshi * plugin/60sf.rb: fix bug, plugin file unreadable error. 2008-05-22 SHIBATA Hiroshi * tdiary.rb, plugin/60sf.rb, plugin/*/60sf.rb: applied patch #58. 2008-05-08 SHIBATA Hiroshi * skel/diary.rhtml, skel/latest.rhtml, skel/month.rhtml: fixed #88. 2008-05-08 SHIBATA Hiroshi * tdiary.conf.beginner, tdiary.conf.sample, skel/preview.rhtml, skel/update.rhtml: fixed #81. 2008-04-24 TADA Tadashi * plugin/10spamfilter.rb: fixed #84. 2008-04-15 TADA Tadashi * tdiary_style.rb: deleted useless counter variable. 2008-04-15 Yamaguchi * tdiary.rb: fixed #80. 2008-03-31 TADA Tadashi * tdiary_style.rb: fixed #74. 2008-03-22 SHIBATA Hiroshi * doc/*.html: fix document charset, change euc-jp to utf-8. 2008-03-14 Kazuhiko * plugin/en/00default.rb, plugin/ja/00default.rb, plugin/zh/00default.rb: fix invalid HTML. * plugin/ja/00default.db: fix invalid HTML (reported by hb). 2008-03-11 SHIBATA Hiroshi * dot.htaccess: add 'AddType application/xml' 2008-03-02 TADA Tadashi * marged with Test_UTF8 branch, and started development of series 2.3. 2008-02-29 TADA Tadashi * release 2.2.1. 2008-02-29 YAA * plugin/05referer.rb: fixed to display volatile referers in latest edit page. 2008-02-27 TADA Tadashi * misc/style/etdiary: catch up current specification of the style. * skel/preview.rhtml*: supported label element for hide diary checkbox. 2008-02-24 TADA Tadashi * plugin/05referer.rb: fixed no saving referer on day mode. 2008-02-23 TADA Tadashi * plugin/05referer.rb: fixed #49. 2008-02-14 ds14050 * tdiary/wiki_style.rb: fixed eval error in valid_plugin_syntax?. 2008-02-13 TADA Tadashi * misc/lib/hikidoc.rb: updated to trunk and fix about InterWikiName. 2008-02-10 TADA Tadashi * tdiary/wiki_style.rb: removed warning by HikiDoc#to_html. 2008-02-08 TADA Tadashi * skel/diary.rhtml: hide div#comment-form-section without day mode. 2008-02-04 SHIBATA Hiroshi * tdiary.rb,plugin/00default.rb,plugin/10spamfilter.rb, plugin/en/10spamfilter.rb,plugin/ja/10spamfilter.rb, plugin/zh/10spamfilter.rb,tdiary/filter/spam.rb: [EXPERIMENTAL] remove option for spamfilter.hide_comment. Javascript is used to display all TSUKKOMI from into setting days before. 2008-02-03 TADA Tadashi * skel/diary.rhtml, plugin/00default.rb: [EXPERIMENTAL] add TSUKKOMI form by Javascript in the hidden comment form condition. 2008-01-19 TADA Tadashi * misc/lib/hikidoc.rb: updated to 0.0.2. * tdiary/wiki_style.rb: added :use_wiki_name and :allow_bracket_inline_image option to false to HikiDoc. thanks to ds14050. 2008-01-15 TADA Tadashi * plugin/05referer.rb: fixed #11: error on update with no referer. 2008-01-11 SHIBATA Hiroshi * plugin/00default.rb, plugin/10spamfilter.rb, plugin/*/10spamfilter.rb: add option for hide comment-form before days considered to be spam. 2008-01-11 TADA Tadashi * plugin/00default.rb: hide comment form when accessed by bot. 2008-01-08 TADA Tadashi * plugin/05referer.rb: saving recent a few days into volatile. 2008-01-05 TADA Tadashi * plugin/00default.rb: hide comment form when over comments per day on mobile mode. 2008-01-03 TADA Tadashi * plugin/00default.rb: unescaped category name because over escape on Wiki style. 2007-12-16 TADA Tadashi * release 2.2.0. 2007-10-31 TADA Tadashi * skel/conf.rhtml: inserted submit button to page top. 2007-10-07 TADA Tadashi * plugin/00default.rb: ACCESSKEY changed in mobile mode. * plugin/00default.rb: replaced Update link to Edit in mobile navi menu. 2007-08-12 TADA Tadashi * plugin/00default.rb, plugin/10spamfilter.rb: support change comment description in preference page of spam filter. thanks for hsbt. 2007-08-04 TADA Tadashi * tdiary.rb, plugin/00default.rb: specify base_url in preference page. 2007-07-17 TADA Tadashi * 00default.rb: add 'rel="nofollow"' attribute to add/edit navigation. 2007-07-14 Kazuhiko * tdiary/filter/spam.rb: ignore invalid regular expressions. 2007-06-30 TADA Tadashi * tdiary.rb: set @date to newest visible date in latest mode. * 00default.rb: skip hidden diary for mobile navigation in latest mode. 2007-06-05 TADA Tadashi * tdiary.conf.beginner: add spam filter conditions. 2007-05-10 TADA Tadashi * tdiary.rb, tdiary.conf.*: add/delete some bots. 2007-05-05 TADA Tadashi * tdiary.rb: TrackBacks save the date of received to spam log. * theme/base.css: add 'span.message'. 2007-05-03 TADA Tadashi * tdiary.conf.beginner: update spam filter conditions. * doc/INSTALL.html: add about tdiary.conf.beginner. * theme/base.css: add style for footnote.rb, my-sequel.rb and category_to_tag.rb plugins. 2007-04-30 TADA Tadashi * skel/update.rhtml*, plugin/*/00default.rb; add label elements in update and preferences form. 2007-04-29 TADA Tadashi * skel/i.category.rb, plugin/00default.rb: category support mobile mode more. * plugin/05referer.rb: add rel="nofollow" into anchors. 2007-04-22 TADA Tadashi * add skel/i.category.rb for category page on mobile mode. 2007-04-10 TADA Tadashi * tdiary/wiki_style.rb: marge new text without subtitle into previous section. 2007-03-28 hajime miyauchi * style/rd/rd_style.rb: section_enter/leave_proc into mobile mode. 2007-03-28 MIYASAKA Masaru * 00default.rb: fix counting @prev_day and @next_day error in calc_links. 2007-03-11 TADA Tadashi * tdiary.rb: 'h' replace to 'CGI::escapeHTML' in TDiaryTrackBackError. thanks to MIYASAKA Masaru. 2007-03-11 MIYASAKA Masaru * tdiary.rb: CGI::request_uri support IIS and some other httpds. 2007-03-06 TADA Tadashi * hikidoc.rb was moved from 'tdiary' to 'misc/lib'. 2007-02-27 TADA Tadashi * theme/base.css: add more detail styles for amazon plugin. 2007-02-24 SHIBATA Hiroshi * plugin/{ja,en,zh}/10spamfilter.rb: fix bug resolv_check_mode setting. 2007-02-22 TADA Tadashi * tdiary.conf.beginner: add some spam and referer data. * filter/spam.rb: spam when referer has a fragment. * rename linkcheck.rb to spamlinkcheck.rb in filter. * plugin/10spamfilter.rb, filter/spamlinkcheck.rb: add options of TrackBack linkcheck. * plugin/00default.rb: add comment_form_mobile_mail_field method. 2007-02-20 TADA Tadashi * tdiary.rb: raise error when TrackBack has been filtered. * add new filter linkcheck.rb. 2007-02-19 TADA Tadashi * theme/base.css: add about edit-today plugin. 2007-02-18 TADA Tadashi * plugin/05referer.rb: move code of checking DefaultIO. 2007-02-10 TADA Tadashi * tdiary.rb: add remove_tag method into Plugin. 2007-02-07 TADA Tadashi * tdiary.rb: rewind about proxy. * tdiary.conf.*: add about @options['proxy']. * doc/HOWTO-use-plugin.html: add about @options['proxy'] * tdiary/wiki_style.rb: escape single quote in expand parameters of plugins. 2007-02-06 TADA Tadashi * tdiary.rb: @options['proxy'] set to ENV['HTTP_PROXY'] in Plugin. * plugin/05referer.rb: DefaultIO detective code change 'class' to 'String'. 2007-02-06 zunda * tdiary.rb: reverting the local change. Sorry. 2007-02-06 zunda * tdiary.rb: stop checking tsukkomi once it has been made invisible by a filter 2007-01-31 TADA Tadashi * skel/mail.rtxt*: add TSUKKOMI display status, 'shown' or 'hidden'. 2007-01-30 TADA Tadashi * filter/spamakismet.rb: force hide TSUKKOMIs. Because Akismet judge Japanese TSUKKOMI to spam sometime. 2007-01-29 TADA Tadashi * filter/spamakismet.rb: add spam filter using Akismet . 2007-01-26 TADA Tadashi * filter/spam.rb: split RBL list by '\n' -> '[\r\n]+'. 2007-01-26 SHIBATA Hiroshi * filer/spam.rb,plugin/10spamfilter.rb: fix spamfilter.max_rate float to interger. 2007-01-25 zunda * skel/preview.html*: removed gsub(/ /, ' ') from the view of plugin error, as the string is espaced more completly with h() 2007-01-26 TADA Tadashi * tdiary.rb, filter/spam.rb, plugin/spamfilter.rb: move debug method into Filter class. And rename options 'spamfilter.debug_*' to 'filter.debug_*'. And split debug mode to 3 state: DEBUG_NONE, DEBUG_SPAM and DEBUG_FULL. * skel/i.update.rhtml*, plugin/00default.rb: enlarge TEXTAREA size. 2007-01-22 TADA Tadashi * tdiary.rb: add misc/lib into default search path of ruby library. 2007-01-18 TADA Tadashi * plugin/{ja,en,zh}/00default.rb: add to_utf8 method. 2007-01-17 SHIBATA Hiroshi * plugin/00default.rb: add name attribute for comment-form. 2007-01-17 TADA Tadashi * tdiary.rb: support TrackBack spec 1.2. * tdiary/lang/*.rb: to_native optional support source charset. 2007-01-09 zunda * plugin/00default.rb: escaped theme_url, nyear_diary_title, and comment_submit_label 2007-01-10 Kazuhiko * plugin/zh/00default.rb: remove parentheses warnings. 2007-01-09 zunda * tdiary.rb: modified TDiaryForm so that, when appending a diary, default title is set if there is already a diary for the same date. 2007-01-09 Kazuhiko * plugin/00default.rb: remove parentheses warnings. 2007-01-07 zunda * plugin/00default.rb: escaped arguments to navi_item 2007-01-07 zunda * plugin/en/00default.rb: fixed typo: s/@.update/@update/ 2007-01-08 TADA Tadashi * index.rb: support ETag and If-None-Match header, and delete cache control from GET response. 2007-01-07 zunda * skel/plugin_error.rb: modified to show error message in

2007-01-06 TADA Tadashi 
	* apply HTML escape when generate HTML in skeltons or plugins.

2006-12-28 TADA Tadashi 
	* tdiary/filter/spam.rb: fix error on logging when no 'date' parameter (again).

2006-12-27 TADA Tadashi 
	* tdiary/filter/spam.rb: fix error on logging when no 'date' parameter.

2006-12-20 zunda 
	* tdiary/filter/spam.rb: add date of rejected tsukkomi to debug log

2006-12-10 TADA Tadashi 
	* skel/conf.rhtml, skel/i.conf.rhtml: security fix: escape @key value.

2006-12-05 zunda 
	* index.rb, update.rb: escape HTML for error page.

2006-12-04 HASHIMOTO Keisuke 
	* plugin/00default.rb: change 'theme' to '#{theme}': position of help icon.

2006-11-28 TADA Tadashi 
	* tdiary.rb: fix error when no 'conf' parameter in preferences page.

2006-11-26 TADA Tadashi 
	* tdiary.rb, skel/conf.rhtml: security fix: escape HTML for conf parameter
	in update.rb.

2006-11-15  Tanaka Akira 
	* tdiary/wiki_style.rb: check plugin syntax in $SAFE=4.

2006-11-13  Kazuhiko  
	* tdiary/wiki_style.rb: rescue SecurityError.
	* tdiary/hikidoc.rb: sync with hikidoc rev.43.
	  use Syntax library in multi-pre if possible

2006-11-11  Tanaka Akira 
	* tdiary/wiki_style.rb: support here document ends without CR/LF in plugin.

2006-11-10 TADA Tadashi 
	* style/wiki_style.rb: fix bug when plugin specified in subtitle.

2006-11-09 TADA Tadashi 
	* tdiary.rb: add 'SoftBank' to mobile user agent.

2006-11-06  Tanaka Akira 
	* tdiary/hikidoc.rb, tdiary/wiki_style.rb: support here document in wiki
	style plugin syntax.

2006-09-13 Shun-ichi TAHARA  
	* style/etdiary/etdiary_style.rb: fix bug for mobile mode.

2006-09-13 Masahiro Sakai  
	* style/rd/rd_style.rb: unescapeHTML for parameters of plugins.

2006-09-05 TADA Tadashi 
	* skel/i.*.rhtml: add navigation link to bottom of pages.

2006-08-16  Kazuhiko  
	* tdiary/wiki_style.rb (append): revise detection of sections.

2006-08-09  Kazuhiko  
	* tdiary/wiki_style.rb: revise to output correct HTML with the
	makerss.rb plugin.

2006-08-05  Kazuhiko  
	* tdiary/hikidoc.rb: sync with hikidoc rev.38.
	  support nested modifier (reported by MoonWolf)
	  support relative inline URL and fix parse_table

2006-07-23 TADA Tadashi 
	* skel/mail.rtxt: ENV['REMOTE_ADDR'] -> @cgi.remote_addr, and move it to
	bottom of the mail body.

2006-07-21 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb: fix namespace ResolvError.

2006-07-21  Kazuhiko  
	* skel/mail.rtxt: output ENV['REMOTE_ADDR'].
	* tdiary/filter/default.rb: untaint referer file names for mod_ruby.

2006-07-19 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb: add timeout to black_domain.

2006-07-19 TADA Tadashi 
	* tdiary/filter/spam.rb: recognize URI only http, https, ftp and mailto.
	* tdiary/filter/spam.rb: max_rate means percentage.

2006-07-10 TADA Tadashi 
	* plugin/ja/10spamfilter.rb: modify messages of preference page more.
	* theme/conf.css: hide div.footer, and enlarge submit button.
	* skel/conf.rhtml: add some classes.

2006-07-08 TADA Tadashi 
	* tdiary/filter/default.rb: TSUKKOMI filtered by 'POST' command exactly.

2006-07-05 TADA Tadashi 
	* misc/style/wiki: fix bug and add notice about obsolete to README.
	thanks Norihiro Hattori .
	* tdiary/defaultio.rb: fix Errno::EACCES error when convert referer to new
	formats on Windows.
	* tdiary/filter/default.rb: check POST method correctly.

2006-07-05 TADA Tadashi 
	* tdiary/defaultio.rb: close file before delete empty diary file.

2006-07-04 TADA Tadashi 
	* add 'tdiary.conf.beginner' for configuration file for beginner.
	* theme/default: move sidebar to rightside, and support beginner conf.

2006-06-26 TADA Tadashi 
	* add help button to each preferences.
	* plugin/ja/10spamfilter.rb: change some words.

2006-06-26 SHIBATA Hiroshi 
	* plugin/10spamfilter.rb: fix bug about spamfilter.date_limit. thanks OGAWA KenIchi.

2006-05-28 TADA Tadashi 
	* index.rb, update.rb: return status 500 on error when "MSIE" also.

2006-05-26 TADA Tadashi 
	* index.rb, update.rb: return status 500 on error. thanks Masahiro Sakai.

2006-05-24  Kazuhiko  
	* misc/style/etdiary/etdiary_style.rb: remove debug code.

2006-05-13 TADA Tadashi 
	* plugin/50sp.rb: add tDiary path before 'misc/plugin' in sp.path. thanks
	KURODA Hiraku.
	* tdiary.rb: fix bug about counting TrackBack. thanks Masahiro YOSHIZAWA.

2006-04-15 TADA Tadashi 
	* release 2.1.4 at dotBAR.

2006-03-23 TADA Tadashi 
	* plugin/00default.rb: delete white spaces in anchor of date.
	thanks cherry.usacho.jp.

2006-03-21 FUDAN 
	* tdiary.conf: add "WILLCOM" to mobile agent.

2006-03-19 TADA Tadashi 
	* skel/show.rhtml, skel/i.show.rhtml: delete contents because these are
	dummy. thanks ZnZ.

2006-03-18 TADA Tadashi 
	* remove a limit of TSUKKOMI max (more).
	* plugin/00default.rb: add Mobile Link Discovery to HTML header.

2006-03-17 TADA Tadashi 
	* remove a limit of TSUKKOMI max.
	* move TSUKKOMI form from skel to plugin.

2006-02-10 TADA Tadashi 
	* tdiary/default_io.rb: revive safety global lock.
	* plugin/05referer.rb: change labels.

2006-02-06 TADA Tadashi 
	* revive @referer_day_only option but reverse default value.

2006-02-04 TADA Tadashi 
	* 01referer.rb: check existence of @referer_volatile in
	referer_of_today_long.
	* 01referer.rb: delete implement of referer_of_today_short.
	* theme/base.css: add p.message.

2006-02-03 TADA Tadashi 
	* large change about referer: daily management, volatile link, etc.
	* default_io.rb: ignore error when *.tdc was empty.

2006-01-02 TADA Tadashi 
	* tdiary/defaultio.rb: ignore Errno::NOENT when delete empty file.

2005-12-09  Kazuhiko  
	* misc/convert2.rb: revise for current tdiary.rb.

2005-10-23 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb, plugin/10spamfilter.rb, plugin/*/10spamfilter.rb:
	  add safe domain list at referer check.

2005-10-22 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb: change uri regexp pattern in DNSBL filter.

2005-10-22 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb: add debug message and retry process in DNSBL filter.

2005-10-21 TADA Tadashi 
	* tdiary/wiki_style.rb: fix enbugged on 2.1.3.20051020.

2005-10-21 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb, plugin/10spamfilter.rb, plugin/*/10spamfilter.rb:
	  remove IP Blacklist filter. add two services to Domain Blacklist initialization.

2005-10-20 SHIBATA Hiroshi 
	* tdiary/filter/spam.rb, plugin/10spamfilter.rb, plugin/*/10spamfilter.rb: add DNSBL filter.

2005-10-20 TADA Tadashi 
	* tdiary/wiki_style.rb: enable specify "{{'

'}}" into text. 2005-10-16 TADA Tadashi * doc/HOWTO-make-plugin.html: add about section_enter/leave_proc. 2005-10-15 Kazuhiko * tdiary/wiki_style.rb (to_html): support multi-line plugins. 2005-10-12 TADA Tadashi * tdiary.rb, *_style.rb, theme/base.css: add section_enter/leave_proc. 2005-10-10 TADA Tadashi * plugin/00default.rb: my plugin: fix bug when @index was full path. 2005-10-06 TADA Tadashi * tdiary/hikidoc.rb, tdiary/wiki_style.rb: support relative inline URL. This is a temporally fix. 2005-10-02 Kazuhiko * tdiary/hikidoc.rb: sync with hikidoc rev.33. revise escapes in parse_link allow empty descriptions in definition lists * tdiary/wiki_style.rb (to_html): replace links to my/kw plugins. 2005-09-29 TADA Tadashi * release 2.1.3. 2005-09-27 Kazuhiko * tdiary/hikidoc.rb: sync with hikidoc rev.29. bugfix in parse_plugin. revise URI_RE. 2005-09-26 TADA Tadashi * tdiary.rb: remove index parameter from Plugin#subtitle_proc. * style/*_style.rb: revise subtitle_proc. 2005-09-26 Kazuhiko * tdiary/hikidoc.rb: sync with hikidoc rev.27. revise parse_plugin. 2005-09-25 ds14050 at vvvvvv.sakura.ne.jp * tdiary/wiki_style.rb: enable @options['kw.show_inter']. 2005-09-22 Kazuhiko * tdiary/wiki_style.rb (do_html4): support diaries without subtitles. 2005-09-18 zunda * plugin/*/10spamfilter.rb: fixed the form always showing comments will be discarded 2005-09-17 Kazuhiko * tdiary/hikidoc.rb: sync with hikidoc rev.25. minimum match in parse_modifier. revise parse_list. move parse_comment next to parse_pre. 2005-09-17 TADA Tadashi * tdiary/wiki_style.rb: unescape target URI in link format. 2005-09-16 TADA Tadashi * plugin/00default.rb: prev/next navigation on edit mode. * tdiary/wiki_style.rb: unescape target URI to own diary. * tdiary.rb, skel/conf.rhtml, theme/conf.css: set inversion color to current preference item in sidebar. 2005-09-12 TADA Tadashi * tdiary/filter/spam.rb: fix debug message in referer_filter. 2005-09-09 TADA Tadashi * plugin/00default.rb: insert thumbnail of selected theme. 2005-09-08 TADA Tadashi * theme/conf.css: a little change about design of list. * tdiary.conf, plugin/00default.rb, skel/tdiary.rconf: add @conf.banner and update genre. 2005-09-07 TADA Tadashi * plugin/*.rb: a little adjustment design in English. * plugin/00default.rb: not generate link for absent month. 2005-09-06 YAMAGUCHI Seiji * tdiary/default.rb: safety lock for storing comments and referers. 2005-09-05 Kazuhiko * tdiary/wiki_style.rb: add a new wiki style using HikiDoc. * misc/style/wiki/wiki_parser.rb: remove. * misc/style/wiki/wiki_style.rb: remove. 2005-08-30 TADA Tadashi * wiki_style.rb: fix: duplicated anchor in mobile mode. 2005-08-29 TADA Tadashi * rd_style.rb, etdiary_style_rb, emptdiary_style.rb: support subtitle_proc. 2005-08-28 TADA Tadashi * tdiary/tdiary_style.rb: fix bug: error when specify plugin in subtitle. * wiki_style.rb: fix bug: subtitle_proc failed when some inline elements in subtitle. * plugin/00default.rb: disable nyear link when mobile mode. 2005-08-26 TADA Tadashi * tdiary.rb: add title_proc and subtitle_proc to Plugin. * plugin/00default.rb: add title_of_today and nyear_link. * tdiary_style.rb, wiki_style.rb: support subtitle_proc. 2005-08-25 TADA Tadashi * tdiary.rb and etc: add genre parameter to Plugin#add_conf_proc. 2005-08-24 TADA Tadashi * (testing) change preferences page design. 2005-08-15 TADA Tadashi * theme/base.css: add calendar2.rb plugin's default image settings. 2005-08-15 akira yamada * filter/spam.rb, plugin/10spamfilter.rb: add dispose mode, more check mail address and date limitation. 2005-08-10 Kazuhiko * plugin/00default.rb (my): use absolute URLs. 2005-08-10 zunda * tdiary/lang/ja.rb: use NKF to convert to charset when NKF::UTF8 defined. 2005-08-08 TADA Tadashi * plugin/00default.rb: TSUKKOMI mail plugin: add new option send mail when filter hide TSUKKOMI. 2005-08-07 akira yamada * filter/spam.rb: fix bug abut @max_uris checking. * filter/spam.rb: add checking TLD. 2005-07-27 TADA Tadashi * plugin/00default.rb, tdiary/defaultio.rb, tdiary/pstoreio.rb, tdiary/tdiary_style.rb, tdiary/filter/default.rb, tdiary/lang/en.rb, tdiary/lang/ja.rb, tdiary/lang/zh.rb, theme/base.css: add license. * add plugin/10spamfilter.rb and rename 01sp.rb to 50sp.rb. 2005-07-21 zunda * tdiary/defaultio.rb DefaultIO#restore(): move rescue clause later: IO#read in ruby-1.8.0 returns not "" but nil when reading over EOF 2005-07-21 TADA Tadashi * doc/HOWTO-make-plugin.html: correct charset ISO-2022-JP to EUC-JP. 2005-07-20 TADA Tadashi * release 2.1.2. 2005-07-19 Yutaka OIWA * doc/HOWTO-make-plugin.html: add about against CSRF attack. 2005-07-07 Yutaka OIWA * tdiary.rb, 00default.rb, skel/*.rhtml, tdiary.conf.sample: against CSRF attack. 2005-06-22 Kazuhiko * tdiary.rb (apply_plugin): ignore exceptions. 2005-06-19 TADA Tadashi * tdiary.rb: fix wrong version number. 2005-06-13 TADA Tadashi * skel/diary.rhtml: TSUKKOMI 'Before...' links to '#c00'. thanks Kazuhiro NISHIYAMA * README.html: s/GPL/GPL2/g * theme/base.css: add some sidebar items. 2005-06-13 hahahaha * index.rb: support 'n days before/after' mode when using ErrorDocument/Action. 2005-06-09 TADA Tadashi * release 2.1.1. 2005-06-07 TADA Tadashi * doc/README.html, doc/INSTALL.html: separate INSTALL from README. 2005-06-06 TADA Tadashi * plugin/ja/00default.rb: change words in navi_next/prev_ndays. 2005-06-05 TADA Tadashi * plugin/00default.rb: hide 'n days' navigation and referer accessed by bots. 2005-06-04 TADA Tadashi * tdiary.conf.sample: add <%=navi%> in footer. * plugin/00default.rb: separate navi_user_* methods from navi_user method. * plugin/00default.rb: "prev/next month" navigation in month mode. 2005-06-03 TADA Tadashi * plugin/00default.rb, misc/style/wiki/wiki_style.rb: my plugin support 'n days before/after' mode. * misc/style/rd/rd_style.rb: my plugin support 'n days before/after' mode. * tdiary.rb: set limit 30 days on 'n days before/after' mode. * plugin/00default.rb: anchor plugin support 'n days before/after' mode. 2005-06-02 TADA Tadashi * tdiary.rb, plugin/00default.rb: "N days before/after" navigation button [EXPERIMENTAL] 2005-06-01 TADA Tadashi * tdiary.rb, index.rb: N days mode [EXPERIMENTAL] 2005-05-29 KURODA Hiraku * escape quote in TSUKKOMI. 2005-05-18 Kazuhiko * tdiary/defaultio.rb: support CRLF. 2005-05-18 TADA Tadashi * tdiary.rb: fix typo by supporting ruby 1.9 HEAD. * doc/HOWTO-make-io.rd: fix about IO#transaction block parameter. 2005-05-16 Kazuhiko * tdiary.rb: support ruby 1.9 HEAD. 2005-05-15 Kazuhiko * tdiary.rb: support ruby 1.9 HEAD. * tdiary/defaultio.rb: close open file only in 'ensure'. 2005-05-05 TADA Tadashi * plugin/{ja,en.zh}/00default.rb: fix wrong to . 2005-04-21 Kazuhiko * tdiary.rb: invoke update_proc in showcomment mode. 2005-04-08 TADA Tadashi * tdiary.rb, plugin/00default.rb, misc/theme_convert/theme_convert.rb: remove using ERbLight. (only support ruby 1.8 or later.) * erb/*: delete. * skel/conf.rhtml, plugin/00default.rb: fix theme to 'default' in configuration mode. 2005-04-06 TADA Tadashi * tdiary/defailtio.rb: support ruby 1.9 HEAD. thanks Mineo Aoki . * tdiary/defailtio.rb: through NameError in restore. 2005-03-09 TADA Tadashi * tdiary.rb: add mobile user agents; 'Vodafone' and 'MOT-'. thanks Masaru Yokoi * skel/i.update.rhtml: fix HTML tag typo. thanks Masaru Yokoi 2005-01-27 zunda * skel/i.update.rhtml: bug fix - Kanji code converted from shift-jis to euc * skel/i.month.rhtml: use labels from plugin for i18n 2005-01-12 Kazuhiko * tdiary/defaultio.rb: separate each transaction and use exclusive lock in writing transaction only. 2004-12-22 zunda * misc/style/emptdiary/emptdiary_style.rb: body_to_html defined, thanks to dai . 2004-12-01 zunda * skel/tdiary.rconf: bug fix - could not saveconf unless icon and description are set 2004-12-01 zunda * plugin/00default.rb, plugin/ja/00default.rb: added icon_tag and description_tag 2004-11-29 zunda * tdiary.rb, skel/tdiary.rconf, plugin/00default.rb, plugin/{ja,en,zh}/00default.rb: added @conf.icon and @conf.description 2004-11-05 MoonWolf * tdiary/tdiary_style.rb: XML-RPC API support * misc/style/emptdiary: XML-RPC API support * misc/style/etdiary: XML-RPC API support * misc/style/rd: XML-RPC API support * misc/style/wiki: XML-RPC API support 2004-11-04 MoonWolf * tdiary.rb: method visibility change. 2004-09-24 Fri UECHI Yasumasa * rd_style.rb: fix tainted name space of RD Headline class. Thanks Shugo Maeda . 2004-08-08 Junichiro Kita * tdiary.rb: TDiaryCategoryView's @last_modified changed to Time.now from Time.at(0). Thanks MATSUOKA Kohei . 2004-07-18 Junichiro Kita * tdiary.rb, tdiary/defaultio.rb: delete dispensable data dir and cache. 2004-07-01 TADA Tadashi * tdiary_style.rb: implement body_to_html method. 2004-06-28 Junichiro Kita * misc/i18n/tdiary.conf.sample-en: fix typo. thanks to jfkimura@yahoo.co.jp 2004-06-27 TADA Tadashi * release 2.0.0. 2004-06-18 TADA Tadashi * 00default.rb: deny robots when update modes. 2004-06-16 TADA Tadashi * add zh (Traditional Chinese) language resources. thanks Hiroshi Yui . 2004-06-15 Tue UECHI Yasumasa * rd_style.rb: remove

tags in manufacture(*_to_html) only subtitles is given. 2004-06-09 TADA Tadashi * 00default.rb: remove debug code. 2004-05-22 zunda * tdiary.conf.sample: English notice at the top. 2004-05-22 TADA Tadashi * default.css, tdiary1.css: add '@charset "euc-jp";'. 2004-05-20 Kazuhiko * skel/mail.rtxt, skel/mail.rtxt.en: separate each address by comma. 2004-05-20 TADA Tadashi * mail.rtxt.en: against empty @author_mail or @author_name. * tdiary.rb: catch exceptions when cannot delete cache files. 2004-05-19 ZnZ * 00default.rb, mail.rtxt: against empty @author_mail or @author_name. 2004-05-16 TADA Tadashi * misc/style/wiki/wiki_parser.rb: ignore any elements in plugin. * tdiary.conf.sample: add self URL into @no_referer. thanks ZnZ . 2004-05-14 TADA Tadashi * skel/mail.rtxt: support absolute path of @conf.index. 2004-05-09 TADA Tadashi * tdiary.rb: support absolute path of @conf.index. * skel/i.diary.rhtml: show TSUKKOMI body length 100 to 200 chars. 2004-05-05 TADA Tadashi * misc: move posttdiary.rb and tdiary-mode to contrib package. * release 1.5.7. 2004-05-05 Kazuhiko * misc/style/etdiary/etdiary_style.rb: fix a bug that causes a problem in 'to_html' without options. 2004-05-04 Kazuhiko * skel/update.rhtml: display an e-mail address of comment if exists. 2004-05-04 TADA Tadashi * tdiary.rb: remove to add '...' after using Config#shorten. 2004-04-19 ZnZ * tdiary.rb: add error information to eval. 2004-04-19 TADA Tadashi * tdiary.conf.sample: uncomment @options['apply_plugin'] and @options['bot']. * tdiary.conf.sample: some robots add to @options['bot']. thanks MUSHA . 2004-04-06 zunda * plugin/01sp.rb: records only plug-in filenames. When more than one plug-ins in different directories have the same filename, first occurrence in sp.path will be used, without raising an error. 2004-04-05 TADA Tadashi * theme/base.css: add .highlight class. thanks ZnZ and Naoko . 2004-04-04 TADA Tadashi * tdiary.rb: apply comment_filter for TrackBack. * tdiary/filter/default.rb: reject without GET method in comment_filter. 2004.03.16 SHIMADA Mitsunobu * misc/style/etdiary/etdiary_style.rb: fix bug: section without subtitle. 2004-03-15 Kazuhiko * tdiary.rb (apply_plugin): return empty string if input string is nil. 2004.03.15 Junichiro Kita * plugin/*/00default.rb: resurrection of category_anchor. Thanks mput. 2004.03.15 Junichiro Kita * index.rb, tdiary.rb, skel/category.rhtml, plugin/*/00default.rb: indexed category. Thanks mass and phonondrive.com. 2004-03-04 TADA Tadashi * tdiary.rb: do not call update_proc when TSUKKOMI was filtered. * plugin/00default.rb: fix bug in comment_mail_send. 2004-02-27 TADA Tadashi * tdiary.rb, skel/*: call update_proc after all plugins loaded. 2004-02-17 TADA Tadashi * tdiary.rb: fix TDiary::Filter::Filter#comment_filter prototype. 2004.02.12 Junichiro Kita * tdiary/filter/default.rb: support ruby 1.6.x. 2004-02-11 zunda * tdiary.rb, tdiary/filter/default.rb: fix bugs. 2004-02-10 TADA Tadashi * tdiary.rb, tdiary/filter/default.rb: TSUKKOMI and referer filter feature. 2004-02-09 TADA Tadashi * plugin/00default.rb: fuzzy regexp in my plugin. * skel/mail.rtxt*: anchor move to the bottom of body. 2004-02-09 mput * tdiary.rb: fix Plugin#apply_plugin. 2004-02-04 UECHI Yasumasa * misc/style/rd/rd_style.rb: rescue ParseError 2004-01-26 UECHI Yasumasa * misc/style/rd/rd_style.rb: fix body_to_html 2004.01.21 Junichiro Kita * tdiary.rb: call update_proc in TDiaryTrackBackReceive#eval_rhtml for recent_trackback3.rb. 2004-01-17 TADA Tadashi * plugin/{ja,en}/00default.rb: split @theme_location_comment. * theme/base.css: modify style of calendar3 plugin. 2004-01-17 TADA Tadashi * misc/posttdiary.rb: support ruby 1.8.1. 2004-01-17 Kazuhiko * tdiary.rb: use erbscan if possible. 2004.01.12 Junichiro Kita * tdiary.rb: remove TDiaryTrackBackBase#trackback_url. * tdiary.rb: use @conf.base_url in TDiaryTrackBackBase#diary_url. 2004.01.12 Junichiro Kita * tdiary.rb: if trackback is longer than 255 byte, it will be shorten to 252 byte and '...' will be added. 2004.01.09 TADA Tadashi * plugin/00default.rb: meta link support HTML 4.01. 2003.12.30 Junichiro Kita * plugin/00default.rb: my can handle 'yyyymmdd#txx'. * wiki_style.rb: strip_subtitle returns nil if subtitle == ''. thanks to YAA. 2003.12.26 TADA Tadashi * tdiary/pstoreio.rb: fix bug: enable running 1.5.6 or later. 2003.12.26 Kazuhiko * tdiary.rb(trackback_url): HTTP_HOST -> SERVER_NAME. (base_url): return '' in non CGI case. 2003.12.26 Junichiro Kita * skel/mail.rtxt*: add comment's URL in the body. 2003.12.25 TADA Tadashi * tdiary.rb: TDiaryBase#clear_cache support parameter of file name pattern. 2003.12.26 Kazuhiro NISHIYAMA * misc/style/wiki/wiki_style.rb: bug fix of parsing categories. thanks to yowa. 2003.12.26 Kazuhiro NISHIYAMA * tdiary.rb: catch StandardError when broken cache. 2003.12.20 Kazuhiko * misc/style/rd/rd_style.rb: bug fix. 2003.12.19 TADA Tadashi * index.rb, update.rb: set $KCODE to 'n'. 2003.12.19 Fri UECHI Yasumasa * misc/style/rd/rd_style.rb: accept lower level headlines without upper level headlines. 2003.12.18 TADA Tadashi * 00default.rb: save theme conf before call header_proc. 2003.12.16 Takeru KOMORIYA * tdiary.rb: do not count up last-modified when the diary disabled. 2003.12.16 TADA Tadashi * 00default.rb: accept fuzzy anchor style. 2003.12.11 TADA Tadashi * skel/day.rhtml, skel/diary.rhtml: do not make link URL when access from bot. 2003.12.09 TADA Tadashi * tdiary.rb: String#make_link replace space to ' ' only top of lines. 2003.12.01 TADA Tadashi * misc/posttdiary.rb: support over 10 images. thanks jun.o. 2003.11.27 TADA Tadashi * index.rb, update.rb: no 'Content-Type' in error message running on mod_ruby. * plugin/01sp.rb: sp.path can terminate by '/'. 2003.11.21 Junichiro Kita * tdiary.rb: Url returned by base_url ends with '/'. 2003.11.21 Kazuhiko * tdiary.rb: remove tail '/' of base_url. 2003.11.19 Junichiro Kita * tdiary.rb: import base_url method from RWiki. 2003.11.18 TADA Tadashi * tdiary.rb: run Plugin#apply_plugin under $SAFE = 4 when secure mode. 2003.11.17 TADA Tadashi * dot.htaccess: move comment about YYYYMMDD.html access to html_anchor.rb plugin. * tdiary/lang/ja.rb: remove decoding of charref. * plugin/00default.rb: remove sub from hostname in comment_mail_send. 2003.11.14 TADA Tadashi * misc/jtime.rb: removed. use plugin/jdate.rb. 2003.11.13 TADA Tadashi * release 1.5.6. 2003.11.10 TADA Tadashi * skel/update.rhtml*: add subtitle in update form. 2003.11.06 zunda * misc/style/emptdiary/README.rd and README.rd.en: emptdiary -> emptDiary 2003.11.06 TADA Tadashi * plugin/{ja,en}/00default.rb: looks up style documents in docs.tdiary.org wiki. 2003.11.05 Junichiro Kita * misc/style/wiki/README*: add document for kw plugin. 2003.11.05 Junichiro Kita * tdiary.rb: rescue SyntaxError and raise BadStyleError when bad style is specified. 2003.11.03 Junichiro Kita * ske/category.rhtml: stripped_subtitle -> stripped_subtitle_to_html. 2003.10.29 zunda * tdiary.rb: passes yield separate values instead of an Array to follow behavior of yield [ruby-dev:21276] 2003.10.28 Junichiro Kita * tdiary.rb: dup string in apply_plugin. * doc/HOWTO-make-io.rd: add documents for *_to_html. * misc/style/etdiary/etdiary_style.rb, misc/style/rd/rd_style.rb, misc/style/wiki/wiki_style.rb, tdiary/pstoreio.rb, tdiary/tdiary_style.rb: add *_to_html. 2003.10.25 Junichiro Kita * tdiary.rb: auto invalidation of parser cache and ERb cache. 2003.10.23 Kazuhiko * plugin/ja/00default.rb, plugin/ja/00default.rb, skel/category.rhtml, skel/conf.rhtml, skel/i.conf.rhtml, skel/i.day.rhtml, skel/i.latest.rhtml, skel/i.month.rhtml, skel/i.show.rhtml, skel/i.update.rhtml, skel/i.update.rhtml.en, skel/preview.rhtml, skel/preview.rhtml.en, skel/show.rhtml, skel/update.rhtml, skel/update.rhtml.en: escape HTML @html_title. 2003.10.22 TADA Tadashi * skel/tdiary.rconf: fix error when @author_mail was nil. 2003.10.21 Junichiro Kita * tdiary/lang/ja.rb: shorten('') returns '' instead of nil. 2003.10.14 Junichiro Kita * misc/style/wiki/wiki_style.rb: support '[[string|inter:key]]'. 2003.10.10 TADA Tadashi * misc/posttdiary.rb: --image-format. 2003.10.10 zunda * plugin/01sp.rb: CGI::escape instead of CGI::escapeHTML to make a URL 2003.10.09 zunda * plugin/01sp.rb: links to plugin documents 2003.10.09 Kazuhiko * plugin/00default.rb: untaint receivers for mod_ruby. 2003.10.09 TADA Tadashi * tdiary.rb, 00default.rb: move Plugin#bot? to Config class, and make wrapper in Plugin. * tdiary.rb: suppress saving referer from bot. 2003.10.08 Kazuhiko * plugin/01sp.rb: untaint sp_option( 'selected' ) for mod_ruby. 2003.10.07 Kazuhiko * tdiary.rb: untaint '#{@lang}.rb' for mod_ruby. 2003.10.07 Yasuaki Gohko * pstoreio.rb: support ruby 1.8. 2003.10.06 zunda * plugin/01sp.rb: allows multiple directories for plugins 2003.10.01 zunda * plugin/01sp.rb: no more revision information, links to sources and comments * plugin/01sp.rb: user friendlier sequence of plugin list 2003.10.01 Kazuhiro NISHIYAMA * tdiary.rb: change security error message in Plugin#add_cookie. 2003.09.29 TADA Tadashi * plugin/01sp.rb: support secure mode. 2003.09.28 TADA Tadashi * add new setting @referer_day_only to reduce 'referer noise'. 2003.09.27 zunda * plugin/01sp.rb: better to have default opt values set nil: hide* -> show* * plugin/01sp.rb: shows help in the resource file if there is 2003.09.27 TADA Tadashi * add plugin/01sp.rb and resources of ja and en. 2003.09.26 TADA Tadashi * tdiary/lang/en.rb: add comments. 2003.09.25 TADA Tadashi * i18n framework. * tdiary/lang: add ja.rb and en.rb. * tdiary.rb: move DiaryBase#disp_referer method to Plugin class. * tdiary.rb: remove Comment#shorten and Plugin#shorten. * misc/i18n/00lang.en.rb: moved to plugin/en/00default.rb. * add plugin/ja/00default.rb. 2003.09.25 Junichiro Kita * tdiary.rb, skel/diary.rhtml, plugin/00default.rb: add

. Thanks to mput. 2003.09.17 UECHI Yasumasa * rd_style.rb: change URL of RAA. 2003.09.16 TADA Tadashi * tdiary.rb, tdiary.conf*: add @cache_path. Thanks MoonWolf . 2003.09.10 TADA Tadashi * skel/tdiary.rconf: fix typo. * tdiary.rb: automatic generate date when Append. * misc/posttdiary.rb: not send date to update CGI. * misc/posttdiary.rb: unset date to request for tDiary. 2003.09.02 Junichiro kita * plugin/00default.rb: calc_links works correctly with mobile agent. 2003.09.02 KAKUTANI Shintaro * skel/plugin_error.rhtml: follow conf proc. 2003.09.02 TADA Tadashi * dot.htaccess: deny "*.rhtml*". * plugin/00default.rb: mobile_navi supports ruby 1.8. 2003.09.01 Junichiro kita * plugin/00default.rb, skel/i.*.rhtml: create navigation link with mobile_navi. 2003-08-23 zunda sp.rb: simpler configuration display 2003.08.28 Kazuhiko * rd_style.rb, wiki_style.rb insert "\n\n" at the end of @body. 2003-08-28 Thu UECHI Yasumasa * rd_style.rb: fix bug when last section doesn't terminate by CR. 2003-08-26 zunda sp.rb: English translation sp.rb: option defaults are flipped sp.rb: Typo for @options are fixed 2003-08-22 zunda sp.rb: following options are added: thanks to kaz sp.rb: @options['select_plugins.hidesource'] sp.rb: @options['select_plugins.hidemandatory'] sp.rb: @options['select_plugins.newdefault'] sp.rb: new plugins are marked in the list until the user configures the selections sp.rb: bug fix: check conf mode before updating the options 2003.08.21 TADA Tadashi * tdiary.rb: remove debug message. * tdiary.rb, 00default.rb: add Plugin@last_modified and insert it into HTML header. * 00default.rb, update.rhtml*, preview.rhtml*: add style_howto plugin. * index.rb, update.rb: waiting 1 second after post. 2003-08-20 zunda sp.rb: first release 2003.08.20 TADA Tadashi * skel/tdiary.rconf: cancel saving Array and Hash. 2003.08.20 TADA Tadashi * skel/tdiary.rconf: save Array and Hash value of @options2. thanks kazuhiko. * tdiary.rb: Config#delete as delete a key of @options. 2003.08.06 zunda * tdiary.rb: taint @options2 when it is created for the first time 2003.08.06 TADA Tadashi * tdiary.rb, 00default.rb: taint all param values of @cgi in Plugin. 2003.08.05 TADA Tadashi * doc/HOWTO-make-plugin.html: about conf_proc. * 00default.rb: fix about comment_mail error in secure mode. thanks kazuhiko. * release 1.5.5. 2003.08.04 TADA Tadashi * support ruby 1.8.0 preview7. * wiki_parser.rb: add "\n" to end of blockquoted lines. 2003.07.31 Junichiro Kita * index.rb: tdiary.cookies is set after tdiary.eval_rhtml, at least in case of whats_new plugin. 2003.07.30 TADA Tadashi * tdiary.rb: use ERB2 when running on ruby 1.8 or later (testing). * wiki_style.rb: support TrackBack anchor. 2003.07.29 UECHI Yasumasa * rd_style: fix Reference element to recognize trackbacks 2003.07.29 Kazuhiko * index.rb: don't make 'body' in case of HEAD request. 2003.07.22 TADA Tadashi * skel/conf.rhtml: to valid html. 2003.07.18 zunda * misc/style/emptdiary/emptydiary.rb: support ruby 1.8.0 (2003-07-18): Array.join() no longer returns EmptdiaryString but returns String. 2003.07.18 UECHI Yasumasa * rd_style: fix ref_ext_IMG is not for HTML4 2003.07.15 TADA Tadashi * save only valid referer, and referer URL to euc before display. 2003.07.10 TADA Tadashi * fix bug when empty receivers in comment_mail plugins. 2003.07.05 TADA Tadashi * fix yeasterday's bug. 2003.07.04 TADA Tadashi * fix some bugs in comment_mail plugins. 2003.06.24 TADA Tadashi * wiki_style.rb: fix bug about only subtitle section. * tdiary.rb, wiki_style.rb: support ruby 1.8.0 preview3. 2003.06.22 TADA Tadashi * 00default.rb: css_tag plugin support base.css. * default.css: remove including base.css. 2003.06.21 TADA Tadashi * conf_proc supports secure mode. 2003.06.16 Junichiro Kita * 00default.rb: use @conf.author_mail when @conf['comment_mail.receivers'] is nil. 2003.06.16 TADA Tadashi * conf_proc: English support. * conf_proc: mobile agent support. 2003.06.15 Hideki SAKAMOTO * tdiary.rb: initialize @css in Config class. 2003.06.14 TADA Tadashi * conf_proc plugin modify. * conf.rhtml.en: deleted. 2003.06.13 TADA Tadashi * [TESTING] conf_proc plugin modify. 2003.06.12 TADA Tadashi * [TESTING] conf_proc plugin support. * 00default.rb, mail.rtxt: optimize comment mail. 2003.06.07 TADA Tadashi * update.rhtml, preview.rhtml: renumbering tabindex. 2003.06.07 Junichiro Kita * wiki_style.rb: remove categorizable? 2003.06.06 TADA Tadashi * tdiary.rb, update.rb: redirection to day page after append or replace diary. * update.rhtml, preview.rhtml: change update form layout. * 00default.rb, 00lang.en.rb: marge edit.rb and change some labels. 2003.06.05 TADA Tadashi * base.css: add some plugin's default settings. thanks Nana. 2003.06.02 TADA Tadashi * tdiary.rb: fix error in 1st preview in the new day. 2003.05.30 TADA Tadashi * tdiary.rb: fix wrong style selected in preview when editing a diary in the another style. * base.css: add default of calendar3 plugin. 2003.05.17 Kenta MURATA * TDiaryComment#eval_rhtml ignores some exceptions 2003.05.15 TADA Tadashi * wiki_parser.rb: remove #!... line. * release 1.5.4. 2003.05.15 UECHI Yasumasa * rd_style.rb: fix footnote element with mput's patch. 2003.05.13 Junichiro Kita * tdiary.rb: TDiary::TDiaryTrackBackReceive#to_euc don't look charset parameter.(automatic translation) 2003.05.11 Junichiro Kita * tdiary.rb: TDiaryTrackBackReceive#eval_rhtml call super to do some plugin tasks. (eg. update_proc) 2003.05.10 Junichiro Kita * tdiary.rb: TrackBack support charset parameter. 2003.05.09 TADA Tadashi * preview.rhtml: show anchor. 2003.05.09 Junichiro Kita * plugin/00default.rb: add bot? 2003.05.06 Junichiro Kita * plugin/00default.rb: anchor can handle yyyymmdd#txx. 2003.05.06 TADA Tadashi * preview: change to simple action on append mode. 2003.05.03 Junichiro Kita * tdiary.rb: import classes for TrackBack(TDiary::TDiaryTrackBack*) from tb.rb. 2003.05.02 TADA Tadashi * index.rb, update.rb: untaint org_path. thanks mput. 2003.04.28 TADA Tadashi * HOWTO-make-plugin.html: add about form_proc. 2003.04.27 Junichiro Kita * plugin/00default.rb: send comment_mail when receive TrackBack Ping. 2003.04.22 TADA Tadashi * escape backslash in header and footer. 2003.04.20 TADA Tadashi * support form_proc plugin. 2003.04.18 TADA Tadashi * remove comment mail feature to plugin: comment_mail-{smtp,qmail,sendmail}.rb. 2003.04.17 TADA Tadashi * default.css: add table settings. * tdiary.conf.sample: updated. 2003.04.15 TADA Tadashi * support edit_proc plugin. 2003.04.11 zunda * skel/i.day.rhtml, skel/i.latest.rhtml, skel/i.month.rhtml: * plugin_error.rhtml: 'Update' -> 'Edit' when error in updating. 2003.04.06 TADA Tadashi * preview: show safety page when plugin error. 2003.04.05 TADA Tadashi * support preview page. 2003.04.04 TADA Tadashi * 00default.rb: add content_script_type plugin. 2003.04.03 TADA Tadashi * HOWTO-use-plugin.html: add about @options['apply_plugin']. * mobile mode support AirH"PHONE browser. 2003-04-02 UECHI Yasumasa * rd_style.rb: fix nested tag in DescList. thanx mput. * rd_style.rb: MethodList use for HTML block element. 2003.03.25 TADA Tadashi * wiki_style.rb: disable WikiName in WikiSection#strip_subtitle. 2003.03.22 Minero Aoki * misc/jtime.rb, misc/posttdiary.rb, misc/theme_convert/theme_conver.rb: remove warning on ruby 1.8. * emptdiary_style.rb, etdiary_style.rb, rd_style.rb, wiki_style.rb: remove warning on ruby 1.8. * skel/plugin_error.rb: remove warning on ruby 1.8. * tdiary/defaultio.rb, tdiary/pstoreio.rb, tdiary/tdiary_style.rb: remove warning on ruby 1.8. * tdiary.rb: remove warning on ruby 1.8. 2003.03.21 zunda * skel/(i.)diary.rhtml, i.update.rhtml(.en): comment.body.shorten -> comment.shorten 2003.03.19 TADA Tadashi * tdiary.rb: loading plugin files before eval rhtmls. 2003.03.17 TADA Tadashi * tdiary.rb: fix bug of referer_limit. 2003.03.14 TADA Tadashi * HOWTO-make-plugin.html: add about @plugin_files. 2003.03.10 TADA Tadashi * tdiary.rb: add @plugin_files into Plugin. 2003.03.08 UECHI Yasumasa * rd style: 'my' and 'a' plugins are used for reference. 2003.03.06 UECHI Yasumasa * rd style: simple subtitle in CHTML 2003.03.06 TADA Tadashi * tDiary/etDiary/emptDiary style: subtitle

to

in mobile mode. 2003.03.05 TADA Tadashi * Wiki style: fix bug of definition list. 2003.03.04 UECHI Yasumasa * rd_style.rb: change apply_to_RefToElement calls ref_ext_* methods directly. 2003.03.04 TADA Tadashi * support ruby 1.8.0 preview2 (again). 2003.03.03 TADA Tadashi * etDiary style: fix section starts with plugin. thanks simm. * support ruby 1.8.0 preview2. 2003.03.01 TADA Tadashi * rd style: fix subtitle without category (again). thanks mput and uechi. 2003.02.29 TADA Tadashi * rd style: fix subtitle without category. thanks mput. 2003.02.26 TADA Tadashi * wiki style: fix bug again when last section doesn't terminate by CR. * add navi_edit plugin (label) into 00default.rb and 00lang.en.rb. 2003.02.25 TADA Tadashi * wiki style: fix bug when last section doesn't terminate by CR. * some styles: update document about install. 2003.02.23 TADA Tadashi * wiki style: fix bug about blockquote grammar. * etDiary style: update. * release 1.5.3. 2003.02.21 TADA Tadashi * wiki style: modify blockquote grammar. * some documents update. 2003.02.19 TADA Tadashi * add etdiary style's document. * some documents update. 2003.02.18 TADA Tadashi * add emptdiary_style.rb and some documents of styles. * move misc/style/wiki/kw.rb to plugin. * doc.css: fix bug. 2003.02.17 TADA Tadashi * add rd_style.rb. 2003.02.16 TADA Tadashi * tdiary_style.rb: fix bug when subtitle has only category. * tdiary.rb: taint Plugin instance. 2003.02.13 TADA Tadashi * 00default.rb: hide preferences in navi_admin when categorized view. 2003.02.13 Junichiro Kita * add misc/style/etdiary/etdiary_style.rb 2003.02.12 Junichiro Kita * merge from Test_Category. 2003.02.12 Junichiro Kita * tdiary/pstoreio.rb: class Diary include UncategorizableDiary. 2003.02.11 Junichiro Kita * wiki_style.rb, tdiary_style.rb: stripped_subtitle returns nil if @subtitle or stripped subtitle is nil. 2003.02.11 Junichiro Kita * plugin/category.rb, skel/category.rhtml: separate cgi parameters with ';'. 2003.02.10 Junichiro Kita * category.rb: valid HTML. thanks Yoshimi KURUMA 2003.02.08 Junichiro Kita * move CategorizableDiary/UncategorizableDiary into tdiary.rb. * HOWTO-make-io.rd: add about category. 2003.02.08 TADA Tadashi * change IO <-> style interface: IOBase#load_styles. 2003.02.06 TADA Tadashi * support WikiWord and table in Wiki parser. 2003.01.22 TADA Tadashi * fix the term of style. 2003.01.21 TADA Tadashi * defaultio.rb: fix style require bug. * pstoreio.rb: fix about style. 2003.01.20 TADA Tadashi * tdiary.rb: rescue SyntaxError in plugins, and support mod_ruby. * support changing describe style. 2003.01.18 TADA Tadashi * HOWTO-make-plugin.html: add about HTML style generated by plugins. 2003.01.10 TADA Tadashi * 00default.rb: making @prev_day and @next_day in calc_link. for navi_user * 00default.rb: add link elements into head: start, first, prev, next and last. 2003.01.09 TADA Tadashi * 00default.rb: add title attr into specifying stylesheet. * tdiary.rb: Plugin#shorten. 2003.01.06 TADA Tadashi * defaultio.rb: truncate after .td2 saving. thanks MIZUNO Takehiko. 2002.12.30 TADA Tadashi * tdiary.rb: fix for mod_ruby. thanks rcn. 2002.12.25 Junichiro Kita * apply_plugin apply ERb when @options['apply_plugin'] == true 2002.12.25 TADA Tadashi * pstoreio.rb: for PStore of ruby 1.6.8. 2002.12.25 TADA Tadashi * release 1.5.2. 2002.12.24 TADA Tadashi * skel/i.*.rhtml: support @hide_comment_form in tdiary.conf. 2002.12.20 TADA Tadashi * tdiary.rb, HOWTO-make-plugin.html: add Plugin#apply_plugin method. 2002.12.19 TADA Tadashi * tdiary.conf.sample: change URL of yahoo search. * document update: theme gallery and theme bench to tDiary.org. * 00default.rb: fix nyear title. thank uechi . 2002.12.18 TADA Tadashi * conf.rhtml*: change theme gallery URL. * tdiary.rb, index.rb: be able to change last modified from plugins. 2002.12.16 TADA Tadashi * dot.htaccess: add some comments about ErrorDocument. * 00default.rb: skip hidden diary in navi_user. 2002.12.15 TADA Tadashi * 00default.rb, 00lang.en.rb: fix wrong title tag when NYEAR mode. 2002.12.13 TADA Tadashi * 00default.rb, 00lang.en.rb: prev and next navi when NYEAR mode, more. * default.css: a little change in list elements. 2002.12.11 TADA Tadashi * 00default.rb: prev and next navi when NYEAR mode. 2002.12.04 Junichiro Kita * plugin/00default.rb: bugfix in navi_user. 2002.12.02 TADA Tadashi * tdiary1.css: convert for 1.5 or later. * misc/i18n/00lang.en.rb: add nyear labels. * update English documents. thanks Mizuho . * add theme/base.css for basic styles. * footer.rhtml: move footer_proc before div.footer. 2002.12.02 Junichiro Kita * skel/diary.rhtml: let nyear into . 2002.12.01 Junichiro Kita * doc/HOWTO-make-plugin.html: add about footer_proc. 2002.12.01 Junichiro Kita * merge from Test_NYEAR. 2002.11.26 TADA Tadashi * tdiary.net -> tdiary.org. 2002.11.25 TADA Tadashi * update documents. thanks Mizuho . 2002.11.20 TADA Tadashi * fix: bad last modified setting in CommentManager::add_comment. 2002.11.19 TADA Tadashi * tdiary.rb: remove a debugging message. * defaultio.rb, pstoreio.rb: support Ruby 1.6.8 (ad hoc). * show.rhtml: make anchor name of section. 2002.11.18 TADA Tadashi * remove Japanese char in diary.rhtml and 00lang.en.rb. * fix: setting default values in Config. * release 1.5.1. 2002.11.17 TADA Tadashi * specify configuration value in default. * navi_user plugin: send Time object to navi_{prev|next}_diary. 2002.11.16 Minero Aoki * avoid ruby 1.7 warnings. 2002.11.13 TADA Tadashi * update docs. 2002.11.13 Junichiro Kita *index.rb: fix: put cookies into head after tdiary.eval_rhtml. 2002.11.12 TADA Tadashi * skel/*.en: marge some files to language independent revision. * tdiary.rb: fix: rescue plugin error. * defaultio.rb, pstoreio.rb: remove white space in the top of paragraph. 2002.11.11 TADA Tadashi * tdiary.rb: TDiaryBase#mode method added. 2002.11.08 Junichiro Kita * add TDiary::Config::mobile_agent? (for squeeze's error...) 2002.11.08 Junichiro Kita * @lang in tdiary.conf and add English resources. 2002.11.07 TADA Tadashi * tdiary.conf.sample: fix Regexp of private address in @no_referer. * dot.htaccess: more condition setting for 'YYYYMMDD.html' style. * add @plugin_path into conf. 2002.11.05 TADA Tadashi * misc/i18n/*: spell checking. 2002.11.02 TADA Tadashi * doc/HOWTO-make-theme.html: add about font-size and div.sidebar, themebench2. 2002.10.30 TADA Tadashi * misc/i18n/*: add English documents(draft), thanks Mizuho . 2002.10.29 Junichiro Kita * tdiary.rb: rescue ArgumentError in parser_cache 2002.10.28 TADA Tadashi * misc/mail-via-*: follow up for TDiary::Config. 2002.10.23 TADA Tadashi * Config#hide_comment_form. * fix bug: waste sending mail when no body of comment. 2002.10.22 TADA Tadashi * remove misc/squeeze.rb. use squeeze.rb in the plugin collection. 2002.10.17 TADA Tadashi * fix(?) bug(?) of 'YYYYMMDD.html' style. 2002.10.12 TADA Tadashi * support 'YYYYMMDD.html' style using ErrorDocument. * fix about reading hidden mode. 2002.10.07 TADA Tadashi * fix @mode value in TDiary::TDiaryBase#load_plugins. 2002.10.03 TADA Tadashi * merge with Test_TDiary_module branch, so... * split namespace by TDiary module. * load plugin files in TDiary::Plugin class. * split TDiary::Config class. * add @conf into Plugin class. * HOWTO-make-io.rd: update. * HOWTO-make-plugin.html: update. 2002.09.30 Hiroyuki Ikezoe * update.rhtml: add "update" into class selector in
. * conf.rhtml: add "conf" into class selector in
. 2002.09.29 TADA Tadashi * misc/posttdiary.rb:fix bug when boundary has special character of Regexp. 2002.09.28 TADA Tadashi * update.rb: remove an unnecessary
. 2002.09.24 TADA Tadashi * i.update.rhtml: fix typo. 2002.09.16 TADA Tadashi * update.rhtml: class="field" into all input field element. 2002.09.15 TADA Tadashi * tdiary.rb: fix bug in TDiaryAppend and TDiaryReplace: title= -> set_title. 2002.09.13 TADA Tadashi * HOWTO-make-io.rd: about Section#body. 2002.09.12 TADA Tadashi * index.rb: redirect using by meta element after comment posting. 2002.09.11 TADA Tadashi * update documents for 1.5 features. * 00default.rb, doc/*.html: HTML 4.01 Strict DOCTYPE. 2002.09.10 TADA Tadashi * tdiary.rb: argument check in DiaryBase#set_date. * HOWTO-make-io.html -> HOWTO-make-io.rd. 2002.09.09 TADA Tadashi * tdiary.rb: implement DiaryBase#title, DiaryBase#set_title. * defaultio.rb, pstoreio.rb: remove title, title=, date method. * rename method: Section#text -> to_src. 2002.08.26 TADA Tadashi * tdiary.rb: change TDiary::DIRTY_NONE false to zero. * tdiary.rb, diary.rhtml: add CommentManager#each_visible_comment. * tdiary.conf.sample: referer_table update. * pstoreio.rb: fix determination of dirty flag. * defaultio.rb: enable hidden comment flag. 2002.08.25 TADA Tadashi * defaultio.rb: fix about lost hidden comments at saving. thanks Mizuho . * update.rhtml: change format of comments. 2002.08.22 TADA Tadashi * defaultio.rb: untaint directory name in calendar method. thanks Mizuho . 2002.08.16 TADA Tadashi * tdiary.rb: create cache directory before using parser cache. thanks Mizuho . * paragraph_anchor -> section_anchor. * theme: panchor -> sanchor. * tdiary.rb: @ignore_parser_cache for yasqeeze. 2002.08.13 TADA Tadashi * tdiary.rb, defaultio.rb pstoreio.rb: change interface of io#transaction method. * diary#each_paragraph -> each_section * update.rhtml, defaultio.rb pstoreio.rb: to_text -> to_src. * HOWTO-make-io.html: add a document for IO class builders (cont.) 2002.08.07 TADA Tadashi * update.rhtml: replace Diary#each_paragraph to Diary#to_text. 2002.08.06 TADA Tadashi * diary.rhtml: remove commenttitle class. * tdiary.rb: call plugins after posting a comment. * tdiary.rb: use Plugin#anchor to make new location after posting comment. 2002.08.05 TADA Tadashi * tdiary.rb, defaultio.rb: implement parser cache. * defaultio.rb: split modules CommentIO and RefererIO. * tdiary.rb, defaultio.rb: optimize dirty flags. 2002.07.25 TADA Tadashi * tdiary.rb: fix of bad fragment of redirection after posting comment. thanks NT. * diary.rhtml: separate CR/LF in comments by
: try again. * append text when the target diary existed on replace mode (porting from Rev.1.31.2.4). 2002.07.24 TADA Tadashi * index.rb, tdiary.rb: redirect to day page after posting comment. * diary.rhtml: separate CR/LF in comments by
: more try. * defaultio.rb: cut surplus \n in tail of comments. 2002.07.23 TADA Tadashi * diary.rhtml: separate CR/LF in comments by
. * defauldio.rb: restore last modified into diaries. * convert2.rb: fix bugs. 2002.06.01 TADA Tadashi * defaultio.rb: fix IO#calendar. * defaultio.rb: fix tDiary2 parser. 2002.05.31 TADA Tadashi * 00default.rb: remove media="all" from meta element in HTML header. * implement tDiary2 file format [update support]. * update.rhtml, default.css: change class of 'hide diary' checkbox 'hide' to 'hidediary'. 2002.05.30 TADA Tadashi * implement tDairy2 file format [read only]. * diary.rhtml, update.rhtml: change class of form. * misc/convert2.rb: added. 2002.05.23 TADA Tadashi * follow i.diary.rhtml also. * diary.rhtml: add
into referer list. 2002.05.22 TADA Tadashi * split DiaryBase module from Diary class. * generate diary body in Diary class. 2002.05.21 TADA Tadashi * generate new HTML. 2002.05.20 TADA Tadashi * fix security hole about apply plugin. 2002.05.16 TADA Tadashi * replace new default theme. 2002.05.15 TADA Tadashi * split CommentManager and RefererManager from Diary class. * move theme files into each directory. 2002.05.14 TADA Tadashi * split IO class to tdiary/pstoreio.rb. * tdiary.rb: move transaction to IO classes. * tdiary.rb: rename make_years to calendar and move to IO class. * tdiary.rb: move Diary and Paragraph class to pstoreio.rb. * enable define @cache_path in tdiary.conf. * add String#shorten. 2002.05.14 TADA Tadashi * tdiary.rb: ignore $KCODE in disp_referer. * tdiary.conf.sample: shorten referer URL in @referer_table. 2002.05.12 TADA Tadashi * 1.4.2. * README.html: add notice about copyright of themes and plugins. 2002.04.26 TADA Tadashi * remove Plugin#eval_rhtml. 2002.04.24 TADA Tadashi * i.day.rhtml, i.show.rhtml: call update_proc when comment added. * tdiary.rb: suppress result string in Plugin#update_proc. 2002.04.23 TADA Tadashi * tdiary.rb: cache file change .rhtml -> .rb. thanks sakai . * add skel/plugin_error.rhtml and change message when errors in plugin. * HOWTO-make-plugin.html: add about @debug. 2002.04.23 MUTOH Masao * tdiary.rb: add @debug for Plugin#method_missing. 2002.04.21 TADA Tadashi * i.diary.rhtml: fix bug of paragraph number increment. 2002.04.19 TADA Tadashi * i.diary.rhtml: fix bug of paragraph number. 2002.04.18 TADA Tadashi * justify mail address auto-link in comment. 2002.04.17 TADA Tadashi * tdiary.rb: change version. * HOWTO-make-plugin.html: add about methods in Plugin. * doc/*: some bugs fixed. 2002.04.17 MUTOH Masao * index.rb, tdiary.rb: add Plugin#add_cookie. 2002.04.16 TADA Tadashi * misc/posttdiary.rb:bmp support for feelH". if found Ruby::Magick use it, else use convert. 2002.04.07 TADA Tadashi * misc/posttdiary.rb:fix mojibake: -mQ -> -m0. 2002.04.05 TADA Tadashi * 1.4.1 2002.04.05 TADA Tadashi * misc/posttdiary.rb: set permission of image to readable everybody. * misc/posttdiary.rb:--image-path and --image-url options. 2002.04.02 TADA Tadashi * conf.rhtml: make link to new Theme Gallery. * conf.rhtml: add notify about comment mail sent to. * update erb to 1.4.3. 2002.03.28 TADA Tadashi * default.css: no underline for links. 2002.03.27 TADA Tadashi * index.rb, update.rb: $:.unshift orig_path. * tdiary.rb: fail safe check for @data_path. 2002.03.26 TADA Tadashi * @options support in tdiary.conf and plugins. 2002.03.22 TADA Tadashi * tdiary.rb: Plugin#add_xxx_proc can receive a block. * 00default.rb: follow new add_xxx_proc style. * HOWTO-make-plugin.html: follow new add_xxx_proc style. * diary.rhtml: escape HTML in comment form. * tdiary.rb: shorten commentator's name and mail address validation in comment mail. 2002.03.20 TADA Tadashi * doctype plugin. * add HTML 4.01 Tr DTD's URL into default DOCTYPE. [testing] 2002.03.18 TADA Tadashi * tdiary.rb: fix comment mail subject was wrong. 2002.03.17 TADA Tadashi * 1.4.0 * conf.rhtml, tdiary.conf.sample, default.css: image anchor in default. * tdiary.rb: no referer saving into hidden diary. * update documents. 2002.03.15 TADA Tadashi * tdiary.rb: fix duplicated referer on day mode. * update.rb: move hide checkbox to right of submit button. 2002.03.14 TADA Tadashi * update.rhtml: remove 'class="commenttitle"' from changing comment status button. * default.css: add style for blockquote and some plugins. 2002.03.12 TADA Tadashi * update erb to 1.4.0. * taint @body_{enter,leave}_procs in Plugin class. 2002.03.11 TADA Tadashi * tdiary.rb, mail.rtxt: fix mime bug in From and Subject of comment mail. 2002.03.09 TADA Tadashi * tdiary.conf.sapmle: add notice about documentation in @footer. 2002.03.09 TADA Tadashi * 1.3.4 2002.03.08 TADA Tadashi * mail.rtxt: add white space after serial in subject. 2002.03.07 TADA Tadashi * add doc/HOWTO-make-theme.html. * tdiary.rb: join all lines in Comment#shorten. 2002.03.06 TADA Tadashi * @mail_header accept the format of Time#strftime. 2002.03.05 TADA Tadashi * documents moved to doc. * HOWTO-use-plugin.html, HOWTO-make-plugin.html: add. * remove sample plugins. * tdiary.rb: change to_mime to return array. 2002.03.05 Kazuhiko * tdiary.conf.sample, conf.rhtml: remove restriction of using Japanese in @mail_header. * skel/mail.rtxt: (Subject) use @date_format instead of '%Y-%m-%d'. * tdiary.rb: specify a message_id by hour, minute and second to avoid possible message_id confliction. exclude @mail_header from a message_id so as to avoid non-ascii character. 2002.03.04 TADA Tadashi * jtime.rb: add description. 2002.03.02 TADA Tadashi * tdiary.conf.sample: fix comment of @latest_limit. 2002.03.01 TADA Tadashi * i.update.rhtml: adjust comment number when some comments hidden. * add 'anchor' plugin. for mod_rewrite. * add 'my' plugin. 2002.02.28 TADA Tadashi * tdiary.rb, update.rhtml: adjust comment number when some comments hidden. 2002.02.27 TADA Tadashi * i.diary.rhtml: paragraph/comment anchor fixed in mobile mode. * squeeze.rb: add -c option and other changes. 2002.02.26 TADA Tadashi * tdiary.rb: fix when wrong file in @data_path. 2002.02.23 TADA Tadashi * mail-via-{qmail,sendmail}.rb: fix typo. * recent_list: fix paragraph numbering. 2002.02.22 Daisuke Kato * posttdiary.rb: support Multipart Mail. 2002.02.22 TADA Tadashi * *.css: valid by W3C. thanks shinchan . * update.rhtml, i.update.rhtml: change tabsindexs. * recent_comment.rb: update by kitaj . 2002.02.21 TADA Tadashi * recent_comment.rb: fix by zoe. 2002.02.20 TADA Tadashi * update.rhtml, i.update.rhtml: move hide box below submit button. * document maintenance. * theme: add wiLL.css. * misc/plugin: add recent_list.rb, calendar2.rb, recent_comment.rb, comment_rank.rb. * title_list.rb: HTML tags have compatibility with recent_list. 2002.02.19 TADA Tadashi * tdiary.rb: enable when no @no_referer in tdiary.conf. * tdiary.rb: untaint cache file name when clear cache. * tdiary.rb: rescue when errors in eval plugins. * tdiary.rb, diary.rhtml, i.diary.rhtml: [testing] body_{enter|leave}_proc plugin. * tdiary.rb, update.rhtml, i.update.rhtml: support hidden diary. * tdiary.rb, diary.rhtml, i.diary.rhtml: correct count of comments by Diary#count_comments. * misc/jtime.rb: added. * tdiary.rb: clear cache after changing comment status. 2002.02.12 TADA Tadashi * mail.rhtml: URL change. * 00default.rb: escape HTML tags in referer table. thanks KT . 2002.02.07 TADA Tadashi * tdiary.rb, 00default.rb: leap second again. * dot.htaccess: ExecCGI -> +ExecCGI. * tdiary.rb: mail-via-smtp as default. * tdiary.rb: sort themes in TDiaryConf. * skel/footer.rhtml: www.spc.gr.jp -> www.tdiary.net. * tdiary.rb: correct message_id. thanks woods 2002.01.31 TADA Tadashi * misc/plugin/README.html: fix bug: description of insert plugin. * 00default.rb: support leap second in navi_user. * tdiary.rb: ignore case hostname in Diary#add_referer. thanks munemasa . * conf.rhtml: insert 'navi plugin'. 2002.01.24 TADA Tadashi * @@update_proc -> add_update_proc, @@header_proc -> add_header_proc. * modify document misc/plugin/README.html. * call update_proc when a new comment appended. * misc/mail-via-{smtp|qmail|sendmail).rb: added. * UPGRADE: update. * mail.rtxt: add name to subject. * remove name attribute in anchor tag without DAY mode. * fix error in mobile mode. 2002.01.23 TADA Tadashi * add @@header into plugin. * fix error handling for loading plugins. * tdiary.conf.sample: maintain referer_table. * add Plugin's instance var: @cgi, @author_name, @author_mail, @theme, @css, @cookie. 2002.01.21 TADA Tadashi * 1.3.3 * tdiary.rb: fix TDiaryLatest#initialize. * tdiary.rb: easy to understand errors in plugins. * @hour_offset support. * 00default.rb: add plugins, "comment_total" and "comment_date". 2002.01.13 TADA Tadashi * 00default.rb: fix navi_user plugin when comment mode. * edit.rb: add new plugin into misc/plugin. * index.rb, update.rb: move 'begin' to top of script. * posttdiary.rb: add into misc. 2002.01.12 TADA Tadashi * misc/posttdiary.rb: added and support null subject. 2002.01.10 TADA Tadashi * fix cache bug. * conf.rhtml: fix typo. * tdiary.rb: bug fix: error when @index_page is nil in navi_user. * dropdown_calendar.rb: fix unclosed tag. * tdiary.rb: cache latest and month. * 00default.rb, diary.rhtml: move referer list to plugin. * tdiary.rb: add to Plugin @data_path and @cache_path. 2001.12.26 TADA Tadashi * 1.3.2 * diary.rhtml: add

when no comment. * themes update for new layout. * tdiary.rb: reverse.each -> reverse_each :-) * 00default.rb: remove title_list. * misc/plugin: added dropdown_calendar.rb, src.rb, title_list.rb. * misc/plugin: documentation of how to use/make plugin as README.html. * update plugin test implement. 2001.12.21 TADA Tadashi * over months in latest mode. thanks gekisive * misc/squeeze.rb: 1.0.1. 2001.12.20 TADA Tadashi * tdiary.rb: add @diaries to Plugin, again. * 00default.rb: bug fix: error when @index_page is empty in navi_user. * diary.rhtml, show.rhtml: hide comment form after update. * follow symlink-shared diary. * 00default.rb: add theme_url. * 00default.rb, *.rhtml: add xxx_label * 00default.rb: add title_list (trial). * CHANGES -> ChangeLog 2001.12.19 TADA Tadashi * tdiary.rb, diary.rhtml: bug fix: adjust number of comments. * tdiary.rb: some refactoring. * tdiary.rb: add @diaries to Plugin. * diary:rhtml: bug fix: @index -> opt['index'] in comment form. 2001.12.19 TADA Tadashi * index.rb, update.rb: remove Accept-Ranges header field in HTTP response. * tdiary.rb: add Plugin#method_missing. * tdiary.rb: comment summary upto 120 bytes. * day.rhtml: move referer list below comment form. * concat all default plugins into 00default.rb. * 00default.rb: split navi to navi_user and navi_admin. * index.rb, update.rb: add Vary header field. * diary.rhtml: change 'More...' to 'Before...'. * diary.rhtml: add '

...
'. 2001.12.17 TADA Tadashi * fix bug: error with mod_ruby. 2001.12.16 TADA Tadashi * 1.3.1 * moved *.rhtml *.rtxt *.rconf to skel/. * plugin support. thanks kitaj . * calendar and insert to plugin. * added navi plugin. 2001.11.26 TADA Tadashi * index.rb, update.rb: $defout.binmode. * link to tDiary Themes. * misc/squeeze.rb: added. * diary.rhtml: escape html to comment.name. 2001.11.18 TADA Tadashi * tdiary.rb, diary.rhtml: HTMLescape for referer. 2001.11.15 TADA Tadashi * index.rb, tdiary.rb: trapped permission error again. 2001.11.12 TADA Tadashi * index.rb, tdiary.rb: trapped permission error. * tdiary.rb: PStore#abort when unless @dirty. thanks sakai . 2001.10.12 TADA Tadashi * tdiary.rb: fix no effective show_referer/show_comment in CGI conf. 2001.10.01 TADA Tadashi * tdiary.rb: Xiino and L-mode into mobile terminal. * tdiary.conf.sample: referer_table update. * tdiary.rb: added 'Xiino' to mobile agent list. * tdiary.rb: fix error when no @smtp_host and @mail_on_comment == true. * tdiary.rb: different TZ problem fix(?). 2001.09.01 TADA Tadashi * 1.2.0 * tdiary.conf.sample: added some search engines into referer_table. * UPGRADE: added. * Document update. * tdiary.rb: exactly match for no_referer. 2001.08.30 TADA Tadashi * update.rb: remove no-cache. * HOWTO-write-tDiary.html: added. * update.rhtml: hide change comment mode button when no comments. 2001.08.27 TADA Tadashi * 1.1.4 * repackage. * tdiary.conf.sample: document update. 2001.08.27 TADA Tadashi * split referer.rhtml from conf.rhtml. * update/configuration page for i-mode. 2001.08.24 TADA Tadashi * add Windows CE's IE to mobile terminal. 2001.08.19 TADA Tadashi * theme: maroon by Shinchan. 2001.08.18 TADA Tadashi * add ASTEL DOTi and H" to mobile terminal. * @index, @update. * owner can hide any comments. 2001.08.17 TADA Tadashi * 1.1.3 * support mod_ruby completely. * tdiary.rb: fix make_link when URL have '@' in it. * add Zaurus to mobile terminal. * diary.conf: hidden 'new comment' when @show_comment was false. 2001.08.16 TADA Tadashi * testing for mod_ruby (3). 2001.08.16 TADA Tadashi * testing for mod_ruby (2). 2001.08.11 TADA Tadashi * testing for mod_ruby. 2001.08.07 TADA Tadashi * 1.1.2 * conf.rhtml: CGI::escapeHTML for each data. 2001.08.03 TADA Tadashi * tdiary.rb: fix bug not saving @latest_limit via CGI. * tdiary.rb: secure CGI setting. changing format of @data_path/tdiary.conf. * header.rhtml: showing error message. * diary.rhtml: link of "making new comment". * conf.rhtml: fix bug: display diff @no_referer2/@referer_table2 and @no_referer/@referer_table. 2001.07.30 TADA Tadashi * 1.1.1 * theme: line, nebula by zoe. * configuration via CGI. * index.rb, update.rb: no-cache. * errata: "auther" -> "author" (^^; * changing term: "Referer" -> "リンク元" 2001.07.25 TADA Tadashi * tdiary.rb: fix bug bad cookie when running on root directory. 2001.07.21 TADA Tadashi * <%=calendar%> added into tdiary.conf.sample. 2001.07.20 TADA Tadashi * make editable when multi user mode. * @date_format for comment. * referer_table into title attr in referer list. * Diary#eval_rhtml requires Hash parameter. 2001.07.19 TADA Tadashi * @date_format. 2001.07.18 TADA Tadashi * testing code for multi user mode. 2001.07.14 TADA Tadashi * 1.1.0 * making theme directory, and move default.css to theme. * theme: desert, lovely, midnight, pool side. * header and footer eval eRuby in Element class. 2001.07.05 TADA Tadashi * 1.0.1 * tdiary.rb: white space to ' ' in String#make_link. * calender -> calendar (^^; * mail.rtxt: add MIME-Version on header. * index.rb, tdiary.rb: force latest mode when incorrect date specified. * tdiary.conf.sample, README.html: 'Mary Diary' into @referer_table. * README.html: hoge.net -> hoge.example (as RFC2606). * tdiary.rb: 'anonymouse@anywhere' -> @auther_mail. 2001.07.01 TADA Tadashi * 1.0.0 * tdiary.rb: fix referer duplicated on latest day bug. * release. 2001.06.29 TADA Tadashi * 0.9.9.5 * tdiary.rb: char code force to EUC-JP * update.rhtml: referer_table apply to update. * header.rhtml: insert generator. * tdiary.rb: no saving duplicated comments. * update.rhtml: unescapeHTML for title. * diary.rhtml, default.css:

to

on subtitle. * day.rhtml: button of previous/next day. * diary.rhtml: SPACE and TAB change to   on comment. * default.css: hr.sep { display: none; } * tdiary.rb: suppress '?\d{8}' of referer URL. * tdiary.rb: text_save. thanks densuke * update.rhtml: add @referer_table. 2001.06.16 TADA Tadashi * 0.9.9 * tdiary.rb: fix referer saving bug on TDiaryDay. * tdiary.rb: ignore case when compare referers. * tdiary.conf.sample: fix typo. 2001.06.16 TADA Tadashi * 0.9.8 * saving name and mail of comment by cookie. 2001.06.15 TADA Tadashi * 0.9.7 * tdiary.rb: using unescaped URL for referer's key. * month.rhtml: fix error when no 1st day on MONTH mode. * tdiary.rb: compare @no_referer with unescaped referer. * tdiary.rb: fix add_referer miss type. * tdiary.rb, index.rb: Palmscape/ezWeb/J-PHONE support. * i.header.rhtml: date in * tdiary.rb: method 'title' in TDiaryView * tdiary.rb: show always latest month on view mode. * tdiary.rb: TDiary{Day|Comment|Month|Latest} classes. * tdiary.rb: mail on comment. * tdiary.rb, day.rhtml: referer_table. 2001.06.12 TADA Tadashi <sho@spc.gr.jp> * 0.9.6 * tdiary.rb: fix referer bug. 2001.06.12 TADA Tadashi <sho@spc.gr.jp> * 0.9.5 * header.rhtml: disable CSS for Netscape 4. * header.rhtml: date for <title> tag. * footer.rhtml: 'powerd' -> 'powered'. * tdiary.rb: fix make_link '&' bug. * tdiary.rb: unescape referer. * diary.rhtml: to_euc for referer URL. * diary.rhtml: idx -> count on today's referer. * diary.rhtml, i.diary.rhtml: enable Tagged paragraph after subtitle. Thanks for Masahiro Sakai <zvm01052@nifty.ne.jp> * index.rb, update.rb: using /usr/bin/env. 2001.05.18 TADA Tadashi <sho@spc.gr.jp> * 0.9.4 * i-mode support (view only) * tdiary.rb: fixed Last-Modified bug. * rename: admin.rb -> update.rb * move: ../tdiary.css -> default.css * anchor for comments. * .diary: @paragraph_anchor, @comment_anchor, @limit_latest * document as README.html. 2001.05.14 TADA Tadashi <sho@spc.gr.jp> * 0.9.3 * tdiary.css: hr.sep class * tdiary.conf support * move: data path * move: admin/index.rb -> admin.rb 2001.04.25 TADA Tadashi <sho@spc.gr.jp> * 0.9.2 * tdiary.rb: fixed Last-Modified bug. * diary.rhtml: split paragraphs when a Paragraph object have some line. * tdiary.rb: saving referer only starting with 'http://'. * diary.rhtml: unescape referer URL when display. 2001.04.24 TADA Tadashi <sho@spc.gr.jp> * 0.9.1 * no update last-modified when request with referer. * no file creation when specified a date no existent. 2001.04.23 TADA Tadashi <sho@spc.gr.jp> * 0.9.0 * create and local release. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/Dockerfile������������������������������������������������������������������������0000664�0000000�0000000�00000001365�13626457307�0015754�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������FROM ruby:2.7 MAINTAINER MATSUOKA Kohei @machu RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY [ "Gemfile", "Gemfile.lock", "/usr/src/app/" ] RUN apt update && apt install -y apt-utils libidn11-dev; \ echo 'gem "puma" \n\ gem "tdiary-contrib" \n\ gem "tdiary-style-gfm" \n\ gem "tdiary-style-rd" \n'\ > Gemfile.local; \ gem install bundler && \ bundle --path=vendor/bundle --without=development:test --jobs=4 --retry=3 COPY . /usr/src/app/ RUN if [ ! -e tdiary.conf ]; then cp tdiary.conf.beginner tdiary.conf; fi && \ bundle && \ bundle exec rake assets:copy VOLUME [ "/usr/src/app/data", "/usr/src/app/public" ] EXPOSE 9292 ENV PORT=9292 ENV HTPASSWD=data/.htpasswd CMD bundle exec rackup -o 0.0.0.0 -p ${PORT} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/Gemfile���������������������������������������������������������������������������0000664�0000000�0000000�00000001644�13626457307�0015255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������source 'https://rubygems.org' gem 'rack' gem 'hikidoc' gem 'fastimage' gem 'emot' gem 'mail' gem 'rake' group :development do gem 'pit', require: false gem 'racksh', require: false gem 'redcarpet' gem 'octokit' gem 'mime-types' platforms :ruby_24 do gem 'ruby-debug-ide' gem 'debase' end group :test do gem 'pry-byebug', platforms: [:ruby_24] gem 'test-unit' gem 'rspec' gem 'capybara', require: 'capybara/rspec' gem 'selenium-webdriver' gem 'launchy' gem 'sequel' gem 'sqlite3' gem 'jasmine', '< 3' gem 'simplecov', require: false gem 'coveralls', '~> 0.8', require: false end end # https://github.com/redmine/redmine/blob/master/Gemfile#L89 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") if File.exist?(local_gemfile) puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` instance_eval File.read(local_gemfile) end ��������������������������������������������������������������������������������������������tdiary-core-5.1.1/Gemfile.lock����������������������������������������������������������������������0000664�0000000�0000000�00000006001�13626457307�0016174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������GEM remote: https://rubygems.org/ specs: addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) byebug (11.1.1) capybara (3.31.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (~> 1.5) xpath (~> 3.2) childprocess (3.0.0) coderay (1.1.2) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) term-ansicolor (~> 1.3) thor (>= 0.19.4, < 2.0) tins (~> 1.6) debase (0.2.4.1) debase-ruby_core_source (>= 0.10.2) debase-ruby_core_source (0.10.9) diff-lcs (1.3) docile (1.3.2) emot (0.0.4) thor faraday (1.0.0) multipart-post (>= 1.2, < 3) fastimage (2.1.7) hikidoc (0.1.0) jasmine (2.99.0) jasmine-core (>= 2.99.0, < 3.0.0) phantomjs rack (>= 1.2.1) rake jasmine-core (2.99.2) json (2.3.0) launchy (2.5.0) addressable (~> 2.7) mail (2.7.1) mini_mime (>= 0.1.1) method_source (0.9.2) mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2019.1009) mini_mime (1.0.2) mini_portile2 (2.4.0) multipart-post (2.1.1) nokogiri (1.10.8) mini_portile2 (~> 2.4.0) octokit (4.16.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) phantomjs (2.1.1.0) pit (0.0.7) power_assert (1.1.6) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) pry-byebug (3.8.0) byebug (~> 11.0) pry (~> 0.10) public_suffix (4.0.3) rack (2.2.2) rack-test (1.1.0) rack (>= 1.0, < 3) racksh (1.0.0) rack (>= 1.0) rack-test (>= 0.5) rake (13.0.1) redcarpet (3.5.0) regexp_parser (1.7.0) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) rspec-core (3.9.1) rspec-support (~> 3.9.1) rspec-expectations (3.9.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-support (3.9.2) ruby-debug-ide (0.7.0) rake (>= 0.8.1) rubyzip (2.2.0) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) sequel (5.29.0) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) sqlite3 (1.4.2) sync (0.5.0) term-ansicolor (1.7.1) tins (~> 1.0) test-unit (3.3.5) power_assert thor (1.0.1) tins (1.24.1) sync xpath (3.2.0) nokogiri (~> 1.8) PLATFORMS ruby DEPENDENCIES capybara coveralls (~> 0.8) debase emot fastimage hikidoc jasmine (< 3) launchy mail mime-types octokit pit pry-byebug rack racksh rake redcarpet rspec ruby-debug-ide selenium-webdriver sequel simplecov sqlite3 test-unit BUNDLED WITH 2.1.4 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/LICENSE���������������������������������������������������������������������������0000664�0000000�0000000�00000043105�13626457307�0014765�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) 19yy <name of author> 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/Procfile��������������������������������������������������������������������������0000664�0000000�0000000�00000000037�13626457307�0015443�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������web: bundle exec puma -p $PORT �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/README.md�������������������������������������������������������������������������0000664�0000000�0000000�00000004331�13626457307�0015235�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# tDiary [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://www.heroku.com/deploy?template=https://github.com/tdiary/tdiary-core) [![Gem Version](https://badge.fury.io/rb/tdiary.png)](https://rubygems.org/gems/tdiary) [![Build Status](https://secure.travis-ci.org/tdiary/tdiary-core.png)](https://travis-ci.org/tdiary/tdiary-core) [![Coverage Status](https://coveralls.io/repos/tdiary/tdiary-core/badge.png?branch=master)](https://coveralls.io/r/tdiary/tdiary-core) [![Code Climate](https://codeclimate.com/github/tdiary/tdiary-core.png)](https://codeclimate.com/github/tdiary/tdiary-core) ## tDiary, The TSUKKOMI-able Weblog. At first, see doc/README-en.rd ## tDiary, ツッコミ可能なWeb日記システム tDiaryはWeb日記(いわゆるブログ)を実現するオープンソースソフトウェアです。ブログサービスをレンタルするのではなく、自分でWeb日記を運用する人のためのツールです。 tDiaryには以下のような特徴があります。 ### 長く日記を続けられます 日記は大切な自分史です。安心して長く日記を書き続けられるように、tDiaryは最低でも25年間はプロジェクトを維持することを目標に開発を続けています。2016年現在で15周年になるので、あと10年間はtDiaryで日記を書き続けることができます。 ### レンタルサーバーユーザにやさしい 必要なのはRuby(2.1.0以降に対応)だけ。単独でCGIとして動作し、基本機能はデータベースや追加のライブラリを必要としません。 ### プラグインで拡張できます 豊富なプラグインで、さまざまな機能を追加できます。ブログツールとして必要な機能はほとんどプラグインとして揃っています。 ### テーマで好きなデザインを選べます 300種類を超えるデザイン・テーマを選べます。ユーザが作成したテーマを一堂に集めたテーマ・ギャラリーも見てください。 ### その他 インストールにはドキュメント(doc/INSTALL.html)を参照して下さい。動作にはruby(2.1.0以降)と、CGIもしくはRackをサポートするWebサーバが必要です。 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/Rakefile��������������������������������������������������������������������������0000664�0000000�0000000�00000000570�13626457307�0015424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������$LOAD_PATH.unshift 'lib' require 'tdiary/environment' require 'tdiary/tasks' require 'rake' require 'rake/clean' require 'bundler/gem_tasks' if File.exist?('tdiary.gemspec') CLEAN.include( "tmp", "data", "index.rdf" ) CLOBBER.include( "rdoc", "coverage" ) # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ����������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/app.json��������������������������������������������������������������������������0000664�0000000�0000000�00000001174�13626457307�0015433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "name": "tDiary", "website": "http://www.tdiary.org/", "repository": "https://github.com/tdiary/tdiary-core", "addons": [ "sendgrid", "memcachier", "mongolab" ], "scripts": { "postdeploy": "bundle exec rake mongodb:index" }, "env": { "TWITTER_KEY": { "required": true }, "TWITTER_SECRET": { "required": true }, "TWITTER_NAME": { "required": true }, "RACK_ENV": "production" }, "buildpacks": [ { "url": "https://github.com/tdiary/heroku-buildpack-tdiary" }, { "url": "https://github.com/heroku/heroku-buildpack-ruby" } ] } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/benchmark/������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0015707�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/benchmark/benchmark_amazon_plugin.rb����������������������������������������������0000664�0000000�0000000�00000001677�13626457307�0023124�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def enable_js(*args); end def add_conf_proc(*args); end def h(args); args; end class Dummyconf def [](*args); if args[0] == 'amazon.imgsize' 0 end end def []=(*args); end def to_native( str, charset = nil ) str = str.dup if str.encoding == Encoding::ASCII_8BIT str.force_encoding(charset || 'utf-8') end unless str.valid_encoding? str.encode!('utf-16be', {invalid: :replace, undef: :replace}) end unless str.encoding == Encoding::UTF_8 str.encode!('utf-8', {invalid: :replace, undef: :replace}) end str end end @conf = Dummyconf.new require 'benchmark/ips' Benchmark.ips do |x| xml = File.read('../spec/fixtures/jpB00H91KK26.xml') require_relative '../misc/plugin/amazon' x.report('rexml') do item = AmazonItem.new(xml) amazon_detail_html( item ) end x.report('oga') do require 'oga' item = AmazonItem.new(xml, :oga) amazon_detail_html(item) end end �����������������������������������������������������������������tdiary-core-5.1.1/benchmark/benchmark_io_default.rb�������������������������������������������������0000664�0000000�0000000�00000001776�13626457307�0022374�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary PATH = File::dirname( __FILE__ ) class << self def root File.expand_path(File.join(library_root, '..')) end # directory where tDiary libraries is located def library_root File.expand_path('..', __FILE__) end # directory where the server was started def server_root Dir.pwd end end end require_relative '../lib/tdiary/cache/file' require_relative '../lib/tdiary/io/default' class DummyTDiary attr_accessor :conf def initialize @conf = DummyConf.new @conf.data_path = TDiary.root + "/tmp/" end def ignore_parser_cache false end end class DummyConf attr_accessor :data_path def cache_path TDiary.root + "/tmp/cache" end def options {} end def style "wiki" end end conf = DummyConf.new conf.data_path = TDiary.root + '/tmp/data/' diary = DummyTDiary.new diary.conf = conf io = TDiary::IO::Default.new(diary) require 'benchmark/ips' Benchmark.ips do |x| x.report('calendar') do io.calendar end x.report('calendar2') do io.calendar2 end end ��tdiary-core-5.1.1/bin/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0014525�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/bin/tdiary������������������������������������������������������������������������0000775�0000000�0000000�00000000244�13626457307�0015747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env ruby lib = File.expand_path('../../lib/', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'tdiary/cli' TDiary::CLI.start ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/config.ru�������������������������������������������������������������������������0000664�0000000�0000000�00000000304�13626457307�0015567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������$:.unshift( File.join(File::expand_path(File::dirname( __FILE__ )), 'lib' ) ) require 'tdiary/application' use ::Rack::Reloader unless ENV['RACK_ENV'] == 'production' run TDiary::Application.new ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/data/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0014666�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/data/.htaccess��������������������������������������������������������������������0000664�0000000�0000000�00000000037�13626457307�0016464�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Order allow,deny Deny from all �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0014522�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-authenticate-in-rack.md�������������������������������������������������0000664�0000000�0000000�00000016332�13626457307�0021747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������How to authenticate in rack =========================== 概要 ---- tDiaryをCGI/FastCGI環境で動かす場合は、WebサーバのBasic認証機能を使って認証を実現しています。一方、Rack環境で動かす場合には、Rackミドルウェアにて認証を実現します。ここでは、Rack環境での認証の導入方法を説明します。 認証方法 ---- Rack環境では、以下の認証方法が利用できます。 - Basic認証 - 外部サービス認証 Basic認証はCGI/FastCGI環境と同様に、 `.htpasswd` ファイルによる認証を提供します。外部サービス認証はOpenIDやOAuthなどの仕組みを使って、TwitterやGitHubなどの外部のサービスによる認証を提供します。 Basic認証の使い方 ---- Basic認証では、パスワードを2つの方法で格納できます。通常はパスワードがハッシュ化されて保存される1の方法を利用してください。 1. IDとパスワードを格納する.htpasswdファイルを作成する 2. 設定ファイル (config.ru) にIDとパスワードを記述する htpasswdコマンドを使って`.htpasswd`ファイルを作成します。 ``` htpasswd -cd .htpasswd username ``` -cオプションはファイルの新規作成、-dオプションは暗号化にCRYPT方式を利用します。現時点ではCRYPT方式にのみ対応しており、MD5やSHA1方式には対応していないため、必ず-dオプションを指定してください。 外部サービス認証 ---- 外部サービス認証は、[OmniAuth](https://github.com/intridea/omniauth)という認証フレームワークを利用して実現しています。設定方法は、利用する外部サービスによって若干異なります。 ここでは、Twitter認証を利用する場合を例にとって説明します。 ### ライブラリを有効にする 利用する外部サービスに対応したライブラリを有効にします。Twitter認証では `omniauth-twitter` ライブラリを使用します。Gemfile.localにて以下の行が有効になっていることを確認してください。無ければ追加してください。 ``` gem 'omniauth' gem 'omniauth-twitter' ``` ### Twitter Appsへのアプリケーションの登録 Twitter 認証を使うためには、Twitter のサイトにてアプリケーションを登録する必要があります。[Twitter Apps](https://dev.twitter.com/apps/new)にアクセスし、以下の情報を入力して新しいアプリケーションを登録してください。 - Name: アプリケーションの名前です。設置する日記のタイトルを設定すると分かりやすいでしょう。 - Description: アプリケーションの説明です。迷ったら「日記へログインするためのTwitter認証」などとすると良いでしょう。 - Website: アプリケーションのURLです。設置する日記のトップページを設定すると分かりやすいでしょう。 - Callback URL: 認証後に移動するURLです。Websiteと同じURLを設定してください。 Name, Description, Websiteに設定した値は、Twitterのアプリ連携画面(認証画面)に表示されます。また、Callback URLを空欄にするとTwitter認証が動作しなくなります。任意のURLで良いので設定してください。 ### 鍵とパスワードの取得と環境変数への設定 Twitterのサイトから鍵とパスワードを取得したら、鍵 (Consumer key) とパスワード (Consumer secret) をそれぞれ環境変数として設定します。 ``` export TWITTER_KEY="your_consumer_key" export TWITTER_SECRET="your_consumer_secret" ``` ここではbashの例を書きましたが、環境変数の設定方法は環境によって異なります。たとえばherokuの場合は `heroku config` コマンドを使用します。もし環境変数が設定できない環境であれば、 `config.ru` を直接書き換えてください。 ### 編集画面へのアクセスを許可するアカウントの設定 日記の編集画面へのアクセスを許可するアカウントを設定します。 環境変数TWITTER_NAMEにログインを許可したい twitter のアカウント名(スクリーンネーム)を設定して下さい。 ``` export TWITTER_NAME='your_twitter_screen_name' ``` 日記の編集画面にアクセスすると、Twitterのログイン画面が表示されるようになります。編集画面へは `your_twitter_screen_name` で指定したアカウントのみがアクセスできます。 サポートしている外部サービス認証の一覧 ---- ### Twitter Gemfile.localの記述 ``` gem 'omniauth' gem 'omniauth-twitter' ``` 環境変数の設定 ``` export TWITTER_KEY="your_consumer_key" # Consumer Key (API Key) export TWITTER_SECRET="your_consumer_secret" # Consumer Secret (API Secret) export TWITTER_NAME="your_screen_name" # アクセスを許可するアカウント名 ``` KeyとSecretは [Twitter Application Management](https://apps.twitter.com/) にて取得できます。 ### Facebook Gemfile.localの記述 ``` gem 'omniauth' gem 'omniauth-facebook' ``` 環境変数の設定 ``` export FACEBOOK_KEY="your_app_id" # App ID export FACEBOOK_SECRET="your_app_secret" # App Secret export FACEBOOK_EMAIL="your_email@example.com" # アクセスを許可するアカウントのメールアドレス ``` IDとSecretは [Facebook Developers](https://developers.facebook.com/) にて取得できます。 設定画面にてWebsiteの「Site URL」と「Mobile Site URL」には、設置する日記のアドレスを指定してください。 ### Google Gemfile.localの記述 ``` gem 'omniauth' gem 'omniauth-google-oauth2' ``` 環境変数の設定 ``` export GOOGLE_CLIENT_ID="your_client_id" # クライアント ID export GOOGLE_CLIENT_SECRET="your_client_secret" # クライアント シークレット export GOOGLE_EMAIL="your_email@gmail.com" # アクセスを許可するアカウントのメールアドレス ``` IDとシークレットは [Google API](https://console.developers.google.com/iam-admin/projects) にて取得できます。 設定画面にて「リダイレクトURL」には、設定する日記のアドレスの末尾に `update.rb/auth/google_oauth2/callback` を加えたものを指定してください。 日記のアドレスが `http://diary.example.com/` の場合、リダイレクトURLは `http://diary.example.com/update.rb/auth/google_oauth2/callback` となります。 また、Google Developers Consoleの「APIと認証」にて、Google+ APIのステータスをonにしてください。 ### GitHub Gemfile.localの記述 ``` gem 'omniauth' gem 'omniauth-github' ``` 環境変数の設定 ``` export GITHUB_KEY="your_client_id" # Cliend ID export GITHUB_SECRET="your_client_secret" # Cliend Secret export GITHUB_NAME="your_github_nickname" # アクセスを許可するアカウント名 ``` Cliend ID と Cliend Secret は、 [New OAuth Application](https://github.com/settings/applications/new) にて取得できます。 設定画面にて「Authorization callback URL」には、設置する日記のアドレスを指定してください。 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-make-io.md��������������������������������������������������������������0000664�0000000�0000000�00000031262�13626457307�0017270�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������IOクラスの作り方 ========= 概要 -- tDiaryは、保存形式や日記記述フォーマットを差し替えることができます。 保存形式はIOクラスと呼ばれるTDiary::IOBaseクラスを継承したクラスを実 装することで変更可能です。また、記述フォーマットはDiaryBaseモジュー ルをincludeしたクラスで実装します。このドキュメントでは、これらの実 装に関する解説を行います。 IOクラス ----- 保存形式を変更する新たなクラスを作成し、tdiary.confで指定することで、 tDiary独自の保存形式と違う、独自の保存形式を選択できます。例えばDBMS に日記データを保存する等、異なる運用のtDiaryを作ることが可能です。こ れを実現するための仕組みを総称して「IOクラス」と呼んでいます(RubyのIO クラスとは違います)。 ### IOBaseクラス tdiary.rbにはTDiary::IO::Baseというクラスが定義されており、これを継承 して独自のIOクラスを作成します。下記の例は、Tdiary::IO::Hogeを定義しています。 ``` module TDiary module IO class Hoge < Base def calendar ..... end ..... end end end ``` ### 最低限実装すべきもの TDiary::IO::BaseクラスにはIOクラスに共通ないくつかのメソッドがすでに実装してあ ります。これを継承したIOクラスでは、さらに以下のようなメソッドを実装 しなくてはいけません。 #### calendar tDiaryに、日記が存在する年月を通知するためのメソッドです。実行時にtDiary から呼び出されます。 返り値には、現在利用できる日記が含まれている年・月を、Hashオブジェク トで返します。Hashに含まれている各値は、キーに西暦年(Stringで4文字)、 対応する値にはArrayで月(Stringで2桁)を設定します。以下に例を示します。 ``` def calendar return { '2001' => ['12'], '2002' => ['01', '02', '03', '04', '05', '08'] } end ``` #### transaction( date ) 指定された月の日記データを読み込み、tDiaryに理解できる形で渡します。 引数dateはTimeオブジェクトで、年と月のみがlocaltimeで与えられます。 transactionメソッドはdateで指定された月の日記データをファイル(または その他の媒体)から読み出して、ブロックパラメタとしてtDiaryに返します。 このブロックパラメタはHashで、キーに年月日(Stringで8桁)、値に日記デー タ(後述するDiaryBaseをincludeしたクラスのインスタンス)を持ちます。 ブロックパラメタを受けとったtDiaryは、それを使って日記を表示または更 新するので、transactionメソッドはその返り値に従って日記を保存する等 の処理を行えます。以下にtDiaryからの返り値を示します。実際にはこれら の論理和が返ります。 - TDiary::TDiaryBase::DIRTY\_NONE: 日記データに変更はありませんでした - TDiary::TDiaryBase::DIRTY\_DIARY: 日記本文に変更がありました - TDiary::TDiaryBase::DIRTY\_COMMENT: ツッコミに変更がありました - TDiary::TDiaryBase::DIRTY\_REFERER: リンク元に変更がありました 以下にtransactionの例を示します。 ``` def trasaction( date ) diaries = { ... } # restore data dirty = yield( diaries ) if dirty & TDiary::TDiaryBase::DIRTY_DIARY != 0 ... # saving diary data if dirty & TDiary::TDiaryBase::DIRTY_COMMENT != 0 ... # saving comment data if dirty & TDiary::TDiaryBase::DIRTY_REFERER != 0 ... # saving referer data end end ``` ### 実装するとよいもの オプショナルですがIOに実装しておいた方がよいメソッドがあります。 プラグインが利用するストレージとしてIOと同じもの(データベースなど)を使えるようにするインタフェースがあります。このストレージはプラグインに対して一種のkey/valueストレージとして見えます。(インスタンスメソッドではなく)クラスメソッドとして下記のメソッドを実装しておくと、そちらが使われます。ない場合はPStoreを使ったデフォルト実装が使われます。サンプル実装はこのデフォルトを参照して下さい( lib/tdiary/io/plugin_pstore.rb )。 #### IO::plugin_open( conf ) プラグイン用のストレージを開きます。すべてのプラグインが実行される前に呼び出されます。引数として TDiary::Conf のインスタンスが渡ります。 実際に何かを開く必要はありませんが、前処理が必要ならここで実施して下さい。また、他の plugin_close や plugin_transaction に渡したい情報があれば返り値に指定して下さい。 #### IO::plugin_close( plugin_storage ) プラグインの実行を終えたあとに呼び出されます。引数には plugin_open が返した値が渡されます。必要に応じて後処理を記述して下さい。 #### IO::plugin_transaction( plugin_storage, plugin_name ) プラグイン用ストレージを読み書きします。引数には plugin_open が返した値と、プラグインの名前が渡ります。 また、ブロックが渡されるので、ストレージを読み書き可能にしてから yield する必要があります。yield にはブロック引数をひとつ渡す必要があり、この引数には以下のメソッドが実装されていなければなりません。 * get( key ) : key で指定された値(value)を返します * set( key, value ) : key に value を保存します。value は文字列です * delete( key ) : key で指定された値を削除します * keys : ストレージに保存されている key をすべて Array で返します 日記データ ----- 続いて、IOクラスのtransactionメソッドの返り値に含まれる日記データが 満たすべき条件について述べます。 日記データの具体例としては tdiary/tdiary\_style.rb で定義されている TDiary::DefaultDiary を参照してください。 「日記データ」は以下の要素から構成されています。 - 日付 - タイトル - 最終更新日 - 0個以上のセクション - 0個以上のツッコミ - 0個以上のリンク元 さらに「セクション」は以下の要素から構成されています。 - サブタイトル - 著者 - 本文 日記のデータ構造がこれと完全に同一である必要はなく、日記データが付加 的なデータを持ったり、 セクションがいくつかのサブセクションに分かれたりしても良いです。 カテゴリ機能について ---------- カテゴリ機能とは、日記中のセクションにキーワードを付けて、 あとで同じキーワードをまとめて一覧できる機能のことです。 セクションのカテゴリは、サブタイトル中で指定します。 tDiaryスタイルでは ``` [カテゴリ] サブタイトル ``` のようにカテゴリを指定することにしていますが、 IOクラス/スタイル作者が各IOクラス/スタイルに適した カテゴリ指定の文法を定義して下さい。 カテゴリ機能の実装は必須ではありません。 日記データをカテゴリ機能に対応させるかどうかはIOクラスの作者が判断して下さい。 日記データのクラス --------- 日記データからはその日付、タイトル、最終更新日、日記本文、 コメント、Referer、セクションなどを参照できる必要があります。 もし、この日記データをスタイルとして設計するのであれば、IOクラスとは 分離して、別のファイルにする必要があります。この場合、スタイル名と ファイル名、日記データクラス名には強い依存性があります。「Hoge」という スタイルを作る場合、以下のように作る必要があります。 - スタイル名: Hoge - ファイル名: style/hoge.rb - クラス名 : TDiary::Style::HogeDiary (スタイル名.capitalize + 'Diary') ### 最低限実装すべきもの DiaryBaseモジュールには日記データのクラスに必要な幾つかのメソッドが 定義されています。DiaryBaseで定義されているメソッド以外に 日記データのクラスが備えるべきメソッドは下記のものになります。 (ここでいうメソッドは Public Instance Method のことです。) - initialize - append - to\_html - to\_src - style メソッドではありませんが、 インスタンス変数の @last\_modified には気をつけましょう。 日記データに変更があった場合に @last\_modified に適切なTimeオブジェクトを設定しないと、 キャッシュの更新がうまくいきません。 - @last\_modified #### initialize 日記データを初期化します。引数はIOクラスによって違うものになります。 このメソッドでは DiaryBase#init\_diary を呼ばなくてはなりません。 例 ``` class HogeDiary ..... def initialize(date, title, body, modified = Time::now) init_diary ..... end ..... end ``` #### append(body, author = nil) 日記本文を追加します。bodyは追加される日記本文です。 authorは日記を記述した人の名前で、文字列です。 authorの引数はデフォルトでnilにしなければなりません。 日記本文が変更された場合、日記本文を解釈し直す必要があります。 解釈し直す時には日記データを構成するセクションも変更されます。 #### each\_section each\_section は各セクションをブロックパラメータとして返します。 下に一例を示します。ここで@sectionsはセクションを保持するArrayのオブジェクトです。 ``` class HogeDiary ..... def each_section @sections.each |section| yield(section) end end ..... end ``` #### to\_src 日記の本文を返します。 #### style 日記データを記述するスタイル名を返します。 tDiary標準の記述形式の場合は「tDiary」です。 この文字列は、システム上は大小文字を区別しません。 セクションのクラス --------- 日記本文は幾つかのセクションに分かれます。 セクションは日記本文、セクションのタイトル、セクションを書いた人の名前 などをデータとして保持しています。 セクションクラスの例としては、tdiary/defaultio.rbにある TDiary::DefaultSectionクラスを参照してください。 ### 最低限実装すべきメソッド 以下にセクションのクラスが実装すべきメソッドを列挙します。 - subtitle - body - to\_src - author - subtitle\_to\_html - body\_to\_html カテゴリ機能に対応させるには、以下のメソッドを実装する必要があります。 - stripped\_subtitle - stripped\_subtitle\_to\_html - categories #### subtitleとsubtitle\_to\_html セクションのタイトルを文字列として返します。 タイトルがない場合はnilを返します。 subtitleはスタイルの文法で記述された本文を、subtitle\_to\_htmlはHTMLに変換後の本文を返します。 #### bodyとbody\_to\_html セクションに対応する本文を返します。返り値の文字列にはタイトルも著者も含まれません。 本文がない場合は空文字("")を返します。 bodyはスタイルの文法で記述された本文を、body\_to\_htmlはHTMLに変換後の本文を返します。 #### to\_src セクションに対応する本文を返します。返り値の文字列にはタイトルと著者が含まれます。 本文がない場合は空文字("")を返します。 #### author セクションを書いた人の名前を文字列として返します。 書いた人の名前がない場合は nil を返します。 #### stripped\_subtitleとstripped\_subtitle\_to\_html セクションのタイトルからカテゴリ指定部分を取り除いた文字列を返します。 タイトルがない場合や、カテゴリ指定部分を取り除いた文字列が空文字("")の場合は nilを返します。 stripped\_subtitleはスタイルの文法で記述された本文を、stripped\_subtitle\_to\_htmlはHTMLに変換後の本文を返します。 #### categories セクションのカテゴリを文字列の配列として返します。 タイトル中にカテゴリ指定がない場合は[]を返します。 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-make-plugin.md����������������������������������������������������������0000664�0000000�0000000�00000072725�13626457307�0020170�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������プラグインの作り方 ========= **※プラグインの使い方については、[HOWTO-use-plugin.html](HOWTO-use-plugin.html)を参照してください。** プラグインはtDiary 1.3.1以降で使えるようになった、システムに機能を追加する仕組みです。プラグインは[tDiary.org](http://www.tdiary.org/)から入手することができます。また、tDiaryフルセットを利用している場合には、misc/pluginディレクトリに単独に配布されているのと同等のものが含まれています。これらの.rbファイルを、ファイルごとインストール先にあるpluginディレクトリに移動することで、利用できるようになります。 プラグインにはさまざまなものがありますが、日記中に自動的に何かの文字列を埋め込んだり、特殊な処理をさせるのが主な目的です。また、特定のプラグインを作ることで、tDiaryのメッセージをカスタマイズすることもできます。 以下では、プラグインについてその「作り方」を説明します。なお、.rbファイルのことを「プラグインファイル」、実際に日記中で呼び出して使う機能(主にRubyのメソッド)のことを「プラグイン」と呼びます。ひとつのプラグインファイルは、複数のプラグインを含みます。 プラグインの種類 -------- プラグインは、Rubyのメソッドになっています。これらのメソッドはプラグインを実装するPluginクラスのメソッドとして読み込まれ、日記ファイル生成時の最後の段階で呼び出されます。プラグインメソッドは文字列を返し、それがそのまま日記に埋め込まれることになります。 制作側から見たプラグインは、3種類あるように見えます。ひとつはカスタマイズ系プラグインです。これらは日記の特定の場所にすでに埋め込まれていて、日記生成時に強制的に呼び出されます。デフォルトプラグインにおいてすでに定義されていて、同名のプラグインを再定義することで動作を変更することができるものです。各種メッセージや、日付・段落アンカー、HTMLヘッダを生成するプラグインがこれにあたります。 2種類目のプラグインは、完全にオリジナルのプラグインです。ヘッダやフッタ、日記本文に日記著者が意図的に記述することで呼び出されます。これらはデフォルトでは未定義で、既存のプラグインと名前がだぶらない限り好きな名称にできます。プラグイン集に収録されているプラグインは、たいていこれです。 3種類目のプラグインはコールバック系プラグインです。これは呼び出される場所が決まっている点でカスタマイズ系プラグインに似ていますが、メソッドにはなっておらず、文字列を返すブロックを追加していく形で定義します。更新時だけに呼び出されるプラグインや、日記本文の前後に呼び出されるプラグイン、HTMLヘッダを追加するプラグインが定義できます。 以降で、これらそれぞれのプラグインの作り方について説明します。 カスタマイズ系プラグイン ------------ 日記本文に現れるメッセージや文字列の多くは、プラグインによって差し込まれています。それぞれのメッセージに対応するプラグインを再定義することで、メッセージをカスタマイズできるのです。プラグイン作成のうちもっとも簡単なこのカスタマイズをこれから見ていきます。 カスタマイズ可能な文字列は、デフォルトプラグインとしてあらかじめ以下のように定義されています。 ``` def no_diary; "#{@date.strftime( @conf.date_format )}の日記はありません。"; end def comment_today; '本日のツッコミ'; end def comment_total( total ); "(全#{total}件)"; end def comment_new; 'ツッコミを入れる'; end def comment_description; 'ツッコミ・コメントがあればどうぞ! E-mailアドレスは公開されません。'; end def comment_description_short; 'ツッコミ!!'; end def comment_name_label; 'お名前'; end def comment_name_label_short; '名前'; end def comment_mail_label; 'E-mail'; end def comment_mail_label_short; 'Mail'; end def comment_body_label; 'コメント'; end def comment_body_label_short; '本文'; end def comment_submit_label; '投稿'; end def comment_submit_label_short; '投稿'; end def comment_date( time ); time.strftime( "(#{@date_format} %H:%M)" ); end def referer_today; '本日のリンク元'; end def navi_index; 'トップ'; end def navi_latest; '最新'; end def navi_update; "更新"; end def navi_preference; "設定"; end def navi_prev_diary(date); "前の日記(#{date})"; end def navi_next_diary(date); "次の日記(#{date})"; end ``` これらのメソッドを再定義することで、別の文字列を埋め込むことが可能です。モバイルモード向けにも用意されています。詳しくは00default.rbを参照してください。 まず、自分のカスタマイズ用プラグインファイルを用意します。pluginディレクトリに、例えば「custom.rb」という名前でファイルを作ります。自分の日記の雰囲気には「ツッコミ」という言葉がしっくり来ないという場合を想定して、これらを書き換えることにしましょう。ツッコミという言葉を使っている4つのメソッドをcustom.rbにコピーして、「コメント」という言葉に置き換えます。 ``` def comment_today; '本日のコメント'; end def comment_new; 'コメントを入れる'; end def comment_description; 'コメントがあればどうぞ! E-mailアドレスは公開されません。'; end def comment_description_short; 'コメント'; end ``` これだけでOKです。日記を表示して、変化していることを確認しましょう(スーパーリロードしないと変化しないかも知れません)。 他にも、カスタマイズ用プラグインとして「theme\_url」が用意されています。 ``` def theme_url; 'theme'; end ``` このプラグインは、テーマファイルが置かれているURLを指定するものです。通常はインストール先のthemeディレクトリなのでこのままで大丈夫ですが、同一サーバで複数の日記を運用している場合など、テーマファイルを一か所に集めたい場合には、これを使わないとテーマが読み込まれません。 カスタマイズするときは、「'theme'」の代わりにテーマファイルのあるディレクトリのURLを指定します。URLの最後を「/」で終わってはいけません。 このほかにも、navi\_userやnavi\_adminを再定義することで、ナビゲーションボタンのラベルを変更することもできます。また00default.rbにはこれ以外にも、HTMLのヘッダの情報生成や、日付・段落アンカータグを生成する以下のようなプラグインが定義されています(詳しくはコードを読んでください)。 - author\_name: 著者名を示すmetaタグを生成 - author\_mail: 著者のメールアドレスを示すmetaタグを生成 - index\_page: INDEXを示すmetaタグを生成 - css\_tag: スタイルシートの利用を指示するタグを生成 - title\_tag: titleタグを生成 - anchor: アンカータグを生成する オリジナルプラグインの実装 ------------- 以下では、Rubyのコードが書ける人を対象に、オリジナルのプラグインを実装する方法を解説します。と言っても、文字列を返すメソッドを書くだけなので難しいことはありません。ここでは、プラグイン内で利用できるインスタンス変数の解説だけ行います。 プラグインは専用のPluginクラスの内部で実行されるので、その中にある変数にしかアクセスできません。tDiaryの他の部分に影響が出ないようになっています。もっとも、evalを使って再定義してしまうことで、いくらでも自由になるのですが。 Pluginクラスのインスタンス変数には以下のものがあります。 <table><tr><th>変数名</th><th>説明</th></tr><tr><th>@mode</th><td>現在動作中のモードを表現する文字列です。tdiary.rb中で使われているTDiaryクラスの策クラス名から、TDiaryを取って、downcaseしたものが含まれています。上手に利用するにはtDiaryの内部構造を知っている必要があるでしょう(いずれちゃんと説明書きます。すまぬ)</td></tr><tr><th>@conf</th><td>TDiary::Configクラスのインスタンスで、tdiary.confから読み込んだ設定値が入っています。「@conf.index」のようにアクセスできます。</td></tr><tr><th>@diaries</th><td>日記データを保持するDiaryインスタンスのHashです。現在表示対象になっている日付を含む月全体が含まれます(最新表示で月をまたいでいる場合は、2ヶ月分含まれることがあります)。Hashのキーは「yyyymmdd」形式の日付で、Hashの値がDiaryインスタンスです。</td></tr><tr><th>@cgi</th><td>CGIクラスのインスタンスで、現在実行中のCGIに渡されてきたパラメタやCookieのデータが含まれています。スクリプトのパスや、パラメタの値を取得したい場合に利用できます。。</td></tr><tr><th>@years</th><td>現存するすべての日記の年月データを保持するHashです。キーは年、値は月のArrayです。</td></tr><tr><th>@cache\_path</th><td>キャッシュファイルのあるディレクトリ。プラグインでキャッシュを使いたい場合は、ここに独自のディレクトリを掘って利用します。</td></tr><tr><th>@date</th><td>現在表示中の日付。特定の日か、月を表現したものかどうかは、@modeを見なければ判断できません。</td></tr><tr><th>@plugin\_files</th><td>プラグインファイル名(フルパス)が読み込まれた順に入ったArrayインスタンスです。現在の稼働中のシステムで、どのようなプラグインが利用可能かを知る指標として使えます。</td></tr><tr><th>@last\_modified</th><td>現在表示しようとしているページの最終更新時刻が入ったTimeオブジェクトです(HTTPヘッダで返るものと同じ)。ただし、更新ページの場合など、この値が意味を持たない場合にはnilになります。</td></tr><tr><th>@debug</th><td>プラグイン開発時のデバッグ用フラグです。この値をメソッド内でtrueにすると、プラグイン実行時に存在しないメソッドを呼んでもエラーになります(通常時には無視されています)。この変数を利用するのはプラグイン開発時のみにとどめ、プラグイン配布時には必ず削除してください。</td></tr></table> コールバック系プラグイン ------------ 上で説明した、単に文字列を返すメソッドを定義してそれを日記本文に埋め込んで使うだけのプラグインと違い、特定の状況でのみ呼び出されるようなコールバック系プラグインがあります。tDiaryの機能を拡張するために利用できます。以下にその作り方を解説します。 コールバック系のプラグインは現在、以下の4種類定義されています。 - update\_proc: 日記更新時およびツッコミ追加時に呼び出される - header\_proc: HTMLヘッダ情報の生成時に呼び出される - body\_enter\_proc: 日記本文開始の直前で呼び出される。パラメタに処理中の日記の日付(Timeインスタンス)が与えられる - subtitle\_proc: セクションのサブタイトルを表示する局面で呼び出される。セクションアンカーを付与するなど、サブタイトルを装飾するためのプラグイン - body\_leave\_proc: 日記本文終了の直後に呼び出される。パラメタに処理中の日記の日付(Timeインスタンス)が与えられる - footer\_proc: footer生成時に呼び出される - section\_enter\_proc: セクションの開始(サブタイトルの直前)で呼び出される。パラメタに処理中の日記の日付(Timeインスタンス)とセクションの番号(1〜)が与えられる - section\_leave\_proc: セクションの終了直後に呼び出される。パラメタに処理中の日記の日付(Timeインスタンス)とセクションの番号(1〜)が与えられる - edit\_proc: 更新フォームの内部で呼び出される。更新フォーム内に新たなアイテムを追加する時に使う。パラメタに処理中の日記の日付(Timeインスタンス)が与えられる。追加したアイテムのname属性は、必ず「plugin\_プラグイン名\_アイテム名」になっていなくてはならない - comment\_leave\_proc: ツッコミの直後に呼び出される。パラメタに処理中の日記の日付(Timeインスタンス)が与えられる - form\_proc: 更新フォームの次に呼び出される。更新フォームとは別のフォームなどを追加するときに使う。パラメタに処理中の日記の日付(Timeインスタンス)が与えられる。フォームを追加した場合、submitボタンには必ず「plugin」というname属性を付ける必要がある - conf\_proc: 設定画面で呼び出される。プラグインのオプション設定をWebから行うためのプラグイン - title\_proc: 日ごとのタイトルを表示する局面で呼び出される。日付をリンクにするなど、タイトルを装飾するためのプラグイン いずれも通常のプラグインと同様にメソッドとして実装されていますが、上書き定義してはいけません。上書きすると、この機能を使っている他のプラグインが呼び出されなくなってしまうためです。 このため、これらのプラグインには機能を追加するためのメソッド、add\_XXX\_proc(XXXは各プラグインの名称が入る)が用意されています。これらはブロックを受けとります。ここで登録されたブロックが順番に呼び出されることで、複数のプラグインが実行されます。また、conf\_procに対応するadd\_conf\_procは後述するようにキーワードとラベル文字列を引数に取り、必要な時だけ呼び出されます。 これらのプラグインは、一般的に以下のように定義して使います。ブロックの返り値が、プラグインの値になります。 ``` # 検索キーワードをheadに挿入する add_header_proc do '<meta name="keyword" content="foo,bar,baz">' end ``` デフォルトプラグインファイルである00default.rbには、標準のHTMLヘッダを生成するheader\_proc用ブロックが定義されています。 なお、コールバック系プラグインはそれぞれのブロックが返した文字列をすべて連結してHTMLに埋め込みますが(ただし後述するtitle\_procとsubtitle\_procは連結しません)、update\_procは何も埋め込みません(意味がないので)。このため、update用に追加するブロックは何も返す必要はありません。 body\_enter\_procとbody\_leave\_proc、edit\_proc、form\_procは、現在対象にしている日記の日付がブロックパラメタとして受け取れるようになっているので、以下のように指定する必要があります。 ``` # 最終更新日を表示する add_body_enter_proc do |date| diary = @diaries[date.strftime( '%Y%m%d' )] "#{diary.last_modified( "%Y-%m%-d" )}" end ``` section\_enter\_procとsection\_leave\_procはbody\_enter\_procによく似ていますが、ブロックパラメタにセクションの通し番号(1〜)が加わっています。 ``` # Permalinkを表示する add_section_enter_proc do |date, index| "#{@index}#{anchor( date.strftime( '%Y%m%d' ) + '#p' + sprintf( '%02d', index )}" end ``` また、title\_procとsubtitle\_procはそれぞれ、日付・タイトル、日付・インデックス・サブタイトルがブロックパラメタとして渡されます。また、渡されたタイトルやサブタイトル文字列は、直前に登録されていた同じプラグインによってすでに装飾されているため、それに情報を付加して返さなくてはなりません。 ``` # タイトルの末尾にリンクを付加する add_title_proc do |date, title| return title + '<a href="hoge">link</a>' end # サブタイトルの末尾にリンクを付加する add_subtitle_proc do |date, index, subtitle| return subtitle + '<a href="hoge">link</a>' end ``` title\_procやsubtitle\_procも、00default.rb内にいくつかの標準的なプラグインが定義されています。メソッドとして独立しているので、メソッドを丸ごと上書きすることで、標準の挙動を変更することも可能です。 また、単独では意味のないコールバック系プラグインがあります。edit\_procです。edit\_procは更新フォーム内に文字列を埋め込むためのプラグインですが、これによって更新フォームに任意のアイテムを追加できます。このアイテムに入力された値は、別途update\_proc内で受けとる必要があるでしょう。 ``` # name属性には「plugin_プラグイン名_アイテム名」を付けなければならない add_edit_proc do |date| 'Hoge: <input name="plugin_hoge_item1">' end # 更新時に値を受け取れる add_update_proc do if /^(append|replace)$/ =~ @mode hoge = @cgi.params['plugin_hoge_item1'][0] end end ``` 一方、同じフォーム追加を目的としたform\_procではこのようにする必要はなく、同じform\_proc内で入力を受けとることができます。 他のコールバック系プラグインとは少しおもむきが異なるのが、add\_conf\_procです。以下のように呼び出します。 ``` add_conf_proc( 'hoge', 'hogeの設定', 'etc' ) do # 設定の保存 if @mode == 'saveconf' @conf['hoge.fuga'] = @cgi.params['hoge.fuga'][0] end # 設定画面の出力 fugaの指定 <<-HTML <h3>fugaの指定<h3> <p><input name="hoge.fuga"></p> HTML end ``` 1つ目の引数は、複数のconf\_procの中からどれを表示するか選ぶために、全プラグイン内で一意になるようにつけるキーワードです。一般的にはプラグインの名称をつけます。2番目の引数は設定画面の一覧を表示するときに使うラベル文字列です。言語によって変更させます。3番目の引数は、プラグインのジャンルで、無指定の場合は'etc'になります。ジャンルには現在、以下が定義されています。 - basic: 基本的な設定項目 - theme: テーマ関連 - tsukkomi: ツッコミ関連 - referer: リンク元関連 - security: セキュリティ関連 - etc: その他 @modeが'saveconf'の時のみ、@cgi経由で渡された設定を保存します。保存先は@conf[]にオプション用のキーワードを指定して代入します。これは従来tdiary.confにて、@optionsとして指定したものと同じです。なお、conf\_procで保存できるオプションは、文字列(String)、整数(Integer/Fixnum)、真偽値(TrueClass/FalseClass)、nil(NilClass)で表現されるオブジェクトだけです。 conf\_procを使って設定を保存すると、その後はtdiary.confによる@optionsは効かなくなるので注意が必要です。 プラグインが生成するHTML -------------- プラグインは一般的に文字列を返すことでその文字列が日記に埋め込まれるわけですが、多くの場合その文字列はHTMLの断片になります。このHTML断片は以下のルールに従うようにしてください。 - HTML 4.01 Strictに準拠する。tDiaryはHTML 4.01 Strictに準拠したHTMLを生成します。このため、プラグインもそれに倣う必要があります - 独自のクラス名(HTMLタグのclass属性)を生成する場合には、テーマ上での指定時に汎用性を持たせるために「プラグイン名-クラス名」のような形式にすることを強く推奨します 古いプラグインでは2番目の条件に従っていない場合が少なくありませんが、新規に作成する場合には遵守するようにしてください。 Pluginクラスのメソッド -------------- プラグインは、TDiary::Pluginクラスのインスタンス内に定義された特異メソッドとして動作します(コールバックは除く)。そのため、すでにPluginインスタンス中で定義されているメソッドは、プラグインから自由に呼び出すことが可能です。例えばあるプラグインの機能を別のプラグインから通常のメソッド呼び出しの形式で利用できるわけです。 この他に、Pluginクラスには以下のようなメソッドが用意されています。通常はPluginクラス外へ影響を及ぼせないプラグインですが、これらのメソッドを使うことでそれが一部可能になっています。 <table><tr><th>メソッド名</th><th>説明</th></tr><tr><th>add\_cookie( cookie )</th><td>Webブラウザに返すCookieを追加します。プラグインから何らかの情報をWebブラウザ側に保持しておいて欲しい時に使います。引数cookieはCGI::Cookieインスタンスです。なお、逆にCookieを受けとる時は、@cgiインスタンス変数から取得してください。</td></tr><tr><th>apply\_plugin( str, remove\_tag )</th><td>プラグイン内で生成した文字列の中に、さらにプラグイン呼出しの指定がある場合、もう一度プラグインの呼出しを行います。第二引数をtrueにすると(省略可能でデフォルトはfalse)、さらにHTMLタグを削除します。</td></tr><tr><th>shorten( str, limit )</th><td>文字列strをlimitで指定されたバイト数に切り詰めます。切り詰められた場合には末尾に「...」が付加されます。プラグイン内で生成した文字列の表示文字数を制限したい場合に使います。</td></tr><tr><th>add\_XXX\_proc( proc )</th><td>コールバック系プラグインを追加するメソッド。「XXX」にはheader、update、body\_enter、body\_leave、footerなどが入る。引数procにはProcインスタンス、もしくはブロックを与える。</td></tr><tr><th>enable\_js( script\_file\_name, async: false )</th><td>jsディレクトリ配下にあるJavaScriptを有効にする(例: 'amazon.js')。このメソッドで有効にしたファイルは、HTMLヘッダ内に呼び出された順番に埋めこまれます。asyncオプションをtrueにすると(省略可能でデフォルトはfalse)、ファイルは非同期で読み込まれ実行順は不定となります。他プラグインに依存しないファイルはasync: trueとすることで日記本体を早く表示することができるでしょう。</td></tr><tr><th>add\_js\_setting( var, val )</th><td>enable\_jsで埋めこまれたJavaScriptへのパラメタを受け渡す。「var」には変数名を与えます。標準では「$tDiary.plugin.プラグイン名.変数名」で、「$tDiary.plugin」までは名前空間としてtDiary側で確保済みです。「val」には変数に与える値をJavaScriptとして有効な形の文字列で指定します。例えば「abc」という文字列であれば「"'abc'"」のようにする必要があります。</td></tr></table> プラグインへのオプションの渡し方 ---------------- プラグインはRubyのメソッドですから、呼び出し時に引数を指定することで、利用者がプラグインの挙動を変更することが可能です。しかし、tdiary.conf等で日記管理者が強制的にオプションを指定したい場合があります。そのようなプラグインを作成する時には、tdiary.confで指定できる@options変数を使うことができます。 @option変数は、プラグインから@conf[]を経由して見ることができるで、tdiary.confで任意の文字列をキーとして定義すれば、それをプラグイン内で利用することが可能です。@optionsのキーに指定する文字列はなんでもかまいませんが、名前の重複を避けるためにプラグイン名とオプション名を「.」で区切ったものを推奨します。 ``` # sampleプラグインにhogeオプションを指定する(tdiary.conf内) @options['sample.hoge'] = 'foobar' ``` ``` # sampleプラグイン内でオプションを取得する(sample.rb内) hoge = @conf['sample.hoge'] ``` またconf\_procプラグインを使うことで、この変数の値をWeb上から対話的に設定できるようにもできます。詳しくはコールバック系プラグインの説明を参照してください。 なお、この仕組みはプラグイン制作者側には便利ですが、ファイルを設置するだけで使えるようになるプラグインの簡便さを削いでしまう可能性もあります。できるだけ@optionsが設定されていなくても動作するように、適切なデフォルトを用意するようにして下さい。 CSRF 対策とプラグインの関係 ---------------- tDiary 2.0.2、2.1.2 以降、クロスサイトリクエストフォージェリ (CSRF) 攻撃に対する防御機構が実装されました。CSRF 攻撃の被害を防ぐためには、 プラグインも含む Web アプリケーション全体が防御策を実装していなければ なりません。tDiary では、個々のプラグイン作者が対策手法の詳細を意識しな くても、全体として一体的な防御策がとられるよう配慮されていますが、 正しく防御機構を動作させるためには、プラグインの作者も若干の 注意が必要となります。具体的には、次の3点に注意して実装を行ってください。 1. 副作用を含む設定動作には conf モードを使わない tDiary の設定、動作などに何らかの影響を加えるページ(例えば、キャッシュの消去)などは、 conf モードではなく、必ず saveconf モード内で実装して下さい。conf モードの ページに関しては、CSRF 対策が働きませんので、外部から攻撃される可能性が あります。 なお、当然のことですが、日記の読者が行う動作(例えば、ツッコミ)などには 対策は必要ありません。 2. formplugin モードで動作させるためのフォームには CSRF 対策鍵を埋め込む form\_proc 内などで、plugin モードで動作させる機能のためのフォームを 生成する場合(例えば、絵日記プラグインの「画像をアップロード」フォーム)、 POST メソッドのフォーム内で csrf\_protection メソッドの呼び出し結果を埋め込んで下さい。 CSRF 鍵が設定され使われている場合に限り、 CSRF 対策キーが hidden 項目で埋め込まれます。 標準の絵日記プラグイン (image.rb) などが対策済みですので そちらを参考にして下さい。 この対策を忘れた場合、CSRF 対策鍵を利用するモードでのみ プラグインが動作しなくなります。デフォルトの設定では 問題なく動作してしまいますので、プラグイン作者は CSRF 鍵もチェックに利用する設定 (@options['csrf\_protection\_method'] = 3) にして動作確認することをお勧めします。 当然のことですが、自分の日記の update.rb に送付するフォーム以外には、 絶対に CSRF 対策鍵を埋め込んではいけません。 なお、この鍵を埋め込まれたフォームは、必ず POST メソッドで送信される必要 があります (Referer ヘッダ経由で外部に漏出することを防ぐため)。 プラグインの誤実装による CSRF 鍵の漏洩を防ぐため、 tDiary は、update.rb に GET メソッドで CSRF 対策鍵が送られてきた場合、 すべての要求を拒否するようになっています。 edit\_proc と conf\_proc で動作する機能に関しては、 フォームに既に対策鍵が埋め込まれていますので、 本項の対策は必要ありません。目安としては、 <form method="post" action="#{@conf.update}"> のような文字列を自分で出力している場合が該当すると思ってください。 3. 実動作を伴うページへの送信は必ず POST で plugin, saveconf, preview系, 更新系 の各ページは、 CSRF 鍵を必要とする場合があるため、POST 以外でのリクエストを 拒絶するようになっています。もし plugin ページを GET で呼び出している場合は POST メソッドを利用するよう (そして 2. の対策をするよう) 変更して下さい。 場合によっては、リンクをフォームに変更するなどの書き換えが必要かもしれません。 �������������������������������������������tdiary-core-5.1.1/doc/HOWTO-make-theme.md�����������������������������������������������������������0000664�0000000�0000000�00000015062�13626457307�0017763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������テーマの作り方 ======= テーマ作成に先だって ---------- テーマはtDiary 1.1.0以降で使えるようになった、日記の見栄えを簡単に変更する仕組みです。テーマはCSS(カスケーディングスタイルシート)で実現されているので、CSSの書き方がわかれば作ることができます。CSSの書き方についてはここでは述べません。このドキュメントでは、tDiaryのテーマを作るときの約束事だけを説明します。 tDiaryのテーマは、インストールディレクトリにあるthemeディレクトリに入っています。tDiary標準セットではDefaultだけ、フルセットではテーマ集にあるすべてのテーマが入っています。 テーマ作成の基本ルール ----------- tDiaryテーマには、以下のような基本的な約束事があります。もちろん、CSSであればなんでもかまわないのですが、themeディレクトリに配置してtDiaryの設定画面から選択したり、テーマ・ギャラリーに入るようなテーマにするなら、これらの約束事を守った方が良いでしょう。 - テーマの配置 - themeディレクトリの下にテーマ名のディレクトリを作成し、その下に関連するファイルをすべて納める - テーマ名は英小文字または数字で始まる英小文字・数字・「\_」「-」からつける。なお「\_」で単語を区切ると、tDiaryの設定画面の一覧で「\_」が空白に置き換えられることを覚えておいて損はない - テーマ名の文字数に制限はないが、あまり長くしすぎないように - (少なくとも公開する気があるのなら)テーマ集にまだ含まれていない名称をつけるべきである - そのテーマが表現するものを端的に表した名称が望ましい - CSSファイル名 - 個々のテーマのディレクトリ直下に「テーマ名.css」というファイル名で作成する - 最低限default.cssに含まれているエレメントは含むようにする(ただしプラグインに関する記述は任意)。後述する「テストベンチ」で確認すると良い - 関連ファイル(README、イメージファイルなど) - テーマに関連するファイルは、個々のテーマディレクトリにすべて納める - そのテーマの説明はREADMEというファイル名にする。このファイルの先頭に後述するフォーマットで簡単な説明を書いておくと、テーマ・ギャラリー掲載時にその内容が使われる - その他のファイル名に特に制限はないが、テーマの命名と同程度の規則を適用するのが望ましい。慣例として、イメージアンカーにはsanchor.png(セクション)、canchor.png(ツッコミ)の名称がよく使われる。 - エレメント - div.section(日記本文)で使われる文字サイズ(font-size)は、「100%」を強く推奨する。もちろん、親要素で文字サイズを指定していない場合には無指定でよい。また、ツッコミ等の読者によく読まれる可能性のあるエレメントでも、90%に満たない文字サイズの指定は推奨しない。 - div.mainとdiv.sidebarは、サイドバー(タイトルリスト等を入れる縦長のボックス)を実現するために用意されている。div.mainは本文用、div.sidebarはサイドバー用のエレメント。これらを定義しておくと、他のテーマと共通のやり方でサイドバーが設置できるようになる。 - もし、サイドバーの位置としてdiv.sidebarで指定したのと反対側にも出せるようにしたい場合には、div.main2、div.sidebar2を定義する。 なお、実際のエレメントやクラスがtDiary上で持つ意味は、付属のdefault/default.cssにコメントとして書かれていますので、参考にしてください。 テーマ・ギャラリー用の説明 ------------- tDiary.Netには、[テーマ・ギャラリー](http://www.tdiary.org/20021001.html)というページがあります。テーマ集に登録されたテーマはここでスクリーンショットともども一覧することができます。ここに表示されている作者名やコメントは、テーマ付属のREADME(1.4の時の名残でcssファイルも利用されている)に一定のフォーマットで書かれているものを自動的に抜き出しているものです。 最初からこのフォーマットで書いておくと、テーマ集に入った時に見栄えがします。以下にそのフォーマットについて解説します。 ``` Title: クローバー Author: ただただし Access: t@tdtds.jp License: GPL2 or any later version Comment: 四つ葉のクローバーの葉をあしらった、シンプルでかわいらしいテーマ 春向きのテーマです。 サイドバー対応。 calendar2、recent_list、footnote、amazonプラグイン対応。 ``` この説明は、READMEの最初の行から記述します。「キー」と「値」を「: 」で挟んだ形式で、1項目1行で書きます。日本語を書くときは、文字コードをUTF-8にして下さい。英語の説明があれば、README.enというファイルにしてください。 各項目の意味は以下のとおりです。なお、現在ギャラリーで利用されている項目はTitle、Author、License、Commentだけです。 - Title: テーマのタイトルです。ファイル名だけでは味気ないと思ったら、この項目を書いてください。なくてもかまいません。 - Author: 作者名 - Access: 作者の連絡先。メールアドレスか、URLを - License: ライセンス。記述しない場合はtDiaryと同じGPL2になります - Comment: このテーマに関する簡単な説明 これらのあとに空改行をあければ、それ以下には何を書いてもかまいません。レイアウト上のアドバイスや、作者の思い入れを語る等、好きなように使ってください。 テーマ・テストベンチ ---------- テーマの見え方を確認するための、[テストベンチ](http://www.tdiary.org/theme.sample.html)というページがあります。ギャラリーのスクリーンショットと異なり、こちらでは様々なエレメントの見え方や、代表的なプラグインの表示を確認することができます。テーマ作成時に利用してください。 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-testing-tDiary.md�������������������������������������������������������0000664�0000000�0000000�00000004530�13626457307�0020653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������How to testing tDiary ===================== 概要 -- tDiary-3.0.1.20101011 以降のバージョンでは tDiary を test するための仕組みがいくつか導入されています。具体的には以下の2点です。 - Capybara と steak を使った End-to-End のテスト方法 - RSpec2 による単体テスト方法 前者の方法は tDiary の内部構造に意識せずに、初期データからブラウザに表示される内容をテストする方法であり、後者の方法はプラグインや特定のメソッドをテストするたびに用いられる方法です。 テスト可能な tDiary 最終目標は cgi.rb に依存する仕組みから Rack のインタフェースに載せ替えた上で、tDiary の各モジュールに対してテストを実行できるようにすることです。 必要なもの ----- tDiary でテストを実行するためには以下の環境を用意する必要があります。 - Ruby 2.1.0 以降 - Bundler 1.3.5 以降 動かし方 ---- tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。 ``` bundle install ``` Ruby をインストールしているディレクトリへの書き込み権限がない場合は --path オプションを付けることで任意のディレクトリに依存 gem をインストールすることができます。 ``` bundle install --path ~/.bundle ``` bundler によるインストールが完了すると、tDiary でテストを実行できるようになります。以下のコマンドを実行すると、tDiary に付属しているテストが全て実行されます。 ``` bundle exec rake spec ``` テストのディレクトリ構成と Rake タスク ---------------------- tDiary に用意されているテストは以下の3種類で構成されています。この構成は今後も変更される可能性もあるので、Rake -T コマンドを実行して Rake タスクの内容を確認するようにしてください。 - spec:core: core(tDiary本体)に関わるテストを実行します。 - spec:plugin: misc/plugin 配下に存在するプラグインファイルのテストを実行します。 - spec:acceptance: 日記の作成や削除について、HTTPリクエストからデータの保存までの End-to-End のテストを実行します ������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-use-plugin.md�����������������������������������������������������������0000664�0000000�0000000�00000025500�13626457307�0020034�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������プラグインの使い方 ========= **※プラグインの作り方については、[HOWTO-make-plugin.html](HOWTO-make-plugin.html)を参照してください。** プラグインはシステムに簡単に機能を追加する仕組みです。プラグインは[tDiary.org](http://www.tdiary.org/)から入手することができます。また、tDiaryフルセットを利用している場合には、misc/pluginディレクトリに単独に配布されているのと同等のものが含まれています。これらの.rbファイルを、ファイルごとインストール先にあるmisc/pluginディレクトリに移動することで、利用できるようになります。 プラグインにはさまざまなものがありますが、日記中に自動的に何かの文字列を埋め込んだり、特殊な処理をさせるのが主な目的です。また、特定のプラグインを作ることで、tDiaryのメッセージをカスタマイズすることもできます。 以下では、プラグインについてその「使い方」「プラグイン集について」を説明します。なお、.rbファイルのことを「プラグインファイル」、実際に日記中で呼び出して使う機能(主にRubyのメソッド)のことを「プラグイン」と呼びます。ひとつのプラグインファイルは、複数のプラグインを含みます。 プラグインの使い方 --------- プラグインを使うには、そのプラグインを含んだプラグインファイルが、tDiaryインストール先にあるmisc/pluginディレクトリになければなりません。あらかじめ使いたいプラグインファイルをmisc/pluginディレクトリにコピーしておく必要があります。その上で、設定画面のプラグイン選択にて使いたいプラグインを有効にしましょう。プラグインの中には高機能で処理に時間のかかるものも含まれているので、必要でないプラグインまでコピーすると、日記の表示が遅くなったりします。必要なプラグインだけを使うように、きちんと選択してください。 プラグインは、eRubyと呼ばれる文法を使って、日記のタイトルや本文、ヘッダやフッタに埋め込むことで利用できます。日記本文で使う場合には、使っている記法によってプラグインの呼び出し方が異なります。「calendar」や「navi」というデフォルトプラグインは、すでにヘッダの中で使っているので見たことがあるでしょう。プラグインの機能を日記に埋め込むときのもっとも簡単な書式は以下のとおりです。 tDiaryスタイルおよびヘッダ/フッタで使う場合: ``` <%=プラグイン名%> ``` Wikiスタイルの場合: ``` {{プラグイン名}} ``` たとえば、カレンダーを埋め込むプラグイン「calendar」は、以下のようにして記述します。 tDiaryスタイルおよびヘッダ/フッタで使う場合: ``` <%=calendar%> ``` Wikiスタイルの場合: ``` {{calendar}} ``` プラグインの種類によっては、以下のようにパラメタを指定して動作を変えることもできます。 ``` <%=プラグイン名 パラメタ1, パラメタ2, ...%> ``` 各プラグインがどのようなパラメタを利用できるかは、プラグイン選択画面のリンクからたどれるヘルプを見るか、[tDiaryドキュメント](https://github.com/tdiary/tdiary-docs-ja/wiki)から探せます。また、プラグインによっては、上記のような呼び出しが不要で、プラグイン選択で有効にするだけで動作するものもあります。 プラグインを使えるのは、日記のタイトルと本文、およびヘッダとフッタです。すべてのページに表示したい場合にはヘッダかフッタを、その日の日記にだけ使いたい場合にはタイトルや本文に使います。また、ツッコミには使えません。 プラグインのカスタマイズ ------------ 呼び出し時のパラメタを使う以外に、設定画面やtdiary.conf内でオプションを指定する方法でカスタマイズができるものもあります。主に、コピーするだけで動くプラグインの動作を変えたり、パラメタを指定しない時の挙動を変更する場合に使います。設定画面でカスタマイズできるプラグインは、有効にしたあとに設定画面のメニューが増えます。 tdiary.confでのオプションの指定には、@optionsという変数を使います。例えば、hogeというプラグインのfugaというパラメタをカスタマイズするには、以下のような指定方法を使います。 ``` @options['hoge.fuga'] = 'なんとか' ``` どのようなパラメタが指定できるかは、プラグインのドキュメントに書かれています。 また、多くのプラグインで共通に使われるオプション指定がいくつかあります。 まず、apply\_pluginというパラメタは、プラグインが展開したあとの文字列にさらにプラグイン呼び出しの指定があった時に、それをもう一度展開するかどうかを指定するパラメタです。 ``` @options['apply_plugin'] = true ``` 無指定時には再展開はしないようになっているので、apply\_pluginに対応したプラグインで再展開機能を使いたい場合には上記の指定をtdiary.confに書いておく必要があります。 さらに、botというパラメタもあります。これは、検索エンジンの巡回ロボットが、「本日のリンク元」を見て本文と無関係な検索キーワードを拾うのを防ぐためのものです。値には巡回ロボットのUser-Agentの配列を指定しますが、主要なロボットは登録済みなので、これをいじる必要はあまりないでしょう。 ``` @options['bot'] = ['GoogleBot', 'Hatena Antenna'] ``` 企業内にtDiaryを設置する場合に、インターネット上のサービスを利用するいくつかのプラグインやフィルタが、プロクシを経由しないと動作しない場合があります。このときに利用できるパラメタにproxyがあります。このオプションには、プロクシサーバのホスト名とポート番号を「:」で区切って指定します。 ``` @options['proxy'] = 'proxy.example.com:8080' ``` デフォルトプラグインの説明 ------------- 「デフォルトプラグイン」というプラグインファイル「00default.rb」がすでにpluginディレクトリに置いてあります。まず、これらのプラグインについて説明します。 ### naviプラグイン 日記ページの先頭にある、「トップ」「最新」「更新」などのナビゲーションボタンを表示するためのプラグインです。パラメタはありません。ヘッダやフッタに埋め込むことで、ページによって最適なボタンを表示します。このプラグインをどこかに埋め込んでおかないと、日記の更新ができなくなってしまいます。 ※もしnaviプラグインを埋め込み忘れてしまい、日記の更新ができなくなってしまったら、日記のURLの後ろに「update.rb」(環境によっては「update.cgi」など)を付けて呼び出してみましょう。更新ページが表示されます。 ※naviプラグインは、更新や設定のページに内部的に埋め込まれています。もとの挙動を大きく変えるような改造をすると、操作性を大きく損ねるおそれがあるので注意してください。 ### navi\_userプラグイン naviプラグインから内部的に呼び出されているプラグインですが、単独で使うこともできます。このプラグインは、ナビゲーションボタンのうち、日記閲覧者にのみ必要なボタン(「トップ」「最新」「」)を表示します。これを使うことで、「更新」のような日記オーナーにだけ必要なボタンを表示させないなどのカスタマイズを行えます。 パラメタはありませんが、naviプラグインを使う場合に比べて、前後のPタグが省略されるので、以下のようにして埋め込むと良いでしょう。 ``` <p class="adminmenu"><%=navi_user%></p> ``` ### navi\_adminプラグイン navi\_userプラグインと反対に、管理用に必要なボタン「更新」「設定」を表示します。使い方はnavi\_userと同じです。 ### calendarプラグイン カレンダーを表示します。日記が書かれている月のみをリストします。ヘッダやフッタに埋め込んで使います。パラメタはありません。このプラグインをどこかに入れておかないと、日記閲覧者は過去の日記を読むことができなくなってしまいます。 ### insertプラグイン 外部ファイルを日記に読み込みます。主な用途は、ヘッダやフッタに、すでにある定型ファイルを挿入したいような場合です。そのままの形で埋め込むので、挿入するファイルはHTMLでなければなりません。パラメタとしてひとつのファイル名をとるので、以下のように使います。 ``` <%=insert 'menu.html'%> ``` ### myプラグイン 日記本文中で、自分の日記内へのリンクを簡単に作成します。[...](〜)とやってもよいのですが、こちらの方がサーバの引っ越しやmod\_rewriteを利用してURLを変更した場合などに強くできます。 最初のパラメタにリンク先の日付とアンカーを「YYYYMMDD#pXX」(YYYY年MM月DD日のXX番目のセクション)や「YYYYMMDD#cXX」(YYYY年MM月DD日のXX番目のツッコミ)のような形式で指定します。2番目のパラメタには、リンクにする文字列を指定します。3番目のパラメタには、必要であればリンクタイトルを指定できます。 ``` <%=my '20020301#c01', 'そのツッコミ' %>はひどい。 ``` プラグイン集について ---------- 続いて、プラグイン集について説明します。プラグイン集は、tDiaryユーザが作った数々のプラグインを集めたものです。tDiaryフルパッケージをインストールした場合にはmisc/pluginディレクトリにありますし、そうでない場合にも[tDiary.org](http://www.tdiary.org/)から入手することができます。これらのプラグインファイルは、は自分でmisc/pluginディレクトリにコピーして利用します。 それぞれのプラグインの詳しい使い方は、各プラグインのドキュメントを読んでください。 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-write-tDiary.en.md������������������������������������������������������0000664�0000000�0000000�00000015121�13626457307�0020727�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tDiary -- How to write diary ============================ Index ----- - Format of the diary in tDiary - Tips Format of the diary in tDiary ----------------------------- Basically, you write your diary in HTML. But, the format of the diary has extra rules in order to write your diary without knowledge of HTML. In this format, a linefeed and a character at the beginning of the line have special meanings. These rules are for the purpose of setting sub-title and paragraph easily. The rules are explained below. To distinguish a linefeed in appearance(HTML) from an actual linefeed(format), "$" stands for an actual linefeed in this manual. ``` sub-title(1)$ Like the above, the first line becomes a sub-title. With the tDiary's standard style sheet, the sub-title is displayed in bold face. Lines from the sub-title to the next space line are called section, and a section anchor is added in front of the sub-title. $ Lines after the sub-title, like this line and the line just above, are recognized as normal lines. If a paragraph begins with a sub-title, a section anchor is not attached in front of normal lines.$ $ If a space line exists, the line means the separation of the sections. If space exists in front of the line like this line, the section doesn't have a sub-title. In addition, only the first paragraph has a section anchor. In this case, the line is not shown in bold face.$ If a section doesn't begin with a sub-title, the second and later paragraphs don't have an anchor.$ $ ``` $ If the paragraph begins with a line whose first character is "$ $ sub-title(2)$ As the result of it, you can't add a sub-title which begins with a HTML tag to a section. But if a line begins with "_This example is formatted below._ [2001-08-03](./?date=20010803)title ----- ### [_](./?date=20010803#p01)sub-title(1) Like the above, the first line becomes a sub-title. With the tDiary's standard style sheet, the sub-title is displayed in bold face. Lines from the sub-title to the next space line are called section, and a section anchor is added in front of the sub-title. Lines after the sub-title, like this line and the line just above, are recognized as normal lines. If a paragraph begins with a sub-title, a section anchor is not attached in front of normal lines. [_](./?date=20010803#p02) If a space line exists, the line means the separation of the sections. If space exists in front of the line like this line, the section doesn't have a sub-title. In addition, only the first paragraph has a section anchor. In this case, the line is not shown in bold face. If a section doesn't begin with a sub-title, the second or later paragraphs don't have an anchor. ``` If the paragraph begins with a line whose first character is " ### [_](./?date=20010803#p04)[sub-title(2)](foobar) As the result of it, you can't add a sub-title which begins with a HTML tag to a section. But if a line begins with " ``` In tDiary, users can write their diary without HTML if they don't need to decorate their diary. At the same time, users who are familiar to HTML can write full functions of HTML in their diaries. But, If you use HTML tags in your diary, it is better to read the next section, Tips, to avoid pitfalls of tDiary. Tips ---- ### want a section to include a line which has a tag. For example, you want to use tag in your diary in order to use a list and don't want to change a section. Like this case, if you want to decorate the whole paragraph with html tags, you need to use a trick in tDiary. For instance, you hope that your diary is formatted like the next example. [2001-08-29](./?date=20010830) ---------- ### [\_](./?date=20010829#p01)sub title Like this, you write a list which has two items. - item1 - item2 Here is in the same sectionOne way is to merge a paragraph with the previous paragraph. Ordinarily, a paragraph is enclosed by -tag(you can confirm it if you read the HTML source created by tDiary.). You take advantage of this. ``` sub-title Like this, you write a list which has two items. ``` - item1 - item2 Here is in the same section$ It is the point not to put a linefeed. This way is usable if a paragraph enclosed by a tag is not composed of plural lines. But, this is a little difficult to read. In the way above, you take advantage of the fact that a paragraph is enclosed by in tDiary. On the contrary, another way is to take advantage of the fact that tag is not inserted to a section if the section has a line which begin with a tag. In the next example, tDiary insert no tag into a section because the section has a line which begins with "- , except a list. ``` sub title$ Like this, you write a list which has two items. $ ``` $ - item1 $ - item2 $ $ Here is in the same section. $This way is suitable if a paragraph enclosed by tags is plural. For example, you insert source code with ``` tag.Of course, if you don't mind the fact that the sections are split, you are not bothered with formatting. In this case, it may be better to write like the next example. ``` sub title$ Like this, you write a list which has two items.$ $ ``` ``` $ - item1 $ - item2 $ $ $ Here is in the same section.$The last line, "Here ...", has a section anchor, but this is not a big problem. ### You want to insert an anchor per paragraph, not section tDiary is developed under the policy that it is not necessary to insert an anchor to a paragraph. So, basically, you can't insert an anchor to a paragraph. But, you can insert an anchor to a section in appearance if you utilize the fact that we can make a section without a sub-title. Please read the next example. ``` sub-title(2)$ $ Like this, you put a space line under the sub-title and make a section to begin with space. This makes two sections. The first section has only the sub-title. The second section has only the paragraph. $ $ If you insert a space line to every paragraph, every paragraph has an anchor.$ $ sub-title(2)$ $ Please be careful that a line which doesn't begin with space becomes a sub-title.$ ``` This example is displayed like this. It is the point that a line begins with space. [2001-08-30](./?date=20010830) ---------- ### [\_](./?date=20010830#p01)sub-title(1) [\_](./?date=20010830#p02)Like this, you put a space line under the sub-title and make a section to begin with space. This makes two sections. The first section has only the sub-title. The second section has only the paragraph. [\_](./?date=20010830#p03)If you insert a space line to every paragraph, every paragraph has an anchor. ### [\_](./?date=20010830#p04)sub-title(2) [\_](./?date=20010830#p04)Please be careful that a line which doesn't begin with space becomes a sub-title. ``` ``` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/HOWTO-write-tDiary.md���������������������������������������������������������0000664�0000000�0000000�00000021534�13626457307�0020333�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������日記の書き方 ====== 目次 -- - - tDiaryの日記フォーマット --------------- 本文には、HTMLで日記を記述します。とは言っても、普通の文章だけの日記を書く分にはHTMLを意識しなくても良いように、HTMLに対して改行や行頭文字に特別なルールを加えたものです。サブタイトルや段落を簡単に指定するためにこのような拡張をしてあります。 以下のようなルールがあります。表示上の改行と実際の改行を区別するために、実際の改行には「_↓_」と書いてあります。 ******** サブタイトル(1)_↓_上記のように行頭から始まる行は、サブタイトルとなります。標準のスタイルシートでは、太字で表示されます。サブタイトルから次の空改行までを「セクション」と呼び、サブタイトルの前にはセクションアンカーが付きます。_↓_上の行やこの行のように、サブタイトル以降の行は通常の文章として認識されます。段落がサブタイトルで始まっている場合には、文章の前にはセクションアンカーはつきません。_↓__↓_ 空改行があると、セクションの切り替えを意味します。このように、空白で文章を始めると、サブタイトル抜きでセクションが始まります。最初の段落の先頭にだけセクションアンカーが付きます。サブタイトルのある場合ように太字にはなりません。_↓_ サブタイトルで始まらなくても、2つ目の段落以降にはアンカーは付きません。_↓__↓_``` _↓_このように行の最初が「↓ そのセクションは全体が整形の対象にならなくなります。_↓_次に空改行が現れるまで(つまり次のセクションまで)の文_↓_章はそのままの形でHTML内に展開されます。リストやテー_↓_ブルなどを使いたい場合等、HTMLタグをそのまま使いたい_↓_場面に利用できます。セクションアンカーは付きません。_↓_``` _↓__↓_サブタイトル(2)_↓_必然的に、HTMLタグで始まるサブタイトルがつけられないことになりますが、上記のように「↓ ******** 上記の内容は、以下のように表示されます。 ******** [2001-08-03](./?date=20010803)(指定したタイトル) ---------- ### [■](./?date=20010803#p01)サブタイトル(1) 上記のように行頭から始まる行は、サブタイトルとなります。標準のスタイルシートでは、太字で表示されます。サブタイトルから次の空改行までを「セクション」と呼び、サブタイトルの前にはセクションアンカーが付きます。 上の行やこの行のように、サブタイトル以降の行は通常の文章として認識されます。段落がサブタイトルで始まっている場合には、文章の前にはセクションアンカーはつきません。 [■](./?date=20010803#p02) 空改行があると、セクションの切り替えを意味します。このように、空白で文章を始めると、サブタイトル抜きでセクションが始まります。最初の段落の先頭にだけセクションアンカーが付きます。サブタイトルのある場合ように太字にはなりません。  サブタイトルで始まらなくても、2つ目の段落以降にはアンカーは付きません。 ``` このように最初の行が「 ### [■](./?date=20010803#p04)[サブタイトル(2)](hogehoge) 必然的に、HTMLタグで始まるサブタイトルがつけられないことになりますが、上記のように「 ``` ******** このようにtDiaryは、簡単な文章だけからなる日記をつける場合にはHTMLを知らなくても使え、HTMLに詳しい場合にはそれもサポートするようになっています。……が、ときどき不用意にタグを使ってハマる人も少なくないので、日記中でタグを多用する人は次の「tDiary記述のコツ」もお読みください。 tDiary記述のコツ ----------- ### セクションにタグ入りの行を含めたい 例えば日記中にリストを埋め込むために タグを入れたいとしましょう。話題は同じなのでセクションは変えたくない。このように段落全体を特殊なタグで装飾したい場合、tDiaryでは少しコツが必要です。以下のようなレイアウトをしたい場合を例にとりあげます。 ******** [2001-08-29](./?date=20010830) ---------- ### [■](./?date=20010829#p01)サブタイトル  以下のように2つの項目からなるリストを書きます。 - リスト項目1 - リスト項目2  こんな感じです。ここまで同一のセクション。 ******** まずひとつの方法は、前の段落に合体させてしまう方法です。生成された日記のHTMLを見ればわかるように、段落というのは〜で囲まれているだけです。これを利用してごまかしを入れます。 ******** サブタイトル_↓_ 以下のように2つの項目からなるリストを書きます。 - リスト項目1 - リスト項目2  こんな感じです。ここまで同一のセクション。_↓_******** 途中でいっさい改行を入れないところがミソです。タグで囲まれた段落が何行にもわたる場合以外はこれでもけっこういけますが、ちょっと見通しが悪いですね。上の例は、tDiaryが段落には自動的にを入れることを利用しています。逆に、タグで始まる行があるセクションにはこのタグ自体を挿入しないことを利用する方法もあります。通常の段落に、手動でタグを入れる方法です。以下の記述例では、セクション中に「〜で囲んでいます。 ******** サブタイトル_↓_ 以下のように2つの項目からなるリストを書きます。_↓__↓_- リスト項目1 _↓_- リスト項目2 _↓__↓_ こんな感じです。ここまで同一のセクション。_↓_******** この手法は、タグで囲まれた段落が複数行に渡るとき(例えば ``` タグでソースコードを挿入するなど)には必須になるでしょう。もちろん、「セクションが分かれても良い」という場合にはもっと楽になります。こだわりがなければ以下のように書いてしまうのが良いかもしれません。 ******** サブタイトル_↓_ 以下のように2つの項目からなるリストを書きます。_↓__↓_``` _↓_- リスト項目1 _↓_- リスト項目2 _↓__↓__↓_ こんな感じです。ここまで同一のセクション。_↓_******** 最後の「こんな感じです〜」の行頭にはセクションアンカーが入ってしまいますが、たいして気にする問題でもないでしょう。 ### セクション単位でなく、段落単位にアンカーを入れたい tDiaryは、「話題の単位はセクションにあり、段落にまでアンカーを入れる必要はない」というポリシーで作られているため、基本的には段落にアンカーを入れることはできません。ただし、サブタイトルなしのセクションが作れることを利用すれば、見た目は段落単位にアンカーを入れることもできます。以下の例を見てください: ******** サブタイトル(1)_↓__↓_ このようにサブタイトルの下にすぐ空改行を入れてしまい、続く段落を空白で始めるようにすれば、サブタイトルと段落は別々のセクションになります。_↓__↓_ 段落の間にすべて空改行を入れるようにすれば、このようにすべての段落にアンカーを付けることができるわけです。_↓__↓_サブタイトル(2)_↓__↓_  行頭の空白を入れないとサブタイトルになるので注意しましょう。_↓_ ******** 上の例は以下のように展開されます。ポイントは**行頭の空白**ですね。 ******** [2001-08-30](./?date=20010830) ---------- ### [■](./?date=20010830#p01)サブタイトル(1) [■](./?date=20010830#p02)このようにサブタイトルの下にすぐ空改行を入れてしまい、続く段落を空白で始めるようにすれば、サブタイトルと段落は別々のセクションになります。 [■](./?date=20010830#p03)段落の間にすべて空改行を入れるようにすれば、このようにすべての段落にアンカーを付けることができるわけです。 ### [■](./?date=20010830#p04)サブタイトル(2) [■](./?date=20010830#p04)行頭の空白を入れないとサブタイトルになるので注意しましょう。 ******** ��������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/INSTALL-cgi.md����������������������������������������������������������������0000664�0000000�0000000�00000007102�13626457307�0016712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tDiaryのインストール (CGI環境) ============================== 一般的なCGIの実行を許可しているISPやレンタルサーバ上で利用する場合を想定し、以下のような環境を例に説明します。 - WWWサーバ: Apache 2.x - ユーザ名: foo - 日記のURL: `http://www.hoge.example.org/~foo/diary/` - 上記URLのパス: `/home/foo/public_html/diary` ## tDiaryの取得 tDiaryのダウンロードサイトから、配布アーカイブを取得します。 - [tDiary.org - ダウンロード](http://www.tdiary.org/20021112.html) ### 【補足】 tDiaryをGitHubから取得する場合 開発版を使いたい、更新を楽にしたいという理由でtDiaryをGitHubから取得して利用する場合は、外部ライブラリ (hikidocなど) を手動でインストールする必要があります。以降の手順に沿って、ライブラリをインストールしてください。 配布アーカイブから取得する場合は、外部ライブラリは同梱されているため、この手順は不要です。 まず、外部ライブラリの取得に必要となるBundlerインストールします。 ``` % gem install bundler ``` 次に、gitコマンドでtDiaryのソースコードを取得した後に、 `bundle install` コマンドを実行して外部ライブラリをインストールします。 ``` % git clone git://github.com/tdiary/tdiary-core.git tdiary % cd tdiary % bundle install --without development ``` ## CGIスクリプトの設定 配布アーカイブを展開し、中身をすべて`/home/foo/public_html/diary`にコピーします。以下の2つのファイルがCGIスクリプト本体なので、WWWサーバの権限で実行可能なようにパーミッションを設定してください。 - index.rb - update.rb また、/usr/bin/envを使った起動ができない環境では、各ファイルの先頭を、rubyのパスに書き換える必要があるでしょう。ISPのホームディレクトリにこっそりRubyを入れたような場合を除き、通常はあまり気にしなくても良いはずです。 ## .htaccessの作成 続いて、CGIの実行環境を整えます。dot.htaccessを.htaccessにリネームして、環境に合わせて書き換えます。添付のサンプルは以下のようになっています。 ``` Options +ExecCGI AddHandler cgi-script .rb DirectoryIndex index.rb <Files "*.rhtml"> deny from all </Files> <Files "tdiary.*"> deny from all </Files> <Files update.rb> AuthName tDiary AuthType Basic AuthUserFile /home/foo/.htpasswd Require user foo </Files> ``` ここでは、 - CGIの実行を可能にし、 - サフィックス「.rb」のファイルをCGIと認識させ、 - index.rbをデフォルトのファイルに設定し、 - `*.rhtml`と`tdiary.*`のファイルの参照を禁止して、 - update.rbへのアクセスにはユーザ認証が必要 という設定になっています。とりあえず書き換えが必要なのは、AuthUserFileとRequire userでしょう。意味はWebででも調べて下さい。AuthUseFileは、あらかじめhtpasswdコマンドで作成しておく必要があります(これもWebで調べればわかります)。 また、利用するWWWサーバの設定が、CGIの実行ファイルのサフィックスを固定(例:.cgi)にしている場合があります。この場合、AddHandlerやDirectoryIndexも変更する必要があるでしょう。これに応じて、index.rbやupdate.rbのファイル名も変更する必要があります。 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/INSTALL-paas.md���������������������������������������������������������������0000664�0000000�0000000�00000006371�13626457307�0017103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Install to PaaS ## 概要 tDiary-3.1.3 以降のバージョンでは tDiary を [Heroku](http://www.heroku.com) のような PasS で動かすことが可能です。PaaS を利用することで、3.1.3 以前のバージョンで必要とされていた Apache のような http サーバーの用意や CGI として動作させるための環境設定を行う事なく、 tDiary を動かして日記を書くことが可能となります。 ## 動かし方 - Heroku の場合 Webブラウザだけあれば動作させることが可能です。 日記の更新時にTwitterのOAuthを使って認証するようになっています。あらかじめ[Twitter Developpers](https://developer.twitter.com/en/apps)にてアプリケーションを作成し、API key と API secret key を取得しておきます。 続いて GitHub 上にある[tDiaryのリポジトリ](https://github.com/tdiary/tdiary-core)から、Herokuボタンを使ってデプロイしてください(トップページ下部のREADMEにあります)。 Heroku の New App ページになったら、下記の情報を入力して、Deploy for Free ボタンを押します。 * App Name (任意) * TWITTER_KEY: Twitter の API key * TWITTER_SECRET: Twitter の API secret key * TWITTER_NAME: 認証に使う Twitter のユーザ名 「Deployed to Heroku」まで進めば利用可能です。「View it」のリンクから日記に飛んで下さい。 【注意】View itから飛んだ先のURLは https://~ になっています。いったん http://~ にしないと認証が通らないので注意してください。なお、設定画面で「日記のURL」を https://~ に変更することで https での利用が可能です。 また、tDiary 5.10 より、amazonプラグインを利用する場合に特別な設定が必要になっています。[tDiary 5.1.0のリリース](http://www.tdiary.org/20191129.html)にある方法でAmazon PA-APIのアクセスキーとシークレットキーを取得し、Herokuの環境変数(Settings→Config Vars)にてぞれぞれ以下の変数に指定します。 * AMAZON_ACCESS_KEY * AMAZON_SECRET_KEY あとはtDiaryの設定画面から、AmazonのアソシエイトIDを指定すれば利用できます。 ## memcache アドオンを使う方法 - Heroku の場合 Heroku で アドオンの追加・削除を行うことが出来るユーザーは memcache アドオンを使うことで、より高速に日記キャッシュデータを扱えるようになります。tDiary on Heroku で memcache アドオンを使う方法を以下に解説します。 tdiary-core の deploy ブランチに切り替えます。 ``` git checkout deploy ``` heroku コマンドを用いて memcache アドオンを有効にします。 ``` heroku addons:add memcache ``` Gemfile の以下の行を有効にします。 ``` gem 'dalli' ``` tdiary.conf を以下のように変更します。 ``` # require 'tdiary/cache/file' # To use memcache addon require 'tdiary/cache/memcached' ``` この状態を Heroku に反映させます。 ``` git add . git commit -m "enable memcache" git push heroku deploy:master ``` git push コマンドが完了すると memcached をキャッシュの保存先とした tDiary が利用可能となります。 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/INSTALL-rack.md���������������������������������������������������������������0000664�0000000�0000000�00000006654�13626457307�0017103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tDiaryのインストール (Rack環境) ============================ ## 概要 tDiary-4.0 以降のバージョンは gem に対応しているので、簡単に tDiary を設置出来ます。 ## tDiary の取得 gem コマンドで tDiary をインストールします。 ``` % gem install tdiary ``` インストールすると、 tdiary コマンドが使えるようになります。ちゃんとインストールできているか、確認してみましょう。以下のようにバージョン番号が表示されればインストール成功です(表示される番号はバージョンにより異なります)。 ``` % tdiary version 4.0.0 ``` rbenv を使っている場合は忘れずに rehash を実行しておきましょう。 ``` % rbenv rehash ``` ## tDiary の設置 newコマンドを実行してtdiaryを設置します。インストール先のディレクトリ名を指定します。以下の例では diary ディレクトリにインストールします。 ``` % tdiary new diary create diary create diary/public (中略) create diary/tdiary.conf run bundle install --without test development from "./diary" Resolving dependencies... Using rake (10.1.0) Using bundler (1.3.5) (中略) Using twitter-text (1.6.1) Your bundle is complete! Gems in the groups test and development were not installed. Use `bundle show [gemname]` to see where a bundled gem is installed. run bundle exec tdiary htpasswd from "./diary" Input your username/password ``` インストール途中で「Input your username/password」と表示され、 更新画面のユーザ認証のために、IDとパスワードを入力します。 ``` Username: machu New password: Re-type new password: install finished run `tdiary server` in diary directory to start server ``` ## tDiary の起動と終了 インストール先のディレクトリに移動して、serverコマンドを実行するとtDiaryサーバが起動します。 ``` % cd diary % bundle exec tdiary server >> Thin web server (v1.5.1 codename Straight Razor) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:19292, CTRL+C to stop ``` Webブラウザで http://localhost:19292/ にアクセスすると、tDiaryの画面が表示されます。 CTRL+CコマンドでtDiaryサーバを終了します。 ``` >> Stopping ... ``` ## tDiary の更新 tDiaryのアップデートもgemコマンドを使います。 ``` $ gem update tdiary ``` tDiaryの設置ディレクトリに展開されたファイルは、 tdiary updateコマンドを使って更新できます。 ``` $ cd [tDiaryの設置ディレクトリ] $ tdiary update $ bundle install ``` ## 追加のgemを使うには tDiaryの関連ライブラリは、別のgemになっている場合があります。これらを使いたい場合、Rubyで一般的な`Gemfile`ではなく、`tdiary new`コマンドで作成した先(このドキュメントの場合はdirayディレクトリ)にある`Gemfile.local`に使いたいgemを指定します。例えばBlogKitを使いたい場合には以下のように指定します: ``` gem 'tdiary-blogkit' ``` このあと、`bundle install`をして、指定したgemをインストールします: ``` $ bundle install ``` 他にも、日記の保存先をデータベースにするIO系のgem、スタイルを追加するgem、Thin以外のWebサーバを使いたい場合にも`Gemfile.local`に記述します。 ������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/INSTALL.md��������������������������������������������������������������������0000664�0000000�0000000�00000024024�13626457307�0016154�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������インストールマニュアル ====================== tDiaryの設置 ------------ tDiaryは様々な環境で動作します。それぞれの環境にあわせた設置手順を参照してください。 - 独自サーバ、VPSサーバなどのRack環境 … [INSTALL-rack.html](INSTALL-rack.html) - Heroku、SqaleなどのPaaS環境 … [INSTALL-paas.html](INSTALL-paas.html) - レンタルサーバなどのCGI環境 … [INSTALL-cgi.html](INSTALL-cgi.html) tDiaryの設定 ------------ ### tdiary.confの作成 tDiaryの設定ファイルであるtdiary.confを作ります。 初めてtDiaryをインストールする人には、付属のtdiary.conf.beginnerを使うのがオススメです。最初に使えるようにしておくと良いプラグインがあらかじめONになっていたり、spamフィルタにある程度の設定がされているなど、インストールしてすぐに使いやすい状態になっています。 tdiary.conf.beginnerをtdiary.confにリネームして、内容を書き換えます。tDiaryの設定はほとんどWebブラウザ経由で行えます。ただし、`@data_path`は必要に応じて最初に書き換えてください。 ``` @data_path = 'data' ``` `@data_path`は、日記のデータを保存するディレクトリです。ほとんどのレンタルサーバで使われているApache HTTPサーバ向けには、このディレクトリをWWWサーバ経由で参照されないように.htaccessファイルによるアクセス制御を設定済みです。他のWebサーバを使用する場合には、WWWサーバ経由でアクセスできない(`public_html`配下でない)ディレクトリを指定するか、アクセス制御を設定してください。また、このディレクトリはWWWサーバの権限で書き込めるパーミッションにしておく必要があります。 tdiary.confには、他にもいろいろな設定項目を記述できます。これらの項目には以下の3つの種類があります。 tDiary は日記データのキャッシュを PStore ファイルとして保存しますが、設定を変えることによりより高速な memcached を使用することも可能です。memcached をキャッシュの保存先として使用する場合は tdiary.conf を以下のように変更します。 ``` # 以下の行をコメントアウト # require 'tdiary/cache/file' require 'tdiary/cache/memcached' require 'tdiary/io/default' @io_class = TDiary::IO::Default ``` 同様に redis を使用する場合は tdiary.conf を以下のように変更します。 ``` # 以下の行をコメントアウト # require 'tdiary/cache/file' require 'tdiary/cache/redis' require 'tdiary/io/default' @io_class = TDiary::IO::Default ``` #### CGIで設定できない項目 `@data_path`のように、CGIでは設定できない項目です。これらの項目は、tdiary.confファイルを直接編集して変更しなければいけません。 #### CGIで設定できる項目 変更画面のメニューにある「設定」を開くと、ブラウザからtDiaryの設定を変更できます。ほとんどの項目はここから設定できるので、わざわざtdiary.confを手で書き換える必要はありません。 #### CGIで追加設定できるが、標準設定を記述できる項目 tdiary.confに記述しておくことで、CGIの設定画面からは編集できないが追加はできるといった設定をできる項目があります(リンク元記録除外や、リンク元変換表)。あらかじめtdiary.confに記述しておくことで、複数の人が同一サーバ上でtDiaryを使うような場合に手間を省くことができます。 各々の項目については、tdiary.conf.sampleの説明を読んでください。一般的な使用では、`@data_path`だけを正しく設定すれば、あとはブラウザから変更が可能です。 また、サフィックス.rbのファイルをCGIスクリプトとして指定できない環境では、index.rbやupdate.rbのファイル名を変更する必要がありますが、この変更をtDiaryに教えるために、@indexや@updateという変数が用意されています。環境によってはこれも指定する必要があるでしょう。 tdiary.confの設定が終わったら、http://www.hoge.example.org/~foo/diary/にアクセスしてみましょう。からっぽの日記ページが出れば設定は正しいです。不幸にして「Internal Server Error」が出てしまったら、Apacheのエラーログを参照して間違った設定を修正してください。 tDiaryの実行 ------------ ### 日記の更新 ページの先頭には、「トップ」「更新」の2つのリンクがあります。「トップ」は`@index_page`で指定した表紙へ、「更新」は日記を更新するフォームへ移動します。もし「更新」をクリックした時、認証ダイアログが出なかったら、.htaccessの記述が正しくない可能性があります。 更新ページの先頭にもメニューがあります。一番右端に「設定」が増えているでしょう。ここをクリックすると、設定用のページが開きます。詳しくはを参照してください。 更新ページには、日記の日付とその日のタイトル、本文を入力するフォームがあります。日付、タイトル、本文を入力して「追加」ボタンを押すと、その日の日記に追加されます。タイトルと本文はどちらも省略可能です。追加なので、一日に何度も日記を書く場合に、わざわざ以前のデータを呼び出す必要はありません。また、すでにタイトルが指定されている場合、タイトルを入力しなければ以前指定したものが使われます。 フォームで日付を入力して「この日付の日記を編集」ボタンを押すと、(その日の日記がすでに存在すれば)タイトルと本文に過去の日記のデータが読み込まれます。この時、フォームの最後のボタンは「登録」になります(つまり、追加ではありません)。 日記本文には日記向けに少し特殊化したHTMLを使います。多少癖があって人によってはなかなか馴染めないことがあるようなので、[日記の書き方](HOWTO-write-tDiary.html)には必ず目を通して下さい。 ### 日記の設定 更新画面で「設定」をクリックすると、設定画面になります。ここではtDiaryのさまざまな設定項目をブラウザから設定できます。各項目の説明は画面中に記述してありますから、それを参考にいろいろと設定を変えてみてください。また、ページ中には利用しやすくするために「OK」ボタンがたくさん置いてありますが、すべて同じものです。つまり、どの「OK」を押してもすべての項目が保存されます。 なお、この設定画面で行った変更は、`@data_path`で指定したディレクトリに別のtdiary.confとして保存されます(初期設定時に手動で書き換えたtdiary.confではありません)。このファイルは、元のtdiary.confのあとに読み込まれるので、設定の内容はブラウザから指定したものが優先されます(ただし、元のtdiary.conf中の設定を変えることで、読み込むタイミングは変更できます)。 ### 日記の参照 日記の参照には、最新、月別、日別の3種類のモードがあります。デフォルトページは最新です。月別は、ページの最初の方に出るカレンダーをクリックすると参照できます。また、日別は日付をクリックすると参照できます。 最新・月別と日別には、表示される内容に違いがあります。最新・月別では「本日のツッコミ」「本日のリンク元」が省略されて表示されるのに対し、日別ではすべて表示されます。また、日別にはツッコミ用のフォームがあります。ツッコミをしてもらいたかったら、読者を日別ページに誘導するように、ヘッダ(@header)を工夫する必要があるかも知れません。 月、日、セクション、ツッコミには、それぞれアンカーがあり、他の場所からリンクできるようになっています。それぞれのアンカーはリンクにもなっているので、そこにポインタを合わせることで、そのURLを知ることができます。 携帯端末からの参照ではデータ量に制限があるため、上記の機能はほとんど使えません。最新は最新日付の日記だけが表示され、前日・翌日へ移動できるだけです。ただし、すべてのページにツッコミ用フォームが付いているので、ツッコミを入れることは可能です。 ### プラグインによるカスタマイズ tDiaryにはプラグインと呼ばれる機能があります。プラグインを追加することで、tDiaryの機能を増やしたり、変更したりすることが可能です。プラグインについての詳しい説明は、[HOWTO-use-plugin.html](HOWTO-use-plugin.html)(使い方)・[HOWTO-make-plugin.html](HOWTO-make-plugin.html)(作り方)を参照してください。 ### あとは…… 日記をつけ続けるだけです(これが一番難しい:-)。Have fun!! 著作権、サポートなど -------------------- tDiary本体は、原作者であるただただし(t@tdtds.jp)が、GPL2ないしその後継ライセンスの元で配布、改変を許可するフリーソフトウェアです。 また、tDiaryフルセットに付属するテーマ、プラグインはすべて、それぞれの原作者が著作権を有します。ライセンス等に関しては個々のファイルを参照してください。 tDiaryは[tDiary.org](http://www.tdiary.org/)でサポートを行っています。ご意見・ご要望はこちらへどうぞ。パッチ歓迎です。 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/README.en.md������������������������������������������������������������������0000664�0000000�0000000�00000024611�13626457307�0016406�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tDiary -- a TSUKKOMI-able Web-log ================================= tDiary is so called Weblog. tDiary has these features. features -------- ### You can change your configuration with browser. You can not only read diary, but also write diary. Also, it is possible to change your configuration with browser. With tDiary, you can easily use and maintain Web-log system. So, you continue to write diary for a long time. ### TSUKKOMI 'TSUKKOMI' means a short, smart and heartfelt comment in Japanese. It is possible for diary readers to add a TSUKKOMI to your diary. In other words, tDiary is equipped with BBS. With this BBS, you can communicate with your diary readers. tDiary can inform the author of a new TSUKKOMI by e-mail. ### Today's Link (Referer) When people links their diary to your diary, tDiary shows their URL by analysis of the referer header. This feature is supported in many Japanese web-log systems. In tDiary, this feature is more user-friendly. ### small devices -- PDA or mobile phone You can read your diary with PDA or mobile phone, for example, i-mode, Palm, Zaurus(SHARP's PDA) and so on. When you access the same URL as usual, tDiary creates a page for PDA or mobile phone. The page for small devices are small and suitable for reading with them. ### theme -- CSS You can change the look of the diary by CSS. In tDiary, this feature is called 'theme'. tDiary package has some themes. Of course, you can create a new theme. You can change your theme with browser. ### Plugin By plugins, you can add new features to tDiary, and change the existing feature of tDiary. ### Selectable Style and IO You can choice a grammar of writing your diary by 'Style' feature. Some style files are in misc/style. And you can choice data saving format (IO) also. Seee HOWTO-make-io.html for more information about Style or IO. ### Written in Ruby Important :-). tDiary requires Ruby 2.1.0 or later. ### Others tDiary also supports these features. - Section anchor - Read past diaries Installation and Configuration ------------------------------ In this manual, we presume this environment as one example. - WWW server: Apache 1.3.x - User: foo - Diary URL: http://www.bar.example.org/~foo/diary/ - Diary Path: /home/foo/public\_html/diary/ ### CGI script configuration Unpack archive, and copy all the files to "/home/foo/public\_html/diary/". You must change permission of two files, which are executed as CGI script. - index.rb - update.rb If you use tDiary in an environment where the command "/usr/bin/env" can't be used, you need to edit these files and change their front line so that it stands for the Ruby executable. Except the case when you install Ruby under your home directory, you may be not careful about this thing. ### .htaccess Next, you arrange CGI environment. You copy "dot.htaccess" as ".htaccess". And, edit it. The file, "dot.htaccess", is like this; ``` Options ExecCGI AddHandler cgi-script .rb DirectoryIndex index.rb deny from all deny from all AuthName tDiary AuthType Basic AuthUserFile /home/foo/.htpasswd Require user foo ``` "dot.htaccess" configures these things. - makes it possible to use CGI. - makes files whose suffix is ".rb" recognized as CGI script. - sets "index.rb" to the default file. - prohibits accesses to "*.rhtml" and "tdiary.*" - When you access "update.rb", authentification is needed. At least, you must change the "AuthUserFile" and "Require User" items. In Addition to it, you must create the the file named as "AuthUserFile" by "htpasswd" command before you access your diary. If you don't know "AuthUserFile" and "Require users", please examine these words. If your WWW server doesn't allow you to change the suffix of CGI scripts, you need to change the "AddHandeler" or "DirectoryIndex" items. In this case, you may need to change the filenames of "index.rb" and "update.rb". ### creation of tdiary.conf You copy "misc/i18n/tdiary.conf.sample-en" as "tdiary.conf" and edit "tdiary.conf". _Notice! "tdiary.conf.sample" in INSTALLDIR is Japanese version_. "tdiary.conf.sample" only supports Japanese. "tdiary.conf" is loaded as Ruby script by the CGI scripts, for example, "index.rb" and "update.rb". With tDiary, you can do configuration with browser. If necessary, you may change "@data\_path" parameter at first. "@data\_path" is appeared at the beginning of "tdiary.conf". ``` @data_path = "data" ``` In "@data\_path", you specify the directory where your diary data are stored. This item is usually set to the directory which can not be accessed through WWW. In addition to it, you must set permission of this directory so that the WWW server can access it. In "tdiary.conf", you can configure many items. They are divided into three categories. The items which you can't set with browserLike "@data\_path", these are the items which you can't change with browser. These items are configured only by editing "tdiary.conf" directly. The items which you can set with browserWhen you click the menu, "preferences", you can change your configuration with browser. Almost all the items are changed with browser. You don't have to edit "tdiary.conf" directly. The items to which you can add values with browser"tdiary.conf" has some items to which values are added with browser, for example, the ignored links and the rules which convert a URL. By editing these items of "tdiary.conf", you can set the default values(This is meaningful if you use multi-user mode). ### Configuration The meaning of each item is explained in "tdiary.conf.sample". Generally speaking, you can change your configuration with browser after you configure @data\_path. If you want to receive a new TSUKKOMI by e-mail, you configure the @smtp\_host and @smtp\_port. If you run tDiary in the environment where you can't use the suffix, ".rb", as CGI script, you change the filenames of "index.rb" and "update.rb". In this case, you must configure @index and @update. After you finish configuration, access "http://www.hoge.example.org/~foo/diary/". If you can see an empty page, tDiary works well. Unfortunately, if you encounter "Internal Server Error", you must change configuration. The error-log of Apache is useful in order to investigate the cause. run tDiary ---------- ### update the diary At the beginning of the diary page, there are two links, "Top" and "Update". When you click "Top", you move to the page which is specified by "@index\_page". When you click "Update", you move to the page which has the form to update your diary. If the authentification dialog doesn't appear in clicking "Update", there is possibility that your ".htaccess" is wrong. The "Update" page also has the menu in its beginning. In "Update" page, "Preferences" is added in the right of the menu. When you click it, the "Preferences" page is opened. The detail about the "Preferences" page is explained in the below. The "Update" page has the form where you can input the date, title, and body of diary. Write your diary and put the "Add" button. By this procedure, the diary is added. Because this procedure is "Add", you don't have to show all the diary data if you write diary many times a day. Once you set the title of the diary, tDiary uses it. If you set date and click the "Edit this day" button, the title and body of the date are loaded(If the data is empty, these data are not loaded). In this case, the last button of the form is "Register"(Be careful. It is not "Add"). In tDiary, You use a bit specialized HTML in order to describe your diary. It is a little characteristic and it takes considerable time for some people to get accustomed to writing diary in this format. Please read HOWTO-write-diary. ### Configuration with browser When you click the "Preferences" button in the "Update" page, the "Preferences" page is shown. Here, you can configure many items with browser. In the "Preferences" page, each item has explanation. When you change a item, it is good to refer to explanation. Though the "Preferences" page has many "OK" buttons, their role is the same. When any "OK" button is clicked, all the items are stored to the configuration file. These buttons are located for the purpose of convenience. The configuration which is done with browser is stored as "tdiary.conf", which is located in the "@data\_path" directory. This "tdiary.conf" is not the "tdiary.conf" which you edit manually. This file is normally loaded after the original "tdiary.conf" is loaded, so the values of the CGI "tdiary.conf" has priority over the values of the original "tdiary.conf". (If you edit the original "tdiary.conf", you can change the timing of loading the cgi "tdiary.conf") ### Read Diary When you read your diary, tDiary provides the three kind of the pages, "Latest", "Monthly", and "Daily". In default, tDiary shows "Latest" page. You can read the "Monthly" page if you click the link of the calendar located at the beginning of the page. And you can read the "Daily" page if you click the date. There is difference between "Latest"/"Monthly" and "Daily" page. In "Latest"/"Monthly" page, today's TSUKKOMIs and today's links are partly omitted. On the other hand, "Daily" page shows all the TSUKKOMIs and links. And, "Daily" page has the form for TSUKKOMI. Every month, day, section, and TSUKKOMI has an anchor, and diary readers can link other place to it. Because each anchor is also a link, you can know the URL of it if you move pointer to it. With small devices, for instance, mobile phone, Zaurus and Palm, you can't use some of the features above because of restriction on data amount. When you access the diary with small devices, the "Latest" page shows the page which contains only one latest diary. You can move from this page to previous day page or next day page. ### And ... Now, All you have to do is that you write diary ( But, it is the most difficult to continue to write diary:-) ). Have fun.!! License ------- tDiary is free software created by TADA Tadashi(sho@spc.gr.jp). tDiary is licensed under the terms of GPL2 or any later version. You can distribute and modify it under the terms of GPL2. But, all the files that are in "erb/" directory is ERb library created by Seki-san. You can know the detail about the license of these files at http://www2a.biglobe.ne.jp/~seki/ruby/. And, authors of all the plugins and themes have its copyright. All the plugins can be distributed and modified under the terms of GPL2. Most themes are also under GPL2, but some have original license. See each theme file. tDiary is developed on https://sourceforge.net/projects/tdiary/. �����������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/README.md���������������������������������������������������������������������0000664�0000000�0000000�00000007356�13626457307�0016014�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ツッコミのできるWeb日記システム ================= tDiaryでできること ------------ tDiaryは、いわゆるWeb日記を支援するシステムです。tDiaryには以下の特徴があります。 ### 更新や設定までブラウザからできる 日記の参照だけでなく、日記の更新、設定までもWebブラウザから実行できます。ブラウザさえあれば面倒なメンテナンスは不要。手軽に使えて、長く続けられます。 ### 「ツッコミ」が入れられる 日記の読者が、日記に「ツッコミ」を入れられます。ようするに、日付ごとに掲示板がついています。これを通じて、読者とのコミュニケーションが生まれます。 ツッコミがあったことを著者にメールで知らせる機能もあります。 ### 「本日のリンク元」(Referer)機能 他の日記等からリンクされると、Refererヘッダを見てそのURLを表示します。どこかで自分の日記が話題にされていることがすぐにわかるように、従来のWeb日記コミュニケーションで使われている手法をわかりやすくサポートしています。 ### 携帯端末対応 iモードに限らず、ほとんどの携帯電話やPalm・ザウルスなどの携帯端末からも日記を参照できます。専用の特別なURLは必要なく、自動認識して最適なページを生成します。通信料金のシビアな端末向けには無駄を省いた小さなページを送るようになっています。 ### CSSを使ったテーマ機能 スタイルシートを使って見た目をがらりを変えることができます。これは「テーマ」と呼ばれ、別パッケージとして配布されているテーマ集には、100を越えるテーマが収録されています。もちろん自分で作ることも可能です。テーマは設定画面で簡単に切り替えることができます。 ### プラグインによる機能追加 プラグインというモジュールを追加することで、日記の機能を増やしたり変更したりすることが可能です。詳しくは[HOWTO-use-plugin.html](HOWTO-use-plugin.html)(使い方)・[HOWTO-make-plugin.html](HOWTO-make-plugin.html)(作り方)を参照してください。 ### 記述形式や保存形式を変更できる 日記を記述する形式(スタイル機能)や、データの保存形式(IO機能)が選択可能です。スタイルはmisc/styleの下に複数収められています。IOは現在、1.4系までの旧tDiary互換のPStoreIOと、2.0系以降の新しいテキスト形式であるDefaultIOがあります。詳しくは[HOWTO-make-io.html](HOWTO-make-io.html)を参照してください。 ### Rubyで書かれている 重要なポイントでしょう:-) ruby 2.1.0以上が必要です。 セクション(段落)アンカーや過去の日記の参照など、一般的なWeb日記システムの持つ機能は基本的にサポートしています。 tDiaryのインストールと設定 ---------------- [INSTALL.html](INSTALL.html)を参照してください。 著作権、サポートなど ---------- tDiary本体は、原作者であるただただし(t@tdtds.jp)が、GPL2ないしその後継ライセンスの元で配布、改変を許可するフリーソフトウェアです。 また、tDiaryフルセットに付属するテーマ、プラグインはすべて、それぞれの原作者が著作権を有します。ライセンス等に関しては個々のファイルを参照してください。 tDiaryは[http://www.tdiary.org/](http://www.tdiary.org/)でサポートを行っています。ご意見・ご要望はこちらへどうぞ。パッチ歓迎です。 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/doc/UPGRADE.md��������������������������������������������������������������������0000664�0000000�0000000�00000025675�13626457307�0016152�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������アップグレードガイド ========= このドキュメントについて -- tDiaryは、バージョン番号が「X.Y.Z」の形式のものがリリースバージョン、その後ろに「.YYYYMMDD」形式で日付が入っているものが開発バージョンとなっています。このドキュメントでは、リリースバージョン間の変更点について解説します。開発バージョンを使っている場合は、ChangeLogファイルを参照してください。 4.0と5.0の違い ----- 5.0での大きな変更点は、secure modeがなくなったことです。secure modeを実現するために利用していたRubyの機能が、サポートしているruby 2.1以降で使えなくなったためです。このため、従来secure modeで利用していたtDiaryをruby 2.1以降で利用する場合は、以下のような手段で別途安全を確保する必要があります。 - suexecやそれに類した環境でCGIをそれぞれのユーザ権限で動作させる - jailやそれに類した環境でWebサーバをそれぞれのユーザ権限で動作させる - Dockerやそれに類した環境でコンテナ自体を分離する - 日記ごとに別のサーバを用意する 2.2と3.0の違い ----- 2.2系から3.0への最大の変更点は、「UTF-8化」と「ruby 1.9対応」です。いずれも大きな変更になりますので、以下の注意をよく読んでからアップデートを行って下さい。すでに2.3系で運用している場合は特に大きな問題はでないでしょう。 ### アップデートに関する注意点■ #### 文字コードのUTF-8化 tDiary 3.0では日記データのファイルのエンコードをEUC-JPからUTF-8へと変更しています。この変更により複数の言語で日記を書けるようになりました。 tDiary 3.0にバージョンアップすることで、自動的に新しく書いた日記はエンコーディングがUTF-8で作成され、過去の日記データも表示する際にEUC-JPからUTF-8に自動的に変換されます。 いちどUTF-8に変換された日記データは、基本的にはEUC-JPへは戻せません。かならずバックアップをとってからアップデート作業をしてください。 #### ruby 1.9.2 への対応 tDiary 3.0ではrubyを1.9.2にバージョンアップするだけで移行できるようになっていますが、 tDiaryが生成するキャッシュファイルは互換性の問題でまれにエラーになることがあります。 エラーになった場合のもっとも簡単な対処は、データディレクトリにあるcacheディレクトリを丸ごと削除する方法です。ただし、counter.rbの情報が消えるとカウンタが巻き戻ってしまうので、初期値を控えておくなどの対処が必要です。また makerss.rbやrecent_comment.rbが生成するキャッシュが消えるため、しばらくは寂しい状況になるかも知れませんが、これらは時間が解決してくれます:-) すべてのキャッシュを削除するのが困難な場合は、個別のファイルごとに対処してください。 また、カテゴリに関する情報も、同様な理由でエラーを起こすことがあります。この場合は、categoryプラグインの設定画面で「カテゴリインデックスの作成」を実行してください。 いちどruby 1.9.2上で動作させた日記データは、基本的には1.8へは戻せません。かならずバックアップをとってからアップデート作業をしてください。 #### tDiary 3.0とruby 1.9.2を同時にアップデートしない ruby 1.8.* で動かしているtDiary 2.2系をtDiary 3.0とruby 1.9.2の環境へ同時にアップデートすることは避けるべきでしょう。日記データが壊れることはないはずですが、キャッシュデータが壊れてしまう可能性があります。 どうしてもtDiaryとrubyの両方をバージョンアップしたい場合は以下の手順でバージョンアップして下さい。 1. tDiaryをまず3.0にバージョンアップし、ruby 1.8の状態でブラウザから日記を表示します。この際に日記データと利用しているプラグインのキャッシュデータがUTF-8へと変換されます。 2. 利用しているプラグインの動作を全て確認後にruby 1.9.2へとアップデートします。 3. 利用しているプラグインによっては、上記の手順で完全に変換が実行されない可能性もあります。 不安な場合は<tdiary-devel@sourceforge.net>まで相談してください。 2.0と2.2の違い ----- ### 2.0から2.2移行時の注意 #### いくつかのファイル名が変更になっています。 - plugin/01sp.rb → plugin/50sp.rb - plugin/ja/01sp.rb → plugin/ja/50sp.rb - plugin/en/01sp.rb → plugin/en/50sp.rb - plugin/zh/01sp.rb → plugin/zh/50sp.rb 2.2へのアップデートをする前に、上記のファイルをあらかじめ削除しておいてください。残っていると誤動作する場合があります。 #### リンク元の記録方法が変更になっています。 リンク元は従来、月単位に記録していましたが、2.2からは日単位の記録になっています。このため、データディレクトリには自動的にYYYYMMDD.tdrというファイルが生成され、元のYYYYMM.tdrはYYYYMM.tdr~にリネームされて残されます。ディスク容量に余裕がない場合には、古いファイルは削除してかまいません。 #### 2.0から2.2への主な変更点 [tDiary.orgのリリース](http://www.tdiary.org/20071216.html)を参照してください。 プラグインの中にも廃止・統合されたファイルがあります。 1.4と2.0の違い ----- ### 1.4から2.0移行時の注意 #### データ形式が変更になっています。 1.4系ではバイナリ形式でしたが、2.0からは標準でテキスト形式になっています。保存形式は差し替え可能になっていますが、テキスト形式に変換することをお勧めします。詳しくは[tDiary.orgのページ](http://www.tdiary.org/20021121.html)を参照してください。 #### プラグインのインストール方法が変わっています。 tDiaryインストールディレクトリのmisc/pluginにプラグインファイルを入れておくと、設定画面から有効にするプラグインを選択できます。従来の方法でもインストールできますが、プラグインファイルが本体と言語リソースに分離されたこともあり、今後はこちらを推奨します。 #### ツッコミのメール通知を、本体内蔵からプラグインにしました。 comment_mail-smtp.rb 他のプラグインを使うようにしてください。 ### 1.4から2.0への主な変更点 1. 「長年日記」機能 2. カテゴリ機能追加(http://www.tdiary.org/20030224.html) 3. スタイル機能で記述形式を選択可能に(http://www.tdiary.org/20030225.html) 4. 更新前に内容を確認できるプレビュー機能 5. 設定画面の大幅機能拡張で絵日記などが可能に 6. ツッコミやリンク元を制限できるフィルタ機能 7. 更新画面に機能を追加できるプラグイン拡張 8. 国際化機能。標準でja(日本語)、en(英語)、zh(中国語繁字体)に対応 9. 各種ウェブログ機能(TrackBack、ping、RSS)対応(プラグイン併用) 1.2と1.4の違い ---- ### 1.2から1.4移行時の注意 #### *.rhtml、*.rconf、*.rtxtが、ディレクトリskelに移動しています。 これら以前のファイルは削除してかまいません。 #### ページ最上部に出ていたナビゲーションボタンが、プラグインとして独立し、自由な場所に配置できるようになりました。 この副作用で、ヘッダ(@header)に「<%=navi%>」という文字列を含めないとナビゲーションボタンが出てきません。移行後にブラウザからupdate.rbを開いて、ヘッダを変更してください。 ### 1.2から1.4への主な変更点 1. プラグインによる拡張機能 2. 最新表示で月をまたいだ表示 3. キャッシュによる高速化 4. 複数日記の運用が簡単に 5. 検索インデックス作成用squeeze.rbによる静的HTML生成 6. モバイルモード対象機種を充実 7. 特定の日付を隠せるようになった 1.0と1.2の違い ----- ### 1.0から1.2移行時の注意 #### CSSがthemeディレクトリへ移動になっています。 ここに*.cssを入れておくと、設定画面から対話式にテーマを切り替えることができます。従来のデフォルトCSSは、default.cssとしてthemeディレクトリに再録されています。 #### tdiary.confのフォーマットが少し変更になっています。 1.1以前のtDiaryから移行する場合には、以下の2行をtdiary.confの末尾に追加する必要があります。これを加えないと後述する対話式の設定変更機能が使えません。 ``` @secure = false load_cgi_conf ``` #### ヘッダやフッタにeRuby書式を許可したのに伴い、カレンダーの挿入位置を自由にできるようにしました。 このため、デフォルトではカレンダーは表示されません。従来のヘッダ(@header)、もしくはフッタ(@footer)に、「<%=calendar%>」という文字列を挿入して下さい。 #### CGIによる対話式設定が可能になりました。 従来tdiary.confで設定していた変数の多くはCGI経由で設定できます。しかし、いくつかの変数を除いて、一度CGI上で設定を変更してしまうと旧来のtdiary.confよりも優先されてしまいます。tdiary.conf.sampleにそのあたりの説明があるので、良く読んでください。 ### 1.0から1.2への主な変更点 1. CSSを使ったテーマに対応 2. ヘッダ(@header)とフッタ(@footer)にeRuby書式の記述が可能になった 3. カレンダーの挿入位置をヘッダとフッタ内で自由に指定可能になった 4. @multi_userで簡易マルチユーザモードを設定可能になった 5. @date_formatで、日付の表示形式をカスタマイズ可能になった 6. ブラウザ上で設定の変更ができるようになった 7. 用語の変更(Referer→リンク元、段落→セクション) 8. 新しいツッコミを入れやすいようにリンクを追加 9. 設定以上のツッコミがある場合に「More...」を表示 10. mod_ruby対応 11. 携帯端末の対応を拡充(各社携帯電話、ザウルス、Windows CE機) 12. *.rbをCGIとして設定できないサーバ上への設置に対応(@index、@update) 13. 任意のツッコミを非表示にできるようになった 14. ドキュメントの充実 15. 多数のバグFIX �������������������������������������������������������������������tdiary-core-5.1.1/doc/doc.css�����������������������������������������������������������������������0000664�0000000�0000000�00000002451�13626457307�0016003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* doc.css: CSS for tDiary documents 2002-11-13 TADA Tadashi <t@tdtds.jp> * created */ body { color: #000; background-color: #fff; line-height: 130%; } h1 { color: #fff; background-color: #32c832; border-style: solid; border-width: 0px 0px 2px 0px; border-color: #166416; padding: 4px; } div.footer { margin-right: 4px; text-align: right; clear: both; font-size: 80%; } a:link, a:visited { color: #32c832; background-color: transparent; text-decoration: none; } a:hover { text-decoration: underline; } hr.sep { display: none; } h2 { border-style: solid; border-color: #32c832; border-width: 0px 0px 1px 0px; } h3 { margin: 1em; } h4 { margin: 2em; } p { margin-left: 3em; } pre, p.sample { border-style: solid; border-color: #32c832; border-width: 1px 1px 1px 3px; margin-left: 5em; padding: 4px; } div.sample { border-style: solid; border-color: #32c832; border-width: 1px 1px 1px 3px; margin-left: 5em; padding: 4px; } dl { margin-left: 5em; } dt { font-weight: bold; } dd { margin-bottom: 0.5em; } ul, ol { margin-left: 5em; } li { margin-bottom: 0.5em; } table { color: #fff; background-color: #32c832; } th { color: #fff; background-color: #166416; padding: 0.2em; text-align: left; } td { color: #000; background-color: #fff; padding: 0.2em; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/dot.htaccess����������������������������������������������������������������������0000664�0000000�0000000�00000000773�13626457307�0016271�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Options +ExecCGI # if you run tDiary with symbolic link, use settings below. #Options +FollowSymLinks # if making anchor style as 'YYYYMMDD.html', add some settings below. # SEE header of html_anchor.rb plugin. AddHandler cgi-script .rb DirectoryIndex index.rb AddType application/xml .rdf <Files "*.rhtml*"> deny from all </Files> <Files "tdiary.*"> deny from all </Files> <Files update.rb> AuthName tDiary AuthType Basic AuthUserFile /home/foo/.htpasswd Require user foo </Files> �����tdiary-core-5.1.1/index.fcgi������������������������������������������������������������������������0000775�0000000�0000000�00000001760�13626457307�0015725�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env ruby # # index.fcgi $Revision: 1.35 $ # # Copyright (C) 2004, Akinori MUSHA # Copyright (C) 2006, moriq # Copyright (C) 2006-2009, Kazuhiko <kazuhiko@fdiary.net> # You can redistribute it and/or modify it under GPL2 or any later version. # require 'fcgi' # workaround untaint LOAD_PATH for rubygems library path is always tainted. $:.each{|path| path if path.include?('fcgi') } if FileTest::symlink?( __FILE__ ) then org_path = File::dirname( File::readlink( __FILE__ ) ) else org_path = File::dirname( __FILE__ ) end load "#{org_path}/misc/lib/fcgi_patch.rb" FCGI.each_cgi do |cgi| begin ENV.clear ENV.update(cgi.env_table) class << CGI; self; end.class_eval do define_method(:new) {|*args| cgi } end dir = File::dirname( cgi.env_table["SCRIPT_FILENAME"] || __FILE__ ) Dir.chdir(dir) do load 'index.rb' end ensure class << CGI remove_method :new end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������tdiary-core-5.1.1/index.rb��������������������������������������������������������������������������0000775�0000000�0000000�00000002647�13626457307�0015425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env ruby # -*- coding: ascii-8bit; -*- # # index.rb # # Copyright (C) 2001-2009, TADA Tadashi <t@tdtds.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # BEGIN { $stdout.binmode } begin if FileTest::symlink?( __FILE__ ) then org_path = File::dirname( File::readlink( __FILE__ ) ) else org_path = File::dirname( __FILE__ ) end $:.unshift( (org_path + '/lib') ) unless $:.include?( org_path + '/lib' ) require 'tdiary' encoding_error = {} cgi = CGI::new(accept_charset: "UTF-8") do |name, value| encoding_error[name] = value end if encoding_error.empty? @cgi = cgi else @cgi = CGI::new(accept_charset: 'shift_jis') @cgi.params = cgi.params end request = TDiary::Request.new( ENV, @cgi ) status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi ) TDiary::Dispatcher.send_headers( status, headers ) ::Rack::Handler::CGI.send_body(body) rescue Exception if @cgi then print @cgi.header( 'status' => CGI::HTTP_STATUS['SERVER_ERROR'], 'type' => 'text/html' ) else print "Status: 500 Internal Server Error\n" print "Content-Type: text/html\n\n" end puts "<h1>500 Internal Server Error</h1>" puts "<pre>" puts CGI::escapeHTML( "#{$!} (#{$!.class})" ) puts "" puts CGI::escapeHTML( $@.join( "\n" ) ) puts "</pre>" puts "<div>#{' ' * 500}</div>" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������tdiary-core-5.1.1/js/�������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0014371�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/00default.js�������������������������������������������������������������������0000664�0000000�0000000�00000004605�13626457307�0016520�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 00default.js: default javascript file for tDiary Copyright (C) 2010, TADA Tadashi <t@tdtds.jp> You can redistribute it and/or modify it under GPL2 or any later version. */ /* values of plugin settings */ $tDiary = new Object(); $tDiary.plugin = new Object(); $tDiary.blogkit = false; /* * https://github.com/jquery/jquery/blob/1.8.3/src/deprecated.js */ (function() { var matched, browser; // Use of jQuery.browser is frowned upon. // More details: http://api.jquery.com/jQuery.browser // jQuery.uaMatch maintained for back-compat jQuery.uaMatch = function( ua ) { ua = ua.toLowerCase(); var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || /(webkit)[ \/]([\w.]+)/.exec( ua ) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || /(msie) ([\w.]+)/.exec( ua ) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || []; return { browser: match[ 1 ] || "", version: match[ 2 ] || "0" }; }; matched = jQuery.uaMatch( navigator.userAgent ); browser = {}; if ( matched.browser ) { browser[ matched.browser ] = true; browser.version = matched.version; } // Chrome is Webkit, but Webkit is also Safari. if ( browser.chrome ) { browser.webkit = true; } else if ( browser.webkit ) { browser.safari = true; } jQuery.browser = browser; })(); /* utility functions */ $.fn.extend({ insertAtCaret: function(text){ var elem = this.get(0); elem.focus(); if(jQuery.browser.msie){ var selection = document.selection.createRange(); selection.text = text; selection.select(); }else{ var orig = elem.value; var posStart = elem.selectionStart; var posEnd = posStart + text.length; elem.value = orig.substr(0, posStart) + text + orig.substr(posStart); elem.setSelectionRange(posEnd, posEnd); } } }); $.extend({ makePluginTag: function(name, params){ params = params || []; var tag = []; switch($tDiary.style){ case 'wiki': case 'gfm': case 'markdown': tag = ['{{', '}}']; break; case 'rd': tag = ['((%', '%))']; break; default: tag = ['<%=', '%>']; break; } return tag[0] + name + ' ' + ($.isFunction(params) ? params() : $.map(params, function(p){ return '"' + p + '"'; })).join(', ') + tag[1]; } }); ���������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/01conf.js����������������������������������������������������������������������0000664�0000000�0000000�00000003533�13626457307�0016021�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 01conf.js: javascript for preferences pages of tDiary Copyright (C) 2011 by TADA Tadashi <t@tdtds.jp> You can redistribute it and/or modify it under GPL2 or any later version. */ $(function(){ $('#saving') .hide() .css('text-align', 'center') .css('margin-top', '10em'); $('#conf-form').submit(function(){ var form = $(this); $.ajax({ type: 'post', url: form.attr('action'), data: form.serialize() + '&saveconf=OK', dataType: 'html', beforeSend: function(){ form.hide(); $('#saving').show(); }, success: function(data){ if(location.search.match(/conf=(sp|csrf_protection)$/)){ location.reload(); } else { var result = data.match(/<form id="conf-form"[\s\S]*<\/form>/)[0]; $('#saving').hide(); form.empty().append($('div:first', result)).show(); } }, error: function(){ $('#saving').hide(); form.show(); alert('cannot save!'); } }); return false; }); /* * theme thumbnail changer */ $(document).on('change', '#theme_selection',function(){ var list = $(this); var image = $('#theme_thumbnail'); var theme = ''; if ( list.selectedIndex == 0 ) { theme = 'nowprinting'; } else { theme = list.val().replace(/^.*\//, ''); } image.attr('src', 'http://www.tdiary.org/theme.image/' + theme + '.jpg'); }); /* * old ruby alert */ $('#alert-old-ruby').on('click', function(){ var data = 'conf=old_ruby_alert;saveconf=OK'; var csrf_key = $('#conf-form input[name=csrf_protection_key]').attr('value'); if (csrf_key){ data += ';csrf_protection_key=' + csrf_key; } $.ajax({ url: $('#conf-form').attr('action'), type: 'POST', dataType: 'html', data: data }).done(function(html){ $('.alert-warn').hide(); }).fail(function(XMLHttpRequest, textStatus, errorThrown){ alert('failed saving settings.' + textStatus); }); }); }); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/02edit.js����������������������������������������������������������������������0000664�0000000�0000000�00000000604�13626457307�0016016�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������(function() { $(document).ready(function() { var form, targetArea; form = $('textarea'); targetArea = $('div.update > div.form').first(); if (form.width() < targetArea.width() / 2.5) { form.width(targetArea.width() / 2.5); } if (form.height() < targetArea.height() / 1.5) { return form.height(targetArea.height() / 1.5); } }); }).call(this); ����������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/amazon.js����������������������������������������������������������������������0000664�0000000�0000000�00000000452�13626457307�0016215�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * amazon.js : * * remove height / width infomation of images * * Copyright (C) 2015 by TADA Tadashi <t@tdtds.jp> * You can distribute it under GPL2 or any later version. */ $(function(){ if($(window).width() <= 360) { $('img.amazon').attr('height', null).attr('width', null); } }); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/amazon_bitly.js����������������������������������������������������������������0000664�0000000�0000000�00000002025�13626457307�0017416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * amazon_bitly.js : replace amazon URL using bit.ly (amzn.to). * * Copyright (C) 2011 by TADA Tadashi <t@tdtds.jp> * You can distribute it under GPL2 or any later version. */ $(function(){ function shorten(link){ var url = link.attr('href'); var api = 'http://api.bit.ly/v3/shorten' + '?format=json' + '&longUrl=' + encodeURIComponent(url) + '&login=' + $tDiary.plugin.bitly.login + '&apiKey=' + $tDiary.plugin.bitly.apiKey; $.ajax({ type: 'GET', url: api, dataType: 'jsonp', success: function(data){ if (data['data']){ link.attr('href',data['data']['url']); } else{ //console.warn('fail to short: ' + link.attr('href')); } } }); } $(window).on('scroll', function(event){ var bottom = $(window).height() + $(window).scrollTop(); //console.warn('window.bottom: ' + bottom); $('a[href*="://www.amazon.co.jp/"]').each(function(){ var a = $(this); if (bottom > a.offset().top){ //console.warn('appear!: ' + a.text()); shorten(a); } }); }); }); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/calendar3.js�������������������������������������������������������������������0000664�0000000�0000000�00000006131�13626457307�0016564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// http://www.din.or.jp/~hagi3/JavaScript/JSTips/Mozilla/ // _dom : kind of DOM. // IE4 = 1, IE5+ = 2, NN4 = 3, NN6+ = 4, others = 0 _dom = document.all?(document.getElementById?2:1) :(document.getElementById?4 :(document.layers?3:0)); var _calendar3_popElement = null; var _calendar3_popCount = 0; if (document.compatMode){ if (_dom==2 && document.compatMode=="CSS1Compat") _dom = 2.5; } // Win IE6 function getLeft(div){ result = 0; while (1){ div = div.offsetParent; result += div.offsetLeft; if (div.tagName=="BODY") return result; } } function getTop(div){ result = 0; while (1){ div = div.offsetParent; result += div.offsetTop; if (div.tagName=="BODY") return result; } } function moveDivTo(div,left,top){ if(_dom==4){ div.style.left=left+'px'; div.style.top =top +'px'; return; } if(_dom==2.5 || _dom==2 || _dom==1){ div.style.pixelLeft=left; div.style.pixelTop =top; return; } if(_dom==3){ div.moveTo(left,top); return; } } function moveDivBy(div,left,top){ if(_dom==4){ div.style.left=div.offsetLeft+left; div.style.top =div.offsetTop +top; return; } if(_dom==2.5 || _dom==2){ div.style.pixelLeft=div.offsetLeft+left; div.style.pixelTop =div.offsetTop +top; return; } if(_dom==1){ div.style.pixelLeft+=left; div.style.pixelTop +=top; return; } if(_dom==3){ div.moveBy(left,top); return; } } function getDivLeft(div){ if(_dom==2.5) return div.offsetLeft+getLeft(div); if(_dom==4 || _dom==2) return div.offsetLeft; if(_dom==1) return div.style.pixelLeft; if(_dom==3) return div.left; return 0; } function getDivTop(div){ if(_dom==2.5) return div.offsetTop+getTop(div); if(_dom==4 || _dom==2) return div.offsetTop; if(_dom==1) return div.style.pixelTop; if(_dom==3) return div.top; return 0; } function getDivWidth (div){ if(_dom==4 || _dom==2.5 || _dom==2) return div.offsetWidth; if(_dom==1) return div.style.pixelWidth; if(_dom==3) return div.clip.width; return 0; } function getDivHeight(div){ if(_dom==4 || _dom==2.5 || _dom==2) return div.offsetHeight; if(_dom==1) return div.style.pixelHeight; if(_dom==3) return div.clip.height; return 0; } function popup(target,element,notitle) { _calendar3_popCount++; popdownNow(); if (navigator.appName=='Microsoft Internet Explorer') { moveDivTo(element,getDivLeft(target)+getDivWidth(target),getDivTop(target)+getDivHeight(target)*13/8); } else { moveDivTo(element,getDivLeft(target)+getDivWidth(target)/2,getDivTop(target)+(getDivHeight(target)*2)/3); } element.style.display="block"; notitle.title=""; } function popdown(element) { _calendar3_popElement=element; setTimeout('popdownDelay()', 2000); } function popdownDelay() { _calendar3_popCount--; if (_calendar3_popCount==0) { popdownNow(); } } function popdownNow() { if (_calendar3_popElement!=null) { _calendar3_popElement.style.display="none"; _calendar3_popElement=null; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/caretposition.js���������������������������������������������������������������0000664�0000000�0000000�00000013244�13626457307�0017616�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* caretposition.js Copyright (c) 2012- Hiroki Akiyama http://akiroom.com/ caretposition.js is free software distributed under the terms of the MIT license. */ Measurement = new function() { this.caretPos = function(textarea, mode) { var targetElement = textarea; if (typeof jQuery != 'undefined') { if (textarea instanceof jQuery) { targetElement = textarea.get(0); } } // HTML Sanitizer var escapeHTML = function (s) { var obj = document.createElement('pre'); obj[typeof obj.textContent != 'undefined'?'textContent':'innerText'] = s; return obj.innerHTML; }; // Get caret character position. var getCaretPosition = function (element) { var CaretPos = 0; var startpos = -1; var endpos = -1; if (document.selection) { // IE Support(not yet) var docRange = document.selection.createRange(); var textRange = document.body.createTextRange(); textRange.moveToElementText(element); var range = textRange.duplicate(); range.setEndPoint('EndToStart', docRange); startpos = range.text.length; var range = textRange.duplicate(); range.setEndPoint('EndToEnd', docRange); endpos = range.text.length; } else if (element.selectionStart || element.selectionStart == '0') { // Firefox support startpos = element.selectionStart; endpos = element.selectionEnd; } return {start: startpos, end: endpos}; }; // Get element css style. var getStyle = function (element) { var style = element.currentStyle || document.defaultView.getComputedStyle(element, ''); return style; }; // Get element absolute position var getElementPosition = function (element) { // Get scroll amount. var html = document.documentElement; var body = document.body; var scrollLeft = (body.scrollLeft || html.scrollLeft); var scrollTop = (body.scrollTop || html.scrollTop); // Adjust "IE 2px bugfix" and scroll amount. var rect = element.getBoundingClientRect(); var left = rect.left - html.clientLeft + scrollLeft; var top = rect.top - html.clientTop + scrollTop; var right = rect.right - html.clientLeft + scrollLeft; var bottom = rect.bottom - html.clientTop + scrollTop; return {left: parseInt(left), top: parseInt(top), right: parseInt(right), bottom:parseInt(bottom)}; }; /***************************\ * Main function start here! * \***************************/ var undefined; var salt = "salt.akiroom.com"; var textAreaPosition = getElementPosition(targetElement); var dummyName = targetElement.id + "_dummy"; var dummyTextArea = document.getElementById(dummyName); if (!dummyTextArea) { // Generate dummy textarea. dummyTextArea = document.createElement("div"); dummyTextArea.id = dummyName; var textAreaStyle = getStyle(targetElement) dummyTextArea.style.cssText = textAreaStyle.cssText; // Fix for browser differece. var isWordWrap = false; if (targetElement.wrap == "off") { // chrome, firefox wordwrap=off dummyTextArea.style.overflow = "auto"; dummyTextArea.style.whiteSpace = "pre"; isWordWrap = false; } else if (targetElement.wrap == undefined) { if (textAreaStyle.wordWrap == "break-word") // safari, wordwrap=on isWordWrap = true; else // safari, wordwrap=off isWordWrap = false; } else { // firefox wordwrap=on dummyTextArea.style.overflowY = "auto"; isWordWrap = true; } dummyTextArea.style.visibility = 'hidden'; dummyTextArea.style.position = 'absolute'; dummyTextArea.style.top = '0px'; dummyTextArea.style.left = '0px'; // Firefox Support dummyTextArea.style.width = textAreaStyle.width; dummyTextArea.style.height = textAreaStyle.height; dummyTextArea.style.fontSize = textAreaStyle.fontSize; dummyTextArea.style.maxWidth = textAreaStyle.width; dummyTextArea.style.backgroundColor = textAreaStyle.backgroundColor; dummyTextArea.style.fontFamily = textAreaStyle.fontFamily; targetElement.parentNode.appendChild(dummyTextArea); } // Set scroll amount to dummy textarea. dummyTextArea.scrollLeft = targetElement.scrollLeft; dummyTextArea.scrollTop = targetElement.scrollTop; // Set code strings. var codeStr = targetElement.value; // Get caret character position. var selPos = getCaretPosition(targetElement); var leftText = codeStr.slice(0, selPos.start); var selText = codeStr.slice(selPos.start, selPos.end); var rightText = codeStr.slice(selPos.end, codeStr.length); if (selText == '') selText = "a"; // Set keyed text. var processText = function (text) { // Get array of [Character reference] or [Character] or [NewLine]. var m = escapeHTML(text).match(/((&|<|>|"|')|.|\n)/g); if (m) return m.join('<wbr>').replace(/\n/g, '<br>'); else return ''; }; // Set calculation text for in dummy text area. dummyTextArea.innerHTML = (processText(leftText) + '<wbr><span id="' + dummyName + '_i">' + processText(selText) + '</span><wbr>' + processText(rightText)); // Get caret absolutely pixel position. var dummyTextAreaPos = getElementPosition(dummyTextArea); var caretPos = getElementPosition(document.getElementById(dummyName+"_i")); switch (mode) { case 'self': // Return absolutely pixel position - (0,0) is most top-left of TEXTAREA. return {left: caretPos.left-dummyTextAreaPos.left, top: caretPos.top-dummyTextAreaPos.top}; case 'body': case 'screen': case 'stage': case 'page': default: // Return absolutely pixel position - (0,0) is most top-left of PAGE. return {left: textAreaPosition.left+caretPos.left-dummyTextAreaPos.left, top: textAreaPosition.top+caretPos.top-dummyTextAreaPos.top}; } }; }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/category.js��������������������������������������������������������������������0000664�0000000�0000000�00000001456�13626457307�0016552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* category.js: javascript for category.rb plugin of tDiary Copyright (C) 2011 by TADA Tadashi <t@tdtds.jp> You can redistribute it and/or modify it under GPL2 or any later version. */ $(function(){ // insert clicked category item into textarea of update form function insertCategoryItem(item) { $('#body').insertAtCaret( '[' + item.text() + ']' ); } $('.category-item') .hover(function(){ $(this).css('cursor', 'pointer'); }, function(){ $(this).css('cursor', 'default'); }) .click(function(){ insertCategoryItem($(this)); }); $('#category-candidate').change(function(){ $('option:selected', this).each(function(){ insertCategoryItem($(this)); }); }); // reverse list of category var list = $('ul.category li').toArray().reverse(); $('ul.category').empty().append(list); }); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/category_autocomplete.js�������������������������������������������������������0000664�0000000�0000000�00000004526�13626457307�0021334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * category_autocomplete.js : Support the automatic input of the category, * using jQuery UI autocomplete. * * Copyright (C) 2012 by tamoot <tamoot+tdiary@gmail.com> * You can distribute it under GPL2 or any later version. */ $(function() { var config = $tDiary.plugin.category_autocomplete; var support = false; var regrep = "" if ( $tDiary.style == "tdiary" ){ support = true; regrep = "^ *\\[.*"; } else if ( $tDiary.style == 'gfm' ) { support = true; regrep = "^# *\\[.*"; } else if ( $tDiary.style == "wiki" ){ support = true; regrep = "^! *\\[.*"; } function widgetPosition(){ var caretPosition = Measurement.caretPos($("#body")); return {left: caretPosition.left + "px", top: caretPosition.top + 20 + "px", width: "auto"}; } function matchedCategory(val){ if(support == false){ return false; } terms = val.split("\n"); term = terms[ terms.length - 1]; var matched = term.match(regrep); if( matched == null ){ return false; } return true; } function typedCategory( term ) { var array = term.split("["); return array[ array.length - 1 ]; } $( "#body" ) .on( "keydown", function( event ) { if ( event.keyCode === $.ui.keyCode.TAB && $( this ).data( "autocomplete" ).menu.active ) { event.preventDefault(); } }) .autocomplete({ delay: 500, //filtering source: function( request, response ) { if(matchedCategory(request.term)){ response( $.ui.autocomplete.filter( config.candidates, typedCategory( request.term ) ) ); } }, // prevent value inserted on focus focus: function() { return false; }, // replace textarea select: function( event, ui ) { var terms = this.value.split("["); // remove the current typed category terms.pop(); // add the selected item terms.push( ui.item.value ); this.value = terms.join( "[" ) + "]"; return false; }, // re-positioning supports excluding IE. open: function(){ if (! document.uniqueID) { $(".ui-autocomplete").css(widgetPosition()) } } }); }); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/comment_ajax.js����������������������������������������������������������������0000664�0000000�0000000�00000001625�13626457307�0017400�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * comment_ajax.js: * * Copyright (C) 2013 by MATSUOKA Kohei <kohei@machu.jp> * You can distribute it under GPL2 or any later version. */ $(function() { $(document).on('submit', 'form.comment', function(e) { e.preventDefault(); var form = $(this); $('<input type="hidden">').attr('name', 'comment').appendTo(form); $(':submit', form).attr('disabled', 'disabled'); $('div.button input', form).hide(); $('div.button', form).append('<div id="loading-button"><img src="' + $tDiary.plugin.comment_ajax.theme + '/loading.gif">') $.post(form.attr('action'), form.serialize(), function(data) { $('#loading-button').remove(); $('div.button input', form).show(); form[0].reset(); $(':submit', form).removeAttr('disabled'); // $(data) is a diary HTML of the day $('div.comment:first', form.parents('div.day')) .after($('div.comment', $(data))) .remove(); }, 'html'); }); }); �����������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/comment_emoji_autocomplete.js��������������������������������������������������0000664�0000000�0000000�00000036770�13626457307�0022352�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * emoji_autocomplete.js : Support the automatic input of the emoji, * using jQuery UI autocomplete. * * Copyright (C) 2013 by tamoot <tamoot+tdiary@gmail.com> * You can distribute it under GPL2 or any later version. */ $(function() { var config = new Object(); config.candidates = [":blush:",":scream:",":smirk:",":smiley:",":stuck_out_tongue_closed_eyes:",":stuck_out_tongue_winking_eye:",":rage:",":disappointed:",":sob:",":kissing_heart:",":wink:",":pensive:",":confounded:",":flushed:",":relaxed:",":mask:",":heart:",":broken_heart:",":sunny:",":umbrella:",":cloud:",":snowflake:",":snowman:",":zap:",":cyclone:",":foggy:",":ocean:",":cat:",":dog:",":mouse:",":hamster:",":rabbit:",":wolf:",":frog:",":tiger:",":koala:",":bear:",":pig:",":pig_nose:",":cow:",":boar:",":monkey_face:",":monkey:",":horse:",":racehorse:",":camel:",":sheep:",":elephant:",":panda_face:",":snake:",":bird:",":baby_chick:",":hatched_chick:",":hatching_chick:",":chicken:",":penguin:",":turtle:",":bug:",":honeybee:",":ant:",":beetle:",":snail:",":octopus:",":tropical_fish:",":fish:",":whale:",":whale2:",":dolphin:",":cow2:",":ram:",":rat:",":water_buffalo:",":tiger2:",":rabbit2:",":dragon:",":goat:",":rooster:",":dog2:",":pig2:",":mouse2:",":ox:",":dragon_face:",":blowfish:",":crocodile:",":dromedary_camel:",":leopard:",":cat2:",":poodle:",":paw_prints:",":bouquet:",":cherry_blossom:",":tulip:",":four_leaf_clover:",":rose:",":sunflower:",":hibiscus:",":maple_leaf:",":leaves:",":fallen_leaf:",":herb:",":mushroom:",":cactus:",":palm_tree:",":evergreen_tree:",":deciduous_tree:",":chestnut:",":seedling:",":blossom:",":ear_of_rice:",":shell:",":globe_with_meridians:",":sun_with_face:",":full_moon_with_face:",":new_moon_with_face:",":new_moon:",":waxing_crescent_moon:",":first_quarter_moon:",":waxing_gibbous_moon:",":full_moon:",":waning_gibbous_moon:",":last_quarter_moon:",":waning_crescent_moon:",":last_quarter_moon_with_face:",":first_quarter_moon_with_face:",":moon:",":earth_africa:",":earth_americas:",":earth_asia:",":volcano:",":milky_way:",":partly_sunny:",":octocat:",":squirrel:",":bamboo:",":gift_heart:",":dolls:",":school_satchel:",":mortar_board:",":flags:",":fireworks:",":sparkler:",":wind_chime:",":rice_scene:",":jack_o_lantern:",":ghost:",":santa:",":christmas_tree:",":gift:",":bell:",":no_bell:",":tanabata_tree:",":tada:",":confetti_ball:",":balloon:",":crystal_ball:",":cd:",":dvd:",":floppy_disk:",":camera:",":video_camera:",":movie_camera:",":computer:",":tv:",":iphone:",":phone:",":telephone:",":telephone_receiver:",":pager:",":fax:",":minidisc:",":vhs:",":sound:",":speaker:",":mute:",":loudspeaker:",":mega:",":hourglass:",":hourglass_flowing_sand:",":alarm_clock:",":watch:",":radio:",":satellite:",":loop:",":mag:",":mag_right:",":unlock:",":lock:",":lock_with_ink_pen:",":closed_lock_with_key:",":key:",":bulb:",":flashlight:",":high_brightness:",":low_brightness:",":electric_plug:",":battery:",":calling:",":email:",":mailbox:",":postbox:",":bath:",":bathtub:",":shower:",":toilet:",":wrench:",":nut_and_bolt:",":hammer:",":seat:",":moneybag:",":yen:",":dollar:",":pound:",":euro:",":credit_card:",":money_with_wings:",":e-mail:",":inbox_tray:",":outbox_tray:",":envelope:",":incoming_envelope:",":postal_horn:",":mailbox_closed:",":mailbox_with_mail:",":mailbox_with_no_mail:",":door:",":smoking:",":bomb:",":gun:",":hocho:",":pill:",":syringe:",":page_facing_up:",":page_with_curl:",":bookmark_tabs:",":bar_chart:",":chart_with_upwards_trend:",":chart_with_downwards_trend:",":scroll:",":clipboard:",":calendar:",":date:",":card_index:",":file_folder:",":open_file_folder:",":scissors:",":pushpin:",":paperclip:",":black_nib:",":pencil2:",":straight_ruler:",":triangular_ruler:",":closed_book:",":green_book:",":blue_book:",":orange_book:",":notebook:",":notebook_with_decorative_cover:",":ledger:",":books:",":bookmark:",":name_badge:",":microscope:",":telescope:",":newspaper:",":football:",":basketball:",":soccer:",":baseball:",":tennis:",":8ball:",":rugby_football:",":bowling:",":golf:",":mountain_bicyclist:",":bicyclist:",":horse_racing:",":snowboarder:",":swimmer:",":surfer:",":ski:",":spades:",":hearts:",":clubs:",":diamonds:",":gem:",":ring:",":trophy:",":musical_score:",":musical_keyboard:",":violin:",":space_invader:",":video_game:",":black_joker:",":flower_playing_cards:",":game_die:",":dart:",":mahjong:",":clapper:",":memo:",":pencil:",":book:",":art:",":microphone:",":headphones:",":trumpet:",":saxophone:",":guitar:",":shoe:",":sandal:",":high_heel:",":lipstick:",":boot:",":shirt:",":tshirt:",":necktie:",":womans_clothes:",":dress:",":running_shirt_with_sash:",":jeans:",":kimono:",":bikini:",":ribbon:",":tophat:",":crown:",":womans_hat:",":mans_shoe:",":closed_umbrella:",":briefcase:",":handbag:",":pouch:",":purse:",":eyeglasses:",":fishing_pole_and_fish:",":coffee:",":tea:",":sake:",":baby_bottle:",":beer:",":beers:",":cocktail:",":tropical_drink:",":wine_glass:",":fork_and_knife:",":pizza:",":hamburger:",":fries:",":poultry_leg:",":meat_on_bone:",":spaghetti:",":curry:",":fried_shrimp:",":bento:",":sushi:",":fish_cake:",":rice_ball:",":rice_cracker:",":rice:",":ramen:",":stew:",":oden:",":dango:",":egg:",":bread:",":doughnut:",":custard:",":icecream:",":ice_cream:",":shaved_ice:",":birthday:",":cake:",":cookie:",":chocolate_bar:",":candy:",":lollipop:",":honey_pot:",":apple:",":green_apple:",":tangerine:",":lemon:",":cherries:",":grapes:",":watermelon:",":strawberry:",":peach:",":melon:",":banana:",":pear:",":pineapple:",":sweet_potato:",":eggplant:",":tomato:",":corn:",":alien:",":angel:",":anger:",":angry:",":anguished:",":astonished:",":baby:",":blue_heart:",":blush:",":boom:",":bow:",":bowtie:",":boy:",":bride_with_veil:",":broken_heart:",":bust_in_silhouette:",":busts_in_silhouette:",":clap:",":cold_sweat:",":collision:",":confounded:",":confused:",":construction_worker:",":cop:",":couple_with_heart:",":couple:",":couplekiss:",":cry:",":crying_cat_face:",":cupid:",":dancer:",":dancers:",":dash:",":disappointed:",":dizzy_face:",":dizzy:",":droplet:",":ear:",":exclamation:",":expressionless:",":eyes:",":facepunch:",":family:",":fearful:",":feelsgood:",":feet:",":finnadie:",":fire:",":fist:",":flushed:",":frowning:",":girl:",":goberserk:",":godmode:",":green_heart:",":grey_exclamation:",":grey_question:",":grimacing:",":grin:",":grinning:",":guardsman:",":haircut:",":hand:",":hankey:",":hear_no_evil:",":heart_eyes_cat:",":heart_eyes:",":heart:",":heartbeat:",":heartpulse:",":hurtrealbad:",":hushed:",":imp:",":information_desk_person:",":innocent:",":japanese_goblin:",":japanese_ogre:",":joy_cat:",":joy:",":kiss:",":kissing_cat:",":kissing_closed_eyes:",":kissing_heart:",":kissing_smiling_eyes:",":kissing:",":laughing:",":lips:",":love_letter:",":man_with_gua_pi_mao:",":man_with_turban:",":man:",":mask:",":massage:",":metal:",":muscle:",":musical_note:",":nail_care:",":neckbeard:",":neutral_face:",":no_good:",":no_mouth:",":nose:",":notes:",":ok_hand:",":ok_woman:",":older_man:",":older_woman:",":open_hands:",":open_mouth:",":pensive:",":persevere:",":person_frowning:",":person_with_blond_hair:",":person_with_pouting_face:",":point_down:",":point_left:",":point_right:",":point_up_2:",":point_up:",":poop:",":pouting_cat:",":pray:",":princess:",":punch:",":purple_heart:",":question:",":rage:",":rage1:",":rage2:",":rage3:",":rage4:",":raised_hand:",":raised_hands:",":relaxed:",":relieved:",":revolving_hearts:",":runner:",":running:",":satisfied:",":scream_cat:",":scream:",":see_no_evil:",":shit:",":skull:",":sleeping:",":sleepy:",":smile_cat:",":smile:",":smiley_cat:",":smiley:",":smiling_imp:",":smirk_cat:",":smirk:",":sob:",":sparkling_heart:",":sparkles:",":speak_no_evil:",":speech_balloon:",":star:",":star2:",":stuck_out_tongue_closed_eyes:",":stuck_out_tongue_winking_eye:",":stuck_out_tongue:",":sunglasses:",":suspect:",":sweat_drops:",":sweat_smile:",":sweat:",":thought_balloon:",":-1:",":thumbsdown:",":thumbsup:",":+1:",":tired_face:",":tongue:",":triumph:",":trollface:",":two_hearts:",":two_men_holding_hands:",":two_women_holding_hands:",":unamused:",":v:",":walking:",":wave:",":weary:",":wink2:",":wink:",":woman:",":worried:",":yellow_heart:",":yum:",":zzz:",":109:",":house:",":house_with_garden:",":school:",":office:",":post_office:",":hospital:",":bank:",":convenience_store:",":love_hotel:",":hotel:",":wedding:",":church:",":department_store:",":european_post_office:",":city_sunrise:",":city_sunset:",":japanese_castle:",":european_castle:",":tent:",":factory:",":tokyo_tower:",":japan:",":mount_fuji:",":sunrise_over_mountains:",":sunrise:",":stars:",":statue_of_liberty:",":bridge_at_night:",":carousel_horse:",":rainbow:",":ferris_wheel:",":fountain:",":roller_coaster:",":ship:",":speedboat:",":boat:",":sailboat:",":rowboat:",":anchor:",":rocket:",":airplane:",":helicopter:",":steam_locomotive:",":tram:",":mountain_railway:",":bike:",":aerial_tramway:",":suspension_railway:",":mountain_cableway:",":tractor:",":blue_car:",":oncoming_automobile:",":car:",":red_car:",":taxi:",":oncoming_taxi:",":articulated_lorry:",":bus:",":oncoming_bus:",":rotating_light:",":police_car:",":oncoming_police_car:",":fire_engine:",":ambulance:",":minibus:",":truck:",":train:",":station:",":train2:",":bullettrain_front:",":bullettrain_side:",":light_rail:",":monorail:",":railway_car:",":trolleybus:",":ticket:",":fuelpump:",":vertical_traffic_light:",":traffic_light:",":warning:",":construction:",":beginner:",":atm:",":slot_machine:",":busstop:",":barber:",":hotsprings:",":checkered_flag:",":crossed_flags:",":izakaya_lantern:",":moyai:",":circus_tent:",":performing_arts:",":round_pushpin:",":triangular_flag_on_post:",":jp:",":kr:",":cn:",":us:",":fr:",":es:",":it:",":ru:",":gb:",":uk:",":de:",":100:",":1234:",":one:",":two:",":three:",":four:",":five:",":six:",":seven:",":eight:",":nine:",":keycap_ten:",":zero:",":hash:",":symbols:",":arrow_backward:",":arrow_down:",":arrow_forward:",":arrow_left:",":capital_abcd:",":abcd:",":abc:",":arrow_lower_left:",":arrow_lower_right:",":arrow_right:",":arrow_up:",":arrow_upper_left:",":arrow_upper_right:",":arrow_double_down:",":arrow_double_up:",":arrow_down_small:",":arrow_heading_down:",":arrow_heading_up:",":leftwards_arrow_with_hook:",":arrow_right_hook:",":left_right_arrow:",":arrow_up_down:",":arrow_up_small:",":arrows_clockwise:",":arrows_counterclockwise:",":rewind:",":fast_forward:",":information_source:",":ok:",":twisted_rightwards_arrows:",":repeat:",":repeat_one:",":new:",":top:",":up:",":cool:",":free:",":ng:",":cinema:",":koko:",":signal_strength:",":u5272:",":u5408:",":u55b6:",":u6307:",":u6708:",":u6709:",":u6e80:",":u7121:",":u7533:",":u7a7a:",":u7981:",":sa:",":restroom:",":mens:",":womens:",":baby_symbol:",":no_smoking:",":parking:",":wheelchair:",":metro:",":baggage_claim:",":accept:",":wc:",":potable_water:",":put_litter_in_its_place:",":secret:",":congratulations:",":m:",":passport_control:",":left_luggage:",":customs:",":ideograph_advantage:",":cl:",":sos:",":id:",":no_entry_sign:",":underage:",":no_mobile_phones:",":do_not_litter:",":non-potable_water:",":no_bicycles:",":no_pedestrians:",":children_crossing:",":no_entry:",":eight_spoked_asterisk:",":eight_pointed_black_star:",":heart_decoration:",":vs:",":vibration_mode:",":mobile_phone_off:",":chart:",":currency_exchange:",":aries:",":taurus:",":gemini:",":cancer:",":leo:",":virgo:",":libra:",":scorpius:",":sagittarius:",":capricorn:",":aquarius:",":pisces:",":ophiuchus:",":six_pointed_star:",":negative_squared_cross_mark:",":a:",":b:",":ab:",":o2:",":diamond_shape_with_a_dot_inside:",":recycle:",":end:",":on:",":soon:",":clock1:",":clock130:",":clock10:",":clock1030:",":clock11:",":clock1130:",":clock12:",":clock1230:",":clock2:",":clock230:",":clock3:",":clock330:",":clock4:",":clock430:",":clock5:",":clock530:",":clock6:",":clock630:",":clock7:",":clock730:",":clock8:",":clock830:",":clock9:",":clock930:",":heavy_dollar_sign:",":copyright:",":registered:",":tm:",":x:",":heavy_exclamation_mark:",":bangbang:",":interrobang:",":o:",":heavy_multiplication_x:",":heavy_plus_sign:",":heavy_minus_sign:",":heavy_division_sign:",":white_flower:",":heavy_check_mark:",":ballot_box_with_check:",":radio_button:",":link:",":curly_loop:",":wavy_dash:",":part_alternation_mark:",":trident:",":black_square:",":white_square:",":white_check_mark:",":black_square_button:",":white_square_button:",":black_circle:",":white_circle:",":red_circle:",":large_blue_circle:",":large_blue_diamond:",":large_orange_diamond:",":small_blue_diamond:",":small_orange_diamond:",":small_red_triangle:",":small_red_triangle_down:",":shipit:"]; var regrep = ":.+$"; function widgetPosition(){ var caretPosition = Measurement.caretPos($("textarea[name=body]")); return { left: caretPosition.left + "px", top: caretPosition.top + 20 + "px", width: "auto" }; } function matchedEmoji(val){ terms = val.split("\n"); term = terms[ terms.length - 1]; var matched = term.match(regrep); if( matched == null ){ return false; } return true; } function typedEmoji( term ) { var array = term.split(":"); return array[ array.length - 1 ]; } $( "textarea[name=body]" ) .on( "keydown", function( event ) { if ( event.keyCode === $.ui.keyCode.TAB && $( this ).data( "autocomplete" ).menu.active ) { event.preventDefault(); } }) .autocomplete({ delay: 500, //filtering source: function( request, response ) { if(matchedEmoji(request.term)){ response( $.ui.autocomplete.filter( config.candidates, typedEmoji( request.term ) ) ); } }, // prevent value inserted on focus focus: function() { return false; }, // replace textarea select: function( event, ui ) { // no match data ... if (ui.item.value == null){ return false; } var terms = this.value.split(":"); // remove the current typed emoji terms.pop(); // add the selected item terms.push( ui.item.value.replace(/:/g, "") ); this.value = terms.join( ":" ) + ":"; return false; }, // re-positioning supports excluding IE. open: function(){ if (! document.uniqueID) { $(".ui-autocomplete").css(widgetPosition()) } } }) // customize autocomplate item $.ui.autocomplete.prototype._renderItem = function( ul, item ) { var icon_img = null; if (item.value != null){ png_basename = item.value.replace(/:/g, ""); if (png_basename == '+1'){ png_basename = 'plus1' } icon_img = $("<img>").attr('src', '//www.webpagefx.com/tools/emoji-cheat-sheet/graphics/emojis/' + png_basename + '.png') .css('width', '20').css('height', '20'); } var label_a = $("<a></a>") .append(icon_img) .append(item.label) return $( "<li></li>" ) .data( "item.autocomplete", item ) .append(label_a) .appendTo( ul ); }; // customize filter and result $.ui.autocomplete.filter = function(array, term) { var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); var aryMatches = $.grep( array, function(value) { return matcher.test(value.label || value.value || value); }); if (aryMatches.length == 0){ aryMatches.push({ label: '<span class="info" style="font-style: italic;">no match found</span>', value: null }); } return aryMatches; }; }); ��������tdiary-core-5.1.1/js/draft.js�����������������������������������������������������������������������0000664�0000000�0000000�00000010326�13626457307�0016031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * draft.js: save draft data to Web Storage automatically * * Copyright (c) MATSUOKA Kohei <http://www.machu.jp/> * Distributed under the GPL2 or any later version. */ $(function() { if (!localStorage) { return; } var Draft = function(storage, text) { // 保存先のストレージ this.storage = storage; // 下書きの保存件数 this.maxCount = 10; // 下書き一覧 this.items = []; this.initialize(text); }; Draft.prototype = { // ローカルストレージから下書きを読み込む initialize: function(text) { this.items = this.storage.drafts ? JSON.parse(this.storage.drafts) : new Array(); // 下書きに空の日記・テキストエリアと同じ日記が存在すれば削除する this.items = $.grep(this.items, function(item, index) { // 改行と空白文字を無視して比較(プレビュー時に末尾へ改行が付加されるため) if (item.value == "" || DraftUtils.trim(item.value) == DraftUtils.trim(text)) { return false; } return true; }); this.save(text, true); // console.log("Draft.initialized"); }, // ローカルストレージに下書きを保存する // append が true の場合は、下書き一覧の末尾に追加する // append が false の場合は、最後の下書きに上書きする save: function(text, append) { if (!append) { this.items.pop(); } this.items.push({ date: new Date().getTime(), value: text }); // 最大でmaxCount件数の履歴を保持 if (this.items.length > this.maxCount) { this.items.shift(); } this.storage.drafts = JSON.stringify(this.items); }, // 下書き一覧から index 番目の下書きを取得する // 取得した下書きは一覧の末尾に移動する load: function(index) { var item = this.items.splice(index, 1)[0]; this.items.push(item); return item.value; }, // 下書きのタイトル一覧の配列を返す(表示用) // タイトルは textarea の先頭1行目 + 更新日時 titles: function() { return $.map(this.items, function(item) { var date = new Date(item.date); date = DraftUtils.dateToString(date); var title = "No-Name"; if (item.value && typeof item.value == "string") { title = item.value.match(/.*/)[0]; } return title + " (" + date + ")"; }); } }; // ユーティリティ関数 var DraftUtils = { // 日付を YYYY-mm-dd HH:MM:SS 形式に変換する dateToString: function(date) { var d = date || new Date(); var year = d.getFullYear(); var month = zp(d.getMonth() + 1); date = zp(d.getDate()); var hour = zp(d.getHours()); var min = zp(d.getMinutes()); var sec = zp(d.getSeconds()); return year + "-" + month + "-" + date + " " + hour + ":" + min + ":" + sec; function zp(s, l) { s = String(s); l = l || 2; while (s.length < l) { s = "0" + s; } return s; } }, // 文字列から改行と空白文字を取り除く trim: function(str) { return str.replace(/\s+/g, ""); } }; // --------------------------------------- // ここからDOMの初期化処理 // --------------------------------------- // 保存対象のテキストエリア var textarea = $("[name=body]"); // 下書き一覧を表示するセレクトボックス var select = $("[name=drafts]"); // 自動保存の間隔(ミリ秒) var autoSaveInterval = 5 * 1000; var draft = new Draft(localStorage, textarea.val()); // 下書き保存 saveDraft = function() { draft.save(textarea.val()); showSelectForm(true); }; // 下書き読み込み loadDraft = function() { textarea.val(draft.load(select.val())); showSelectForm(false); }; // 下書き選択用のセレクトボックスを描画 showSelectForm = function(keepIndex) { var index = select.val(); select.empty(); $.each(draft.titles(), function(i, title) { select.append($("<option/>").attr("value", i).text(title)); select.val(i); }); if (keepIndex) { select.val(index); } }; // DOMイベント設定 $("#draft_load").click(loadDraft); setInterval(saveDraft, autoSaveInterval); textarea.change(saveDraft); showSelectForm(false); // console.log("ready"); }); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/highlight.js�������������������������������������������������������������������0000664�0000000�0000000�00000001701�13626457307�0016675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * highlight.js: Highlighting the element jumped from other pages. * * Copyright (C) 2003 by Ryuji SAKAI * Copyright (C) 2003 by Kazuhiro NISHIYAMA * Copyright (C) 2011 by MATSUOKA Kohei <kmachu@gmail.com> * You can distribute it under GPL2 or any later version. */ $(function() { function highlight(anchor) { // clear current highlight $(".highlight").removeClass("highlight"); // change document title var target = $(anchor).parent(); if (target.filter('h3').length > 0) { document.title = target.children("a").attr("title") + " - " + $tDiary.title; } target.addClass("highlight"); } // bind click event to anchors $(document.anchors) .filter(function() { return $(this).attr("name").match(/^[pc]/); }) .on("click", function() { highlight(this); }) if (document.location.hash) { highlight($('[name=' + document.location.hash.replace(/[^\w]/g, "") + ']')[0]); } }); ���������������������������������������������������������������tdiary-core-5.1.1/js/image.js�����������������������������������������������������������������������0000664�0000000�0000000�00000011060�13626457307�0016007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* image.js: javascript for image.rb plugin of tDiary Copyright (C) 2011 by TADA Tadashi <t@tdtds.jp> Copyright (C) 2011 by hb <smallstyle@gmail.com> You can redistribute it and/or modify it under GPL2 or any later version. */ function insertImage(text){ $('#body').insertAtCaret(text); } $(function(){ $('.image-img') .on('hover', function(){ $(this).css('cursor', 'pointer'); }, function(){ $(this).css('cursor', 'default'); }) .on('click', function(){ var idx = this.id.replace('image-index-', ''); var w = $('#image-info-' + idx + ' .image-width').text(); var h = $('#image-info-' + idx + ' .image-height').text(); $('#body').insertAtCaret($.makePluginTag('image', function(){ return [idx, "'" + $tDiary.plugin.image.alt + "'", 'nil', '[' + w + ',' + h + ']'] })); }); var ImagePlugin = function(url){ this.url =url; }; ImagePlugin.prototype = { upload: function(formData, callback){ $.ajax({ url: this.url, type: 'post', data: formData, processData: false, contentType: false, beforeSend: function(){ $('#plugin-image-addimage input[type="submit"]').attr('disabled', 'disabled'); $('#plugin-image-uploading').show(); }, success: function(data){ callback(data); }, complete: function(){ $('#plugin-image-addimage input[type="submit"]').removeAttr('disabled'); $('#plugin-image-uploading').hide(); } }); }, remove: function(data, callback){ $.ajax({ url: this.url, type: 'post', data: data, dataType: 'html', success: function(response){ callback(); } }); } }; $('#plugin-image-addimage input[name="plugin"]') .after($('<span>', {text: 'Uploading...'}).attr('id', 'plugin-image-uploading').hide()); $('#plugin-image-addimage form') .submit(function(e){ if(typeof(FormData) == 'undefined') { return true; } e.preventDefault(); uploadFiles(this.plugin_image_file.files); this.reset(); return false; }); var uploadFiles = function(files) { var formData = new FormData(); formData.append('plugin', 'image'); $.each($('#plugin-image-addimage input[type="hidden"]'), function(){ formData.append($(this).attr('name'), $(this).val()); }); $.each(files, function(i, file){ formData.append('plugin_image_file', file); }); var imagePlugin = new ImagePlugin($(this).attr('action')); imagePlugin.upload(formData, function(result){ $('#plugin-image-delimage').parents('div.form').remove(); $('<div>') .attr({ 'class': 'form' }) .append($('#plugin-image-delimage', result).parents('div.form').html()) .insertBefore('#plugin-image-addimage'); var timestamp = new Date().getTime(); $.each($('#plugin-image-delimage img'), function(){ $(this).attr('src', $(this).attr('src') + '?' + timestamp); }); }); return false; }; $('#plugin-image-delimage') .on('submit', function(e){ e.preventDefault(); var ids = $.map($('#image-table input[name="plugin_image_id"]:checked'), function(i){ return $(i).val(); }); var imagePlugin = new ImagePlugin($(this).attr('action')); imagePlugin.remove($(this).serialize() + '&plugin=image', function(){ $.each(ids, function(i, id){ $('#image-index-' + id).parent().fadeOut(); $('#image-info-' + id).fadeOut(); }); }); return false; }); if(window.File) { $('<div>') .attr({ id: 'plugin_image_dnd' }) .css({ 'height': '5em', 'text-align': 'center', 'line-height': '5em', 'background': '#ddd', 'border': 'dashed 3px #AAA' }) .on('dragenter', function(){ $(this).css('border', 'solid 3px #AAA'); return false; }) .on('dragleave', function(){ $(this).css('border', 'dashed 3px #CCC'); return false; }) .on('drop', function(e){ $('#plugin_image_dnd').hide(); $(this).css('border', 'dashed 3px #CCC'); $('#plugin-image-addimage form').show(); var files = e.originalEvent.dataTransfer.files; uploadFiles(files); return false; }) .text($tDiary.plugin.image.drop_here) .hide() .appendTo('#plugin-image-addimage'); var dnd_timer = false; $('body') .on('dragenter', function() { if (dnd_timer) { clearTimeout( dnd_timer ); } $('#plugin-image-addimage form').hide(); $('#plugin_image_dnd').show(); }) .on('dragover', function(){ if (dnd_timer) { clearTimeout( dnd_timer ); } return false; }) .on('dragleave', function(){ dnd_timer = setTimeout(function(){ $('#plugin_image_dnd').hide(); $('#plugin-image-addimage form').show(); }, 500); return false; }); } }); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/js/preview.js���������������������������������������������������������������������0000664�0000000�0000000�00000003713�13626457307�0016414�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * preview.js: view preview automatically * * Copyright (c) MATSUOKA Kohei <http://www.machu.jp/> * Distributed under the GPL2 or any later version. */ $(function() { var previewButton = $('input[name*="preview"]'); var intervalRate = 1; $tDiary.plugin.preview.reload = function() { previewButton.prop("disabled", true); $.post( 'update.rb', $('form.update').serialize() + "&appendpreview=1", function(data) { var previewContent = $(data).find('div.autopagerize_page_element'); if (previewContent.length != 0) { $('div.autopagerize_page_element').replaceWith(previewContent); intervalRate = 1; } else { intervalRate *= 2; console.info('[preview.js] update failed, the next update will be after ' + $tDiary.plugin.preview.interval * intervalRate + 'sec.'); } $('div.day') .css('flex', "1 1 " + $tDiary.plugin.preview.minWidth / 2 + "px"); }, 'html' ) .fail(function() { intervalRate *= 2; console.info('[preview.js] update failed, the next update will be after ' + $tDiary.plugin.preview.interval * intervalRate + 'sec.'); }) .always(function() { previewButton.prop("disabled", false); setTimeout($tDiary.plugin.preview.reload, $tDiary.plugin.preview.interval * 1000 * intervalRate); }); } if ($('div.autopagerize_page_element').length == 0) { $('div.update').before( '<div class="day autopagerize_page_element">' ); } $('<div class="preview-container"></div>') .css('display', 'flex') .css('flex-flow', 'row-reverse wrap') .insertAfter('h1') .append($('div.day')); $('div.day') .css('flex', "1 1 " + $tDiary.plugin.preview.minWidth / 2 + "px"); $("div.whole-content").css('max-width', 'none'); // プレビューボタンを押した時もajaxで更新するよう設定 previewButton.click( function(event) { event.preventDefault(); $tDiary.plugin.preview.reload(); } ); $tDiary.plugin.preview.reload(); }); �����������������������������������������������������tdiary-core-5.1.1/lib/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0014523�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/aws/��������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0015315�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/aws/pa_api.rb�����������������������������������������������������������������0000664�0000000�0000000�00000005451�13626457307�0017100�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'aws/sig_v4' require 'json' require 'net/http' module AWS class PAAPI Market = Struct.new(:host, :region) MARKETS = { au: Market.new('webservices.amazon.com.au', 'us-west-2'), br: Market.new('webservices.amazon.com.br' 'us-east-1'), ca: Market.new('webservices.amazon.ca', 'us-east-1'), fr: Market.new('webservices.amazon.fr', 'eu-west-1'), de: Market.new('webservices.amazon.de', 'eu-west-1'), in: Market.new('webservices.amazon.in', 'eu-west-1'), it: Market.new('webservices.amazon.it', 'eu-west-1'), jp: Market.new('webservices.amazon.co.jp', 'us-west-2'), mx: Market.new('webservices.amazon.com.mx', 'us-east-1'), es: Market.new('webservices.amazon.es', 'eu-west-1'), tr: Market.new('webservices.amazon.com.tr', 'eu-west-1'), ae: Market.new('webservices.amazon.ae', 'eu-west-1'), uk: Market.new('webservices.amazon.co.uk', 'eu-west-1'), us: Market.new('webservices.amazon.com', 'us-east-1'), }.freeze def initialize(access_key, secret_key, partner_tag) @access_key, @secret_key, @partner_tag = access_key, secret_key, partner_tag end def get_items(asin, locale) asin = isbn13to10(asin) if asin.length == 13 payload = { "PartnerTag" => @partner_tag, "PartnerType" => "Associates", "Marketplace" => MARKETS[locale].host.sub('webservices', 'www'), "ItemIds" => [asin], "Resources" => [ "Images.Primary.Small", "Images.Primary.Medium", "Images.Primary.Large", "ItemInfo.ByLineInfo", "ItemInfo.Title", "Offers.Listings.Price" ] }.to_json time_stamp = Time.now.utc.strftime("%Y%m%dT%H%M%SZ") signature = AWS::SigV4.signature(@secret_key, time_stamp, MARKETS[locale].region, MARKETS[locale].host, payload) authorization = "AWS4-HMAC-SHA256 Credential=#{@access_key}/#{time_stamp[0,8]}/#{MARKETS[locale].region}/ProductAdvertisingAPI/aws4_request, SignedHeaders=content-encoding;host;x-amz-content-sha256;x-amz-date;x-amz-target, Signature=#{signature}" headers = { "X-Amz-Target" => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.GetItems", "Content-Encoding" => "amz-1.0", "Host" => MARKETS[locale].host, "X-Amz-Date" => time_stamp, "X-Amz-Content-Sha256" => OpenSSL::Digest::SHA256.hexdigest(payload), "Authorization" => authorization, "Content-Type" => "application/json; charset=utf-8" } uri = URI("https://#{MARKETS[locale].host}/paapi5/getitems") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true response = http.post(uri.path, payload, headers) response.value # raise on errors return response.body end private def isbn13to10(isbn13) sum, = isbn13[3, 9].split(//).map(&:to_i).reduce([0,10]){|s,d|[s[0] + d * s[1], s[1]-1]} return isbn13[3, 9] + %w(0 1 2 3 4 5 6 7 8 9 X 0)[11 - sum % 11] end end end �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/aws/sig_v4.rb�����������������������������������������������������������������0000664�0000000�0000000�00000002650�13626457307�0017040�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # A Simple impl of AWS Signature V4 for PA-API GetItems # require 'openssl' module AWS module SigV4 def self.canonical_request(host, payload, time_stamp) headers = { 'Content-Encoding' => 'amz-1.0', 'Host' => host, 'X-Amz-Content-Sha256' => OpenSSL::Digest::SHA256.hexdigest(payload), 'X-Amz-Date' => time_stamp, 'X-Amz-Target' => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.GetItems", } [ "POST", "/paapi5/getitems", '', headers.keys.sort.map{|k|"#{k.downcase}:#{headers[k]}"}.join("\n") + "\n", headers.keys.sort.map{|k|k.downcase}.join(';'), OpenSSL::Digest::SHA256.hexdigest(payload) ].join("\n") end def self.string2sign(host, payload, time_stamp) [ 'AWS4-HMAC-SHA256', time_stamp, "#{time_stamp[0,8]}/us-west-2/ProductAdvertisingAPI/aws4_request", OpenSSL::Digest::SHA256.hexdigest(canonical_request(host, payload, time_stamp)) ].join("\n") end def self.signature(secret, time_stamp, region, host, payload) k_secret = secret k_date = hmac("AWS4" + k_secret, time_stamp[0,8]) k_region = hmac(k_date, region) k_service = hmac(k_region, 'ProductAdvertisingAPI') k_credential = hmac(k_service, "aws4_request") OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), k_credential, string2sign(host, payload, time_stamp)) end def self.hmac(key, value) OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value) end end end����������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary.rb���������������������������������������������������������������������0000664�0000000�0000000�00000010334�13626457307�0016345�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin == NAME tDiary: the "tsukkomi-able" web diary system. Copyright (C) 2001-2013, TADA Tadashi <t@tdtds.jp> You can redistribute it and/or modify it under GPL2 or any later version. =end Encoding::default_external = 'UTF-8' require 'tdiary/version' TDIARY_VERSION = TDiary::VERSION $:.unshift File.join(File::dirname(__FILE__), '../misc/lib') ['../misc/lib/*/lib', '../vendor/*/lib'].each do |path| Dir[File.join(File.dirname(__FILE__), path)].each {|dir| $:.unshift dir } end require 'cgi' require 'uri' require 'fileutils' require 'pstore' require 'json' require 'erb' require 'tdiary/environment' require 'tdiary/compatible' require 'tdiary/core_ext' # # module TDiary # module TDiary PATH = File::dirname( __FILE__ ) # tDiary configuration class, initialize tdiary.conf and stored configuration. autoload :Configuration, 'tdiary/configuration' autoload :Config, 'tdiary/configuration' # tDiary plugin class, loading all Plugin and eval plugins in view context. autoload :Plugin, 'tdiary/plugin' # tDiary Filter class, all filters is loaded by in TDiaryView. autoload :Filter, 'tdiary/filter' # CGI standalone server autoload :Server, 'tdiary/server' # Rack Application, TODO: integrate Server and Application autoload :Application, 'tdiary/application' autoload :Extensions, 'tdiary/extensions' # Diary model class autoload :Style, 'tdiary/style' autoload :Comment, 'tdiary/comment' autoload :DiaryContainer, 'tdiary/diary_container' # Routing and Dispatch autoload :Dispatcher, 'tdiary/dispatcher' # Rack Request and Reponse, If you don't use Rack, adopt Rack interface. autoload :Request, 'tdiary/request' autoload :Response, 'tdiary/response' # ViewController created by Dispatcher autoload :TDiaryBase, 'tdiary/base' autoload :TDiaryCategoryView, 'tdiary/base' autoload :TDiarySearch, 'tdiary/base' autoload :TDiaryPluginView, 'tdiary/base' autoload :TDiaryAuthorOnlyBase, 'tdiary/author_only_base' autoload :TDiaryFormPlugin, 'tdiary/author_only_base' autoload :TDiaryConf, 'tdiary/author_only_base' autoload :TDiarySaveConf, 'tdiary/author_only_base' autoload :TDiaryAdmin, 'tdiary/admin' autoload :TDiaryForm, 'tdiary/admin' autoload :TDiaryEdit, 'tdiary/admin' autoload :TDiaryPreview, 'tdiary/admin' autoload :TDiaryUpdate, 'tdiary/admin' autoload :TDiaryAppend, 'tdiary/admin' autoload :TDiaryReplace, 'tdiary/admin' autoload :TDiaryShowComment, 'tdiary/admin' autoload :TDiaryView, 'tdiary/view' autoload :TDiaryDay, 'tdiary/view' autoload :TDiaryDayWithoutFilter, 'tdiary/view' autoload :TDiaryComment, 'tdiary/view' autoload :TDiaryMonthBase, 'tdiary/view' autoload :TDiaryMonth, 'tdiary/view' autoload :TDiaryNYear, 'tdiary/view' autoload :TDiaryMonthWithoutFilter, 'tdiary/view' autoload :TDiaryLatest, 'tdiary/view' # Helper, these module called from ViewController and Plugins autoload :ViewHelper, 'tdiary/view_helper' # # exception classes # class TDiaryError < StandardError; end class PermissionError < TDiaryError; end class PluginError < TDiaryError; end class BadStyleError < TDiaryError; end class NotFound < TDiaryError; end # class ForceRedirect # force redirect to another page # class ForceRedirect < StandardError attr_reader :path def initialize( path ) @path = path end end class << self def logger @@logger end def logger=(obj) @@logger = obj end def root File.expand_path(File.join(library_root, '..')) end # directory where tDiary libraries is located def library_root File.expand_path('..', __FILE__) end # directory where the server was started def server_root Dir.pwd end def configuration @@configuration ||= Configuration.new end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0016017�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/admin.rb���������������������������������������������������������������0000664�0000000�0000000�00000011454�13626457307�0017441�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary # # class TDiaryAdmin # base class of administration # class TDiaryAdmin < TDiaryAuthorOnlyBase def initialize( cgi, rhtml, conf ) super begin @date = Time::local( @cgi.params['year'][0].to_i, @cgi.params['month'][0].to_i, @cgi.params['day'][0].to_i ) rescue ArgumentError, NameError raise TDiaryError, 'bad date' end end end # # class TDiaryForm # show diary append form # class TDiaryForm < TDiaryAdmin def csrf_protection_get_is_okay; true; end def initialize( cgi, rhtml, conf ) begin super rescue TDiaryError end @date = Time::now + (@conf.hour_offset * 3600).to_i title = '' @io.transaction( @date ) do |diaries| @diaries = diaries diary = self[@date] title = diary.title if diary DIRTY_NONE end @diary = @io.diary_factory( @date, title, '', @conf.style ) end end # # class TDiaryEdit # show edit diary form # class TDiaryEdit < TDiaryAdmin def csrf_protection_get_is_okay; true; end def initialize( cgi, rhtm, conf ) super @io.transaction( @date ) do |diaries| @diaries = diaries @diary = self[@date] if @diary then @conf.style = @diary.style else @diary = @io.diary_factory( @date, '', '', @conf.style ) end DIRTY_NONE end end end # # class TDiaryPreview # preview diary # class TDiaryPreview < TDiaryAdmin def initialize( cgi, rhtm, conf ) super @title = @cgi.params['title'][0] @body = @cgi.params['body'][0] @title = @conf.to_native( @title ) @body = @conf.to_native( @body ) @old_date = @cgi.params['old'][0] @hide = @cgi.params['hide'][0] == 'true' ? true : false @io.transaction( @date ) do |diaries| @diaries = diaries diary = @diaries[@date.strftime( '%Y%m%d' )] @conf.style = diary.style if diary @diary = @io.diary_factory( @date, @title, @body, @conf.style ) @diary.show( ! @hide ) DIRTY_NONE end end def eval_rhtml( prefix = '' ) begin @show_result = true r = do_eval_rhtml( prefix ) rescue PluginError, SyntaxError, ArgumentError @exception = $!.dup @show_result = false r = super end r end end # # class TDiaryUpdate # super class of diary saving classes # class TDiaryUpdate < TDiaryAdmin def initialize( cgi, rhtml, conf ) @title = cgi.params['title'][0] @body = cgi.params['body'][0] @title = conf.to_native( @title ) @body = conf.to_native( @body ) @hide = cgi.params['hide'][0] == 'true' ? true : false super end protected def do_eval_rhtml( prefix ) super @plugin.instance_eval { update_proc } anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"] ) @io.clear_cache( /(latest|#{@date.strftime( '%Y%m' )})/ ) raise ForceRedirect::new( "#{@conf.index}#{anchor_str}" ) end end # # class TDiaryAppend # append diary # class TDiaryAppend < TDiaryUpdate def initialize( cgi, rhtml, conf ) begin super rescue TDiaryError @date = newdate end @author = @conf.multi_user ? @cgi.remote_user : nil @io.transaction( @date ) do |diaries| @diaries = diaries @diary = self[@date] || @io.diary_factory( @date, @title, '', @conf.style ) self << @diary.append( @body, @author ) @diary.set_title( @title ) unless @title.empty? @diary.show( ! @hide ) DIRTY_DIARY end end protected def newdate Time::now + (@conf.hour_offset * 3600).to_i end end # # class TDiaryReplace # replace diary # class TDiaryReplace < TDiaryUpdate def initialize( cgi, rhtm, conf ) super old_date = @cgi.params['old'][0] @io.transaction( @date ) do |diaries| @diaries = diaries @diary = self[@date] if @diary then if @date.strftime( '%Y%m%d' ) != old_date then @diary.append( @body, @append ) @diary.set_title( @title ) if @title.length > 0 else @diary.replace( @date, @title, @body ) end else @diary = @io.diary_factory( @date, @title, @body, @conf.style ) end @diary.show( ! @hide ) self << @diary DIRTY_DIARY end end end # # class TDiaryShowComment # change visible mode of comments # class TDiaryShowComment < TDiaryAdmin def initialize( cgi, rhtml, conf ) super @io.transaction( @date ) do |diaries| @diaries = diaries dirty = DIRTY_NONE @diary = self[@date] if @diary then idx = 0 @diary.each_comment do |com| com.show = @cgi.params[(idx += 1).to_s][0] == 'true' ? true : false; end self << @diary @io.clear_cache( /(latest|#{@date.strftime( '%Y%m' )})/ ) dirty = DIRTY_COMMENT end dirty end end def eval_rhtml( prefix = '' ) load_plugins @plugin.instance_eval { update_proc } super end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/application.rb���������������������������������������������������������0000664�0000000�0000000�00000005205�13626457307�0020651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'tdiary' require 'tdiary/extensions/core' require 'rack/builder' require 'tdiary/rack' # FIXME too dirty hack :-< class CGI def env_table_rack $RACK_ENV || ENV end alias :env_table_orig :env_table alias :env_table :env_table_rack end module TDiary class Application def initialize( base_dir = nil ) index_path = self.index_path update_path = self.update_path assets_path = self.assets_path assets_paths = self.assets_paths base_dir ||= self.base_dir @app = ::Rack::Builder.app do map base_dir do map '/' do use TDiary::Rack::HtmlAnchor use TDiary::Rack::Static, ["public"] use TDiary::Rack::ValidRequestPath map index_path do run TDiary::Dispatcher.index end end map update_path do use TDiary::Rack::Auth run TDiary::Dispatcher.update end map assets_path do run TDiary::Rack::Static.new(nil, assets_paths) end end end run_plugin_startup_procs end def call( env ) begin @app.call( env ) rescue Exception => e body = ["#{e.class}: #{e}\n"] body << e.backtrace.join("\n") [500, {'Content-Type' => 'text/plain'}, body] end end def assets_paths TDiary::Extensions::constants.map {|extension| TDiary::Extensions::const_get( extension ).assets_path }.flatten.uniq end protected def index_path (Pathname.new('/') + URI(TDiary.configuration.index).path).to_s end def update_path (Pathname.new('/') + URI(TDiary.configuration.update).path).to_s end def assets_path '/assets' end def base_dir base_url = TDiary.configuration.base_url if base_url.empty? '/' else URI.parse(base_url).path end end private def run_plugin_startup_procs # avoid offline mode at CGI.new ARGV.replace([""]) cgi = RackCGI.new request = TDiary::Request.new(ENV, cgi) conf = TDiary::Configuration.new(cgi, request) tdiary = TDiary::TDiaryBase.new(cgi, '', conf) io = conf.io_class.new(tdiary) begin plugin = TDiary::Plugin.new( 'conf' => conf, 'mode' => 'startup', 'diaries' => tdiary.diaries, 'cgi' => cgi, 'years' => nil, 'cache_path' => io.cache_path, 'date' => Time.now, 'comment' => nil, 'last_modified' => Time.now, # FIXME 'logger' => TDiary.logger, # 'debug' => true ) # run startup plugin plugin.__send__(:startup_proc, self) rescue TDiary::ForceRedirect => e # 90migrate.rb raises TDiary::ForceRedirect at first startup TDiary::logger.warn(e) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/author_only_base.rb����������������������������������������������������0000664�0000000�0000000�00000010561�13626457307�0021704�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary # # class TDiaryAuthorOnlyBase # base class for author-only access pages # class TDiaryAuthorOnlyBase < TDiaryBase def csrf_protection_get_is_okay; false; end def initialize( cgi, rhtml, conf ) super csrf_check( cgi, conf ) end private def csrf_check( cgi, conf ) # CSRF condition check protection_method = conf.options['csrf_protection_method'] masterkey = conf.options['csrf_protection_key'] updaterb_regexp = conf.options['csrf_protection_allowed_referer_regexp_for_update'] protection_method = 1 unless protection_method return if protection_method == -1 # don't use this setting! check_key = (protection_method & 2 != 0) check_referer = (protection_method & 1 != 0) masterkey = '' unless masterkey updaterb_regexp = '' unless updaterb_regexp if (masterkey != '' && check_key) @csrf_protection = %Q[<input type="hidden" name="csrf_protection_key" value="#{h masterkey}">] else @csrf_protection="<!-- no CSRF protection key used -->" end referer = cgi.referer || '' referer = referer.sub(/\?.*$/, '') base_uri = URI.parse(base_url) config_uri = URI.parse(base_url) + conf.update referer_is_empty = referer == '' referer_uri = URI.parse(referer) if !referer_is_empty referer_is_config = !referer_is_empty && config_uri == referer_uri referer_is_config ||= Regexp.new(updaterb_regexp) =~ referer if !referer_is_empty && updaterb_regexp != '' is_post = cgi.request_method == 'POST' given_key = nil if cgi.valid?('csrf_protection_key') given_key = cgi.params['csrf_protection_key'][0] case given_key when String else given_key = given_key.read end end is_key_ok = masterkey != '' && given_key == masterkey keycheck_ok = !check_key || is_key_ok referercheck_ok = referer_is_config || (!check_referer && referer_is_empty) if csrf_protection_get_is_okay then return if is_post || given_key == nil else return if keycheck_ok && referercheck_ok end raise Exception.new(<<"EOS") Security Error: Possible Cross-site Request Forgery (CSRF) Diagnostics: - Protection Method is #{ protection_method } - Mode is #{ self.mode || 'unknown' } - GET is #{ csrf_protection_get_is_okay ? '' : 'not '}allowed - Request Method is #{ is_post ? 'POST' : 'not POST' } - Referer is #{ referer_is_empty ? 'empty' : referer_is_config ? 'config' : 'another page' } - Given referer: #{h referer_uri.to_s} - Expected base URI: #{h base_uri.to_s} - Expected update URI: #{h config_uri.to_s} - CSRF key is #{ is_key_ok ? 'OK' : given_key ? 'NG (' + (given_key || '') + ')' : 'nothing' } EOS end def load_plugins super @plugin.instance_eval("def csrf_protection\n#{(@csrf_protection || '').dump}\nend;") end end # # class TDiaryFormPlugin # show edit diary form after calling form plugin. # class TDiaryFormPlugin < TDiaryAuthorOnlyBase def initialize( cgi, rhtm, conf ) super if @cgi.valid?( 'date' ) then if @cgi.params['date'][0].kind_of?( String ) then date = @cgi.params['date'][0] else date = @cgi.params['date'][0].read end @date = Time::local( *date.scan( /(\d{4})(\d\d)(\d\d)/ )[0] ) else @date = Time::now + (@conf.hour_offset * 3600).to_i @diary = @io.diary_factory( @date, '', '', @conf.style ) end @io.transaction( @date ) do |diaries| @diaries = diaries @diary = self[@date] if @diary then @conf.style = @diary.style else @diary = @io.diary_factory( @date, '', '', @conf.style ) end DIRTY_NONE end end end # # class TDiaryConf # show configuration form # class TDiaryConf < TDiaryAuthorOnlyBase def csrf_protection_get_is_okay; true; end def initialize( cgi, rhtml, conf ) super @key = @cgi.params['conf'][0] || '' end end # # class TDiarySaveConf # save configuration # class TDiarySaveConf < TDiaryConf def csrf_protection_get_is_okay; false; end def initialize( cgi, rhtml, conf ) super end def eval_rhtml( prefix = '' ) r = super begin @conf.save @io.clear_cache rescue @error = [$!.dup, $@.dup] end r end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 �����������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/base.rb����������������������������������������������������������������0000664�0000000�0000000�00000010502�13626457307�0017254�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary # # class TDiaryBase # tDiary CGI # class TDiaryBase include ERB::Util include ViewHelper DIRTY_NONE = 0 DIRTY_DIARY = 1 DIRTY_COMMENT = 2 DIRTY_REFERER = 4 attr_reader :cookies, :date, :diaries attr_reader :cgi, :rhtml, :conf attr_reader :ignore_parser_cache def initialize( cgi, rhtml, conf ) @cgi, @rhtml, @conf = cgi, rhtml, conf @diaries = {} @cookies = [] @io = @conf.io_class.new( self ) @ignore_parser_cache = false end def eval_rhtml( prefix = '' ) begin r = do_eval_rhtml( prefix ) rescue PluginError, SyntaxError, ArgumentError, Exception => e if e.class == ForceRedirect raise else body = File.read("#{File.dirname(__FILE__)}/../../views/plugin_error.rhtml") r = ERB.new(body).result(binding) end end r end def last_modified nil end def []( date ) @diaries[date.strftime( '%Y%m%d' )] end def calendar @years = @io.calendar unless @years end protected def do_eval_rhtml( prefix ) load_plugins r = @io.restore_cache( prefix ) if r.nil? r = @rhtml ? erb_src(prefix) : "" @io.store_cache( r, prefix ) unless @diaries.empty? end r = @plugin.eval_src( r ) if @plugin @cookies += @plugin.cookies r end def mode self.class.to_s.sub( /^TDiary::TDiary/, '' ).downcase end def load_plugins calendar # # caching plugin # NOTE: currently, plugin cache doesn't work with blog-category plugin # see also https://github.com/tdiary/tdiary-core/issues/203 # if @plugin and not @plugin.respond_to?( 'blog_category' ) @plugin.diaries = @diaries @plugin.date = @date @plugin.last_modified = last_modified @plugin.comment = @comment @plugin else @plugin = Plugin::new( 'conf' => @conf, 'mode' => mode, 'diaries' => @diaries, 'cgi' => @cgi, 'years' => @years, 'cache_path' => @io.cache_path, 'date' => @date, 'comment' => @comment, 'last_modified' => last_modified, 'logger' => TDiary.logger ) end end def <<( diary ) @diaries[diary.date.strftime( '%Y%m%d' )] = diary end def delete( date ) @diaries.delete( date.strftime( '%Y%m%d' ) ) end private def erb_src(prefix) rhtml = ["header.rhtml", @rhtml, "footer.rhtml"].map do |file| path = "#{File.dirname(__FILE__)}/../../views/#{prefix}#{file}" begin File.read("#{path}.#{@conf.lang}") rescue File.read(path) end end.join begin r = ERB.new(rhtml).result(binding) rescue ::Encoding::CompatibilityError # migration error on ruby 1.9 only 1st time, reload. raise ForceRedirect.new(base_url) end ERB.new(r).src end end # # class TDiaryCategoryView # base of category view mode classes # class TDiaryCategoryView < TDiaryBase attr_reader :last_modified def initialize(cgi, rhtml, conf) super @last_modified = Time.now end end # # class TDiarySearch # base of search view mode classes # class TDiarySearch < TDiaryBase attr_reader :last_modified def initialize(cgi, rhtml, conf) super @last_modified = Time.now end end # class TDiaryPluginView # base of plugin view mode classes # class TDiaryPluginView < TDiaryBase attr_reader :last_modified def initialize(cgi, rhtml, conf) super tdiary = tdiary_class(cgi.params['date'][0] || '').new(cgi, '', conf) @date = tdiary.date @diaries = tdiary.diaries @last_modified = Time.now end def eval_rhtml( prefix = '' ) load_plugins # TODO: prefixでモバイルモードかどうかを判定 # TODO: rhtml rendering @rhtml = "#{plugin_name}.rhtml" @plugin.__send__(:content_proc, plugin_name, @date.strftime('%Y%m%d')) end protected def plugin_name # plugin name MUST contain only words ([a-zA-Z0-9_]) @plugin_name ||= (@cgi.params['plugin'][0] || '').match(/^(\w+)$/).to_a[1] raise TDiary::PermissionError.new('invalid plugin name') unless @plugin_name @plugin_name end def tdiary_class(date) # YYYYMMDD-N, YYYYMMDD, YYYYMM, MMDD, or nil case date when /^\d{8}-\d+$/ TDiaryLatest when /^\d{8}$/ TDiaryDay when /^\d{6}$/ TDiaryMonth when /^\d{4}$/ TDiaryNYear else TDiaryLatest end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/cache/�����������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0017062�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/cache/file.rb����������������������������������������������������������0000664�0000000�0000000�00000004761�13626457307�0020336�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary module Cache def restore_cache( prefix ) restore_data("#{cache_path}/#{cache_file( prefix )}") if cache_enable?( prefix ) end def store_cache(cache, prefix) store_data(cache, "#{cache_path}/#{cache_file( prefix )}") if cache_file( prefix ) end def clear_cache( target = /.*/ ) Dir::glob( "#{cache_path}/*.r[bh]*" ).each do |c| delete_data(c) if target =~ c end end private def restore_data(path) File.read(path) rescue nil end def store_data(data, path) File.open(path, 'w') do |f| f.flock(File::LOCK_EX) f.write(data) end end def delete_data(path) File.delete(path) end def restore_parser_cache(date, key = nil) return nil if @tdiary.ignore_parser_cache file = date.strftime("#{cache_path}/%Y%m.parser") obj = nil begin PStore.new(file).transaction do |cache| begin ver = cache.root?('version') ? cache['version'] : nil if ver == TDIARY_VERSION and cache.root?(key) obj = cache[key] else clear_cache end cache.abort rescue PStore::Error end end rescue clear_parser_cache( date ) end obj end def store_parser_cache(date, obj, key = nil) return nil if @tdiary.ignore_parser_cache file = date.strftime("#{cache_path}/%Y%m.parser") begin PStore::new(file).transaction do |cache| begin cache[key] = obj cache['version'] = TDIARY_VERSION rescue PStore::Error end end rescue clear_parser_cache(date) end end def clear_parser_cache(date) file = date.strftime("#{cache_path}/%Y%m.parser") begin File.delete(file) File.delete(file + '~') rescue end nil end def cache_file( prefix ) if @tdiary.is_a?(TDiaryMonth) "#{prefix}#{@tdiary.rhtml.sub( /month/, @tdiary.date.strftime( '%Y%m' ) ).sub( /\.rhtml$/, '.rb' )}" elsif @tdiary.is_a?(TDiaryLatest) if @tdiary.cgi.params['date'][0] then nil else "#{prefix}#{@tdiary.rhtml.sub( /\.rhtml$/, '.rb' )}" end else nil end end def cache_exists?( prefix ) cache_file( prefix ) && FileTest::file?( "#{cache_path}/#{cache_file( prefix )}" ) end def cache_enable?( prefix ) if @tdiary.is_a?(TDiaryView) cache_exists?( prefix ) && (File::mtime( "#{cache_path}/#{cache_file( prefix )}" ) > @tdiary.last_modified) else cache_exists?( prefix ) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������tdiary-core-5.1.1/lib/tdiary/cli.rb�����������������������������������������������������������������0000664�0000000�0000000�00000012154�13626457307�0017116�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'thor' require 'tdiary/version' require 'bundler' module TDiary class CLI < Thor include Thor::Actions def self.source_root File.expand_path('../../..', __FILE__) end desc "new DIR_NAME", "Create a new tDiary directory" method_option "skip-bundle", type: :boolean, banner: "don't run bundle and .htpasswd generation" def new(name) target = File.join(Dir.pwd, name) deploy(target) copy_file('tdiary.conf.beginner', File.join(target, 'tdiary.conf')) template('misc/templates/Gemfile.local.erb', File.join(target, 'Gemfile.local')) unless options[:'skip-bundle'] Bundler.with_clean_env do inside(target) do run('bundle install --without test development') run('bundle exec tdiary htpasswd') end end else say "run `bundle install && bundle exec tdiary htpasswd` manually", :red end say 'install finished', :green say "run `tdiary server` in #{name} directory to start server", :green end desc "update", "update tDiary" method_option "skip-bundle", type: :boolean, banner: "don't run bundle" def update target = Dir.pwd unless in_tdiary_dir?(target) say "please run update command in your tdiary directory", :red return 1 end deploy(target) unless options[:'skip-bundle'] Bundler.with_clean_env do inside(target) do run('bundle install --without test development') end end end say 'update finished', :green end desc "assets_copy", "copy assets files" def assets_copy require 'tdiary' assets_path = File.join(TDiary.server_root, 'public/assets') TDiary::Application.new.assets_paths.each do |path| Dir.glob(File.join(path, '*')).each do |entity| if File.directory?(entity) directory entity, File.join(assets_path, File.basename(entity)) else copy_file entity, File.join(assets_path, File.basename(entity)) end end end end desc "test", "Create test server and run tDiary test" def test target = File.join(Dir.pwd, 'tmp/test') deploy(target) append_to_file(File.join(target, 'Gemfile'), "path '#{CLI::source_root}'") directory('spec', File.join(target, 'spec')) directory('test', File.join(target, 'test')) Bundler.with_clean_env do inside(target) do run('bundle install') run('bundle exec rake spec') end end end desc "server", "Start tDiary server" method_option "rack", type: :string, banner: "start server with rack interface (default)" method_option "cgi", type: :string, banner: "start server with cgi interface" method_option "bind", aliases: "b", type: :string, default: "0.0.0.0", banner: "bind to the IP" method_option "port", aliases: "p", type: :numeric, default: 19292, banner: "use PORT" method_option "log", aliases: "l", type: :string, banner: "File to redirect output" def server require 'tdiary' require 'tdiary/environment' if options[:cgi] opts = { daemon: ENV['DAEMON'], bind: options[:bind], port: options[:port], logger: $stderr, access_log: options[:log] ? File.open(options[:log], 'a') : $stderr } TDiary::Server.run( opts ) elsif # --rack option # Rack::Server reads ARGV as :config, so delete it require 'webrick' ARGV.shift opts = { environment: ENV['RACK_ENV'] || "development", daemonize: false, Host: options[:bind], Port: options[:port], pid: File.expand_path("tdiary.pid"), config: File.expand_path("config.ru") } if options[:log] opts[:AccessLog] = [[File.open(options[:log], 'a'), WEBrick::AccessLog::CLF]] end ::Rack::Server.start( opts ) end end desc "htpasswd", "Create a .htpasswd file" def htpasswd require 'webrick/httpauth/htpasswd' say "Input your username/password" print 'Username: ' ARGV.replace([]) username = gets().chop print 'New password: ' system "stty -echo" password = $stdin.gets.chop puts print 'Re-type new password: ' password2 = $stdin.gets.chop puts system "stty echo" if password != password2 raise StandardError, 'password verification error' end htpasswd = WEBrick::HTTPAuth::Htpasswd.new(ENV['HTPASSWD'] || '.htpasswd') htpasswd.set_passwd(nil, username, password) htpasswd.flush end desc "version", "Prints the tDiary's version information" def version say "tdiary #{TDiary::VERSION}" end map %w(-v --version) => :version no_commands do def deploy(target) empty_directory(target) empty_directory(File.join(target, 'public')) empty_directory(File.join(target, 'misc/plugin')) empty_directory(File.join(target, 'lib/tdiary/filter')) empty_directory(File.join(target, 'lib/tdiary/style')) empty_directory(File.join(target, 'js')) empty_directory(File.join(target, 'theme')) %w( README.md Gemfile Gemfile.lock config.ru tdiary.conf.beginner tdiary.conf.sample tdiary.conf.sample-en ).each do |file| copy_file(file, File.join(target, file)) end directory('doc', File.join(target, 'doc')) end def in_tdiary_dir?(target) File.exist?(File.join(target, 'tdiary.conf')) end end end end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/comment.rb�������������������������������������������������������������0000664�0000000�0000000�00000001266�13626457307�0020013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # class Comment # Management a comment. # module TDiary class Comment attr_reader :name, :mail, :body, :date def initialize( name, mail, body, date = Time::now ) @name, @mail, @body, @date = name, mail, body, date @show = true end def shorten( length = 120 ) matched = body.gsub( /\n/, ' ' ).scan( /^.{0,#{length - 2}}/u )[0] unless $'.empty? then matched + '..' else matched end end def visible?; @show; end def show=( s ); @show = s; end def ==( c ) (@name == c.name) and (@mail == c.mail) and (@body == c.body) end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/comment_manager.rb�����������������������������������������������������0000664�0000000�0000000�00000003452�13626457307�0021504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # module CommentManager # Management comments in a day. Include in Diary class. # module TDiary module CommentManager private # # call this method when initialize # def init_comments @comments = [] end public def add_comment( com ) (@comments << com).sort!{|a, b| a.date <=> b.date} if not @last_modified or @last_modified < com.date @last_modified = com.date end com end def count_comments( all = false ) i = 0 @comments.each do |comment| i += 1 if all or comment.visible? end i end def each_comment( limit = -1 ) @comments.each_with_index do |com,idx| break if idx >= limit and limit >= 0 yield com end end def each_comment_tail( limit = 3 ) idx = 0 comments = @comments.collect {|c| idx += 1 if c.visible? then [c, idx] else nil end }.compact s = comments.size - limit s = 0 if s < 0 for idx in s...comments.size yield comments[idx][0], comments[idx][1] # idx is start with 1. end end def each_visible_comment( limit = -1 ) @comments.each_with_index do |com,idx| break if idx >= limit and limit >= 0 next unless com.visible? yield com,idx+1 # idx is start with 1. end end def each_visible_trackback( limit = -1 ) i = 0 @comments.each do |com| break if i >= limit and limit >= 0 next unless /^TrackBack$/ =~ com.name next unless com.visible_true? i += 1 yield com, i end end def each_visible_trackback_tail( limit = 3 ) i = 0 @comments.find_all {|com| com.visible_true? and /^TrackBack$/ =~ com.name }.reverse[0,limit].reverse.each do |com| i += 1 # i starts with 1. yield com,i end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/compatible.rb����������������������������������������������������������0000664�0000000�0000000�00000002642�13626457307�0020467�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ENV#[] raises an exception on secure mode class CGI ENV = ::ENV.to_hash end # Auto convert ASCII_8BIT pstore data (created by Ruby-1.8) to UTF-8. require 'pstore' class PStoreRuby18Exception < Exception; end class PStore alias compatible_transaction_original transaction unless defined?(compatible_transaction_original) def transaction(*args, &block) begin compatible_transaction_original(*args, &block) rescue PStoreRuby18Exception # first loaded the pstore file (it's created by Ruby-1.8) # force convert ASCII_8BIT pstore data to UTF_8 file = open_and_lock_file(@filename, false) table = Marshal::load(file, proc {|obj| if obj.respond_to?('force_encoding') && obj.encoding == Encoding::ASCII_8BIT obj.force_encoding('UTF-8') end obj }) table[:__ruby_version] = RUBY_VERSION if on_windows? save_data_with_fast_strategy(Marshal::dump(table), file) else save_data_with_atomic_file_rename_strategy(Marshal::dump(table), file) end retry end end private def load(content) table = Marshal::load(content) raise PStoreRuby18Exception.new if !table[:__ruby_version] || table[:__ruby_version] < '1.9' # hide __ruby_version to caller table.delete(:__ruby_version) table end def dump(table) table[:__ruby_version] = RUBY_VERSION Marshal::dump(table) end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/configuration.rb�������������������������������������������������������0000664�0000000�0000000�00000014175�13626457307�0021223�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # class Configuration # configuration class # module TDiary class Configuration attr_reader :database_url def initialize( cgi = nil, request = nil ) @request = request configure_attrs configure_bot_pattern setup_attr_accessor_to_all_ivars load_logger end def save result = ERB.new(File.read("#{File.dirname(__FILE__)}/../../views/tdiary.rconf")).result(binding) eval( result, binding, "(TDiary::Configuration#save)", 1 ) @io_class.save_cgi_conf(self, result) end # # get/set/delete plugin options # def []( key ) @options[key] end def []=( key, val ) @options2[key] = @options[key] = val end def delete( key ) @options.delete( key ) @options2.delete( key ) end # backward compatibility, returns NOT mobile phone always def mobile_agent? false end # backward compatibility, returns NOT smartphone always def smartphone? false end alias iphone? smartphone? # backward compatibility, you can use bot? or @conf.bot =~ @cgi.user_agent def bot? @bot =~ @request.user_agent end # backward compatibility, you can use TDiary::ViewHelper#base_url def base_url if @options['base_url'] && @options['base_url'].length > 0 @options['base_url'] elsif @request @request.base_url else '' end end def to_native( str, charset = nil ) str = str.dup if str.encoding == Encoding::ASCII_8BIT str.force_encoding(charset || 'utf-8') end unless str.valid_encoding? str.encode!('utf-16be', invalid: :replace, undef: :replace) end unless str.encoding == Encoding::UTF_8 str.encode!('utf-8', invalid: :replace, undef: :replace) end str end private # loading tdiary.conf in @data_path. def load_cgi_conf def_vars1 = '' def_vars2 = '' [ :tdiary_version, :html_title, :author_name, :author_mail, :index_page, :hour_offset, :description, :icon, :banner, :x_frame_options, :header, :footer, :section_anchor, :comment_anchor, :date_format, :latest_limit, :show_nyear, :theme, :css, :show_comment, :comment_limit, :comment_limit_per_day, :mail_on_comment, :mail_header, :show_referer, :no_referer2, :only_volatile2, :referer_table2, :options2, ].each do |var| def_vars1 << "#{var} = nil\n" def_vars2 << "@#{var} = #{var} unless #{var} == nil\n" end unless defined?(::TDiary::Cache) && ::TDiary::Cache.method_defined?(:store_cache) require 'tdiary/cache/file' end unless @io_class require 'tdiary/io/default' @io_class = IO::Default attr_reader :io_class end cgi_conf = @io_class.load_cgi_conf(self) b = binding eval( def_vars1, b ) begin eval( cgi_conf, b, "(TDiary::Configuration#load_cgi_conf)", 1 ) rescue SyntaxError enc = case @lang when 'en' 'UTF-8' else 'EUC-JP' end cgi_conf.force_encoding( enc ) retry end if cgi_conf eval( def_vars2, b ) end # loading tdiary.conf in current directory def configure_attrs @options = {} eval( File::open( 'tdiary.conf' ) {|f| f.read }, nil, "(tdiary.conf)", 1 ) # language setup @lang = 'ja' unless @lang begin instance_eval( File::open( "#{TDiary::PATH}/tdiary/lang/#{@lang}.rb" ){|f| f.read }, "(tdiary/lang/#{@lang}.rb)", 1 ) rescue Errno::ENOENT @lang = 'ja' retry end @data_path += '/' if @data_path && /\/$/ !~ @data_path @style = 'tDiary' unless @style @index = './' unless @index @update = 'update.rb' unless @update @hide_comment_form = false unless defined?( @hide_comment_form ) @author_name = '' unless @author_name @index_page = '' unless @index_page @hour_offset = 0 unless @hour_offset @html_title = '' unless @html_title @x_frame_options = nil unless @x_frame_options @header = '' unless @header @footer = '' unless @footer @section_anchor = '<span class="sanchor">_</span>' unless @section_anchor @comment_anchor = '<span class="canchor">_</span>' unless @comment_anchor @date_format = '%Y-%m-%d' unless @date_format @latest_limit = 10 unless @latest_limit @show_nyear = false unless @show_nyear @theme = 'default' if not @theme and not @css @theme = "local/#{@theme}" unless @theme.index('/') @css = '' unless @css @show_comment = true unless defined?( @show_comment ) @comment_limit = 3 unless @comment_limit @comment_limit_per_day = 100 unless @comment_limit_per_day @show_referer = true unless defined?( @show_referer ) @referer_limit = 10 unless @referer_limit @referer_day_only = true unless defined?( @referer_day_only ) @no_referer = [] unless @no_referer @no_referer2 = [] unless @no_referer2 @no_referer = @no_referer2 + @no_referer @only_volatile = [] unless @only_volatile @only_volatile2 = [] unless @only_volatile2 @only_volatile = @only_volatile2 + @only_volatile @referer_table = [] unless @referer_table @referer_table2 = [] unless @referer_table2 @referer_table = @referer_table2 + @referer_table @options = {} unless @options.class == Hash if @options2 then @options.update( @options2 ) else @options2 = {} end # for 1.4 compatibility @section_anchor = @paragraph_anchor unless @section_anchor end def setup_attr_accessor_to_all_ivars names = instance_variables().collect {|ivar| ivar.to_s.sub(/@/, '') } (class << self; self; end).class_eval { attr_accessor *names } end def configure_bot_pattern bot = ["bot", "spider", "antenna", "crawler", "moget", "slurp"] bot += @options['bot'] || [] @bot = Regexp::new( "(#{bot.uniq.join( '|' )})", true ) end def load_logger if @logger TDiary.logger = @logger else require 'logger' log_path = (@log_path || "#{@data_path}/log") FileUtils.mkdir_p(log_path) TDiary.logger = Logger.new(File.join(log_path, "debug.log"), 'daily') TDiary.logger.level = Logger.const_get(@log_level || 'DEBUG') end end def method_missing( *m ) (class << self; self; end).class_eval { attr_accessor m[0] } if m.length == 1 nil end end # backward compatibility Config = Configuration end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/core_ext.rb������������������������������������������������������������0000664�0000000�0000000�00000005667�13626457307�0020172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'emot' module TDiary module RequestExtension # backward compatibility, returns NOT mobile phone always def mobile_agent? false end # backward compatibility, returns NOT smartphone always def smartphone? false end end end =begin == String class enhanced String class =end class String def make_link r = %r<(((http[s]{0,1}|ftp)://[\(\)%#!/0-9a-zA-Z_$@.&+-,'"*=;?:~-]+)|([0-9a-zA-Z_.-]+@[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+\.[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+))> return self. gsub( / /, "\001" ). gsub( /</, "\002" ). gsub( />/, "\003" ). gsub( /&/, '&' ). gsub( /\"/, "\004"). gsub( r ){ $1 == $2 ? "<a href=\"#$2\">#$2</a>" : "<a href=\"mailto:#$4\">#$4</a>" }. gsub( /\004/, '"' ). gsub( /\003/, '>' ). gsub( /\002/, '<' ). gsub( /^\001+/ ) { $&.gsub( /\001/, ' ' ) }. gsub( /\001/, ' ' ). gsub( /\t/, ' ' * 8 ) end def emojify self.to_str.gsub(/:([a-zA-Z0-9_+-]+):/) do |match| emoji_alias = $1.downcase emoji_url = %Q[<img src='//www.webpagefx.com/tools/emoji-cheat-sheet/graphics/emojis/%s.png' width='20' height='20' title='%s' alt='%s' class='emoji' />] if emoji_alias == 'plus1' or emoji_alias == '+1' emoji_url % (['plus1']*3) elsif Emot.unicode(emoji_alias) emoji_url % ([CGI.escape(emoji_alias)]*3) else match end end end end =begin == CGI class enhanced CGI class =end class CGI include TDiary::RequestExtension def valid?( param, idx = 0 ) self.params[param] and self.params[param][idx] and self.params[param][idx].length > 0 end def https? return true if env_table['HTTP_X_FORWARDED_PROTO'] == 'https' return false if env_table['HTTPS'].nil? or /off/i =~ env_table['HTTPS'] or env_table['HTTPS'] == '' true end def request_uri _request_uri = env_table['REQUEST_URI'] _script_name = env_table['SCRIPT_NAME'] if !_request_uri || _request_uri == '' || _request_uri == _script_name then _path_info = env_table['PATH_INFO'] || '' _query_string = env_table['QUERY_STRING'] || '' # Workaround for IIS-style PATH_INFO ('/dir/script.cgi/path', not '/path') # See http://support.microsoft.com/kb/184320/ _request_uri = _path_info.include?(_script_name) ? '' : _script_name.dup _request_uri << _path_info _request_uri << '?' + _query_string if _query_string != '' end _request_uri end def redirect_url env_table['REDIRECT_URL'] end def base_url return '' unless script_name begin script_dirname = script_name.empty? ? '' : File::dirname(script_name) if https? port = (server_port == 443) ? '' : ':' + server_port.to_s "https://#{server_name}#{port}#{script_dirname}/" else port = (server_port == 80) ? '' : ':' + server_port.to_s "http://#{server_name}#{port}#{script_dirname}/" end.sub(%r|/+$|, '/') rescue SecurityError '' end end end class RackCGI < CGI; end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 �������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/diary_container.rb�����������������������������������������������������0000664�0000000�0000000�00000002412�13626457307�0021515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary class DiaryContainer # YYYYMMDD def self.find_by_day(conf, date) # date: YYYYMMDD m = date.match(/^(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})$/) raise ArgumentError.new("date must be YYYYMMDD format") unless m new(conf, m[:year], m[:month], m[:day]) end def self.find_by_month(conf, date) # date: YYYYMM m = date.match(/^(?<year>\d{4})(?<month>\d{2})$/) raise ArgumentError.new("date must be YYYYMM format") unless m new(conf, m[:year], m[:month]) end def initialize(conf, year, month, day = nil) cgi = FakeCGI.new if year && month && day cgi.params['date'] = ["#{year}#{month}#{day}"] @controller = TDiaryDayWithoutFilter::new(cgi, '', conf) elsif year && month cgi.params['date'] = ["#{year}#{month}"] @controller = TDiaryMonthWithoutFilter::new(cgi, '', conf) else raise StandardError.new end end def conf @controller.conf end def diaries # Hash of 'YYYYMMDD' => TDiary::Style::WikiDiary @controller.diaries end class FakeCGI < CGI def refeter; nil end def user_agent; nil; end def mobile_agent?; nil; end def request_method; 'GET'; end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/dispatcher.rb����������������������������������������������������������0000664�0000000�0000000�00000004072�13626457307�0020475�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'stringio' module TDiary class Dispatcher autoload :IndexMain, 'tdiary/dispatcher/index_main' autoload :UpdateMain, 'tdiary/dispatcher/update_main' TARGET = { index: IndexMain, update: UpdateMain } def initialize( target ) @target = TARGET[target] end def call( env ) req = adopt_rack_request_to_plain_old_tdiary_style( env ) dispatch_cgi(req, RackCGI.new) end # FIXME rename method name to more suitable one. def dispatch_cgi(request, cgi) result = @target.run( request, cgi ) result.headers.reject!{|k,v| k.to_s.downcase == "status" } result.to_a end class << self # stolen from Rack::Handler::CGI.send_headers def send_headers(status, headers) begin headers['type'] = headers.delete('Content-Type') $stdout.print CGI.new.header({'Status'=>status}.merge(headers)) rescue EOFError charset = headers.delete('charset') headers['Content-Type'] ||= headers.delete( 'type' ) headers['Content-Type'] += "; charset=#{charset}" if charset $stdout.print headers.map{|k,v| "#{k}: #{v}\r\n"}.join << "\r\n" end $stdout.flush end # FIXME temporary method during (scratch) refactoring def extract_status_for_legacy_tdiary( head ) status_str = head.delete('status') return 200 if !status_str || status_str.empty? if m = status_str.match(/(\d+)\s(.+)\Z/) m[1].to_i else 200 end end def index new( :index ) end def update new( :update ) end private :new end private def adopt_rack_request_to_plain_old_tdiary_style( env ) req = TDiary::Request.new( env ) req.params # fill params to tdiary_request $RACK_ENV = req.env env["rack.input"].rewind fake_stdin_as_params req end # FIXME dirty hack def fake_stdin_as_params stdin_spy = StringIO.new if $RACK_ENV && $RACK_ENV['rack.input'] stdin_spy.print($RACK_ENV['rack.input'].read) stdin_spy.rewind end $stdin = stdin_spy end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/dispatcher/������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0020145�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/lib/tdiary/dispatcher/index_main.rb�����������������������������������������������0000664�0000000�0000000�00000006710�13626457307�0022611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������module TDiary class Dispatcher class IndexMain def self.run( request, cgi ) new( request, cgi ).run end attr_reader :request, :cgi, :conf, :tdiary, :params def initialize( request, cgi ) @request = request @cgi = cgi @conf = TDiary::Configuration::new( cgi, request ) @params = request.params end def run begin status = nil @tdiary = create_tdiary begin head = { 'Content-Type' => 'text/html; charset=UTF-8', 'Vary' => 'User-Agent' } head['status'] = status if status body = '' head['Last-Modified'] = CGI::rfc1123_date( tdiary.last_modified ) if request.head? head['Pragma'] = 'no-cache' head['Cache-Control'] = 'no-cache' return TDiary::Response.new( '', 200, head ) else require 'digest/md5' body = tdiary.eval_rhtml head['ETag'] = %Q["#{Digest::MD5.hexdigest( body )}"] if ENV['HTTP_IF_NONE_MATCH'] == head['ETag'] and request.get? then head['status'] = CGI::HTTP_STATUS['NOT_MODIFIED'] else head['charset'] = conf.encoding head['Content-Length'] = body.bytesize.to_s end head['Pragma'] = 'no-cache' head['Cache-Control'] = 'no-cache' head['X-Frame-Options'] = conf.x_frame_options if conf.x_frame_options head['cookie'] = tdiary.cookies if tdiary.cookies.size > 0 TDiary::Response.new( body, ::TDiary::Dispatcher.extract_status_for_legacy_tdiary( head ), head ) end rescue TDiary::NotFound body = %Q[ <h1>404 Not Found</h1> <div>#{' ' * 500}</div>] TDiary::Response.new( body, 404, { 'Content-Type' => 'text/html' } ) end rescue TDiary::ForceRedirect head = { #'Location' => $!.path 'Content-Type' => 'text/html', } body = %Q[ <html> <head> <meta http-equiv="refresh" content="1;url=#{$!.path}"> <title>moving... Wait or Click here! ] head['cookie'] = tdiary.cookies if tdiary && tdiary.cookies.size > 0 # TODO return code should be 302? (current behaviour returns 200) TDiary::Response.new( body, 200, head ) end end def create_tdiary begin if params['comment'] tdiary = TDiary::TDiaryComment::new( cgi, "day.rhtml", conf ) elsif params['plugin'] tdiary = TDiary::TDiaryPluginView::new( cgi, '', conf ) elsif (date = params['date']) if /^\d{8}-\d+$/ =~ date tdiary = TDiary::TDiaryLatest::new( cgi, "latest.rhtml", conf ) elsif /^\d{8}$/ =~ date tdiary = TDiary::TDiaryDay::new( cgi, "day.rhtml", conf ) elsif /^\d{6}$/ =~ date tdiary = TDiary::TDiaryMonth::new( cgi, "month.rhtml", conf ) elsif /^\d{4}$/ =~ date tdiary = TDiary::TDiaryNYear::new( cgi, "month.rhtml", conf ) end elsif params['category'] tdiary = TDiary::TDiaryCategoryView::new( cgi, "category.rhtml", conf ) elsif params['q'] tdiary = TDiary::TDiarySearch::new( cgi, "search.rhtml", conf ) else tdiary = TDiary::TDiaryLatest::new( cgi, "latest.rhtml", conf ) end rescue TDiary::PermissionError raise rescue TDiary::TDiaryError end ( tdiary ? tdiary : TDiary::TDiaryLatest::new( cgi, "latest.rhtml", conf ) ) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/dispatcher/update_main.rb000066400000000000000000000050351362645730700227630ustar00rootroot00000000000000module TDiary class Dispatcher class UpdateMain def self.run( request, cgi ) new( request, cgi ).run end attr_reader :request, :cgi, :conf, :tdiary, :params def initialize( request, cgi ) @request = request @cgi = cgi @conf = TDiary::Configuration::new( cgi, request ) @params = request.params end def run @tdiary = create_tdiary begin head = {}; body = '' body = tdiary.eval_rhtml head = { 'Content-Type' => 'text/html; charset=UTF-8', 'charset' => conf.encoding, 'Content-Length' => body.bytesize.to_s, 'Vary' => 'User-Agent', 'X-Frame-Options' => 'SAMEORIGIN' } body = ( request.head? ? '' : body ) TDiary::Response.new( body, 200, head ) rescue TDiary::ForceRedirect head = { #'Location' => $!.path 'Content-Type' => 'text/html', } body = %Q[ moving... Wait or Click here! ] head['cookie'] = tdiary.cookies if tdiary.cookies.size > 0 # TODO return code should be 302? (current behaviour returns 200) TDiary::Response.new( body, 200, head ) end end private def create_tdiary begin if params['plugin'] tdiary = TDiary::TDiaryFormPlugin::new( cgi, 'update.rhtml', conf ) elsif params['append'] tdiary = TDiary::TDiaryAppend::new( cgi, nil, conf ) elsif params['edit'] tdiary = TDiary::TDiaryEdit::new( cgi, 'update.rhtml', conf ) elsif params['replace'] tdiary = TDiary::TDiaryReplace::new( cgi, nil, conf ) elsif params['appendpreview'] or params['replacepreview'] tdiary = TDiary::TDiaryPreview::new( cgi, 'preview.rhtml', conf ) elsif params['comment'] tdiary = TDiary::TDiaryShowComment::new( cgi, 'update.rhtml', conf ) elsif params['saveconf'] tdiary = TDiary::TDiarySaveConf::new( cgi, 'conf.rhtml', conf ) elsif params['conf'] tdiary = TDiary::TDiaryConf::new( cgi, 'conf.rhtml', conf ) elsif params['referer'] tdiary = TDiary::TDiaryConf::new( cgi, 'referer.rhtml', conf ) else tdiary = TDiary::TDiaryForm::new( cgi, 'update.rhtml', conf ) end rescue TDiary::TDiaryError tdiary = TDiary::TDiaryForm::new( cgi, 'update.rhtml', conf ) end tdiary end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/environment.rb000066400000000000000000000021171362645730700207110ustar00rootroot00000000000000# name spaces reservation module TDiary; end module TDiary::Cache; end # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __FILE__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) # FIXME: workaround fix for tainted path from Gemfile.local $LOAD_PATH.each{|lp| $LOAD_PATH << $LOAD_PATH.shift.dup} if defined?(Bundler) env = [:default, :rack] env << :development if ENV['RACK_ENV'].nil? || ENV['RACK_ENV'].empty? env << ENV['RACK_ENV'].intern if ENV['RACK_ENV'] env = env.reject{|e| (Bundler.settings.without rescue Bundler.settings[:without]).include? e } Bundler.require *env end # Bundler.require doesn't load gems specified in .gemspec # see: https://github.com/bundler/bundler/issues/1041 # # load gems dependented by tdiary tdiary_spec = Bundler.definition.specs.find {|spec| spec.name == 'tdiary'} if tdiary_spec tdiary_spec.dependent_specs.each {|dep_spec| begin require dep_spec.name rescue LoadError => e STDERR.puts "failed require '#{dep_spec.name}'" STDERR.puts e end } end tdiary-core-5.1.1/lib/tdiary/extensions.rb000066400000000000000000000000541362645730700205420ustar00rootroot00000000000000module TDiary module Extensions end end tdiary-core-5.1.1/lib/tdiary/extensions/000077500000000000000000000000001362645730700202165ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/extensions/core.rb000066400000000000000000000003711362645730700214740ustar00rootroot00000000000000module TDiary module Extensions class Core def self.sp_path end def self.assets_path %w(js theme).map {|path| [TDiary.root, TDiary.server_root].map {|base_dir| File.join(base_dir, path) } } end end end end tdiary-core-5.1.1/lib/tdiary/filter.rb000066400000000000000000000015271362645730700176360ustar00rootroot00000000000000# # module/class Filter # module TDiary module Filter class Filter include ViewHelper DEBUG_NONE = 0 DEBUG_SPAM = 1 DEBUG_FULL = 2 def initialize( cgi, conf ) @cgi, @conf = cgi, conf if @conf.options.include?('filter.debug_mode') @debug_mode = @conf.options['filter.debug_mode'] else @debug_mode = DEBUG_NONE end end def comment_filter( diary, comment ) true end def referer_filter( referer ) true end def debug( msg, level = DEBUG_SPAM ) return if @debug_mode == DEBUG_NONE return if @debug_mode == DEBUG_SPAM and level == DEBUG_FULL TDiary.logger.info("#{@cgi.remote_addr}->#{(@cgi.params['date'][0] || 'no date').dump}: #{msg}") end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/filter/000077500000000000000000000000001362645730700173045ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/filter/default.rb000066400000000000000000000023301362645730700212530ustar00rootroot00000000000000# # default.rb: included TDiary::Filter::DefaultFilter class # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # module TDiary module Filter class DefaultFilter < Filter def comment_filter( diary, comment ) if 'POST' != @cgi.request_method then return false end if comment.name.strip.empty? or comment.body.strip.empty? then return false end idx = 1 diary.each_comment( -1 ) do |com| return false if idx >= @conf.comment_limit_per_day return false if comment == com idx += 1 end true end def referer_filter( referer ) if not referer then false #elsif /[\x00-\x20\x7f-\xff]/ =~ referer then # false elsif @conf.bot =~ @cgi.user_agent false elsif %r|^https?://|i =~ referer ref = CGI::unescape( referer.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) ).force_encoding('ASCII-8BIT') @conf.no_referer.each do |noref| return false if /#{noref.dup.force_encoding('ASCII-8BIT')}/i =~ ref end true else false end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/filter/spam.rb000066400000000000000000000204751362645730700206010ustar00rootroot00000000000000# Copyright (C) 2005 akira yamada # You can redistribute it and/or modify it under GPL2 or any later version. require 'uri' require 'resolv' require 'socket' require 'timeout' module TDiary module Filter class SpamFilter < Filter TLD = %w(com net org edu gov mil int info biz name pro museum aero coop [a-z]{2}) def initialize( *args ) super( *args ) @filter_mode = true @max_uris = nil @max_rate = nil @bad_uri_patts_for_mails = false @bad_uri_patts = nil @bad_mail_patts = nil @bad_comment_patts = nil @bad_ip_addrs = nil @bad_uris = [] @bad_mails_ext = [] @bad_mails = [] @bad_comments = [] @bad_ips = [] @date_limit = nil end def update_config if @conf.options.include?('spamfilter.filter_mode') if @conf.options['spamfilter.filter_mode'] @filter_mode = true # invisible else @filter_mode = false # drop end else @filter_mode = true # invisible end if @conf.options.include?('spamfilter.max_uris') @max_uris = @conf.options['spamfilter.max_uris'].to_i else @max_uris = nil end if @conf.options.include?('spamfilter.max_rate') @max_rate = @conf.options['spamfilter.max_rate'].to_i else @max_rate = nil end if @conf.options.include?('spamlookup.ip.list') @spamlookup_ip_list = @conf.options['spamlookup.ip.list'] else @spamlookup_ip_list = "bsb.spamlookup.net" end if @conf.options.include?('spamlookup.domain.list') @spamlookup_domain_list = @conf.options['spamlookup.domain.list'] else @spamlookup_domain_list = "bsb.spamlookup.net\nmulti.surbl.org\nrbl.bulkfeeds.jp" end if @conf.options.include?('spamlookup.safe_domain.list') @spamlookup_safe_domain_list = @conf.options['spamlookup.safe_domain.list'] else @spamlookup_safe_domain_list = "www.google.com\nwww.google.co.jp\nsearch.yahoo.co.jp\nwww.bing.com" end if @conf.options.include?('spamfilter.bad_uri_patts_for_mails') @bad_uri_patts_for_mails = @conf.options['spamfilter.bad_uri_patts_for_mails'] else @bad_uri_patts_for_mails = false end unless @bad_uri_patts_for_mails @bad_mails_ext = [] end unless @conf.options.include?('spamfilter.bad_uri_patts') @conf.options['spamfilter.bad_uri_patts'] = '' end if @bad_uri_patts != @conf.options['spamfilter.bad_uri_patts'] @bad_uri_patts = @conf.options['spamfilter.bad_uri_patts'] tmp = @bad_uri_patts.split(/[\r\n]+/) tmp.delete_if {|t| t.empty?} if tmp.empty? @bad_uris = [] @bad_mails_ext = [] else @bad_uris = [ %r!^[a-z]*://(?:[^/]*(?:#{tmp.join('|')})){2}!i, %r!^[a-z]*://[^/]*\b(?:#{tmp.join('|')})!i, %r!^[a-z]*://[^/]*(?:#{tmp.join('|')})\b!i, %r!^[a-z]*://.*\b(?:#{tmp.join('|')})\b!i, %r!^[a-z]*://[^/]*?[^./]{20,}[^/]*/?$!i, %r!^[a-z]*://[^/.]+(?:/|$)!i, %r<^[a-z]*://[^/]+\.(?!(?:#{TLD.join("|")})\b\.?)[^.:/]+(?:\.?(?::\d+)?(?:/|$))>i, ] if @bad_uri_patts_for_mails @bad_mails_ext = [ %r!\b(?:#{tmp.join('|')})!i, %r!(?:#{tmp.join('|')})\b!i, ] end end end unless @conf.options.include?('spamfilter.bad_mail_patts') @conf.options['spamfilter.bad_mail_patts'] = '' end if @bad_mail_patts != @conf.options['spamfilter.bad_mail_patts'] @bad_mail_patts = @conf.options['spamfilter.bad_mail_patts'] tmp = @bad_mail_patts.split(/[\r\n]+/) tmp.delete_if {|t| t.empty?} @bad_mails = tmp.collect {|t| %r!#{t}!i rescue nil}.compact end unless @conf.options.include?('spamfilter.bad_comment_patts') @conf.options['spamfilter.bad_comment_patts'] = '' end if @bad_comment_patts != @conf.options['spamfilter.bad_comment_patts'] @bad_comment_patts = @conf.options['spamfilter.bad_comment_patts'] tmp = @bad_comment_patts.split(/[\r\n]+/) tmp.delete_if {|t| t.empty?} @bad_comments = tmp.collect {|t| %r!#{t}!i rescue nil}.compact end unless @conf.options.include?('spamfilter.bad_ip_addrs') @conf.options['spamfilter.bad_ip_addrs'] = '' end if @bad_ip_addrs != @conf.options['spamfilter.bad_ip_addrs'] @bad_ip_addrs = @conf.options['spamfilter.bad_ip_addrs'] tmp = @bad_ip_addrs.split(/[\r\n]+/) tmp.delete_if {|t| t.empty?} @bad_ips = tmp.collect do |t| if /\.$/ =~ t %r!#{Regexp.quote(t[0..-2]) + '.*'}!i else %r!#{Regexp.quote(t)}!i end end end nil end def name_base_black_domain?( domain ) @spamlookup_domain_list.split(/[\n\r]+/).inject(false) do |r, dnsbl| r || lookup(domain, dnsbl) end end def ip_base_black_domain?( domain ) @spamlookup_ip_list.split(/[\n\r]+/).inject(false) do |r, dnsbl| r || lookup(domain, dnsbl, true) end end def lookup(domain, dnsbl, iplookup = false) Timeout::timeout(1) do domain = IPSocket::getaddress( domain ).split(/\./).reverse.join(".") if iplookup address = Resolv.getaddress( "#{domain}.#{dnsbl}" ) debug("lookup:#{domain}.#{dnsbl} address:#{address}: spam host.") return true end rescue Timeout::Error, Resolv::ResolvTimeout debug("lookup:#{domain}.#{dnsbl}: safe host.") return false rescue Resolv::ResolvError, Exception debug("unknown error:#{domain}.#{dnsbl}", DEBUG_FULL) return false end def black_url?( body ) body.scan( %r|https?://([^/:\s]+)| ) do |s| if @spamlookup_safe_domain_list.include?( s[0] ) debug("#{s[0]} is safe host.", DEBUG_FULL) next end return true if name_base_black_domain?( s[0] ) || ip_base_black_domain?( s[0] ) end return false end def comment_filter( diary, comment ) update_config return false if black_url?( comment.body ) if %r{/\.\/} =~ ENV['REQUEST_URI'] debug( "REQUEST_URI contains %r{/\./}: #{ENV['REQUEST_URI']}" ) comment.show = false return @filter_mode end if /^[\x20-\x7f]*$/io !~ comment.mail # mail address include not ASCII charactor debug( "invalid mail address: #{comment.mail.dump}" ) comment.show = false return @filter_mode end if !comment.mail.empty? && %r<@[^@]+\.(?:#{TLD.join("|")})$>i !~ comment.mail debug( "invalid domain name of mail address: #{comment.mail.dump}" ) comment.show = false return @filter_mode end p = nil if @bad_mails.detect {|p| p =~ comment.mail} || @bad_mails_ext.detect {|p| p =~ comment.mail} debug( "mail address blacklisted: /#{p}/ =~ #{comment.mail.dump}" ) comment.show = false return @filter_mode end if @bad_comments.detect {|p| p =~ comment.body} debug( "comment contains bad words: /#{p}/" ) comment.show = false return @filter_mode end if @bad_ips.detect {|p| p =~ @cgi.remote_addr} debug( "ip address blacklisted: /#{p}/ =~ #{@cgi.remote_addr}" ) comment.show = false return @filter_mode end uris = URI.extract( comment.body, %w(http https ftp mailto) ) unless uris.empty? if @max_uris && @max_uris >= 0 && uris.size > @max_uris debug( "too many URIs" ) comment.show = false return @filter_mode end if @max_rate && @max_rate > 0 && uris.join('').size * 100 / comment.body.gsub(/\s+/, '').size > @max_rate debug( "too many URI-chars" ) comment.show = false return @filter_mode end uris.each do |uri| uri = uri.sub(/^ur[il]:/io, '') @bad_uris.each do |bad_uri| if bad_uri =~ uri debug( "comment contains bad words: #{uri}: #{bad_uri}" ) comment.show = false return @filter_mode end end end end return true end def referer_filter( referer ) return true unless referer update_config return false if black_url?( referer ) if /#/ =~ referer then debug( "referer has a fragment: #{referer}" ) return false end if %r{\A[^:]+://[^/]*\z} =~ referer debug( "referer has no path: #{referer}" ) return false end @bad_uris.each do |bad_uri| if bad_uri =~ referer debug( "referer contains bad words: #{referer}: #{bad_uri}" ) return false end end return true end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/io/000077500000000000000000000000001362645730700164265ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/io/base.rb000066400000000000000000000037041362645730700176710ustar00rootroot00000000000000# # class IOBase # base of IO class # require 'fileutils' require 'tdiary/style' # XXX can't auto loading TDiary::Style subclasses module TDiary module IO class Base def initialize( tdiary ) @tdiary = tdiary @data_path = @tdiary.conf.data_path if @tdiary.conf.data_path load_styles end def calendar raise StandardError, 'not implemented' end def transaction(date) raise StandardError, 'not implemented' end def diary_factory(date, title, body, style_name = 'tDiary') style(style_name.downcase).new(date, title, body) end def cache_dir raise StandardError, 'not implemented' end def cache_path @_cache_path ||= cache_dir FileUtils.mkdir_p(@_cache_path) @_cache_path end def load_styles @styles = {} paths = @tdiary.conf.options['style.path'] || [TDiary::PATH, TDiary.server_root].map {|base| "#{base}/tdiary/style" } [paths].flatten.uniq.each do |path| path = path.sub(/\/+$/, '') Dir.glob("#{path}/*.rb") {|style_file| require style_file } end TDiary::Style.constants(false).each do |name| prefix = name.slice(/\A(.*)Diary\z/, 1) if prefix && /\A(Base|Categorizable|Uncategorizable)\z/ !~ prefix klass = TDiary::Style.const_get(name) klass.send(:include, TDiary::Style::BaseDiary) klass.send(:include, TDiary::Style::CategorizableDiary) section_class_name = "#{prefix}Section" if TDiary::Style.const_defined?(section_class_name) TDiary::Style.const_get(section_class_name).send(:include, TDiary::Style::BaseSection) end @styles[prefix.downcase] = klass end end end def style(s) unless @styles raise BadStyleError, "styles are not loaded" end r = @styles[s.downcase] unless r raise BadStyleError, "bad style: #{s}" end r end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/io/default.rb000066400000000000000000000201271362645730700204010ustar00rootroot00000000000000# # defaultio.rb: tDiary IO class for tDiary 2.x - 4.x format. # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # require 'fileutils' require 'tdiary/io/base' require 'tdiary/comment' module TDiary TDIARY_MAGIC_MAJOR = 'TDIARY2' TDIARY_MAGIC_MINOR = '01.00' TDIARY_MAGIC = "#{TDIARY_MAGIC_MAJOR}.#{TDIARY_MAGIC_MINOR}" module IO module Comment def comment_file( data_path, date ) date.strftime( "#{data_path}%Y/%Y%m.tdc" ) end def restore_comment( file, diaries ) minor = '' begin File::open( file ) do |fh| fh.flock( File::LOCK_SH ) major, minor = fh.gets.chomp.split( /\./, 2 ) unless TDIARY_MAGIC_MAJOR == major then raise StandardError, 'bad file format.' end s = fh.read s = migrate_to_01( s ) if minor == '00.00' and !@tdiary.conf['stop_migrate_01'] s.split( /\r?\n\.\r?\n/ ).each do |l| headers, body = Default.parse_tdiary( l ) next unless body comment = ::TDiary::Comment::new( headers['Name'], headers['Mail'], body, Time::at( headers['Last-Modified'].to_i ) ) comment.show = false if headers['Visible'] == 'false' diaries[headers['Date']].add_comment( comment ) if headers['Date'] end end rescue Errno::ENOENT end return minor == '00.00' ? TDiaryBase::DIRTY_COMMENT : TDiaryBase::DIRTY_NONE end def store_comment( file, diaries ) File::open( file, File::WRONLY | File::CREAT ) do |fhc| fhc.flock( File::LOCK_EX ) fhc.rewind fhc.truncate( 0 ) fhc.puts( TDIARY_MAGIC ) diaries.each do |date,diary| diary.each_comment( diary.count_comments( true ) ) do |com| fhc.puts( "Date: #{date}" ) fhc.puts( "Name: #{com.name}" ) fhc.puts( "Mail: #{com.mail}" ) fhc.puts( "Last-Modified: #{com.date.to_i}" ) fhc.puts( "Visible: #{com.visible? ? 'true' : 'false'}" ) fhc.puts fhc.puts( com.body.gsub( /\r/, '' ).sub( /\n+\Z/, '' ).gsub( /\n\./, "\n.." ) ) fhc.puts( '.' ) end end end end end module Referer def referer_file( data_path, date ) date.strftime( "#{data_path}%Y/%Y%m.tdr" ) end def restore_referer( file, diaries ) begin File::open( file ) do |fh| fh.flock( File::LOCK_SH ) fh.read.split( /\r?\n\.\r?\n/ ).each do |l| headers, body = Default.parse_tdiary( l ) next unless body body.lines.each do |r| count, ref = r.chomp.split( / /, 2 ) next unless ref diaries[headers['Date']].add_referer( ref.chomp, count.to_i ) end end # convert to referer plugin format diaries.each do |date,diary| fname = file.sub( /\.tdr$/, "#{date[6,2]}.tdr" ) File::open( fname, File::WRONLY | File::CREAT ) do |fhr| fhr.flock( File::LOCK_EX ) fhr.rewind fhr.truncate( 0 ) fhr.puts( TDiary::TDIARY_MAGIC ) fhr.puts( "Date: #{date}" ) fhr.puts diary.each_referer( diary.count_referers ) do |count,ref| fhr.puts( "#{count} #{ref}" ) end fhr.puts( '.' ) end end end File::rename( file, file.sub( /\.tdr$/, '.tdr~' ) ) rescue Errno::ENOENT end return TDiaryBase::DIRTY_NONE end def store_referer( file, diaries ) return end end class Default < Base include Comment include Referer include Cache class << self def parse_tdiary( data ) header, body = data.split( /\r?\n\r?\n/, 2 ) headers = {} if header then header.lines.each do |l| l.chomp! key, val = l.scan( /([^:]*):\s*(.*)/ )[0] headers[key] = val ? val.chomp : nil end end if body then body.gsub!( /^\./, '' ) else body = '' end [headers, body] end def load_cgi_conf(conf) conf.class.class_eval { attr_accessor :data_path } raise TDiaryError, 'No @data_path variable.' unless conf.data_path conf.data_path += '/' if /\/$/ !~ conf.data_path raise TDiaryError, 'Do not set @data_path as same as tDiary system directory.' if conf.data_path == "#{TDiary::PATH}/" File::open( "#{conf.data_path}tdiary.conf" ){|f| f.read } rescue IOError, Errno::ENOENT end def save_cgi_conf(conf, result) File::open( "#{conf.data_path}tdiary.conf", 'w' ) {|o| o.print result } rescue IOError, Errno::ENOENT end end # # block must be return boolean which dirty diaries. # def transaction( date ) diaries = {} dir = date.strftime( "#{@data_path}%Y" ) @dfile = date.strftime( "#{@data_path}%Y/%Y%m.td2" ) cfile = comment_file( @data_path, date ) rfile = referer_file( @data_path, date ) begin FileUtils.mkdir_p(dir) begin fh = File::open( @dfile, 'r+' ) rescue fh = File::open( @dfile, 'w+' ) end fh.flock( File::LOCK_EX ) cache = restore_parser_cache( date, 'default' ) force_save = TDiaryBase::DIRTY_NONE unless cache then force_save |= restore( fh, diaries ) force_save |= restore_comment( cfile, diaries ) force_save |= restore_referer( rfile, diaries ) else diaries.update( cache ) end dirty = yield( diaries ) if iterator? store( fh, diaries ) if ((dirty | force_save) & TDiaryBase::DIRTY_DIARY) != 0 store_comment( cfile, diaries ) if ((dirty | force_save) & TDiaryBase::DIRTY_COMMENT) != 0 store_referer( rfile, diaries ) if ((dirty | force_save) & TDiaryBase::DIRTY_REFERER) != 0 if dirty != TDiaryBase::DIRTY_NONE or not cache then store_parser_cache(date, diaries, 'default') end if diaries.empty? begin if fh then fh.close fh = nil end File::delete( @dfile ) rescue Errno::ENOENT end begin store_parser_cache(date, nil, nil) rescue Errno::ENOENT end end # delete dispensable data directory begin Dir.delete( dir ) if Dir.new( dir ).entries.reject {|f| "." == f or ".." == f}.empty? rescue Errno::ENOENT end ensure fh.close if fh end end def calendar calendar = {} Dir["#{@data_path}????/??????.td2"].sort.each do |file| if file =~ /(\d{4})(\d{2})\.td2$/ calendar[$1] = [] unless calendar[$1] calendar[$1] << $2 end end calendar end def cache_dir @tdiary.conf.cache_path || "#{@data_path}/cache" end private def restore( fh, diaries ) begin fh.seek( 0 ) begin major, minor = fh.gets.chomp.split( /\./, 2 ) unless TDIARY_MAGIC_MAJOR == major then raise StandardError, 'bad file format.' end # read and parse diary style_name = '' s = fh.read s = migrate_to_01( s ) if minor == '00.00' and !@tdiary.conf['stop_migrate_01'] s.split( /\r?\n\.\r?\n/ ).each do |l| headers, body = Default.parse_tdiary( l ) style_name = headers['Format'] || 'tDiary' diary = style( style_name )::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) ) diary.show( headers['Visible'] == 'true' ? true : false ) diaries[headers['Date']] = diary end rescue NameError # no magic number when it is new file. end end return minor == '00.00' ? TDiaryBase::DIRTY_DIARY : TDiaryBase::DIRTY_NONE end def store( fh, diaries ) begin fh.seek( 0 ) fh.puts( TDIARY_MAGIC ) diaries.sort_by {|date, diary| date}.each do |date,diary| # save diaries fh.puts( "Date: #{date}" ) fh.puts( "Title: #{diary.title}" ) fh.puts( "Last-Modified: #{diary.last_modified.to_i}" ) fh.puts( "Visible: #{diary.visible? ? 'true' : 'false'}" ) fh.puts( "Format: #{diary.style}" ) fh.puts fh.puts( diary.to_src.gsub( /\r/, '' ).gsub( /\n\./, "\n.." ) ) fh.puts( '.' ) end fh.truncate( fh.tell ) end end def migrate_to_01( day ) @tdiary.conf.migrate_to_utf8( day ) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/io/plugin_pstore.rb000066400000000000000000000016301362645730700216450ustar00rootroot00000000000000# # module io/plugin_pstore # default plugin storage implemented by PStore # require 'pstore' module TDiary module IO module PluginPStore # returning storage object def plugin_open(conf) storage = Pathname(conf.data_path) + 'plugin' storage.mkpath return storage end def plugin_close(storage_object) end def plugin_transaction(storage_object, plugin_name) PStore.new(storage_object + "#{plugin_name}.db").transaction do |db| # define methods of plugin storage interface # PStore has 'delete' method as same function def db.get(key) self[key] end def db.set(key, value) self[key] = value end # def db.delete( key ) # # end def db.keys self.roots end yield db end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/io/pstore.rb000066400000000000000000000127321362645730700202740ustar00rootroot00000000000000# # pstoreio.rb: tDiary IO class of tdiary 1.x format. # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # require 'pstore' module TDiary module IO class PStore def initialize( tdiary ) @data_path = tdiary.conf.data_path end # # block must be return boolean which dirty diaries. # def transaction( date ) diaries = {} filename = date.strftime( "#{@data_path}%Y%m" ) begin PStore::new( filename ).transaction do |db| dirty = false if db.root?( 'diary' ) then diaries.update( db['diary'] ) end dirty = yield( diaries ) if iterator? if dirty != TDiary::TDiaryBase::DIRTY_NONE then db['diary'] = diaries else db.abort end end rescue PStore::Error, NameError, Errno::EACCES raise PermissionError::new( "make your @data_path to writable via httpd. #$!" ) end begin File::delete( filename ) if diaries.empty? rescue Errno::ENOENT end return diaries end def calendar calendar = {} Dir["#{@data_path}??????"].sort.each do |file| year, month = file.scan( %r[/(\d{4})(\d\d)$] )[0] next unless year calendar[year] = [] unless calendar[year] calendar[year] << month end calendar end def diary_factory( date, title, body, style = nil ) Diary::new( date, title, body ) end end end end =begin == class Comment Management a comment. =end class Comment attr_reader :name, :mail, :body, :date def initialize( name, mail, body, date = Time::now ) @name, @mail, @body, @date = name, mail, body, date @show = true end def shorten( len = 120 ) lines = NKF::nkf( "-e -m0 -f#{len}", @body.gsub( /\n/, ' ' ) ).split( /\n/ ) lines[0].concat( '..' ) if lines[0] and lines[1] lines[0] || '' end def visible?; @show; end def show=( s ); @show = s; end def ==( c ) (@name == c.name) and (@mail == c.mail) and (@body == c.body) end end =begin == Paragraph class Management a paragraph. =end class Paragraph attr_reader :subtitle, :body alias :body_to_html :body alias :subtitle_to_html :subtitle def initialize( fragment, author = nil ) @author = author lines = fragment.split( /\n+/ ) if lines.size > 1 then if /^<\n] if paragraph.subtitle then r << %Q[

">#{opt['section_anchor']} ] if opt['multi_user'] and paragraph.author then r << %Q|[#{paragraph.author}]| end r << %Q[#{paragraph.subtitle}

] end if /^#{paragraph.body.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

\n

" )}

] else r << %Q[

">#{opt['section_anchor']} #{paragraph.body.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

\n

" )}

] end r << %Q[

] idx += 1 end r end def to_chtml( opt ) idx = 0 r = '' each_section do |paragraph| if paragraph.subtitle then r << %Q[

* #{paragraph.subtitle}

] end if /^#{paragraph.body.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

\n

" )}

] else r << %Q[

* ] if opt['multi_user'] and paragraph.author then r << %Q|[#{paragraph.author}]| end r << %Q[#{paragraph.body.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

\n

" )}

] end end r end def to_s "date=#{@date.strftime('%Y%m%d')}, title=#{@title}, body=[#{@paragraphs.join('][')}]" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/lang/000077500000000000000000000000001362645730700167405ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/lang/en.rb000066400000000000000000000023561362645730700176750ustar00rootroot00000000000000# # tDiary language setup: English(en) # # Copyright (C) 2001-2011, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # 'html_lang' method returns String of HTML language attribute. # def html_lang 'en-US' end # # 'encoding' method returns String of HTTP or HTML charactor encoding. # def encoding 'UTF-8' end def encoding_old 'UTF-8' end # # 'mobile_encoding' method returns charactor encoding in mobile mode. # def mobile_encoding 'UTF-8' end # # 'migrate_to_utf8' method converts string to UTF-8, but dummy in en. # def migrate_to_utf8( str ) str.dup end # # 'to_mobile' method converts string automatically to mobile mode encoding. # def to_mobile( str ) str.dup end # # 'to_mail' method converts string automatically to E-mail encoding. # def to_mail( str ) str.dup end # # 'shorten' method cuts string length. # def shorten( str, length = 120 ) matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{length - 2}}/u )[0] unless $'.empty? matched + '..' else matched end end # # 'comment_length' returns length of shorten comment on recent or monthly view. # def comment_length 120 end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/lang/ja.rb000066400000000000000000000015021362645730700176550ustar00rootroot00000000000000# # tDiary language setup: Japanese(ja) # # Copyright (C) 2001-2011, TADA Tadashi # You can redistribute it and/or modify it under GPL2. or any later version # def html_lang 'ja-JP' end def encoding 'UTF-8' end def encoding_old 'EUC-JP' end def mobile_encoding 'Shift_JIS' end def to_mobile( str ) str.encode(mobile_encoding, {invalid: :replace, undef: :replace}) end def to_mail( str ) str.encode('iso-2022-jp', {invalid: :replace, undef: :replace}) end def migrate_to_utf8( str ) to_native( str, encoding_old ) end def shorten( str, len = 120 ) matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{len - 2}}/u )[0] if $'.nil? || $'.empty? matched else matched + '..' end end def comment_length 60 end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin.rb000066400000000000000000000177261362645730700176570ustar00rootroot00000000000000# # class Plugin # plugin management class # require 'erb' module TDiary class Plugin include ERB::Util include ViewHelper attr_reader :cookies attr_writer :comment, :date, :diaries, :last_modified def initialize( params ) @header_procs = [] @footer_procs = [] @update_procs = [] @title_procs = [] @body_enter_procs = [] @body_leave_procs = [] @section_index = {} @section_enter_procs = [] @comment_leave_procs = [] @subtitle_procs = [] @section_leave_procs = [] @edit_procs = [] @form_procs = [] @conf_keys = [] @conf_procs = {} @conf_genre_label = {} @content_procs = {} @startup_procs = [] @cookies = [] @javascripts = {} @javascript_setting = [] params.each do |key, value| instance_variable_set( "@#{key}", value ) end # for 1.4 compatibility @index = @conf.index @update = @conf.update @author_name = @conf.author_name || '' @author_mail = @conf.author_mail || '' @index_page = @conf.index_page || '' @html_title = @conf.html_title || '' @theme = @conf.theme @css = @conf.css @date_format = @conf.date_format @referer_table = @conf.referer_table @options = @conf.options # setup plugin storage unless @conf.io_class.method_defined?(:plugin_open) require 'tdiary/io/plugin_pstore' @conf.io_class.extend(TDiary::IO::PluginPStore) end @storage = @conf.io_class.plugin_open(@conf) # loading plugins @plugin_files = [] plugin_path = @conf.plugin_path || "#{File.dirname(__FILE__)}/plugin" plugin_file = '' begin Dir::glob( "#{plugin_path}/*.rb" ).sort.each do |file| plugin_file = file load_plugin( file ) @plugin_files << plugin_file end rescue ::TDiary::ForceRedirect raise rescue Exception raise PluginError::new( "Plugin error in '#{File::basename( plugin_file )}'.\n#{$!}\n#{$!.backtrace[0]}" ) end end def load_plugin( file ) @resource_loaded = false begin res_file = File::dirname( file ) + "/#{@conf.lang}/" + File::basename( file ) open( res_file ) do |src| instance_eval( src.read, "(plugin/#{@conf.lang}/#{File::basename( res_file )})", 1 ) end @resource_loaded = true rescue IOError, Errno::ENOENT end File::open( file ) do |src| instance_eval( src.read, "(plugin/#{File::basename( file )})", 1 ) end end def eval_src( src ) ret = eval( src, binding, "(TDiary::Plugin#eval_src)", 1 ) @conf.io_class.plugin_close(@storage) return ret end private def transaction(plugin_name) @conf.io_class.plugin_transaction(@storage, plugin_name) do |db| yield db end end def add_header_proc( &block ) @header_procs << block if block_given? end def header_proc r = [] @header_procs.each do |proc| r << proc.call end r.join.chomp end def add_footer_proc( &block ) @footer_procs << block if block_given? end def footer_proc r = [] @footer_procs.each do |proc| r << proc.call end r.join.chomp end def add_update_proc( &block ) @update_procs << block if block_given? end def update_proc @update_procs.each(&:call) '' end def add_title_proc( &block ) @title_procs << block if block_given? end def title_proc( date, title ) @title_procs.each do |proc| title = proc.call( date, title ) end apply_plugin( title ) end def add_body_enter_proc( &block ) @body_enter_procs << block if block_given? end def body_enter_proc( date ) r = [] @body_enter_procs.each do |proc| r << proc.call( date ) end r.join end def add_body_leave_proc( &block ) @body_leave_procs << block if block_given? end def body_leave_proc( date ) r = [] @body_leave_procs.each do |proc| r << proc.call( date ) end r.join end def add_section_enter_proc( &block ) @section_enter_procs << block if block_given? end def section_enter_proc( date ) @section_index[date] = (@section_index[date] || 0) + 1 r = [] @section_enter_procs.each do |proc| r << proc.call( date, @section_index[date] ) end r.join end def add_subtitle_proc( &block ) @subtitle_procs << block if block_given? end def subtitle_proc( date, subtitle ) @subtitle_procs.each do |proc| subtitle = proc.call( date, @section_index[date], subtitle ) end apply_plugin( subtitle ) end def add_section_leave_proc( &block ) @section_leave_procs << block if block_given? end def section_leave_proc( date ) r = [] @section_leave_procs.each do |proc| r << proc.call( date, @section_index[date] ) end r.join end def add_comment_leave_proc( &block ) @comment_leave_procs << block if block_given? end def comment_leave_proc( date ) r = [] @comment_leave_procs.each do |proc| r << proc.call( date ) end r.join end def add_edit_proc( &block ) @edit_procs << block if block_given? end def edit_proc( date ) r = [] @edit_procs.each do |proc| r << proc.call( date ) end r.join end def add_form_proc( &block ) @form_procs << block if block_given? end def form_proc( date ) r = [] @form_procs.each do |proc| r << proc.call( date ) end r.join end def add_conf_proc( key, label, genre = 'etc', &block ) return unless @mode =~ /^(conf|saveconf)$/ genre_and_key = "#{genre}:#{key}" @conf_keys << genre_and_key unless @conf_keys.index( genre_and_key ) @conf_procs[key] = [label, block] if block_given? end def each_conf_genre genres = {} @conf_keys.each do |genre_and_key| genre, key = genre_and_key.split( /:/, 2 ) next if genres[genre] yield genre genres[genre] = key end end def each_conf_key( genre ) re = /^#{genre}:/ @conf_keys.each do |genre_and_key| if re =~ genre_and_key then genre, key = genre_and_key.split( /:/, 2 ) yield key end end end def conf_proc( key ) r = '' _, block = @conf_procs[key] r = block.call if block r end def conf_genre_label( genre ) label = @conf_genre_label[genre] label ? label : genre end def conf_label( key ) label, = @conf_procs[key] label end def conf_current_style( key ) if key == @cgi.params['conf'][0] then 'selected' else 'other' end end def add_cookie( cookie ) @cookies << cookie end def enable_js( script, async: false ) @javascripts[script] = { async: async } end def add_js_setting( var, val = 'new Object()' ) @javascript_setting << [var, val] end def add_content_proc( key, &block ) @content_procs[key] = block if block_given? end def content_proc( key, date ) unless @content_procs.key?( key ) raise PluginError::new( "Plugin error: #{key} is not found." ) end @content_procs[key].call( date ) end def add_startup_proc( &block ) @startup_procs << block if block_given? end def startup_proc( app ) @startup_procs.each do |proc| proc.call( app ) end end def remove_tag( str ) str.gsub( /<[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$)/, '' ) end def apply_plugin( str, remove_tag = false ) return '' unless str r = str.dup if @conf.options['apply_plugin'] and r.index( '<%' ) then begin r = ERB::new( r ).result( binding ) rescue Exception r = %Q|

Invalid Text

#{r}| end end r = remove_tag( r ) if remove_tag r end def disp_referer( table, ref ) ref = @conf.to_native( CGI::unescape( ref ) ) str = nil table.each do |url, name| if /#{url}/iu =~ ref then str = ref.gsub( /#{url}/iu, name ) break end end str ? str : ref end def help( name ) %Q[Help] end def method_missing( *m ) super if @debug # ignore when no plugin end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/plugin/000077500000000000000000000000001362645730700173155ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/plugin/00default.rb000066400000000000000000000655541362645730700214450ustar00rootroot00000000000000# # 00default.rb: default plugins # # Copyright (C) 2010, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # setting @date # unless @date if @diary then @date = @diary.date else @date = case @mode when 'day' Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)(\d\d)/ ).flatten ) when 'month' Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)/ ).flatten ) when 'edit' Time::local( @cgi.params['year'][0].to_i, @cgi.params['month'][0].to_i, @cgi.params['day'][0].to_i ) else nil end end end # # make navigation buttons # def navi result = %Q[
\n] result << navi_user result << navi_admin result << %Q[
] end def navi_item( link, label, rel = nil ) result = %Q[#{label}\n] end def navi_user result = navi_user_default case @mode when 'latest' result << navi_user_latest when 'day' result << navi_user_day when 'month' result << navi_user_month when 'nyear' result << navi_user_nyear when 'edit' result << navi_user_edit else result << navi_user_else end result end def navi_user_default result = '' result << navi_item( h(@conf.index_page), h(navi_index) ) unless @conf.index_page.empty? result end def navi_user_latest result = '' result << navi_item( "#{h @conf.index}#{anchor( @conf['ndays.prev'] + '-' + @conf.latest_limit.to_s )}", "«#{navi_prev_ndays}", "next" ) if @conf['ndays.prev'] and not bot? result << navi_item( h(@conf.index), h(navi_latest) ) if @cgi.params['date'][0] result << navi_item( "#{h @conf.index}#{anchor( @conf['ndays.next'] + '-' + @conf.latest_limit.to_s )}", "#{navi_next_ndays}»", "prev") if @conf['ndays.next'] and not bot? result end def navi_user_day result = '' if @navi_user_days then result << navi_item( "#{h @conf.index}#{anchor @navi_user_days[0]}", "«#{h navi_prev_diary(navi_user_format(@navi_user_days[0]))}" ) if @navi_user_days[0] result << navi_item( h(@conf.index), h(navi_latest) ) result << navi_item( "#{h @conf.index}#{anchor @navi_user_days[2]}", "#{h navi_next_diary(navi_user_format(@navi_user_days[2]))}»" ) if @navi_user_days[2] end result end def navi_user_month ym = [] @years.keys.each do |y| ym += @years[y].collect {|m| y + m} end ym.sort! now = @date.strftime( '%Y%m' ) return '' unless ym.index( now ) prev_month = ym.index( now ) == 0 ? nil : ym[ym.index( now )-1] next_month = ym[ym.index( now )+1] result = '' result << navi_item( "#{h @conf.index}#{anchor( prev_month )}", "«#{h navi_prev_month}" ) if prev_month and not bot? result << navi_item( h(@conf.index), h(navi_latest) ) result << navi_item( "#{h @conf.index}#{anchor( next_month )}", "#{h navi_next_month}»" ) if next_month and not bot? result end def navi_user_nyear result = '' result << navi_item( "#{h @conf.index}#{anchor @prev_day[4,4]}", "«#{h navi_prev_nyear(Time::local(*@prev_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}" ) if @prev_day result << navi_item( h(@conf.index), h(navi_latest) ) unless @mode == 'latest' result << navi_item( "#{h @conf.index}#{anchor @next_day[4,4]}", "#{h navi_next_nyear(Time::local(*@next_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}»" ) if @next_day result end def navi_user_edit result = '' if @prev_day then a = @prev_day.scan( /^(\d{4})(\d\d)(\d\d)$/ ).flatten result << navi_item( "#{h @conf.update}?edit=true;year=#{a[0]};month=#{a[1]};day=#{a[2]}", "«#{h navi_prev_diary(Time::local(*@prev_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}" ) end result << navi_item( h(@conf.index), h(navi_latest) ) if @next_day then a = @next_day.scan( /^(\d{4})(\d\d)(\d\d)$/ ).flatten result << navi_item( "#{h @conf.update}?edit=true;year=#{a[0]};month=#{a[1]};day=#{a[2]}", "#{h navi_next_diary(Time::local(*@next_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}»" ) end result end def navi_user_else navi_item( h(@conf.index), h(navi_latest) ) end def navi_user_format( day ) Time::local( *day.scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] ) end def navi_admin if @mode == 'day' then result = navi_item( "#{h @conf.update}?edit=true;year=#{@date.year};month=#{@date.month};day=#{@date.day}", h(navi_edit), "nofollow" ) else result = navi_item( h(@conf.update), h(navi_update), "nofollow") end result << navi_item( "#{h @conf.update}?conf=default", h(navi_preference) ) if /^(latest|month|day|comment|conf|nyear|category.*)$/ !~ @mode result end def mobile_navi result = [] if @navi_user_days and @navi_user_days[0] result << %Q[[*]#{mobile_navi_prev_diary}] end if @mode != 'latest' result << %Q[[0]#{mobile_navi_latest}] end if @navi_user_days and @navi_user_days[2] result << %Q[[#]#{mobile_navi_next_diary}] end if @mode == 'day' then result << %Q[[5]#{mobile_navi_edit}] else result << %Q[[5]#{mobile_navi_update}] end result << %Q[[8]#{mobile_navi_preference}] unless /^(latest|month|day|conf|nyear)$/ === @mode result.join('|') end # # make calendar # def calendar result = %Q[
\n] @years.keys.sort.each do |year| result << %Q[
#{year}|] @years[year.to_s].sort.each do |month| m = "#{year}#{month}" result << %Q[#{month}|] end result << "
\n" end result << "
" end # # insert file # def insert( file ) begin File::readlines( file ).join rescue %Q[

#$! (#{h $!.class})
cannot read #{h file}.

] end end # # define DOCTYPE # def doctype %Q|| end # # default HTML header # add_header_proc do calc_links <<-HEADER #{author_name_tag} #{author_mail_tag} #{index_page_tag} #{icon_tag} #{ogp_tag} #{description_tag} #{css_tag.chomp} #{jquery_tag.chomp} #{script_tag.chomp} #{title_tag.chomp} #{robot_control.chomp} HEADER end def calc_links if /day|edit/ =~ @mode then today = @date.strftime('%Y%m%d') days = [] yms = [] this_month = today[0,6] @years.keys.each do |y| yms += @years[y].collect {|m| y + m} end yms |= [this_month] yms.sort! yms.unshift(nil).push(nil) yms[yms.index(this_month) - 1, 3].each do |ym| next unless ym now = @cgi.params['date'] # backup cgi = @cgi.clone cgi.params['date'] = [ym] m = TDiaryMonthWithoutFilter.new(cgi, '', @conf) @cgi.params['date'] = now # restore m.diaries.delete_if {|date,diary| !diary.visible?} days += m.diaries.keys.sort end days |= [today] days.sort! days.unshift(nil).push(nil) @navi_user_days = days[days.index(today) - 1, 3] @prev_day = @navi_user_days[0] @next_day = @navi_user_days[2] elsif @mode == 'nyear' y = 2000 # specify leam year m, d = @cgi.params['date'][0].scan(/^(\d\d)(\d\d)$/)[0] @prev_day = (Time.local(y, m, d) - 24*60*60).strftime( '%Y%m%d' ) @next_day = (Time.local(y, m, d) + 24*60*60).strftime( '%Y%m%d' ) end end def charset @conf.encoding end def last_modified_header '' end def content_script_type '' end def author_name_tag if @conf.author_name and not(@conf.author_name.empty?) then %Q[] else '' end end def author_mail_tag if @conf.author_mail and not(@conf.author_mail.empty?) then %Q[] else '' end end def index_page_tag result = '' if @conf.index_page and @conf.index_page.size > 0 then result << %Q[\n\t] end if @prev_day then case @mode when 'day' result << %Q[\n\t] when 'nyear' result << %Q[\n\t] end end if @next_day then case @mode when 'day' result << %Q[\n\t] when 'nyear' result << %Q[\n\t] end end result << %Q[\n\t] result.chop.chop end def icon_tag if @conf.icon and not(@conf.icon.empty?) then if /\.ico$/ =~ @conf.icon then %Q[] else %Q[] end else '' end end def ogp_tag ogp = { 'og:title' => title_tag.gsub(/<[^>]*>/, ""), } if @conf.banner && !@conf.banner.empty? ogp['og:image'] = @conf.banner end uri = @conf.index.dup uri[0, 0] = base_url if %r|^https?://|i !~ @conf.index uri.gsub!( %r|/\./|, '/' ) if @mode == 'day' then ogp['og:type'] = 'article' ogp['article:author'] = @conf.author_name ogp['og:site_name'] = @conf.html_title ogp['og:url'] = uri + anchor( @date.strftime( '%Y%m%d' ) ) else ogp['og:type'] = 'website' ogp['og:description'] = @conf.description ogp['og:url'] = uri end ogp.map { |k, v| %Q|| }.join("\n") end def description_tag if @conf.description and not(@conf.description.empty?) then %Q[] else '' end end def jquery_tag %Q[] end enable_js( '00default.js', async: false ) add_js_setting( '$tDiary.style', "'#{@conf.style.downcase.sub( /\Ablog/, '' )}'" ) if /^form|edit|preview|showcomment/ =~ @mode enable_js( '02edit.js', async: true ) end def script_tag_query_string "?#{TDIARY_VERSION}#{Time::now.strftime('%Y%m%d')}" end def js_url @cgi.is_a?(RackCGI) ? 'assets' : 'js' end def script_tag require 'uri' query = script_tag_query_string html = @javascripts.keys.sort.map {|script| async = @javascripts[script][:async] ? "async" : "" if URI(script).scheme or script =~ %r|\A//| %Q|| else %Q|| end }.join( "\n\t" ) html << "\n" << <<-HEAD HEAD end def theme_url @cgi.is_a?(RackCGI) ? 'assets' : 'theme' end def css_tag location, name = (@conf.theme || '').split(%r[/], 2) if @mode =~ /conf$/ then css = "#{h theme_url}/conf.css" elsif name && name.length > 0 css = __send__("theme_url_#{location}", name) css = theme_url_local('default') unless css # the location is not defined else css = @conf.css end title = File::basename( css, '.css' ) <<-CSS CSS end def robot_control if /^form|edit|preview|showcomment$/ =~ @mode then '' else '' end end # # title of day # add_title_proc do |date, title| title_of_day( date, title ) end def title_of_day( date, title ) r = <<-HTML #{date.strftime @conf.date_format} #{title} HTML return r.gsub( /^\t+/, '' ).chomp end add_title_proc do |date, title| nyear_link( date, title ) end def nyear_link( date, title ) if @conf.show_nyear and @mode != 'nyear' then m = date.strftime( '%m' ) d = date.strftime( '%d' ) years = @years.find_all {|year, months| months.include? m} if years.length >= 2 then %Q|#{title} [#{nyear_diary_label}]| else title end else title end end # # make anchor string # def anchor( s ) if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then if $2 then "?date=#$1##$2" else "?date=#$1" end else "" end end # # subtitle # add_subtitle_proc do |date, index, subtitle| subtitle_link( date, index, subtitle ) end def make_category_link( subtitle ) r = '' if subtitle if respond_to?( :category_anchor ) then r << subtitle.sub( /^(\[([^\[]+?)\])+/ ) do $&.gsub( /\[(.*?)\]/ ) do $1.split( /,/ ).collect do |c| category_anchor( "#{CGI::unescapeHTML c}" ) end.join end end else r << subtitle end end r end def subtitle_link( date, index, subtitle ) r = '' if date then r << "#{@conf.section_anchor} ] end r << %Q[(#{h @author}) ] if @multi_user and @author and subtitle r << make_category_link( subtitle ) end # # make anchor tag in my diary # def my( a, str, title = nil ) date, _, frag = a.scan( /^(\d{4}|\d{6}|\d{8}|\d{8}-\d+)([^\d]*)?#?([pct]\d+)?$/ )[0] anc = frag ? "#{date}#{frag}" : date index = /^https?:/ =~ @conf.index ? '' : base_url index += @conf.index.sub(%r|^\./|, '') if title then %Q[#{str}] else %Q[#{str}] end end # # other resources # def submit_command if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then 'append' else 'replace' end end def preview_command if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then 'appendpreview' else 'replacepreview' end end # # make comment form # def comment_description begin if @conf.options['comment_description'].length > 0 then return @conf.options['comment_description'] end rescue end comment_description_default end def comment_form_text unless @diary then @diary = @diaries[@date.strftime( '%Y%m%d' )] return '' unless @diary end r = '' unless @conf.hide_comment_form then r = <<-FORM
FORM if @diary.count_comments( true ) >= @conf.comment_limit_per_day then r << <<-FORM FORM else r << <<-FORM
#{comment_name_label}:
#{comment_mail_label}:
#{comment_body_label}:
FORM end r << <<-FORM
FORM end r end add_footer_proc do if @mode != 'day' or bot? then '' elsif hide_comment_day_limit r = '' r << <<-JS JS else '' end end def comment_form return '' unless @mode == 'day' return '' if bot? return '' if hide_comment_day_limit comment_form_text end def comment_form_mobile_mail_field %Q|#{comment_mail_label_short}:
| end def comment_form_mobile return '' if @conf.hide_comment_form return '' if bot? return '' if hide_comment_day_limit if @diaries[@date.strftime('%Y%m%d')].count_comments( true ) >= @conf.comment_limit_per_day then return "

#{comment_limit_label}

" end return <<-FORM

#{comment_description_short}
#{comment_name_label_short}:
#{comment_form_mobile_mail_field} #{comment_body_label_short}:

FORM end def hide_comment_day_limit if @conf.options.include?('spamfilter.date_limit') && @conf.options['spamfilter.date_limit'] && /\A\d+\z/ =~ @conf.options['spamfilter.date_limit'].to_s date_limit = @conf.options['spamfilter.date_limit'].to_s.to_i now = Time.now today = Time.local(now.year, now.month, now.day) limit = today - 24 * 60 * 60 * date_limit if @date < limit return true end end return false end # # service methods for comment_mail # def comment_mail_send return unless @comment return unless @conf['comment_mail.enable'] return unless @conf['comment_mail.sendhidden'] or @comment.visible? case @conf['comment_mail.receivers'] when Array # for compatibility receivers = @conf['comment_mail.receivers'] when String receivers = @conf['comment_mail.receivers'].split( /[, ]+/ ) else receivers = [] end receivers = [@conf.author_mail] if receivers.compact.empty? return if receivers.empty? require 'socket' name = comment_mail_mime( @conf.to_mail( @comment.name ) )[0] body = @comment.body.sub( /[\r\n]+\Z/, '' ) mail = @comment.mail mail = @conf.author_mail unless mail =~ %r<[0-9a-zA-Z_.-]+@[\(\)%!0-9a-zA-Z_$@.&+-,'"*-]+> mail = receivers[0] if mail.empty? now = Time::now g = now.dup.gmtime l = Time::local( g.year, g.month, g.day, g.hour, g.min, g.sec ) tz = (g.to_i - l.to_i) / 36 date = now.strftime( "%a, %d %b %Y %X " ) + sprintf( "%+05d", tz ) serial = @diaries[@date.strftime( '%Y%m%d' )].count_comments( true ) message_id = %Q!! mail_header = (@conf['comment_mail.header'] || '').dup mail_header << ":#{@conf.date_format}" unless /%[a-zA-Z%]/ =~ mail_header mail_header = @date.strftime( mail_header ) mail_header = comment_mail_mime( @conf.to_mail( mail_header ) ).join( "\n " ) #if /[\x80-\xff]/ =~ mail_header rmail = '' begin rmail = File::open( "#{TDiary::PATH}/../views/mail.rtxt.#{@conf.lang}" ){|f| f.read } rescue rmail = File::open( "#{TDiary::PATH}/../views/mail.rtxt" ){|f| f.read } end text = @conf.to_mail( ERB::new( rmail ).result( binding ) ) comment_mail( text, receivers ) end def comment_mail( text ) # no action in default. # override by each plugins. end def comment_mail_basic_setting if @mode == 'saveconf' then @conf['comment_mail.enable'] = @cgi.params['comment_mail.enable'][0] == 'true' ? true : false @conf['comment_mail.receivers'] = @cgi.params['comment_mail.receivers'][0].strip.gsub( /[\n\r]+/, ',' ) @conf['comment_mail.header'] = @cgi.params['comment_mail.header'][0] @conf['comment_mail.sendhidden'] = @cgi.params['comment_mail.sendhidden'][0] == 'true' ? true : false end end # # convert to UTF-8 # def to_utf8( str, charset = nil ) @conf.to_native( str, charset ) end # # layout # def brr; '
'; end def brl; '
'; end # # preferences (saving methods) # if @mode =~ /conf|saveconf/ enable_js( '01conf.js', async: true ) end # basic (default) def saveconf_default if @mode == 'saveconf' then @conf.html_title = @conf.to_native( @cgi.params['html_title'][0] ) @conf.author_name = @conf.to_native( @cgi.params['author_name'][0] ) @conf.author_mail = @cgi.params['author_mail'][0] @conf.index_page = @cgi.params['index_page'][0] @conf.description = @conf.to_native( @cgi.params['description'][0] ) @conf.icon = @cgi.params['icon'][0] @conf.banner = @cgi.params['banner'][0] @conf['base_url'] = @cgi.params['base_url'][0] @conf.x_frame_options = @cgi.params['x_frame_options'][0] @conf.x_frame_options = nil if @conf.x_frame_options.empty? end end # header/footer (header) def saveconf_header if @mode == 'saveconf' then @conf.header = @conf.to_native( @cgi.params['header'][0] ).lines.map(&:chomp).join( "\n" ).sub( /\n+\z/, '' ) @conf.footer = @conf.to_native( @cgi.params['footer'][0] ).lines.map(&:chomp).join( "\n" ).sub( /\n+\z/, '' ) end end # diaplay def saveconf_display if @mode == 'saveconf' then @conf.section_anchor = @conf.to_native( @cgi.params['section_anchor'][0] ) @conf.comment_anchor = @conf.to_native( @cgi.params['comment_anchor'][0] ) @conf.date_format = @conf.to_native( @cgi.params['date_format'][0] ) @conf.latest_limit = @cgi.params['latest_limit'][0].to_i @conf.latest_limit = 10 if @conf.latest_limit < 1 @conf.show_nyear = @cgi.params['show_nyear'][0] == 'true' ? true : false end end # timezone def saveconf_timezone if @mode == 'saveconf' then @conf.hour_offset = @cgi.params['hour_offset'][0].to_f end end # themes def conf_theme_list r = '' t = -1 @conf_theme_list.each_with_index do |theme, index| if theme[0] == @conf.theme then select = " selected" t = index end r << %Q|| end img = t == -1 ? 'nowprinting' : @conf.theme.sub(/^.*\//, '') r << <<-HTML

#{@theme_thumbnail_label}

#{@theme_location_comment} HTML end def theme_list_local(list) Dir::glob( theme_paths_local ).sort.map {|dir| theme = dir.sub( %r[.*/theme/], '') next unless FileTest::file?( "#{dir}/#{theme}.css" ) name = theme.split( /_/ ).collect{|s| s.capitalize}.join( ' ' ) list << ["local/#{theme}",name] } list end def theme_url_local(theme) "#{h theme_url}/#{h theme}/#{h theme}.css" end def theme_paths_local [::TDiary::PATH, TDiary.server_root].map {|d| "#{d}/theme/*" } end def saveconf_theme if @mode == 'saveconf' then @conf.theme = @cgi.params['theme'][0] @conf.css = @cgi.params['css'][0] end @conf_theme_list = methods.inject([]) {|conf_theme_list, method| if /^theme_list_/ =~ method.to_s __send__(method, conf_theme_list) else conf_theme_list end }.sort.compact.uniq end # comments def saveconf_comment if @mode == 'saveconf' then @conf.show_comment = @cgi.params['show_comment'][0] == 'true' ? true : false @conf.comment_limit = @cgi.params['comment_limit'][0].to_i @conf.comment_limit = 3 if @conf.comment_limit < 1 @conf.comment_limit_per_day = @cgi.params['comment_limit_per_day'][0].to_i @conf.comment_limit_per_day = 0 if @conf.comment_limit_per_day < 0 end end def saveconf_csrf_protection if @mode == 'saveconf' then err = nil check_method = 0 case @cgi.params['check_enabled'] when ['true'] else err = :param end case @cgi.params['check_referer'] when ['true'] check_method |= 1 when ['false'] check_method |= 0 else err = :param end case @cgi.params['check_key'] when ['true'] check_method |= 2 when ['false'] check_method |= 0 else err = :param end err = :param if check_method == 0 check_key = '' key_seed = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 1.upto(30) do check_key << key_seed[rand( key_seed.length )] end if check_method & 2 != 0 && (!check_key || check_key == '') then err ||= :key end unless err old_key = @conf['csrf_protection_key'] old_method = @conf['csrf_protection_method'] @conf['csrf_protection_method'] = check_method @conf['csrf_protection_key'] = check_key if (check_method & 2 == 2 && (old_method & 2 == 0 || old_key != check_key)) @conf.save raise ForceRedirect, "#{h @conf.update}?conf=csrf_protection#{@cgi.referer ? '&referer_exists=true' : ''}" end end err else nil end end def saveconf_logger if @mode == 'saveconf' then @conf['log_level'] = @cgi.params['log_level'][0] end end def conf_logger_list log_level_list = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"] r = '' @conf['log_level'] ||= "INFO" log_level_list.each do |level| if level == @conf['log_level'] then select = " selected" end r << %Q|| end r << %Q|

| end def saveconf_recommendfilter if @mode == 'saveconf' && @cgi.params['recommend.filter'][0] == 'true' then @conf['sf.selected'] = "" @conf['comment_description'] = "ツッコミ・コメントがあればどうぞ! URIは1つまで入力可能です。" if @sp_path.inject(false){|r, dir| r || FileTest.exist?("#{dir}/hide-mail-field.rb") } if @conf['sp.selected'] @conf['sp.selected'].concat("hide-mail-field.rb\n") else @conf['sp.selected'] = "hide-mail-field.rb\n" end @conf['spamfilter.bad_mail_patts'] = "@" @conf['comment_description'].concat("spam対策でE-mail欄は隠してあります。もしE-mail欄が見えていても、何も入力しないで下さい。") end @conf['spamfilter.bad_comment_patts'] = "href=\r\nurl=\r\nURL=\r\n" @conf['spamfilter.bad_ip_addrs'] = "" @conf['spamfilter.bad_uri_patts'] = "" @conf['spamfilter.bad_uri_patts_for_mails'] = false @conf['spamfilter.date_limit'] = "7" @conf['spamfilter.debug_file'] = "" @conf['spamfilter.debug_mode'] = false @conf['spamfilter.filter_mode'] = false @conf['spamfilter.hide_commentform'] = true @conf['spamfilter.linkcheck'] = 1 @conf['spamfilter.max_rate'] = "0" @conf['spamfilter.max_uris'] = "1" @conf['spamfilter.resolv_check'] = true @conf['spamfilter.resolv_check_mode'] = false @conf['spamlookup.domain.list'] = "bsb.spamlookup.net\r\nmulti.surbl.org\r\nrbl.bulkfeeds.jp" @conf['spamlookup.ip.list'] = "dnsbl.spam-champuru.livedoor.com" @conf['spamlookup.safe_domain.list'] = "www.google.com\r\nwww.google.co.jp\r\nezsch.ezweb.ne.jp\r\nwww.yahoo.co.jp\r\nsearch.mobile.yahoo.co.jp\r\nwww.bing.com" end end # # old ruby alert # def old_ruby_alert if RUBY_VERSION < '2.0.0' and !@conf['old_ruby_alert.hide'] %Q|
× #{old_ruby_alert_message}
| else '' end end def old_ruby_alert_message "お使いのRuby #{RUBY_VERSION}は次のリリースからサポート対象外になります。" end add_conf_proc( 'old_ruby_alert', nil) do if @mode == 'saveconf' @conf['old_ruby_alert.hide'] = true end %Q|

OLD RUBY ALERT

| # dummy end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/05referer.rb000066400000000000000000000161311362645730700214430ustar00rootroot00000000000000# # 05referer.rb: load/save and show today's referer plugin # # Copyright (C) 2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # saving referer # add_header_proc do referer_save_trigger '' end def referer_save_trigger return unless @conf.io_class.to_s == 'TDiary::IO::Default' return unless @mode =~ /^(latest|day|edit|append|replace)$/ if @date then diary = @diaries[@date.strftime( '%Y%m%d' )] diary.clear_referers if diary end referer_update( diary ) end # # fake diary class for volatile referer # class RefererDiary include ::TDiary::RefererManager def initialize( keep ) init_referers @keep = keep @current_date = nil @refs = {} end # return Time object def date if @current_date then Time::local( *(@current_date.scan( /^(\d{4})(\d\d)(\d\d)$/ )[0]) ) else @date end end # date as String 'YYYYMMDD' def current_date=( d ) @current_date = d @refs[d] ||= {} if d end alias :add_referer_orig :add_referer def add_referer( ref, count = 1 ) return nil unless ref current = @current_date || @refs.keys.sort[-1] || '00000101' ref_info = add_referer_orig( ref, count ) uref = CGI::unescape( ref ) @refs[current] ||= {} if pair = @refs[current][uref] then @refs[current][uref] = [pair[0] + count, ref_info[1]] else @refs[current][uref] = [count, ref_info[1]] end end def clear_oldest_referer( newest ) return if (@refs.keys.sort[-1] || '') > newest @refs[newest] = {} unless @refs[newest] return if @refs.keys.size <= @keep @refs.delete( @refs.keys.sort[0] ) end alias :each_referer_orig :each_referer def each_referer( limit = 10 ) if @current_date then @refs[@current_date].values.sort.reverse.each_with_index do |ary,idx| break if idx >= limit yield( ary[0], ary[1] ) end else each_referer_orig( limit ) do |count, ref| yield( count, ref ) end end end def each_date @refs.keys.sort.each do |d| @current_date = d yield( self ) end end end def latest_day?( diary ) return false unless diary y = @years.keys.sort[-1] m = @years[y].sort[-1] diary.date.year == y.to_i and diary.date.month == m.to_i and diary.date.day == @diaries.keys.sort[-1][6,2].to_i end def referer_update( diary ) # ignore an invalid URL including a non-ASCII character return if @cgi.referer && !@cgi.referer.match(/^[!-~]+$/) @referer_volatile = RefererDiary::new( @conf.latest_limit ) case @mode when 'latest' if @cgi.referer and !@conf.referer_day_only then referer_load_volatile( @referer_volatile ) referer_save_volatile( @referer_volatile, @cgi.referer ) end when 'day' if diary referer_load_current( diary ) referer_save_current( diary, @cgi.referer ) if latest_day?( diary ) then referer_load_volatile( @referer_volatile ) elsif @cgi.referer referer_load_volatile( @referer_volatile ) referer_save_volatile( @referer_volatile, @cgi.referer ) end end when "edit" referer_load_current( diary ) referer_load_volatile( @referer_volatile ) if latest_day?( diary ) when /^(append|replace)$/ referer_load_volatile( @referer_volatile ) @referer_volatile.clear_oldest_referer( @date.strftime( '%Y%m%d' ) ) referer_save_volatile( @referer_volatile, nil ) end end def referer_file_name( diary ) diary.date.strftime( "#{@conf.data_path}%Y/%Y%m%d.tdr" ) end def referer_volatile_file_name "#{@conf.data_path}volatile.tdr" end def referer_load( file, diary ) begin File::open( file, 'rb' ) do |fh| fh.flock( File::LOCK_SH ) fh.gets # read magic fh.read.split( /\r?\n\.\r?\n/ ).each do |l| headers, body = @conf.io_class.parse_tdiary( l ) yield( headers, @conf.to_native( body ) ) end end rescue Errno::ENOENT end end def referer_add_to_diary( diary, body ) return unless body body.lines.each do |r| count, ref = r.chomp.split( / /, 2 ) next unless ref diary.add_referer( ref.chomp, count.to_i ) end end def referer_load_current( diary ) return unless diary referer_load( referer_file_name( diary ), diary ) do |headers, body| referer_add_to_diary( diary, body ) end end def referer_load_volatile( diary ) referer_load( referer_volatile_file_name, diary ) do |headers, body| diary.current_date = headers['Date'] referer_add_to_diary( diary, body ) end diary.current_date = nil end def referer_save( file, diary ) File::open( file, File::WRONLY | File::CREAT ) do |fh| fh.flock( File::LOCK_EX ) fh.rewind fh.truncate( 0 ) fh.puts( ::TDiary::TDIARY_MAGIC ) yield( fh ) end end def referer_write_from_diary( fh, diary ) fh.puts( "Date: #{diary.date.strftime( '%Y%m%d' )}\n\n" ) diary.each_referer( diary.count_referers ) do |count,ref| fh.puts( "#{count} #{ref}" ) end fh.puts( '.' ) end def referer_save_current( diary, referer ) return unless referer # checking only volatile list ref = CGI::unescape( referer.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) ) @conf.only_volatile.each do |volatile| return if /#{volatile}/i =~ ref end diary.add_referer( referer ) referer_save( referer_file_name( diary ), diary ) do |fh| referer_write_from_diary( fh, diary ) end end def referer_save_volatile( diary, referer ) # to prevend the increase in file size return if diary.count_referers > 10000 diary.add_referer( referer ) if referer referer_save( referer_volatile_file_name, diary ) do |fh| diary.each_date do |date| referer_write_from_diary( fh, diary ) end end end # # referer of today # def referer_of_today_short( diary, limit ) '' end def referer_of_today_long( diary, limit ) return '' if bot? result = '' if diary and diary.count_referers != 0 then result << %Q[
#{referer_today}
\n] result << %Q[' end if @referer_volatile and latest_day?( diary ) and @referer_volatile.count_referers != 0 then result << %Q[
#{volatile_referer}
\n] result << %Q[' end result end # # referer preference # def saveconf_referer if @mode == 'saveconf' then @conf.show_referer = @cgi.params['show_referer'][0] == 'true' ? true : false no_referer2 = [] @conf.to_native( @cgi.params['no_referer'][0] ).lines.each do |ref| ref.strip! no_referer2 << ref if ref.length > 0 end @conf.no_referer2 = no_referer2 only_volatile2 = [] @conf.to_native( @cgi.params['only_volatile'][0] ).lines.each do |ref| ref.strip! only_volatile2 << ref if ref.length > 0 end @conf.only_volatile2 = only_volatile2 referer_table2 = [] @conf.to_native( @cgi.params['referer_table'][0] ).lines.each do |pair| u, n = pair.sub( /[\r\n]+/, '' ).split( /[ \t]+/, 2 ) referer_table2 << [u,n] if u and n end @conf.referer_table2 = referer_table2 end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/10spamfilter.rb000066400000000000000000000127751362645730700221650ustar00rootroot00000000000000# Copyright (C) 2005 akira yamada # You can redistribute it and/or modify it under GPL2 or any later version. add_conf_proc( 'spamfilter', @spamfilter_label_conf, 'security' ) do if @mode == 'saveconf' if @cgi.params['spamfilter.max_uris'] && @cgi.params['spamfilter.max_uris'][0] && /\A\d+\z/ =~ @cgi.params['spamfilter.max_uris'][0] @conf['spamfilter.max_uris'] = @cgi.params['spamfilter.max_uris'][0] else @conf['spamfilter.max_uris'] = 0 end if @cgi.params['spamfilter.max_rate'] && @cgi.params['spamfilter.max_rate'][0] && /\A\d*\z/ =~ @cgi.params['spamfilter.max_rate'][0] @conf['spamfilter.max_rate'] = @cgi.params['spamfilter.max_rate'][0] else @conf['spamfilter.max_rate'] = 0 end if @cgi.params['spamfilter.bad_uri_patts'] && @cgi.params['spamfilter.bad_uri_patts'][0] @conf['spamfilter.bad_uri_patts'] = @cgi.params['spamfilter.bad_uri_patts'][0] else @conf['spamfilter.bad_uri_patts'] = '' end if @cgi.params['spamfilter.bad_mail_patts'] && @cgi.params['spamfilter.bad_mail_patts'][0] @conf['spamfilter.bad_mail_patts'] = @cgi.params['spamfilter.bad_mail_patts'][0] else @conf['spamfilter.bad_mail_patts'] = '' end if @cgi.params['spamfilter.bad_comment_patts'] && @cgi.params['spamfilter.bad_comment_patts'][0] @conf['spamfilter.bad_comment_patts'] = @cgi.params['spamfilter.bad_comment_patts'][0] else @conf['spamfilter.bad_comment_patts'] = '' end if @cgi.params['spamfilter.bad_ip_addrs'] && @cgi.params['spamfilter.bad_ip_addrs'][0] @conf['spamfilter.bad_ip_addrs'] = @cgi.params['spamfilter.bad_ip_addrs'][0] else @conf['spamfilter.bad_ip_addrs'] = '' end if @cgi.params['spamfilter.bad_uri_patts_for_mails'] && @cgi.params['spamfilter.bad_uri_patts_for_mails'][0] && @cgi.params['spamfilter.bad_uri_patts_for_mails'][0] == "true" @conf['spamfilter.bad_uri_patts_for_mails'] = true else @conf['spamfilter.bad_uri_patts_for_mails'] = false end if @cgi.params['spamfilter.filter_mode'] && @cgi.params['spamfilter.filter_mode'][0] && @cgi.params['spamfilter.filter_mode'][0] == "false" @conf['spamfilter.filter_mode'] = false else @conf['spamfilter.filter_mode'] = true end if @cgi.params['filter.debug_mode'] && @cgi.params['filter.debug_mode'][0] @conf['filter.debug_mode'] = @cgi.params['filter.debug_mode'][0].to_i else @conf['filter.debug_mode'] = 0 end if @cgi.params['spamfilter.date_limit'] && @cgi.params['spamfilter.date_limit'][0] && /\A\d+\z/ =~ @cgi.params['spamfilter.date_limit'][0] @conf['spamfilter.date_limit'] = @cgi.params['spamfilter.date_limit'][0] else @conf['spamfilter.date_limit'] = nil end if @cgi.params['spamlookup.ip.list'] && @cgi.params['spamlookup.ip.list'][0] @conf['spamlookup.ip.list'] = @cgi.params['spamlookup.ip.list'][0] else @conf['spamlookup.ip.list'] = nil end if @cgi.params['spamlookup.domain.list'] && @cgi.params['spamlookup.domain.list'][0] @conf['spamlookup.domain.list'] = @cgi.params['spamlookup.domain.list'][0] else @conf['spamlookup.domain.list'] = nil end if @cgi.params['spamlookup.safe_domain.list'] && @cgi.params['spamlookup.safe_domain.list'][0] @conf['spamlookup.safe_domain.list'] = @cgi.params['spamlookup.safe_domain.list'][0] else @conf['spamlookup.safe_domain.list'] = nil end @conf['comment_description'] = @cgi.params['comment_description'][0] end # initialize IP based DNSBL list @conf['spamlookup.ip.list'] ||= "bsb.spamlookup.net" auto_migration_spam_champuru # initialize DNSBL list @conf['spamlookup.domain.list'] ||= "bsb.spamlookup.net\nmulti.surbl.org\nrbl.bulkfeeds.jp" # initialize safe domain list. @conf['spamlookup.safe_domain.list'] ||= "search.yahoo.co.jp\nwww.google.com\nwww.google.co.jp\nsearch.msn.co.jp" # initialize spamfilter.linkcheck mode. @conf['spamfilter.linkcheck'] = 1 unless @conf['spamfilter.linkcheck'] spamfilter_conf_html end add_conf_proc( 'dnsblfilter', @dnsblfilter_label_conf, 'security' ) do if @mode == 'saveconf' if @cgi.params['spamlookup.ip.list'] && @cgi.params['spamlookup.ip.list'][0] @conf['spamlookup.ip.list'] = @cgi.params['spamlookup.ip.list'][0] else @conf['spamlookup.ip.list'] = nil end if @cgi.params['spamlookup.domain.list'] && @cgi.params['spamlookup.domain.list'][0] @conf['spamlookup.domain.list'] = @cgi.params['spamlookup.domain.list'][0] else @conf['spamlookup.domain.list'] = nil end if @cgi.params['spamlookup.safe_domain.list'] && @cgi.params['spamlookup.safe_domain.list'][0] @conf['spamlookup.safe_domain.list'] = @cgi.params['spamlookup.safe_domain.list'][0] else @conf['spamlookup.safe_domain.list'] = nil end end # initialize IP based DNSBL list @conf['spamlookup.ip.list'] ||= "bsb.spamlookup.net" auto_migration_spam_champuru # initialize DNSBL list @conf['spamlookup.domain.list'] ||= "bsb.spamlookup.net\nmulti.surbl.org\nrbl.bulkfeeds.jp" # initialize safe domain list. @conf['spamlookup.safe_domain.list'] ||= "www.google.com\nwww.google.co.jp\nsearch.yahoo.co.jp\nwww.bing.com" dnsblfilter_conf_html end def auto_migration_spam_champuru # auto migration of spam-champuru shutdown. if @conf['spamlookup.ip.list'] && @conf['spamlookup.ip.list'].scan(/dnsbl\.spam-champuru\.livedoor\.com/).size > 0 @conf['spamlookup.ip.list'].gsub!(/dnsbl\.spam-champuru\.livedoor\.com/, "bsb.spamlookup.net") end end auto_migration_spam_champuru # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/plugin/50sp.rb000066400000000000000000000073651362645730700204440ustar00rootroot00000000000000# 50sp.rb - select-plugins plugin SP_PREFIX = 'sp' @sp_path = [( @conf["#{SP_PREFIX}.path"] || "#{TDiary.root}/misc/plugin" )].flatten @sp_path = @sp_path.collect do |path| /\/$/ =~ path ? path.chop : path end @sp_path << "#{TDiary.root}/misc/plugin" if @sp_path.include?('misc/plugin') @sp_path.concat TDiary::Extensions::constants.map {|extension| TDiary::Extensions::const_get( extension ).sp_path }.flatten.compact.uniq # get plugin option def sp_option( key ) @conf["#{SP_PREFIX}.#{key}"] end # hash of paths from array of dirs def sp_hash_from_dirs( dirs ) r = Hash.new dirs.each do |dir| Dir::glob( "#{dir}/*.rb" ).each do |path| filename = File.basename( path ) unless r[ filename ] then r[ filename ] = path end end end r end # url of the document def sp_doc_url( file ) "https://github.com/tdiary/tdiary-docs-#{@conf.lang}/wiki/#{CGI::escape( file )}" end #
  • list of plugins def sp_li_plugins( paths, is_checked ) r = '' paths.collect { |path| File.basename( path ) }.sort.each do |file| r += <<-_HTML
  • #{h file} _HTML end r end # lists of plugins def sp_list_plugins( sp_opt ) r = '' if ( sp_opt && !sp_opt.empty? ) then # categorize the available plugins used = Array.new notused = Array.new unknown = Array.new # File.basenmame needed to read option from 01sp.rb <= 1.10 selected_array = sp_option( 'selected' ) ? sp_option( 'selected').split( /\n/ ).collect{ |p| File.basename( p ) } : [] notselected_array = sp_option( 'notselected' ) ? sp_option( 'notselected').split( /\n/ ).collect{ |p| File.basename( p ) } : [] sp_opt.keys.each do |path| if selected_array.include?( path ) then used << path elsif notselected_array.include?( path ) then notused << path else unknown << path end end # list up r += @sp_label_please_select unless unknown.empty? then r += @sp_label_new r += "
      \n" r += sp_li_plugins( unknown, sp_option( 'usenew' ) ) r += "
    \n" end # selected plugins unless used.empty? then r += @sp_label_used r += "
      \n" r += sp_li_plugins( used, true ) r += "
    \n" end # not selected plugins unless notused.empty? then r += @sp_label_notused r += "
      \n" r += sp_li_plugins( notused, false ) r += "
    \n" end else r += @sp_label_noplugin end r end # things needed to configure this plugin if SP_PREFIX == (@cgi.params['conf'] && @cgi.params['conf'][0]) then # list of plugins @sp_opt = sp_hash_from_dirs( @sp_path ) # update options # we have to do this when we are eval'ed to update the config menu if /saveconf/ =~ @mode then @conf["#{SP_PREFIX}.selected"] = '' @conf["#{SP_PREFIX}.notselected"] = '' @sp_opt.each_key do |file| if 't' == @cgi.params["#{SP_PREFIX}.#{file}"][0] then @conf["#{SP_PREFIX}.selected"] << "#{file}\n" else @conf["#{SP_PREFIX}.notselected"] << "#{file}\n" end end end end # configuration menu # options are updated when we are eval'ed add_conf_proc( SP_PREFIX, @sp_label, 'basic' ) do @sp_label_description + sp_list_plugins( @sp_opt ) end # Finally, we can eval the selected plugins as tdiary.rb does if sp_option( 'selected' ) then sp_option( 'selected' ).split( /\n/ ).collect{ |p| File.basename( p ) }.sort.each do |filename| @sp_path.each do |dir| path = "#{dir}/#{filename}" if File.readable?( path ) then begin load_plugin( path ) @plugin_files << path rescue ArgumentError next rescue Exception raise PluginError::new( "Plugin error in '#{path}'.\n#{$!}" ) end break end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/60sf.rb000066400000000000000000000075441362645730700204320ustar00rootroot00000000000000# 60sf.rb - select-filters plugin # This file is based on 50sp.rb Revision: 1.5 # Modified by KURODA Hiraku. SF_PREFIX = 'sf' @sf_path = [( @conf["#{SF_PREFIX}.path"] || "#{TDiary.root}/misc/filter" )].flatten @sf_path = @sf_path.collect do |path| /\/$/ =~ path ? path.chop : path end # get plugin option def sf_option( key ) @conf["#{SF_PREFIX}.#{key}"] end # hash of paths from array of dirs def sf_hash_from_dirs( dirs ) r = Hash.new dirs.each do |dir| Dir::glob( "#{dir}/*.rb" ).each do |path| filename = File.basename( path ) unless r[ filename ] then r[ filename ] = path end end end r end # url of the document def sf_doc_url( file ) "https://github.com/tdiary/tdiary-docs-#{@conf.lang}/wiki/#{CGI::escape( file )}" end #
  • list of plugins def sf_li_plugins( paths, is_checked ) r = '' paths.collect { |path| File.basename( path ) }.sort.each do |file| r += <<-_HTML
  • #{h file} _HTML end r end # lists of plugins def sf_list_plugins( sf_opt ) r = '' if ( sf_opt && !sf_opt.empty? ) then # categorize the available plugins used = Array.new notused = Array.new unknown = Array.new # File.basenmame needed to read option from 01sp.rb <= 1.10 selected_array = sf_option( 'selected' ) ? sf_option( 'selected').split( /\n/ ).collect{ |p| File.basename( p ) } : [] notselected_array = sf_option( 'notselected' ) ? sf_option( 'notselected').split( /\n/ ).collect{ |p| File.basename( p ) } : [] sf_opt.keys.each do |path| if selected_array.include?( path ) then used << path elsif notselected_array.include?( path ) then notused << path else unknown << path end end # list up r += @sf_label_please_select unless unknown.empty? then r += @sf_label_new r += "
      \n" r += sf_li_plugins( unknown, sf_option( 'usenew' ) ) r += "
    \n" end # selected plugins unless used.empty? then r += @sf_label_used r += "
      \n" r += sf_li_plugins( used, true ) r += "
    \n" end # not selected plugins unless notused.empty? then r += @sf_label_notused r += "
      \n" r += sf_li_plugins( notused, false ) r += "
    \n" end else r += @sf_label_noplugin end r end # things needed to configure this plugin if SF_PREFIX == (@cgi.params['conf'] && @cgi.params['conf'][0]) then # list of plugins @sf_opt = sf_hash_from_dirs( @sf_path ) # update options # we have to do this when we are eval'ed to update the config menu if /saveconf/ =~ @mode then @conf["#{SF_PREFIX}.selected"] = '' @conf["#{SF_PREFIX}.notselected"] = '' @sf_opt.each_key do |file| if 't' == @cgi.params["#{SF_PREFIX}.#{file}"][0] then @conf["#{SF_PREFIX}.selected"] << "#{file}\n" else @conf["#{SF_PREFIX}.notselected"] << "#{file}\n" end end end end # configuration menu # options are updated when we are eval'ed add_conf_proc( SF_PREFIX, @sf_label, 'security' ) do @sf_label_description + sf_list_plugins( @sf_opt ) end # Finally, we can eval the selected plugins as tdiary.rb does if sf_option( 'selected' ) && !@sf_filters then @sf_filters = [] sf_option( 'selected' ).split( /\n/ ).collect{ |p| File.basename( p ) }.sort.each do |filename| @sf_path.each do |dir| path = "#{dir}/#{filename}" if File.readable?( path ) then begin require File.expand_path( path ) @sf_filters << TDiary::Filter::const_get("#{File::basename(filename, ".rb").capitalize}Filter")::new(@cgi, @conf) plugin_path = "#{dir}/plugin/#{filename}" load_plugin(plugin_path) if File.readable?(plugin_path) rescue Exception raise PluginError::new( "Plugin error in '#{path}'.\n#{$!}" ) end break end end end end def sf_filters @sf_filters||[] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/90migrate.rb000066400000000000000000000052741362645730700214530ustar00rootroot00000000000000# # 90migrate.rb: tDiary plugin for migration 2.2 to 2.3. # if !@conf.tdiary_version && @conf.io_class.to_s == 'TDiary::IO::Default' def convert_pstore( file ) require "pstore" db = PStore.new( file ) begin roots = db.transaction{ db.roots } rescue ArgumentError if /\Aundefined class\/module (.+?)(::)?\z/ =~ $!.message klass = $1 if /EmptdiaryString\z/ =~ klass eval( "class #{klass} < String; end" ) else eval( "class #{klass}; end" ) end retry end end db.transaction do roots.each do |root| convert_element( db[root] ) end end end def convert_element( data ) case data when Hash, Array data.each_with_index do |e, i| if String === e data[i] = @conf.migrate_to_utf8( e ) else convert_element( e ) end end else data.instance_variables.each do |e| var = data.instance_variable_get( e ) if String === var data.instance_variable_set( e, @conf.migrate_to_utf8( var ) ) else convert_element( var ) end end end end require "fileutils" # convert tdiary.conf in @conf.data_path begin conf_path = "#{@conf.data_path}tdiary.conf" conf = File::open( conf_path ){|f| @conf.migrate_to_utf8( f.read ) } conf.gsub!(/(\\[0-9]{3})+/) do |str| @conf.migrate_to_utf8( eval( %Q["#{$&}"] ) ).dump[1...-1] end rescue end File::open( conf_path, 'w' ) do |o| o.puts %Q!tdiary_version = "#{TDIARY_VERSION}"! o.print( conf ) if conf end @conf.tdiary_version = TDIARY_VERSION # convert pstore cache files of plugins dir = @cache_path || "#{@conf.data_path}cache" %w(makerss.cache recent_comments recent_trackbacks tlink/tlink.dat whatsnew-list blog_category).each do |e| convert_pstore( "#{dir}/#{e}" ) if File.exist?( "#{dir}/#{e}" ) end Dir["#{dir}/disp_referrer2.d/*"].each do |file| convert_pstore( file ) end Dir["#{@conf.data_path}category/*"].each do |file| convert_pstore( file ) end # rename category cache files Dir["#{@conf.data_path}category/*"].each do |file| dirname, basename = File.split( file ) new_basename = u( @conf.migrate_to_utf8( CGI::unescape( basename ) ) ) FileUtils.mv( file, File.join( dirname, new_basename ) ) unless basename == new_basename end # other files a_dat = @conf['a.path'] || "#{dir}/a.dat" if File.exist?( a_dat ) then t = File::open( a_dat ){|f| f.read} File::open( a_dat, 'wb' ){|f| f.write( @conf.migrate_to_utf8( t ) )} end # remove ruby/erb cache files Dir["#{dir}/*.rb"].each{|f| FileUtils.rm_f( f )} Dir["#{dir}/*.parser"].each{|f| FileUtils.rm_f( f )} # redirect to top page raise ::TDiary::ForceRedirect, base_url end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/en/000077500000000000000000000000001362645730700177175ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/plugin/en/00default.rb000066400000000000000000000406161362645730700220370ustar00rootroot00000000000000# # en/00default.rb: English resources of 00default.rb. # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # header # def title_tag r = "#{h @conf.html_title}" case @mode when 'day', 'comment' r << "(#{@date.strftime( '%Y-%m-%d' )})" if @date when 'month' r << "(#{@date.strftime( '%Y-%m' )})" if @date when 'form' r << '(Append)' when 'edit' r << '(Edit)' when 'preview' r << '(Preview)' when 'showcomment' r << '(TSUKKOMI Status Change Completed)' when 'conf' r << '(Preferences)' when 'saveconf' r << '(Preferences Changed)' when 'nyear' years = @diaries.keys.map {|ymd| ymd.sub(/^\d{4}/, "")} r << "(#{years[0].sub( /^(\d\d)/, '\1-')}[#{nyear_diary_label}])" if @date end r << '' end # # link to HOWTO write diary # def style_howto %Q|/How to write| end # # labels # def no_diary; "No diary on #{@date.strftime( @conf.date_format )}"; end def comment_today; "Today's TSUKKOMI"; end def comment_total( total ); "(Total: #{total})"; end def comment_new; 'Add a TSUKKOMI'; end def comment_description_default; 'Add a TSUKKOMI or Comment please. E-mail address will be shown to only me.'; end def comment_limit_label; 'You cannot make more TSUKKOMI because it has over limit.'; end def comment_description_short; 'TSUKKOMI!!'; end def comment_name_label; 'Name'; end def comment_name_label_short; 'Name'; end def comment_mail_label; 'E-mail'; end def comment_mail_label_short; 'Mail'; end def comment_body_label; 'Comment'; end def comment_body_label_short; 'Comment'; end def comment_submit_label; 'Submit'; end def comment_submit_label_short; 'Submit'; end def comment_date( time ); time.strftime( "(#{@conf.date_format} %H:%M)" ); end def trackback_today; "Today's TrackBacks"; end def trackback_total( total ); "(Total: #{total})"; end def navi_index; 'Top'; end def navi_latest; 'Latest'; end def navi_oldest; 'Oldest'; end def navi_update; "Append"; end def navi_edit; "Edit"; end def navi_preference; "Preference"; end def navi_prev_diary(date); "Prev(#{date.strftime(@conf.date_format)})"; end def navi_next_diary(date); "Next(#{date.strftime(@conf.date_format)})"; end def navi_prev_month; "Prev month"; end def navi_next_month; "Next month"; end def navi_prev_nyear(date); "Prev(#{date.strftime('%m-%d')})"; end def navi_next_nyear(date); "Next(#{date.strftime('%m-%d')})"; end def navi_prev_ndays; "#{@conf.latest_limit} days before"; end def navi_next_ndays; "#{@conf.latest_limit} days after"; end def submit_label if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then 'Append' else 'Replace' end end def preview_label; 'Preview'; end def nyear_diary_label; "my old days"; end def nyear_diary_title; "same days in past"; end # # labels (for mobile) # def mobile_navi_latest; 'Latest'; end def mobile_navi_update; 'Update'; end def mobile_navi_edit; "Edit"; end def mobile_navi_preference; 'Prefs'; end def mobile_navi_prev_diary; 'Prev'; end def mobile_navi_next_diary; 'Next'; end def mobile_label_hidden_diary; 'This day is HIDDEN.'; end # # category # def category_anchor(c); "[#{c}]"; end # # preferences # @conf_saving = 'Saving...' # genre labels @conf_genre_label['basic'] = 'Basic' @conf_genre_label['theme'] = 'Themes' @conf_genre_label['tsukkomi'] = 'TSUKKOMI' @conf_genre_label['referer'] = 'Referrer' @conf_genre_label['security'] = 'Security' @conf_genre_label['etc'] = 'etc' # basic (default) add_conf_proc( 'default', 'Site information', 'basic' ) do saveconf_default @conf.description ||= '' @conf.icon ||= '' @conf.banner ||= '' <<-HTML

    Title

    The title of your diary. This value is used in HTML <title> element. Do not use HTML tags.

    Author

    Specify your name. This value is into HTML header.

    E-mail address

    Specify your E-mail address. This value is into HTML header.

    URL of index page

    The URL of index of your website if you have.

    URL of Your Diary

    Specify your diary's URL. This URL is used by some plugins for indicate your diary

    #{"

    NOTICE!! The URL specified below is different from current URL of accessed now.

    " unless base_url == @cgi.base_url}

    Description

    A brief description of your diary. Can be left blank.

    Site icon (favicon)

    URL for the small icon (aka 'favicon') of your site. Can be left blank.

    Site banner

    URL for the banner image of your site. makerss plugin will use this value to make RSS. Can be left blank.

    If you want to use the default banner of tDiary, use your diary's URL + "/theme/ogimage.png".

    Permit display in Frames

    Permit display your diary included by frames.

    HTML end # header/footer (header) add_conf_proc( 'header', 'Header/Footer', 'basic' ) do saveconf_header <<-HTML

    Header

    This text is inserted into top of each pages. You can use HTML tags. Do not remove "<%=navi%>", because it mean Navigation bar inclued "Update" button. And "<%=calendar%>" mean calendar. So you can specify other plugins also.

    Footer

    This text is inserted into bottom of each pages. You can specify as same as Header.

    HTML end # diaplay add_conf_proc( 'display', 'Display', 'basic' ) do saveconf_display <<-HTML

    Section anchor

    "Anchor" guide to link from other website. Section anchors are insertd into begining of each section. So if you specify "<span class="sanchor">_</span>", image anchor will be shown Image anchor by themes.

    TSUKKOMI anchor

    TSUKKOMI anchor is inserted into begining of each TSUKKOMIs. So You can specify "<span class="canchor">_</span>" for Image anchor.

    Date format

    Format of date. If you specify a charactor after %, it mean special about date formatting: "%Y"(Year), "%m"(Month), "%b"(Short name of month), "%B"(Long name of month), "%d"(Day), "%a"(Short name of day of week), "%A"(Long name of day of week).

    Max dates of Latest diaplay

    In the Latest mode, you can specify the number of days in the page.

    days in a page.

    My old days

    Show the link of "My old days"

    HTML end # timezone add_conf_proc( 'timezone', 'Time difference adjustment', 'update' ) do saveconf_timezone <<-HTML

    Time difference adjustment

    When updating diary, you can adjust date which is automatically inserted into the form. The unit is hour. For example, if you want to handle the time until 2 a.m. as the previous day, you set this to -2. tDiary inserts the date which is older by 2 hours than the actual time.

    HTML end # themes @theme_location_comment = "

    You can get many themes from Theme Gallery(Japanese).

    " @theme_thumbnail_label = "Thumbnail" add_conf_proc( 'theme', 'Themes', 'theme' ) do saveconf_theme r = <<-HTML

    Theme

    Specify the design of your diary using Theme or CSS. When you select "CSS specify", input URL of CSS into the field right side.

    Number of TSUKKOMI

    In Latest or Month mode, you can specify number of visible TSUKKOMIs. So in Dayly mode, all of TSUKKOMIs are shown.

    TSUKKOMIs

    Limit of TSUKKOMI per a day

    When numbers of TSUKKOMI over this value in a day, nobody can make new TSUKKOMI. If you use TrackBack plugin, this value means sum of TSUKKOMIs and TrackBacks.

    TSUKKOMIs

    HTML end # comment mail def comment_mail_mime( str ) [str.dup] end def comment_mail_conf_label; 'TSUKKOMI Mail'; end def comment_mail_basic_html @conf['comment_mail.header'] = '' unless @conf['comment_mail.header'] @conf['comment_mail.receivers'] = '' unless @conf['comment_mail.receivers'] @conf['comment_mail.sendhidden'] = false unless @conf['comment_mail.sendhidden'] <<-HTML

    Notify TSUKKOMI by E-mail

    Select notify or not when your diary gets a new TSUKKOMI. So TSUKKOMI mail need SMTP server settings in tdiary.conf.

    Receivers

    Sepecify receivers of TSUKKOMI mail, 1 address per 1 line. If you dose not specify, TSUKKOMI mails will be sent to your address.

    Mail header

    Specify a string insert to beginning of mail subject. The subject have a style of "your_specified_string:DATE-SERIAL NAME". "date" is formatted as same as diary's date you specified. But when you specify another date style in this string, subject style is changed to "your_specified_string-SERIAL NAME" (ex: "hoge:%Y-%m-%d")

    About hidden TSUKKOMI

    Some TSUKKOMI are hidden by filters. You can decide which sending E-mail by hidden TSUKKOMI.

    HTML end add_conf_proc( 'csrf_protection', 'CSRF Protection', 'security' ) do err = saveconf_csrf_protection errstr = '' case err when :param errstr = '

    Invalid options specified. Configuration not saved.

    ' when :key errstr = '

    No key specified. Configuration not saved.

    ' end csrf_protection_method = @conf.options['csrf_protection_method'] || 1 <<-HTML #{errstr}

    This page configures a protection scheme to prevent "cross-site request forgery" (CSRF) attacks.

    To make CSRF attack, a malicious person prepares a trap link in some web page and lets you visit that page. When the trap link is invoked (either by Javascript or your mouse click), your web browser sends a forged request to tDiary. Thus, neither encryption nor usual password protection can serve as a protection mechanism. TDiary provies two methods -- "checking referer" and "checking CSRF key" -- to prevent such attacks.

    Checking Referer

    Checks for Referer values

    #{if [0,1,2,3].include?(csrf_protection_method) then ' ' else '' end}Enabled (default)

    Configures Referer-based CSRF protection. TDiary checks the Referer value sent from your web browser. If the post request comes from some outer page, the request will be rejected. This setting can't be disabled through web-based configuration, for safety reasons.

    Handling of Referer-disabled browsers

    Reject (default) Accept

    Configures handling for requests without any Referer: value. By default tDiary rejects such request for safety reasons. If your browser is configured not to send Referer values, alter that setting to allow sending Referer, at least for originating sites. If it is impossible, configure the key-based CSRF protection below, and change this setting to "Accept".

    Checking CSRF key

    Checks for CSRF protection key

    Enabled Disabled (default)

    tDiary can add a secret key for every post form to prevent CSRF. As long as attackers do not know the secret key, forged requests will not be granted. To enable this feature, tDiary will generate a key automatically. To allow Referer-disabled browsers, you must enable this setting.

    #{"

    Caution: Your browser seems not to be sending any Referers, although Referer-based protection is enabled. Please open this page again via this link. If you see this message again, you must either change your browser setting (temporarily to change these settings, at least), or edit \"tdiary.conf\" directly.

    " if [1,3].include?(csrf_protection_method) && ! @cgi.referer && !@cgi.valid?('referer_exists')}
    HTML end add_conf_proc( 'logger', 'Log Level', 'basic' ) do saveconf_logger r = <<-HTML

    Log Level

    Select log level of tDiary's output. If you selected spam filter's log level is enabled then select INFO or DEBUG.

    HTML end # # old ruby alert # def old_ruby_alert_message "The ruby #{RUBY_VERSION} will be unsupported by tDiary next release." end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/en/05referer.rb000066400000000000000000000041251362645730700220450ustar00rootroot00000000000000# # 05referer.rb: English resource of referer plugin # # Copyright (C) 2006, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # def referer_today; "Today's Links"; end def volatile_referer; "Links to old diaries"; end def label_no_referer; "Today's Links Excluding List"; end def label_only_volatile; "Volatile Links List"; end def label_referer_table; "Today's Links Conversion Rule"; end add_conf_proc( 'referer', "Today's Link", 'referer' ) do saveconf_referer <<-HTML

    Show links

    Select show or hide about Today's Link

    #{label_no_referer}

    List of excluding URL that is not recorded to Today's Link. Specify it in regular expression, and a URL into a line.

    See Default configuration is here.

    #{label_only_volatile}

    List of URLs recorded to only volatile lists. This list will be clear when update diary in new day. Specify it in regular expression, and a URL into a line.

    See Default configuration is here.

    #{label_referer_table}

    A table to convert URL to words in Today's Link. Specify it in regular expression, and a URL into a line.

    See Default configurations.

    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/en/10spamfilter.rb000066400000000000000000000067411362645730700225630ustar00rootroot00000000000000# # en/10spamfilter.rb: resource of en # @spamfilter_label_conf = 'spam filter' @dnsblfilter_label_conf = 'DNSBL filter' def spamfilter_conf_html r = <<-HTML

    Basic filters

    Which dou you want to do spam TSUKKOMI finally?

    It is spam when TSUKKOMI body has URIs over this value.

    It is spam when percentage of URI charctors in TSUKKOMI body is over this value.

    It is spam when TSUKKOMI body has URIs match with these patterns.

    It is spam when TSUKKOMI body matches with these patterns.

    It is spam when mail address matches with these patterns.

    Use patterns of URI for checking mail address.

    Date

    Javascript is used to display TSUKKOMI from into
    days before (null: no limit, 0: only today)

    IP address filters

    It is spam when sender IP address matches these patterns. You have to specify complete IP address or part of IP address ends by '.'.

    Description of TSUKKOMI

    Show messeges and spam conditions for your subscribers.

    HTML r << <<-HTML

    for Debug

    Debug mode.

    HTML r end def dnsblfilter_conf_html r = <<-HTML

    Domain Blacklist Services

    List of IP based Domain Blacklist Services

    List of Domain Blacklist Services

    List of Safe Domain. Example for search engine.

    HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/en/50sp.rb000066400000000000000000000032411362645730700210330ustar00rootroot00000000000000# English resources of 50sp.rb =begin = Select-plugin plugin == Abstract Selects which plugin to be actually used. == Usage Put this file into the plugin/ directory. Next, move the plugins you want to be optional into another directory. In the example below, these plugins are assumed to be in plugin/selectable directory. Finally, edit the tdiary.conf file in the same directory as tdiary.rb and add the following line: @conf.options['sp.path'] = 'misc/plugin' to indicate the directory you have put the optional plugins. It can be an absolute path. == Options :@conf.options['sp.path'] Directory name where the optional plugins are, relative from the directory where tdiary.rb is or absolute. :@conf.options['sp.usenew'] Define true if you want to the users to try a newly installed plugin. Newly installed plugins are detected next time when the user configures this plugin. == Copyright notice Copyright (C) 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end @sp_label = 'Plugin selection' @sp_label_description = '

    Selects which plugins you want to use.

    ' @sp_label_please_select = '

    Please check the plugins you want to use. Each plugin filename is linked to its document. Please create or improve the document!

    ' @sp_label_new = '

    New! Give it a try.

    ' @sp_label_used = '

    Being used

    ' @sp_label_notused = '

    Currently not used

    ' @sp_label_noplugin = '

    There is no optional plugins.

    ' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/en/60sf.rb000066400000000000000000000036141362645730700210260ustar00rootroot00000000000000# English resources of 60sf.rb # Based on English resources of 50sp.rb Revision: 1.2 # Modified by KURODA Hiraku =begin = Select-spamfilter plugin == Abstract Selects which filter to be actually used. == Usage Put this file into the plugin/ directory. Next, move the filterss you want to be optional into another directory. In the example below, these filters are assumed to be in filter/selectable directory. Finally, edit the tdiary.conf file in the same directory as tdiary.rb and add the following line: @conf.options['sf.path'] = 'misc/filter' to indicate the directory you have put the optional filters. It can be an absolute path. == Options :@conf.options['sf.path'] Directory name where the optional filters are, relative from the directory where tdiary.rb is or absolute. :@conf.options['sf.usenew'] Define true if you want to the users to try a newly installed filter. Newly installed filters are detected next time when the user configures this plugin. == Copyright notice Copyright (C) 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. Original version of these files is for selecting plugins. Modifying for selecting filters is by KURODA Hiraku Feb. 2008 =end @sf_label = 'Filter selection' @sf_label_description = '

    Selects which filters you want to use.

    ' @sf_label_please_select = '

    Please check the filters you want to use. Each filter filename is linked to its document. Please create or improve the document!

    ' @sf_label_new = '

    New! Give it a try.

    ' @sf_label_used = '

    Being used

    ' @sf_label_notused = '

    Currently not used

    ' @sf_label_nofilter = '

    There is no optional filters.

    ' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/ja/000077500000000000000000000000001362645730700177075ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/plugin/ja/00default.rb000066400000000000000000000502251362645730700220240ustar00rootroot00000000000000# # ja/00default.rb: Japanese resources of 00default.rb. # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # header # def title_tag r = "#{h @conf.html_title}" case @mode when 'day', 'comment' r << "(#{@date.strftime( '%Y-%m-%d' )})" if @date when 'month' r << "(#{@date.strftime( '%Y-%m' )})" if @date when 'form' r << '(追記)' when 'edit' r << '(編集)' when 'preview' r << '(プレビュー)' when 'showcomment' r << '(変更完了)' when 'conf' r << '(設定)' when 'saveconf' r << '(設定完了)' when 'nyear' r << "(#{h @cgi.params['date'][0].sub( /^(\d\d)/, '\1-')}[#{nyear_diary_label}])" if @date end r << '' end # # TSUKKOMI mail # def comment_mail_mime( str ) require 'nkf' NKF::nkf( "-j -m0 -f50", str ).lines.collect do |s| %Q|=?ISO-2022-JP?B?#{[s.chomp].pack( 'm' ).gsub( /\n/, '' )}?=| end end def comment_mail_conf_label; 'ツッコミメール'; end def comment_mail_basic_html @conf['comment_mail.header'] = '' unless @conf['comment_mail.header'] @conf['comment_mail.receivers'] = '' unless @conf['comment_mail.receivers'] @conf['comment_mail.sendhidden'] = false unless @conf['comment_mail.sendhidden'] <<-HTML

    ツッコミメールを送る

    ツッコミがあった時に、メールを送るかどうかを選択します。

    送付先

    メールの送付先を指定します。1行に1メールアドレスの形で、複数指定可能です。指定のない場合には、あなたのメールアドレスに送られます。

    メールヘッダ

    メールのSubjectにつけるヘッダ文字列を指定します。振り分け等に便利なように指定します。実際のSubjectには「指定文字列:日付-1」のように、日付とコメント番号が付きます。ただし指定文字列中に、%に続く英字があった場合、それを日付フォーマット指定を見なします。つまり「日付」の部分は自動的に付加されなくなります(コメント番号は付加されます)。

    非表示ツッコミの扱い

    フィルタの結果、最初から非表示にされたツッコミが記録されることがあります。この非表示のツッコミが来たときにもメールを発信するかどうかを選択します。

    HTML end # # link to HOWTO write diary # def style_howto %Q|/書き方| end # # labels (normal) # def no_diary; "#{@date.strftime( @conf.date_format )}の日記はありません。"; end def comment_today; '本日のツッコミ'; end def comment_total( total ); "(全#{total}件)"; end def comment_new; 'ツッコミを入れる'; end def comment_description_default; 'ツッコミ・コメントがあればどうぞ! E-mailアドレスは公開されません。'; end def comment_limit_label; '本日の日記はツッコミ数の制限を越えています。'; end def comment_description_short; 'ツッコミ!!'; end def comment_name_label; 'お名前'; end def comment_name_label_short; '名前'; end def comment_mail_label; 'E-mail'; end def comment_mail_label_short; 'Mail'; end def comment_body_label; 'コメント'; end def comment_body_label_short; '本文'; end def comment_submit_label; '投稿'; end def comment_submit_label_short; '投稿'; end def comment_date( time ); time.strftime( "(#{@conf.date_format} %H:%M)" ); end def trackback_today; '本日のTrackBacks'; end def trackback_total( total ); "(全#{total}件)"; end def navi_index; 'トップ'; end def navi_latest; '最新'; end def navi_oldest; '最古'; end def navi_update; "追記"; end def navi_edit; "編集"; end def navi_preference; "設定"; end def navi_prev_diary(date); "前の日記(#{date.strftime(@conf.date_format)})"; end def navi_next_diary(date); "次の日記(#{date.strftime(@conf.date_format)})"; end def navi_prev_month; "前月"; end def navi_next_month; "翌月"; end def navi_prev_nyear(date); "前の日(#{date.strftime('%m-%d')})"; end def navi_next_nyear(date); "次の日(#{date.strftime('%m-%d')})"; end def navi_prev_ndays; "前#{@conf.latest_limit}日分"; end def navi_next_ndays; "次#{@conf.latest_limit}日分"; end def submit_label if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then '追記' else '登録' end end def preview_label; 'プレビュー'; end def nyear_diary_label; "長年日記"; end def nyear_diary_title; "長年日記"; end # # labels (for mobile) # def mobile_navi_latest; '最新'; end def mobile_navi_update; "追記"; end def mobile_navi_edit; "編集"; end def mobile_navi_preference; "設定"; end def mobile_navi_prev_diary; "前"; end def mobile_navi_next_diary; "次"; end def mobile_label_hidden_diary; 'この日は【非表示】です'; end # # category # def category_anchor(c); "[#{c}]"; end # # preferences (resources) # @conf_saving = '保存中……' # genre labels @conf_genre_label['basic'] = '基本' @conf_genre_label['update'] = '更新' @conf_genre_label['theme'] = 'テーマ' @conf_genre_label['tsukkomi'] = 'ツッコミ' @conf_genre_label['referer'] = 'リンク元' @conf_genre_label['security'] = 'セキュリティ' @conf_genre_label['etc'] = 'その他' add_conf_proc( 'default', 'サイトの情報', 'basic' ) do saveconf_default @conf.description ||= '' @conf.icon ||= '' @conf.banner ||= '' <<-HTML

    タイトル

    HTMLの<title>タグ中および、モバイル端末からの参照時に使われるタイトルです。HTMLタグは使えません。

    著者名

    あなたの名前を指定します。HTMLヘッダ中に展開されます。

    メールアドレス

    あなたのメールアドレスを指定します。HTMLヘッダ中に展開されます。

    トップページURL

    日記よりも上位のコンテンツがあれば指定します。存在しない場合は何も入力しなくてかまいません。

    日記のURL

    日記のURLを指定します。このURLは、さまざまなプラグインで日記を指し示すために利用されるので、正しく一意なものを指定しましょう。

    #{"

    指定してある値と、現在アクセス中のURLが異なります。注意してください。

    " unless base_url == @cgi.base_url}

    日記の説明

    この日記の簡単な説明を指定します。HTMLヘッダ中に展開されます。何も入力しなくてもかまいません。

    サイトアイコン(favicon)

    この日記を表す小さなアイコン画像(favicon)があればそのURLを指定します。HTMLヘッダ中に展開されます。何も入力しなくてもかまいません。

    バナー画像

    この日記を表す画像(バナー)があればそのURLを指定します。makerssプラグインなどでRSSを出力する場合などに使われます。何も入力しなくてもかまいません。

    tDiary 標準のバナーを用いる場合は日記を設置している URL に "/theme/ogimage.png" を付与して入力してください。

    フレーム内表示

    日記全体をフレーム内にくるんで表示することを許可します。

    HTML end add_conf_proc( 'header', 'ヘッダ・フッタ', 'basic' ) do saveconf_header <<-HTML

    ヘッダ

    日記の先頭に挿入される文章を指定します。HTMLタグが使えます。「<%=navi%>」で、ナビゲーションボタンを挿入できます(これがないと更新ができなくなるので削除しないようにしてください)。また、「<%=calendar%>」でカレンダーを挿入できます。その他、各種プラグインを記述できます。

    フッタ

    日記の最後に挿入される文章を指定します。ヘッダと同様に指定できます。

    HTML end add_conf_proc( 'display', '表示一般', 'basic' ) do saveconf_display <<-HTML

    セクションアンカー

    日記のセクションの先頭(サブタイトルの行頭)に挿入される、リンク用のアンカー文字列を指定します。なお「<span class="sanchor">_</span>」を指定すると、テーマによっては自動的に画像アンカーがつくようになります。

    ツッコミアンカー

    読者からのツッコミの先頭に挿入される、リンク用のアンカー文字列を指定します。なお「<span class="canchor">_</span>」を指定すると、テーマによっては自動的に画像アンカーがつくようになります。

    日付フォーマット

    日付の表示部分に使われるフォーマットを指定します。任意の文字が使えますが、「%」で始まる英字には次のような特殊な意味があります。「%Y」(西暦年)、「%m」(月数値)、「%b」(短月名)、「%B」(長月名)、「%d」(日)、「%a」(短曜日名)、「%A」(長曜日名)。

    最新表示の最大日数

    最新の日記を表示するときに、そのページ内に何日分の日記を表示するかを指定します。

    最大日分

    長年日記の表示

    長年日記を表示するためのリンクを表示するかどうかを指定します。

    HTML end add_conf_proc( 'timezone', '時差調整', 'update' ) do saveconf_timezone <<-HTML

    時差調整

    更新時、フォームに挿入される日付を時間単位で調整できます。例えば午前2時までは前日として扱いたい場合には「-2」のように指定することで、2時間分引かれた日付が挿入されるようになります。また、この日付はWebサーバ上の時刻になっているので、海外のサーバで運営している場合の時差調整にも利用できます。

    HTML end @theme_location_comment = "

    ここにないテーマはテーマ・ギャラリーから入手できます。

    " @theme_thumbnail_label = "サムネイル" add_conf_proc( 'theme', 'テーマ選択', 'theme' ) do saveconf_theme r = <<-HTML

    テーマの指定

    日記のデザインをテーマ、もしくはCSSの直接入力で指定します。ドロップダウンメニューから「CSS指定→」を選択した場合には、右の欄にCSSのURLを入力してください。

    ツッコミリスト表示数

    最新もしくは月別表示時に表示する、ツッコミの最大件数を指定します。なお、日別表示時にはここの指定にかかわらずすべてのツッコミが表示されます。

    最大

    1日あたりのツッコミ最大数

    1日に書き込めるツッコミの最大数を指定します。この数を超えると、ツッコミ用のフォームが非表示になります。なお、TrackBackプラグインを入れている場合には、ツッコミとTrackBackの合計がこの制限を受けます。

    最大

    HTML end add_conf_proc( 'csrf_protection', 'CSRF(乗っ取り)対策', 'security' ) do err = saveconf_csrf_protection errstr = '' case err when :param errstr = '

    不正な組み合わせです。変更されませんでした。

    ' when :key errstr = '

    鍵が空です。変更されませんでした。

    ' end csrf_protection_method = @conf.options['csrf_protection_method'] || 1 <<-HTML #{errstr}

    クロスサイト・リクエストフォージェリ(CSRF)の対策手法を設定します。

    CSRF攻撃は、悪意のある人間がWebページに罠を仕掛けます。 その罠を仕掛けたページをあなたが閲覧すると、あなたのブラウザは tDiaryに偽の書き込み要求を送出してしまいます。あなたのブラウザが 偽要求を送出してしまうため、暗号化・パスワード保護だけでは対策になりません。 tDiaryでは、この種の攻撃に対して、「Refererチェック」と「CSRFキー」という 2種類の防衛手段を用意しています。

    Refererチェックによる防衛

    Refererの正当性の検査

    #{if [0,1,2,3].include?(csrf_protection_method) then ' ' else '' end}する(標準)

    あなたのブラウザが送出するReferer(リンク元情報)を検査します。 書き込み要求が正しいページから送出されたことを確認することで、 偽ページからの要求を防ぎます。不正なページからの要求を検出した場合、 更新リクエストを拒否します。 この設定画面では、無効にすることは出来ません。

    Refererを送出しないブラウザを拒否

    する(標準) しない

    ブラウザからRefererが送られてこなかった場合の動作を指定します。

    標準では、Refererが送出されない場合、不正なリクエストを 判別できないため、書き込み・設定変更を拒否します。 あなたのブラウザがRefererを送出しない設定の場合、 この設定が「する」になっていると、正規の書き込み要求も拒否してしまいます。 ブラウザを設定を変更しRefererを送出するようにしてください。 どうしてもRefererを送出する設定に出来ない場合、「しない」にしてください。 この場合、Refererが全く送出されなかった場合にも、 書き込み・設定変更を許すようになりますが、 CSRFによる攻撃と区別できなくなりますので、必ず次の「CSRF防止キー」の 設定と併用して下さい。

    CSRF防止キーによる防衛

    CSRF防止キーの検査

    する しない(標準)

    書き込みフォームに偽装書き込み防止のためのキーを設定し、CSRFを防ぎます。 偽ページが秘密のキーを知らない限り、 偽の書き込み要求を生成することができなくなります。 この検査を「する」にすると、システムが鍵を自動的に生成、設定します。 上の設定と両方「しない」にすることはできません。

    この設定を「する」にした場合、この機構に対応していない一部の プラグインが動作しなくなることがあります。

    #{"

    注意: あなたのブラウザは現在Refererを送出していないようです。 このリンクからもう一回 このページを開いてみて下さい。 それでもこのメッセージが出る状況では、この設定を変える場合、 一時的にRefererを送出する設定にするか、 直接tdiary.confを編集して下さい。

    " if [1,3].include?(csrf_protection_method) && ! @cgi.referer && !@cgi.valid?('referer_exists')}
    HTML end add_conf_proc( 'logger', 'ログレベル選択', 'basic' ) do saveconf_logger r = <<-HTML

    ログレベルの設定

    tDiaryが出力するログレベルを指定します。spam フィルタのログ記録を利用する場合は INFO または DEBUG に指定して下さい。

    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/ja/05referer.rb000066400000000000000000000050411362645730700220330ustar00rootroot00000000000000# # 05referer.rb: Japanese resource of referer plugin # # Copyright (C) 2006, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # def referer_today; '本日のリンク元'; end def volatile_referer; '以前の日記へのリンク元'; end def label_no_referer; 'リンク元記録除外リスト'; end def label_only_volatile; '以前の日記へのリンク元に記録するリスト'; end def label_referer_table; 'リンク置換リスト'; end add_conf_proc( 'referer', 'リンク元', 'referer' ) do saveconf_referer <<-HTML

    リンク元の表示

    リンク元リストを表示するかどうかを指定します。

    #{label_no_referer}

    リンク元リストに追加しないURLを指定します。正規表現で指定できます。1件1行で入力してください。

    既存設定はこちら

    #{label_only_volatile}

    「以前の日記へのリンク元」にのみ記録したいURLはこちらに記述します。「以前の日記へのリンク元」は、新しい日付の日記を書くと消去されます。正規表現で指定できます。1件1行で入力してください。

    既存設定はこちら

    #{label_referer_table}

    リンク元リストのURLを、特定の文字列に変換する対応表を指定できます。1件につき、URLと表示文字列を空白で区切って指定します。正規表現が使えるので、URL中に現れた「(〜)」は、置換文字列中で「\\\\1」のような「\\数字」で利用できます。

    既存設定はこちら

    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/ja/10spamfilter.rb000066400000000000000000000104421362645730700225440ustar00rootroot00000000000000# # ja/10spamfilter.rb: resource of ja # @spamfilter_label_conf = 'spamフィルタ' @dnsblfilter_label_conf = 'DNSBLフィルタ' def spamfilter_conf_html r = <<-HTML

    spamの扱い

    spamと判定されたツッコミを

    内容によるフィルタ

    ツッコミ中のURLの数が個を超えたらspamとみなす

    ツッコミ中でURLを表す文字の占める割合が%より高いものはspamとみなす

    ツッコミ本文が以下のパターンに当てはまる場合はspamとみなす。正規表現が利用できます

    ツッコミのメールアドレスが以下のパターンに当てはまる場合はspamとみなす。正規表現が使えます

    ツッコミやリンク元に含まれるURLに、以下のパターンが含まれる場合はspamとみなす

    上のパターンをツッコミのメールアドレスのチェックにも

    日付けによるフィルタ

    日以上前の日付けのツッコミフォームはjavascriptで表示する。
    (空欄は制限なし、0は当日のみ)

    IPアドレスによるフィルタ

    ツッコミのIPアドレスが、以下のパターンに当てはまる場合はspamとみなす(リストには完全なIPアドレスまたは「.」で終わるIPアドレスの一部を記述する)

    ツッコミの注意文

    ツッコミフォームの上に表示する注意文を設定します。spam判定条件を変更した場合に、読者にそれをきちんと知らせましょう

    HTML r << <<-HTML

    フィルタのログ

    フィルタのログを

    HTML r end def dnsblfilter_conf_html r = <<-HTML

    DNSBL(DNSブラックリスト)サービスを使ったフィルタ

    IPベースのブラックリスト問い合わせサーバーを指定します

    ドメインベースのブラックリスト問い合わせサーバーを指定します

    以下に指定したドメインはブラックリストに問い合わせません。検索エンジン等を指定してください

    HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/ja/50sp.rb000066400000000000000000000057021362645730700210270ustar00rootroot00000000000000# Japanese resources of 50sp.rb =begin = プラグイン選択プラグイン((-$Id: 50sp.rb,v 1.3 2008-03-02 09:01:21 kazuhiko Exp $-)) Please see below for an English description. == 概要 どのプラグインを使うのか選びます このプラグインは00defaults.rbの次に読まれ、このプラグイン自身から選択可 能なプラグインが読まれます。その後にデフォルトのパスにあるプラグインが読 み込まれますので、同じメソッドを定義している場合には、デフォルトのパスの ものが有効になります。 == 使い方 このプラグインをplugin/ディレクトリに配置してください。 また、00defaults.rbやこのプラグインなど、絶対に必要なプラグイン以外は、 httpサーバーから見られる別のディレクトリに移してください。以下の例では、 pluginディレクトリの下にselectableというディレクトリを作っています。 最後に、tdiary.rbと同じ場所にあるtdiary.confに、 @conf.options['sp.path'] = 'misc/plugin' などと、選択できるプラグインのあるディレクトリをtdiary.rbのあるディレク トリからの相対パスか絶対パスで指定してください。 == オプション :@conf.options['sp.path'] 'plugin/selectable'などと、選択できるプラグインのあるディレクトリを、 tdiary.rbのあるディレクトリからの相対パスか絶対パスで指定してください。 :@conf.options['sp.usenew'] 新しくインストールされたプラグインをデフォルトで使うようにする場合は trueに設定してください。新しくインストールされたプラグインを検出するの は、次にプラグインが選択される時です。 == TODO 選択されていたプラグインが消去された時にどうするか。現在の実装では、プラ グイン読み込み時には無視して、次に選択をしなおした時に消える。 == 著作権について (Copyright notice) Copyright (C) 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end @sp_label = 'プラグイン選択' @sp_label_description = '

    どのプラグインを使うか選択します。

    ' @sp_label_please_select = '

    有効にしたいプラグインにチェックしてください。プラグインのファイル名をクリックするとドキュメントが見られるかもしれません。ぜひ追加・編集してくださいね。

    ' @sp_label_new = '

    新入荷!お試しください

    ' @sp_label_used = '

    使用中

    ' @sp_label_notused = '

    休憩中

    ' @sp_label_noplugin = '

    選択可能なプラグインはありません。

    ' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/plugin/ja/60sf.rb000066400000000000000000000056141362645730700210200ustar00rootroot00000000000000# Japanese resources of 60sf.rb # Based on 50sp.rb # Modified by KURODA Hiraku. =begin = スパムフィルター選択プラグイン Please see below for an English description. == 概要 どのフィルターを使うのか選びます 選択したフィルターはデフォルトのフィルターによる判定の後で適用されます。 == 使い方 このプラグインをplugin/ディレクトリに配置してください。 次に、tdiary.rbと同じ場所にあるtdiary.confに、 @conf.options['sf.path'] = 'misc/filter' などと、選択できるフィルターのあるディレクトリをtdiary.rbのあるディレク トリからの相対パスか絶対パスで指定してください。 フィルターに設定用のプラグインが付属している場合は、フィルター用ディレク トリの下にpluginディレクトリを作り、その中に入れておくと、フィルターを ロードした後でプラグインもロードされます。 例えばベイズフィルタをmisc/filterに置いた場合は次のようなディレクトリ 構成になります。 misc/filter/ |-- plugin/ | |-- en/spambayes.rb | |-- ja/spambayes.rb | `-- spambayes.rb `-- spambayes.rb == オプション :@conf.options['sf.path'] 'filter/selectable'などと、選択できるフィルターのあるディレクトリを、 tdiary.rbのあるディレクトリからの相対パスか絶対パスで指定してください。 :@conf.options['sf.usenew'] 新しくインストールされたフィルターをデフォルトで使うようにする場合は trueに設定してください。新しくインストールされたフィルターを検出するの は、次にフィルターが選択される時です。 == 著作権について (Copyright notice) Copyright (C) 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. Original version of these files is for selecting plugins. Modifying for selecting filters is by KURODA Hiraku Feb. 2008 =end @sf_label = 'スパムフィルター選択' @sf_label_description = '

    どのフィルターを使うか選択します。

    ' @sf_label_please_select = '

    有効にしたいフィルターにチェックしてください。フィルターのファイル名をクリックするとドキュメントが見られるかもしれません。ぜひ追加・編集してくださいね。

    ' @sf_label_new = '

    新入荷!お試しください

    ' @sf_label_used = '

    使用中

    ' @sf_label_notused = '

    休憩中

    ' @sf_label_noplugin = '

    選択可能なフィルターはありません。

    ' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/rack.rb000066400000000000000000000006431362645730700172670ustar00rootroot00000000000000module TDiary module Rack autoload :HtmlAnchor, 'tdiary/rack/html_anchor' autoload :ValidRequestPath, 'tdiary/rack/valid_request_path' autoload :Session, 'tdiary/rack/session' autoload :Static, 'tdiary/rack/static' autoload :Auth, 'tdiary/rack/auth' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/rack/000077500000000000000000000000001362645730700167375ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/rack/auth.rb000066400000000000000000000006341362645730700202300ustar00rootroot00000000000000module TDiary module Rack class Auth autoload :Basic, 'tdiary/rack/auth/basic' autoload :OmniAuth, 'tdiary/rack/auth/omniauth' def initialize(app) if defined? ::OmniAuth @app = TDiary::Rack::Auth::OmniAuth.new(app) else @app = TDiary::Rack::Auth::Basic.new(app, ENV['HTPASSWD'] || '.htpasswd') end end def call(env) @app.call(env) end end end end tdiary-core-5.1.1/lib/tdiary/rack/auth/000077500000000000000000000000001362645730700177005ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/rack/auth/basic.rb000066400000000000000000000015631362645730700213130ustar00rootroot00000000000000require 'rack' require 'webrick/httpauth/htpasswd' module TDiary module Rack class Auth class PasswordFileNotFound < StandardError; end class Basic def initialize(app, file = '.htpasswd') @authenticator = ::Rack::Auth::Basic.new(app) do |user, pass| unless File.exist?(file) raise PasswordFileNotFound.new("#{file} is not found. Please create it by htpasswd program.") end htpasswd = WEBrick::HTTPAuth::Htpasswd.new(file) crypted = htpasswd.get_passwd(nil, user, false) crypted == pass.crypt(crypted) if crypted end end def call(env) begin @authenticator.call(env) rescue PasswordFileNotFound => e [403, {"Content-Type" => "text/plain"}, [e.message]] end end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/rack/auth/omniauth.rb000066400000000000000000000044101362645730700220500ustar00rootroot00000000000000require 'omniauth' require 'tdiary/rack/auth/omniauth/authorization' class TDiary::Rack::Auth::OmniAuth class NoStrategyFoundError < StandardError; end @provider_procs = {} class << self attr_reader :provider_procs end def self.add_provider(name, &block) @provider_procs[name] = block end def initialize(app) provider = enabled_providers.first unless provider raise NoStrategyFoundError.new("Not found any strategies. Write the omniauth strategy in your Gemfile.local.") end @app = ::Rack::Builder.new(app) { use TDiary::Rack::Session }.tap {|builder| builder.instance_eval(&self.class.provider_procs[provider]) }.to_app end def call(env) @app.call(env) end add_provider(:Twitter) do # https://apps.twitter.com/ # https://github.com/arunagw/omniauth-twitter use ::OmniAuth::Builder do provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end use TDiary::Rack::Auth::OmniAuth::Authorization, :twitter do |auth| ENV['TWITTER_NAME'].split(/,/).include?(auth.info.nickname) end end add_provider(:Facebook) do # https://developers.facebook.com/apps/ # https://github.com/mkdynamic/omniauth-facebook use ::OmniAuth::Builder do provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'] end use TDiary::Rack::Auth::OmniAuth::Authorization, :facebook do |auth| ENV['FACEBOOK_EMAIL'].split(/,/).include?(auth.info.email) end end add_provider(:GitHub) do # https://github.com/settings/applications # https://github.com/intridea/omniauth-github use ::OmniAuth::Builder do provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'] end use TDiary::Rack::Auth::OmniAuth::Authorization, :github do |auth| ENV['GITHUB_NAME'].split(/,/).include?(auth.info.nickname) end end add_provider(:GoogleOauth2) do # https://code.google.com/apis/console/ # https://github.com/zquestz/omniauth-google-oauth2 use ::OmniAuth::Builder do provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"] end use TDiary::Rack::Auth::OmniAuth::Authorization, :google_oauth2 do |auth| ENV['GOOGLE_EMAIL'].split(/,/).include?(auth.info.email) end end private def enabled_providers ::OmniAuth::Strategies.constants.select do |name| self.class.provider_procs.has_key?(name) end end end tdiary-core-5.1.1/lib/tdiary/rack/auth/omniauth/000077500000000000000000000000001362645730700215245ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/rack/auth/omniauth/authorization.rb000066400000000000000000000035241362645730700247550ustar00rootroot00000000000000require 'omniauth' module TDiary module Rack class Auth class OmniAuth class Authorization def initialize(app, provider, &block) @app = app @provider = provider @authz = block end def call(env) if not authenticate?(env) # phase 1: request phase login(env) elsif env['REQUEST_PATH'].match(%r|auth/#{@provider}/callback|) # phase 2: callback phase callback(env) else # phase 3: authorization phase auth = env['rack.session']['auth'] env['REMOTE_USER'] = "#{auth.uid}@#{auth.provider}" return forbidden unless @authz.call(auth) @app.call(env) end end def login(env) STDERR.puts "use #{@provider} authentication strategy" req = ::Rack::Request.new(env) env['rack.session']['tdiary.auth.redirect'] = "#{req.base_url}#{req.fullpath}" redirect = File.join("#{req.base_url}#{req.path}", "#{::OmniAuth.config.path_prefix}/#{@provider}") [302, {'Content-Type' => 'text/plain', 'Location' => redirect}, []] end def logout(env) env['rack.session']['user_id'] = nil end def forbidden [403, {'Content-Type' => 'text/plain'}, ['forbidden']] end def callback(env) # reset sesstion to prevend session fixation attack # see: http://www.ipa.go.jp/security/vuln/documents/website_security.pdf (section 1.4) env['rack.session.options'][:renew] = true auth = env['omniauth.auth'] env['rack.session']['auth'] = auth env['REMOTE_USER'] = "#{auth.uid}@#{auth.provider}" redirect = env['rack.session']['tdiary.auth.redirect'] || '/' [302, {'Content-Type' => 'text/plain', 'Location' => redirect}, []] end def authenticate?(env) env['omniauth.auth'] || env['rack.session']['auth'] end end end end end end tdiary-core-5.1.1/lib/tdiary/rack/html_anchor.rb000066400000000000000000000011001362645730700215520ustar00rootroot00000000000000require 'rack/request' module TDiary module Rack class HtmlAnchor def initialize( app ) @app = app end def call( env ) if env['PATH_INFO'].match(/(.*\/)([0-9\-]+)(p(\d\d))?\.html$/) env["PATH_INFO"] = $1 date = $2 anchor = $4 env["QUERY_STRING"] += "&" unless env["QUERY_STRING"].empty? env["QUERY_STRING"] += "date=#{date}" env["QUERY_STRING"] += "&p=#{anchor}" if anchor end @app.call( env ) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/rack/session.rb000066400000000000000000000010161362645730700207450ustar00rootroot00000000000000begin require 'rack/session/dalli' rescue LoadError end module TDiary module Rack class Session def initialize(app) @app = session_middleware(app) end def call(env) @app.call(env) end private def session_middleware(app) if ::Rack::Session.const_defined? :Dalli ::Rack::Session::Dalli.new( app, cache: Dalli::Client.new, expire_after: 2592000 ) else ::Rack::Session::Pool.new( app, expire_after: 2592000 ) end end end end end tdiary-core-5.1.1/lib/tdiary/rack/static.rb000066400000000000000000000010531362645730700205520ustar00rootroot00000000000000require 'rack/file' module TDiary module Rack class Static def initialize( app, base_dir ) @app = app @file = base_dir.map{|dir| ::Rack::File.new(dir) } end def call( env ) result = [] @file.each do |f| result = f.call(env) break if result[0].to_i < 400 || result[0].to_i >= 500 end if result[0].to_i >= 400 && result[0].to_i < 500 @app.call( env ) else result end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/rack/valid_request_path.rb000066400000000000000000000012471362645730700231530ustar00rootroot00000000000000module TDiary module Rack class ValidRequestPath def initialize( app ) @app = app end def call( env ) valid_paths = [ %r{^/$}, %r{^/index\.(rb|cgi)$}, %r{^/([0-9\-p]+)\.html$} ] valid_paths.each do |path| return @app.call(env) if env['PATH_INFO'].match(path) end body = "Not Found: #{env['PATH_INFO']}" if env["REQUEST_METHOD"] == "HEAD" [404, {'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s}, []] else [404, {'Content-Type' => 'text/plain'}, [body]] end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/referer_manager.rb000066400000000000000000000032111362645730700214650ustar00rootroot00000000000000# # module RefererManager # Management referers in a day. Include in Diary class. # module TDiary module RefererManager private # # call this method when initialize # def init_referers @referers = {} @new_referer = true # for compatibility end public def add_referer( ref, count = 1 ) newer_referer ref = ref.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) if /^([^:]+:\/\/)([^\/]+)/ =~ ref ref = $1 + $2.downcase + $' end begin uref = CGI::unescape( ref ) rescue ::Encoding::CompatibilityError return end if pair = @referers[uref] then pair = [pair, ref] if pair.class != Array # for compatibility @referers[uref] = [pair[0] + count, pair[1]] else @referers[uref] = [count, ref] end end def clear_referers @referers = {} end def count_referers @referers.size end def each_referer( limit = 10 ) newer_referer # dirty workaround to avoid recursive sort that # causes SecurityError in @secure=true # environment since # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=16081 @referers.values.sort_by{|e| "%08d_%s" % e}.reverse.each_with_index do |ary,idx| break if idx >= limit yield ary[0], ary[1] end end private def newer_referer unless @new_referer then # for compatibility @referers.keys.each do |ref| count = @referers[ref] if count.class != Array then @referers.delete( ref ) @referers[CGI::unescape( ref )] = [count, ref] end end @new_referer = true end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/request.rb000066400000000000000000000113761362645730700200440ustar00rootroot00000000000000# stolen from okkez http://github.com/hiki/hiki/blob/rack/hiki/request.rb module TDiary class Request < ::Rack::Request include RequestExtension attr_reader :env, :cgi def initialize( env, cgi = nil ) @env = env @cgi = cgi end def params if @cgi return @params if @params @params = { } @cgi.params.each{|k, v| v = v.uniq case v.size when 0 @params[k] = nil when 1 @params[k] = v[0] else @params[k] = v end } @params else super end end def []( key ) if @cgi params[key.to_s] else super end end def []=( key, val ) if @cgi params[key.to_s] = val else super end end def request_method if @cgi @env['REQUEST_METHOD'] else super end end def header( header ) if @cgi @cgi.header( header ) else super end end def get? if @cgi request_method == 'GET' else super end end def head? if @cgi request_method == 'HEAD' else super end end def post? if @cgi request_method == 'POST' else super end end def put? if @cgi request_method == 'PUT' else super end end def delete? if @cgi request_method == 'DELETE' else super end end def xhr? if @cgi @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" else super end end def accept_encoding if @cgi raise NameError, 'not implemented : accept_encoding' else super end end def body if @cgi raise NameError, 'not implemented : body' else super end end def content_charset if @cgi @env['CONTENT_CHARSET'] else super end end def content_length if @cgi @env['CONTENT_LENGTH'] else super end end def content_type if @cgi @env['CONTENT_TYPE'] else super end end def remote_addr if @cgi @env['REMOTE_ADDR'] else super end end def cookies if @cgi return @cookies if @cookies @cookies = { } @cgi.cookies.each{|k, v| case v.size when 0 @cookies[k] = nil when 1 @cookies[k] = v[0] else @cookies[k] = v end } @cookies else super end end def form_data? if @cgi raise NameError, 'not implemented : form_data?' else super end end def fullpath if @cgi raise NameError, 'not implemented : fullpath' else super end end def host if @cgi # Remove port number.from Rack::Response ( @env["HTTP_HOST"] || @env["SERVER_NAME"] ).gsub( /:\d+\z/, '' ) else super end end def ip if @cgi raise NameError, 'not implemented : ip' else super end end alias remote_addr ip def media_type if @cgi raise NameError, 'not implemented : madia_type' else super end end def media_type_params if @cgi raise NameError, 'not implemented : media_type_params' else super end end def openid_request if @cgi raise NameError, 'not implemented : openid_request' else super end end def openid_response if @cgi raise NameError, 'not implemented : openid_response' else super end end def parseable_data? if @cgi raise NameError, 'not implemented : parseable_data?' else super end end def path if @cgi raise NameError, 'not implemented : path' else super end end def path_info if @cgi raise NameError, 'not implemented : path' else super end w end def path_info=( s ) if @cgi raise NameError, 'not implemented : path_info=' else super end end def port if @cgi raise NameError, 'not implemented : port' else super end end def query_string if @cgi raise NameError, 'not implemented : query_string' else super end end def referer if @cgi raise NameError, 'not implemented : referer' else super end end alias referrer referer def schema if @cgi raise NameError, 'not implemented : schema' else super end end def script_name if @cgi @env['SCRIPT_NAME'] else super end end def session_options if @cgi raise NameError, 'not implemented : session_options' else super end end def url if @cgi raise NameError, 'not implemented : url' else super end end def user_agent if @cgi @cgi.user_agent else super end end def base_url if @cgi @cgi.base_url else super end end def values_at( *keys ) if @cgi raise NameError, 'not implemented : values_at' else super end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/response.rb000066400000000000000000000002361362645730700202030ustar00rootroot00000000000000module TDiary class Response < ::Rack::Response end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/server.rb000066400000000000000000000041301362645730700176500ustar00rootroot00000000000000# # server.rb: standalone tdiary cgi server via WEBrick. # # Copyright (C) 2008-2010, Kakutani Shintaro # You can redistribute it and/or modify it under GPL2 or any later version. module TDiary class Server require 'webrick' require 'webrick/httpservlet/cgihandler' require 'webrick/httputils' require 'webrick/accesslog' require 'tempfile' class << self def run( option ) @@server = new( option ) trap( "INT" ) { @@server.shutdown } trap( "TERM" ) { @@server.shutdown } @@server.start end def stop @@server.shutdown end end def initialize( opts ) @server = WEBrick::HTTPServer.new( Port: opts[:port], BindAddress: opts[:bind], DocumentRoot: TDiary.root, MimeTypes: tdiary_mime_types, Logger: webrick_logger_to( opts[:logger] ), AccessLog: webrick_access_log_to( opts[:access_log] ), ServerType: opts[:daemon] ? WEBrick::Daemon : nil, CGIInterpreter: WEBrick::HTTPServlet::CGIHandler::Ruby ) @server.logger.level = WEBrick::Log::DEBUG @server.mount("/", WEBrick::HTTPServlet::CGIHandler, TDiary.root + "/index.rb") @server.mount("/index.rb", WEBrick::HTTPServlet::CGIHandler, TDiary.root + '/index.rb') @server.mount("/update.rb", WEBrick::HTTPServlet::CGIHandler, TDiary.root + "/update.rb") @server.mount("/theme", WEBrick::HTTPServlet::FileHandler, TDiary.root + '/theme') @server.mount("/js", WEBrick::HTTPServlet::FileHandler, TDiary.root + '/js') end def start @server.start end def shutdown @server.shutdown end private def tdiary_mime_types WEBrick::HTTPUtils::DefaultMimeTypes.merge( { "rdf" => "application/xml", } ) end def webrick_logger_to( io ) io ||= Tempfile.new( "webrick_logger" ) WEBrick::Log::new( io, WEBrick::Log::DEBUG ) end def webrick_access_log_to( io ) io ||= Tempfile.new( "webrick_access_log" ) [ [ io, WEBrick::AccessLog::COMMON_LOG_FORMAT ], [ io, WEBrick::AccessLog::REFERER_LOG_FORMAT ] ] end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/style.rb000066400000000000000000000070711362645730700175110ustar00rootroot00000000000000require 'tdiary/comment_manager' require 'tdiary/referer_manager' require 'erb' module TDiary module Style module BaseSection attr_reader :subtitle, :author attr_reader :categories, :stripped_subtitle attr_reader :subtitle_to_html, :stripped_subtitle_to_html, :body_to_html def body @body.dup end def body=(str) @body = str end def html4(date, idx, opt) r = %Q[
    \n] r << %Q[<%=section_enter_proc( Time.at( #{date.to_i} ) )%>\n] r << do_html4( date, idx, opt ) r << %Q[<%=section_leave_proc( Time.at( #{date.to_i} ) )%>\n] r << "
    \n" end def chtml(date, idx, opt) r = %Q[<%=section_enter_proc( Time.at( #{date.to_i} ) )%>\n] r << do_html4( date, idx, opt ) r << %Q[<%=section_leave_proc( Time.at( #{date.to_i} ) )%>\n] end def to_s to_src end def categories_to_string @categories = categories cat_str = "" categories.each {|cat| cat_str << "[#{cat}]"} cat_str << " " unless cat_str.empty? end end module BaseDiary include ::ERB::Util include CommentManager include RefererManager def init_diary init_comments init_referers @show = true end def date @date end def set_date( date ) if date.class == String then y, m, d = date.scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] raise ArgumentError::new( 'date string needs YYYYMMDD format.' ) unless y @date = Time::local( y, m, d ) else @date = date end end def title @title || '' end def set_title( title ) @title = title @last_modified = Time::now end def last_modified # 日本語を含むツッコミを入れると diary.last_modified が String になる (原因不明) # (PStore 保存前は Time だが, 保存後に String となる) # 暫定的に String だったら Time へ変換する if @last_modified.instance_of? String @last_modified = Time.at(0) elsif @last_modified @last_modified else Time::at( 0 ) end end def last_modified=( lm ) @last_modified = lm end def visible? @show != false; end def show( s ) @show = s end def replace(date, title, body) set_date( date ) set_title( title ) @sections = [] append( body ) end def each_section @sections.each do |section| yield section end end def delete_section(index) @sections.delete_at(index - 1) end def eval_rhtml( opt, path = "#{File.dirname(__FILE__)}/../.." ) ERB.new(File.read("#{path}/views/#{opt['prefix']}diary.rhtml")).result(binding) end def to_src r = '' each_section do |section| r << section.to_src end r end def to_html( opt = {}, mode = :HTML ) case mode when :CHTML to_chtml( opt ) else to_html4( opt ) end end def to_html4(opt) r = '' idx = 1 each_section do |section| r << section.html4( date, idx, opt ) idx += 1 end r end def to_chtml( opt ) r = '' idx = 1 each_section do |section| r << section.chtml( date, idx, opt ) idx += 1 end r end def to_s "date=#{date.strftime('%Y%m%d')}, title=#{title}, body=[#{@sections.join('][')}]" end end # # module CategorizableDiary # module CategorizableDiary def categorizable?; true; end end # # module UncategorizableDiary # module UncategorizableDiary def categorizable?; false; end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/style/000077500000000000000000000000001362645730700171575ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/style/tdiary.rb000066400000000000000000000116121362645730700210010ustar00rootroot00000000000000# # tdiary_style.rb: tDiary style class for tDiary 2.x format. $Revision: 1.16 $ # # if you want to use this style, add @style into tdiary.conf below: # # @style = 'tDiary' # # Copyright (C) 2001-2005, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # module TDiary module Style class TdiarySection attr_reader :subtitle, :body, :author attr_reader :categories, :stripped_subtitle alias :subtitle_to_html :subtitle alias :stripped_subtitle_to_html :stripped_subtitle def initialize( fragment, author = nil ) @author = author lines = fragment.split( /\n+/ ) if lines.size > 1 then if /^<#{p}

    " end html end def to_s "subtitle=#{@subtitle}, body=#{@body}" end def categorized_subtitle @categories.collect do |c| %Q|<%= category_anchor("#{c}") %>| end.join + @stripped_subtitle.to_s end private def get_categories return [] unless @subtitle cat = /^(\[(.*?)\])+/.match(@subtitle).to_a[0] return [] unless cat cat.scan(/\[(.*?)\]/).collect do |c| c[0].split(/,/) end.flatten end def strip_subtitle return nil unless @subtitle @subtitle.sub( /^(\[(.*?)\])+\s*/, '' ) end end class TdiaryDiary def initialize( date, title, body, modified = Time::now ) init_diary replace( date, title, body ) @last_modified = modified end def style 'tDiary' end def append( body, author = nil ) body.gsub( /\r/, '' ).split( /\n\n+/ ).each do |fragment| section = TdiarySection::new( fragment, author ) @sections << section if section end @last_modified = Time::now self end def add_section(subtitle, body) sec = TdiarySection::new("\n\n ") sec.subtitle = subtitle sec.body = body @sections << sec @sections.size end def to_html4( opt ) r = '' each_section do |section| r << %Q[
    \n] r << %Q[<%= section_enter_proc( Time::at( #{date.to_i} ) ) %>\n] if section.subtitle then r << %Q[

    <%= subtitle_proc( Time::at( #{date.to_i} ), #{section.subtitle.dump.gsub( /%/, '\\\\045' )} ) %>

    \n] end if /^#{section.body.lines.collect{|l|l.chomp.sub( /^[  ]/u, '')}.join( "

    \n

    " )}

    \n] else r << %Q[

    <%= subtitle_proc( Time::at( #{date.to_i} ), nil ) %>] r << %Q[#{section.body.lines.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

    \n

    " )}

    ] end r << %Q[<%= section_leave_proc( Time::at( #{date.to_i} ) ) %>\n] r << %Q[
    ] end r end def to_chtml( opt ) r = '' each_section do |section| r << %Q[<%= section_enter_proc( Time::at( #{date.to_i} ) ) %>\n] if section.subtitle then r << %Q[

    <%= subtitle_proc( Time::at( #{date.to_i} ), #{section.subtitle.dump.gsub( /%/, '\\\\045' )} ) %>

    \n] end if /^#{section.body.lines.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

    \n

    " )}

    \n] else r << %Q[

    <%= subtitle_proc( Time::at( #{date.to_i} ), nil ) %>] r << %Q[#{section.body.lines.collect{|l|l.chomp.sub( /^[  ]/u, '' )}.join( "

    \n

    " )}

    \n] end r << %Q[<%= section_leave_proc( Time::at( #{date.to_i} ) ) %>\n] end r end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/style/wiki.rb000066400000000000000000000127221362645730700204530ustar00rootroot00000000000000# # Wiki_style.rb: Wiki style for tDiary 2.x format. $Revision: 1.32 $ # # if you want to use this style, add @style into tdiary.conf below: # # @style = 'Wiki' # # Copyright (C) 2003, TADA Tadashi # Copyright (C) 2005, Kazuhiko # You can distribute this under GPL2 or any later version. # require 'hikidoc' require 'uri' module TDiary module Style class WikiSection def initialize( fragment, author = nil ) @author = author if fragment[0] == ?! then @subtitle, @body = fragment.split( /\n/, 2 ) @subtitle.sub!( /^\!\s*/, '' ) else @subtitle = nil @body = fragment.dup end @body = @body || '' @body.sub!( /[\n\r]+\Z/, '' ) @body << "\n\n" @categories = get_categories @stripped_subtitle = strip_subtitle @subtitle_to_html = @subtitle ? to_html( "!#{@subtitle}" ) : '' @body_to_html = to_html( @body ) @html = @subtitle_to_html + "\n" + @body_to_html + "\n" @subtitle_to_html = strip_headings( @subtitle_to_html ) @body_to_html = strip_headings( @body_to_html ) @stripped_subtitle_to_html = @stripped_subtitle ? strip_headings( to_html( "!#{@stripped_subtitle}" ) ) : nil end def subtitle=(subtitle) @subtitle = subtitle ? (categories_to_string + subtitle) : nil @stripped_subtitle = strip_subtitle end def categories=(categories) @subtitle = @subtitle ? (categories_to_string + @stripped_subtitle) : nil @stripped_subtitle = strip_subtitle end def to_src r = '' r << "! #{@subtitle}\n" if @subtitle r << @body end def do_html4( date, idx, opt ) subtitle = false r = @html.lstrip r.sub!( %r!

    (.+?)

    !m ) do subtitle = true "

    <%= subtitle_proc( Time.at( #{date.to_i} ), #{$1.dump.gsub( /%/, '\\\\045' )} ) %>

    " end r.sub!( %r!^

    (.+?)

    $!m ) do "

    <%= subtitle_proc( Time.at( #{date.to_i} ), #{$1.dump.gsub( /%/, '\\\\045' )} ) %>

    " end unless subtitle r.gsub( /<(\/)?tdiary-section>/, '<\\1p>' ) end private def valid_plugin_syntax?(code) eval( "BEGIN {return true}\n#{code.dup}", nil, "(plugin)", 0 ) rescue SyntaxError lambda { eval('') }.call false end def to_html( string ) html = HikiDoc::to_html( string, level: 3, empty_element_suffix: '>', use_wiki_name: false, allow_bracket_inline_image: false, plugin_syntax: method(:valid_plugin_syntax?) ).strip html.gsub!( %r!\{\{(.+?)\}\}!m ) do "<%=#{CGI.unescapeHTML($1)}\n%>" end html.gsub!( %r!
    \{\{(.+?)\}\}
    !m ) do "

    <%=#{CGI.unescapeHTML($1)}\n%>

    " end html.gsub!( %r!(.+?)! ) do k, u = $2, $1 if /^(\d{4}|\d{6}|\d{8}|\d{8}-\d+)[^\d]*?#?([pct]\d+)?$/ =~ u then %Q[<%=my '#{$1}#{$2}', '#{escape_quote k}' %>] elsif /:/ =~ u scheme = URI( u ).scheme rescue nil # URI::InvalidURIError # if 'a' elements with some attr in the plugin notation, # its HTML will be diffelent from link notation (then it error). # trap the style of HTML when u has a space because it means # two or more attr. if / / =~ u || /\A(?:http|https|ftp|mailto)\z/ =~ scheme u.sub!( /^\w+:/, '' ) if %r|://| !~ u and /^mailto:/ !~ u %Q[#{k}] elsif ( k == u ) %Q[<%=kw '#{escape_quote u}'%>] else %Q[<%=kw '#{escape_quote u}', '#{escape_quote k}'%>] end elsif k == u %Q[<%=kw '#{escape_quote u}', '#{escape_quote k}'%>] else %Q[#{k}] end end html end def escape_quote( s ) s.gsub( /'/, "\\\\'" ) end def strip_headings( string ) html = string html.sub!( /\A

    /, '' ) html.sub!( %r|

    \z|, '' ) html.empty? ? nil : html end def get_categories return [] unless @subtitle cat = /^(\[([^\[]+?)\])+/.match(@subtitle).to_a[0] return [] unless cat cat.scan(/\[(.*?)\]/).collect do |c| c[0].split(/,/) end.flatten end def strip_subtitle return nil unless @subtitle r = @subtitle.sub(/^(\[[^\[]+?\])+\s*/,'') if r == "" nil else r end end end class WikiDiary def initialize( date, title, body, modified = Time.now ) init_diary replace( date, title, body ) @last_modified = modified end def style 'Wiki' end def append( body, author = nil ) # body1 is a section starts without subtitle. # body2 are sections starts with subtitle. if /(.*?)(^![^!].*)/m =~ body body1 = $1 body2 = $2 elsif /^![^!]/ !~ body body1 = body body2 = '' else body1 = '' body2 = body end unless body1.empty? current_section = @sections.pop if current_section then body1 = "#{current_section.to_src.sub( /\n+\Z/, '' )}\n\n#{body1}" end @sections << WikiSection::new( body1, author ) end section = nil body2.each_line do |l| case l when /^\![^!]/ @sections << WikiSection::new( section, author ) if section section = l else section = '' unless section section << l end end @sections << WikiSection::new( section, author ) if section @last_modified = Time.now self end def add_section(subtitle, body) @sections << WikiSection::new("! #{subtitle}\n#{body}") @sections.size end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/lib/tdiary/tasks.rb000066400000000000000000000001151362645730700174660ustar00rootroot00000000000000Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f } tdiary-core-5.1.1/lib/tdiary/tasks/000077500000000000000000000000001362645730700171445ustar00rootroot00000000000000tdiary-core-5.1.1/lib/tdiary/tasks/assets.rake000066400000000000000000000006521362645730700213150ustar00rootroot00000000000000namespace :assets do desc "copy assets files" task :copy do require 'fileutils' assets_path = File.dirname(__FILE__) + '/../../../public/assets' FileUtils.mkdir_p assets_path FileList['{js,theme}/*'].each do |file| FileUtils.cp_r(file, "#{assets_path}/#{Pathname.new(file).basename}") end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/auth.rake000066400000000000000000000012721362645730700207530ustar00rootroot00000000000000namespace :auth do namespace :password do desc "create password" task :create do require 'webrick/httpauth/htpasswd' puts 'create .htpasswd file' print 'Username: ' ARGV.replace([]) username = gets().chop print 'New password: ' system "stty -echo" password = $stdin.gets.chop puts print 'Re-type new password: ' password2 = $stdin.gets.chop puts system "stty echo" if password != password2 raise StandardError, 'password verification error' else htpasswd = WEBrick::HTTPAuth::Htpasswd.new('.htpasswd') htpasswd.set_passwd(nil, username, password) htpasswd.flush puts "Adding password for user #{username}" end end end end tdiary-core-5.1.1/lib/tdiary/tasks/db.rake000066400000000000000000000061621362645730700204020ustar00rootroot00000000000000namespace :db do desc "import database from file system" task :import do $:.unshift '.' require 'tdiary' cgi = CGI.new conf = TDiary::Config.new(cgi) base = TDiary::TDiaryBase.new(cgi, 'day.rhtml', conf) io = conf.io_class.new(base) io.load_styles Sequel.connect(conf.database_url) do |db| db.create_table :conf do String :body, :text => true end unless db.table_exists?(:conf) db[:conf].insert(:body => File.read(conf.data_path + 'tdiary.conf')) end yms = base.calendar yms.keys.sort.reverse_each do |year| yms[year.to_s].sort.reverse_each do |month| date = Time.local(year, month) io.transaction(date) do |diaries| Sequel.connect(conf.database_url) do |db| db.create_table :diaries do String :diary_id, :size => 8 String :year, :size => 4 String :month, :size => 2 String :day, :size => 2 String :title, :text => true String :body, :text => true String :style, :text => true Fixnum :last_modified TrueClass :visible primary_key :diary_id end unless db.table_exists?(:diaries) db.create_table :comments do String :diary_id, :size => 8 Fixnum :no String :name, :text => true String :mail, :text => true String :comment, :text => true Fixnum :last_modified TrueClass :visible primary_key [:diary_id, :no] end unless db.table_exists?(:comments) diaries.each do |d, diary| no = 0 if /(\d\d\d\d)(\d\d)(\d\d)/ =~ d year = $1 month = $2 day = $3 end entry = db[:diaries].filter(:year => year, :month => month, :day => day, :diary_id => d) if entry.count > 0 entry.update(:title => diary.title, :last_modified => diary.last_modified.to_i, :style => diary.style, :visible => diary.visible?, :body => diary.to_src) else db[:diaries].insert(:year => year, :month => month, :day => day, :diary_id => d, :title => diary.title, :last_modified => diary.last_modified.to_i, :style => diary.style, :visible => diary.visible?, :body => diary.to_src) end diary.each_comment(diary.count_comments(true)) do |com| no += 1 comment = db[:comments].filter(:diary_id => d, :no => no) if comment.count > 0 comment.update(:name => com.name, :mail => com.mail, :last_modified => com.date.to_i, :visible => com.visible?, :comment => com.body) else db[:comments].insert(:name => com.name, :mail => com.mail, :last_modified => com.date.to_i, :visible => com.visible?, :comment => com.body, :diary_id => date, :no => no) end end end end end end end end desc "drop database" task :drop do conf = TDiary::Config.new(CGI.new) Sequel.connect(conf.database_url || ENV['DATABASE_URL']) do |db| db.drop_table :diaries, :comments, :conf end end end if defined?(Sequel) # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/doc.rake000066400000000000000000000014551362645730700205620ustar00rootroot00000000000000desc "generate document files" task :doc do require 'redcarpet' require 'pathname' FileList['doc/*.md'].each do |md| target = Pathname.new(md) header = <<-HEADER #{target.basename('.md')} HEADER footer = <<-FOOTER FOOTER html = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true).render(File.open(md).read) open(target.sub(/\.md\z/, '.html'), 'w') {|f| f.write(header + html + footer)} end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/heroku.rake000066400000000000000000000014511362645730700213060ustar00rootroot00000000000000namespace :heroku do file 'tdiary.conf' => ['tdiary.conf.heroku'] do |t| FileUtils.cp(t.prerequisites.first, t.name) end file '.htpasswd' do Rake::Task["auth:password:create"].invoke end task :install => ['.htpasswd', 'tdiary.conf'] do |t| sh "git checkout -b deploy" sh "git add -f #{t.prerequisites.join(' ')}" sh "git commit -m 'deploy'" sh "git push heroku deploy:master" # FIXME: heroku command does not work in rake env # sh "heroku run rake db:create" end task :update do # sh "git pull origin master:deploy" # sh "git push heroku deploy:master" raise NotImplementedError end task :clean do sh "git checkout master" sh "git branch -D deploy" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/jasmine.rake000066400000000000000000000004721362645730700214410ustar00rootroot00000000000000begin require 'jasmine' load 'jasmine/tasks/jasmine.rake' rescue LoadError task :jasmine do abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/mongodb.rake000066400000000000000000000005061362645730700214360ustar00rootroot00000000000000namespace :mongodb do desc "make index into mongoDB" task :index do require 'erb' require 'tdiary' conf = TDiary::Config.new TDiary::DiaryContainer.new(conf, '2015', '01') TDiary::IO::MongoDB::Diary.create_indexes TDiary::IO::MongoDB::Comment.create_indexes TDiary::IO::MongoDB::Plugin.create_indexes end end tdiary-core-5.1.1/lib/tdiary/tasks/rdoc.rake000066400000000000000000000010401362645730700207320ustar00rootroot00000000000000desc "generate rdoc files" task :rdoc do root_dir = File.dirname(__FILE__) dirlist = Dir.glob(root_dir + "/rdoc/**/").sort { |a,b| b.split('/').size <=> a.split('/').size } dirlist.each {|d| Dir.foreach(d) {|f| File::delete(d + f) if !(/\.+$/ =~ f) } Dir.rmdir(d) } `cd #{root_dir} && rdoc --all --charset=UTF8 --op=rdoc --inline-source README ChangeLog index.rb update.rb tdiary.rb tdiary/* misc/* plugin/*` end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/release.rake000066400000000000000000000107631362645730700214370ustar00rootroot00000000000000# # Ralefile for releasing tDiary. # begin require 'octokit' STABLE = `git tag | sort -r -V | head -1`.chomp REPOS = %w(tdiary-core tdiary-theme tdiary-blogkit tdiary-contrib) DEST_DIR = "/var/www/tdiary.org/htdocs/download" TARBALLS = [] def fetch_files( repo ) Dir.chdir("tmp") do rm_rf repo rescue true sh "git clone https://github.com/tdiary/#{repo}.git #{repo}" end end def make_tarball( repo, version = nil ) suffix = version ? "-#{version}" : '-snapshot' dest = "#{repo == 'tdiary-core' ? 'tdiary' : repo}#{suffix}" if version then Dir.chdir repo do sh "git checkout #{version}" end end rm_rf "#{repo}/.git" sh "find #{repo} -type f | xargs chmod 644" sh "find #{repo} -type d | xargs chmod 755" if repo == 'tdiary-core' then Dir.chdir 'tdiary-core' do sh "chmod +x index.rb index.fcgi update.rb update.fcgi" sh 'rake doc' Bundler.with_clean_env do sh "bundle --path .bundle --without rack:development:test" end # reduce filesize Dir.glob('.bundle/ruby/*/cache/*').each do |file| # cached gem file rm_rf file end Dir.glob('.bundle/ruby/*/gems/*/*/').each do |dir| # spec, fixtures etc.. rm_rf dir unless File.basename(dir).match(/lib|data/) end Dir.chdir '.bundle/ruby' do versions = %w(2.4.0 2.5.0 2.6.0 2.7.0) current = `ls`.chomp versions.each {|version| FileUtils.cp_r current, version unless current == version } FileUtils.rm_rf current unless versions.member?(current) end Dir.chdir 'misc/lib' do sh 'gem unpack bundler' end end end mv repo, dest sh "tar zcf #{dest}.tar.gz --format=posix #{dest}" mv dest, repo TARBALLS << "#{dest}.tar.gz" end def make_full_package(version = nil) suffix = version ? "-#{version}" : '-snapshot' Dir.chdir("tmp") do TARBALLS.clear REPOS.each do |repo| make_tarball( repo, version ) end Dir["tdiary-theme/*"].each do |d| mv d, "tdiary-core/theme/" rescue true end mv "tdiary-core", "tdiary#{suffix}" sh "tar zcf tdiary-full#{suffix}.tar.gz --format=posix tdiary#{suffix}" TARBALLS << "tdiary-full#{suffix}.tar.gz" rm_rf "tdiary#{suffix}" REPOS.each {|repo| rm_rf repo rescue true } end end # # https://developer.github.com/v3/repos/releases/#create-a-release # def create_github_release(version) name = "tDiary #{version.sub(/v/, '')}" puts "creating github release #{version}, #{name}" begin Octokit.create_release('tdiary/tdiary-core', version, name: name) rescue Octokit::ClientError => e STDERR.puts e end end # # https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name # def find_or_create_github_release(version) begin release = Octokit.release_for_tag('tdiary/tdiary-core', version) rescue Octokit::NotFound release = create_github_release(version) end release end # # https://developer.github.com/v3/repos/releases/#upload-a-release-asset # def upload_github_asset(release, file) puts "updating file to github: #{file}" begin Octokit.upload_asset(release.url, file) rescue Octokit::ClientError => e STDERR.puts e end end # # https://developer.github.com/v3/#authentication # def login_github unless ENV['GITHUB_ACCESS_TOKEN'] raise "Missing $GITHUB_ACCESS_TOKEN environment.\nSee: https://help.github.com/articles/creating-an-access-token-for-command-line-use/" end Octokit.configure {|c| c.access_token = ENV['GITHUB_ACCESS_TOKEN'] } Octokit.auto_paginate = true end namespace :package do desc 'fetching all files from GitHub.' task :fetch do REPOS.each{|r| fetch_files(r) } end desc 'releasing all files' task :release do login_github Dir.chdir("tmp") do TARBALLS = Dir["*.tar.gz"] if TARBALLS.empty? TARBALLS.each do |tgz| # TODO: v5.0.0.20160501 形式のバージョンに対応させる version = tgz.match(/v?\d\.\d\.\d/).to_a[0] next unless version release = find_or_create_github_release(version) upload_github_asset(release, tgz) end end end desc 'making packages of snapshot.' task :snapshot => :fetch do make_full_package end desc 'making packages of stable.' task :stable => :fetch do make_full_package(STABLE) end desc 'cleanup all files.' task :clean do Dir.chdir("tmp") do REPOS.each {|repo| rm_rf repo rescue true } sh "rm *.tar.gz" rescue true end end end rescue LoadError end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/rspec.rake000066400000000000000000000014751362645730700211330ustar00rootroot00000000000000if defined? RSpec require 'rspec/core/rake_task' desc 'Run the code in spec' RSpec::Core::RakeTask.new(:spec) do |t| t.pattern = "spec/**/*_spec.rb" end namespace :spec do %w(core plugin acceptance).each do |dir| desc "Run the code examples in spec/#{dir}" RSpec::Core::RakeTask.new(dir.to_sym) do |t| t.pattern = "spec/#{dir}/**/*_spec.rb" end end namespace :acceptance do desc 'Run the code examples in spec/acceptance with cgi mode' task :cgi do ENV['TEST_MODE'] = 'webrick' Rake::Task["spec:acceptance"].invoke end end desc 'Displayed code coverage with SimpleCov' task :coverage do ENV['COVERAGE'] = 'simplecov' Rake::Task["spec"].invoke end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/tasks/server.rake000077500000000000000000000017361362645730700213300ustar00rootroot00000000000000# # server: script for running standalone tdiary cgi server. # # Copyright (C) 2008-2010, Kakutani Shintaro # You can redistribute it and/or modify it under GPL2 or any later version. task :server do $:.unshift File.expand_path('../../../', __FILE__) require 'tdiary' unless File.exist?(TDiary.root + '/tdiary.conf') FileUtils.cp_r(TDiary.root + '/spec/fixtures/tdiary.conf.webrick', TDiary.root + '/tdiary.conf', :verbose => false) end unless File.directory?(TDiary.root + '/tmp/data') FileUtils.mkdir_p(TDiary.root + '/tmp/data/log') File.open(TDiary.root + '/tmp/data/tdiary.conf', 'w') do |f| f.write "tdiary_version = \"#{TDIARY_VERSION}\"" end File.chmod(0644, TDiary.root + '/tmp/data/tdiary.conf') end opts = { :daemon => ENV['DAEMON'], :bind => ENV['BIND'] || '0.0.0.0', :port => ENV['PORT'] || 19292, :logger => $stderr, :access_log => $stderr, } TDiary::Server.run( opts ) end tdiary-core-5.1.1/lib/tdiary/tasks/test.rake000066400000000000000000000004321362645730700207660ustar00rootroot00000000000000if defined? Test::Unit require 'rake/testtask' Rake::TestTask.new do |t| t.libs << "test" t.test_files = FileList['test/**/*_test.rb'] t.verbose = true end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/version.rb000066400000000000000000000000451362645730700200300ustar00rootroot00000000000000module TDiary VERSION = '5.1.1' end tdiary-core-5.1.1/lib/tdiary/view.rb000066400000000000000000000244041362645730700173220ustar00rootroot00000000000000module TDiary # # class TDiaryView # base of view mode classes # class TDiaryView < TDiaryBase def initialize( cgi, rhtml, conf ) super unless referer_filter( @cgi.referer ) def @cgi.referer; nil; end end # save referer to latest if (!@conf.referer_day_only or (@cgi.params['date'][0] and @cgi.params['date'][0].length == 8)) and @cgi.referer then ym = latest_month @date = ym ? Time::local( ym[0], ym[1] ) : Time::now @io.transaction( @date ) do |diaries| @diaries = diaries dirty = DIRTY_NONE @diaries.keys.sort.reverse_each do |key| @diary = @diaries[key] break if @diary.visible? end if @diary then @diary.add_referer( @cgi.referer ) dirty = DIRTY_REFERER end dirty end @date = @diary.date if @diary end end def last_modified lm = Time::at( 0 ) @diaries.each_value do |diary| lmd = diary.last_modified lm = lmd if lm < lmd and diary.visible? end lm end protected def each_day @diaries.keys.sort.each do |date| diary = @diaries[date] next unless diary.visible? yield diary end end def latest_month result = nil calendar @years.keys.sort.reverse_each do |year| @years[year.to_s].sort.reverse_each do |month| result = [year, month] break end break end result end def oldest_month result = nil calendar @years.keys.sort.each do |year| @years[year.to_s].sort.each do |month| result = [year, month] break end break end result end private def load_filters return if @filters @filters = [] filter_path = @conf.filter_path || "{#{PATH},#{TDiary.server_root}}/tdiary/filter" Dir::glob( "#{filter_path}/*.rb" ).sort.each do |file| require file @filters << TDiary::Filter::const_get( "#{File::basename( file, '.rb' ).capitalize}Filter" )::new( @cgi, @conf ) end end def all_filters load_filters @filters + (load_plugins.sf_filters || []) end def comment_filter( diary, comment ) all_filters.each do |filter| return false unless filter.comment_filter( diary, comment ) break unless comment.visible? end true end def referer_filter( referer ) all_filters.each do |filter| return false unless filter.referer_filter( referer ) end true end end # # class TDiaryDay # show day mode view # class TDiaryDay < TDiaryView def initialize( cgi, rhtml, conf ) super begin # time is noon for easy to calc leap second. @date = Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] ) + 12*60*60 load( @date ) rescue ArgumentError, NameError raise TDiaryError, 'bad date' end @diary = nil if @diary and not @diary.visible? end def last_modified @diary ? @diary.last_modified : Time::at( 0 ) end def eval_rhtml( prefix = '' ) if not @diary and bot? raise NotFound else super(prefix) end end protected def load( date ) if not @diary or (@diary.date.dup + 12*60*60).gmtime.strftime( '%Y%m%d' ) != date.dup.gmtime.strftime( '%Y%m%d' ) then @io.transaction( date ) do |diaries| @diaries = diaries dirty = DIRTY_NONE @diary = self[date] if @diary and @cgi.referer then @diary.add_referer( @cgi.referer ) dirty = DIRTY_REFERER end dirty end else @diary = self[date] end end def cookie_name @cgi.cookies['tdiary'][0] or '' end def cookie_mail @cgi.cookies['tdiary'][1] or '' end end # # class TDiaryDayWithoutFilter # class TDiaryDayWithoutFilter < TDiaryDay def referer_filter(referer); end end # # class TDiaryComment # save a comment # class TDiaryComment < TDiaryDay def initialize( cgi, rhtml, conf ) super end protected def load( date ) @date = date @name = @cgi.params['name'][0] @mail = @cgi.params['mail'][0] @body = @cgi.params['body'][0] @name = @conf.to_native( @name ) @body = @conf.to_native( @body ) @comment = Comment::new( @name, @mail, @body ) dirty = DIRTY_NONE @io.transaction( @date ) do |diaries| @diaries = diaries @diary = self[@date] if @diary and comment_filter( @diary, @comment ) then @diary.add_comment( @comment ) dirty = DIRTY_COMMENT cookie_path = File::dirname( @cgi.script_name ) cookie_path += '/' if cookie_path !~ /\/$/ @cookies << CGI::Cookie::new( { 'name' => 'tdiary', 'value' => [@name,@mail], 'path' => cookie_path, 'expires' => Time::now.gmtime + 90*24*60*60 # 90days } ) @io.clear_cache( /(latest|#{@date.strftime( '%Y%m' )})/ ) else @comment = nil end dirty end end def do_eval_rhtml( prefix ) load_plugins @plugin.instance_eval { update_proc } if @comment if @conf.request.xhr? super else anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"] ) raise ForceRedirect::new( "#{@conf.index}#{anchor_str}#c#{'%02d' % @diary.count_comments( true )}" ) end end end # # class TDiaryMonthBase # base of TDiaryMonth and TDiaryNYear # class TDiaryMonthBase < TDiaryView def eval_rhtml( prefix = '' ) if @diaries.empty? and bot? raise NotFound else super(prefix) end end end # # class TDiaryMonth # show month mode view # class TDiaryMonth < TDiaryMonthBase def initialize( cgi, rhtml, conf ) super begin date = Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)$/ )[0] ) d1 = @date.dup.gmtime if @date d2 = date.dup.gmtime if not @date or d1.year != d2.year or d1.month != d2.month then @date = date @io.transaction( @date ) do |diaries| @diaries = diaries @diary = @diaries[@diaries.keys.sort.reverse[0]] DIRTY_NONE end end rescue ArgumentError, NameError raise TDiaryError, 'bad date' end end end # # class TDiaryNYear # show nyear mode view # class TDiaryNYear < TDiaryMonthBase def initialize(cgi, rhtml, conf) super @diaries = {} month, day = @cgi.params['date'][0].scan(/^(\d\d)(\d\d)$/)[0] nyear(month).each do |y, m| @date = Time::local(y, m) @io.transaction(@date) do |diaries| ymd = y + m + day @diaries[ymd] = diaries[ymd] if diaries[ymd] DIRTY_NONE end end end protected def nyear(month) r = [] calendar @years.keys.reverse_each do |year| r << [year, month] if @years[year].include? month end r end end # # class TDiaryMonthWithoutFilter # class TDiaryMonthWithoutFilter < TDiaryMonth def referer_filter(referer); end end # # class TDiaryLatest # show latest mode view # class TDiaryLatest < TDiaryView def initialize( cgi, rhtml, conf ) super if @cgi.params['date'][0] then ym = [@cgi.params['date'][0][0,4].to_i, @cgi.params['date'][0][4,2].to_i] @date = nil else ym = latest_month end unless @date then @date = ym ? Time::local( ym[0], ym[1] ) : Time::now @io.transaction( @date ) do |diaries| @diaries = diaries if @cgi.params['date'][0] then @diary = @diaries[@cgi.params['date'][0][0,8]] @date = @diary.date if @diary end unless @diary then @diaries.keys.sort.reverse_each do |d| diary = @diaries[d] if diary.visible? @diary = diary break end end @diary = @diaries[@diaries.keys.sort.reverse[0]] unless @diary @date = @diary.date if @diary end DIRTY_NONE end end if ym then # read +2 days for calc ndays.prev in count_diaries method limit = limit_size( @conf.latest_limit ) + 2 # read next month data until limit y = ym[0].to_i m = ym[1].to_i latest = latest_month diaries_tmp = {}.update( @diaries ) diaries_size = count_diaries_after( diaries_tmp ) while ( latest and diaries_size < limit ) date = if m == 12 then Time::local( y += 1, m = 1 ) else Time::local( y, m += 1 ) end break if date > Time::local( *latest ) @io.transaction( date ) do |diaries| diaries_tmp.update( diaries ) diaries_size = count_diaries_after( diaries_tmp ) DIRTY_NONE end end # read prev month data until limit y = ym[0].to_i m = ym[1].to_i oldest = oldest_month diaries_size = count_diaries_before( @diaries ) while ( oldest and diaries_size < limit ) date = if m == 1 then Time::local( y -= 1, m = 12 ) else Time::local( y, m -= 1 ) end break if date < Time::local( *oldest ) @io.transaction( date ) do |diaries| @diaries.update( diaries ) diaries_size = count_diaries_before( @diaries ) DIRTY_NONE end end end end def latest( limit = 5 ) start = start_date limit = limit_size( limit ) idx = 0 @diaries.keys.sort.reverse_each do |date| next if date > start diary = @diaries[date] next unless diary.visible? yield diary idx += 1 break if idx >= limit end end protected def count_diaries_after( diaries ) start = start_date limit = limit_size( @conf.latest_limit ) diaries_size = 0 continue_exist = true diaries.keys.sort.each do |date| if diaries[date].visible? and date > start then continue_exist = true if diaries_size < limit @conf['ndays.next'] = date if diaries_size < limit diaries_size += 1 end end @conf['ndays.next'] = nil unless continue_exist diaries_size end def count_diaries_before( diaries ) start = start_date limit = limit_size( @conf.latest_limit ) diaries_size = 0 continue_exist = false diaries.keys.sort.reverse_each do |date| if diaries[date].visible? and date <= start then continue_exist = true if diaries_size >= limit @conf['ndays.prev'] = date if diaries_size <= limit diaries_size += 1 end end @conf['ndays.prev'] = nil unless continue_exist diaries_size end def start_date if @cgi.params['date'][0] then @cgi.params['date'][0][0,8] else '99999999' # max of date string end end def limit_size( default_limit ) if @cgi.params['date'][0] then date = @cgi.params['date'][0] limit = date[9,date.length-9].to_i limit = 30 if limit > 30 limit else default_limit end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/lib/tdiary/view_helper.rb000066400000000000000000000004171362645730700206570ustar00rootroot00000000000000module TDiary module ViewHelper def bot? @conf.bot =~ @cgi.user_agent end def base_url if @conf.options['base_url'] && @conf.options['base_url'].length > 0 @conf.options['base_url'] else @cgi.base_url end end end end tdiary-core-5.1.1/misc/000077500000000000000000000000001362645730700147105ustar00rootroot00000000000000tdiary-core-5.1.1/misc/convert2.rb000077500000000000000000000053401362645730700170040ustar00rootroot00000000000000#!/usr/bin/env ruby # # convert2: convert diary data file format tDiary1 to tDiary2. # # Copyright (C) 2001,2002, All right reserved by TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. =begin How to usage ruby convert2.rb [-p ] [-c ] -p : tDiaryのインストールパス。未指定時はカレントディレクトリ 例: -p /usr/local/tdiary -c : tdiary.confが存在するパス。未指定時はカレントディレクトリ 例: -c /home/hoge/public_html/diary =end =begin ChangeLog 2002-10-08 TADA Tadashi * for tDiary 1.5.0.20021003. 2002-08-16 TADA Tadashi * follow new IO classes specification. 2002-07-25 TADA Tadashi * display progress. 2002-07-23 TADA Tadashi * fix some bugs. 2002-05-30 TADA Tadashi * created. =end def usage puts "convert2: convert diary data file format tDiary1 to tDiary2." puts "usage: ruby convert2.rb [-p ] [-c ]" exit end require 'getoptlong' parser = GetoptLong::new tdiary_path = '.' tdiary_conf = nil parser.set_options( ['--path', '-p', GetoptLong::REQUIRED_ARGUMENT], ['--conf', '-c', GetoptLong::REQUIRED_ARGUMENT] ) begin parser.each do |opt, arg| case opt when '--path' tdiary_path = arg when '--conf' tdiary_conf = arg else usage end end rescue usage end tdiary_conf = tdiary_path unless tdiary_conf Dir::chdir( tdiary_conf ) begin ARGV << '' # dummy argument against cgi.rb offline mode. $:.unshift tdiary_path require "#{tdiary_path}/tdiary" rescue LoadError $stderr.puts 'convert.rb: cannot load tdiary.rb. try -p option.' exit end module TDiary class TDiaryConvert2 < TDiaryBase def initialize cgi = CGI.new super( cgi, 'day.rhtml', Config::new(cgi) ) require "#{PATH}/tdiary/pstoreio" @io_old = PStoreIO::new( self ) @years = @io_old.calendar @years.keys.sort.each do |year| @years[year.to_s].sort.each do |month| puts "#{year}-#{month}" date = Time::local( year.to_i, month.to_i ) @io_old.transaction( date ) do |diaries| @diaries = diaries false end require 'tdiary/io/default' IO::Default::new( self ).transaction( date ) do |diaries| diaries.update( @diaries ) TDiaryBase::DIRTY_DIARY | TDiaryBase::DIRTY_COMMENT | TDiaryBase::DIRTY_REFERER end clear_parser_cache( date ) end end end protected def cookie_name '' end def cookie_mail '' end end end TDiary::TDiaryConvert2::new # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/docker-devel/000077500000000000000000000000001362645730700172545ustar00rootroot00000000000000tdiary-core-5.1.1/misc/docker-devel/Dockerfile000066400000000000000000000002521362645730700212450ustar00rootroot00000000000000FROM ruby:2.5 LABEL maintainer "@tdtds " RUN mkdir -p /usr/src/app WORKDIR /usr/src COPY [ "run-app.sh", "/usr/src/" ] EXPOSE 9292 CMD "/usr/src/run-app.sh" tdiary-core-5.1.1/misc/docker-devel/README.md000066400000000000000000000005671362645730700205430ustar00rootroot00000000000000# Docker image for tdiary development ## how to build ``` % docker build -t tdiary-devel misc/docker-devel ``` ## how to run ``` % docker run -v $(pwd):/usr/src/app -p 9292:9292 -it --rm tdiary-devel ``` or debugging `contrib` in the parent directory: ``` % docker run -v $(pwd):/usr/src/app -v $(pwd)/../contrib:/usr/src/contrib -p 9292:9292 -it --rm tdiary-devel ``` tdiary-core-5.1.1/misc/docker-devel/run-app.sh000077500000000000000000000004241362645730700211750ustar00rootroot00000000000000#!/bin/bash cd /usr/src/app if [ ! -f tdiary.conf ]; then cp tdiary.conf.beginner tdiary.conf fi bundle --path=vendor/bundle --jobs=4 --retry=3 bundle exec rake assets:copy if [ ! -f .htpasswd ]; then bundle exec bin/tdiary htpasswd fi bundle exec rackup -o 0.0.0.0 -p 9292 tdiary-core-5.1.1/misc/filter/000077500000000000000000000000001362645730700161755ustar00rootroot00000000000000tdiary-core-5.1.1/misc/filter/antispamservice.rb000066400000000000000000000054711362645730700217260ustar00rootroot00000000000000# # antispamservice.rb: tDiary comment spam filter using Antispam API $Revision: 1.4 $ # # usage: # 1) Get your free API Key from: # a. Akismet API from http://akismet.com/personal/ # 2) Set the API key and enable filter in your tdiary.conf. See below. # @options['antispam.service'] = 'rest.akismet.com' # @options['antispam.key'] = '1234567890ab' # # Copyright (C) TADA Tadashi 2007. # Modified by SHIBATA Hiroshi 2008. # Distributed under GPL2 or any later version. # require 'net/http' require 'uri' module TDiary::Filter class AntispamserviceFilter < Filter def comment_filter( diary, comment ) @antispam_service_list = { # Service => ServiceHost 'Akismet' => 'rest.akismet.com', } host = @antispam_service_list[@conf['antispam.service']] return true unless (host || '' ).length > 0 debug("#{host}") key = @conf['antispam.key'] return true unless (key || '' ).length > 0 blog = @conf.index.dup blog[0, 0] = base_url unless %r|^https?://|i =~ blog blog.gsub!( %r|/\./|, '/' ) permalink = "#{blog}?date=#{diary.date.strftime('%Y%m%d')}" if comment.name == 'TrackBack' then comment_type = 'trackback' comment_author_url = comment.body.split[0] else comment_type = 'comment' comment_author_url = nil end uri = URI::parse( "http://#{key}.#{host}/1.1/comment-check" ) data = "blog=#{blog}" data << "&user_ip=#{@cgi.remote_addr}" data << "&user_agent=#{u @cgi.user_agent}" data << "&permalink=#{permalink}" data << "&comment_type=#{comment_type}" data << "&comment_author=#{u comment.name}" data << "&comment_author_email=#{u comment.mail}" data << "&comment_author_url=#{u comment_author_url}" if comment_author_url data << "&comment_content=#{u comment.body}" unless check( uri, data ) then debug( "antispam judged spam." ) comment.show = false # # NOTICE: force hide TSUKKOMIs. because Antispam judge # Japanese TSUKKOMI to spam sometime. # return true # (@conf['spamfilter.filter_mode'] || true) end debug( "antispam judged ham.", DEBUG_FULL ) return true end def check( uri, data ) header = { 'User-Agent' => "tDiary/#{TDIARY_VERSION} | Antispam filter/$Revision: 1.4 $", 'Content-Type' => 'application/x-www-form-urlencoded' } debug( "antispam request: #{data}", DEBUG_FULL ) proxy_h, proxy_p = (@conf['proxy'] || '').split( /:/ ) res = ::Net::HTTP::Proxy( proxy_h, proxy_p ).start( uri.host, uri.port ) do |http| http.post( uri.path, data, header ) end debug( "antispam result: #{res.body}", DEBUG_FULL ) return (res.body != 'true') end def u( str ) CGI::escape( str ) end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/filter/limitdays.rb000066400000000000000000000016171362645730700205260ustar00rootroot00000000000000# # limitdays.rb: # # Copyright (C) SHIBATA Hiroshi 2008. # Distributed under GPL2 or any later version. # module TDiary::Filter class LimitdaysFilter < Filter def comment_filter( diary, comment ) if @conf.options.include?('spamfilter.date_limit') && @conf.options['spamfilter.date_limit'] && /\A\d+\z/ =~ @conf.options['spamfilter.date_limit'].to_s @date_limit = @conf.options['spamfilter.date_limit'].to_s.to_i else @date_limit = nil end if @date_limit now = Time.now today = Time.local(now.year, now.month, now.day) limit = today - 24 * 60 * 60 * @date_limit if diary.date < limit debug( "too old: #{diary.date} (limit >= #{limit})" ) comment.show = false return false end end return true end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/filter/linkcheck.rb000066400000000000000000000040111362645730700204510ustar00rootroot00000000000000# # linkcheck.rb: tDiary filter for checking link to my site in TrackBack source site. # # specification: # * if source site has no URI of my site of top page, it's spam! # * reading only top of 100KB of source site. # * no response over 10 sec, it's mybe spam. # # Copyright (C) 2007 by TADA Tadashi # Distributed under GPL2 or any later version. # require 'open-uri' require 'timeout' module TDiary::Filter class LinkcheckFilter < Filter def initialize( *args ) super( *args ) @filter_mode = @conf['spamfilter.filter_mode'] @filter_mode = true if @filter_mode == nil end def comment_filter( diary, comment ) if @conf['spamfilter.linkcheck'] == 0 then debug( "No linkcheck to TrackBacks.", DEBUG_FULL ) return true end # check only TrackBack return true unless comment.name == 'TrackBack' dest_uri = @conf.index.dup dest_uri[0, 0] = base_url if %r|^https?://|i !~ @conf.index dest_uri.gsub!( %r|/\./|, '/' ) # TrackBack URI is the 1st line of comment.body. src_uri, = comment.body.split( /\n/ ) unless %r|^https?://|i =~ src_uri then debug( "TrackBack has bad source URI." ) comment.show = false return @filter_mode end if src_uri.index( dest_uri ) == 0 then debug( "TrackBack was sent to myself.", DEBUG_FULL ) return true end begin Timeout::timeout( 10 ) do open( src_uri ) do |f| if f.read( 100 * 1024 ).include?( dest_uri ) then debug( "TrackBack has links to me.", DEBUG_FULL ) return true else debug( "TrackBack dose not have links to me." ) comment.show = false return @filter_mode end end end rescue Timeout::Error debug( "TrackBack source was no response." ) comment.show = false return @filter_mode rescue debug( "Cannot access to TrackBack source (#{$!})." ) comment.show = false return @filter_mode end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/filter/plugin/000077500000000000000000000000001362645730700174735ustar00rootroot00000000000000tdiary-core-5.1.1/misc/filter/plugin/antispamservice.rb000066400000000000000000000041421362645730700232160ustar00rootroot00000000000000# # antispamservice.rb: tDiary comment spam filter using API setup plugin. $Revision: 1.3 $ # # Copyright (C) TADA Tadashi 2007. # Modified by SHIBATA Hiroshi 2008. # Distributed under GPL2 or any later version. # require 'net/http' require 'uri' @antispam_service_list = { # Service => ServiceHost 'Akismet' => 'rest.akismet.com', } add_conf_proc( 'antispamservice', @antispam_label_conf, 'security' ) do antispam_conf_proc end def antispam_conf_proc verify = true if @mode == 'saveconf' then @conf['antispam.service'] = @cgi.params['antispam.service'][0] @conf['antispam.key'] = @cgi.params['antispam.key'][0] if (@conf['antispam.key'] || '').length > 0 then verify = antispam_verify_key?(@conf['antispam.service'], @conf['antispam.key'] ) end end result = <<-HTML

    #{@antispam_desc}

    #{@antispam_label_service}

    HTML options = '' @antispam_service_list.each_key do |key| options << %Q|\n| end result << <<-HTML

    #{@antispam_label_key}

    HTML unless verify then result << %Q[

    #{@antispam_warn_key}

    ] end result << <<-HTML

    #{@antispam_desc_key}:

    HTML end def antispam_verify_key?( host, key ) uri = URI::parse( "http://#{@antispam_service_list[host]}/1.1/verify-key") blog = @conf.index.dup blog[0, 0] = base_url unless %r|^https?://|i =~ blog blog.gsub!( %r|/\./|, '/' ) data = "key=#{key}&blog=#{blog}" header = { 'User-Agent' => "tDiary/#{TDIARY_VERSION} | Antispam filter", 'Content-Type' => 'application/x-www-form-urlencoded' } proxy_h, proxy_p = (@conf['proxy'] || '').split( /:/ ) res = ::Net::HTTP::Proxy( proxy_h, proxy_p ).start( uri.host, uri.port ) do |http| http.post( uri.path, data, header ) end return (res.body == 'valid') end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/filter/plugin/en/000077500000000000000000000000001362645730700200755ustar00rootroot00000000000000tdiary-core-5.1.1/misc/filter/plugin/en/antispamservice.rb000066400000000000000000000010651362645730700236210ustar00rootroot00000000000000# # en/antispamservice.rb: English resource of Antispam filter setup plugin. $Revision: 1.2 $ # @antispam_label_conf = 'Antispam service filter' @antispam_desc = 'Antispam service filter is a filter using WebService API. If you want to use this filter, you have to get API Key from your selected service.' @antispam_label_service = 'Select Antispam Service' @antispam_label_key = 'API Key' @antispam_desc_key = 'API Key' @antispam_warn_key = 'Invalid API Key.' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/filter/plugin/ja/000077500000000000000000000000001362645730700200655ustar00rootroot00000000000000tdiary-core-5.1.1/misc/filter/plugin/ja/antispamservice.rb000066400000000000000000000015141362645730700236100ustar00rootroot00000000000000# # ja/antispamservice.rb: Japanese resource of Antispam filter setup plugin. $Revision: 1.2 $ # @antispam_label_conf = 'Antispamサービス フィルタ' @antispam_desc = 'Antispamサービス フィルタは、APIとして提供されるspam判定サービスを使って、ツッコミやTrackBackのspamを排除するフィルタです。このサービスを利用するには、使用するサービスのAPI Keyを取得して、以下に設定する必要があります。' @antispam_label_service = '使用するspam判定サービスの選択' @antispam_label_key = 'API Key' @antispam_desc_key = 'API Key' @antispam_warn_key = 'API Keyが正しくありません。サービスの提供元によって拒絶されました。' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/lib/000077500000000000000000000000001362645730700154565ustar00rootroot00000000000000tdiary-core-5.1.1/misc/lib/README000066400000000000000000000001651362645730700163400ustar00rootroot00000000000000This directory is for libraries: * for compatibility with ruby 1.8 and 1.9. * for patching about charctor encoding. tdiary-core-5.1.1/misc/lib/compatible.rb000066400000000000000000000000371362645730700201220ustar00rootroot00000000000000# move to tdiary/compatible.rb tdiary-core-5.1.1/misc/lib/fcgi_patch.rb000066400000000000000000000041761362645730700201020ustar00rootroot00000000000000=begin Patched version of FCGI::each_cgi from fcgi-0.8.8. * if encoding error happens with UTF-8, try Shift_JIS. Original copyright notices: fastcgi.rb Copyright (C) 2001 Eli Green fcgi.rb Copyright (C) 2002-2003 MoonWolf fcgi.rb Copyright (C) 2004 Minero Aoki Patch written by: Copyright (C) 2011 Kazuhiko =end class FCGI def self::each_cgi(*args) require 'cgi' eval(<<-EOS,TOPLEVEL_BINDING) class CGI public :env_table def self::remove_params if (const_defined?(:CGI_PARAMS)) remove_const(:CGI_PARAMS) remove_const(:CGI_COOKIES) end end end # ::CGI class class FCGI class CGI < ::CGI def initialize(request, *args) ::CGI.remove_params @request = request # PATCH BEGIN : if encoding error happens with UTF-8, try # Shift_JIS. encoding_error = {} super(*(args+[:accept_charset => "UTF-8"])) do |name, value| encoding_error[name] = value end params = @params unless encoding_error.empty? super(*(args+[:accept_charset => "Shift_JIS"])) @params = params end # PATCH END : if encoding error happens with UTF-8, try # Shift_JIS. @args = *args end def args @args end def env_table @request.env end def stdinput @request.in end def stdoutput @request.out end end # FCGI::CGI class end # FCGI class EOS if FCGI::is_cgi? yield ::CGI.new(*args) else FCGI::each {|request| $stdout, $stderr = request.out, request.err yield CGI.new(request, *args) request.finish } end end end # The following indentation rule is not same as tDiary's by intention. # It is same as the original (fcgi-0.8.8/lib/fcgi.rb) so that we can # easily see the difference by diff command. # Local Variables: # mode: ruby # indent-tabs-mode: nil # ruby-indent-level: 2 # End: tdiary-core-5.1.1/misc/migrate.rb000066400000000000000000000074771362645730700167040ustar00rootroot00000000000000#!/usr/bin/env ruby # # migrate.rb $Revision: 1.2 $ # # Copyright (C) 2001-2003, TADA Tadashi # Copyright (C) 2007, Kazuhiko # You can redistribute it and/or modify it under GPL2 or any later version. # BEGIN { $stdout.binmode } require "fileutils" require "pstore" begin if FileTest::symlink?( __FILE__ ) then org_path = File::dirname( File::readlink( __FILE__ ) ) else org_path = File::dirname( __FILE__ ) end $:.unshift( org_path ) require 'tdiary' class TDiary::MigrateConfig < TDiary::Config include ERB::Util def load_cgi_conf raise TDiaryError, 'No @data_path variable.' unless @data_path @data_path += '/' if /\/$/ !~ @data_path raise TDiaryError, 'Do not set @data_path as same as tDiary system directory.' if @data_path == "#{TDiary::PATH}/" # convert tdiary.conf in @data_path conf_path = "#{@data_path}tdiary.conf" conf = convert( File::open( conf_path ){|f| f.read } ) conf.gsub!(/(\\[0-9]{3})+/) do |str| convert(eval(%Q["#{$&}"])).dump[1...-1] end File::open( conf_path, 'w' ) do |o| o.print conf end # convert diary data and comment data Dir["#{@data_path}[0-9][0-9][0-9][0-9]/??????.td[2c]"].each do |file| convert_file(file) end # convert pstore cache files dir = cache_path || "#{@data_path}cache" %w(makerss.cache recent_comments recent_trackbacks tlink/tlink.dat).each do |e| convert_pstore("#{dir}/#{e}") if File.exist?("#{dir}/#{e}") end Dir["#{dir}/disp_referrer2.d/*"].each do |file| convert_pstore(file) end Dir["#{@data_path}category/*"].each do |file| convert_pstore(file) end # rename category cache files Dir["#{@data_path}category/*"].each do |file| dirname, basename = File.split(file) new_basename = u(convert(CGI::unescape(basename))) FileUtils.mv(file, File.join(dirname, new_basename)) unless basename == new_basename end # remove ruby/erb cache files Dir["#{dir}/*.rb"].each{|f| FileUtils.rm_f(f)} Dir["#{dir}/*.parser"].each{|f| FileUtils.rm_f(f)} end def convert_pstore(file) db = PStore.new(file) begin roots = db.transaction{ db.roots } rescue ArgumentError if /\Aundefined class\/module (.+?)(::)?\z/ =~ $!.message klass = $1 if /EmptdiaryString\z/ =~ klass eval("class ::#{klass} < String; end") else eval("class ::#{klass}; end") end retry end end db.transaction do roots.each do |root| convert_element(db[root]) end end end def convert_element(data) case data when Hash, Array data.each_with_index do |e, i| if String === e data[i] = convert(e) else convert_element(e) end end else data.instance_variables.each do |e| var = data.instance_variable_get(e) if String === var data.instance_variable_set(e, convert(var)) else convert_element(var) end end end end def convert_file(file) body = convert( File::open( file ){|f| f.read} ) File::open( file, 'w' ) do |o| o.print body end end def convert(str) str.class.new(to_native(str, 'EUC-JP')) end end @cgi = CGI::new TDiary::MigrateConfig::new(@cgi) print @cgi.header( 'status' => '200 OK', 'type' => 'text/html' ) puts "

    Migration completed.

    " puts "

    Do not forget to remove migrate.rb.

    " rescue Exception if @cgi then print @cgi.header( 'status' => '500 Internal Server Error', 'type' => 'text/html' ) else print "Status: 500 Internal Server Error\n" print "Content-Type: text/html\n\n" end puts "

    500 Internal Server Error

    " puts "
    "
    	puts CGI::escapeHTML( "#{$!} (#{$!.class})" )
    	puts ""
    	puts CGI::escapeHTML( $@.join( "\n" ) )
    	puts "
    " puts "
    #{' ' * 500}
    " end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/paas/000077500000000000000000000000001362645730700156345ustar00rootroot00000000000000tdiary-core-5.1.1/misc/paas/heroku/000077500000000000000000000000001362645730700171315ustar00rootroot00000000000000tdiary-core-5.1.1/misc/paas/heroku/Gemfile.local000066400000000000000000000005031362645730700215130ustar00rootroot00000000000000ruby '~> 2.7.0' gem 'puma', require: false gem 'tdiary-io-mongodb', git: 'https://github.com/tdiary/tdiary-io-mongodb.git' gem 'tdiary-contrib', git: 'https://github.com/tdiary/tdiary-contrib.git' gem 'tdiary-style-gfm' gem 'tdiary-style-rd' gem 'omniauth' gem 'omniauth-twitter' gem 'dalli' gem 'memcachier' gem 'octokit' tdiary-core-5.1.1/misc/paas/heroku/Gemfile.lock000066400000000000000000000120451362645730700213550ustar00rootroot00000000000000GIT remote: https://github.com/tdiary/tdiary-contrib.git revision: 680043284b0872104b4298f66f0e9b18c1c0c28b specs: tdiary-contrib (5.1.0) pushbullet_ruby tdiary (~> 5.0) GIT remote: https://github.com/tdiary/tdiary-io-mongodb.git revision: 7c55edb93c9ef0faca7bddf49f292d0304e4a62f specs: tdiary-io-mongodb (5.0.4) hikidoc mongo (< 2.9.0) mongoid (~> 7.0) tdiary (>= 5.0) GEM remote: https://rubygems.org/ specs: activemodel (6.0.2.1) activesupport (= 6.0.2.1) activesupport (6.0.2.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) bson (4.8.0) byebug (11.1.1) capybara (3.31.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (~> 1.5) xpath (~> 3.2) childprocess (3.0.0) coderay (1.1.2) commonmarker (0.21.0) ruby-enum (~> 0.5) concurrent-ruby (1.1.6) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) term-ansicolor (~> 1.3) thor (>= 0.19.4, < 2.0) tins (~> 1.6) dalli (2.7.10) debase (0.2.4.1) debase-ruby_core_source (>= 0.10.2) debase-ruby_core_source (0.10.9) diff-lcs (1.3) docile (1.3.2) emot (0.0.4) thor faraday (0.17.3) multipart-post (>= 1.2, < 3) fastimage (2.1.7) hashie (3.6.0) hikidoc (0.1.0) i18n (1.8.2) concurrent-ruby (~> 1.0) idn-ruby (0.1.0) jasmine (2.99.0) jasmine-core (>= 2.99.0, < 3.0.0) phantomjs rack (>= 1.2.1) rake jasmine-core (2.99.2) json (2.3.0) launchy (2.5.0) addressable (~> 2.7) mail (2.7.1) mini_mime (>= 0.1.1) memcachier (0.0.2) method_source (0.9.2) mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2019.1009) mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.14.0) mongo (2.8.0) bson (>= 4.4.2, < 5.0.0) mongoid (7.0.5) activemodel (>= 5.1, < 6.1) mongo (>= 2.5.1, < 3.0.0) multipart-post (2.1.1) nio4r (2.5.2) nokogiri (1.10.8) mini_portile2 (~> 2.4.0) oauth (0.5.4) octokit (4.16.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) omniauth (1.9.0) hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack phantomjs (2.1.1.0) pit (0.0.7) power_assert (1.1.6) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) pry-byebug (3.8.0) byebug (~> 11.0) pry (~> 0.10) public_suffix (4.0.3) puma (4.3.2) nio4r (~> 2.0) pushbullet_ruby (1.1.4) faraday (>= 0.13.0, < 1.0) mime-types rack (2.2.2) rack-test (1.1.0) rack (>= 1.0, < 3) racksh (1.0.0) rack (>= 1.0) rack-test (>= 0.5) rake (13.0.1) rdtool (0.6.38) redcarpet (3.5.0) regexp_parser (1.7.0) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) rspec-core (3.9.1) rspec-support (~> 3.9.1) rspec-expectations (3.9.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-support (3.9.2) ruby-debug-ide (0.7.0) rake (>= 0.8.1) ruby-enum (0.7.2) i18n rubyzip (2.2.0) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) sequel (5.29.0) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) sqlite3 (1.4.2) sync (0.5.0) tdiary (5.1.0) bundler (>= 1.3, < 3.0) emot fastimage hikidoc mail rack rake thor tdiary-style-gfm (1.2.0) commonmarker emot twitter-text (>= 2.0) tdiary-style-rd (0.0.3) rdtool term-ansicolor (1.7.1) tins (~> 1.0) test-unit (3.3.5) power_assert thor (1.0.1) thread_safe (0.3.6) tins (1.24.1) sync twitter-text (3.0.0) idn-ruby unf (~> 0.1.0) tzinfo (1.2.6) thread_safe (~> 0.1) unf (0.1.4) unf_ext unf_ext (0.0.7.6) xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.2.2) PLATFORMS ruby DEPENDENCIES capybara coveralls (~> 0.8) dalli debase emot fastimage hikidoc jasmine (< 3) launchy mail memcachier mime-types octokit omniauth omniauth-twitter pit pry-byebug puma rack racksh rake redcarpet rspec ruby-debug-ide selenium-webdriver sequel simplecov sqlite3 tdiary-contrib! tdiary-io-mongodb! tdiary-style-gfm tdiary-style-rd test-unit RUBY VERSION ruby 2.7.0p0 BUNDLED WITH 2.1.4 tdiary-core-5.1.1/misc/paas/heroku/misc/000077500000000000000000000000001362645730700200645ustar00rootroot00000000000000tdiary-core-5.1.1/misc/paas/heroku/misc/plugin/000077500000000000000000000000001362645730700213625ustar00rootroot00000000000000tdiary-core-5.1.1/misc/paas/heroku/misc/plugin/system_update.rb000066400000000000000000000044351362645730700246030ustar00rootroot00000000000000# # system update plugin: automatic update tDiary usging GitHub and Heroku # # Copyright (C) 2015 by TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # def system_update token = @conf['system_update.token'] || '' user = @conf['system_update.user'] || '' raise StandardError.new('no token or user') if token.empty? || user.empty? begin @logger.info 'starting syatem update...' client = Octokit::Client.new(access_token: token) title = "system update on #{Time.now}" body = 'update by system_update plugin' pull_request = client.create_pull_request("#{user}/tdiary-core", 'master', 'tdiary:master', title, body) client.merge_pull_request("#{user}/tdiary-core", pull_request[:number]) @logger.info 'syatem update finished' rescue Octokit::UnprocessableEntity @logger.info(@error = 'no commits in upstream') end end add_conf_proc('system_update', 'システム更新', 'basic') do if @mode == 'saveconf' then @conf['system_update.token'] = @cgi.params['system_update.token'][0] @conf['system_update.user'] = @cgi.params['system_update.user'][0] begin system_update if @cgi.valid?('system_update.run') rescue @logger.error(@error = $!.message) end end r = <<-HTML

    tDiaryシステムの更新

    GitHubとHerokuの連携機能を使って、tDaiaryシステムの更新を行います。あらかじめtDiaryの公式リポジトリを自分のアカウントにforkし、そのリポジトリをHerokuのGitHub Deployに指定しておく必要があります。更新はmasterブランチを使って行われます。

    GitHub access token (40文字):

    GitHub user name:


    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/paas/heroku/tdiary.conf000066400000000000000000000056741362645730700213100ustar00rootroot00000000000000# # tdiary.conf for Heroku # require 'tempfile' @data_path = Dir.tmpdir @style = 'Wiki' @io_class = TDiary::IO::MongoDB @database_url = ENV['MONGODB_URI'] || ENV['MONGOLAB_URI'] @index = './' @update = 'update.rb' @logger = Logger.new($stderr) @accesskey_enabled = false @options['bot'] = [ '^BlogLines/', '^blogmap', 'MI[CK]AN/', '^NG/', '^samidare', '^TAMATEBAKO/' ] @options['apply_plugin'] = true @options['sp.path'] = ['misc/plugin'] @options['sp.selected'] = %w(amazon.rb append-css.rb calendar2.rb comment_ajax.rb comment_mail-smtp.rb dropdown_calendar.rb footnote.rb highlight.rb html_anchor.rb jdate.rb makerss.rb kw.rb my-ex.rb select-style.rb theme_online.rb ).join("\n") # dropdown_calendarの先頭に表示するテキスト # @options['dropdown_calendar.label'] = '過去の日記' @options['comment_mail.smtp_host'] = 'smtp.sendgrid.net' @options['comment_mail.smtp_port'] = 587 @options['comment_mail.user_name'] = ENV['SENDGRID_USERNAME'] @options['comment_mail.password'] = ENV['SENDGRID_PASSWORD'] @options['comment_mail.authentication'] = :plain @options['comment_mail.starttls'] = true @options['amazon.access_key'] = ENV['AMAZON_ACCESS_KEY'] @options['amazon.secret_key'] = ENV['AMAZON_SECRET_KEY'] @options['spamfilter.bad_comment_patts'] = "(href=|casino|gambling|betting|fastsearch\\.eu\\.com|ganzao|poker|holdem|hold.em|roulette|drug|tramadol|viagra|fioricet|oxycontin|biaxin|aldara|business cards|home depot|slot.?machine|insurance|getblog2|video-game|Good site|internet-all\\.com|deai|tdfms|comu2|omaha)\r\n" @options['spamfilter.bad_ip_addrs'] = "" @options['spamfilter.bad_mail_patts'] = "(mu@alloha\\.info|mumu2004@mail\\.com|zhongleibo|dfd@12\\.com|anonimous|aol\\.|yahoo\\.|google\\.|hotmail\\.|msn\\.|leroy\\.|ablare\\.|gmx\\.|lorazepam|\\.co$)" @options['spamfilter.bad_uri_patts'] = "" @options['spamfilter.bad_uri_patts_for_mails'] = false @options['spamfilter.debug_file'] = "" @options['spamfilter.debug_mode'] = false @options['spamfilter.filter_mode'] = true @options['spamfilter.max_uris'] = "2" @options['spamfilter.resolv_check'] = false @options['spamfilter.resolv_check_mode'] = false @options['spamlookup.domain.list'] = "bsb.spamlookup.net\r\nsc.surbl.org\r\nrbl.bulkfeeds.jp" @options['spamlookup.safe_domain.list'] = "search.yahoo.co.jp\r\nwww.google.com\r\nwww.google.co.jp\r\nsearch.msn.co.jp" @html_title = %Q[【日記のタイトル】] @header = <

    <%= @html_title %>

    HEADER @footer = <
    FOOTER @date_format = '%Y年%m月%d日' @section_anchor = '_' @comment_anchor = '_' @latest_limit = 10 @theme = 'default' @show_comment = true @comment_limit = 3 @show_referer = false @referer_day_only = true @hour_offset = 9 @show_nyear = true load_cgi_conf @style = @options2['style'] if @options2 && @options2['style'] tdiary-core-5.1.1/misc/plugin/000077500000000000000000000000001362645730700162065ustar00rootroot00000000000000tdiary-core-5.1.1/misc/plugin/ChangeLog.DO_NOT_UPDATE000066400000000000000000002435721362645730700220600ustar00rootroot00000000000000### CAUTION ### This ChangeLog has frozen. Add new log to /ChangeLog. 2010-04-13 TADA Tadashi * pre_wrap.rb: supported URLs in comments. 2010-04-07 TADA Tadashi * category.rb: fixed bug: div.conf -> div.category. 2010-04-06 TADA Tadashi * amazon.rb: set empty alt in img elements for better accessibility. * amazon.rb: make link around all elements. * amazon.rb: added a class "amazon-detail" for img element of isbn_detail. * amazon.rb, image.rb: deleted width/height attr on iPhone. * pre_wrap.rb: added new plugin. 2010-03-29 TADA Tadashi * categody.rb: moved script to header. * image.rb: moved script to header. 2010-03-27 TADA Tadashi * amazon.rb: added div element around description in isbn_detail. 2010-03-12 TADA Tadashi * gradient.rb, gradation.rb: fixed bug of splitting by character. 2010-02-17 TADA Tadashi * tb-send.rb: changed character encoding of some parameters. 2010-01-11 TADA Tadashi * ja/makerss.rb: fixed typo (ticket #186). 2009-12-24 TADA Tadashi * amazon.rb: supported EAN code. Thanks for yoshida. 2009-11-24 SHIBATA Hiroshi * navi_user.rb: obsolete. 2009-10-24 TADA Tadashi * highlight.rb: splitted exactly local jump URL. 2009-10-15 SHIBATA Hiroshi * makerss.rb : applied patch #178. thx sakai. 2009-09-07 Kazuhiko * makerss.rb (absolutify): fix a bug that raises an exception when replacing attributes don't appear. 2009-09-06 Kazuhiko * makerss.rb (absolutify): fix a bug that raises an exception when there are white spaces around '='. 2009-09-01 Kazuhiko * navi_user.rb, pb-show.rb, recent_list.rb, title_tag.rb: delete eval to define toplevel module, that is not required on Ruby 1.8 or later. * disp_referrer.rb: remove a code for Ruby 1.6 compatibility. 2009-09-01 TADA Tadashi * makerss.rb: deleteed eval for define toplevel module. 2009-08-26 zunda * makerss.rb: modified to cache regexps (Thanks to Kazuhiko) 2009-08-26 Kazuhiko * category.rb: use autoload for kconv library not to reduce performance for non-required case. make an Array explicitly not to depends on String#to_a, that is provided in compatible.rb. 2009-08-23 Kazuhiko * makerss.rb (absolutify): fix a bug that breaks html if new lines are included in a tag. 2009-08-22 sakai * category.rb: redirected to old encoding access to UTF-8's. 2009-08-19 zunda * makerss.rb: modified handle absolute URLs w/o host with query/fragment 2009-08-18 zunda * makerss.rb: modified to make absolute URLs in CDATA 2009-08-10 Kazuhiko * category.rb: code cleanup. use sort_by for better performance. 2009-08-09 Kazuhiko * navi_user.rb, recent_list.rb: create and use TDiaryMonthWithoutFilter instead of TDiaryMonth to reduce load_plugins() call. * navi_user.rb: a little optimisation to reduce Time#strftime call. 2009-08-06 Kazuhiko * disp_referrer.rb (DispRef2URL::parse_as_others): add encoding flag in regexp. 2009-08-03 TADA Tadashi * release 2.3.3. 2009-08-02 TADA Tadashi * amazon.rb: added option @conf['amazon.default_country']. 2009-08-02 Kazuhiko * en/category.rb, ja/category.rb, zh/category.rb: escape configuration sample's HTML. thanks to Motoya Kurotsu for providing a patch. 2009-07-31 TADA Tadashi * amazon.rb: added option @conf['amazon.endpoints'] for replacement default proxy server of amazon API. 2009-07-28 TADA Tadashi * footnote.rb: escaped HTML to marks. 2009-07-27 Kazuhiko * amazon/amazonimg.rb: change entry point of Amazon API to amazon-auth-proxy. special thanks to furyu-tei. support amazon.ca. 2009-07-22 TADA Tadashi * amazon.rb: supported request redirection by amazon-auth-proxy. 2009-07-21 Kazuhiko * recent_trackback3.rb: fix a typo. * amazon.rb: support amazon.ca. 2009-07-21 SHIBATA Hiroshi * recent_comment3.rb, recent_trackback3.rb: fix data path when data path is not empty. 2009-07-20 SHIBATA Hiroshi * recent_comment3.rb, recent_trackback3.rb, todo.rb: changed save data path. * todo.rb: use Time.parse instead of ParseDate. 2009-07-19 TADA Tadashi * amazon.rb: changed entry point of Amazon API to amazon-auth-proxy. special thanks to furyu-tei. 2009-07-07 Motoya Kurotsu * image.rb: fixed error on upload when PNG file header has 0x0a. 2009-06-10 TADA Tadashi * ja/disp_referrer.rb: added search engine: Bing, auOne. * ja/disp_referrer.rb: added some condition for some search engines: Google, Infoseek. 2009-05-17 zunda * disp_referrer.rb: added u option to regular expressions 2009-05-08 TADA Tadashi * release 2.3.2. 2009-05-07 TADA Tadashi * makerss.rb: without downcase character entities. thanks Masahiro Sakai. 2009-05-06 TADA Tadashi * my-sequel.rb: fixed redundant nested repeat operator in Regexp. * comment_mail_smtp.rb: fixed error on ruby 1.9.1. * counter.rb: fixed error when @conf['bot'] is nil. And fixed a wrong HTML tag. 2009-04-30 SHIBATA Hiroshi * amazon.rb: applied patch #151. thx arton. 2009-04-27 SHIBATA Hiroshi * ja/calendar2.rb: modified language resource, changed Array of String. 2009-04-26 SHIBATA Hiroshi * category.rb: applied patch #130. thx tamo. thx sugiyama. http://www.kde.ics.tut.ac.jp/~sugiyama/diary/20061127.html#p01 2009-03-30 SHIBATA Hiroshi * pingback/pb.rb, trackback/tb.rb, xmlrpc/xmlrpc.rb: replace defout to stdout. defout is obsolete. 2009-03-10 TADA Tadashi * todo.rb: changed WAVE DASH to TILDA. * squeeze.rb: changed name of global variable. 2009-02-26 TADA Tadashi * my-ex.rb: fixed warning of Regexp on ruby 1.9.1. 2009-02-25 TADA Tadashi * highlight.rb: suppressed Regexp warning on ruby 1.9.1. 2009-02-11 SHIBATA Hiroshi * category.rb, random_google.rb, speed_comment.rb, weather.rb: supported ruby 1.9.1 more. 2009-02-03 TADA Tadashi * amazon.rb: deleted duplicated author names. 2009-01-20 TADA Tadashi * category.rb: added user_agent and request_method into fake CGI class. 2008-12-26 TADA Tadashi * calendar2.rb, calendar3.rb: fixed bug on search mode. Thanks NT. 2008-12-15 TADA Tadashi * amazon.rb: added "Artist" to author elements. 2008-11-12 TADA Tadashi * tb-show.rb: added comment mode into no overriding TDiary::Comment class. 2008-11-07 TADA Tadashi * makerss.rb: fixed bad numeric entiries value (again). 2008-10-26 SHIBATA Hiroshi * recent_comment3.rb, */recent_comment3.rb: applied patch #128. thx tamo. 2008-10-26 SHIBATA Hiroshi * recent_comment.rb, */recent_comment.rb: fix #128. thx tamo. 2008-10-24 TADA Tadashi * amazon.rb: added "Creator" to author elements. 2008-10-19 TADA Tadashi * release 2.3.1. 2008-10-18 TADA Tadashi * navi_user.rb: added request_method to NaviUserCGI class. 2008-10-17 TADA Tadashi * highlight.rb: compared tag name case insensitive. 2008-09-10 KURODA Hiraku * highlight.rb: enable to work on XHTML mode. 2008-08-26 TADA Tadashi * recent_rss.rb: added a parameter 'show_modified'. 2008-08-20 TADA Tadashi * squeeze.rb: fixed #120, memory leak by nested loading. thanks KURODA Hiraku . * squeeze.rb: fixed #122, unsecure operation using with -p option. thanks KURODA Hiraku . * squeeze.rb: added --overwrite option. 2008-08-04 TADA Tadashi * category.rb: fixed #82, incompatible of white space of category. 2008-08-03 TADA Tadashi * titile_tag.rb: fixed a bug about no site name in the title. * highlight.rb: changed title format to as same as default. 2008-08-01 TADA Tadashi * squeeze.rb: inserted user_navi plugin into the footer. * navi_user.rb: added user_agent method into dummy CGI class. 2008-07-21 TADA Tadashi * makerss.rb: fixed error when subtitle was nil. 2008-07-21 SHIBATA Hiroshi * squeeze.rb: fix #117. thx Kazuhiko. 2008-07-11 TADA Tadashi * title_tag.rb: changed title format to start with day title. 2008-07-10 TADA Tadashi * category.rb: sorted categories in case-insensitive. 2008-07-05 SHIBATA Hiroshi * category.rb: raise 404 error when bot access to no existent diary. 2008-07-04 SHIBATA Hiroshi * counter.rb: fix indent. 2008-07-02 SHIBATA Hiroshi * squeeze.rb: changed module TDiary to TOPLEVEL. 2008-07-02 TADA Tadashi * makerss.rb: fixed over deleting category name from title. thanks for TAKAHASHI Tamotsu. 2008-06-18 SHIBATA Hiroshi * tlink.rb: convert to toutf8 instead of toeuc. 2008-06-18 SHIBATA Hiroshi * a.rb: add utf8 option. 2008-06-17 SHIBATA Hiroshi * title_tag.rb, ja/search_form.rb: convert to utf-8 instead of euc-jp. 2008-05-12 SHIBATA Hiroshi * navi_user.rb: fix indent. 2008-05-12 SHIBATA Hiroshi * makerss.rb: tabify. 2008-04-29 SHIBATA Hiroshi * category.rb: fixed #79. 2008-02-29 TADA Tadashi * release 2.2.1. 2008-02-28 TADA Tadashi * makerss.rb: fixed bad numeric entiries value. 2008-02-25 TADA Tadashi * makerss.rb: replaced character entities to numeric. 2008-01-24 TADA Tadashi * */hide-mail-field.rb: added notice to rewite TSUKKOMI information. 2008-01-23 TADA Tadashi * */makerss.rb: change some labels on edit page. 2008-01-19 zunda * weather.rb, */weather.rb: modified so that weather can be shown at right of title * weather.rb: modified to include default CSS 2008-01-16 zunda * */weather.rb: fixed escape of URL of NOAA 2008-01-16 zunda * weather.rb, */weather.rb: moved definition of surrounding tags to html_string methods 2008-01-15 zunda * */weather.rb: added included weather/condition and temperature into span 2008-01-14 SHIBATA Hiroshi * weather.rb: Hide output string in RSS feed. 2008-01-06 Kazuhiko * amazon.rb, amazon/amazonimg.rb: support multi-country amazon links. 2008-01-06 TADA Tadashi * makerss.rb: delete over escape of in each items. thanks for Ogawa KenIchi. 2008-01-05 akira yamada <akira at arika.org> * highlight.rb: escape backslash in diary title and delete white space from tail of subtitle. 2008-01-03 OGAWA KenIchi <kenichi at ice.email.ne.jp> * category.rb: delete over escapes from categories. * */category.rb: delete character entity reference from navigation default. 2007-12-16 TADA Tadashi <sho@spc.gr.jp> * release 2.2.0. 2007-12-10 zunda <zunda at freeshell.org> * disp_referrer.rb: modified to allow to write keys for seach word (String) and recursive URL (Symbol) in an Array * ja/disp_referrer.rb: added translation URLs from Google 2007-12-10 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: added search engines from chew, wordtantei, sfa-cms, hatena, Live Search. Modified search engines from Yahoo and Infoseek. Thank you, knu 2007-12-10 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: added require 'uri' to test code 2007-12-07 zunda <zunda at freeshell.org> * disp_referrer.rb: modified to recursively convert URL in query with keyword specified with a Symbol * disp_referrer.rb: refactored parse_as_search() * ja/disp_referrer.rb: modified an entry of DispReferrer2_Engines accordingly * ja/disp_referrer.rb: add an option to extensive test. Provide path to .tdr files to the command line * en/disp_referrer.rb, zh/disp_referrer.rb: added a comment for specifing recuseive conversion 2007-12-06 zunda <zunda at freeshell.org> * disp_referrer.rb, ja/disp_referrer.rb: applied patch at http://d.akinori.org/?date=20070704#p01 by Akinori MUSHA <akinori:at:musha:dot:org>. Thank you. Please note that I am thinking of chaging the notation from prev>q to {'prev' => 'q'} or something simpler. * ja/disp_referrer.rb: added a test case for recursive conversion 2007-12-06 zunda <zunda at freeshell.org> * ??/disp_referrer.rb: added label tags to radio buttons and check boxes 2007-12-05 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: added support for unit test 2007-09-27 TADA Tadashi <sho@spc.gr.jp> * category.rb: escape HTML more. 2007-09-23 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: splited CDATA section by each ']]>'. 2007-08-12 TADA Tadashi <sho@spc.gr.jp> * hide-mail-field.rb: add preference page for changing description of TSUKKOMI. 2007-07-22 TADA Tadashi <sho@spc.gr.jp> * a.rb: i18n. 2007-07-17 TADA Tadashi <sho@spc.gr.jp> * edit_today.rb: add 'rel="nofollow"' attribute to add/edit navigation. 2007-07-15 TADA Tadashi <sho@spc.gr.jp> * navi_user.rb: do not show navigations to hidden diaries. 2007-07-15 Kazuhiko <kazuhiko@fdiary.net> * category.rb: update category caches in append or replace mode only. 2007-07-14 Kazuhiko <kazuhiko@fdiary.net> * highlight.rb: calculate the length of the section anchor not by ruby but by javascript. 2007-07-09 TADA Tadashi <sho@spc.gr.jp> * recent_trackback3.rb: fix error on changing visibility of TrackBack in mobile mode. 2007-05-05 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: print error message from amazon API when preview mode. * search_form.rb: i18n. * search_form.rb: add extract_search_keyword plugin using disp_referrer.rb. 2007-05-03 TADA Tadashi <sho@spc.gr.jp> * search_control.rb: force nofollow in category page. 2007-05-01 TADA Tadashi <sho@spc.gr.jp> * amazon.rb, category.rb, recent_comment3.rb, recent_trakcback3.rb, my-sequel.rb, search_control.rb: add label elements in preferences form. 2007-04-30 TADA Tadashi <sho@spc.gr.jp> * makerss.rb, ping.rb: add label elements in update form. 2007-04-29 TADA Tadashi <sho@spc.gr.jp> * category.rb: support mobile mode more. 2007-04-26 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: postfixed slashes to host names, prefixed `:?' to parenthesis which are not referred. 2007-04-26 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: made regexps stricter, sorted out goo search engines, and added support for goo OEM search, such as So-net's. Thanks to Akinori MUSHA <knu at idaemons.org> 2007-04-22 TADA Tadashi <sho@spc.gr.jp> * category.rb: support mobile mode. 2007-04-19 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: cleaned up and added some URLs Thanks to Akinori MUSHA <knu at idaemons.org> 2007-04-03 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: sorry, re-tabify. 2007-04-12 zunda <zunda at freeshell.org> * ja/disp_referer.rb: modified for more of mobile.goo.ne.jp search engines. 2007-04-03 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb,recent_trackback3.rb: replace soft tab to hard tab. 2007-03-28 TADA Tadashi <sho@spc.gr.jp> * hide-mail-field.rb: set empty string into mail field by JavaScript. 2007-03-26 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: fix error when no price, no label on isbn_detail 2007-03-23 MIYASAKA Masaru <alkaid at coral.ocn.ne.jp> * category.rb: class CGI -> Category::CGI. 2007-03-11 MIYASAKA Masaru <alkaid at coral.ocn.ne.jp> * squeeze.rb: close each data transactions before convert. 2007-03-06 Kazuhiko <kazuhiko@fdiary.net> * number_anchor.rb: fix a warning message. 2007-03-06 TADA Tadashi <sho@spc.gr.jp> * edit_today.rb: fix warning message was shown on Firefox. 2007-02-27 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: add span elements into isbn_detail. 2007-02-09 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: delete xhtml prefix from attributes of mobile link discovery. * amazon.rb: add new plugin 'isbn_detail'. 2007-02-23 MIYASAKA Masaru <alkaid at coral.ocn.ne.jp> * category.rb: @index -> @conf.index in Info class. 2007-02-23 TADA Tadashi <sho@spc.gr.jp> * recent_comment3.rb: compare date after to_s. 2007-02-22 TADA Tadashi <sho@spc.gr.jp> * add new plugin: hide-mail-field.rb * zh/tb-show.rb: up to date to recent preferences page. * trackback/tb.rb: up to date to recent error page. * hide-mail-field.rb: set hidden attribute on mobile mode. 2007-02-21 zunda <zunda at freeshell.org> * my-sequel.rb: reformatted the CSS and Javascript sniplets. Thanks to miyasaka_m: http://zunda.freeshell.org/d/20070122.html#c04 2007-02-21 zunda <zunda at freeshell.org> * my-sequel.rb: updated testconfhtml following the new specification for the configuration interface 2007-02-21 zunda <zunda at freeshell.org> * my-sequel.rb: fixed the bug that shows only links from a month 2007-02-21 zunda <zunda at freeshell.org> * my-sequel.rb: added a test case `testadd_two_months', which reproduces the bug reported at http://zunda.freeshell.org/d/20070122.html#c01 Thanks to miyasaka_m 2007-02-21 TADA Tadashi <sho@spc.gr.jp> * footnote.rb: fix bug on Wiki style. support latest and month view. thanks to sunoko. 2007-02-19 TADA Tadashi <sho@spc.gr.jp> * add new plugin: edit_today.rb. 2007-02-15 Kazuhiko <kazuhiko@fdiary.net> * footnote.rb: modified to work on secure mode. 2007-02-13 TADA Tadashi <sho@spc.gr.jp> * footnote.rb: support whatsnew-list.rb in Blogkit. 2007-02-10 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: fix: author dose not have '()'. * footnote.rb: insert footnote into each section. * makerss.rb: insert body_enter and body_leave procs. * makerss.rb: add 'feed?' method that turns true in feed. 2007-02-09 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: delete xhtml prefix from attributes of mobile link discovery. * amazon.rb: add new plugin 'isbn_detail'. 2007-02-07 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: rewind about proxy, and use @conf['proxy']. 2007-02-06 SHIBATA Hiroshi <h-sbt@nifty.com> * amazon.rb: replace NKF::nkf to @conf.to_native. 2007-02-06 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: delete proxy code (using ENV in open-uri). 2007-01-29 TADA Tadashi <sho@spc.gr.jp> * akismet.rb: add plugin to setup Akismet spam filter. 2007-01-27 TADA Tadashi <sho@spc.gr.jp> * my-sequel.rb: remove <p> inner <div>. 2007-01-24 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_trackback3.rb,recent_comment3.rb: fix bug: enable to shoten title. 2007-01-24 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: support Amazon-ECS 2007-01-17: ISBN-13. 2007-01-23 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: added blog-search.yahoo.co.jp 2007-01-21 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: modified not to escape anchor(). * recent_trackback3.rb: rollback visible to visible_true. 2007-01-20 zunda <zunda at freeshell.org> * my-sequel.rb: MySequel::Conf: uncheck the restore checkbox onfocus instead of onchange. Thank you, Tada-san 2007-01-20 zunda <zunda at freeshell.org> * my-sequel.rb: MySequel::Conf: added event handlers so default values are displayed when checkboxes are checked and checkboxes are unchecked when settings are edited. 2007-01-20 zunda <zunda at freeshell.org> * my-sequel.rb: MySequel::Conf: modified to execute event handlers in configuration HTML. Event handlers are still to be implmented. 2007-01-21 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_trackback3.rb: fix bug: show invisible trackbacks. 2007-01-19 zunda <zunda at freeshell.org> * my-sequel.rb: modified to require 'erb' only when needed * my-sequel.rb: MySequel::Conf: modified to use separate parameter, and added check boxes to restore to the default values * my-sequel.rb: MySequel::css: modified not to use empty css 2007-01-19 zunda <zunda at freeshell.org> * my-sequel.rb: copied from zunda's local repository, v.1.28 * ja/my-sequel.rb: copied from zunda's local repository, v.1.10 2007-01-18 TADA Tadashi <sho@spc.gr.jp> * makerss.rb, ping.rb, tb-send.rb: fix charset to UTF-8, and using to_utf8 method. 2007-01-18 zunda <zunda at freeshell.org> * category.rb: added a code to recreate category cache files when escape or encoding for cache files has been chnaged 2007-01-17 zunda <zunda at freeshell.org> * navi_user.rb: added and modified to use mock-up CGI class to avoid error from cgi.rb:980:in `read_multipart': no content body (EOFError) 2007-01-18 Kazuhiko <kazuhiko@fdiary.net> * amazon.rb: convert to String first. 2007-01-17 SHIBATA Hiroshi <h-sbt@nifty.com> * pb-show.rb: modified not to escape anchor() because number_anchor.rb returns class attribute for a tag. This might be a security problem in the future. 2007-01-17 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: support TrackBack spec 1.2 and send by UTF-8 charset. * trackback/tb.rb: support TrackBack spec 1.2. * ja/{makerss,ping}.rb: use NKF insted of Uconv. * zh/{makerss,ping}.rb: use Iconv for convert to UTF-8. 2007-01-16 TADA Tadashi <sho@spc.gr.jp> * bq.rb: i18n. {ja,en,zh}/bq.rb added. 2007-01-14 TADA Tadashi <sho@spc.gr.jp> * tlink.rb, xmlrpc.rb: modified to use ERB::Util.h instead of CGI::escpaeHTML and escape base-html 2007-01-13 zunda <zunda at freeshell.org> * search_form.rb: modified to escape button name, quoated some values in HTML tags 2007-01-13 zunda <zunda at freeshell.org> * recent_namazu.rb: modified to URL-escape the keywords instead of HTML-escape. Sorry, not tested. 2007-01-13 zunda <zunda at freeshell.org> * recent_list.rb: modified not to escape anchor() because number_anchor.rb returns class attribute for a tag. This might be a security problem in the future. 2007-01-11 zunda <zunda at freeshell.org> * recent_comment.rb: modified not to escape anchor() because number_anchor.rb returns class attribute for a tag. This might be a security problem in the future. 2007-01-11 zunda <zunda at freeshell.org> * random_google.rb: modified to better escape the query string 2007-01-11 zunda <zunda at freeshell.org> * random_google.rb: modified to escape values of input tags in configuration interface 2007-01-11 zunda <zunda at freeshell.org> * navi_user.rb: modified to check @date before going further. @date is nil in configuration mode. 2007-01-11 zunda <zunda at freeshell.org> * makelirs.rb: modified to escape comma in uri 2007-01-11 zunda <zunda at freeshell.org> * kw.rb: modified to escape anchor string 2007-01-11 zunda <zunda at freeshell.org> * image.rb: removed an escape which was too much 2007-01-11 zunda <zunda at freeshell.org> * image.rb: added escapes 2007-01-11 zunda <zunda at freeshell.org> * highlight.rb: modified to unescape section_title in Javascript 2007-01-11 zunda <zunda at freeshell.org> * */category.rb: stoped HTML-escaping category_title. Escape should be done just when constructing HTML sniplets. 2007-01-11 zunda <zunda at freeshell.org> * gradient.rb: modified to escape each character 2007-01-11 zunda <zunda at freeshell.org> * gradation.rb: modified to escape each character 2007-01-11 zunda <zunda at freeshell.org> * footnote.rb: modified to escape later to make future maintenance easier 2007-01-11 zunda <zunda at freeshell.org> * dropdown_calendar.rb: escape @index 2007-01-11 zunda <zunda at freeshell.org> * daily_theme.rb: modified to URL-escape urls as well as escape theme names 2007-01-10 zunda <zunda at freeshell.org> * amazon.rb and category.rb: stop HTML-escaping URL-escaped strings. Excuse me, this was too much. 2007-01-11 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: support ISBN-13 (only starts with 978, maybe). 2007-01-10 zunda <zunda at freeshell.org> * counter.rb: modified to escape theme_url and values for inputs and text areas 2007-01-10 zunda <zunda at freeshell.org> * category.rb: modified to escape category names in sub titles (as is done in the other place) and URL-escape category names in URLs. We might still have to take care of charactor codes before URL-escaping category names. 2007-01-10 zunda <zunda at freeshell.org> * calendar3.rb: modified to escape title attributes of pop-ups 2007-01-11 Kazuhiko <kazuhiko@fdiary.net> * title_list.rb: remove escape of *_to_html() results. * kw.rb: url_encode key instead of html_escape. add '-m0' option to nkf(). * xmlrpc/xmlrpc.rb: use nkf instead of uconv. 2007-01-10 Kazuhiko <kazuhiko@fdiary.net> * xmlrpc/xmlrpc.rb: support recent tDiary. 2007-01-10 zunda <zunda at freeshell.org> * navi_user.rb: fixed bug introduced with previous commit: should have userd navi_latest for link to latest view 2007-01-10 zunda <zunda at freeshell.org> * amazon.rb: modified to escape pos, which can be typed by the user, and URL-escape asin and amazon.imgsize. 2007-01-10 zunda <zunda at freeshell.org> * a.rb: modified to URL-escape syntheized part of URL independent of charset, use h() insted of CGI.escapeHTML(), and HTML-escape data inside textarea 2007-01-10 TADA Tadashi <sho@spc.gr.jp> * src.rb: modified to use ERB::Util.h instead of CGI::escpaeHTML. * todo .rb: modified to use ERB::Util.h instead of CGI::escpaeHTML and escape base-html * tb-show.rbm pb-show.rb: rewind some over escapes. 2007-01-09 zunda <zunda at freeshell.org> * navi_user.rb: modified to work on secure mode 2007-01-10 Kazuhiko <kazuhiko@fdiary.net> * pb-show.rb, recent_list.rb, title_list.rb: remove parentheses warnings. 2007-01-10 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: include ERB::Util to MakeRssFull class. 2007-01-09 zunda <zunda at freeshell.org> * disp_referrer.rb: extend ERB::Util to use h() on ruby-1.8.2 2007-01-09 SHIBATA Hiroshi <h-sbt@nifty.com> * apply HTML escape when generate HTML in some more plugins. 2007-01-09 zunda <zunda at freeshell.org> * disp_referrer.rb: do not try to use ERB::Util.h which will fail on ruby-1.8.2 * */weather.rb: include ERB::Util in class Weather for ruby-1.8.2 * */weather.rb: use u() instead of h() to encode URLs 2007-01-08 TADA Tadashi <sho@spc.gr.jp> * makelirs.rb: remove CR/LF char from LIRS items. * makerss.rb: escape HTML tags from feed XML. 2007-01-08 zunda <zunda at freeshell.org> * navi_user.rb: escaped arguments to navi_item 2007-01-07 zunda <zunda at freeshell.org> * highlgiht.rb: modififed to escape diary_title in Ruby and unescape it in Javascript 2007-01-07 zunda <zunda at freeshell.org> * search_control.rb: modified to use h instead of CGI::escpaeHTML and escape base-html 2007-01-07 zunda <zunda at freeshell.org> * disp_referrer.rb: fixed typo in to_short_html 2007-01-07 zunda <zunda at freeshell.org> * my-ex.rb: modified to use ERB::Util.h instead of CGI::escpaeHTML and escape base-html 2007-01-07 zunda <zunda at freeshell.org> * disp_referrer.rb: try ERB::Util.h before trying CGI::escpaeHTML * disp_referrer.rb, */disp_referrer.rb: added HTML-escapes to @conf.update, urls, and other strings 2007-01-07 zunda <zunda at freeshell.org> * */weather.rb: use ERB::Util.h instead of CGI::escpaeHTML and added HTML-escapes to URLs 2007-01-07 SHIBATA Hiroshi <h-sbt@nifty.com> * apply HTML escape when generate HTML in some more plugins. 2007-01-07 TADA Tadashi <sho@spc.gr.jp> * apply HTML escape when generate HTML in some more plugins. 2007-01-06 TADA Tadashi <sho@spc.gr.jp> * apply HTML escape when generate HTML in some plugins. 2006-12-28 zunda <zunda at freeshell.org> * my-ex.rb: fix bug: bad link maked for YYYYMMDD#.. in Wiki style. 2006-12-12 zunda <zunda at freeshell.org> * ja/disp_referer.rb: added 209.85.128.0/17 for Google cache 2006-12-14 zunda <zunda at freeshell.org> * my-ex.rb: allow a URL as the first argument 2006-12-12 zunda <zunda at freeshell.org> * disp_referer.rb: refined regexp of livedoor Reader 2006-12-12 zunda <zunda at freeshell.org> * disp_referer.rb: added http://reader.livedoor.com/reader/ to antenna URL * ja/disp_referer.rb: added ezweb to search engines. Could not confirm the page title from the internet. * ja/disp_referer.rb: updated URLs for Matome-kensaku. Thank you Eguchi-san * ja/disp_referer.rb: added overture, multimeta, starware, Technorati, pageone, and yahoogle. Thank you kobito-san. * ja/disp_referer.rb: added wrs.search.yahoo.co.jp to search engines. Thank you J-san. * ja/disp_referer.rb: added and checked rambler. 2006-12-04 YAMAGUCHI Seiji <valda at underscore.jp> * recent_rss.rb: fix error on Ruby 1.8.5. 2006-09-13 Kazuhiko <kazuhiko@fdiary.net> * makerss.rb: guess rss uris by rss file names. add "makerss.suffix" and "makerss.no_comments.suffix" options. 2006-08-01 SHIBATA Hiroshi <h-sbt@nifty.com> * title_tag.rb: hide title in invisible diary. 2006-07-23 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: delete control codes without "\n", "\r" and "\t". thanks KURODA Hiraku <hiraku at hinet.mydns.jp>. 2006-07-02 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: change ID of preference page 'TrackBack' -> 'tb-show'. 2006-06-18 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: MakeRssFull#writable? check more when file dose not exist. 2006-06-18 SHIBATA Hiroshi <h-sbt@nifty.com> * makerss.rb: change value of Auto-Discovery title element. 2006-06-18 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: enable to make another feed without TSUKKOMI. * makerss.rb: obsolete makerss.hidecomment option. 2006-05-05 SHIBATA Hiroshi <h-sbt@nifty.com> * tb-show.rb: bugfix count up in trackbacks_of_today_short. 2006-04-15 TADA Tadashi <sho@spc.gr.jp> * release 2.1.4. 2006-03-28 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: fix order of TSUKKOMI in normal view mode. * recent_trackback3.rb: fix order of Trackback in normal view mode. 2006-03-23 TADA Tadashi <sho@spc.gr.jp> * {ja,en,zh}/makerss.rb: correct TSUKKOMI number into <title> when it over 100. thanks Namamura. 2006-03-18 TADA Tadashi <sho@spc.gr.jp> * recent_rss.rb: fix some typo. thanks kou-san. * comment_rank.rb, makerss.rb, recent_comment3.rb, recent_trackback3.rb, tb-show.rb: remove a limit of TSUKKOMI count. * makerss.rb: support Mobile Link Discovery. 2006-03-18 KURODA Hiraku <hiraku at hinet.mydns.jp> * ja/disp_referrer.rb: support new Google cache. 2006-03-17 TADA Tadashi <sho@spc.gr.jp> * recent_rss.rb: replace 'rss_recent' to 'recent-rss' in class name in HTML. 2006-03-14 TADA Tadashi <sho@spc.gr.jp> * recent_rss.rb: replace 'rss_recent' to 'recent_rss' in all sources. * ja/disp_referrer.rb: remove 'my.yahoo' and 'blog.yahoo' from search engines. 2006-03-13 TADA Tadashi <sho@spc.gr.jp> * rename {ja,en,zh}rss-recent.rb to recent_rss.rb. 2006-03-07 TADA Tadashi <sho@spc.gr.jp> * rename rss-recent.rb to recent_rss.rb, and make method alias to recent_rss. 2006-03-06 Kouhei Sutou <kou at cozmixng.org> * rss-recent.rb: support HTTPS. 2006-02-27 Kouhei Sutou <kou at cozmixng.org> * makerss.rb: erase deleted sections from cache. 2006-02-24 TADA Tadashi <sho@spc.gr.jp> * disp_referrer.rb: fix bug: no_cache option effective. 2006-02-14 Masao Mutoh * counter.rb: + Add some user-agents. + Fixed a problem when counter2_access.dat is broken by Ken-ichi Mito. + 2.0.2 2006-02-12 TADA Tadashi <sho@spc.gr.jp> * disp_referrer.rb: fix bug: hide volatile referer in old diaries. 2006-02-11 SHIBATA Hiroshi <h-sbt@nifty.com> * ja/amazon.rb: fix typo. 2006-02-10 TADA Tadashi <sho@spc.gr.jp> * disp_referrer.rb: support volatile referer and disable cache in default_io. 2006-02-07 MUTOH Masao * Revert the log file name from counter2.log to counter.log. Reported by Ken-ichi Mito. 2006-02-03 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb: delete referer when generate static HTML files. 2006-02-02 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: acceptable numeric ASIN. 2006-01-20 MUTOH Masao <mutoh@highway.ne.jp> * counter.rb: + Improves the speed and stability. - Separate data to counterdata and accessdata. - counterdata is the target of backup, but accessdata doesn't do backup. - change a key of an Array of String to a hash. - Removed "counter.daily_backup" option. Now daily_backup is applied everyday unless this setting. - Add a new "counter.max_keep_access_num" option which you can set the max number to keep users in the accessdata file to avoid to become too large the accessdata file. + Follow tDiary framework. - Add configuration page. + Misc - Removed "counter.deny_remote_addrs" option. - Added default deny user-agents. 2006-01-23 SHIBATA Hiroshi <h-sbt@nifty.com> * ping.rb: fix update option. 2006-01-12 Kazuhiko <kazuhiko@fdiary.net> * recent_trackback3.rb: more revise for mod_ruby. 2005-12-20 Kazuhiko <kazuhiko@fdiary.net> * amazon.rb: display an item name if no image is found and the 'amazon.nodefault' option is true. 2005-12-07 Lilia <nursery at s8.xrea.com> * kw.rb: unescape HTML for google query in default. 2005-12-04 zunda <zunda at freeshell.org> * highlight.rb: apply_plugin before counting sanchor 2005-12-04 Lilia <nursery at s8.xrea.com> * kw.rb: support title attribute and add some escapes in HTML. 2005-12-04 Taku YASUI <tach at debian.or.jp> * kw.rb: support UTF-8. 2005-12-04 N.KASHIJUKU <n-kashi at whi.m-net.ne.jp> * image.rb: swap width and height in image_info method. 2005-12-01 SHIBATA Hiroshi <h-sbt@nifty.com> * makerss.rb: insert link of Tsukkomi in RSS. 2005-11-21 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: move to contrib/util/rast-search/. 2005-11-18 Kazuhiko <kazuhiko@fdiary.net> * recent_trackback3.rb: revise for mod_ruby. * recent_comment3.rb: revise for mod_ruby. * image.rb (image_info): fix a bug in analysing jpeg files. 2004-11-17 MoonWolf <moonwolf@moonwolf.com> * image.rb: rescue ENOENT. 2005-11-13 Kazuhiko <kazuhiko@fdiary.net> * recent_trackback3.rb: revise for mod_ruby. * recent_comment3.rb: revise for mod_ruby. 2005-11-11 SHIBATA Hiroshi <h-sbt@nifty.com> * daily_theme.rb: use css_tag. 2005-11-10 SHIBATA Hiroshi <h-sbt@nifty.com> * daily_theme.rb: add new plugin. 2005-11-02 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: revise for rast-0.3.x. 2005-10-20 peo <peo at mb.neweb.ne.jp> * rss-recent.rb: support HTTP 304 response. 2005-10-19 Masao Mutoh <mutoh@highway.ne.jp> * counter.rb: Fixed a problem on Win32. Reported by Ken-ichi Mito 2005-10-18 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: added net range 72.14.192.0-239.255 for Google cache 2005-10-18 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: fix typo.(nill to nil) * recent_trackback3.rb: fix typo.(nill to nil) Thanks to yowa <yowa at yowaken.dip.jp>. 2005-10-16 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: add notify about amazon associate ID in preference page. 2005-10-15 zunda <zunda at freeshell.org> */disp_referrer.rb: update description about Nora. Thanks to yowa <yowa at yowaken.dip.jp>. 2005-10-14 zunda <zunda at freeshell.org> * */disp_referrer.rb: update description about unknown URLs listed on the browser. Thanks to FUDAN <joker at comel.or.jp>. 2005-10-13 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: delte category tags from title. * my-ex.rb: delete category tags from title. 2005-10-11 vette <vette at mail.ne.jp> * ping.rb: inherit checkbox status to preview page. 2005-10-11 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: delete category tags from title. 2005-10-10 TADA Tadashi <sho@spc.gr.jp> * my-ex.rb: my plugin: fix bug when @index was full path. 2005-10-05 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: never hide TrackBack in trackbackreceive mode. 2005-10-04 NT <nt@be.to> * tlink.rb: fix to create a cache file on ruby 1.8. thanks Takeshi Miyasaka <miyaken at iname.com>. 2005-09-29 TADA Tadashi <sho@spc.gr.jp> * release 2.1.3. 2005-09-28 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: remove catching SocketError. 2005-09-28 TADA Tadahi <sho@spc.gr.jp> * rss-recent.rb: insert a message when running on secure mode. 2005-09-27 TADA Tadahi <sho@spc.gr.jp> * amazon/*.png: add sample of default images. 2005-09-25 zunda <zunda at freeshell.org> * disp_referrer.rb: more titles to be categorized as antennas, generates better regexp for unknown URLs 2005-09-20 TADA Tadahi <sho@spc.gr.jp> * amazon.rb: use default images on tDiary.org. 2005-09-19 TADA Tadahi <sho@spc.gr.jp> * makerss.rb: correct tabindex and some fix. 2005-09-17 FUDAN <joker at comel.or.jp> * amazon.rb: quote image URL when using @amazon_default_image. * category.rb: add div element inside of form element. 2005-09-16 TADA Tadahi <sho@spc.gr.jp> * amazon.rb: return asin when SocketError. 2005-09-12 Keiichiro SAKURAI <kei-tdiary at ksakurai.nwr.jp> * makerss.rb: suppress making null entry when exclude TSUKKOMI into RSS. 2005-09-12 TADA Tadahi <sho@spc.gr.jp> * recent_comment3.rb, recent_trackback3.rb: insert a message when running on secure mode. 2005-09-09 TADA Tadahi <sho@spc.gr.jp> * makerss.rb: invert initial state of update option. 2005-09-08 TADA Tadahi <sho@spc.gr.jp> * makerss.rb, ping.rb: move genre from etc to update. 2005-09-07 TADA Tadahi <sho@spc.gr.jp> * some plugins: a little adjustment design in English. 2005-09-07 vette <vette at mail.ne.jp> * recent_trackback3.rb: support tree view mode. 2005-09-06 SHIBATA Hiroshi <h-sbt@nifty.com> * makerss.rb: add update option for edit mode. 2005-09-06 TADA Tadahi <sho@spc.gr.jp> * amazon.rb: deny zero length proxy. 2005-09-05 TADA Tadahi <sho@spc.gr.jp> * amazon.rb: remove 'over18' option. * amazon.rb: add class into img element in secure html. 2005-09-04 Kazuhiko <kazuhiko@fdiary.net> * makerss.rb: remove cache files when ArgumentError raises that may occurs by changing implementation of the Wiki style. 2005-09-03 Kazuhiko <kazuhiko@fdiary.net> * amazon.rb: not display images in the category mode. 2005-09-01 Kazuhiko <kazuhiko@fdiary.net> * amazon.rb: escape HTML in labels. * amazon/amazonimg.rb: mkdir @cache_path if not exists. revise for mod_ruby. 2005-08-31 TADA Tadahi <sho@spc.gr.jp> * amazon.rb: whole rewrite using Amazon ECS 4.0. * add amazon/amazonimg.rb: support CGI script for amazon.rb. 2005-08-30 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: change date format at tree view mode. 2005-08-28 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment3.rb: add Tree view mode. thanks MORIOKA Toru <vette at mail.ne.jp>. 2005-08-25 TADA Tadahi <sho@spc.gr.jp> * specify genre of preference to some plugins. 2005-08-20 Taku YASUI <tach at debian.or.jp> * tb-send.rb: support basic authentication for TrackBack ping URL. 2005-08-18 zunda <zunda at freeshell.org> * recent_comment3.rb: no longer records comments rejected by filter/spam.rb 2005-08-15 TADA Tadahi <sho@spc.gr.jp> * calendar2.rb: add image mode, thanks KASHIJUKU <n-kashi at whi.m-net.ne.jp> * recent_comment3.rb, recent_trackback3.rb: disable on secure mode. * calendar2.rb: i18n. 2005-08-11 TADA Tadahi <sho@spc.gr.jp> * sqeeze.rb: fix fatal bug when running on CGI mode. thanks TAKEMURA Masahiro <mas at mstk.que.jp>. * hilight.rb, append-css.rb: suppress action for bot. 2005-08-10 TADA Tadahi <sho@spc.gr.jp> * my-ex.rb: generate absolute URLs. 2005-08-10 Kazuhiko <kazuhiko@fdiary.net> * makerss.rb (makerss_body): output the full text of comments to <content:encoded>. 2005-08-07 TADA Tadahi <sho@spc.gr.jp> * image.rb: default value of @image_url to absolute URL. 2005-08-07 MORIOKA Toru <vette at mail.ne.jp> * makerss.rb: change <copyright> to <dc:rights>. 2005-08-07 Kazuhiro NISHIYAMA <zn@mbf.nifty.com> * makelirs.rb: fix when update.rb is in different path of index.rb. 2005-07-31 TADA Tadashi <sho@spc.gr.jp> * highlight.rb : add copyright. 2005-07-29 TADA Tadashi <sho@spc.gr.jp> * bq.rb: add license. * comment_rank.rb, gradation.rb, gradient.rb, recent_comment.rb: add license. 2005-07-28 TADA Tadashi <sho@spc.gr.jp> * dropdown_calendar.rb: add license. * en/recent_trackback3.rb, zh/recent_trackback3.rb: correct label of preference. * rast-register.rb: add license. * windex.rb: move to contrib/plugin. * amazon.rb: add license. 2005-07-27 TADA Tadashi <sho@spc.gr.jp> * doctype-html401tr.rb, src.rb, title_list.rb: add license. * add new plugin: rss-recent.rb. * highlight.rb, makelirs.rb: add license. 2005-07-25 SHIBATA Hiroshi <h-sbt@nifty.com> * recent_comment.rb : fix a anchor value. 2005-07-22 zunda <zunda at freeshell.org> * referer_scheme.rb: added URL for n-day mode in TdiaryDates, thanks to yowa, http://yowaken.dip.jp/tdiary/20050721.html#p01 2005-07-20 TADA Tadashi <sho@spc.gr.jp> * release 2.1.2. 2005-07-12 zunda <zunda at freeshell.org> * disp_referer.rb: clear cache only in saveconf mode 2005-07-07 TADA Tadashi <sho@spc.gr.jp> * category.rb: against CSRF attack. 2005-07-07 Yutaka OIWA <y.oiwa at aist.go.jp> * image.rb: against CSRF attack. 2005-07-07 SHIBATA Hiroshi <h-sbt@nifty.com> * xmlrpc.rb : fix name value(xmlrpc.lastname). 2005-07-06 TADA Tadashi <sho@spc.gr.jp> * recent_list.rb: add </li> to recent-list items. 2005-06-29 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb: fix bug: without data updating in command mode. 2005-06-27 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: for a little modified of web site changing. 2005-06-24 Kazuhiko <kazuhiko@fdiary.net> * disp_referrer.rb (update_options): use 'next' instead of 'continue'. 2005-06-23 SHIBATA Hiroshi <h-sbt at nifty.com> * recent_comment.rb: add a configuration page, and delete all parameters. 2005-06-23 TADA Tadashi <sho@spc.gr.jp> * jdate.rb: move to contrib/plugin/japanese. 2005-06-22 SHIBATA Hiroshi <h-sbt at nifty.com> * recent_comment3.rb: add a configuration page, and delete all parameters. 2005-06-22 Kazuhiko <kazuhiko@fdiary.net> * disp_referrer.rb: fix a typo. 2005-06-21 Hiroyuki Ikezoe <poincare@ikezoe.net> * recent_comment.rb, comment_rank.rb: Added GPL2 Licence. Delegated copy right to TADA-san. 2005-06-17 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: no operation when no TrackBack ping URL specified. 2005-06-15 TADA Tadashi <sho@spc.gr.jp> * recent_comment3.rb: bug fix: enable 'max' parameter. 2005-06-13 TADA Tadashi <sho@spc.gr.jp> * html_anchor.rb: change description of web server settings to using URL of tDiary-users wiki. * title_list.rb, recent_list.rb: change HTML to using <ul>. * recent_comment.rb, recent_comment3.rb: change HTML to using <ul>. * recent_trackback3.rb: change HTML to using <ul> and delete recent_trackback3.sep option. 2005-06-09 TADA Tadashi <sho@spc.gr.jp> * release 2.1.1. 2005-06-04 TADA Tadashi <sho@spc.gr.jp> * navi_user.rb: support 'n days before/after' mode. * navi_user.rb: change implementation to overwrite navi_user_day. 2005-06-03 TADA Tadashi <sho@spc.gr.jp> * html_anchor.rb, my-ex.rb: support 'n days before/after' mode. 2005-05-12 TADA Tadashi <sho@spc.gr.jp> * makerss.rb, recent_comment3.rb, recent_trackback3.rb: creation RSS file only once when showcomment mode. 2005-05-11 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: set false to show_nyear option in command/cgi mode. 2005-05-11 TADA Tadashi <sho@spc.gr.jp> * rast-resister.rb: set false to show_nyear option. 2005-05-10 TADA Tadashi <sho@spc.gr.jp> * rast-resister.rb: get title from h2 element. 2005-05-10 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: use diary's title as 'title' attribute. include 'title' to 'body'. 2005-05-01 Kazuhiko <kazuhiko@fdiary.net> * category.rb (category_list_sections): fix a bug in an image url. 2005-04-28 ishinao <ishinao at ishinao.net> * highlight.rb: set subtitle into title element. 2005-04-21 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: fix a typo. not set @ignore_parser_cache. 2005-04-21 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb, windex.rb: remove setting of $KCODE. * recent_comment3.rb, recent_trackback3.rb: return emprty string. 2005-04-16 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: never set $KCODE. 2005-04-14 zunda <zunda at freeshell.org> * disp_referrer.rb, */disp_referrer.rb: better handle ignore_urls 2005-04-14 Kazuhiko <kazuhiko@fdiary.net> * rast-register.rb: new plugin. 2005-04-08 TADA Tadashi <sho@spc.gr.jp> * append-css.rb: not apply in configuration mode. 2005-03-16 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: last section focused in default. 2005-03-10 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: add some error check and bug fix. thanks Yutaka Oiwa <yutaka at oiwa.jp>. * image.rb: add new option "image.maxwidth", thanks Masaru Yokoi <masaru at masaru.org>. 2005-03-09 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: remove debug print. 2005-03-09 TAHARA Shunichi <jado at flowernet.gr.jp> * calendar2.rb: escape quote in subtitle. 2005-03-03 zunda <zunda at freeshell.org> * disp_referrer.rb: handle rush conditions more properly when removing cache 2005-03-02 Tatsuki Sugiura <sugi@nemui.org> * tb-show.rb, ja/tb-show.rb, en/tb-show.rb: trackbacks_of_today_short is now selectable when in non-BlogKit mode from the config page 2005-02-28 zunda <zunda at freeshell.org> * disp_referrer.rb: handle rush conditions properly when removing cache 2005-02-21 zunda <zunda at freeshell.org> * disp_referrer.rb: debug code removed * disp_referrer.rb, {ja,en,zh}/disp_referrer.rb: configurable cache size * zh/disp_referrer.rb: sync with the en resource 2005-02-20 zunda <zunda at freeshell.org> * disp_referrer.rb, {ja,en,zh}/disp_referrer.rb: cache URLs of search engines, cache files are divided into each month, thanks to Aoki-san and kazuhiko-san. 2005-02-10 zunda <zunda at freeshell.org> * makerss.rb: escape comment body, thanks to Kouhei Sutou <kou at cozmixng.org> 2005-02-01 zunda <zunda at freeshell.org> * disp_referrer.rb: added del.icio.us to antenna regexp * ja/disp_referrer.rb: gw.mobile.goo.ne.jp and msearch.mobile.goo.ne.jp added to search engines 2005-01-26 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: better key for Feedback search, more URLs for livedoor and goo, thanks to Hahahaha <rin_ne at big.or.jp> * disp_referrer.rb, ja/disp_referrer.rb: can get search keyword from URL for Matome-search, thanks to Hahahaha <rin_ne at big.or.jp> 2005-01-25 zunda <zunda at freeshell.org> * makerss.rb: fix bug not to make empty items, contribution from Keiichiro SAKURAI <kei-tdiary at ksakurai.nwr.jp> 2005-01-22 zunda <zunda at freeshell.org> * ja/disp_referrer.rb: Feedback search and blogpeople, thanks to Hahahaha <rin_ne at big.or.jp> * disp_referrer.rb: add rel="nofollow" to links, see http://www.google.com/googleblog/2005/01/preventing-comment-spam.html 2005-01-12 Junichiro Kita <kita@kitaj.no-ip.com> * calendar3.rb: hide 'onmouseover' if @options['calendar3.show_popup'] == false, thanks to Ohiwa-san 2005-01-12 Masao Mutoh <mutoh@highway.ne.jp> * amazon.rb (get_amazon_image): add a title attribute. 2005-01-11 zunda <zunda at freeshell.org> * disp_referrer.rb: rescue PStore errors on ruby-1.8.1 and 1.6.8, thanks to Ohiwa-san 2005-01-05 Kazuhiko <kazuhiko@fdiary.net> * image.rb (image_info): get correct size of any jpeg files. 2004-12-17 zunda <zunda at freeshell.org> * makerss.rb: escapes inside description and title, thanks to Hideki Ikemoto <ikemo at wakaba.jp> 2004-12-05 NT <nt@be.to> * tlink.rb: adjusted to ruby 1.8.2 2004-12-05 Kazuhiko <kazuhiko@fdiary.net> * category.rb: delete category icon setting if 'none' is selected 2004-11-29 zunda <zunda at freeshell.org> * zh/search_control.rb: forgot to follow revision of search_control.rb 2004-11-29 zunda <zunda at freeshell.org> * makerss.rb: @conf.icon can be empty 2004-11-29 zunda <zunda at freeshell.org> * ja/makerss.rb: better description of options, thanks to TADA Tadashi <sho@spc.gr.jp> 2004-11-28 zunda <zunda at freeshell.org> * makerss.rb, {ja,en,zh}/makerss.rb: added option to hide tsukkomi-items from rss, thanks to Keiichiro SAKURAI <kei-tdiary at ksakurai.nwr.jp> 2004-11-24 zunda <zunda at freeshell.org> * makerss.rb: does not include TSUKKOMI when it is hidden, thanks to Mr. Hiromitsu Takagi (http://takagi-hiromitsu.jp/diary/20041124.html#p02) 2004-11-18 zunda <zunda at freeshell.org> * {en,zh}/makerss.rb: fixed typo, thanks to vette <vette at mail.ne.jp> * {ja,en,zh}/makerss.rb: reflects form values only when OK button has been pushed, thanks to vette <vette at mail.ne.jp> 2004-11-16 zunda <zunda at freeshell.org> * makerss.rb, {ja,en,zh}/makerss.rb: more options: - hidecomment, hidecontent, shortdescription: configurable thru. browser - @conf.icon @conf.description: configurable thru. browser in the future - file, url, partial: configurable in tdiary.conf * makerss.rb: includes copyright notice, shortened text as title when there is no subtitle. 2004-11-12 zunda <zunda at freeshell.org> * search_control.rb: config form remembers number of agents. Works properly even when the user delets an agent and push back button to reconfigure it. 2004-11-10 zunda <zunda at freeshell.org> * ja/disp_refrrer.rb: better handles links from goo.ne.jp. * ja/disp_refrrer.rb: support ocnsearch.goo.ne.jp Thanks to Michitaka Ohno (http://bigfield.ddo.jp/diary/20041111.html#p01) 2004-11-10 zunda <zunda at freeshell.org> * disp_referrer.rb: better handles links from bloglines.com as an antenna 2004-11-09 zunda <zunda at freeshell.org> * disp_referrer.rb: shows unknown referrers when the diary is edited Thanks to akira yamada (http://arika.org/diary/20041011#p01) * ja/disp_referrer.rb: less livedoor.jp URLs as search engine Thanks to Michitaka Ohno (http://bigfield.ddo.jp/diary/20041110.html#p02) 2004-11-09 zunda <zunda at freeshell.org> * search_control.rb: @cgi.user_agent can be nil 2004-11-09 zunda <zunda at freeshell.org> * search_control.rb, {en,ja}/search_control.rb: multiple user agents are now allowed 2004-11-09 zunda <zunda at freeshell.org> * disp_referrer.rb: delete cache when it is broken * disp_referrer.rb: i-know.jp and bloglines.com added as antenna * ja/disp_referrer.rb: added and modified DispReferrer2_Engines 2004-11-04 MoonWolf <moonwolf@moonwolf.com> * category.rb: remove TDiaryMonth::attr_reader * xmlrpc/xmlrpc.rb remove eval's 2004-11-03 MoonWolf <moonwolf@moonwolf.com> * xmlrpc/xmlrpc.rb some changed 2004-11-02 MoonWolf <moonwolf@moonwolf.com> * xmlrpc.rb Added * ja/xmlrpc Added * en/xmlrpc.rb Added * zh/xmlrpc.rb Added * xmlrpc/xmlrpc.rb Changed * xmlrpc/README Changed 2004-10-29 MoonWolf <moonwolf@moonwolf.com> * xmlrpc/README Added. * xmlrpc/xmlrpc.rb Added. 2004-10-28 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: exclude 'Pingback'. 2004-10-13 Kazuhiko <kazuhiko@fdiary.net> * category.rb: more revise for mod_ruby. add 'title' attribute in categor_icon_sample. correct icon url in category_anchor 2004-10-12 Kazuhiko <kazuhiko@fdiary.net> * category.rb: revise for mod_ruby 2004-10-03 Junichiro Kita <kita@kitaj.no-ip.com> * amazon.rb: add new option, @conf['amazon.over18'] 2004-10-01 Masao Mutoh <mutoh@highway.ne.jp> * counter.rb: Support @options["bot"] 2004-09-30 Masao Mutoh <mutoh@highway.ne.jp> * a.rb: improve HTML 2004-09-26 Masao Mutoh <mutoh@highway.ne.jp> * a.rb: Support config menu. * en/a.rb: Added. * a/: Removed. 2004-09-15 URABE Shyouhei <shyouhei@ice.uec.ac.jp> * ja/disp_referrer.rb : add some search engines. 2004-08-13 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: cut tail of entity reference. thanks IKEDA and snak. 2004-08-10 zunda <zunda at freeshell.org> * weather.rb, */weather.rb: show_robot enables to hide weather from robots 2004-08-09 NT <nt@be.to> * tlink.rb: fix typo. 2004-08-08 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: fix bug in category_anchor. 2004-08-07 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: watch changing subtitle. * makerss.rb: delete entity references in description. * makerss.rb: fix wrong TSUKKOMI id with TrackBacks. * trackback/tb.rb: fix security hole of TrackBack spam by JavaScript. * image.rb: fix thumbnail specify bug on secure mode. 2004-07-30 zunda <zunda at freeshell.org> * ja/referer_scheme.rb: better regexp, thanks to Nishiyama-san <zn at mbf.nifty.com> 2004-07-27 zunda <zunda at freeshell.org> * ja/referer_scheme.rb: HatenaHost remended, thanks to Kakutani-san <shintaro at kakutani.com>. 2004-07-19 Junichiro Kita <kita@kitaj.no-ip.com> * makelirs.rb: fix errors when user agent is mobile. 2004-07-07 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: some HTML tags escaped in description and content:encoded. 2004-07-06 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: add description elements to items. 2004-07-05 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: add categories to dc:subject element. thanks smbd <mitsuru@diana.dti.ne.jp>. 2004-07-02 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: save HTML tag of subtitle in content. thanks smbd <mitsuru@diana.dti.ne.jp>. 2004-07-01 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: enclose subtitle with h3 element. * category.rb: remove white space after category tag insert by JavaScript. 2004-06-27 TADA Tadashi <sho@spc.gr.jp> * release 2.0.0. 2004-06-27 Junichiro Kita <kita@kitaj.no-ip.com> * calendar3.rb: tDiary 1.4 is not supported any more 2004-06-26 Junichiro Kita <kita@kitaj.no-ip.com> * makerss.rb: define RDFSection if @mode == trackbackreceive * my-ex.rb: invalidated if mobile_agent 2004-06-24 Junichiro Kita <kita@kitaj.no-ip.com> * random_google.rb: hide if user agent is bot or modile_agent. 2004-06-23 Junichiro Kita <kita@kitaj.no-ip.com> * recent_comment3.rb: hide invisible comments. * recent_trackback3.rb: hide invisible trackbacks. 2004-06-19 TADA Tadashi <sho@spc.gr.jp> * footnote.rb: suppress making footnote in update mode. * makerss.rb: call body_enter_proc and body_leave_proc before output each section. * makerss.rb: support RSS auto discovery. 2004-06-19 zunda <zunda at freeshell.org> * category.rb: support ruby 1.6.x on secure mode. 2004-06-18 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: catch more error from trackback server. 2004-06-16 TADA Tadashi <sho@spc.gr.jp> * add zh (Traditional Chinese) language resources. thanks Hiroshi Yui <thinker60@mail2000.com.tw>. * makerss.rb: fix typo. 2004-06-15 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: insert time zone into dc:date. * makerss.rb: fix error when section has no subtitle. * output_rdf.rb: remove. 2004-06-14 Kazuhiko <kazuhiko@fdiary.net> * makerss.rb: CGI::escapeHTML title and description. 2004-06-14 TADA Tadashi <sho@spc.gr.jp> * makerss.rb: new plugin. 2004-06-12 zunda <zunda at freeshell.org> * disp_referer.rb: option added for command-line executed benchmark * {en,ja}/disp_referer.rb: better regexp, thanks to Aoki-san http://i.loveruby.net/d/20040530.html#p02 2004-06-12 Kazuhiko <kazuhiko@fdiary.net> * ping.rb: use cgi.params['key'][0] instead of cgi['key'][0] 2004-06-11 TADA Tadashi <sho@spc.gr.jp> * ping.rb: fix error when no @options['ping.list']. 2004-06-10 TADA Tadashi <sho@spc.gr.jp> * ping.rb: multi threading. * ping.rb: 'Sending ping' checkbox in edit form. 2004-06-09 TADA Tadashi <sho@spc.gr.jp> * append-css.rb: fix typo. * ping.rb: append. 2004-06-07 TADA Tadashi <sho@spc.gr.jp> * list.rb: apply_plugin to the result string. 2004-05-28 Masao Mutoh <mutoh@highway.ne.jp> * search_form.rb: Fix a wrong anchor for Yahoo Japan. Reported by michieru. 2004-06-02 zunda <zunda at freeshell.org> * ja/disp_referrer.rb, en/disp_referrer.rb: constants tainted to be used under secure diaries and ruby-1.6.x. Thanks Kazuhiko. 2004-06-01 Kazuhiko <kazuhiko@fdiary.net> * windex.rb: check existence of the pstore directory in load(). * squeeze.rb: 'add_update_proc' in plugin mode only. 2004-05-29 TADA Tadashi <sho@spc.gr.jp> * image.rb: fix bad width attribute in secure mode. 2004-05-28 Masao Mutoh <mutoh@highway.ne.jp> * a.rb: escape HTML in anchor tag by Akinori MUSHA. 2004-05-17 Kazuhiko <kazuhiko@fdiary.net> * title_tag.rb: apply_plugin in a day's title. * title_tag.rb: escape diary's title and day's title. 2004-05-16 mput <root@mput.dip.jp> * title_tag.rb : New file. 2004-05-14 zunda <zunda at freeshell.org> * ja/weather.rb: correct translation of `rain showers': http://zunda.freeshell.org/d/20040428.html#p02 2004-05-09 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb, tb-show.rb, output_rdf.rb: support absolute path of @conf.index. * tb-show.rb: apply_plugin to dc:title. 2004-05-05 TADA Tadashi <sho@spc.gr.jp> * makelirs.rb: change ruby version independ code. 2004-05-05 yowa <yowaken@cool.ne.jp> * tb-send.rb: check excerpt is not null. 2004-05-04 TADA Tadashi <sho@spc.gr.jp> * makelirs.rb: add a comment into HTML header. 2004-05-03 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: support to specify multiple ping URL. * tb-show.rb: remove to add '...' after shorten. 2004-05-02 TADA Tadashi <sho@spc.gr.jp> * image.rb: a little modify forms and labels. * tb-send.rb: select section support in append mode. 2004-04-23 mput <root@mput.dip.jp> * recent_comment3.rb (recent_comment3): Sorry the commit I posted yesterday had another problem. Fixed that. Thanks to Kitaj. 2004-04-22 mput <root@mput.dip.jp> * recent_comment3.rb (recent_comment3): Bug fix. 2004.04.10 Masanori_KADO <QVE02451@nifty.com> * category.rb: display categories you use on update form. 2004-04-05 TADA Tadashi <sho@spc.gr.jp> * highlight.rb: using CSS class as .highlight. thanks ZnZ <zn@mbf.nifty.com>. * highlight.rb: insert when day mode only. 2004-03-31 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: section subtitle into TrackBack title when excerpt specified. * tb-send.rb: set tabindex to section field. 2004.03.23 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: works in secure mode. sorry. 2004.03.23 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb, */category.rb: icon dir can be configured in unsecure mode. 2004.03.22 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb, */category.rb: category icons can be configured. 2004-03-20 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: specify section of TrackBack source. thanks yowa <yowaken@cool.ne.jp>. * {ja,en}/tb-send.rb, tb-show.rb: a little modified some labels. 2004-03-16 TADA Tadashi <sho@spc.gr.jp> * referer_scheme.rb: support WiLiKi style. 2004.03.16 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: cache shorten body this time around. sumaso- 2004.03.15 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: add category_dropdown_list. * */category.rb: escape category name by CGI.escapeHTML in category_title. 2004.03.15 Masashi Seiki <mass@starshine.jp> * category.rb: category_navi does'nt show buttons who have empty labels. 2004.03.15 Masashi Seiki <mass@starshine.jp> * category.rb: save configurations. * category.rb: add new conf parameter: @conf['category.period'] 2004-03-15 mput <root@mput.dip.jp> * category.rb (Cache::categorize_diary): bug fix for heredoc handling 2004.03.15 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: works in secure mode. cache shorten body again. 2004.03.15 Junichiro Kita <kita@kitaj.no-ip.com> * amazon.rb: don't show image when @mode == categoryview. 2004.03.15 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: cache entire body. Thanks kazuhiko. 2004.03.15 Junichiro Kita <kita@kitaj.no-ip.com> * category.rb: indexed category. Thanks mass and phonondrive.com. 2004-03-04 TADA Tadashi <sho@spc.gr.jp> * makelirs.rb: running under update_proc. * output_rdf.rb: running under update_proc. * squeeze.rb: running under update_proc. * tb-send.rb: running under update_proc. * comment_mail-*.rb: running under update_proc. 2004-02-26 TADA Tadashi <sho@spc.gr.jp> * ja/referer_scheme.rb: fix mod_ruby's error. * ja/referer_scheme.rb: modify hatena's URL. thanks KAKUTANI Shintaro <shintaro@kakutani.com> * output_rdf.rb: add <dc:creator> into RDF. * output_rdf.rb: remove path name from @options['outout_rdf.file']. Kazuhiro NISHIYAMA <zn@mbf.nifty.com>. * a/a_conf.rhtml: support ruby 1.8's ERB. thanks miyaken. 2004-02-25 mput <mput@users.sf.net> * en/disp_referrer.rb (DispRef2SetupIF::show_unknown_list): ditto. * ja/disp_referrer.rb (DispRef2SetupIF::show_unknown_list): add similarity search, answerbus, dogpile. 2004-02-24 TADA Tadashi <sho@spc.gr.jp> * referer_scheme.rb: a little modify about wiki scheme. 2004-02-22 Kazuhiko <kazuhiko@fdiary.net> * output_rdf.rb: catch exception of 'File::mtime( rdf_file )' 2004-02-17 TADA Tadashi <sho@spc.gr.jp> * trackback/bookmarklet.ja: add. written by s.sawada <moonwave@ba2.so-net.ne.jp>. 2004-02-16 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: swap aliased method names, and bug fix. 2004-02-09 TADA Tadashi <sho@spc.gr.jp> * my-ex.rb: fuzzy regexp in my plugin. * makelirs.rb: remove option 'makelirs.url'. 2004-02-09 sfanla <tdiary@sfanla.com> * append-css.rb: without escape CSS elements. 2004.01.28 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: fix error when TrackBack has only URL. 2004.01.27 mput <mput@users.sf.net> * ja/disp_referrer.rb: add Bulkfeeds to search engine. 2004.01.26 Junichiro Kita <kita@kitaj.no-ip.com> * calendar3.rb: fix displacement of popup window. thanks sfanla<tdiary@sfanla.com>. 2004.01.25 Junichiro Kita <kita@kitaj.no-ip.com> * recent_trackback3.rb: setting via conf. 2004.01.21 Junichiro Kita <kita@kitaj.no-ip.com> * recent_trackback3.rb: Oops. remove debug code. 2004.01.21 Junichiro Kita <kita@kitaj.no-ip.com> * recent_trackback3.rb: add. 2004.01.20 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: fix typo on autodiscovery RDF. 2004.01.14 Junichiro Kita <kita@kitaj.no-ip.com> * makelirs.rb: define Time#utc_offset if not defined. 2004.01.12 Junichiro Kita <kita@kitaj.no-ip.com> * my-ex.rb: this time, my can handle 'yyyymmdd#txx'. 2004.01.12 Junichiro Kita <kita@kitaj.no-ip.com> * tb-*.rb: if trackback is longer than 255 byte, it will be shorten to 252 byte and '...' will be added. 2004.01.09 RedGecko <redgecko@redgecko.jp> * random_google.rb: hide link access by bot. 2003.12.30 Junichiro Kita <kita@kitaj.no-ip.com> * my-ex.rb: my can handle 'yyyymmdd#txx'. 2003.12.26 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: shorten excerpt into 256 bytes. * image.rb: support blog styles. 2003.12.25 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: support error messages in multi-lines. * makelirs.rb: set last-modified to time stamp of file. thanks Takeru KOMORIYA <komoriya@paken.org>. * output_rdf.rb: set revious time stamp to RDF when diary was hidden. 2003.12.19 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb, windex.rb, trackback/tb.rb: set $KCODE to 'n'. 2003-12-17 zunda <zunda at freeshell.org> * referer_scheme.rb: updated documentation in the lang. resources * referer_scheme.rb: avoid infinite call of aliased `each' when the plug-in is eval'ed more than once. * referer_scheme.rb: scheme_tdiary moved to the plugin-body * referer_scheme.rb: bug fixed for scheme_tdiarynet. thanks to kosaka http://tnat.net/diary/?date=20031217#p01 * ja/weather.rb: translation for heavy rain added. thanks to kosaka http://tnat.net/diary/?date=20031217 * referer_scheme.rb: scheme_ymd added. thanks to kitaj http://kitaj.no-ip.com/tdiary/20031218.html#p02 2003-12-16 zunda <zunda at freeshell.org> * referer_scheme.rb: new plug-in to expand referer_table. Idea by akira yamada <akira at akira.org>, doesn't work with ruby 1.6.7 ;( * referer_scheme.rb: now works on ruby 1.6.7. thanks Minero Aoki <aamine at loveruby.net> 2003-12-16 TADA Tadashi <sho@spc.gr.jp> * my-ex.rb: accept fuzzy anchor style. 2003-12-12 TADA Tadashi <sho@spc.gr.jp> * output_rdf.rb: add output_rdf.image option. thanks Kouhei Sutou <kou@cozmixng.org>. 2003-12-11 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb: behave to like a bot. 2003-12-10 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: add 'clear cache' switch in prefenrences page. * tb-show.rb: hide link when bot access (against trackback spam). * tb-show.rb: hide RDF of ping url when bot access (against trackback spam). 2003-12-05 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: hide conf menu when secure mode and amazon.hideconf. 2003-12-02 Kazuhiko <kazuhiko@fdiary.net> * amazon.rb: hide some options in secure mode. 2003-12-02 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: add options amazon.imgsize and amazon.nodefault. thanx KOMORIYA. * amazon.rb: remove options amazon.smallimg. * amazon.rb: split ja resource. 2003-12-01 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: add options amazon.smallimg and amazon.hidename. thanx KOMORIYA. 2003-11-26 nt <nt@be.to> * tlink.rb: use @conf.base_url. 2003-11-25 zunda <zunda at freeshell.org> * weather.rb: avoid showing duplicated translation like mist/mist, thanks toshi-san. 2003-11-19 Junichiro Kita <kita@kitaj.no-ip.com> * tb-send.rb, tb-show.rb, makelirs.rb, output_rdf.rb: use @conf.base_url 2003-11-18 zunda <zunda at freeshell.org> * ja/disp_referrer.rb, en/disp_referer.rb: hopefully more usable config menu * Thanks to Kazuhiro NISHIYAMA, TADA Tadashi, NISHIMURA Takashi, ysano, Daigo Moriwaki, and mass. 2003-11-19 Kazuhiko <kazuhiko@fdiary.net> * output_rdf.rb: escape @html_title. support hidden diary. 2003-11-17 TADA Tadashi <sho@spc.gr.jp> * edit.rb: remove. 2003-11-14 TADA Tadashi <sho@spc.gr.jp> * append-css.rb: add "type" attr and comment tag. * random_google.rb: remove TARGET attr from A element. * html_anchor.rb: add come comments. 2003-11-13 TADA Tadashi <sho@spc.gr.jp> * nazo.rb: removed. * highlight.rb: nazo.rb modified and added. thanks to ZnZ <zn@mbf.nifty.com> 2003-11-11 Kazuhiko <kazuhiko@fdiary.net> * comment_rank.rb: fix XSS. 2003-11-10 Junichiro Kita <kita@kitaj.no-ip.com> * tb-show.rb: fix XSS. 2003-11-10 TADA Tadashi <sho@spc.gr.jp> * tb-send.rb: i18n, but not support UTF-8. * tb-show.rb, trackback/tb.rb: i18n. 2003-11-09 Junichiro Kita <kita@kitaj.no-ip.com> * amazon.rb: fix bug in amazonNoImg. 2003-11-07 TADA Tadashi <sho@spc.gr.jp> * output_rdf.rb: add information to HTML header for Auto-Discovery. thanks mput. * output_rdf.rb: i18n. 2003-11-05 zunda <zunda at freesehll.org> * ja/weather.rb: added `(partial )?(freezing )?' to `fog', ignore `patches of' 2003-10-30 TADA Tadashi <sho@spc.gr.jp> * tb-show.rb: fix bug in mod_ruby environment. 2003-10-28 Junichiro Kita <kita@kitaj.no-ip.com> * calendar2.rb, calendar3.rb, my-ex.rb, output_rdf.rb, recent_list.rb, title_list.rb: support new io. 2003-10-24 TADA Tadashi <sho@spc.gr.jp> * disp_referrer.rb: fix bug on 23 Oct. 2003-10-23 TADA Tadashi <sho@spc.gr.jp> * disp_referrer.rb: escape a bug of String#tr in ruby 1.6 dose not run in secure mode. 2003-10-23 Junichiro Kita <kita@kitaj.no-ip.com> * tb-show.rb: bug fix. Make <a name="t"> even if there is no trackbacks. 2003-10-22 zunda <zunda at freeshell.org> * disp_referrer.rb: language resources for ja and en completed (kondo koso..) 2003-10-21 zunda <zunda at freeshell.org> * disp_referrer.rb: language resources for ja and en completed (hopefully :) 2003-10-21 Junichiro Kita <kita@kitaj.no-ip.com> * output_rdf.rb: follow new @conf.shorten. 2003-10-21 Kazuhiko <kazuhiko@fdiary.net> * outpur_rdf.rb: make plain text title. ignore empty comment. add 'dc:date' to each comment. 2003-10-20 zunda <zunda at freeshell.org> * disp_referrer.rb: syntax error fixed. su ma so... 2003-10-20 zunda <zunda at freeshell.org> * disp_referrer.rb: search engine added: Comet Web Search 2003-10-19 Junichiro Kita <kita@kitaj.no-ip.com> * todo.rb: priority is optional. 2003-10-18 Kazuhiko <kazuhiko@fdiary.net> * output_rdf.rb: make plain text description. change default file name from 't.rdf' to 'index.rdf'. make an item per comment. 2003-10-16 Kazuhiko <kazuhiko@fdiary.net> * plugin.rb: 'priority' is also optional. 2003.10.14 zunda <zunda at freeshell.org> * disp_referrer.rb: search engine list in lang. resources (still more to do) 2003.10.13 Gony <gony@sm.rim.or.jp> * windex.rb: bug fix. * windex.rb: add wikw method. * windex.rb: support kw argument at CGI mode. * windex.rb: support @options['windex.generate_all'] option. 2003-10-13 zunda <zunda at freeshell.org> * search_control.rb: ja and en resources are divided. 2003-10-13 Junichiro Kita <kita@kitaj.no-ip.com> * kw.rb: kw can take 2 args. thanks to yowa. 2003-10-13 Junichiro Kita <kita@kitaj.no-ip.com> * tb-send.rb: HTMLize excerpt of TrackBack ping. thanks to matz. 2003-10-13 Kazuhiko <kazuhiko@fdiary.net> * image.rb: revise for @conf.secure. 2003-10-13 Junichiro Kita <kita@kitaj.no-ip.com> * image.rb: support ruby1.8. 2003-10-12 TADA Tadashi <sho@spc.gr.jp> * image.rb: comma separated image size by 3digs. 2003-10-12 Junichiro Kita <kita@kitaj.no-ip.com> * image.rb: guess image type and image size from file header. thanks to akira@arika.org. 2003-10-09 Kazuhiko <kazuhiko@fdiary.net> * comment_mail-qmail.rb: add "-f #{@conf.author_mail.untaint}" 2003-10-09 TADA Tadashi <sho@spc.gr.jp> * referer-antibot.rb: support 'bot?' method and English document. 2003-10-08 Kazuhiko <kazuhiko@fdiary.net> * todo.rb: catch exception of 'FileTest::exist?(todo_file)' for mod_ruby. 2003-10-08 Junichiro Kita <kita@kitaj.no-ip.com> * todo.rb: if @conf['todo.todos'] == nil, @conf['todo.todos'] = ''. 2003-10-08 Kazuhiko <kazuhiko@fdiary.net> * image.rb: show image size unless @conf.secure only. 2003-10-07 Junichiro Kita <kita@kitaj.no-ip.com> * tb-send.rb, tb-show.rb: move from trackback/ 2003-10-06 Kazuhiko <kazuhiko@fdiary.net> * comment_mail-smtp.rb: untaint 'From address' for mod_ruby. 2003-10-02 zunda <zunda at freeshell.org> * disp_referrer.rb: refined match for nifty 2003-10-01 Junichiro Kita <kita@kitaj.no-ip.com> * todo/*: removed. * todo.rb, ja/todo.rb, en/todo.rb: ToDo is saved into @conf['todo.todos']. 2003-09-30 zunda <zunda at freeshell.org> * disp_referrer.rb: refined match for biglobe search, one more search engine 2003-09-29 zunda <zunda at freeshell.org> * weather.rb: Japanese resources divided into a separate file, English resource created 2003-09-29 zunda <zunda at freeshell.org> * disp_referrer.rb: forgot to change arguments after changing initialize() 2003-09-28 Junichiro Kita <kita@kitaj.no-ip.com> * image.rb: write images with print method instead of puts method. * image.rb: show image size. 2003-09-27 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-show.rb: make RDF only when @mode == 'day'. 2003-09-26 TADA Tadashi <sho@spc.gr.jp> * select_plugins.rb: enable running on ruby 1.6.5. again. 2003-09-25 zunda <zunda at freeshell.org> * disp_referrer.rb: name.untaint to eval name 2003-09-25 TADA Tadashi <sho@spc.gr.jp> * select_plugins.rb: enable running on ruby 1.6.5. 2003-09-25 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb.rb, todo/todo.rb: use conf.encoding and conf.mobile_encoding instead of conf.charset. 2003-09-25 zunda <zunda at freeshell.org> * disp_referrer.rb: to_euc removed, instead using @conf.to_native 2003-09-25 TADA Tadashi <sho@spc.gr.jp> * support i18n framework. * english support: append-css, image, kw, speed_comment, amazon, dropdown_calendar. * *.rb: remove String#to_euc. * referer-utf8.rb: obsolete. * amazon.rb: safe on secure mode. 2003-09-25 Kita Junichiro <kita@kitaj.no-ip.com> * trackback/tb-show.rb: add <div class="trackbacks">. Thanks to mput. 2003-09-25 TADA Tadashi <sho@spc.gr.jp> * image.rb: english support. * output_rdf.rb: use @conf.shorten. 2003-09-24 TADA Tadashi <sho@spc.gr.jp> * speed_comment.rb: support cookie for name, and conf_proc. 2003-09-23 SAKAMOTO Hideki <hs@on-sky.net> * sn.rb: document corrected 2003-09-19 zunda <zunda at freeshell.org> * disp_referrer.rb (head): overwritten with disp_referrer2.rb,v 1.1.2.104 2003-09-19 Kazuhiko <kazuhiko@fdiary.net> * trackback/tb.rb: remove '</div>\n<div class="refererlist">'. 2003-09-18 TADA Tadashi <sho@spc.gr.jp> * whatsnew.rb: support apply_plugin. 2003-09-17 SAKAMOTO Hideki <hs@on-sky.net> * sn.rb: add add_body_leave_proc 2003-09-16 TADA Tadashi <sho@spc.gr.jp> * sn.rb: added. * number_anchor.rb: fix typo. 2003-09-10 zunda <zunda at freeshell.org> * disp_referrer.rb: Branch_disp_referrer-1 made on disp_referrer.rb. * disp_referrer.rb: use -r Branch_disp_referrer-1 option for MUTOH-san's 2003-09-07 Junichiro Kita <kita@kitaj.no-ip.com> * random_google.rb: add 2003-09-01 zunda <zunda at freeshell.org> * todo/todo.rhtml: s/%%>/%>/g for newer version of erb 2003-08-26 zunda <zunda at freeshell.org> * select_plugins.rb: simpler configuration display * search_control.rb: simpler configuration display 2003-08-27 zunda <zunda at freeshell.org> * 01_select_plugins.rb: renamed as select_plugins.rb * select_plugins.rb: does not show comments and sources in default 2003-08-26 zunda <zunda at freeshell.org> * search_control.rb: no table in configuration view, thanks to Tada-san. 2003-08-26 zunda <zunda at freeshell.org> * search_control.rb: added * 01_select_plugins.rb: added 2003-08-24 Junichiro Kita <kita@kitaj.no-ip.com> * output_rdf.rb: use @date 2003-08-20 TADA Tadashi <sho@spc.gr.jp> * append-css.rb: add. 2003-08-20 TADA Tadashi <sho@spc.gr.jp> * search_form.rb: to valid HTML. thanks Kakutani. 2003-08-20 TADA Tadashi <sho@spc.gr.jp> * kw.rb: save as String to conf. 2003-08-20 TADA Tadashi <sho@spc.gr.jp> * kw.rb: support conf_proc. thanks kazuhiko. 2003-08-16 zunda <zunda at freeshell.org> * weather.rb: heavy rain showers, thank you halchan-san 2003-08-11 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: fix error when amazon.aid was nil. 2003-08-08 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: support conf_proc, and add an option 'amazon.hideconf'. 2003-08-06 zunda <zunda at freeshell.org> * weather.rb: lightning -> Inazuma, thank you kotak-san 2003-08-06 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-send.rb: raise TDiaryTrackBackError if TrackBack Ping fail. 2003-08-05 Kazuhiko <kazuhiko@fdiary.net> * squeeze.rb: make html when receiving TrackBack Ping * output_rdf.rb: make rdf when receiving TrackBack Ping 2003-08-04 zunda <zunda at freeshell.org> * squeeze.rb: sets mtime of the HTML files, exit(1) when error 2003-08-03 Junichiro Kita <kita@kitaj.no-ip.com> * makelirs.rb: make lirs when receiving TrackBack Ping 2003-07-24 zunda <zunda at freeshell.org> * weather.rb: Syntax error in drizzle fixed 2003-07-22 zunda <zunda at freeshell.org> * weather.rb: debug code erased m(. .;;)m 2003-07-21 zunda <zunda at freeshell.org> * weather.rb: support conf_proc, %r literals for ruby-1.8.0 2003-06-16 TADA Tadashi <sho@spc.gr.jp> * comment_mail-*.rb: support conf_proc new spec. 2003-06-14 TADA Tadashi <sho@spc.gr.jp> * comment_mail-*.rb: support conf_proc. 2003-06-12 TADA Tadashi <sho@spc.gr.jp> * [TESTING] comment_mail-*.rb: support conf_proc. 2003-06-07 TADA Tadashi <sho@spc.gr.jp> * image.rb: renumbering tabindex. * trackback/tb-send.rb: renumbering tabindex. 2003-06-06 zunda <zunda at freeshell.org> * weather.rb: checks data age, `towering cumulus clouds' 2003-06-06 TADA Tadashi <sho@spc.gr.jp> * edit.rb: obsolete. 2003-06-03 zunda <zunda at freeshell.org> * weather.rb: ignores `... in the vicinity' Thank you kosaka-san. 2003-05-26 zunda <zunda at freeshell.org> * weather.rb: fix typo on option names (thank you haluchan). 2003-05-19 MUTOH Masao <mutoh@highway.ne.jp> * disp_referrer.rb: Support to seperate Antenna similar to disp_referrer2(by zunda). 2003-05-17 TADA Tadashi <sho@spc.gr.jp> * squeeze.rb: fix path of theme on CGI or CMD mode. * image.rb: fix typo. thanks HASHIMOTO Keisuke. * image.rb: add thumbnail in 3rd parameter of image method. * image.rb: force image width to 160 in update form. * image.rb: add image_link method. 2003-05-15 TADA Tadashi <sho@spc.gr.jp> * add trackback/README. 2003-05-15 Junichiro Kita <kita@kitaj.no-ip.com> * tb-show.rb: CGI::escapeHTML dc:title. * tb-show.rb: replace /-{2,}/ in RDF's dc:title to '-'s. 2003-05-15 Junichiro Kita <kita@kitaj.no-ip.com> * tb-send.rb: add charset parameter. 2003-05-13 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: cancel modify on 2003-05-11. * amazon.rb: support ruby 1.8. 2003-05-11 TADA Tadashi <sho@spc.gr.jp> * amazon.rb: escapeHTML strings from amazon. 2003-05-11 Junichiro Kita <kita@kitaj.no-ip.com> * tb.rb: use day.rhtml to do some plugin task. 2003-05-11 Junichiro Kita <kita@kitaj.no-ip.com> * tb-show.rb: new option. @options['tb.hide_if_no_tb']. 2003-05-10 Junichiro Kita <kita@kitaj.no-ip.com> * tb-send.rb: rescue failure to send TrackBack Ping. 2003-05-09 Junichiro Kita <kita@kitaj.no-ip.com> * calendar3.rb: use bot? to detect bot * trackback/tb-show.rb: use bot? to detect bot 2003-05-09 zunda <zunda at freeshell.org> * weather.rb: imported from zunda's local revision 1.1.2.32. 2003-05-08 TADA Tadashi <sho@spc.gr.jp> * kw.rb: fix bug when no default in @options['kw.dic']. thenks yowa. * kw.rb: @options['kw.show_inter'] support. 2003-05-06 TADA Tadashi <sho@spc.gr.jp> * image.rb: add notice 'JPEG only' when secure mode. * trackback/tb-show.rb: fail safe for running on command line. * html_anchor.rb, numberanchor.rb: anchor can handle yyyymmdd#txx. 2003-05-06 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-show.rb: generate anchor for each TrackBack. * recent_comment3.rb: use each_comment rather than count_comments to count comments. (for trackback) 2003-05-05 TADA Tadashi <sho@spc.gr.jp> * trackback/tb-send.rb: modify form layout. 2003-05-04 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-show.rb: antibot. * trackback/tb-show.rb: displaying position changed. * trackback/tb-show.rb: don't use ENV['SERVER_PORT']. (ENV['HTTP_HOST'] includes port number.) 2003-05-03 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-send.rb: Add methods for customizing messages. * trackback/tb.rb: remove classes for TrackBack. 2003-05-01 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-send.rb: shorten excerpt to about 255bytes. 2003-04-30 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-show.rb: show TrackBacked time. 2003-04-29 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb-show.rb: make anchor to TrackBack Ping URL. * trackback/tb-send.rb: change separator of CGI parameters from ';' to '&'. now it works with b2. 2003-04-28 TADA Tadashi <sho@spc.gr.jp> * makelirs.rb: enable running on secure mode. 2003-04-28 TADA Tadashi <sho@spc.gr.jp> * trackback/tb-show.rb, tb.rb: fix some security holes. * trackback/tb-show.rb: show ping url under 'add TSUKKOMI'. * trackback/tb-show.rb: support name based virtual host and root directory. * trackback/tb-send.rb: change name attr of fields for edit_proc spec. * trackback/tb-send.rb: independ from net/uri. * trackback/tb.rb: support symlink. * trackback/tb.rb: save TrackBack in visible. * image.rb: fix bug when comment status change. * sqeeze.rb, output_rdf.rb, makelirs.rb: enable running on secure mode. * output_rdf.rb: enable running on secure mode. * output_rdf.rb: support non UTF-8 when cannot load uconv. 2003-04-28 Junichiro Kita <kita@kitaj.no-ip.com> * trackback/tb.rb: GET request is redirected to TrackBacks(?date=yyyymmdd#t). 2003-04-27 TADA Tadashi <sho@spc.gr.jp> * trackback/tb-show.rb: support TrackBack hide and ruby 1.8. 2003-04-27 Junichiro Kita <kita@kitaj.no-ip.com> * add trackback/*. 2003-04-25 TADA Tadashi <sho@spc.gr.jp> * image: maxnum and maxsize effective in secure mode. * image: add JavaScript for insert plugin tag into diary. thanks Yoshimi KURUMA <yoshimik@iris.dti.ne.jp>. * image: show message when upload failed. 2003-04-24 TADA Tadashi <sho@spc.gr.jp> * image: enable running on secure mode. 2003-04-24 TADA Tadashi <sho@spc.gr.jp> * add image.rb into plugin collection. 2003-04-23 TADA Tadashi <sho@spc.gr.jp> * amazon: add some comments to description of parameters. 2003-04-19 TADA Tadashi <sho@spc.gr.jp> * add jdate.rb. 2003-04-18 TADA Tadashi <sho@spc.gr.jp> * add comment_mail-{smtp,qmail,sendmail}.rb. 2003-04-16 TADA Tadashi <sho@spc.gr.jp> * dropdown_calendar: fix p.calendar -> div.calendar. * dropdown_calendar: support @options['dropdown_calendar.label']. 2003-03-04 TADA Tadashi <sho@spc.gr.jp> * follow to changing book title style in Amazon's HTML. 2003-03-28 TADA Tadashi <sho@spc.gr.jp> * add referer-antibot.rb and referer-utf8.rb. 2003-03-22 Minero Aoki <aamine@loveruby.net> * a/a_conf.rb, bq.rb, kw.rb, nazo.rb, recent_comment3.rb, todo/todo.rb: remove warning on ruby 1.8. 2003-03-08 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp> * makelirs.rb: set TD. Thanks koyasu san. 2003-03-04 TADA Tadashi <sho@spc.gr.jp> * support ruby 1.8.0 preview2. 2003-03-03 MUTOH Masao <mutoh@highway.ne.jp> * a.rb: Added. 2003-03-03 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp> * output_rdf.rb: validate by RSS 1.0 <http://www.redland.opensource.ac.uk/rss/> Thanks Kakutani san. (see http://www.tdiary.net/archive/devel/msg00581.html) 2003-02-09 Junichiro Kita <kita@kitaj.no-ip.com> * merge from amazon2.rb. see http://kuwa.s26.xrea.com/b/20030211.html 2003-01-27 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp> * output_rdf.rb: reorder apply_plugin. 2003-01-21 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp> * output_rdf.rb: no requirement of diary.rrdf. * output_rdf.rb: rss version 1.0. 2003-01-13 TADA Tadashi <sho@spc.gr.jp> * for ruby 1.6.8. thanks woods <sodium@da2.so-net.ne.jp>. 2003-01-11 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp> * output_rdf.rb: use Plugin#apply_plugin. * output_rdf.rb: compatible defaultio 2003-01-09 MUTOH Masao <mutoh@highway.ne.jp> * my-ex.rb: Improve to show the anchor's title of section.subtitle. 2003-01-02 Kazuhiko <kazuhiko@fdiary.net> * nazo.rb (nazo): Add 'type="text/javascript"' for valid html output. Revise URI of FAQ. 2002-11-28 TADA Tadashi <sho@spc.gr.jp> * HTML 4.01 Strict support. 2002-10-28 zoe <zoe@kasumi.sakura.ne.jp> * makelirs.rb: merge 1.4. Thanks koyasu san. 2002-10-13 MUTOH Masao <mutoh@highway.ne.jp> * search_form.rb: fix in Google search. * search_form.rb: insert image into Yahoo search. * search_form.rb: remove Lycos search. All of them were pointed out by patagon. * search_form.rb: version 1.0.2 2002-10-06 TADA Tadashi <http://sho.tdiary.net/> * makelirs.rb: for tDiary 1.5.0.20021003. 2002-09-01 Junichiro Kita <kita@kitaj.no-ip.com> * change URL for images. 2002-07-09 TADA Tadashi <sho@spc.gr.jp> * follow chaging of title format in amazon. 2002-05-19 MUTOH Masao <mutoh@highway.ne.jp> * search_form.rb: document update. * search_form.rb: version 1.0.1 2002-05-05 TADA Tadashi <http://sho.tdiary.net/> * makelirs.rb: support @options. 2002-05-04 Kazuhiro NISHIYAMA <zn@mbf.nifty.com> * makelirs.rb: create. 2002-04-01 MUTOH Masao <mutoh@highway.ne.jp> * search_form.rb: tab = 3, change document format. 2002-03-24 MUTOH Masao <mutoh@highway.ne.jp> * search_form.rb: support Namazu, Google, Yahoo!, Lycos * search_form.rb: version 1.0.0 ��������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/a.rb������������������������������������������������������������������0000664�0000000�0000000�00000011152�13626457307�0016753�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# a.rb # # Create anchor easily. # # 1. Usage # a(url, name) # # a "http://www.hoge.com/diary/", "Hoge Diary" # # a(key, option_or_name = "", name = nil) # Use dictionary file. You need to create the dictionary # file with a CGI. # a "home" # a "home", "20020329.html", "Here" # # a("name|key:option") # Use dictionary file. You need to create the dictionary # file with a CGI. # # a "key" # a "key:20020329.html" # a "key:20020329.html|Here" # a "Hoge Diary|http://www.hoge.com/diary/" # a "Hoge Diary|20020201.html#p01" #=> Same as "my" plugin # # 2. Dictionary file # You can edit the dictionary file from "Preferences". # # 3. Documents # See URLs below for more details. # http://ponx.s5.xrea.com/hiki/a.rb.html (English) # http://ponx.s5.xrea.com/hiki/ja/a.rb.html (Japanese) # # Copyright (c) 2002-2004 MUTOH Masao <mutoh@highway.ne.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # # Resources unless @resource_loaded then def a_conf_label; "アンカー自動生成プラグイン辞書ファイル編集"; end def a_conf_explain; "<p>1行で1つのアンカーになります。フォーマットは、キー URL 名称です。各項目は空白で区切ります。名称は省略可能です。省略した場合はキーが名称として使われます。</p><p>例: bibo http://ponx.s5.xrea.com/bibo/ Linuxビボ〜ろく</p>"; end end def a_conf_cols; '70%'; end def a_conf_rows; 20; end A_REG_PIPE = /\|/ A_REG_COLON = /\:/ A_REG_URL = /:\/\// A_REG_CHARSET = /utf8|euc|sjis|jis/ A_REG_CHARSET2 = /euc|sjis|jis/ A_REG_MY = /^\d{8}/ if @options and @options["a.path"] a_path = @options["a.path"] else a_path = File.join(@cache_path, "a.dat") end @a_anchors = Hash.new if FileTest::exist?(a_path) open(a_path) do |file| file.each_line do |line| key, baseurl, *data = line.split(/\s+/) if data.last =~ A_REG_CHARSET charset = data.pop else charset = "" end @a_anchors[key] = [baseurl, data.join(" "), charset] end end end def a_separate(word) if A_REG_PIPE =~ word name, data = $`, $' else name, data = nil, word end option = nil if data =~ A_REG_URL key = data elsif data =~ A_REG_COLON key, option = $`, $' else key = data #Error pattern end [key, option, name] end def a_convert_charset(option, charset) return "" unless option return option unless charset if charset =~ A_REG_CHARSET2 ret = if String.method_defined?(:encode) option.encode(charset == 'jis' ? 'ISO-2022-JP' : charset) else require 'nkf' NKF::nkf("-#{charset[0].chr}", option) end else ret = option end ret end def a_anchor(key) data = @a_anchors[key] if data data.collect{|v| v ? v.dup : nil} else [nil, nil, nil] end end def a(key, option_or_name = nil, name = nil, charset = nil) url, value, cset = a_anchor(key) if url.nil? key, option, name = a_separate(key) url, value, cset = a_anchor(key) option_or_name = option unless option_or_name; end charset = cset unless charset value = key if value == "" if url.nil? url = key if name value = name url += u(a_convert_charset(option_or_name, charset)) elsif option_or_name value = option_or_name else value = key end else url += u(a_convert_charset(option_or_name, charset)) value = name if name end if key =~ A_REG_MY option_or_name = key unless option_or_name return my(option_or_name, name) end if @options["a.tlink"] if defined?(tlink) result = tlink(url, value) else result = "tlink is not available." end else result = %Q[<a href="#{h url}">#{value}</a>] end result end def navi_a(name = "a.rb conf") "<span class=\"adminmenu\"><a href=\"a_conf.rb\">#{name}</a></span>\n" end def a_conf_html(data) %Q[ #{a_conf_explain} <p><textarea name="anchor_plugin_data" cols="#{a_conf_cols}" rows="#{a_conf_rows}">#{h data}</textarea></p> ] end add_conf_proc( 'a_conf', a_conf_label ) do data = "" if FileTest.exist?( a_path ) open( a_path, "r" ) do |i| data = i.readlines.join end end if @mode == 'saveconf' if @cgi['anchor_plugin_data'] if FileTest.exist?( a_path ) open( a_path, "r" ) do |i| open( a_path + "~", "w" ) do |o| o.print i.readlines end end end open( a_path, 'w' ) do |o| @cgi["anchor_plugin_data"].lines.each do |v| v.split(/\n/).each do |line| o.print line, "\n" if line =~ /\w/ end end end data = @cgi["anchor_plugin_data"] end end a_conf_html(data) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/amazon.rb�������������������������������������������������������������0000664�0000000�0000000�00000020352�13626457307�0020022�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# amazon.rb: Making link with image to Amazon using Amazon ECS. # # see document: #{@lang}/amazon.rb # # Copyright (C) 2005-2019 TADA Tadashi <t@tdtds.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # require 'aws/pa_api' require 'timeout' enable_js( 'amazon.js' ) if @conf['amazon.bitly'] and @conf['bitly.login'] and @conf['bitly.key'] then enable_js( 'amazon_bitly.js' ) add_js_setting( '$tDiary.plugin.bitly' ) add_js_setting( '$tDiary.plugin.bitly.login', "'#{@conf['bitly.login']}'" ) add_js_setting( '$tDiary.plugin.bitly.apiKey', "'#{@conf['bitly.key']}'" ) end class AmazonRedirectError < StandardError; end def amazon_author(item) begin author = item["ItemInfo"]["ByLineInfo"]["Contributors"][0]["Name"] rescue '-' end end def amazon_title(item) item["ItemInfo"]["Title"]["DisplayValue"] end def amazon_image(item) image = {} begin size = case @conf['amazon.imgsize'] when 0; 'Large' when 2; 'Small' else; 'Medium' end image[:src] = item["Images"]["Primary"][size]["URL"] image[:height] = item["Images"]["Primary"][size]["Height"] image[:width] = item["Images"]["Primary"][size]["Width"] rescue base = @conf['amazon.default_image_base'] || 'https://tdiary.github.io/tdiary-theme/plugin/amazon/' case @conf['amazon.imgsize'] when 0 image[:src] = "#{base}large.png" image[:height] = 500 image[:width] = 380 when 2 image[:src] = "#{base}small.png" image[:height] = 75 image[:width] = 57 else image[:src] = "#{base}medium.png" image[:height] = 160 image[:width] = 122 end end image end def amazon_url(item) item["DetailPageURL"] end def amazon_label( item ) begin item["ItemInfo"]["ByLineInfo"]["Manufacturer"]["DisplayValue"] rescue '-' end end def amazon_price(item) begin item["Offers"]["Listings"][0]["Price"]["DisplayAmount"] rescue '(no price)' end end def amazon_detail_html(item) author = amazon_author(item) title = amazon_title(item) size_orig = @conf['amazon.imgsize'] @conf['amazon.imgsize'] = 2 image = amazon_image(item) @conf['amazon.imgsize'] = size_orig url = amazon_url(item) <<-HTML <a class="amazon-detail" href="#{url}"><span class="amazon-detail"> <img class="amazon-detail left" src="#{h image[:src]}" height="#{h image[:height]}" width="#{h image[:width]}" alt=""> <span class="amazon-detail-desc"> <span class="amazon-title">#{h title}</span><br> <span class="amazon-author">#{h author}</span><br> <span class="amazon-label">#{h amazon_label(item)}</span><br> <span class="amazon-price">#{h amazon_price(item)}</span> </span> </span></a> HTML end def amazon_to_html(item, with_image = true, label = nil, pos = 'amazon') with_image = false if @mode == 'categoryview' author = amazon_author(item) author = "(#{author})" unless author.empty? label ||= %Q|#{amazon_title(item)}#{author}| alt = '' if with_image and @conf['amazon.hidename'] || pos != 'amazon' then label, alt = alt, label end if with_image image = amazon_image(item) unless image[:src] then img = '' else size = %Q|height="#{h image[:height]}" width="#{h image[:width]}"| img = <<-HTML <img class="#{h pos}" src="#{h image[:src]}" #{size} alt="#{h alt}"> HTML img.gsub!( /\t/, '' ) end end url = amazon_url(item) %Q|<a href="#{h url}">#{img}#{h label}</a>| end def amazon_get(asin, with_image = true, label = nil, pos = 'amazon') asin = asin.to_s.strip.gsub(/-/, '') country, item_id = asin.scan(/\A(..):(.*)/).flatten unless country country = @conf['amazon.default_country'] || @amazon_default_country item_id = asin end begin cache = "#{@cache_path}/amazon" Dir::mkdir( cache ) unless File::directory?( cache ) begin json = File::read("#{cache}/#{country}#{item_id}.json") rescue Errno::ENOENT access_key = @conf['amazon.access_key'] secret_key = @conf['amazon.secret_key'] return asin unless access_key && secret_key partner_tag = @conf['amazon.aid'] paapi = AWS::PAAPI.new(access_key, secret_key, partner_tag) json = paapi.get_items(item_id, country.to_sym) File::open("#{cache}/#{country}#{item_id}.json", 'wb'){|f| f.write(json)} end item = JSON.parse(json)["ItemsResult"]["Items"][0] if pos == 'detail' then amazon_detail_html(item) else amazon_to_html(item, with_image, label, pos) end rescue Net::HTTPUnauthorized @logger.error "amazon.rb: Amazon API Unauthorized." message = asin if @mode == 'preview' then message << %Q|<span class="message">(Amazon API Unauthorized))</span>| end message rescue Timeout::Error @logger.error "amazon.rb: PA-API Timeouted." message = asin if @mode == 'preview' then message << %Q|<span class="message">(PA-API Timeouted))</span>| end message rescue Net::HTTPResponse, Net::HTTPExceptions => e @logger.error "amazon.rb: #{e.message}" message = label || asin if @mode == 'preview' then message << %Q|<span class="message">(#{h e.message})</span>| end message rescue NoMethodError @logger.error "amazon.rb: #{json["Errors"][0]["Message"]}" message = label || asin if @mode == 'preview' then message << %Q|<span class="message">(#{h json["Errors"][0]["Message"]})</span>| end message end end add_conf_proc( 'amazon', @amazon_label_conf ) do amazon_conf_proc end def amazon_conf_proc if @mode == 'saveconf' then @conf['amazon.imgsize'] = @cgi.params['amazon.imgsize'][0].to_i @conf['amazon.hidename'] = (@cgi.params['amazon.hidename'][0] == 'true') @conf['amazon.bitly'] = (@cgi.params['amazon.bitly'][0] == 'true') @conf['amazon.nodefault'] = (@cgi.params['amazon.nodefault'][0] == 'true') if @cgi.params['amazon.clearcache'][0] == 'true' then Dir["#{@cache_path}/amazon/*"].each do |cache| File::delete( cache ) end end unless @conf['amazon.hideconf'] then @conf['amazon.aid'] = @cgi.params['amazon.aid'][0] end end result = '' result << <<-HTML <h3>#{@amazon_label_imgsize}</h3> <p><select name="amazon.imgsize"> <option value="0"#{" selected" if @conf['amazon.imgsize'] == 0}>#{@amazon_label_large}</option> <option value="1"#{" selected" if @conf['amazon.imgsize'] == 1}>#{@amazon_label_regular}</option> <option value="2"#{" selected" if @conf['amazon.imgsize'] == 2}>#{@amazon_label_small}</option> </select></p> <h3>#{@amazon_label_title}</h3> <p><select name="amazon.hidename"> <option value="true"#{" selected" if @conf['amazon.hidename']}>#{@amazon_label_hide}</option> <option value="false"#{" selected" unless @conf['amazon.hidename']}>#{@amazon_label_show}</option> </select></p> HTML if @options['bitly.login'] and @options['bitly.key'] then result << <<-HTML <h3>#{@amazon_label_bitly}</h3> <p><select name="amazon.bitly"> <option value="true"#{" selected" if @conf['amazon.bitly']}>#{@amazon_label_bitly_enabled}</option> <option value="false"#{" selected" unless @conf['amazon.bitly']}>#{@amazon_label_bitly_disabled}</option> </select></p> HTML end result << <<-HTML <h3>#{@amazon_label_notfound}</h3> <p><select name="amazon.nodefault"> <option value="true"#{" selected" if @conf['amazon.nodefault']}>#{@amazon_label_usetitle}</option> <option value="false"#{" selected" unless @conf['amazon.nodefault']}>#{@amazon_label_usedefault}</option> </select></p> <h3>#{@amazon_label_clearcache}</h3> <p><label for="amazon.clearcache"><input type="checkbox" id="amazon.clearcache" name="amazon.clearcache" value="true">#{@amazon_label_clearcache_desc}</label></p> HTML unless @conf['amazon.hideconf'] then result << <<-HTML <h3>#{@amazon_label_aid}</h3> <p>#{@amazon_label_aid_desc}</p> <p><input name="amazon.aid" value="#{h( @conf['amazon.aid'] ) if @conf['amazon.aid']}"></p> HTML end result end def isbn_detail( asin ) amazon_get( asin, true, nil, 'detail' ) end def isbn_image( asin, label = nil ) amazon_get( asin, true, label ) end def isbn_image_left( asin, label = nil ) amazon_get( asin, true, label, 'left' ) end def isbn_image_right( asin, label = nil ) amazon_get( asin, true, label, 'right' ) end def isbn( asin, label = nil ) amazon_get( asin, false, label ) end # for compatibility alias isbnImgLeft isbn_image_left alias isbnImgRight isbn_image_right alias isbnImg isbn_image alias amazon isbn_image # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/amp.rb����������������������������������������������������������������0000664�0000000�0000000�00000004607�13626457307�0017317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# amp.rb # # generate AMP style HTML # # Copyright (c) 2016 MATSUOKA Kohei # Distributed under the GPL2 or any later version. # module AMP def amp_header_procs @amp_header_procs ||= [] end def amp_body_enter_procs @amp_body_enter_procs ||= [] end def add_amp_header_proc(&block) amp_header_procs << block if block_given? end def add_amp_body_enter_proc(&block) amp_body_enter_procs << block if block_given? end def amp_header_proc amp_header_procs.map{|proc| proc.call }.join("\n") end def amp_body_enter_proc amp_body_enter_procs.map {|proc| proc.call }.join("\n") end end extend AMP add_header_proc do if @mode == 'day' begin diary = @diaries[@date.strftime('%Y%m%d')] %Q|<link rel="amphtml" href="#{amp_html_url(diary)}">| rescue NoMethodError '' end end end add_content_proc('amp') do |date| begin diary = @diaries[date] template = File.read(File.join(TDiary::root, "views/amp.rhtml")) ERB.new(template).result(binding) rescue NoMethodError raise TDiary::NotFound end end def amp_body(diary) apply_plugin(diary.to_html) .gsub(/<img\s/, '<amp-img layout="responsive" ') .gsub(/<script[^<]+<\/script>/, '') end def amp_canonical_url(diary) URI.join(@conf.base_url, anchor(diary.date.strftime('%Y%m%d'))) end def amp_day_title(diary) title_proc(Time::at(@date.to_i), diary.title) end def amp_html_url(diary) uri = amp_canonical_url(diary) uri.query = [uri.query, "plugin=amp"].compact.join '&' uri end def amp_style base_css = amp_base_css theme_css = amp_theme_css .gsub(/^@charset.*$/, '') .gsub(/!important/, '') <<-EOL #{base_css} #{theme_css} EOL end def amp_base_css base_css_path = theme_paths_local.map {|path| File.join(File.dirname(path), "base.css") }.find {|path| File.exist?(path) } base_css_path ? File.read(base_css_path) : '' end def amp_theme_css _, location, theme = @conf.theme.match(%r|(\w+)/(\w+)|).to_a case location when 'online' require 'uri' require 'open-uri' uri = URI.parse(theme_url_online(theme)) uri.scheme ||= 'https' URI.parse(uri.to_s).read when 'local' theme_path = theme_paths_local.map {|path| File.join(File.dirname(path), "#{theme}/#{theme}.css") }.find {|path| File.exist?(path) } theme_path ? File.read(theme_path) : '' end end def amp_title @conf.html_title end �������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/append-css.rb���������������������������������������������������������0000664�0000000�0000000�00000002115�13626457307�0020567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# append-css.rb # # Append CSS fragment via Preferences Page. # # Copyright (c) 2002 TADA Tadashi <sho@spc.gr.jp> # Distributed under the GPL2 or any later version. # add_header_proc do if @mode !~ /conf$/ && @conf['append-css.css'] && @conf['append-css.css'].length > 0 && !bot? <<-HTML if @conf['append-css.css'] <style type="text/css"><!-- #{@conf['append-css.css']} --></style> HTML else '' end end unless @resource_loaded def append_css_label 'CSSの追加' end def append_css_desc <<-HTML <h3>CSS断片</h3> <p>現在指定してあるテーマに、スタイルシートを追加設定する場合、 以下にCSSの断片を入力してください。</p> HTML end end add_conf_proc( 'append-css', append_css_label, 'theme' ) do if @mode == 'saveconf' @conf['append-css.css'] = @cgi.params['append-css.css'][0] end <<-HTML #{append_css_desc} <p><textarea name="append-css.css" cols="60" rows="15">#{h @conf['append-css.css']}</textarea></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/bq.rb�����������������������������������������������������������������0000664�0000000�0000000�00000002441�13626457307�0017136�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bq.rb # # bq: blockquoteを使った引用を生成する # パラメタ: # src: 引用するテキスト # title: 引用元のタイトル # url: 引用元のURL # # 引用元タイトルをうまく表示するには、スタイルシートでp.sourceを # 定義する必要があります。スタイルの例: # # p.source { # margin-top: 0.3em; # text-align: right; # font-size: 90%; # } # # Copyright (C) 2002 s.sawada <moonwave@ba2.so-net.ne.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # def bq( src, title = nil, url = nil ) if url result = %Q[<blockquote cite="#{h url}" title="#{h title}">\n] elsif title result = %Q[<blockquote title="#{h title}">\n] else result = %Q[<blockquote>\n] end result << %Q[<p>#{src.gsub( /\n/, "</p>\n<p>" )}</p>\n].sub( %r[<p></p>], '' ) result << %Q[</blockquote>\n] if url cite = %Q[<cite><a href="#{h url}" title="#{h bq_cite_from( title )}">#{title}</a></cite>] result << %Q[<p class="source">[#{bq_cite_from cite}]</p>\n] elsif title cite = %Q[<cite>#{title}</cite>] result << %Q[<p class="source">[#{bq_cite_from cite}]</p>\n] end result end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/calendar2.rb����������������������������������������������������������0000664�0000000�0000000�00000012601�13626457307�0020366�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# calendar2.rb # # calendar2: add calendar as table layout. # parameter: # days_format: Array of weekday name stats with Sunday. (optional) # navi_format: Array of navigation label on top of calendar. (optional) # show_todo: You can write todo list into future diary as hidden with a # subtitle. if calendar2 find this parameter string in future # diary, it popup your todo. (optional) # # options: # calendar2.show_image: true or false. show a image that makes by image.rb # on each date. default is falase. # and if you want to change image size, add CSS to your theme. # for example (25x25 pixel image): # # td.calendar-day img { # width: 25px; # height: 25px; # border: 0; # } # # Copyright (c) 2001,2002 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # @calendar2_image_dir = @options && @options['image.dir'] || './images/' @calendar2_image_dir.chop! if /\/$/ =~ @calendar2_image_dir @calendar2_image_url = @options && @options['image.url'] || "#{base_url}images/" @calendar2_image_url.chop! if /\/$/ =~ @calendar2_image_url @calendar2_imageex_yearlydir = @options && @options['image_ex.yearlydir'] || 0 @calendar2_show_image = @options && @options['calendar2.show_image'] || false def calendar2_make_cal(year, month) result = [] t = Time.local(year, month, 1) r = Array.new(t.wday, nil) r << 1 2.upto(31) do |i| break if Time.local(year, month, i).month != month r << i end r += Array.new((- r.size) % 7, nil) 0.step(r.size - 1, 7) do |i| result << r[i, 7] end result end def calendar2_prev_current_next yyyymm = if /^(latest|search)$/ =~ @mode Time.now else @date end.strftime "%Y%m" yms = [yyyymm] @years.keys.each do |y| yms |= @years[y].collect {|i| y + i} end yms.sort! yms.unshift nil yms.push nil i = yms.index(yyyymm) yms[i - 1, 3] end def calendar2_make_anchor(ym, str) if ym %Q|<a href="#{h @index}#{anchor ym}">#{str}</a>| else str end end def calender2_make_image(diary, date) /[^_]image(?:_left|_right|_gps)?\s*\(?\s*([0-9]*)\s*\,?\s*'[^']*'/ =~ diary.to_s if $1 == nil return nil end image_dir = (@calendar2_imageex_yearlydir == 0 ? @calendar2_image_dir : %Q|#{@calendar2_image_dir}/#{date[0,4]}|) image_url = (@calendar2_imageex_yearlydir == 0 ? @calendar2_image_url : %Q|#{@calendar2_image_url}/#{date[0,4]}|) f_list = Dir.glob(%Q|#{image_dir}/#{date}_#{$1}*|) if f_list[0] file = File.basename(f_list[0]) file = %Q|s#{file}| if File.exist?(%Q|#{image_dir}/s#{file}|) %Q|<img src="#{image_url}/#{file}">| else nil end end def calendar2(days_format = nil, navi_format = nil, show_todo = nil) days_format ||= @calendar2_days_format navi_format ||= @calendar2_navi_format return '' if /TAMATEBAKO/ =~ @cgi.user_agent date = if /^(latest|search)$/ =~ @mode Time.now else @date end year = date.year month = date.month p_c_n = calendar2_prev_current_next result = <<CALENDAR_HEAD <table class="calendar" title="calendar"> <tr> <td class="image" colspan="7"></td> </tr> <tr> <td class="calendar-prev-month" colspan="2">#{calendar2_make_anchor(p_c_n[0], navi_format[0] % [year, month])}</td> <td class="calendar-current-month" colspan="3">#{calendar2_make_anchor(p_c_n[1], navi_format[1] % [year, month])}</td> <td class="calendar-next-month" colspan="2">#{calendar2_make_anchor(p_c_n[2], navi_format[2] % [year, month])}</td> </tr> CALENDAR_HEAD result << "<tr>" result << %Q| <td class="calendar-sunday">#{days_format[0]}</td>\n| 1.upto(5) do |i| result << %Q| <td class="calendar-weekday">#{days_format[i]}</td>\n| end result << %Q| <td class="calendar-saturday">#{days_format[6]}</td>\n| result << "</tr>\n" calendar2_make_cal(year, month).each do |week| result << "<tr>\n" week.each do |day| if day == nil result << %Q| <td class="calendar-day"></td>\n| else date = "%04d%02d%02d" % [year, month, day] result << %Q| <td class="calendar-day">%s</td>\n| % if @diaries[date] == nil day.to_s elsif ! @diaries[date].visible? if show_todo todos = [] @diaries[date].each_section do |section| if show_todo === section.subtitle todos << section.body end end if todos.size != 0 %Q|<a title="#{h todos.join( "\n" )}"><span class="calendar-todo">#{day}</span></a>| else day.to_s end else day.to_s end else subtitles = [] idx = "01" @diaries[date].each_section do |section| if section.subtitle text = section.subtitle_to_html else text = section.body_to_html end subtitles << h( %Q|#{idx}. #{@conf.shorten(apply_plugin( text, true ))}| ) idx.succ! end day_img = ((@calendar2_show_image) ? calender2_make_image(@diaries[date], date) : day.to_s) day_img = day.to_s if day_img == nil %Q|<a href="#{h @index}#{anchor date}" title="#{subtitles.join(" ")}">#{day_img}</a>| end end end result << "</tr>\n" end result << "</table>\n" end #@calendar2_cache = CacheMonth.new(@date, :calender2, method(:calendar2)) #add_update_proc @calendar2_cache.writer # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/calendar3.rb����������������������������������������������������������0000664�0000000�0000000�00000015505�13626457307�0020375�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# calendar3.rb # # calendar3: 現在表示している月のカレンダーを表示します. # パラメタ: なし # # tdiary.confで指定するオプション: # @options['calendar3.show_todo'] # パラグラフのサブサイトルとここで指定した文字列が一致し # かつその日の日記が非表示の場合,そのパラグラフの内容を # 予定としてpopupする. # # @options['calendar3.show_popup'] # JavaScriptによるpopupを表示するかどうか. # 省略時の値はtrueなので,表示したくない場合のみfalseを設定する. # # Copyright (c) 2001,2002 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # # # sample CSS for calendar3 # # .calendar-popup { # display: none; # text-align: left; # position: absolute; # border-style: solid; # border-width: 1px; # padding: 0 1ex 0 1ex; # } # # .calendar-sunday { # color: red; # } # # .calendar-saturday { # color: blue; # } # # .calendar-weekday { # color: black; # } # # .calendar-normal { # } # # .calendar-day { # font-weight: bold; # } # # .calendar-todo { # border-style: solid; # border-color: red; # border-width: 1px; # } # =begin ChengeLog 2003-09-25 TADA Tadashi <sho@spc.gr.jp> * use @conf.shorten. 2003-03-25 Junichiro Kita <kita@kitaj.no-ip.com> * add css to navigation links to next, current, prev month. 2003-02-27 Junichiro Kita <kita@kitaj.no-ip.com> * @options['calendar.show_popup'] 2003-01-07 Junichiro Kita <kita@kitaj.no-ip.com> * append sample css 2003-01-07 MURAI Kensou <murai@dosule.com> * modify javascript for popdown-delay 2002-12-20 TADA Tadashi <sho@spc.gr.jp> * use Plugin#apply_plugin. =end module Calendar3 WEEKDAY = 0 SATURDAY = 1 SUNDAY = 2 STYLE = { WEEKDAY => "calendar-weekday", SATURDAY => "calendar-saturday", SUNDAY => "calendar-sunday", } def make_cal(year, month) result = [] 1.upto(31) do |i| t = Time.local(year, month, i) break if t.month != month case t.wday when 0 result << [i, SUNDAY] when 1..5 result << [i, WEEKDAY] when 6 result << [i, SATURDAY] end end result end def prev_month(year, month) if month == 1 year -= 1 month = 12 else month -= 1 end [year, month] end def next_month(year, month) if month == 12 year += 1 month = 1 else month += 1 end [year, month] end module_function :make_cal, :next_month, :prev_month end def calendar3 return '' if bot? show_todo = @options['calendar3.show_todo'] show_todo = Regexp.new(show_todo) if show_todo result = '' if @options.has_key? 'calendar3.erb' result << %Q|<p class="message">@options['calendar3.erb'] is obsolete!<p>| end if /^(latest|search)$/ =~ @mode date = Time.now else date = @date end year = date.year month = date.month result << %Q|<span class="calendar-prev-month"><a href="#{h @index}#{anchor "%04d%02d" % Calendar3.prev_month(year, month)}"><<</a></span>\n| result << %Q|<span class="calendar-current-month"><a href="#{h @index}#{anchor "%04d%02d" % [year, month]}">#{"%04d/%02d" % [year, month]}</a>/</span>\n| #Calendar3.make_cal(year, month)[(day - num >= 0 ? day - num : 0)..(day - 1)].each do |day, kind| Calendar3.make_cal(year, month).each do |day, kind| date = "%04d%02d%02d" % [year, month, day] if @diaries[date].nil? result << %Q|<span class="calendar-normal"><a class="#{Calendar3::STYLE[kind]}">#{day}</a></span>\n| elsif !@diaries[date].visible? todos = [] if show_todo @diaries[date].each_section do |section| if show_todo === section.subtitle todos << h( section.body_to_html ).gsub( /\n/, " " ) end end end if todos.size != 0 result << %Q|<span class="calendar-todo"><a class="#{Calendar3::STYLE[kind]}" title="#{day}日の予定: #{todos.join " "}">#{day}</a></span>\n| else result << %Q|<span class="calendar-normal"><a class="#{Calendar3::STYLE[kind]}">#{day}</a></span>\n| end else if @calendar3_show_popup result << %Q|<span class="calendar-day" id="target-#{day}" onmouseover="popup(document.getElementById('target-#{day}'),document.getElementById('popup-#{day}'), document.getElementById('title-#{day}'));" onmouseout="popdown(document.getElementById('popup-#{day}'));">\n| else result << %Q|<span class="calendar-day" id="target-#{day}">\n| end result << %Q| <a class="#{Calendar3::STYLE[kind]}" id="title-#{day}" title="| i = 1 r = [] if !@plugin_files.grep(/\/category.rb$/).empty? and @diaries[date].categorizable? @diaries[date].each_section do |section| if section.stripped_subtitle text = apply_plugin( section.stripped_subtitle_to_html, true ) r << %Q|#{i}. #{h text}| end i += 1 end else @diaries[date].each_section do |section| if section.subtitle text = apply_plugin( section.subtitle_to_html, true ) r << %Q|#{i}. #{h text}| end i += 1 end end result << r.join(" ") result << %Q|" href="#{h @index}#{anchor date}">#{day}</a>\n| if @calendar3_show_popup result << %Q| <span class="calendar-popup" id="popup-#{day}">\n| i = 1 if !@plugin_files.grep(/\/category.rb$/).empty? and @diaries[date].categorizable? @diaries[date].each_section do |section| if section.stripped_subtitle text = apply_plugin( section.body_to_html, true ) subtitle = apply_plugin( section.stripped_subtitle_to_html ) result << %Q| <a href="#{h @index}#{anchor "%s#p%02d" % [date, i]}" title="#{h @conf.shorten( text )}">#{i}</a>. #{subtitle}<br>\n| end i += 1 end else @diaries[date].each_section do |section| if section.subtitle text = apply_plugin( section.body_to_html, true ) subtitle = apply_plugin( section.subtitle_to_html ) result << %Q| <a href="#{h @index}#{anchor "%s#p%02d" % [date, i]}" title="#{h @conf.shorten( text )}">#{i}</a>. #{subtitle}<br>\n| end i += 1 end end result << %Q| </span>\n| end result << %Q|</span>\n| end end result << %Q|<span class="calendar-next-month"><a href="#{h @index}#{anchor "%04d%02d" % Calendar3.next_month(year, month)}">>></a></span>\n| result end @calendar3_show_popup = true if @options.has_key?('calendar3.show_popup') @calendar3_show_popup = @options['calendar3.show_popup'] end if /w3m|MSIE.*Mac/ === @cgi.user_agent @calendar3_show_popup = false add_header_proc do <<JAVASCRIPT <script type="text/javascript"> <!-- function popup(target,element,notitle) { } function popdown(element) { } // --> </script> JAVASCRIPT end end if @calendar3_show_popup enable_js('calendar3.js') end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: set ts=3: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/category-legacy.rb����������������������������������������������������0000664�0000000�0000000�00000042645�13626457307�0021625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # category-legacy.rb : tDiary plugin for show category pages # legacy version for ruby 2.0 or later # # Copyright (c) 2003 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # require 'tdiary/diary_container' # # initialize # def category_init @conf['category.header1'] ||= %Q[<div class="adminmenu">\n<p>\n<%= category_navi %>\n</p>\n</div>\n] @conf['category.header2'] ||= %Q[<p>Categories |\n<%= category_list %>\n</p>\n] @conf['category.edit_support'] = @conf['category.edit_support'].to_i rescue 1 end category_init def category_icon_location_init @category_icon_dir = (@conf['category.icon_dir'] || './icons/').sub(%r|/*$|, '/') @category_icon_url = (@conf['category.icon_url'] || './icons/').sub(%r|/*$|, '/') end def category_icon_init category_icon_location_init @conf['category.icon'] ||= '' @category_icon = {} @conf['category.icon'].split(/\n/).each do |l| c, i = l.split next if c.nil? or i.nil? @category_icon[c] = i if File.exist?("#{@category_icon_dir}#{i}") end end category_icon_init # # plugin methods # def category_form # don't you need this method any more? end def category_anchor(category) period = @conf['category.period'] || 'quarter' period_string = case period when "month" "year=#{@date.year};month=#{'%02d' % @date.month};" when "quarter" "year=#{@date.year};month=#{(@date.month - 1) / 3 + 1}Q;" when "half" "year=#{@date.year};month=#{(@date.month - 1) / 6 + 1}H;" when "year" "year=#{@date.year};" else "" end if @category_icon[category] %Q|<a href="#{h @index}?#{period_string}category=#{u category}" title="#{h category}"><img class="category" src="#{h @category_icon_url}#{h @category_icon[category]}" alt="#{h category}"></a>| else %Q|[<a href="#{h @index}?#{period_string}category=#{u category}" title="#{h category}">#{h category}</a>]| end end def category_navi_anchor(info, label) ((!label.nil?) && label.empty?) ? '' : %Q[<span class="adminmenu">#{info.make_anchor(label)}</span>\n] end def category_navi info = Category::Info.new(@cgi, @years, @conf) mode = info.mode result = '' case mode when :year, :half, :quarter, :month all_diary = Category::Info.new(@cgi, @years, @conf, year: -1, month: -1) all = Category::Info.new(@cgi, @years, @conf, category: ['ALL'], year: -1, month: -1) result << category_navi_anchor(info.prev, @conf['category.prev_' + mode.to_s]) result << category_navi_anchor(info.next, @conf['category.next_' + mode.to_s]) result << category_navi_anchor(all_diary, @conf['category.all_diary']) result << category_navi_anchor(all, @conf['category.all']) when :all year = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s) half = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: "#{((Time.now.month - 1) / 6 + 1)}H") quarter = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: "#{((Time.now.month - 1) / 3 + 1)}Q") month = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: '%02d' % Time.now.month) result << category_navi_anchor(year, @conf['category.this_year']) result << category_navi_anchor(half, @conf['category.this_half']) result << category_navi_anchor(quarter, @conf['category.this_quarter']) result << category_navi_anchor(month, @conf['category.this_month']) end if !info.category.include?('ALL') then all_category = Category::Info.new(@cgi, @years, @conf, category: ['ALL']) result << category_navi_anchor(all_category, @conf['category.all_category']) end result end def category_list_sections info = Category::Info.new(@cgi, @years, @conf) r = '' raise ::TDiary::NotFound if @categorized.empty? and bot? @categorized.to_a.sort_by{|e| e[0].downcase}.each do |c, v| info.category = [c] if @category_icon[c] img = %Q|<img class="category" src="#{h @category_icon_url}#{h @category_icon[c]}" alt="#{h c}">| else img = '' end r << <<HTML <div class="category day"> <h2><span class="title">#{img}#{info.make_anchor}</span></h2> <div class="body"> <ul class="category"> HTML v.to_a.sort_by{|e| e[0]}.each do |ymd, ary| text = Time.local(ymd[0,4], ymd[4,2], ymd[6,2]).strftime(@conf.date_format) ary.sort.each do |idx, title, excerpt| r << %Q|\t\t\t<li><a href="#{h @index}#{anchor "#{ymd}#p#{'%02d' % idx}"}" title="#{h excerpt}">#{text}#p#{'%02d' % idx}</a> #{apply_plugin(title)}</li>\n| end end r << <<HTML </ul> </div> </div> HTML end r end def category_list_sections_mobile info = Category::Info.new(@cgi, @years, @conf) r = '' raise ::TDiary::NotFound if @categorized.empty? and bot? @categorized.to_a.sort_by{|e| e[0].downcase}.each do |c, v| info.category = [c] r << "<H2>#{info.make_anchor}</H2>" r << "<UL>" v.to_a.sort_by{|e| e[0]}.each do |ymd, ary| text = Time.local(ymd[0,4], ymd[4,2], ymd[6,2]).strftime(@conf.date_format) ary.sort.each do |idx, title, excerpt| r << %Q|<LI><A HREF="#{h @index}#{anchor "#{ymd}#p#{'%02d' % idx}"}">#{text}#p#{'%02d' % idx}</A> #{apply_plugin(title)}</LI>\n| end end r << "</UL>" end r end def category_list info = Category::Info.new(@cgi, @years, @conf) @categories.map do |c| info.category = [c] info.make_anchor end.join(" | \n") end def category_dropdown_list(label = nil, multiple = nil) label ||= 'Categorize!' multiple ||= false info = Category::Info.new(@cgi, @years, @conf) category = info.category if category.empty? category = ['ALL'] end options = '' (['ALL'] + @categories).each do |c| options << %Q|\t\t<option value="#{h c}"#{" selected" if category.include?(c)}>#{h c}</option>\n| end params = '' params << %Q[<input type="hidden" name="year" value="#{h info.year}">] if info.year params << %Q[<input type="hidden" name="month" value="#{h info.month}">] if info.month <<HTML <form method="get" action="#{h @index}"><div> <select name="category"#{" multiple" if multiple}> #{options} </select> #{params} <input type="submit" value="#{label}"> </div></form> HTML end # # misc # def category_icon_save @conf['category.icon'] = @category_icon.map {|c, i| "#{c} #{i}"}.join("\n") end module Category # # Info # class Info include ERB::Util def initialize(cgi, years, conf, args = {}) @cgi = cgi @years = years @conf = conf @category = args[:category] || @cgi.params['category'].map do |c| @conf.to_native(c, @conf.encoding_old) end @year = args[:year] || @cgi.params['year'][0] @month = args[:month] || @cgi.params['month'][0] @mode = :all set_mode end protected attr_writer :year attr_writer :month public attr :category, true attr_reader :year attr_reader :month attr_reader :mode def prev pp = self.dup case mode when :half h = @month.to_i if h == 1 pp.month = "2H" pp.year = (@year.to_i - 1).to_s if @year else pp.month = "1H" end when :quarter q = @month.to_i if q == 1 pp.month = "4Q" pp.year = (@year.to_i - 1).to_s if @year else pp.month = "#{q - 1}Q" end when :month m = @month.to_i if m == 1 pp.month = "12" pp.year = (@year.to_i - 1).to_s if @year else pp.month = '%02d' % (m - 1) end when :year pp.year = (@year.to_i - 1).to_s end pp end def next pp = self.dup case mode when :half h = @month.to_i if h == 2 pp.month = "1H" pp.year = (@year.to_i + 1).to_s if @year else pp.month = "2H" end when :quarter q = @month.to_i if q == 4 pp.month = "1Q" pp.year = (@year.to_i + 1).to_s if @year else pp.month = "#{q + 1}Q" end when :month m = @month.to_i if m == 12 pp.month = "01" pp.year = (@year.to_i + 1).to_s if @year else pp.month = '%02d' % (m + 1) end when :year pp.year = (@year.to_i + 1).to_s end pp end def make_anchor(label = nil) a = @category.map {|c| "category=#{u c}"}.join(';') a << ";year=#{@year}" if @year a << ";month=#{@month}" if @month if label case mode when :year label = label.gsub(/\$1/, @year) when :month, :quarter, :half label = label.gsub(/\$2/, @month) label = label.gsub(/\$1/, @year || '*') end else label = @category.to_a.join(':') end %Q|<a href="#{h @conf.index}?#{h a}">#{h label}</a>| end # # return ym_spec # # {"yyyy" => ["mm", ...], ...} # # date spec: # (1) none -> all diary # (2) month=xH -> all diary in xH of all year # (3) year=YYYY;month=xH -> all diary in YYYY/xH # (4) month=xQ -> all diary in xQ of all year # (5) year=YYYY;month=xQ -> all diary in YYYY/xQ # (6) month=MM -> all diary in MM of all year # (7) year=YYYY;month=MM -> all diary in YYYY/MM # (8) year=YYYY -> all diary in YYYY # def years if @mode == :all return @years end months = case @mode when :half [('01'..'06'), ('07'..'12')][@month.to_i - 1].to_a when :quarter [['01', '02', '03'], ['04', '05', '06'], ['07', '08', '09'], ['10', '11', '12']][@month.to_i - 1] when :month [@month] else ('01'..'12').to_a end r = {} (@year ? [@year] : @years.keys).each do |y| r[y] = months end r end # # date spec: # (1) none -> all # (2) month=xH -> half # (3) year=YYYY;month=xH -> half # (4) month=xQ -> quarter # (5) year=YYYY;month=xQ -> quarter # (6) month=MM -> month # (7) year=YYYY;month=MM -> month # (8) year=YYYY -> year # def set_mode if @year.nil? and @month.nil? @mode = :all end if /\d{4}/ === @year.to_s @mode = :year else @year = nil end if /[12]H/ === @month.to_s @mode = :half elsif /[1-4]Q/ === @month.to_s @mode = :quarter elsif (1..12).include?(@month.to_i) @mode = :month else @month = nil end end end # # Cache # class Cache include ERB::Util def initialize(conf, bind) @conf = conf @binding = bind # ...... very ugly @plugin = @binding.eval('self') @categories = nil end def get(db, cat) JSON.load(db.get(cat) || '{}') end def set(db, cat, data) db.set(cat, data.to_json) end def add_categories(list) return if list.nil? or list.empty? replace_categories(restore_categories + list) end def replace_categories(list) @categories = list end def restore_categories return @categories if @categories @plugin.__send__(:transaction, 'category') do |db| @categories = db.keys end return @categories end # # cache each section of diary # used in update_proc # def replace_sections(diary) return if diary.nil? or !diary.categorizable? categorized = categorize_diary(diary) categories = restore_categories deleted = [] ymd = diary.date.strftime('%Y%m%d') @plugin.__send__(:transaction, 'category') do |db| categories.each do |c| cat = get(db, c) || {} if diary.visible? and categorized[c] cat.update(categorized[c]) set(db, c, cat) else # diary is invisible or sections of this category is deleted cat.delete(ymd) if cat.empty? db.delete(c) deleted << c else set(db, c, cat) end end end if !deleted.empty? replace_categories(categories - deleted) end end end # # (re)create category cache # def recreate(years) list = [] @plugin.__send__(:transaction, 'category') do |db| db.keys.each {|key|db.delete(key)} years.each do |y, ms| ms.each do |m| m = DiaryContainer::find_by_month(@conf, "#{y}#{m}") m.diaries.each do |ymd, diary| next if !diary.visible? or !diary.categorizable? categorized = categorize_diary(diary) categorized.keys.each do |c| cat = get(db, c) || {} set(db, c, cat.update(categorized[c])) end diary.each_section do |s| list |= s.categories unless s.categories.empty? end end end end end replace_categories(list) end # # categorize sections of category of years # # {"category" => {"yyyymmdd" => [[idx, title, excerpt], ...], ...}, ...} # def categorize(category, years) categories = category - ['ALL'] if categories.empty? categories = restore_categories else categories &= restore_categories end categorized = {} begin categorized.clear categories.each do |c| @plugin.__send__(:transaction, 'category') do |db| categorized[c] = get(db, c) end categorized[c].keys.each do |ymd| y, m = ymd[0,4], ymd[4,2] if years[y].nil? or !years[y].include?(m) categorized[c].delete(ymd) end end categorized.delete(c) if categorized[c].empty? end rescue NoMethodError # when categorized[c] is nil recreate(years) retry end categorized end private def cache_file(category = nil) if category "#{@dir}/#{u( category ).gsub(/%20/,'+')}" else "#{@dir}/category_list" end end # # categorize sections of diary # # {"category" => {"yyyymmdd" => [[idx, title, excerpt], ...]}} # def categorize_diary(diary) categorized = {} ymd = diary.date.strftime('%Y%m%d') idx = 1 diary.each_section do |s| shorten = begin body = %Q|apply_plugin(#{s.body_to_html.dump}, true)| @conf.shorten(eval(body, @binding)) rescue NameError "" end s.categories.each do |c| categorized[c] = {} if categorized[c].nil? categorized[c][ymd] = [] if categorized[c][ymd].nil? categorized[c][ymd] << [idx, s.stripped_subtitle_to_html, shorten] end idx +=1 end categorized end end end # module Category # read cache here so that you can use category with secure mode. @category_cache = Category::Cache.new(@conf, binding) # # display categories on update form # def category_edit_support_flatlist ret = '' ret << '<div class="field title">' ret << "#{@category_conf_label}:\n" @categories.each do |c| ret << %Q!| <span class="category-item">#{h c}</span>\n! end ret << "|\n</div>\n<br>\n" ret end def category_edit_support_dropdown ret = '' ret << '<div class="field title">' ret << %Q|#{@category_conf_label}: <select id="category-candidate" name="category-candidate">\n| @categories.each do |c| ret << %Q!<option>#{h c}</option>\n! end ret << "|\n</select>\n</div>\n<br>\n" ret end if @conf['category.edit_support'] != 0 then enable_js( 'category.js' ) add_edit_proc do |date| ret = '' unless @categories.size == 0 then ret << if @conf['category.edit_support'] == 2 then category_edit_support_dropdown else category_edit_support_flatlist end end end end # # when update diary, update cache # add_update_proc do if /^(append|replace)$/ =~ @mode cache = @category_cache list = [] diary = @diaries[@date.strftime('%Y%m%d')] diary.each_section do |s| list |= s.categories end cache.add_categories(list) cache.replace_sections(diary) end end # # configuration # def category_icon_find_icons return if @category_all_icon @category_all_icon = [] %w(png jpg gif bmp).each do |e| @category_all_icon += Dir.glob("#{@category_icon_dir}*.#{e}").map {|i| File.basename(i)} end @category_all_icon.sort! end def category_icon_select(category) options = %Q|<\t<option value="none">#{@category_icon_none_label}</option>\n| @category_all_icon.each do |i| options << %Q|\t<option value="#{h i}"#{" selected" if @category_icon[category] == i}>#{h i}</option>\n| end <<HTML <select name="category.icon.#{h category}"> #{options} </select> HTML end def category_icon_sample @category_all_icon.map do |i| %Q|<img src="#{h @category_icon_url}#{h i}" alt="#{h i}" title="#{h i}">\n| end.join("/\n") end if @mode == 'conf' || @mode == 'saveconf' add_conf_proc( 'category', @category_conf_label, 'basic' ) do if @mode == 'saveconf' if @cgi.valid?( 'category_initialize' ) @category_cache.recreate(@years) end [ 'category.header1', 'category.header2', ].each do |name| @conf[name] = @conf.to_native( @cgi.params[name][0] ) end [ 'category.prev_year', 'category.next_year', 'category.prev_half', 'category.next_half', 'category.prev_quarter', 'category.next_quarter', 'category.prev_month', 'category.next_month', 'category.this_year', 'category.this_half', 'category.this_quarter', 'category.this_month', 'category.all_diary', 'category.all_category', 'category.all', ].each do |name| @conf[name] = @conf.to_native( @cgi.params[name][0] ) end if ["month", "quarter", "half", "year", "all"].index(@cgi.params["category.period"][0]) @conf["category.period"] = @cgi.params["category.period"][0] end @conf['category.edit_support'] = (@cgi.params['category.edit_support'][0] || '1').to_i end category_conf_html end category_icon_find_icons if @cgi.params['conf'][0] == 'category_icon' add_conf_proc( 'category_icon', @category_icon_conf_label, 'basic' ) do if @mode == 'saveconf' unless @conf.secure [ 'category.icon_dir', 'category.icon_url', ].each do |name| @conf[name] = @cgi.params[name][0].sub(%r|/*$|, '/') end category_icon_location_init end @cgi.params.keys.each do |key| next unless /\Acategory\.icon\..*\z/ === key category = key.sub(/\Acategory\.icon\./, '') if @cgi.params[key][0] == 'none' @category_icon.delete(category) else @category_icon[category] = @cgi.params[key][0] end end category_icon_save end category_icon_conf_html end end @categories = @category_cache.restore_categories.sort_by{|e| e.downcase} if @mode == 'categoryview' info = Category::Info.new(@cgi, @years, @conf) @categorized = @category_cache.categorize(info.category, info.years) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 �������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/category.rb�����������������������������������������������������������0000664�0000000�0000000�00000013313�13626457307�0020351�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # category.rb : tDiary plugin for show category pages # # Copyright (C) 2016 TADA Tadashi # Distributed under the GPL2 or any later version. # require 'tdiary/diary_container' # read cache here so that you can use category with secure mode. @conf['category.header1'] = '' @conf['category.header2'] = '<%= category_dropdown_list %>' @category_icon = {} @categories = transaction('category'){|db|db.keys}.sort_by{|c|c.downcase} module Category class Info def initialize(cgi, _, conf) @cgi, @conf = cgi, conf end def category @name ||= @conf.to_native(@cgi.params['category'][0] || '', @conf.encoding_old) end end end def category_title info = Category::Info.new(@cgi, nil, @conf) "[#{info.category}]" end def category_anchor(category) %Q|[<a href="#{h @index}?category=#{u category}" title="#{h category}">#{h category}</a>]| end def category_list info = Category::Info.new(@cgi, _, @conf) @categories.map do |c| %Q|<a href="#{h @index}?category=#{h c}">#{h c}</a>| end.join(" | \n") end def category_dropdown_list(label = nil, _ = nil) label ||= 'show category list' info = Category::Info.new(@cgi, _, @conf) category = info.category category = [] if category.empty? options = '' @categories.each do |c| options << %Q|<option value="#{h c}"#{" selected" if category.include?(c)}>#{h c}</option>\n| end <<-HTML <form method="get" action="#{h @index}"><div> <select name="category"> #{options} </select> <input type="submit" value="#{label}"> </div></form> HTML end def category_transaction(categories) transaction('category') do |db| (categories || db.keys).each do |category| Hash[*JSON.load(db.get(category) || '{}').sort_by{|d,_|d}.flatten(1)].each do |ymd, diaries| yield db, category, ymd, diaries end end end end def category_list_sections info = Category::Info.new(@cgi, nil, @conf) r = '' r << <<-HTML <div class="category day"> <h2> <span class="title"> <a href="#{h @conf.index}?category=#{u info.category}">#{h info.category}</a> </span> </h2> <div class="body"> <ul class="category"> HTML category_transaction([info.category]) do |db, category, ymd, diaries| date = Time.local(*ymd.scan(/(.{4})(..)(..)/)[0]).strftime(@conf.date_format) diaries.sort_by{|i|i[0]}.each do |idx, title, excerpt| r << <<-HTML <li> <a href="#{h @index}#{anchor "#{ymd}#p#{'%02d' % idx}"}" title="#{h excerpt}"> #{date}#p#{'%02d' % idx} </a> #{apply_plugin(title)} </li> HTML end end r << <<-HTML </ul> </div> </div> HTML return r end def category_serialize(diary) data = {} ymd = diary.date.strftime('%Y%m%d') idx = 1 diary.each_section do |s| shorten = begin body = %Q|apply_plugin(#{s.body_to_html.dump}, true)| @conf.shorten(eval(body)) rescue NameError "" end s.categories.each do |c| data[c] ||= {} data[c][ymd] ||= [] data[c][ymd] << [idx, s.stripped_subtitle_to_html, shorten] end idx +=1 end data end def category_rebuild(years) transaction('category') do |db| cache = Hash.new{{}} @years.each do |y, ms| ms.each do |m| m = DiaryContainer::find_by_month(@conf, "#{y}#{m}") m.diaries.each do |ymd, diary| next if !diary.visible? or !diary.categorizable? serialize = category_serialize(diary) serialize.keys.each do |category| cache[category] = cache[category].merge!(serialize[category]) end end end end db.keys.each {|key| db.delete(key)} cache.each do |category, diaries| db.set(category, diaries.to_json) end end end add_update_proc do if /^(append|replace)$/ =~ @mode ymd = @date.strftime('%Y%m%d') diary = @diaries[ymd] serialize = category_serialize(diary) transaction('category') do |db| (db.keys + serialize.keys).uniq.each do |category| data = JSON.load(db.get(category) || '{}') if diary.visible? and serialize[category] data.update(serialize[category]) db.set(category, data.to_json) else data.delete(ymd) if data.empty? db.delete(category) else db.set(category, data.to_json) end end end end end end # # edit support: insert category to editing diary using JavaScript # def category_edit_support_flatlist(categories) ret = '' ret << '<div class="field title">' ret << "#{@category_conf_label}:\n" categories.each do |c| ret << %Q!| <span class="category-item">#{h c}</span>\n! end ret << "|\n</div>\n<br>\n" ret end def category_edit_support_dropdown(categories) ret = '' ret << '<div class="field title">' ret << %Q|#{@category_conf_label}: <select id="category-candidate" name="category-candidate">\n| categories.each do |c| ret << %Q!<option>#{h c}</option>\n! end ret << "|\n</select>\n</div>\n<br>\n" ret end if @mode =~ /^(form|edit)$/ and @conf['category.edit_support'] != 0 enable_js( 'category.js' ) add_edit_proc do |date| ret = '' transaction('category') do |db| categories = db.keys unless categories.size == 0 then if @conf['category.edit_support'] == 2 then ret << category_edit_support_dropdown(categories) else ret << category_edit_support_flatlist(categories) end end end ret end end if @mode =~ /^categoryview$/ and @conf['category.show_reverse'] enable_js('category.js') end if @mode == 'conf' || @mode == 'saveconf' add_conf_proc('category', @category_conf_label, 'basic') do if @mode == 'saveconf' category_rebuild(@years) if @cgi.valid?('category_initialize') @conf['category.edit_support'] = (@cgi.params['category.edit_support'][0] || '1').to_i @conf['category.show_reverse'] = !!(@cgi.params['category.show_reverse'][0] == 'true') end category_conf_html end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/category_autocomplete.rb����������������������������������������������0000664�0000000�0000000�00000001735�13626457307�0023137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # category_autocomplete.rb : Support the automatic input of the category # using jQuery UI autocomplete. # # Copyright (C) 2010-2012, tamoot <tamoot+tdiary@gmail.com> # You can redistribute it and/or modify it under GPL2 or any later version. # if /\A(?:form|preview|append|edit|update)\z/ =~ @mode add_header_proc do %Q|<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.min.css"/>| end enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') enable_js('caretposition.js') enable_js('category_autocomplete.js') if @categories.size > 0 categories_json = @categories.map{ |c| "\"#{c}\"" } add_js_setting('$tDiary.plugin.category_autocomplete') add_js_setting('$tDiary.plugin.category_autocomplete.candidates', "[#{categories_json.join(",")}]") end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 �����������������������������������tdiary-core-5.1.1/misc/plugin/comment_ajax.rb�������������������������������������������������������0000664�0000000�0000000�00000000462�13626457307�0021202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������if @mode == 'day' and not bot? then enable_js('comment_ajax.js') add_js_setting('$tDiary.plugin.comment_ajax') add_js_setting('$tDiary.plugin.comment_ajax.theme', %Q["#{theme_url}"]) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vi: ts=3 sw=3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/comment_emoji_autocomplete.rb�����������������������������������������0000664�0000000�0000000�00000001321�13626457307�0024136�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # comment_emoji_autocomplete.rb : Support the automatic input of the emoji # using jQuery UI autocomplete. # # Copyright (C) 2013, tamoot <tamoot+tdiary@gmail.com> # You can redistribute it and/or modify it under GPL2 or any later version. # if /\A(?:day)\z/ =~ @mode add_header_proc do %Q|<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.min.css"/>| end enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') enable_js('caretposition.js') enable_js('comment_emoji_autocomplete.js') end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/comment_mail-qmail.rb�������������������������������������������������0000664�0000000�0000000�00000004105�13626457307�0022300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# comment_mail_qmail.rb # # qmailを使ってツッコミをメールで知らせる # 入れるだけで動作する。 # # Options: # 設定画面から指定できるもの(ツッコミメール系プラグイン共通): # @options['comment_mail.enable'] # メールを送るかどうかを指定する。true(送る)かfalse(送らない)。 # 無指定時はfalse。 # @options['comment_mail.header'] # メールのSubjectに使う文字列。振り分け等に便利なように指定する。 # 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が # 付く。ただし指定文字列中に、%に続く英字があった場合、それを # 日付フォーマット指定を見なす。つまり「日付」の部分は # 自動的に付加されなくなる(コメント番号は付加される)。 # 無指定時には空文字。 # @options['comment_mail.receivers'] # メールを送るアドレス文字列。カンマで区切って複数指定できる。 # 無指定時には日記筆者のアドレスになる。 # # tdiary.confでのみ指定できるもの: # @options['comment_mail.qmail'] # qmail_injectコマンドのパスを指定する。 # 無指定時には「'/var/qmail/bin/qmail-inject'」。 # # Copyright (c) 2003 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # def comment_mail( text, to ) begin qmail = @conf['comment_mail.qmail'] || '/var/qmail/bin/qmail-inject' open( %Q[|'#{qmail.gsub(/'/, '')}' -f '#{@conf.author_mail.gsub( /'/, '' )}' '#{to.map{|x|x.gsub(/'/,'')}.join("' '")}'], 'w' ) do |o| o.write( text ) end rescue $stderr.puts $! end end add_update_proc do comment_mail_send if @mode == 'comment' end add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do comment_mail_basic_setting comment_mail_basic_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/comment_mail-sendmail.rb����������������������������������������������0000664�0000000�0000000�00000004027�13626457307�0022774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# comment_mail_sendmail.rb # # sendmailを使ってツッコミをメールで知らせる # 入れるだけで動作する。 # # Options: # 設定画面から指定できるもの(ツッコミメール系プラグイン共通): # @options['comment_mail.enable'] # メールを送るかどうかを指定する。true(送る)かfalse(送らない)。 # 無指定時はfalse。 # @options['comment_mail.header'] # メールのSubjectに使う文字列。振り分け等に便利なように指定する。 # 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が # 付く。ただし指定文字列中に、%に続く英字があった場合、それを # 日付フォーマット指定を見なす。つまり「日付」の部分は # 自動的に付加されなくなる(コメント番号は付加される)。 # 無指定時には空文字。 # @options['comment_mail.receivers'] # メールを送るアドレス文字列。カンマで区切って複数指定できる。 # 無指定時には日記筆者のアドレスになる。 # # tdiary.confでのみ指定できるもの: # @options['comment_mail.sendmail'] # sendmailコマンドのパスを指定する。 # 無指定時には「'/usr/sbin/sendmail'」。 # # Copyright (c) 2003 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # def comment_mail( text, to ) begin sendmail = @conf['comment_mail.sendmail'] || '/usr/sbin/sendmail' open( %Q[|'#{sendmail.gsub(/'/, '')}' '#{to.map{|x|x.gsub(/'/, '')}.join("' '")}'], 'w' ) do |o| o.write( text ) end rescue $stderr.puts $! end end add_update_proc do comment_mail_send if @mode == 'comment' end add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do comment_mail_basic_setting comment_mail_basic_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/comment_mail-smtp.rb��������������������������������������������������0000664�0000000�0000000�00000005610�13626457307�0022162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# comment_mail-smtp.rb # # SMTPプロトコルを使ってツッコミをメールで知らせる # 同一ホスト内にSMTPサーバがある場合は有効にするだけで動作する # # Options: # 設定画面から指定できるもの(ツッコミメール系プラグイン共通): # @options['comment_mail.enable'] # メールを送るかどうかを指定する。true(送る)かfalse(送らない)。 # 無指定時はfalse。 # @options['comment_mail.header'] # メールのSubjectに使う文字列。振り分け等に便利なように指定する。 # 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が # 付く。ただし指定文字列中に、%に続く英字があった場合、それを # 日付フォーマット指定を見なす。つまり「日付」の部分は # 自動的に付加されなくなる(コメント番号は付加される)。 # 無指定時には空文字。 # @options['comment_mail.receivers'] # メールを送るアドレス文字列。カンマで区切って複数指定できる。 # 無指定時には日記筆者のアドレスになる。 # # tdiary.confでのみ指定できるもの: # @options['comment_mail.smtp_host'] # @options['comment_mail.smtp_port'] # それぞれ、メール送信に使うSMTPサーバのホスト名とポート番号。 # 無指定時はそれぞれ「'localhost'」と「25」。 # 以下は通常は不要。必要に応じて指定する: # @options['comment_mail.user_name'] # @options['comment_mail.password'] # SMTP認証が必要な場合のユーザ名とパスワード # @options['comment_mail.authentication'] # SMTP認証の方式。:plainや:loginなど(Mail gemに指定できるもの) # @options['comment_mail.starttls'] # TLSに自動接続する(true/false) (Mail gem) # # Copyright (c) 2015 TADA Tadashi <t@tdtds.jp> # You can distribute this file under the GPL2 or any later version. # def comment_mail( text, to ) begin require 'mail' mail = Mail.new( text ) delivery_opts = { address: @conf['comment_mail.smtp_host'] || 'localhost', port: @conf['comment_mail.smtp_port'] || 25, authentication: @conf['comment_mail.authentication'], user_name: @conf['comment_mail.user_name'], password: @conf['comment_mail.password'], enable_starttls_auto: @conf['comment_mail.starttls'] }.delete_if{|k,v| v == nil} mail.delivery_method( :smtp, delivery_opts ) mail.deliver rescue $stderr.puts $! end end add_update_proc do comment_mail_send if @mode == 'comment' end add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do comment_mail_basic_setting comment_mail_basic_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/comment_rank.rb�������������������������������������������������������0000664�0000000�0000000�00000001635�13626457307�0021215�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# comment_rank.rb # # comment_rank: ツッコミの数でランキング # パラメタ: # max: 最大表示数(未指定時:5) # sep: セパレータ(未指定時:空白) # except: 無視する名前(いくつもある場合は,で区切って並べる) # # Copyright (c) 2002 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # # def comment_rank( max = 5, sep = ' ', *except ) name = Hash::new(0) @diaries.each_value do |diary| diary.each_comment do |comment| next if except.include?(comment.name) name[comment.name] += 1 end end result = [] name.sort{|a,b| (a[1])<=>(b[1])}.reverse.each_with_index do |ary,idx| break if idx >= max result << "<strong>#{idx+1}.</strong>#{h ary[0]}(#{ary[1].to_s})" end result.join( sep ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/counter.rb������������������������������������������������������������0000664�0000000�0000000�00000061720�13626457307�0020220�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# counter.rb # # Access counter plugin. # # 1. Usage # counter(figure, filetype = ""): Show number of all visitors. # counter_today(figure, filetype = ""): Show number of visitors for today. # counter_today(figure, filetype = ""): Show number of visitors for yesterday. # filetype: jpg, gif, png ... . # # kiriban?: Return true when the number is a kiriban. # kiriban_today?: Return true when the number is a kiriban(for today's couner). # # counter # counter 3 # coutner 3, "jpg" # counter_today 4, "jpg" # counter_yesterday # # 2. Documents # See URLs below for more details. # http://ponx.s5.xrea.com/hiki/counter.rb.html (English) # http://ponx.s5.xrea.com/hiki/ja/counter.rb.html (Japanese) # # Copyright (c) 2002-2006 Masao Mutoh # You can redistribute it and/or modify it under GPL2 or any later version. # =begin ChangeLog 2006-02-14 Masao Mutoh * Add some user-agents. * 2.0.2 2006-02-14 mitty * Fixed a problem when counter2_access.dat is broken. 2006-02-07 Masao Mutoh * Revert the log file name from counter2.log to counter.log. Reported by Ken-ichi Mito. * 2.0.1 2006-01-20 Masao Mutoh * Improves the speed and stability. - Separate data to counterdata and accessdata. - counterdata is the target of backup, but accessdata doesn't do backup. - change a key of an Array of String to a hash. - Removed "counter.daily_backup" option. Now daily_backup is applied everyday unless this setting. - Add a new "counter.max_keep_access_num" option which you can set the max number to keep users in the accessdata file to avoid to become too large the accessdata file. * Follow tDiary framework. - Add configuration page. * Misc - Removed "counter.deny_remote_addrs" option. 2004-10-01 Masao Mutoh * Improved process against bots. @options["bot"] is now supported. 2003-11-15 Masao Mutoh * translate documents to English. 2003-02-15 Masao Mutoh * counter.datが大きくなる不具合の修正 * version 1.6.3 2002-11-26 Junichiro Kita <kita@kitaj.no-ip.com> * remove 'cgi.cookies = nil' in TDiaryCounter::main 2002-11-19 TADA Tadashi <sho@spc.gr.jp> * for squeeze.rb error more. * version 1.6.2 2002-11-13 TADA Tadashi <sho@spc.gr.jp> * for squeeze.rb error. 2002-10-12 Masao Mutoh * 初めて使うときに動作しなくなっていた不具合の修正。 * 1日1回保持しているユーザ情報をクリーンアップするようにした。 * version 1.6.1 2002-08-30 Masao Mutoh * データファイルが読み込めなくなったとき、1つ前のバックアップデータ を用いて復旧するようにした(その際に、1つ前のバックアップデータは counter.dat.?.bakという名前でバックアップされる)。さらに1つ前の バックアップデータからも復旧できなかった場合は全てのカウンタ値を 0にしてエラー画面が表示されないようにした。 * version 1.6.0 2002-07-23 Masao Mutoh * バックアップファイルのファイル名のsuffixを曜日(0-6の数値)にした。 従って、1週間毎に古いファイルは上書きされるのでファイルの数は 最大7つとなる。数字が新しいものが最新というわけではないので注意。 (proposed by Junichiro KITA <kita@kitaj.no-ip.com>) * version 1.5.1 2002-07-19 Masao Mutoh * 日々単位でデータをバックアップするようにした。 @options["counter.dairy_backup"]で指定。falseを指定しない限り バックアップする。 * Date#==メソッドでnilを渡さないように修正 * require 'pstore'追加(tDiary version 1.5.x系対応) * logのフォーマット変更(全て・今日・昨日のデータを出力) * @options["counter.deny_same_src_interval"]のデフォルト値を2時間 に変更した。 * version 1.5.0 2002-05-19 Masao Mutoh * Cookieを使うことのできない同一クライアントからの連続アクセスを、 カウントアップしないようにした。 * @options["counter.deny_same_src_interval"]追加。連続GETの間隔を指定。 デフォルトで0.1時間(6分)。 * version 1.4.0 2002-05-11 Masao Mutoh * 初期値を与えない場合は5桁としていたが、「前0をなくす」に変更した。 また、前0を無くす場合は0を指定しても良い。 * version 1.3.0 2002-05-05 Masao Mutoh * @debug = true 削除 :-> * コメント変更 * version 1.2.1 2002-05-04 Masao Mutoh * tlinkプラグインからのアクセスをカウントしてしまう不具合の修正 * @options["counter.deny_user_agents"]追加 * @options["counter.deny_remote_addrs"]追加 * @options["counter.init_num"]追加。キリ番機能との関係で、counter * メソッドの引数のinit_numはobsoleteとします。 * @options["counter.kiriban"], @options["counter.kiriban_today"]追加 * キリ番機能追加(kiriban?,kiriban_today?メソッド追加) * version 1.2.0 2002-04-27 Masao Mutoh * add_header_procを使わないようにした * @options["counter.timer"]が有効にならない不具合の修正 * @options["counter.log"]追加。trueを指定するとcounter.dat と同じディレクトリにcounter.logというファイルを作成し 1日前のアクセス数を記録するようにした * cookieの値としてバージョン番号を入れるようにした * version 1.1.0 2002-04-25 Masao Mutoh * HEADでアクセスがあった場合に再びカウントされるように なってしまっていた不具合の修正(by NT<nt@24i.net>) * version 1.0.4 2002-04-24 Masao Mutoh * ツッコミを入れたときにエラーが発生する不具合の修正 * version 1.0.3 2002-04-23 Masao Mutoh * データファイルを削除後、クッキーが有効期間中の端末から アクセスした場合に@todayが0になる不具合の修正 * コメント入れたときに数字が表示されない不具合の修正 * HEADでアクセスがあった場合はカウントしないようにした (reported by NT<nt@24i.net>, suggested a solution by TADA Tadashi <sho@spc.gr.jp>) * version 1.0.2 2002-04-21 Masao Mutoh * CSSで_を使っているところを-に直した(reported by NT<nt@24i.net>) * TDiaryCountData#upで@allが+1されない不具合の修正 * version 1.0.1 2002-04-14 Masao Mutoh * version 1.0.0 =end @counter_default_user_agents = "feed|tlink|WWWOFFLE|^WWWC|^Wget|WWWD|fetch|Antenna|antenna|Infoseek SideWinderBlogRanking|^ichiro|CaptainNAMAAN|Download Ninja|ping.blogger.jp|ia_archiver|Nutch|^Mediapartners.Google|lwp.trivial|nomadscafe_ra|rawler|KMHTTP|Tarantula|Pockey|Microsoft URL Control|Livedoor SF|^Blogline|Yahoo|^Y.J|Ask Jeeves|^Commerobo|^livedoorCheckers|^voyager|^findlinks|^\-$|FunWebProducts|^Headline|lmspider|^FreshReader|^FyberSpider|^Hatena|^intraVnews|^Nandemorss|^Nutch|^1.0$|^Blogshares|Crawl|MSNPTC|MS Search|^Pompos|^Portsurvey|^RSS_READER|^gooRSSreader|^kinja|^larbin|^research\-spider|bot|^HTTP$|SBIder|StackRambler|Wavefire|samidare|MarkAgent|^Java|NewsWire|libwww|ping.blo.gs|wish.lim|Mozilla.4.76|rAntenna|PEAR|Blogslive|edgeio.retriever|^Jakarta" #not bot: RssBar, AppleSyndication def counter_allow? return false if bot? if @options if @options["counter.deny_user_agents"] if @options["counter.deny_user_agents"].kind_of? Array @options["counter.deny_user_agents"] = @options["counter.deny_user_agents"].uniq.join('|') elsif @options["counter.deny_user_agents"].size > 1 agents = Regexp.new("(#{@counter_default_user_agents}|#{@options["counter.deny_user_agents"]})", true) else agents = Regexp.new("(#{@counter_default_user_agents})", true) end else agents = Regexp.new("(#{@counter_default_user_agents})", true) end return false if agents =~ @cgi.user_agent end true end if @cgi.request_method == 'GET' and counter_allow? require 'date' require 'pstore' require 'fileutils' eval(<<TOPLEVEL_CLASS, TOPLEVEL_BINDING) class TDiaryAccessData attr_accessor :ignore_cookie #means ALWAYS ignore a cookie. def previous_access_time(time, remote_addr, user_agent, interval, maxaccessnum) @time = time @users = Hash.new unless @users key = (remote_addr + user_agent).hash ret = @users[key] remove_olddata(interval) @users[key] = @time if @users.size < maxaccessnum ret end def remove_olddata(interval) @users.reject!{|key, val| @time - val > interval * 3600 } end end class TDiaryCountData attr_reader :today, :yesterday, :all, :newestday def initialize(path, all = 0, today = 0, yesterday = 0) @path = path @newestday = Date.today @all, @today, @yesterday = all, today, yesterday end def up(now, cache_path, cgi, _log) if @newestday if now == @newestday @today += 1 else log if _log @yesterday = ((now - 1) == @newestday) ? @today : 0 @today = 1 @newestday = now time = Time.now end else @yesterday = 0 @today = 1 @newestday = now end @all += 1 save end def load begin open(File.join(@path, "counter2.dat"), "r") do |io| eval(io.read) end rescue Exception back = (Dir.glob(File.join(@path, "counter2.dat.?")).sort{|a,b| File.mtime(a) <=> File.mtime(b)}.reverse)[0] open(back, "r") do |io| begin eval(io.read) rescue Exception end end save end self end def save(file = "counter2.dat") open(File.join(@path, file), "w") do |io| io.print "@newestday = Date.parse('" + @newestday.to_s + "'); " io.print "@all = " + @all.to_s + "; " io.print "@today = " + @today.to_s + "; " io.print "@yesterday = " + @yesterday.to_s end end def log if @newestday open(File.join(@path, "counter.log"), "a") do |io| io.print @newestday, " : ", @all, ",", @today, ",", @yesterday, "\n" end save("counter2.dat." + @newestday.wday.to_s) end end end TOPLEVEL_CLASS module TDiaryCounter extend ERB::Util @version = "2.0.2" def run(cache_path, cgi, options) timer = options["counter.timer"] if options timer = 12 unless timer # 12 hour @init_num = options["counter.init_num"] if options @init_num = 0 unless @init_num dir = File.join(cache_path, "counter") path = File.join(dir, "counter2_access.dat") today = Date.today Dir.mkdir(dir, 0700) unless FileTest.exist?(dir) cookie = nil begin cookie = main(cache_path, cgi, options, timer, dir, path, today) rescue => e @cnt = TDiaryCountData.new(dir).load if e.message =~ /marshal|dump|load|referred|depth|io needed|size/i begin File.unlink path rescue end end end cookie end def main(cache_path, cgi, options, timer, dir, path, today) cookie = nil if FileTest.exist?(File.join(dir, "counter.dat")) db = PStore.new(File.join(dir, "counter.dat")) db.transaction do old = db["countdata"] TDiaryCountData.new(dir, old.all, old.today, old.yesterday).save end FileUtils.mv(File.join(dir, "counter.dat"), File.join(dir, "counter.dat.old")) end db = PStore.new(path) db.transaction do begin @access = db["accessdata"] rescue PStore::Error end unless @access @access = TDiaryAccessData.new end begin @cnt = TDiaryCountData.new(dir).load rescue Exception @cnt = TDiaryCountData.new(dir) end changed = false if new_user?(cgi, options) @cnt.up(today, dir, cgi, (options and options["counter.log"])) cookie = CGI::Cookie.new({"name" => "tdiary_counter", "value" => @version, "expires" => Time.now + timer * 3600}) changed = true end if options["counter.kiriban"] if options["counter.kiriban"].kind_of? String if options["counter.kiriban"] == "" options["counter.kiriban"] = [-1] elsif options["counter.kiriban"].include?(",") options["counter.kiriban"] = options["counter.kiriban"].split(",").collect{|i| i.to_i} else options["counter.kiriban"] = [options["counter.kiriban"].to_i] end end @kiriban = options["counter.kiriban"].include?(@cnt.all + @init_num) end if ! @kiriban and options["counter.kiriban_today"] if options["counter.kiriban_today"].kind_of? String if options["counter.kiriban_today"] == "" options["counter.kiriban_today"] = [-1] elsif options["counter.kiriban_today"].include?(",") options["counter.kiriban_today"] = options["counter.kiriban_today"].split(",").collect{|i| i.to_i} else options["counter.kiriban_today"] = [options["counter.kiriban_today"].to_i] end end @kiriban_today = options["counter.kiriban_today"].include?(@cnt.today) end if @access.ignore_cookie @access.ignore_cookie = false changed = true end #when it is kiriban time, ignore the cookie next access time. if @kiriban or @kiriban_today @access.ignore_cookie = true changed = true end if changed db["accessdata"] = @access end end cookie end def new_user_without_cookie?(cgi, options) if options interval = options["counter.deny_same_src_interval"] maxaccessnum = options["counter.max_keep_access_num"] end interval = 2 unless interval # 2 hour. maxaccessnum = 10000 unless maxaccessnum # 2 hour. current_time = Time.now previous_access_time = @access.previous_access_time(current_time, cgi.remote_addr, cgi.user_agent, interval, maxaccessnum) if previous_access_time ret = current_time - previous_access_time > interval * 3600 else ret = true end ret end def new_user?(cgi, options) return true if @access.ignore_cookie if cgi.cookies if cgi.cookies.keys.include?("tdiary_counter") ret = false else ret = new_user_without_cookie?(cgi, options) end else ret = new_user_without_cookie?(cgi, options) end ret end def format(classtype, theme_url, cnt, figure = 0, filetype = "", init_num = 0, &proc) str = "%0#{figure}d" % (cnt + init_num) result = %Q[<span class="counter#{classtype}">] depth = 0 str.scan(/./).each do |num| if block_given? result << %Q[<img src="#{h theme_url}/#{yield(num)}" alt="#{num}" />] elsif filetype == "" result << %Q[<span class="counter-#{depth}"><span class="counter-num-#{num}">#{num}</span></span>] else result << %Q[<img src="#{h theme_url}/#{num}.#{filetype}" alt="#{num}" />] end depth += 1 end result << "</span>" end def called?; @called; end def called; @called = true; end def all; @cnt.all + @init_num; end def today; @cnt.today; end def yesterday; @cnt.yesterday; end def kiriban?; @kiriban; end def kiriban_today?; @kiriban_today; end module_function :new_user?, :new_user_without_cookie?, :all, :today, :yesterday, :format, :main, :run, :kiriban?, :kiriban_today? end #init_num is deprecated. #please replace it to @options["counter.init_num"] def counter(figure = 0, filetype = "", init_num = 0, &proc) TDiaryCounter.format("", theme_url, TDiaryCounter.all, figure, filetype, init_num, &proc) end def counter_today(figure = 0, filetype = "", &proc) TDiaryCounter.format("-today", theme_url, TDiaryCounter.today, figure, filetype, 0, &proc) end def counter_yesterday(figure = 0, filetype = "", &proc) TDiaryCounter.format("-yesterday", theme_url, TDiaryCounter.yesterday, figure, filetype, 0, &proc) end def kiriban? TDiaryCounter.kiriban? end def kiriban_today? TDiaryCounter.kiriban_today? end tdiary_counter_cookie = TDiaryCounter.run(@cache_path, @cgi, @options) if tdiary_counter_cookie if defined?(add_cookie) add_cookie(tdiary_counter_cookie) else @cookie = tdiary_counter_cookie if tdiary_counter_cookie end end def kiriban if kiriban? msg = @options["counter.kiriban_msg"] ? @options["counter.kiriban_msg"] : "" ERB.new(msg).result(binding) elsif kiriban_today? msg = @options["counter.kiriban_today_msg"] ? @options["counter.kiriban_today_msg"] : "" ERB.new(msg).result(binding) else @options["counter.kiriban_nomatch_msg"] ? @options["counter.kiriban_nomatch_msg"] : "" end end end @counter_conf_counter ||= "アクセスカウンタ" @counter_conf_init_head ||= "初期値の指定" @counter_conf_init_desc ||= "「全て」表示の際のカウンタの初期値を指定できます。他のアクセスカウンタからの乗り換える時などに使用すると良いでしょう。デフォルトは0です。" @counter_conf_init_label ||= " 初期値:" @counter_conf_log_head ||= "ログの取得" @counter_conf_log_desc ||= " 日別のアクセス数をログファイルに残したい場合に指定します。デフォルトは「残す」です。基本的には残すようにしましょう。<br/>ログファイルは、"#{@cache_path}/counter/counter.log" に保存されます。" @counter_conf_log_true ||= "残す" @counter_conf_log_false ||= "残さない" @counter_conf_timer_head ||= "訪問間隔の指定" @counter_conf_timer_desc ||= "指定した期間、繰り返し訪問してくるユーザをカウントアップしないようになっています(Cookieを使っています)。デフォルトは12(時間)です。" @counter_conf_timer_label ||= "訪問間隔:" @counter_conf_timer_unit ||= "時間" @counter_conf_deny_same_src_interval_head ||= "カウントアップしない連続アクセス間隔の指定" @counter_conf_deny_same_src_interval_desc ||= "前出の「訪問間隔の指定」では、Cookie機能を持たないクライアントからのアクセスがあると、アクセスがあるたびにカウントアップしてしまいます。こちらの機能は、同一IPアドレス/クライアントアプリケーションからの連続アクセスをカウントアップしないようにします。デフォルトは4時間です。" @counter_conf_deny_same_src_interval_label ||= "カウントアップしない連続アクセス間隔:" @counter_conf_deny_same_src_interval_unit ||= "時間" @counter_conf_max_keep_access_num_head ||= "最大保持アクセス数の指定" @counter_conf_max_keep_access_num_desc ||= "前出の「カウントアップしない連続アクセス間隔の指定」で内部的に保持するクライアントユーザ数を指定します。数が多いほど処理に時間がかかるようになるため、小さい方が望ましいです。デフォルトは10000件です。" @counter_conf_max_keep_access_num_label ||= "最大保持アクセス数:" @counter_conf_max_keep_access_num_unit ||= "件" @counter_conf_deny_user_agents_head ||= "カウントアップしないユーザエージェント" @counter_conf_deny_user_agents_desc ||= "カウントしないユーザーエージェントを指定します。ロボットなどを指定すると良いでしょう。各エージェントを'|'(パイプ)で区切って並べてください(正規表現を使うことができます)。<pre>例:Googlebot|Bulkfeeds</pre><p>指定しない場合でも以下のユーザーエージェントからのアクセスはカウントされません。</p>" @counter_conf_deny_user_agents_label ||= "カウントしないユーザーエージェント:" @counter_conf_kiriban_head ||= "キリ番の指定" @counter_conf_kiriban_desc ||= "「全て」「今日」のキリ番を指定します。複数指定する場合は','(カンマ)を使ってください(例:100,123,300)。" @counter_conf_kiriban_label_all ||= "「全て」のキリ番:" @counter_conf_kiriban_label_today ||= "「今日」のキリ番:" @counter_conf_kiriban_messages_head ||= "kiribanプラグインで出力されるメッセージの指定" @counter_conf_kiriban_messages_desc ||= "ヘッダやサイドメニュー等に、<%= kiriban %>という形でキリ番プラグインを記述しておくと、キリ番になったときに(あるいはキリ番で無いときに)ここで記述する内容を表示します。ヘッダ同様、HTML形式です。" @counter_conf_kiriban_messages_label_all ||= "「全て」のキリ番メッセージ:" @counter_conf_kiriban_messages_label_today ||= "「今日」のキリ番メッセージ:" @counter_conf_kiriban_messages_label_nomatch ||= "キリ番では無いときのメッセージ:" def print_conf_html @conf["counter.init_num"] ||= 0 @conf["counter.log"] ||= true @conf["counter.timer"] ||= 12 @conf["counter.deny_same_src_interval"] ||= 4 @conf["counter.deny_user_agents"] ||= "" @conf["counter.max_keep_access_num"] ||= 10000 @conf["counter.kiriban"] ||= "" if @conf["counter.kiriban"].kind_of? Array @conf["counter.kiriban"] = @conf["counter.kiriban"].join(", ") end @conf["counter.kiriban_today"] ||= "" if @conf["counter.kiriban_today"].kind_of? Array @conf["counter.kiriban_today"] = @conf["counter.kiriban_today"].join(", ") end @conf["counter.kiriban_msg"] ||= "" @conf["counter.kiriban_today_msg"] ||= "" @conf["counter.kiriban_nomatch_msg"] ||= "" if @mode == 'saveconf' then @conf["counter.init_num"] = @cgi.params['counter.init_num'][0].to_i @conf["counter.log"] = @cgi.params['counter.log'][0] == "true" @conf["counter.timer"] = @cgi.params['counter.timer'][0].to_i @conf["counter.deny_same_src_interval"] = @cgi.params['counter.deny_same_src_interval'][0].to_i @conf["counter.deny_user_agents"] = @cgi.params['counter.deny_user_agents'][0] @conf["counter.max_keep_access_num"] ||= @cgi.params["counter.max_keep_access_num"][0].to_i @conf["counter.kiriban"] = @cgi.params["counter.kiriban"][0] @conf["counter.kiriban_today"] = @cgi.params["counter.kiriban_today"][0] @conf["counter.kiriban_msg"] = @conf.to_native(@cgi.params["counter.kiriban_msg"][0]).gsub(/\r\n/, "\n" ).gsub(/\r/, '').sub(/\n+\z/, '') @conf["counter.kiriban_today_msg"] = @conf.to_native(@cgi.params["counter.kiriban_today_msg"][0]).gsub(/\r\n/, "\n").gsub(/\r/, '').sub(/\n+\z/, '') @conf["counter.kiriban_nomatch_msg"] = @conf.to_native(@cgi.params["counter.kiriban_nomatch_msg"][0]).gsub(/\r\n/, "\n").gsub(/\r/, '').sub(/\n+\z/, '') end <<-HTML <h3 class="subtitle">#{@counter_conf_init_head}</h3> <p>#{@counter_conf_init_desc}</p> <p>#{@counter_conf_init_label}<input name="counter.init_num" value="#{h @conf["counter.init_num"]}" size="5"></p> <h3 class="subtitle">#{@counter_conf_log_head}</h3> <p>#{@counter_conf_log_desc}</p> <p> <select name="counter.log"> <option value="true"#{" selected" if @conf["counter.log"]}>#{@counter_conf_log_true}</option> <option value="false"#{" selected" if ! @conf["counter.log"]}>#{@counter_conf_log_false}</option> </select></li> </p> <h3 class="subtitle">#{@counter_conf_timer_head}</h3> <p>#{@counter_conf_timer_desc}</p> <p>#{@counter_conf_timer_label}<input name="counter.timer" value="#{h @conf["counter.timer"]}" size="2">#{@counter_conf_timer_unit}</p> <h3 class="subtitle">#{@counter_conf_deny_same_src_interval_head}</h3> <p>#{@counter_conf_deny_same_src_interval_desc}</p> <p>#{@counter_conf_deny_same_src_interval_label}<input name="counter.deny_same_src_interval" value="#{h @conf["counter.deny_same_src_interval"]}" size="2">#{@counter_conf_deny_same_src_interval_unit}</p> <h3 class="subtitle">#{@counter_conf_max_keep_access_num_head}</h3> <p>#{@counter_conf_max_keep_access_num_desc}</p> <p>#{@counter_conf_max_keep_access_num_label}<input name="counter.max_keep_access_num" value="#{h @conf["counter.max_keep_access_num"]}" size="7">#{@counter_conf_max_keep_access_num_unit}</p> <h3 class="subtitle">#{@counter_conf_deny_user_agents_head}</h3> <p>#{@counter_conf_deny_user_agents_desc}</p> <blockquote>#{(@conf["bot"]||[]).join(", ")}, #{@counter_default_user_agents.gsub(/\|/, ", ")}</blockquote> <dl><li>#{@counter_conf_deny_user_agents_label}<br/><textarea name="counter.deny_user_agents" cols="70" rows="3">#{@conf["counter.deny_user_agents"]}</textarea></li></dl> <h3 class="subtitle">#{@counter_conf_kiriban_head}</h3> <p>#{@counter_conf_kiriban_desc}</p> <p><dl> <li>#{@counter_conf_kiriban_label_all}<input name="counter.kiriban" value="#{h @conf["counter.kiriban"]}" size="60"></li> <li>#{@counter_conf_kiriban_label_today}<input name="counter.kiriban_today" value="#{h @conf["counter.kiriban_today"]}" size="60"></li> </dl></p> <h3 class="subtitle">#{@counter_conf_kiriban_messages_head}</h3> <p>#{@counter_conf_kiriban_messages_desc}</p> <p><dl> <li>#{@counter_conf_kiriban_messages_label_all}<br/> <textarea name="counter.kiriban_msg" cols="70" rows="10">#{CGI.escapeHTML(@conf["counter.kiriban_msg"])}</textarea></li> <li>#{@counter_conf_kiriban_messages_label_today}<br/> <textarea name="counter.kiriban_today_msg" cols="70" rows="10">#{CGI.escapeHTML(@conf["counter.kiriban_today_msg"])}</textarea></li> <li>#{@counter_conf_kiriban_messages_label_nomatch}<br/> <textarea name="counter.kiriban_nomatch_msg" cols="70" rows="10">#{CGI.escapeHTML(@conf["counter.kiriban_nomatch_msg"])}</textarea></li> </dl> </p> HTML end # Configure add_conf_proc('counter', @counter_conf_counter) do print_conf_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������tdiary-core-5.1.1/misc/plugin/daily_theme.rb��������������������������������������������������������0000664�0000000�0000000�00000002756�13626457307�0021031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# daily_theme.rb # # Copyright (c) 2005 SHIBATA Hiroshi <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. # def css_tag theme_name = File::basename( @css, '.css' ) css_url = @css if @mode =~ /conf$/ css_url = "#{h theme_url}/conf.css" theme_name = 'conf' elsif @conf.options.include?('daily_theme.list') && @conf.options['daily_theme.list'].size > 0 theme_list = @conf.options['daily_theme.list'].split(/\n/) index = Time.now.yday % theme_list.size theme_name = theme_list[index].strip css_url = "#{h theme_url}/#{u theme_name}/#{u theme_name}.css" end <<-CSS <link rel="stylesheet" href="#{h theme_url}/base.css" type="text/css" media="all"> <link rel="stylesheet" href="#{h css_url}" title="#{h theme_name}" type="text/css" media="all"> CSS end add_conf_proc( 'daily_theme', @daily_theme_label, 'theme' ) do daily_theme_conf_proc end def daily_theme_conf_proc if @mode == 'saveconf' if @cgi.params['daily_theme.list'] && @cgi.params['daily_theme.list'][0] @conf['daily_theme.list'] = @cgi.params['daily_theme.list'][0] else @conf['daily_theme.list'] = nil end end # initialize Theme list @conf['daily_theme.list'] = "default" unless @conf['daily_theme.list'] <<-HTML <h3>#{@daily_theme_label}</h3> <p>#{@daily_theme_label_desc}</p> <p><textarea name="daily_theme.list" cols="70" rows="20">#{h( @conf['daily_theme.list'] )}</textarea></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������tdiary-core-5.1.1/misc/plugin/disp_referrer.rb������������������������������������������������������0000664�0000000�0000000�00000126007�13626457307�0021374�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = 本日のリンク元もうちょっとだけ強化プラグイン((-$Id: disp_referrer.rb,v 1.70 2008-03-02 09:01:45 kazuhiko Exp $-)) == 概要 アンテナからのリンク、サーチエンジンの検索結果を、通常のリンク元の下にま とめて表示します。サーチエンジンの検索結果は、検索語毎にまとめられます。 最新の日記の表示では、通常のリンク元以外のリンク元を隠します。 == Acknowledgements This plugin uses * Some of the search engine names and URLs from disp_referrer.rb by MUTOH Masao. Methods that parses URL is copied from cgi.rb distributed with Ruby and edited. The idea that categorize the URLs with [] delimited strings is from kazuhiko. The author of this plugin appreciates them. == Copyright notice Copyright (C) 2003-2005 zunda <zunda at freeshell.org> Please note that some methods in this plugin are written by other authors as written in the comments. Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ChangeLog for changes after this. * Mon Sep 29, 2003 zunda <zunda at freeshell.org> - forgot to change arguments after changing initialize() * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - name.untaint to eval name * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - use to_native instead of to_euc * Mon Sep 19, 2003 zunda <zunda at freeshell.org> - disp_referrer2.rb,v 1.1.2.104 commited as disp_referrer.rb * Mon Sep 1, 2003 zunda <zunda at freeshell.org> - more strcit check for infoseek search enigne * Wed Aug 27, 2003 zunda <zunda at freeshell.org> - rd.yahoo, Searchalot, Hotbot added * Tue Aug 12, 2003 zunda <zunda at freeshell.org> - search engine list cleaned up * Mon Aug 11, 2003 zunda <zunda at freeshell.org> - instance_eval for e[2] in the search engine list * Wed Aug 7, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - キャッシュの更新をより確実にするようにしました。WWWブラウザから置換 リストを作った場合にはリストの最初に追加されます。 - secure=trueな日記でその他のリンク元リストが表示できるようになりました。 - Regexp generation for Wiki sites * Wed Aug 6, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - 主なオプションとリンク元置換リストの効率的な編集がWWWブラウザからで きるようになりました。secure=trueな日記では一部の機能は使えません。 * Sat Aug 2, 2003 zunda <zunda at freeshell.org> - Second version - basic functions re-implemented - オプションを命名しなおしました。また不要なオプションを消しました。 tdiary.confを編集していた方は、お手数ですが設定をしなおしてください。 - Noraライブラリとキャッシュの利用で高速化しました。 - 検索エンジンのリストをプラグインで持つようになりました。&や;を含む検 索文字列も期待通りに抽出できます。 * Mon Feb 17, 2003 zunda <zunda at freeshell.org> - First version =end # to be visible from inside classes Dispref2plugin = self Dispref2plugin_cache_path = @cache_path Dispref2plugin_cache_dir = @cache_dir # cache format Root_DispRef2URL = 'dispref2url' # root for DispRef2URLs =begin === Tdiary::Plugin::DispRef2DummyPStore PStoreと同じメソッドを提供しますがなにもしません。db[key]は全てnilを返す ことに注意してください。 =end # dummy PStore class DispRef2DummyPStore def initialize( file ) end def transaction( read_only = false ) yield end def method_missing( name, *args ) nil end end class DispRef2CachePathDummy def initialize( setup ) @setup = setup end def size 0 end def caches( include_backup = true ) [] end def method_missing( name, *args ) nil end end =begin === Tdiary::Plugin::DispRef2CachePath DispRef2Storeのパスの管理をします。 --- DispRef2CachePath::new( setup ) --- DispRef2CachePath#cache( date ) その日の日記のためのキャッシュのパスを返します。 --- DispRef2CachePath#caches 現在存在するそれぞれのキャッシュファイルのパスの配列を返します。 --- DispRef2CachePath#shrink 最近使われていないキャッシュを削除することで、 キャッシュの大きさを設定値程度に抑えます。 === Tdiary::Plugin::DispRef2PStore @secure=falseな日記ではPStoreと同等のメソッドを、@secure=trueな日記では 何もしないメソッドを提供します。 --- DispRef2PSTore#transaction( read_only = false ) Ruby-1.7以降の場合は読み込み専用に開くこともできます。Ruby-1.6の場 合はread_only = trueでも読み書き用に開きます。 --- DispRef2PSTore#real? 本物のPSToreが使える時はtrue、そうでない時はfalseを返します。 =end class DispRef2PStore < DispRef2DummyPStore def real? false end end class DispRef2CachePath < DispRef2CachePathDummy end =begin === Tdiary::Plugin::DispRef2String 文字コードの変換、URL、HTMLでの取り扱いに関するメソッド群です。インスタ ンスは作りません。Uconvライブラリがあればそれを使い、無ければ無いなりに処理します。 --- DispRef2String::normalize( str ) 続く空白を取り去ったりsite:...という文字列を消したりして、検索キー ワードを規格化します。 --- DispRef2String::parse_query( str ) URLに含まれるquery部(key=value&...)を解析し、結果をkeyをキー、 valueの配列を値としたハッシュとして返します。値のアンエスケープは しません。valueが無かった場合は空文字列が設定されます。 --- DispRef2String::separate_query( str ) URLをquery部より前と後に分けて配列として返します。query部が無い場 合はnilを返します。 --- DispRef2String::hostname( str ) URLに含まれるホスト名あるいはIPアドレスを返します。ホスト名がみつ からない場合は、((|str|))を返します。 --- DispRef2String::company_name( str, hash_list ) URLより、googleやbiglobeといった名前のうち((|hash_list|))のkeyに含 まれるものを返します。みつからない場合は、nilを返します。 --- DispRef2String::escapeHTML( str ) HTMLに含まれても安全なようにエスケープします。 --- DispRef2String::unescape( str ) URLをアンエスケープします。 --- DispRef2String::bytes( size ) バイト単位の大きさをMB KB Bの適切な単位に変換します。 --- DispRef2String::comma( integer ) 数字をカンマで3桁ずつに分けます。 --- DispRef2String::url_regexp( url ) ((|url|))から置換リスト用の正規表現文字列をつくります。 --- DispRef2String::url_match?( url, list ) ((|url|))が((|list|))のどれかにマッチするかどうか調べます。 =end # string handling class DispRef2String # strips site:... portion (google), multiple spaces, and start/end spaces def self::normalize( str ) str.sub( /\bsite:(\w+\.)*\w+\b/u, '' ).gsub( /[ \s\n]+/u, ' ' ).strip end # parse_query parses the not unescaped query in a URL # copied from from CGI::parse in cgi.rb by # Copyright (C) 2000 Network Applied Communication Laboratory, Inc. # Copyright (C) 2000 Information-technology Promotion Agency, Japan # Wakou Aoyama <wakou@ruby-lang.org> # eand edited def self::parse_query( str ) params = Hash.new str.split( /[&;]/n ).each do |pair| k, v = pair.split( '=', 2 ) ( params[k] ||= Array.new ) << ( v ? v : '' ) end params end # separate the query part (or nil) from a URL def self::separate_query( str ) base, query = str.split( /\?/, 2 ) if query then [ base, query ] else [ base, nil ] end end # get the host name (or nil) from a URL @@hostname_match = %r!https?://([^/]+)/?! def self::hostname( str ) @@hostname_match =~ str ? $1 : str end # get the `company name' included in keys of hash_table (or nil) from a URL def self::company_name( str, hash_table ) hostname( str ).split( /\./ ).values_at( -2, -3, 0 ).each do |s| return s if s and hash_table.has_key?( s.downcase ) end nil end def self::unescape( str ) if str then # escape ruby 1.6 bug. begin str.gsub( /\+/, ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do [$1.delete('%')].pack('H*') end rescue Encoding::CompatibilityError '' end else '' end end extend ERB::Util def DispRef2String::escapeHTML( str ) str ? h( str ) : '' end # add K, M with 1024 divisions def self::bytes( size ) s = size.to_f t = s / 1024.0 return( '%.0f' % s ) if t < 1 s = t t = s / 1024.0 return( '%.1f K' % s ) if t < 1 return( '%.1f M' % t ) end # insert comma def self::comma( integer ) integer.to_s.reverse.scan(/.{1,3}/).join(',').reverse # [ruby-list:30144] end # make up a regexp from a url def self::url_regexp( url ) r = url.dup r.sub!( /\/\d{4,8}\.html$/, '/' ) # from a tDiary? r.sub!( /\/(index\.(rb|cgi))?\?date=\d{4,8}$/, '/' ) # from a tDiary? r.gsub!( /\./, '\\.' ) # dots in the FQDN unless /(w|h)iki/i =~ r then r.sub!( /\?.*/, '.*' ) else r.sub!( /\?.*/, '\?(.*)' ) end r.sub!( /\/(index\.html?)$/, '/' ) # directory index r.sub!( /\/$/, '/?.*' ) # may be also from a lower level "\\A#{r}" # always good to put a \A end # matchs to the regexp strings? def self::url_match?( url, list ) list = list.split( /\n/ ) if String == list.class list.each do |entry| entry = entry[0] if Array == entry.class return true if /#{entry}/i =~ url end false end end =begin === Tdiary::Plugin::DispRef2Setup プラグインの動作を決めるパラメータを設定します。 --- DispRef2Setup::Last_parenthesis 文字列の最後の()の中身が$1に設定される正規表現です。 --- DispRef2Setup::First_bracket 文字列の最初の[]の中身が$1に、その後の文字列が$2に設定される正規表 現です。 --- DispRef2Setup::Defaults オプションのデフォルト値です。tDiary本体から@optionsで設定するには、 このハッシュのkeyの前に「disp_referrer2.」をつけたkeyを使ってくだ さい。オプションの詳細はソースのコメントを参照してください。 --- DispRef2Setup::new( conf, limit = 100, is_long = true ) ((|conf|))にはtDiaryの@confを、((|limit|))には一項目あたりの表示リ ンク元数を、((|is_long|))は一日分の表示の場合にはtrueを、最新の表 示の場合にはfalseを設定してください。 --- DispRef2Setup#update! tDiaryの@optionsにより自身を更新します。 --- DispRef2Setup#is_long --- DispRef2Setup#referer_table --- DispRef2Setup#no_referer --- DispRef2Setup#secure それぞれ、一日分の表示かどうか、tDiaryの置換テーブル、tDiaryのリン ク元除外リスト、日記のセキュリティ設定を返します。 --- DIspRef2Setup#to_native( str ) tDiaryの言語リソースで定義されている文字コードを正規化するメソッド です。 --- DispRef2Setup#[] 設定されている値を返します。 =end # configuration of this plugin class DispRef2Setup < Hash # useful regexps Last_parenthesis = /\((.*?)\)\Z/m First_bracket = /\A\[(.*?)\](.+)/m # default options Defaults = { 'long.only_normal' => false, # trueの場合、一日分の表示で、通常のリンク元以外を隠します。 'short.only_normal' => true, # trueの場合、最新の表示で、通常のリンク元以外を隠します。 # falseの場合は、プラグインの無い場合と全くおなじ表示になります。 'antenna.url' => '(\/a\/|(?!.*\/diary\/)antenna[\/\.]|\/tama\/|\Ahttp:\/\/www\.tdiary\.net\/?(i\/)?(\?|$)|links?|\Ahttp:\/\/kitaj\.no-ip\.com\/iraira\/|\Ahttp:\/\/i-know\.jp\/|\Ahttp:\/\/(www\.)?bloglines\.com\/(myblogs|public)_display|\Ahttp:\/\/del\.icio\.us\/\w+|\Ahttp:\/\/reader\.livedoor\.com\/reader\/)', # アンテナのURLに一致する正規表現の文字列です。 'antenna.title' => '(アンテナ|links?|あんてな|antenna|entry|entries|リンク集|RSS|ブックマーク)', # アンテナの置換後の文字列に一致する正規表現の文字列です。 'normal.label' => Dispref2plugin.referer_today, # 通常のリンク元のタイトルです。デフォルトでは、「本日のリンク元」です。 'antenna.label' => Disp_referrer2_antenna_label, # アンテナのリンク元のタイトルです。 'unknown.label' => Disp_referrer2_unknown_label, # その他のリンク元のタイトルです。 'unknown.hide' => false, # trueの場合はリンク元置換リストにないURLは表示しません 'search.label' => Disp_referrer2_search_label, # 検索エンジンからのリンク元のタイトルです。 'unknown.divide' => true, # trueの場合、置換リストに無いURLを通常のリンク元と分けて表示します。 # falseの場合、置換リストに無いURLを通常のリンク元と混ぜて表示します。 'normal.group' => true, # trueの場合、置換後の文字列で通常のリンク元をグループします。 # falseの場合、URL毎に別のリンク元として表示します。 'normal.categorize' => true, # trueの場合、置換後の文字列の最初の[]の文字列でカテゴリー分けします。 'normal.ignore_parenthesis' => true, # trueの場合、グループする際に置換後の文字列の最後の()を無視します。 'antenna.group' => true, # trueの場合、置換後の文字列で通常のリンク元をグループします。 # falseの場合、URL毎に別のリンク元として表示します。 'antenna.ignore_parenthesis' => true, # trueの場合、グループする際に置換後の文字列の最後の()を無視します。 'search.expand' => false, # trueの場合、検索キーワードとともに検索エンジン名を表示します。 # falseの場合、回数のみを表示します。 'search.unknown_keyword' => Disp_referrer2_search_unknown_keyword, # キーワードがわからない検索エンジンからのリンクに使う文字列です。 'search_engines' => DispReferrer2_Engines, # 検索エンジンのハッシュです。 'cache_label' => Disp_referrer2_cache_label, # 検索エンジンのキャッシュのURLを表示する文字列です。 'cache_path' => "#{Dispref2plugin_cache_path}/disp_referrer2.cache", # このプラグインで使うキャッシュファイルのパスです。 # このオプションは現在は使われていません。 'cache_dir' => "#{Dispref2plugin_cache_path}/disp_referrer2.d", # このプラグインで使うキャッシュファイルのディレクトリです。 'cache_max_size' => 10485760, # 10MB # キャッシュの合計量の制限(バイト)です。時々越えます。 # 0未満なら制限しません。 'no_cache' => false, # trueの場合キャッシュを使いません。 'normal-unknown.title' => '\Ahttps?:\/\/', # 置換された「その他」のリンク元のタイトル、あるいは置換されていな # いリンク元のタイトルにマッチします。 'configure.use_link' => true, # リンク元置換リストの編集画面で、リンク元へのリンクを作ります。 'reflist.ignore_urls' => '', # 置換リストのリストアップの際に無視するURLの正規表現の文字列 # \n区切で並べます } attr_reader :is_long, :referer_table, :no_referer, :years, :conf def initialize( conf, limit = 100, is_long = true, years = nil, mode = nil ) super() @conf = conf @years = years # mode @is_long = is_long @limit = limit @options = conf.options @mode = mode # URL tables @referer_table = conf.referer_table @no_referer = conf.no_referer # options from tDiary update! end def to_native( str ) @conf.to_native( str ) end # options from tDiary def update! # defaults self.replace( DispRef2Setup::Defaults.dup ) # from tDiary self.each_key do |key| options_key = "disp_referrer2.#{key}" self[key] = @options[options_key] if @options.has_key?( options_key ) end self['no_cache'] = true if defined?(::TDiary::IO::Default) && @conf.io_class == ::TDiary::IO::Default # additions self['labels'] = { DispRef2URL::Normal => self['normal.label'], DispRef2URL::Antenna => self['antenna.label'], DispRef2URL::Search => self['search.label'], DispRef2URL::Unknown => self['unknown.label'], } self['antenna.url.regexp'] = /#{self['antenna.url']}/i self['antenna.title.regexp'] = /#{self['antenna.title']}/i self['normal-unknown.title.regexp'] = /#{self['normal-unknown.title']}/i # limits self['limit'] = Hash.new self['limit'][DispRef2URL::Normal] = @limit || 0 if ( @is_long ? self['long.only_normal'] : self['short.only_normal'] ) then [DispRef2URL::Antenna, DispRef2URL::Search, DispRef2URL::Unknown].each do |c| self['limit'][c] = 0 end else [DispRef2URL::Antenna, DispRef2URL::Search, DispRef2URL::Unknown].each do |c| self['limit'][c] = @limit || 0 end end if self['unknown.hide'] and not /\A(append|replace|edit)\Z/ =~ @mode then self['limit'][DispRef2URL::Unknown] = 0 end self end def open_cache( path ) if self['no_cache'] then DispRef2DummyPStore::new( path ) else DispRef2PStore::new( path ) end end def cache_path if self['no_cache'] then DispRef2CachePathDummy::new( self ) else DispRef2CachePath::new( self ) end end end =begin === Tdiary::Plugin::DispRef2URL --- DispRef2URL::new( unescaped_url, setup = nil ) 素のURLを元にしてインスタンスを生成します。((|setup|))がnilではない 場合には、parse( ((|setup|)) ) もします。 --- DispRef2URL#restore( db ) キャッシュから自分のURLに対応する情報を取り出します。((|db|))は DispRef2PStoreのインスタンスです。キャッシュされていなかった場合 にはnilを返します。 --- DispRef2URL#parse( setup ) DispRef2Setupのインスタンス((|setup|))にしたがって、自分を解析します。 --- DispRef2URL::Cached_options DispRef2Setupで設定されるオプションのうち、キャッシュに影響を与え るものの配列を返します。 --- DispRef2URL#store( db ) キャッシュに自分を記録します。((|db|))はDispRef2PStoreのインスタ ンスです。記録に成功した場合は自分を、そうでない場合にはnilを返し ます。 --- DispRef2URL#==( other ) 解析結果が等しい場合に真を返します。 --- DispRef2URL#url --- DispRef2URL#category --- DispRef2URL#category_label --- DispRef2URL#title --- DispRef2URL#title_ignored --- DispRef2URL#title_group --- DispRef2URL#key それぞれ、URL、カテゴリー、カテゴリー名(ユーザーが設定しなければnil)、 タイトル、グループ化した時に無視されたタイトル(無ければnil)、グル ープ化した後のタイトル、グループ化する際のキーを返します。parseあ るいはrestoreしないと設定されません。 =end # handling of a URL class DispRef2URL attr_reader :url, :category, :category_label, :title, :title_ignored, :title_group, :key # category numbers Normal = :normal Antenna = :antenna Search = :search Unknown = :unknown Categories = [Normal, Antenna, Search, Unknown] # options which affects the cache Cached_options = %w( search_engines cache_label unknown.divide antenna.url.regexp antenna.url antenna.title.regexp antenna.title antenna.group antenna.ignore_parenthesis normal.categorize normal.group normal.ignore_parenthesis ) def initialize( unescaped_url, setup = nil ) @url = unescaped_url @dbcopy = nil parse( setup ) if setup end def restore( db ) if db.real? and ( begin db[Root_DispRef2URL] rescue PStore::Error false end ) and db[Root_DispRef2URL][@url] then @category, @category_label, @title, @title_ignored, @title_group, @key = db[Root_DispRef2URL][@url] self else nil end end def parse( setup ) parse_as_search( setup ) || parse_as_others( setup ) self end def store( db ) if db.real? and ( begin db[Root_DispRef2URL] ||= Hash.new rescue PStore::Error db[Root_DispRef2URL] = Hash.new end ) then db[Root_DispRef2URL]["#{@url}"] = [ @category, @category_label, @title, @title_ignored, @title_group, @key ] self else nil end end def ==(other) return @url == other.url && @category == other.category && @category_label == other.category_label && @title == other.title && @title_ignored == other.title_ignored && @title_group == other.title_group && @key == other.key end def replace_with(other) @category = other.category @category_label = other.category_label @title = other.title @title_ignored = other.title_ignored @title_group = other.title_group @key = other.key return self end private def parse_as_search( setup ) # see which search engine is used engine = DispRef2String::company_name( @url, setup['search_engines'] ) return nil unless engine # url and query urlbase, query = DispRef2String::separate_query( @url ) # get titles and keywords title = nil keyword = nil cached_url = nil catch( :done ) do setup['search_engines'][engine].each do |re_url, title_code, keys, cache| next unless re_url =~ urlbase title = eval( title_code ) throw :done if keyword if String == keys.class then # a Ruby code to extract key re_url =~ urlbase keyword, cached_url = (query || @url).instance_eval( keys ) throw :done end next unless query # below is to extract keyword from query values = DispRef2String::parse_query( query ) # an Array of keys in which keywords or recursive URL are stored keys.each do |key| if Symbol === key then k = key.to_s if values[k] and not (encoded_uri = values[k][0]).empty? then begin original_uri = URI::parse( urlbase ) + URI::parse( URI::decode(encoded_uri) ) throw :done if original_uri == urlbase # denial of service? self.replace_with( DispRef2URL.new( original_uri.to_s ).parse( setup ) ) return self rescue URI::InvalidURIError throw :done end end elsif values[key] and not (value = values[key][0]).empty? then unless cache and cache =~ value then cached_url = nil keyword = values[key][0] throw :done else cached_url = $1 keyword = $` + $' throw :done end end next end end return nil end # format keyword ||= setup['search.unknown_keyword'] @category = Search @category_label = nil @title = DispRef2String::normalize( setup.to_native( DispRef2String::unescape( keyword ) ) ) @title_ignored = setup.to_native( title ) @title_ignored << sprintf( setup['cache_label'], setup.to_native( DispRef2String::unescape( cached_url ) ) ) if cached_url @title_group = @title @key = @title_group return self end def parse_as_others( setup ) # try to convert with referer_table matched = false title = setup.to_native( DispRef2String::unescape( @url ) ) setup.referer_table.each do |url, name| unless /\$\d/ =~ name then if title.gsub!( /#{url}/iu, name ) then matched = true break end else if title.gsub!( /#{url}/iu ) { eval name } then matched = true break end end end if setup['antenna.url.regexp'] =~ @url or setup['antenna.title.regexp'] =~ title then # antenna @category = Antenna @category_label = nil grouping = setup['antenna.group'] ignoring = setup['antenna.ignore_parenthesis'] elsif matched and not setup['normal-unknown.title.regexp'] =~ title then # normal @category = Normal if setup['normal.categorize'] and DispRef2Setup::First_bracket =~ title then @category_label = $1 title = $2 else @category_label = nil end grouping = setup['normal.group'] ignoring = setup['normal.ignore_parenthesis'] else # unknown @title = title @title_ignored = nil @title_group = title @key = @url if setup['unknown.divide'] then @category = Unknown @category_label = nil else @category = Normal @category_label = nil end return self end # format the title if not grouping then @title = title @title_group = title @title_ignored = nil @key = @url elsif not ignoring then @title = title @title_group = title @title_ignored = nil @key = title_group else @title = title @title_group = title.gsub( DispRef2Setup::Last_parenthesis, '' ) @title_ignored = $1 @key = title_group end self end # private end =begin === Tdiary::Plugin::DispRef2Refs --- DispRef2Refs::new( diary, setup ) 日記((|diary|))のリンク元を、DispRef2Setupのインスタンス((|setup|)) にしたがって解析します。 --- DispRef2Refs#special_categories 置換文字列の最初に[]でかこったカテゴリ名ラベルを挿入することによっ てユーザーによって定義されたカテゴリーの配列を返します。 --- DispRef2Refs#urls( category = nil ) リンク元のうち、カテゴリーが((|category|))に一致するものを、 DispRef2Cache#urlsと同様のフォーマットで返します。((|category|)) がnilの場合は全てのURLの情報を返します。 --- DispRef2Refs#to_long_html --- DispRef2Refs#to_short_html リンク元のリストをHTML断片にします。 =end class DispRef2Refs def initialize( diary, setup ) @setup = setup @refs = Hash.new @has_ref = false return unless diary done_flag = Hash.new DispRef2URL::Categories.each do |c| done_flag[c] = (@setup['limit'][c] < 1) end h = Hash.new date = diary.respond_to?( :date ) ? diary.date : nil db = setup.open_cache( setup.cache_path.cache( date ) ) db.transaction do diary.each_referer( diary.count_referers ) do |count, url| ref = DispRef2URL.new( url ) @has_ref = true unless ref.restore( db ) then ref.parse( @setup ) ref.store( db ) end if @setup.is_long and @setup['normal.categorize'] then cat_key = ref.category_label || ref.category else cat_key = ref.category end next if done_flag[cat_key] h[cat_key] ||= Hash.new unless h[cat_key][ref.key] then h[cat_key][ref.key] = [count, ref.title_group, [[count, ref]]] else h[cat_key][ref.key][0] += count h[cat_key][ref.key][2] << [count, ref] if h[cat_key][ref.key].size < @setup['limit'][ref.category] end if h[cat_key].size >= @setup['limit'][ref.category] then done_flag[ref.category] = true break unless done_flag.has_value?( false ) end end end db = nil h.each_pair do |cat_key, hash| @refs[cat_key] = hash.values @refs[cat_key].sort! { |a, b| b[0] <=> a[0] } end end def special_categories @refs.keys.reject!{ |c| DispRef2URL::Categories.include?( c ) } end # urls in the diary as a hash def urls( category = nil ) if category then category = [ category ] unless category.respond_to?( :each ) else category = @refs.keys end h = Hash.new category.each do |cat| next unless @refs[cat] @refs[cat].each do |a| a[2].each do |b| h[b[1].url] = [ b[1].category, b[1].category_label, b[1].title, b[1].title_ignored, b[1].title_group, b[1].key ] end end end h end def to_short_html return '' if not @refs[DispRef2URL::Normal] or @refs[DispRef2URL::Normal].size < 1 result = DispRef2String::escapeHTML( @setup['labels'][DispRef2URL::Normal] ) + ' | ' @refs[DispRef2URL::Normal].each do |a| result << %Q[<a rel="nofollow" href="#{DispRef2String::escapeHTML( a[2][0][1].url )}" title="#{DispRef2String::escapeHTML( a[2][0][1].title )}">#{a[0]}</a> | ] end result end def to_long_html( label ) return '' if not @has_ref # we always need a caption result = %Q[<div class="caption">#{DispRef2String::escapeHTML( label )}</div>\n] result << others_to_long_html( DispRef2URL::Normal ) if( @setup['normal.categorize'] and special_categories ) then special_categories.each do |cat| result << others_to_long_html( cat ) end end result << others_to_long_html( DispRef2URL::Antenna ) result << others_to_long_html( DispRef2URL::Unknown ) result << search_to_long_html result end private def others_to_long_html( cat_key ) return '' unless @refs[cat_key] and @refs[cat_key].size > 0 result = '' unless DispRef2URL::Normal == cat_key then # to_long_html provides the catpion for normal links if @setup['labels'].has_key?( cat_key ) then result << %Q[<div class="caption">#{DispRef2String::escapeHTML( @setup['labels'][cat_key] )}</div>\n] else result << %Q[<div class="caption">#{DispRef2String::escapeHTML( cat_key )}</div>\n] end end result << '<ul>' @refs[cat_key].each do |a| begin if a[2].size == 1 then result << %Q[<li><a rel="nofollow" href="#{DispRef2String::escapeHTML( a[2][0][1].url )}">#{DispRef2String::escapeHTML( a[2][0][1].title )}</a> ×#{a[0]}</li>\n] elsif not a[2][0][1].title_ignored then result << %Q[<li><a rel="nofollow" href="#{DispRef2String::escapeHTML( a[2][0][1].url )}">#{DispRef2String::escapeHTML( a[1] )}</a> ×#{a[0]} : #{a[2][0][0]}] a[2][1..-1].each do |b| title = (b[1].title != a[1]) ? %Q[ title="#{DispRef2String::escapeHTML( b[1].title )}"] : '' result << %Q[, <a rel="nofollow" href="#{DispRef2String::escapeHTML( b[1].url )}"#{title}>#{b[0]}</a>] end result << "</li>\n" else result << %Q[<li>#{DispRef2String::escapeHTML( a[1] )} ×#{a[0]} : ] comma = nil a[2][0..-1].each do |b| title = (b[1].title != a[1]) ? %Q[ title="#{DispRef2String::escapeHTML( b[1].title )}"] : '' result << comma if comma result << %Q[<a rel="nofollow" href="#{DispRef2String::escapeHTML( b[1].url )}"#{title}>#{b[0]}</a>] comma = ', ' end result << "</li>\n" end rescue Encoding::CompatibilityError end end result << "</ul>\n" end def search_to_long_html return '' unless @refs[DispRef2URL::Search] and @refs[DispRef2URL::Search].size > 0 result = %Q[<div class="caption">#{DispRef2String::escapeHTML( @setup['labels'][DispRef2URL::Search] )}</div>\n] result << ( @setup['search.expand'] ? "<ul>\n" : '<ul><li>' ) sep = nil @refs[DispRef2URL::Search].each do |a| result << sep if sep if @setup['search.expand'] then result << '<li>' result << DispRef2String::escapeHTML( a[1] ) else result << %Q[<a rel="nofollow" href="#{DispRef2String::escapeHTML( a[2][0][1].url )}">#{DispRef2String::escapeHTML( a[1] )}</a>] end result << %Q[ ×#{a[0]} ] if @setup['search.expand'] then result << ' : ' if a[2].size < 2 then result << %Q[<a rel="nofollow" href="#{DispRef2String::escapeHTML( a[2][0][1].url )}">#{DispRef2String::escapeHTML( a[2][0][1].title_ignored )}</a>] else comma = nil a[2].each do |b| result << comma if comma result << %Q[<a rel="nofollow" href="#{DispRef2String::escapeHTML( b[1].url )}">#{DispRef2String::escapeHTML( b[1].title_ignored )}</a> ×#{b[0]}] comma = ', ' unless comma end end end result << '</li>' if @setup['search.expand'] sep = ( @setup['search.expand'] ? "\n" : ' / ' ) unless sep end result << ( @setup['search.expand'] ? "</ul>\n" : "</li></ul>\n" ) end # private end =begin === Tdiary::Plugin::DispRef2Cache キャッシュの管理をするクラスです。 --- DispRef2Cache.new( setup ) リンク元のキャッシュを、DispRef2Setupのインスタンス((|setup|))にした がって管理します。 --- DispRef2Cache#urls( category = nil, nmonth = 2 ) キャッシュされているURLの情報のうち、カテゴリーが((|category|))に 一致するものを、URLをキー、下記の配列を値としたハッシュとして返し ます。((|category|))がnilの場合は全てのURLの情報を返します。 ((|nmonth|))がnilではない場合は、最近NMONTH分のキャッシュだけから 検索します。 * カテゴリー * カテゴリーのラベル(あるいはnil) * 置換後の文字列 * グループする際に無視された文字列 * グループ全体の文字列 * グループする際のキー =end # cache management class DispRef2Cache def initialize( setup ) @setup = setup @cache = @setup.cache_path end # cached urls as a hash def urls( category = nil, nmonth = 2 ) h = Hash.new if nmonth then caches = @cache.caches( false ).sort{ |a,b| b<=>a }[0...nmonth] else caches = @cache.caches( false ) end caches.each do |path| db = @setup.open_cache( path ) db.transaction( true ) do begin db[Root_DispRef2URL].each_pair do |url, data| h[url] = data if not category or category == data[0] end rescue PStore::Error end end end h end end =begin === TDiary::Plugin::DispRef2SetupIF このプラグインの設定のためのHTMLを生成し、CGIリクエストを受け取ります。 --- DispRef2SetupIF::new( cgi, setup, conf, mode ) CGIのインスタンス((|cgi|))とDispRef2Setupのインスタンス((|setup|)) より、設定のためのインスタンスを生成します。TDiary::Pluginより、 @confと@modeも引数に指定してください。 --- DispRef2SetupIF#show_html 設定の更新と必要ならキャッシュの更新をしてからHTMLを表示します。 --- DispRef2SetupIF#show_description このプラグインのHTML版の説明です。設定する項目も選べます。 --- DispRef2SetupIF#show_options このプラグインのオプションを設定するHTML断片を返します。 --- DispRef2SetupIF#show_unknown_list リンク元置換リストの編集のためのHTML断片を返します。 --- DispRef2SetupIF#update_options cgiからの入力に応じて、このプラグインのオプションを更新します。 @setupも更新します。 --- DispRef2SetupIF#update_tables cgiからの入力に応じて、リンク元置換リストを更新します。 =end # WWW Setup interface class DispRef2SetupIF # setup mode Options = 'options' RefList = 'reflist' def initialize( cgi, setup, conf, mode ) @cgi = cgi @setup = setup @conf = conf @conf['disp_referrer2.reflist.ignore_urls'] ||= '' @mode = mode @need_cache_update = false if @cgi.params['dr2.change_mode'] and @cgi.params['dr2.change_mode'][0] then case @cgi.params['dr2.new_mode'][0] when Options @current_mode = Options when RefList @current_mode = RefList else @current_mode = Options end elsif @cgi.params['dr2.current_mode'] then case @cgi.params['dr2.current_mode'][0] when Options @current_mode = Options when RefList @current_mode = RefList else @current_mode = Options end else @current_mode = Options end unless @setup['no_cache'] then @cache = @setup.cache_path else @cache = nil end end # do what to do and make html def show_html # things to be done if @mode == 'saveconf' then case @current_mode when Options update_options when RefList update_tables end end # clear cache if @mode == 'saveconf' then if not @setup['no_cache'] then unless @cache then @need_cache_update = true @cache = @setup.cache_path end if not 'never' == @cgi.params['dr2.cache.update'][0] and ('force' == @cgi.params['dr2.cache.update'][0] or @need_cache_update) then @cache.clear end else if @setup['no_cache'] then @cache = nil end end end # result r = show_description case @current_mode when Options r << show_options when RefList r << show_unknown_list end r end # show description def show_description r = Disp_referrer2_abstract.dup if @cache then r << sprintf( Disp_referrer2_cache_info, DispRef2String::bytes( @cache.size ) ) r << sprintf( Disp_referrer2_update_info, "#{DispRef2String::escapeHTML(@conf.update)}?conf=referer" ) end r << "<p>\n" case @current_mode when Options r << sprintf( Disp_referrer2_move_to_refererlist, "#{DispRef2String::escapeHTML(@conf.update)}?conf=disp_referrer2;dr2.new_mode=#{RefList};dr2.change_mode=true" ) when RefList r << sprintf( Disp_referrer2_move_to_config, "#{DispRef2String::escapeHTML(@conf.update)}?conf=disp_referrer2;dr2.new_mode=#{Options};dr2.change_mode=true" ) end r << sprintf( Disp_referrer2_also_todayslink, "#{DispRef2String::escapeHTML(@conf.update)}?conf=referer" ) r << %Q{<input type="hidden" name="saveconf" value="ok"></p><hr>\n} r end # updates the options def update_options dirty = false # T/F options %w( antenna.group antenna.ignore_parenthesis antenna.search.expand normal.categorize normal.group normal.ignore_parenthesis search.expand long.only_normal short.only_normal no_cache unknown.divide unknown.hide ).each do |key| tdiarykey = 'disp_referrer2.' + key case @cgi.params['dr2.' + key][0] when 'true' unless @conf[tdiarykey] == true then @conf[tdiarykey] = true @need_cache_update = true if DispRef2URL::Cached_options.include?( key ) dirty = true end when 'false' unless @conf[tdiarykey] == false then @conf[tdiarykey] = false @need_cache_update = true if DispRef2URL::Cached_options.include?( key ) dirty = true end end end # numeric options %w( cache_max_size ).each do |key| tdiarykey = 'disp_referrer2.' + key v = @cgi.params['dr2.' + key][0] next unless v f = 1 if v.gsub!( /M\Z/, '' ) then f = 1024*1024 elsif v.gsub!( /K\Z/, '' ) then f = 1024 end if /\A\d+\Z/ =~ v then @conf[tdiarykey] = v.to_i * f @need_cache_update = true if DispRef2URL::Cached_options.include?( key ) dirty = true end end # update @setup @setup.update! if dirty end # referer tables def update_tables dirty = false if @cgi.params['dr2.urls'] and @cgi.params['dr2.urls'][0].to_i > 0 @cgi.params['dr2.urls'][0].to_i.times do |i| if not @cgi.params["dr2.#{i}.reg"][0].empty? and not @cgi.params["dr2.#{i}.title"][0].empty? then a = [ @setup.to_native( @cgi.params["dr2.#{i}.reg"][0] ).sub( /[\r\n]+/, '' ), @setup.to_native( @cgi.params["dr2.#{i}.title"][0] ).sub( /[\r\n]+/, '' ) ] if not a[0].empty? and not a[1].empty? then @conf.referer_table2.unshift( a ) @conf.referer_table.unshift( a ) # to reflect the change in this requsest @need_cache_update = true dirty = true end end if 'true' == @cgi.params["dr2.#{i}.noref"][0] then unless @cgi.params["dr2.#{i}.reg"][0].empty? then reg = @setup.to_native( @cgi.params["dr2.#{i}.reg"][0] ).strip unless reg.empty? then @conf.no_referer2.unshift( reg ) @conf.no_referer.unshift( reg ) # to reflect the change in this requsest end end end if 'true' == @cgi.params["dr2.#{i}.ignore"][0] then unless @cgi.params["dr2.#{i}.reg"][0].empty? then reg = @setup.to_native( @cgi.params["dr2.#{i}.reg"][0] ).strip unless reg.empty? then @conf['disp_referrer2.reflist.ignore_urls'] = @conf['disp_referrer2.reflist.ignore_urls'].split( /\n/ ).push( reg ).uniq.join( "\n" ) dirty = true end end end end end if @cgi.params['dr2.clear_ignore_urls'] and 'true' == @cgi.params['dr2.clear_ignore_urls'][0] then @conf['disp_referrer2.reflist.ignore_urls'] = '' dirty = true end %w( url title ).each do |cat| if 'true' == @cgi.params["dr2.antenna.#{cat}.default"][0] then @conf["disp_referrer2.antenna.#{cat}"] = DispRef2Setup::Defaults["antenna.#{cat}"] dirty = true @need_cache_update = true elsif @cgi.params["dr2.antenna.#{cat}"] and @cgi.params["dr2.antenna.#{cat}"][0] and @cgi.params["dr2.antenna.#{cat}"][0] != @conf["disp_referrer2.antenna.#{cat}"] then newval = @cgi.params["dr2.antenna.#{cat}"][0].strip unless newval.empty? then @conf["disp_referrer2.antenna.#{cat}"] = newval dirty = true @need_cache_update = true end end end # update @setup @setup.update! if dirty end end =begin === TDiary::Plugin::DispRef2Latest キャッシュが無い場合に、設定プラグインで不明のリンク元を得るためのクラス です。 --- DispRef2Latest::new( cgi, skeltonfile, conf, setup ) TDiary::TDiaryLatestの引数に加えて、DispRef2Setupのインスタンス ((|setup|))を引数にとります。 --- DispRef2Latest::unknown_urls 最新の日記のリンク元のうち、置換できなかったもののURLの配列を返し ます。置換できなかったURLが無い場合には空の配列を返します。 =end class DispRef2Latest < TDiary::TDiaryLatest def initialize( cgi, rhtml, conf, setup ) super( cgi, rhtml, conf ) @setup = setup end # collect unknown URLs from the newest diaries def unknown_urls r = Array.new self.latest( @conf.latest_limit ) do |diary| refs = DispRef2Refs.new( diary, @setup ) h = refs.urls( DispRef2URL::Antenna ) h.each_key do |url| next unless @setup['normal-unknown.title.regexp'] =~ h[url][2] next if DispRef2String::url_match?( url, @setup.no_referer ) r << url end h = nil refs.urls( DispRef2URL::Unknown ).each_key do |url| next if DispRef2String::url_match?( url, @setup.no_referer ) r << url end end r.uniq end end =begin === Tdiary::Plugin --- Tdiary::Plugin#configure_disp_referrer2 このプラグインの設定のために使われるメソッドです。add_conf_procさ れます。 以下は、このプラグインでオーバーライドされるtDiaryのメソッドです。 --- Tdiary::Plugin#referer_of_today_long( diary, limit = 100 ) --- Tdiary::Plugin#referer_of_today_short( diary, limit = 10 ) =end # for configuration interface add_conf_proc( 'disp_referrer2', Disp_referrer2_name, 'referer' ) do setup = DispRef2Setup.new( @conf, 100, true, @years, @mode ) wwwif = DispRef2SetupIF.new( @cgi, setup, @conf, @mode ) wwwif.show_html end # for one-day diary def referer_of_today_long( diary, limit = 100 ) return '' if bot? setup = DispRef2Setup.new( @conf, limit, true, nil, @mode ) r = '' r << DispRef2Refs.new( diary, setup ).to_long_html( referer_today ) r << DispRef2Refs.new( @referer_volatile, setup ).to_long_html( volatile_referer ) if @referer_volatile and latest_day?( diary ) setup.cache_path.shrink r end # we have to know the unknown urls at this moment in a secure diary DispRef2Latest_cache = nil # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/doctype-html401tr.rb��������������������������������������������������0000664�0000000�0000000�00000000574�13626457307�0021745�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # define DOCTYPE: HTML 4.01 Tr without DTD's URL (for compatible mode) # # Copyright (c) 2005 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # def doctype %Q[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/draft.rb��������������������������������������������������������������0000664�0000000�0000000�00000000650�13626457307�0017634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # draft.rb: save draft data to Web Storage automatically # # Copyright (c) MATSUOKA Kohei <http://www.machu.jp/> # Distributed under the GPL2 or any later version. # if /\A(form|edit|preview|showcomment)\z/ === @mode then enable_js('draft.js') end add_edit_proc do <<-EOS <div class="draft"> 下書き: <select name="drafts"></select> <button type="button" id="draft_load">読み込み</button> </div> EOS end ����������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/dropdown_calendar.rb��������������������������������������������������0000664�0000000�0000000�00000001756�13626457307�0022231�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# dropdown_calendar.rb # # calendar: カレンダーをドロップダウンリストに置き換えるプラグイン # パラメタ: なし # # Copyright (C) 2003 TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # @dropdown_calendar_label = '過去の日記' unless @resource_loaded def calendar result = %Q[<form method="get" action="#{h @index}">\n] result << %Q[<div class="calendar">\n] result << %Q[<select name="url" onChange="window.location=$(this).val()">\n] result << "<option value=''>#{@conf.options['dropdown_calendar.label'] || @dropdown_calendar_label}</option>\n" @years.keys.sort.reverse_each do |year| @years[year.to_s].sort.reverse_each do |month| date = "#{year}#{month}" result << %Q[<option value="#{h @index}#{anchor(date)}">#{year}-#{month}</option>\n] end end result << "</select>\n" result << "</div>\n</form>" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������tdiary-core-5.1.1/misc/plugin/edit_today.rb���������������������������������������������������������0000664�0000000�0000000�00000002046�13626457307�0020662�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# edit_today.rb : add link to edit after title of each days. # # Copyright (C) 2007 by NOB <nob@harunaru.com> # You can redistribute it and/or modify it under GPL2 or any later version. # def edit_today_init @conf['edit_today.caption'] ||= @edit_today_caption end add_title_proc do |date,title| edit_today_link( date, title ) end def edit_today_link( date, title ) unless /^(day|preview)$/ =~ @mode edit_today_init caption = @conf['edit_today.caption'] <<-HTML #{title}\n<span class="edit-today"> <a href="#{@update}?edit=true;#{date.strftime( 'year=%Y;month=%m;day=%d' )}" title="#{edit_today_edit_label( date )}" rel="nofollow">#{caption}</a> </span> HTML else title end end def edit_today_saveconf if @mode == 'saveconf' then @conf['edit_today.caption'] = @cgi.params['edit_today_caption'][0] end end add_conf_proc( 'edit_today', @edit_today_caption, 'update' ) do edit_today_saveconf edit_today_init edit_today_conf_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/�������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0016610�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/a.rb���������������������������������������������������������������0000664�0000000�0000000�00000000603�13626457307�0017354�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def a_conf_label; "Edit the dictionary file for the anchor plugin(a.rb)"; end def a_conf_explain; "<p>A row is an anchor. The format is: key URL name. name is omittable. If you omit name, the key used as name.</p><p>e.g.) tdiary http://www.tdiary.org/ tDiary Official Website</p>"; end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/amazon.rb����������������������������������������������������������0000664�0000000�0000000�00000005412�13626457307�0020424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # English resource of amazon plugin # # Copyright (C) 2002 HAL99 <hal99@mtj.biglobe.ne.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # # # isbn_image_left: show the item image of specified ISBN by class="left". # Parameter: # asin: ASIN or ISBN # comment: comment (optional) # # isbn_image_right: # Parameter: # asin: ASIN or ISBN # comment: comment (optional) # # isbn_image: show the item image of specified ISBN by class="right". # asin: ASIN or ISBN # comment: comment (optional) # # isbn_detail: show the item detail with image # asin: ASIN or ISBN # # isbn: light version. it dose not access to amazon. # asin: ASIN or ISBN # comment: comment # # options in tdiary.conf: # @options['amazon.aid']: Your Amazon Assosiate ID. This option can be # changed in preferences page. # @options['amazon.hideconf']: When you want to prohibit changing amazon.aid # via preferences page, set false. # @options['amazon.imgsize']: specify image size (0:laege, 1:regular, 2:small) # @options['amazon.hidename']: hide book name when class="amazon", set true. # @options['amazon.default_image_base']: URL that include default images. # amazon.rb uses images on tDiary.org when this # option not specified. If you want to use your # original images, modify PNG file in amazon directory. # @options['amazon.nodefault']: If you dosen't want to show default image # when the book image not found, set true. @amazon_default_country = 'us' @amazon_item_name = /^Amazon\.com: (.*)$/ @amazon_item_image = %r|(<img src="(http://images\.amazon\.com/images/P/(.*MZZZZZZZ_?.jpg))".*?>)|i @amazon_label_conf = 'Amazon' @amazon_label_aid = 'Amazon Assosiate ID' @amazon_label_aid_desc = "This ID will be used for US Amazon only. If you want to use other country's Amazon, specify in tdiary.conf." @amazon_label_imgsize = 'Image size of the book' @amazon_label_large = 'Large' @amazon_label_regular = 'Regular' @amazon_label_small = 'Small' @amazon_label_title = 'When using isbn_image plugin' @amazon_label_hide = 'Hide book title' @amazon_label_show = 'Show book title' @amazon_label_bitly = 'Using bit.ly' @amazon_label_bitly_enabled = 'Shorten products url by bit.ly' @amazon_label_bitly_disabled = 'Do not shorten' @amazon_label_notfound = 'If book image dose not found' @amazon_label_usetitle = 'Show book title' @amazon_label_usedefault = 'Use default image' @amazon_label_clearcache = 'Clear Cache' @amazon_label_clearcache_desc = 'Delete local cache file about book images' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/append-css.rb������������������������������������������������������0000664�0000000�0000000�00000000425�13626457307�0021173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def append_css_label 'Append CSS' end def append_css_desc <<-HTML <h3>CSS elements</h3> <p>If you want to append some elements of style sheet, specify below.</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/bq.rb��������������������������������������������������������������0000664�0000000�0000000�00000000243�13626457307�0017536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/bq.rb # def bq_cite_from( cite ) "cite from #{cite}" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/calendar2.rb�������������������������������������������������������0000664�0000000�0000000�00000000367�13626457307�0020776�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# calendar2.rb language recource for English @calendar2_days_format = %w(Su Mo Tu We Th Fr Sa) @calendar2_navi_format = ["<-", "%d<br>%d", "->"] # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/category-legacy.rb�������������������������������������������������0000664�0000000�0000000�00000013174�13626457307�0022222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/category-legacy.rb # # Copyright (c) 2004 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # def category_title info = Category::Info.new(@cgi, @years, @conf) mode = info.mode case mode when :year period = "#{info.year}" when :half period = (info.month.to_i == 1 ? "1st half" : "2nd half") period = "#{info.year} #{period}" if info.year when :quarter period = info.month period = "#{info.year}/#{period}" if info.year when :month period = info.month.to_i period = "#{info.year}/#{period}" if info.year end period = " (#{period})" if period "[#{info.category.join('|')}#{period}]" end def category_init_local @conf['category.prev_year'] ||= '<< ($1)' @conf['category.next_year'] ||= '($1) >>' @conf['category.prev_half'] ||= '<< ($1-$2)' @conf['category.next_half'] ||= '($1-$2) >>' @conf['category.prev_quarter'] ||= '<< ($1-$2)' @conf['category.next_quarter'] ||= '($1-$2) >>' @conf['category.prev_month'] ||= '<< ($1-$2)' @conf['category.next_month'] ||= '($1-$2) >>' @conf['category.this_year'] ||= 'this year' @conf['category.this_half'] ||= 'this half' @conf['category.this_quarter'] ||= 'this quarter' @conf['category.this_month'] ||= 'this month' @conf['category.all_diary'] ||= 'all diary' @conf['category.all_category'] ||= 'all category' @conf['category.all'] ||= 'all diary/all category' end category_init_local @category_conf_label = 'Category' def category_conf_html r = <<HTML <h3 class="subtitle">Create category index</h3> <p> To use the category feature, you should create category index. Check the box below to create category index. </p> <p><label for="category_initialize"> <input type="checkbox" id="category_initialize" name="category_initialize" value="1">Rebuild category Index </label></p> <p> It takes several or several tens of second to create it. </p> <h3 class="subtitle">Edit Support</h3> <p> Category names can be shown under the 'Article' form. </p> <p> <select name="category.edit_support"> <option value="1"#{" selected" if @conf['category.edit_support'] == 1}>Flat List</option> <option value="2"#{" selected" if @conf['category.edit_support'] == 2}>Dropdown List/option> <option value="0"#{" selected" if @conf['category.edit_support'] == 0}>Hide</option> </select> </p> <h3 class="subtitle">Default period</h3> <p> Specify the default display period for category view. </p> <p><select name="category.period"> HTML [ ['month', 'month', false], ['quarter', 'quarter', true], ['half-year', 'half', false], ['year', 'year', false], ['all', 'all', false], ].each do |text, value, default| selected = @conf["category.period"] ? @conf["category.period"] == value : default r << <<HTML <option value="#{value}"#{" selected" if selected}>#{text}</option> HTML end r << <<HTML </select></p> <h3 class="subtitle">Header</h3> <p> This text is inserted into top of category view. "<%= category_navi %>" genaretes navigation buttons for category, and "<%= category_list %>" lists all category names. You can use plugins and write any HTML tags. </p> <h4>Header 1</h4> <p>Inserted under the navigtion buttons.</p> <p><textarea name="category.header1" cols="60" rows="8">#{h @conf['category.header1']}</textarea></p> <h4>Header 2</h4> <p>Inserted under the <H1>.</p> <p><textarea name="category.header2" cols="60" rows="8">#{h @conf['category.header2']}</textarea></p> <h3 class="subtitle">Button labels</h3> <p> Specify button labels. $1 and $2 in labels are replaced with year and month. </p> <table border="0"> <tr><th>button name</th><th>label</th><th>sample</th></tr> HTML [ ['previous year', 'category.prev_year'], ['next year', 'category.next_year'], ['previous half', 'category.prev_half'], ['next half', 'category.next_half'], ['previous quarter', 'category.prev_quarter'], ['next quarter', 'category.next_quarter'], ['previous month', 'category.prev_month'], ['next month', 'category.next_month'], ['this year', 'category.this_year'], ['this half', 'category.this_half'], ['this quarter', 'category.this_quarter'], ['this month', 'category.this_month'], ['all diary', 'category.all_diary'], ['all category', 'category.all_category'], ['all diary/all category', 'category.all'], ].each do |button, name| r << <<HTML <tr> <td>#{button}</td> <td><input type="text" name="#{name}" value="#{h @conf[name]}" size="30"></td> <td><p><span class="adminmenu"><a>#{h @conf[name].sub(/\$1/, "2007").sub(/\$2/, "2")}</a></span></p></td> </tr> HTML end r << <<HTML </table> HTML end @category_icon_none_label = 'no icon' @category_icon_conf_label = 'Category Icons' def category_icon_conf_html r = '' unless @conf.secure r << <<HTML <h3 class="subtitle">Location of category icons</h3> <p> Specify the directory and url of category icons. </p> <p> <dl> <dt>Directory:</dt> <dd><input name="category.icon_dir" value="#{h @category_icon_dir}" size="30"></dd> <dt>URL:</dt> <dd><input name="category.icon_url" value="#{h @category_icon_url}" size="30"></dd> </dl> </p> <hr> HTML end str = '' @categories.each do |c| str << %Q|\t<tr>\n\t\t<td>#{c}</td>\n\t\t<td>\n| str << category_icon_select(c) str << %Q|<img src="#{h @category_icon_url}#{h @category_icon[c]}">| if @category_icon[c] str << %Q|</td>\n\t</tr>\n| end <<HTML <h3 class="subtitle">Category Icons</h3> <p> <table> <tr><th>Category</th><th>Icon</th></tr> #{str} </table> </p> <hr> <h3 class="subtitle">Sample icons</h3> <p> You can take your choice from these icons. Move mouse pointer on an icon, the icon's name will pop up. </p> <p> #{category_icon_sample} </p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/category.rb��������������������������������������������������������0000664�0000000�0000000�00000003077�13626457307�0020761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # en/category.rb : tDiary plugin for show category pages # # Copyright (C) 2016 TADA Tadashi # Distributed under the GPL2 or any later version. # @category_conf_label = 'Category' def category_conf_html r = <<-HTML <h3 class="subtitle">Build category index</h3> <p> To use the category feature, you should build category index. Check the box below and press OK to build category index. </p> <p><label for="category_initialize"> <input type="checkbox" id="category_initialize" name="category_initialize" value="1">Build category index </label></p> <p> It takes several or several tens of second to create it. But your diaries are many or the server has low spec, it will be timeout. Rebuild index on off-line again. </p> <h3 class="subtitle">Edit Support</h3> <p> Category names can be shown under the 'Article' form. </p> <p> <select name="category.edit_support"> <option value="1"#{" selected" if @conf['category.edit_support'] == 1}>Flat List</option> <option value="2"#{" selected" if @conf['category.edit_support'] == 2}>Dropdown List/option> <option value="0"#{" selected" if @conf['category.edit_support'] == 0}>Hide</option> </select> </p> <h3 class="subtitle">Display Order</h3> <p><label for="category.show_reverse"> <input type="checkbox" id="category.show_reverse" name="category.show_reverse" value="true"#{" checked" if @conf['category.show_reverse']}>Sorts the list from newest to oldest </label></p> HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/counter.rb���������������������������������������������������������0000664�0000000�0000000�00000005521�13626457307�0020617�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# counter.rb # # English resource file for access counter plugin. # # Copyright (c) 2006 Masao Mutoh # You can redistribute it and/or modify it under GPL2 or any later version. # @counter_conf_counter ||= "Access counter" @counter_conf_init_head ||= "Initial number" @counter_conf_init_desc ||= "Set initial number. Default value is 0." @counter_conf_init_label ||= "Initial value:" @counter_conf_log_head ||= "Logging" @counter_conf_log_desc ||= "Save the access number logs for each days.<br/>The log is saved to "#{@cache_path}/counter/counter.log"." @counter_conf_log_true ||= "Enable" @counter_conf_log_false ||= "Disable" @counter_conf_timer_head ||= "Visitor's interval(cookie)" @counter_conf_timer_desc ||= "Don't count a visitor who repeat to access this tDiary for this interval using cookie. Default value is 12(hour)." @counter_conf_timer_label ||= "Visitor's interval:" @counter_conf_timer_unit ||= "hour" @counter_conf_deny_same_src_interval_head ||= "Visitor's interval(without cookie)" @counter_conf_deny_same_src_interval_desc ||= "Don't count a visitor who isn't enable the cookie for this interval. This function aims to deny to access repeatly from the same user agent without cookie. Default value is 4 hour." @counter_conf_deny_same_src_interval_label ||= "Visitor's interval:" @counter_conf_deny_same_src_interval_unit ||= "hour" @counter_conf_max_keep_access_num_head ||= "Max number to keep the visitors" @counter_conf_max_keep_access_num_desc ||= "Max number to keep the visitors for "Visitor's interval(without cookie)". Default value is 10000." @counter_conf_max_keep_access_num_label ||= "Max number to keep the visitors" @counter_conf_max_keep_access_num_unit ||= "visitors" @counter_conf_deny_user_agents_head ||= "Deny user agents against spams" @counter_conf_deny_user_agents_desc ||= "Don't count a visitor which user agents are defined here. Usually, Crawler/Robots are set. You can use regexp. <pre>(e.g.) Googlebot|Bulkfeeds</pre> <p>Entried user agents are below:" @counter_conf_deny_user_agents_label ||= "Deny user agents: " @counter_conf_kiriban_head ||= "Kiriban(memorial number)" @counter_conf_kiriban_desc ||= "Kiriban is the memorial number. (e.g.) 100,123,300" @counter_conf_kiriban_label_all ||= "Kiribans:" @counter_conf_kiriban_label_today ||= "Today's Kiribans:" @counter_conf_kiriban_messages_head ||= "The messages on the 'kiriban'" @counter_conf_kiriban_messages_desc ||= "Describe <%= kiriban %> in the header or footer, this messages will be shown when the counter number reaches to the Kiriban." @counter_conf_kiriban_messages_label_all ||= "Kiriban message:" @counter_conf_kiriban_messages_label_today ||= "Today's Kiriban message:" @counter_conf_kiriban_messages_label_nomatch ||= "Default(Not Kiriban)message:" # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/daily_theme.rb�����������������������������������������������������0000664�0000000�0000000�00000000470�13626457307�0021422�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/daily_theme.rb # # Copyright (c) 2005 SHIBATA Hiroshi <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. @daily_theme_label = 'Daily Theme' @daily_theme_label_desc = 'List of theme name.' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/disp_referrer.rb���������������������������������������������������0000664�0000000�0000000�00000051160�13626457307�0021773�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = A little bit more powerful display of referrers((-$Id: disp_referrer.rb,v 1.20 2008-03-02 09:01:46 kazuhiko Exp $-)) English resource == Copyright notice Copyright (C) 2003 zunda <zunda at freeshell.org> Please note that some methods in this plugin are written by other authors as written in the comments. Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ../ChangeLog for changes after this. * Mon Sep 29, 2003 zunda <zunda at freeshell.org> - forgot to change arguments after changing initialize() * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - name.untaint to eval name * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - use to_native instead of to_euc * Mon Sep 19, 2003 zunda <zunda at freeshell.org> - disp_referrer2.rb,v 1.1.2.104 commited as disp_referrer.rb * Mon Sep 1, 2003 zunda <zunda at freeshell.org> - more strcit check for infoseek search enigne * Wed Aug 27, 2003 zunda <zunda at freeshell.org> - rd.yahoo, Searchalot, Hotbot added * Tue Aug 12, 2003 zunda <zunda at freeshell.org> - search engine list cleaned up * Mon Aug 11, 2003 zunda <zunda at freeshell.org> - instance_eval for e[2] in the search engine list * Wed Aug 7, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - キャッシュの更新をより確実にするようにしました。WWWブラウザから置換 リストを作った場合にはリストの最初に追加されます。 - secure=trueな日記でその他のリンク元リストが表示できるようになりました。 - Regexp generation for Wiki sites * Wed Aug 6, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - 主なオプションとリンク元置換リストの効率的な編集がWWWブラウザからで きるようになりました。secure=trueな日記では一部の機能は使えません。 * Sat Aug 2, 2003 zunda <zunda at freeshell.org> - Second version - basic functions re-implemented - オプションを命名しなおしました。また不要なオプションを消しました。 tdiary.confを編集していた方は、お手数ですが設定をしなおしてください。 - Noraライブラリとキャッシュの利用で高速化しました。 - 検索エンジンのリストをプラグインで持つようになりました。&や;を含む検 索文字列も期待通りに抽出できます。 * Mon Feb 17, 2003 zunda <zunda at freeshell.org> - First version =end # Message strings Disp_referrer2_name = 'Referrer classification' Disp_referrer2_abstract = <<'_END' <p> This plugin distinguishes the URLs from antennas and search engines and shows them separately. Search keywords from different engines are compound together. </p> _END Disp_referrer2_cache_info = <<'_END' <p> Total size of the caches is %1$s byte(s). </p> _END Disp_referrer2_update_info = <<'_END' <p> Please clear the cache by checking this box: <label for="dr2.cache.update"><input id="dr2.cache.update" name="dr2.cache.update" value="force" type="checkbox">clear the cache</label>, and clicking OK after editing the <a href="%1$s">today's link</a> lists. </p> _END Disp_referrer2_move_to_refererlist = <<'_END' <a href="%s">Follow this link</a> to edit the referer lists. _END Disp_referrer2_move_to_config = <<'_END' <a href="%s">Follow this link</a> to configure the plug-in. _END Disp_referrer2_also_todayslink = <<'_END' Referer list can also be edited via "<a href="%s">Today's link</a>". _END Disp_referrer2_antenna_label = 'Antennae' Disp_referrer2_unknown_label = 'Others' Disp_referrer2_search_label = 'Search engines' Disp_referrer2_search_unknown_keyword = 'Unknown keyword' Disp_referrer2_cache_label = '(cache from %s)' class DispRef2SetupIF # show options def show_options r = <<-_HTML <h3>Categorization and display of referrer URLs</h3> <input name="dr2.current_mode" value="#{Options}" type="hidden"> <table> <tr> <td><label for="dr2.unknown.divide.true"><input id="dr2.unknown.divide.true" name="dr2.unknown.divide" value="true" type="radio"#{' checked'if @setup['unknown.divide']}>Separate #{DispRef2String::escapeHTML(@setup['unknown.label'])}</label> <td><label for="dr2.unknown.divide.false"><input id="dr2.unknown.divide.false" name="dr2.unknown.divide" value="false" type="radio"#{' checked'if not @setup['unknown.divide']}>Treat #{DispRef2String::escapeHTML(@setup['unknown.label'])}</label> as normal links. </table> <table> <tr> <td><label for="dr2.unknown.hide.false"><input id="dr2.unknown.hide.false" name="dr2.unknown.hide" value="false" type="radio"#{' checked'if not @setup['unknown.hide']}>Show</label> <td><label for="dr2.unknown.hide.true"><input id="dr2.unknown.hide.true" name="dr2.unknown.hide" value="true" type="radio"#{' checked'if @setup['unknown.hide']}>Hide</label> separated #{DispRef2String::escapeHTML(@setup['unknown.label'])}. <tr> <td><label for="dr2.normal.categorize.true"><input id="dr2.normal.categorize.true" name="dr2.normal.categorize" value="true" type="radio"#{' checked'if @setup['normal.categorize']}>Use</label> <td><label for="dr2.normal.categorize.false"><input id="dr2.normal.categorize.false" name="dr2.normal.categorize" value="false" type="radio"#{' checked'if not @setup['normal.categorize']}>Don't use</label> strings inside [ and ] to categorize normal links. <tr> <td><label for="dr2.long.only_normal.false"><input id="dr2.long.only_normal.false" name="dr2.long.only_normal" value="false" type="radio"#{' checked'if not @setup['long.only_normal']}>Show</label> <td><label for="dr2.long.only_normal.true"><input id="dr2.long.only_normal.true" name="dr2.long.only_normal" value="true" type="radio"#{' checked'if @setup['long.only_normal']}>Hide</label> links other than normal URLs in the daily view. <tr> <td><label for="dr2.short.only_normal.false"><input id="dr2.short.only_normal.false" name="dr2.short.only_normal" value="false" type="radio"#{' checked'if not @setup['short.only_normal']}>Show</label> <td><label for="dr2.short.only_normal.true"><input id="dr2.short.only_normal.true" name="dr2.short.only_normal" value="true" type="radio"#{' checked'if @setup['short.only_normal']}>Hide</label> links other than normal URLs in the latest view. </table> <h3>Grouping of normal links</h3> <table> <tr> <td><label for="dr2.normal.group.true"><input id="dr2.normal.group.true" name="dr2.normal.group" value="true" type="radio"#{' checked'if @setup['normal.group']}>Group with the title strings</label> <td><label for="dr2.normal.group.false"><input id="dr2.normal.group.false" name="dr2.normal.group" value="false" type="radio"#{' checked'if not @setup['normal.group']}>Show each URLs</label> of normal links. <tr> <td><label for="dr2.normal.ignore_parenthesis.true"><input id="dr2.normal.ignore_parenthesis.true" name="dr2.normal.ignore_parenthesis" value="true" type="radio"#{' checked'if @setup['normal.ignore_parenthesis']}>Ignore</label> <td><label for="dr2.normal.ignore_parenthesis.false"><input id="dr2.normal.ignore_parenthesis.false" name="dr2.normal.ignore_parenthesis" value="false" type="radio"#{' checked'if not @setup['normal.ignore_parenthesis']}>don't ignore</label> the last parenthesis when grouping normal links with the titles. </table> <h3>Grouping of links from antennae</h3> <table> <tr> <td><label for="dr2.antenna.group.true"><input id="dr2.antenna.group.true" name="dr2.antenna.group" value="true" type="radio"#{' checked'if @setup['antenna.group']}>Group with the title strings</label> <td><label for="dr2.antenna.group.false"><input id="dr2.antenna.group.false" name="dr2.antenna.group" value="false" type="radio"#{' checked'if not @setup['antenna.group']}>Show each URLs</label> of links from antennae. <tr> <td><label for="dr2.antenna.ignore_parenthesis.true"><input id="dr2.antenna.ignore_parenthesis.true" name="dr2.antenna.ignore_parenthesis" value="true" type="radio"#{' checked'if @setup['antenna.ignore_parenthesis']}>ignore</labe> <td><label for="dr2.antenna.ignore_parenthesis.false"><input id="dr2.antenna.ignore_parenthesis.false" name="dr2.antenna.ignore_parenthesis" value="false" type="radio"#{' checked'if not @setup['antenna.ignore_parenthesis']}>don't ignore</labe> the last parenthesis when grouping links from antennae with the titles. </table> <h3>Keywords from search engines</h3> <table> <tr> <td><label for="dr2.search.expand.true"><input id="dr2.search.expand.true" name="dr2.search.expand" value="true" type="radio"#{' checked'if @setup['search.expand']}>Show</label> <td><Label for="dr2.search.expand.false"><input id="dr2.search.expand.false" name="dr2.search.expand" value="false" type="radio"#{' checked'if not @setup['search.expand']}>Don't show</label> the search engine names. </table> _HTML r << <<-_HTML <h3>Cache</h3> <p>It isn't available to turn on this option with tDiary2 file format(DefaultIO).</p> <table> <tr> <td><label for="dr2.no_cache.false"><input id="dr2.no_cache.false" name="dr2.no_cache" value="false" type="radio"#{' checked'if not @setup['no_cache']}>Use</label> <td><label for="dr2.no_cache.true"><input id="dr2.no_cache.true" name="dr2.no_cache" value="true" type="radio"#{' checked'if @setup['no_cache']}>Don't use</label> cache. <tr> <td>Limit cache size to <td colspan="3"><input name="dr2.cache_max_size" value="#{DispRef2String::escapeHTML(@setup['cache_max_size'])}" type="text">Bytes. <tr> <td><label for="dr2.cache.update.force"><input id="dr2.cache.update.force" name="dr2.cache.update" value="force" type="radio">clear</label> <td><label for="dr2.cache.update.auto"><input id="dr2.cache.update.auto" name="dr2.cache.update" value="auto" type="radio" checked>clear if needed</label> <td><label for="dr2.cache.update.never"><input id="dr2.cache.update.never" name="dr2.cache.update" value="never" type="radio">don't clear</label> the cache at this time. </table> <p>Cache size limit is an approximation. There is a chance that the cache size is bigger than the configured value. Setting the limit to zero disalbes limitation. K or M can be suffixed meaning Kbytes or Mbytes.</p> _HTML r end # shows URL list to be added to the referer_table or no_referer def show_unknown_list urls = DispRef2Cache.new( @setup ).urls( DispRef2URL::Unknown ).keys if urls.size == 0 then urls = DispRef2Latest.new( @cgi, 'latest.rhtml', @conf, @setup ).unknown_urls end urls.reject!{ |url| DispRef2String::url_match?( url, @setup['reflist.ignore_urls'] ) } r = <<-_HTML <h3>URL Conversion</h3> <input name="dr2.current_mode" value="#{RefList}" type="hidden"> <p>URLs that match the Ignore list are not listed here.</p> <p> If you don't want to see the URLs that you neither put into the Conversion list or the Excluding list can be put in the Ignore list. The Ignore list only affects the list shown here. Please check <input name="dr2.clear_ignore_urls" value="true" type="checkbox">here if you want to reset the Ignore list. </p> _HTML if urls.size > 0 then r << <<-_HTML <p>Please fill in the titles for the URL(s) in the lower text box(es) to put the URL(s) into the Conversion list. Please check the check box(es) if you want to put the URL(s) into the Excluding list. </p> <p> Regular expressions are made up automatically. You can edit them if you want. </p> <p> In the titles, you can refer to the strings between parenthesis in the regular expression with something like "\\1" (backslash plus a number). You can also use a script fragment like "sprintf('[tdiary:%d]', $1.to_i+1)". </p> _HTML if @cgi.auth_type and @cgi.remote_user and @setup['configure.use_link'] then r << <<-_HTML <p> [NOTE] Be aware that by clicking the URLs below, the author of the www site might know the URL of this page to edit and configure your diary. </p> _HTML end r << <<-_HTML <p> Please edit URLs not shown here through "<a href="#{DispRef2String::escapeHTML(@conf.update)}?conf=referer">Today's link</a>" </p> <dl> _HTML i = 0 urls.sort.each do |url| shown_url = DispRef2String::escapeHTML( @setup.to_native( DispRef2String::unescape( url ) ) ) if @cgi.auth_type and @cgi.remote_user and @setup['configure.use_link'] then r << "<dt><a href=\"#{DispRef2String::escapeHTML(url)}\">#{shown_url}</a>" else r << "<dt>#{shown_url}" end r << <<-_HTML <dd> Add this URL to <label for="dr2.#{i}.noref"><input id="dr2.#{i}.noref" name="dr2.#{i}.noref" value="true" type="checkbox">Excluding list</label> <label for="dr2.#{i}.ignore"><input id="dr2.#{i}.ignore" name="dr2.#{i}.ignore" value="true" type="checkbox">Ignore list</label><br> <input name="dr2.#{i}.reg" value="#{DispRef2String::escapeHTML( DispRef2String::url_regexp( url ) )}" type="text" size="70"><br> <input name="dr2.#{i}.title" value="" type="text" size="70"> _HTML i += 1 end r << <<-_HTML <input name="dr2.urls" type="hidden" value="#{i}"> </dl> _HTML else r << <<-_HTML <p>Currently there is no #{DispRef2String::escapeHTML(@setup['unknown.label'])}.</p> _HTML end r << <<-_HTML <h3>Regular expressions for antennae</h3> <p>URLs or titles matching these expression will be categorized as antennae.</p> <ul> <li>URL: <input name="dr2.antenna.url" value="#{DispRef2String::escapeHTML( @setup.to_native( @setup['antenna.url'] ) )}" type="text" size="70"> <label for="dr2.antenna.url.default"><input id="dr2.antenna.url.default" name="dr2.antenna.url.default" value="true" type="checkbox">Use default</label> <li>Title:<input name="dr2.antenna.title" value="#{DispRef2String::escapeHTML( @setup.to_native( @setup['antenna.title'] ) )}" type="text" size="70"> <label for="dr2.antenna.title.default"><input id="dr2.antenna.title.default" name="dr2.antenna.title.default" value="true" type="checkbox">Use default</label> </ul> _HTML r end end # Hash table of search engines # key: company name # value: array of: # [0]:url regexp [1]:title [2]:keys for search keyword [3]:cache regexp # keys - an Array of Strings for usual keys # - a String as a Ruby code to be sent to URL after regexp matching # - a Symbol to indicate the key contains URL to be recursively converted DispReferrer2_Google_cache = /cache:[^:]+:([^+]+)+/ DispReferrer2_Engines = { 'google' => [ [%r{\Ahttp://(?:[^./]+\.)*?google\.([^/]+)/(search|custom|ie)}i, '"Google in .#{$1}"', ['as_q', 'q', 'as_epq'], DispReferrer2_Google_cache], [%r{\Ahttp://(?:[^./]+\.)*?google\.([^/]+)/.*url}i, '"Google URL search in .#{$1}"', ['as_q', 'q'], DispReferrer2_Google_cache], [%r{\Ahttp://(?:[^./]+\.)*?google/search}i, '"Google?"', ['as_q', 'q'], DispReferrer2_Google_cache], [%r{\Ahttp://eval.google\.([^/]+)}i, '"Google Accounts in .#{$1}"', [], nil], [%r{\Ahttp://(?:[^./]+\.)*?google\.([^/]+)}i, '"Google in .#{$1}"', [], nil], ], 'yahoo' => [ [%r{\Ahttp://.*?\.rd\.yahoo\.([^/]+)}i, '"Yahoo! redirector.#{$1}"', 'split(/\*/)[1]', nil], [%r{\Ahttp://.*?\.yahoo\.([^/]+)}i, '"Yahoo! search in .#{$1}"', ['p', 'va', 'vp'], DispReferrer2_Google_cache], ], 'netscape' => [[%r{\Ahttp://.*?\.netscape\.([^/]+)}i, '"Netscape search in .#{$1}"', ['search', 'query'], DispReferrer2_Google_cache]], 'msn' => [[%r{\Ahttp://.*?\.MSN\.([^/]+)}i, '"MSN search in .#{$1}"', ['q', 'MT'], nil ]], 'metacrawler' => [[%r{\Ahttp://.*?.metacrawler.com}i, '"MetaCrawler"', ['q'], nil ]], 'metabot' => [[%r{\Ahttp://.*?\.metabot\.ru}i, '"MetaBot.ru"', ['st'], nil ]], 'altavista' => [[%r{\Ahttp://.*?\.altavista\.([^/]+)}i, '"Altavista in .#{$1}"', ['q'], nil ]], 'infoseek' => [[%r{\Ahttp://(www\.)?infoseek\.co\.jp}i, '"Infoseek"', ['qt'], nil ]], 'odn' => [[%r{\Ahttp://.*?\.odn\.ne\.jp}i, '"ODN検索"', ['QueryString', 'key'], nil ]], 'lycos' => [[%r{\Ahttp://.*?\.lycos\.([^/]+)}i, '"Lycos in .#{$1}"', ['query', 'q', 'qt'], nil ]], 'fresheye' => [[%r{\Ahttp://.*?\.fresheye}i, '"Fresheye"', ['kw'], nil ]], 'goo' => [ [%r{\Ahttp://.*?\.goo\.ne\.jp}i, '"goo"', ['MT'], nil ], [%r{\Ahttp://.*?\.goo\.ne\.jp}i, '"goo"', [], nil ], ], 'nifty' => [ [%r{\Ahttp://search\.nifty\.com}i, '"@nifty/@search"', ['q', 'Text'], DispReferrer2_Google_cache], [%r{\Ahttp://srchnavi\.nifty\.com}i, '"@nifty redirector"', ['title'], nil ], ], 'eniro' => [[%r{\Ahttp://.*?\.eniro\.se}i, '"Eniro"', ['q'], DispReferrer2_Google_cache]], 'excite' => [[%r{\Ahttp://.*?\.excite\.([^/]+)}i, '"Excite in .#{$1}"', ['search', 's', 'query', 'qkw'], nil ]], 'biglobe' => [ [%r{\Ahttp://.*?search\.biglobe\.ne\.jp}i, '"BIGLOBE search"', ['q'], nil ], [%r{\Ahttp://.*?search\.biglobe\.ne\.jp}i, '"BIGLOBE search"', [], nil ], ], 'dion' => [[%r{\Ahttp://dir\.dion\.ne\.jp}i, '"Dion"', ['QueryString', 'key'], nil ]], 'naver' => [[%r{\Ahttp://.*?\.naver\.co\.jp}i, '"NAVER Japan"', ['query'], nil ]], 'webcrawler' => [[%r{\Ahttp://.*?\.webcrawler\.com}i, '"WebCrawler"', ['qkw'], nil ]], 'euroseek' => [[%r{\Ahttp://.*?\.euroseek\.com}i, '"Euroseek.com"', ['string'], nil ]], 'aol' => [[%r{\Ahttp://.*?\.aol\.}i, '"AOL search"', ['query'], nil ]], 'alltheweb' => [ [%r{\Ahttp://.*?\.alltheweb\.com}i, '"AlltheWeb.com"', ['q'], nil ], [%r{\Ahttp://.*?\.alltheweb\.com}i, '"AlltheWeb.com"', [], nil ], ], 'kobe-u' => [ [%r{\Ahttp://bach\.scitec\.kobe-u\.ac\.jp/cgi-bin/metcha.cgi}i, '"Metcha search engine"', ['q'], nil ], [%r{\Ahttp://bach\.istc\.kobe-u\.ac\.jp/cgi-bin/metcha.cgi}i, '"Metcha search engine"', ['q'], nil ], ], 'tocc' => [[%r{\Ahttp://www\.tocc\.co\.jp/search/}i, '"TOCC/Search"', ['QRY'], nil ]], 'yappo' => [[%r{\Ahttp://i\.yappo\.jp/}i, '"iYappo"', [], nil ]], 'suomi24' => [[%r{\Ahttp://.*?\.suomi24\.([^/]+)/.*query}i, '"Suomi24"', ['q'], DispReferrer2_Google_cache]], 'earthlink' => [[%r{\Ahttp://search\.earthlink\.net/search}i, '"EarthLink Search"', ['as_q', 'q', 'query'], DispReferrer2_Google_cache]], 'infobee' => [[%r{\Ahttp://infobee\.ne\.jp/}i, '"Infobee"', ['MT'], nil ]], 't-online' => [[%r{\Ahttp://brisbane\.t-online\.de/}i, '"T-Online"', ['q'], DispReferrer2_Google_cache]], 'walla' => [[%r{\Ahttp://find\.walla\.co\.il/}i, '"Walla! Channels"', ['q'], nil ]], 'mysearch' => [[%r{\Ahttp://.*?\.mysearch\.com/}i, '"My Search"', ['searchfor'], nil ]], 'jword' => [[%r{\Ahttp://search\.jword.jp/}i, '"JWord"', ['name'], nil ]], 'nytimes' => [[%r{\Ahttp://query\.nytimes\.com/search}i, '"New York Times: Search"', ['as_q', 'q', 'query'], DispReferrer2_Google_cache]], 'aaacafe' => [[%r{\Ahttp://search\.aaacafe\.ne\.jp/search}i, '"AAA!CAFE"', ['key'], nil]], 'virgilio' => [[%r{\Ahttp://search\.virgilio\.it/search}i, '"VIRGILIO Ricerca"', ['qs'], nil]], 'ceek' => [[%r{\Ahttp://www\.ceek\.jp}i, '"ceek.jp"', ['q'], nil]], 'cnn' => [[%r{\Ahttp://websearch\.cnn\.com}i, '"CNN.com"', ['query', 'as_q', 'q', 'as_epq'], DispReferrer2_Google_cache]], 'webferret' => [[%r{\Ahttp://webferret\.search\.com}i, '"WebFerret"', 'split(/,/)[1]', nil]], 'eniro' => [[%r{\Ahttp://www\.eniro\.se}i, '"Eniro"', ['query', 'as_q', 'q'], DispReferrer2_Google_cache]], 'passagen' => [[%r{\Ahttp://search\.evreka\.passagen\.se}i, '"Eniro"', ['q', 'as_q', 'query'], DispReferrer2_Google_cache]], 'redbox' => [[%r{\Ahttp://www\.redbox\.cz}i, '"RedBox"', ['srch'], nil]], 'odin' => [[%r{\Ahttp://odin\.ingrid\.org}i, '"ODiN"', ['key'], nil]], 'kensaku' => [[%r{\Ahttp://www\.kensaku\.}i, '"kensaku.jp"', ['key'], nil]], 'hotbot' => [[%r{\Ahttp://www\.hotbot\.}i, '"HotBot Web Search"', ['MT'], nil ]], 'searchalot' => [[%r{\Ahttp://www\.searchalot\.}i, '"Searchalot"', ['q'], nil ]], 'cometsystems' => [[%r{\Ahttp://search\.cometsystems\.com}i, '"Comet Web Search"', ['qry'], nil ]], 'bulkfeeds' => [ [%r{\Ahttp://bulkfeeds\.net/app/search2}i, '"Bulkfeeds: RSS Directory & Search"', ['q'], nil ], [%r{\Ahttp://bulkfeeds\.net/app/similar}i, '"Bulkfeeds Similarity Search"', ['url'], nil ], ], 'answerbus' => [[%r{\Ahttp://www\.answerbus\.com}i, '"AnswerBus"', [], nil ]], 'dogplile' => [[%r{\Ahttp://www.\dogpile\.com/info\.dogpl/search/web/}i, '"AnswerBus"', [], nil ]], 'www' => [[%r{\Ahttp://www\.google/search}i, '"Google?"', ['as_q', 'q'], DispReferrer2_Google_cache]], # TLD missing 'planet' => [[%r{\Ahttp://www\.planet\.nl/planet/}i, '"Planet-Zoekpagina"', ['googleq', 'keyword'], DispReferrer2_Google_cache]], # googleq parameter has a strange prefix '216' => [[%r{\Ahttp://(\d+\.){3}\d+/search}i, '"Google?"', ['as_q', 'q'], DispReferrer2_Google_cache]], # cache servers of google? } # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/dropdown_calendar.rb�����������������������������������������������0000664�0000000�0000000�00000000405�13626457307�0022621�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# English resource of dropdown_calendar.rb # # calendar: replace calendar with dropdown style. # Parameter: none. # @dropdown_calendar_label = 'Past Diaries' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/edit_today.rb������������������������������������������������������0000664�0000000�0000000�00000001016�13626457307�0021260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# English resources of edit_today plugin. @edit_today_caption = 'Edit' def edit_today_edit_label( date ) date.strftime( 'Edit %Y-%m-%d' ) end def edit_today_conf_html <<-HTML <h3 class="subtitle">Link String</h3> <p>Specify string to link to edit page. If you have image file, you can specify icon on this link.</p> <p><input name="edit_today_caption" size="70" value="#{h @conf['edit_today.caption']}"></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/hide-mail-field.rb�������������������������������������������������0000664�0000000�0000000�00000001222�13626457307�0022044�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# English resource of hide-mail-field plugin @hide_mail_field_label_conf = 'Hide Mail Field' def hide_mail_field_conf_html <<-HTML <h3>Description of TSUKKOMI</h3> <p>Show messeges about hidden of E-mail field for your subscribers. This field is as same as in default spam filter preferences.<br> <textarea name="comment_description" cols="60" rows="5">#{h comment_description}</textarea></p> Ex. "Add a TSUKKOMI or Comment please. E-mail field was hidden because against spam. Please do not input E-mail address if you can see it."</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/highlight.rb�������������������������������������������������������0000664�0000000�0000000�00000001354�13626457307�0021107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resource of highlight.rb # def highlight_conf_label; 'Highlight'; end def highlight_conf_html <<-HTML <h3 class="subtitle">Color Settings of Highlight</h3> <p>Highlights subtitle jumped from other pages as <span style="color: #{h @conf['highlight.color']}; background: #{h @conf['highlight.background']}">THIS</span>.</p> <table> <tr> <th>Text color of highlight</th> <td><input name="highlight.color" value="#{h @conf['highlight.color']}"></td> </tr> <tr> <th>Background color of highlight</th> <td><input name="highlight.background" value="#{h @conf['highlight.background']}"></td> </tr> </table> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/image.rb�����������������������������������������������������������0000664�0000000�0000000�00000003445�13626457307�0020225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # English resource of image plugin # # # Image Diary - Upload images and insert to diary. # # image( number, 'altword', thumbnail, size, place ) - show an image. # number - image ID as 0, 1, 2... # altword - alt strings of the img element. # thumbnail - image ID of thumbnail (optional) # size - array format of image size (optional), as [width, height] # place - class name of <img> tag (optional), "place" is default. # # image_left( number, 'altword', thumbnail, size ) - show an image with "class=left" # image_right( number, 'altword', thumbnail, size ) - show an image with "class=right" # # image_link( number, 'desc' ) - make link to an image. # number - image ID as 0, 1, 2... # desc - description of the image. # # options in tdiary.conf: # @options['image.dir'] # Directory of uploading images. Default is './images/'. # You have to set parmission to writable by web server. # @options['image.url'] # URL of the image directory. Default is './images/'. # @options['image.maxwidth'] # Max display width of image without specified 'size' parameter. # def image_error_num( max ); "You can add images upto #{h max} par a day."; end def image_error_size( max ); "You can add images upto #{h max} bytes par an image."; end def image_label_list_caption; 'Image Diary (List/Delete) - Click an image to insert'; end def image_label_add_caption; 'Image Diary (Add)'; end def image_label_description; 'Description of the image'; end def image_label_add_plugin; 'Add to the article'; end def image_label_delete; 'Delete checked images'; end def image_label_only_jpeg; 'Only JPEG'; end def image_label_add_image; 'Upload the image'; end def image_label_drop_here; 'Drop files here'; end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/kw.rb��������������������������������������������������������������0000664�0000000�0000000�00000001002�13626457307�0017547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def kw_label "Keyword" end def kw_desc <<-HTML <p>kw(KeyWord) plugin generate a Link by simple words. You can specify keywords as space sepalated value: "keyword URL". For example,</p> <pre>google http://www.google.com/search?q=$1</pre> <p>then you specify in your diary as:</p> <pre><%=kw 'google:tdiary' %></pre> <p>so it will be translated to link of seraching 'tdiary' at Google.</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/makerss.rb���������������������������������������������������������0000664�0000000�0000000�00000004371�13626457307�0020607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# makerss.rb English resources def makerss_tsukkomi_label( id ) "TSUKKOMI to #{id[0,4]}-#{id[4,2]}-#{id[6,2]}[#{id[/[1-9]\d*$/]}]" end @makerss_conf_label = 'RSS feeds' def makerss_conf_html <<-HTML <h3>RSS feeds settings</h3> <p>RSS feeds provides contents of your diary in a machine-readable format. Information in RSS is read with RSS readers and posted on other web sites.</p> #{%Q[<p class="message">Cannot write to file '#{@makerss_full.file}'.<br>This file have to writable by your web server.</p>] unless @makerss_full.writable?} <ul> <li><select name="makerss.hidecontent"> <option value="f"#{' selected' unless @conf['makerss.hidecontent']}>Include</option> <option value="t"#{' selected' if @conf['makerss.hidecontent']}>Hide</option></select> encoded contents of your diary in the feed. <li>Include summary of your contents<select name="makerss.shortdesc"> <option value="f"#{' selected' unless @conf['makerss.shortdesc']}>as long as possible</option> <option value="t"#{' selected' if @conf['makerss.shortdesc']}>only some portion</option></select> in the feed. <li><select name="makerss.comment_link"> <option value="f"#{' selected' unless @conf['makerss.comment_link']}>Insert</option> <option value="t"#{' selected' if @conf['makerss.comment_link']}>Don't Insert </option></select> a link to TSUKKOMI form into encoded text. </ul> <h3>Feed without TSUKKOMI</h3> <p>Standard feed contains your diary and also TSUKKOMIs by your diary readers. If you want to make a feed without TSUKKOMIs, set this preference below. So, when standard feed has encoded contens, this feed contain encoded text of TSUKKOMI also.</p> #{%Q[<p class="message">Cannot write to file '#{@makerss_no_comments.file}'.<br>This file have to writable by your web server.</p>] if @conf['makerss.no_comments'] and !@makerss_no_comments.writable?} <ul> <li><select name="makerss.no_comments"> <option value="t"#{' selected' if @conf['makerss.no_comments']}>Feed</option> <option value="f"#{' selected' unless @conf['makerss.no_comments']}>Don't feed</option></select> RSS without TSUKKOMI.</li> </ul> HTML end @makerss_edit_label = "A little modify (don't update feeds)" # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/pb-show.rb���������������������������������������������������������0000664�0000000�0000000�00000001661�13626457307�0020520�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# English resource of pb-show.rb # def pingback_today; "Today's Pingbacks"; end def pingback_total( total ); "(Total: #{total})"; end def pb_show_conf_html <<-"HTML" <h3 class="subtitle">Pingback anchor</h3> <p>Pingback anchor is inserted into begining of each Pingbacks from other weblogs. So You can specify '<span class="tanchor">_</span>">', image anchor will be shown Image anchor by themes.</p> <p><input name="trackback_anchor" value="#{ h(@conf['trackback_anchor'] || @conf.comment_anchor ) }" size="40"></p> <h3 class="subtitle">Number of Pingbacks</h3> <p>In Latest or Month mode, you can specify number of visible Pingbacks. So in Dayly mode, all of Pingbacks are shown.</p> <p><input name="trackback_limit" value="#{ h( @conf['trackback_limit'] || @conf.comment_limit )}" size="3"> Pingbacks</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/ping.rb������������������������������������������������������������0000664�0000000�0000000�00000000553�13626457307�0020075�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ping.rb English resources if /conf/ =~ @mode then @ping_label_conf = 'Update ping' @ping_label_list = 'List of ping servers' @ping_label_list_desc = 'Specify URLs of ping request.' @ping_label_timeout = 'Timeout(sec)' end @ping_label_send = 'Sending ping' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/preview.rb���������������������������������������������������������0000664�0000000�0000000�00000000522�13626457307�0020615�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������@preview_label_conf = 'preview' @preview_label_interval = 'refresh interval' @preview_label_interval_desc = 'Specify the interval at which to display the preview in seconds.' @preview_label_min_width = 'side by side screen width' @preview_label_min_width_desc = 'Specifies the width to display the preview screen side-by-side in pixels.' ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/recent_comment.rb��������������������������������������������������0000664�0000000�0000000�00000003720�13626457307�0022141�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/recent_comment.rb # # English resources for recent_comment.rb # # Copyright (c) 2005 Hiroshi SHIBATA <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. # if @mode == 'conf' || @mode == 'saveconf' add_conf_proc( 'recent_comment', 'Recent TSUKKOMI', 'tsukkomi' ) do saveconf_recent_comment recent_comment_init <<-HTML <h3 class="subtitle">The number of display comment</h3> <p>Max <input name="recent_comment.max" value="#{h( @conf['recent_comment.max'] )}" size="3" /> item</p> <h3 class="subtitle">Date format</h3> <p>Refer to <a href="http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Time#strftime">Ruby's Manual</a>for the \'%\' character that can be used.</p> <p><input name="recent_comment.date_format" value="#{h( @conf['recent_comment.date_format'] )}" size="40" /></p> <h3 class="subtitle">Non display name in recent comment list</h3> <p>Specified The name not displayed in the list.</p> <p><input name="recent_comment.except_list" size="60" value="#{h( @conf['recent_comment.except_list'] )}" /></p> <h3 class="subtitle">HTML Template for generate</h3> <p>Specify how each comment is rendered.</p> <textarea name="recent_comment.format" cols="60" rows="3">#{h( @conf['recent_comment.format'] )}</textarea> <p><em>$digit</em> in the template is replaced as follows.</p> <dl> <dt>$2</dt><dd>comment's URL</dd> <dt>$3</dt><dd>comment's shortening display</dd> <dt>$4</dt><dd>name of comment's author</dd> <dt>$5</dt><dd>when the comment is received</dd> </dl> <h3 class="subtitle">Message for no comment</h3> <p>Specify the message to be shown when there is no comment entry.</p> <p><input name="recent_comment.notfound_msg" value="#{h( @conf['recent_comment.notfound_msg'] )}" size="40" /></p> HTML end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/recent_comment3.rb�������������������������������������������������0000664�0000000�0000000�00000005111�13626457307�0022220�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/recent_comment3.rb # # English resources for recent_comment3.rb # # Copyright (c) 2005 Hiroshi SHIBATA <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. # if @mode == 'conf' || @mode == 'saveconf' add_conf_proc( 'recent_comment3', 'Recent TSUKKOMI', 'tsukkomi' ) do saveconf_recent_comment3 recent_comment3_init checked = "t" == @conf['recent_comment3.tree'] ? ' checked' : '' <<-HTML <h3 class="subtitle">The number of display comment</h3> <p>Max <input name="recent_comment3.max" value="#{h( @conf['recent_comment3.max'] )}" size="3" /> item</p> <h3 class="subtitle">Date format</h3> <p>Refer to <a href="http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Time#strftime">Ruby's Manual</a>for the \'%\' character that can be used.</p> <p><input name="recent_comment3.date_format" value="#{h( @conf['recent_comment3.date_format'] )}" size="40" /></p> <h3 class="subtitle">Non display name in recent comment list</h3> <p>Specified The name not displayed in the list. Name is delimited by ","</p> <p><input name="recent_comment3.except_list" size="60" value="#{h( @conf['recent_comment3.except_list'] )}" /></p> <h3 class="subtitle">Tree View mode</h3> <p><label for="recent_comment3.tree"><input id="recent_comment3.tree" name="recent_comment3.tree" type="checkbox" value="t"#{checked} />used Tree View</label></p> <h3 class="subtitle">length of title at Tree View mode</h3> <p>Input length of title at Tree View mode. When Tree view mode is not used, it doesn't relate.</p> <p>Max <input name="recent_comment3.titlelen" value="#{h( @conf['recent_comment3.titlelen'] )}" size="3" /> characters.</p> <h3 class="subtitle">HTML Template for generate</h3> <p>Specify how each comment is rendered.</p> <textarea name="recent_comment3.format" cols="60" rows="3">#{h( @conf['recent_comment3.format'] )}</textarea> <p><em>$digit</em> in the template is replaced as follows.</p> <dl> <dt>$2</dt><dd>comment's URL</dd> <dt>$3</dt><dd>comment's shortening display</dd> <dt>$4</dt><dd>name of comment's author</dd> <dt>$5</dt><dd>when the comment is received</dd> </dl> <h3 class="subtitle">Message for no comment</h3> <p>Specify the message to be shown when there is no comment entry.</p> <p><input name="recent_comment.notfound_msg" value="#{h( @conf['recent_comment.notfound_msg'] )}" size="40" /></p> HTML end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/recent_rss.rb������������������������������������������������������0000664�0000000�0000000�00000001233�13626457307�0021303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- indent-tabs-mode: t -*- # # Copyright (c) 2003-2005 Kouhei Sutou <kou@cozmixng.org> # Distributed under the GPL2 or any later version. # def label_recent_rss_title 'External RSS display' end def label_recent_rss_use_image_link_title 'Image treatment' end def label_recent_rss_use_image_link_description "Select whether you use image as link instead of text or not " + "if the RSS has Web site's image information." end def label_recent_rss_not_use_image_link "don't use image as link" end def label_recent_rss_use_image_link "use image as link" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/referer_scheme.rb��������������������������������������������������0000664�0000000�0000000�00000002652�13626457307�0022120�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = Meta-scheme plugin((-$Id: referer_scheme.rb,v 1.5 2004-02-26 08:09:24 tadatadashi Exp $-)) Makes it easier to edit the referer table. == Usage Enable this plug-in by coping into the plugin directory or selecting from the plug-in selection plug-in. Then, edit the `Rule of conversion URL to words' in `Today's Link' of `Preference'. Add prefixes (meta-scheme) like `tdiary:'. This adds the date of the diaries or blogs according to their URLs. For example, set the `Rule' as * tdiary:http://tdiary.tdiary.net/ tDiary.net management journal. For this example, date is added with a (YYYY-MM-DD) format if the information is contained in the URL. == Notes For URLs with tdiary:, * Do not use parenthesis `(' and `)' * End the URL with a '/' == How to make a meta-scheme Meta-schems are extracted from the user's Rule with a Regexp: /^(\w+):/. Define singleton methods of @conf.referer_table as iterators: def scheme_<scheme>( url, name ) : yield( url_variants, name_variants ) : end The singleton methods are called according to the user's Rule with the `<scheme>:' part omitted in the url. == Copyright Copyright (C) 2003 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/search_control.rb��������������������������������������������������0000664�0000000�0000000�00000004053�13626457307�0022144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = Search control plugin((-$Id: search_control.rb,v 1.2 2004-11-09 21:07:45 zunda Exp $-)) English resource == Summary Ask crawlers whether to make index or not depending upon views (latest, day, etc.) using the meta tag. == Usage Select this plugin through the Select-plugin plugin. To set up, click `Search control' in the configuration view. You can choose if you want crawlers from external search engines to index your one-day view, latest view, etc. The default is to ask the crawlers to only index one-day view. To this plugin to take effect, we have to wish that the crawlers regards the meta-tag. == License Copyright (C) 2003, 2004 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ../ChangeLog for changes after this. * Aug 28, 2003 zunda <zunda at freeshell.org> - 1.3 - simpler configuration display * Aug 26, 2003 zunda <zunda at freeshell.org> - 1.2 - no table in configuration view, thanks to Tada-san. * Aug 26, 2003 zunda <zunda at freeshell.org> - no nofollow - English translation =end ChangeLog # configuration unless defined?( Search_control_plugin_name ) then Search_control_plugin_name = 'Search control' Search_control_description_html = <<'_HTML' <p>Asks the crawlers from external search engines not to index unwanted pages by using the meta tag. Check the viewes you want the search engines to index.</p> <p>Multiple settings can be made for different user agents. If the given user agent does not match any of your settings, the default setting is used.</p> _HTML Search_control_delete_label = 'delete this agent' Search_control_new_label = 'add this agent' Search_control_default_label = 'Default' Search_control_categories = [ [ 'Latest', 'latest' ], [ 'One-day', 'day' ], [ 'One-month', 'month' ], [ 'Same-day', 'nyear' ], [ 'Category', 'category' ] ] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/search_form.rb�����������������������������������������������������0000664�0000000�0000000�00000001546�13626457307�0021433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# search_form.rb English resource. def google_form( button_name = "Google Search", size = 20, default_text = "" ) first = %Q[<a href="https://www.google.com/"> <img src="https://www.google.com/logos/Logo_40wht.gif" style="border-width: 0px; vertical-align: middle;" alt="Google"></a>] search_form( "https://www.google.com/search", "q", button_name, size, default_text, first, '' ) end def yahoo_form( button_name = "Yahoo! Search", size = 20, default_text = "" ) first = %Q[<a href="https://www.yahoo.com/"> <img src="http://us.i1.yimg.com/us.yimg.com/i/yahootogo/ytg_search.gif" style="border-width: 0px; vertical-align: middle;" alt="[Yahoo!]"></a>] search_form( "https://search.yahoo.com/search", "p", button_name, size, default_text, first, "" ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/speed_comment.rb���������������������������������������������������0000664�0000000�0000000�00000000725�13626457307�0021763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def speed_comment_label 'Speed TSUKKOMI' end def speed_comment_html <<-HTML <h3>Size of the form of Speed TSUKKOMI</h3> <p>Name: <input name="speed_comment.name_size" size="5" value="#{h( @conf['speed_comment.name_size'])} || 20 "></p> <p>Body: <input name="speed_comment.body_size" size="5" value="#{h( @conf['speed_comment.body_size'])} || 40 "></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������tdiary-core-5.1.1/misc/plugin/en/tb-show.rb���������������������������������������������������������0000664�0000000�0000000�00000003401�13626457307�0020516�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# English resource of tb-show.rb # def tb_show_conf_html <<-"HTML" <h3 class="subtitle">TrackBack anchor</h3> <p>TrackBack anchor is inserted into begining of each TrackBacks from other weblogs. So You can specify '<span class="tanchor">_</span>">', image anchor will be shown Image anchor by themes.</p> <p><input name="trackback_anchor" value="#{ h(@conf['trackback_anchor'] || @conf.comment_anchor ) }" size="40"></p> <h3 class="subtitle">TrackBack display style</h3> <p>In Latest or Month mode, you can specify style of trackbacks displayed.</p> <p><select name="trackback_shortview_mode"> #{ [["num_in_reflist", "Show number of TrackBacks in referer list (always)"], ["num_in_reflist_if_exists", "Show number of TrackBacks in referer list (if exists)"], ["shortlist", "Show short list of TrackBacks"] ].map{ |op| "<option value='#{op[0]}' #{'selected' if @conf['trackback_shortview_mode'] == op[0]}>#{op[1]}</option>\n" }.to_s } </select></p> <h3 class="subtitle">Number of TrackBacks</h3> <p>In Latest or Month mode, you can specify number of visible TrackBacks. So in Dayly mode, all of TrackBacks are shown.</p> <p><input name="trackback_limit" value="#{ h( @conf['trackback_limit'] || @conf.comment_limit )}" size="3"> TrackBacks</p> <h3 class="subtitle">Show TrackBack URL</h3> <p>In Latest or Month mode, you can specify TrackBack URL will be shown or not in each days.</p> <p><select name="trackback_disp_pingurl"> <option value="true" #{'selected' if @conf['trackback_disp_pingurl']}>Show</options> <option value="false" #{'selected' if !@conf['trackback_disp_pingurl']}>Hide</options> </select></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/todo.rb������������������������������������������������������������0000664�0000000�0000000�00000003074�13626457307�0020106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# en/todo.rb # # English resources for todo.rb # # Copyright (c) 2001,2002,2003 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # def todo_msg_today; "today"; end def todo_msg_in_time(days); "#{days} day(s) left to go"; end def todo_msg_late(days); "#{days} day(s) delay"; end def todo_config_label; "Edit ToDo"; end add_conf_proc('ToDo', 'ToDo plugin') do saveconf_todo todo_init <<-HTML <h3 class="subtitle">How to use</h3> <p>put '<%=todo%>' in the <a href="#{h @update}?conf=header">Header/Footer</a>.</p> <h3 class="subtitle">Edit ToDo</h3> <p>Each line has one ToDo entry, which is in the form of:</p> <pre>priority[deadline] what to do</pre> <p>'priority' and 'what to do' is separated by a apace character.</p> <p>Priority is optional. If you specify priority, put an integer between 1 and 99, otherwise the entry is ignored.</p> <p>Deadline is optional. If you specify deadline, put '[' and ']' around deadline. Deadline is parsed by <a href="http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=ParseDate">ParseDate module</a></p> <p><textarea name="todo.todos" cols="70" rows="15">#{h @todos.join("\n")}</textarea></p> <h3 class="subtitle">Title for ToDo</h3> <p><input name="todo.title" value="#{h(@conf['todo.title']) if @conf['todo.title']}"></p> <h3 class="subtitle">Max number of ToDo entries to be displayed</h3> <p><input name="todo.n" value="#{h @conf['todo.n']}" size="3"> entries</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/weather.rb���������������������������������������������������������0000664�0000000�0000000�00000013675�13626457307�0020610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = Weather-of-today plugin((-$Id: weather.rb,v 1.10 2008-03-02 09:01:46 kazuhiko Exp $-)) Records the weather when the diary is first updated for the date and displays it. == Acknowledgements The idea of this plugin is due to `hsbt'. The author took the hint for the implmentation from `zoe'. `kotak' kindly provided the information about NOAA. The author thanks to them. The author also appreciates National Weather Service ((<URL:http://weather.noaa.gov/>)) making such valuable data available in public domain as described in ((<URL:http://www.noaa.gov/wx.html>)). == Copyright Copyright 2003 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin == Instance variables =end @weather_plugin_name = 'Weather-of-today' =begin == Classes and methods === WeatherTranslator module We want Japanese displayed in a diary written in Japanese. --- Weather::Words_en Array of arrays of a Regexp and a Statement to be executed. WeatherTranslator::S.tr accepts this kind of hash to translate a given string. No translations are defined for English. Please see an example in the Japanese resource. =end require 'erb' class Weather Words_en = [ [%r[\Aunknown\z]i, '""'], ] end =begin === Weather class Weather of a date. --- Weather.html_string --- Weather.error_html_string Returns an HTML fragment showing data or error, called from Weather.to_html. --- Weather.i_html_string Returns a CHTML fragment to be shown on a mobile browser. =end class Weather include ERB::Util def error_html_string %Q|<span class="weather">Weather error:<a href="#{h(@url)}">#{h( @error )}</a></span>| end # edit this method to define how you show the weather def html_string has_data = false r = '<span class="weather">' # weather r << %Q|<a href="#{h(@url)}">| has_condition = false if @data['weather'] then r << %Q|<span class="weather">#{h( WeatherTranslator::S.new( @data['weather']).translate( Words_en ).compact.capitalize )}</span>| has_condition = true has_data = true elsif @data['condition'] then r << %Q|<span class="condition">#{h( WeatherTranslator::S.new( @data['condition']).translate( Words_en ).compact.capitalize )}</span>| has_condition = true has_data = true end # temperature if @data['temperature(C)'] and t = @data['temperature(C)'].scan(/-?[\d.]+/)[-1] then r << ', ' if has_condition r << %Q| <span class="temperature">#{sprintf( '%.0f', 9.0/5.0 * t.to_f + 32.0 )} deg-F</span>| has_data = true end r << '</a>' # time stamp if @tz then tzbak = ENV['TZ'] ENV['TZ'] = @tz # this is not thread safe... end r << ' at ' if @data['timestamp'] then r << Time::at( @data['timestamp'].to_i ).strftime( '%H:%M' ).sub( /^0/, '' ) else r << Time::at( @time.to_i ).strftime( '%H:%M' ).sub( /^0/, '' ) end if @tz then ENV['TZ'] = tzbak end r << "</span>" return has_data ? r : '' end # edit this method to define how you show the weather for a mobile agent def i_html_string r = '' # weather if @data['weather'] then r << %Q|<A HREF="#{u(@url)}">| r << h( WeatherTranslator::S.new( @data['weather']).translate( Words_en ).compact.capitalize ) r << "</A>" elsif @data['condition'] then r << %Q|<A HREF="#{u(@url)}">| r << h( WeatherTranslator::S.new( @data['condition']).translate( Words_en ).compact.capitalize ) r << "</A>" end return r end end # www configuration interface def weather_configure_html( conf ) station = Weather::extract_station_id(conf['weather.url']) station ||= conf['weather.url'] <<-HTML <h3 class="subtitle">Weather-of-today plugin</h3> <p>Records the weather when the diary is first updated for the date and displays it.</p> <h4>Data source</h4> <p>When you want to use e.g. NOAA National Weather Service, select your country from "Select a country..." in <a href="http://weather.noaa.gov/">NOAA National Weather Service</a> and push the "Go!" button. Then select the observation point. Write down the URL of the page shown in the box below. The four letter station ID can also be used here.</p> <p><input name="weather.url" value="#{station}" size="60"></p> <p>It would be better to record your time zone in the data if you are likely to move to another time zone in the future. Thus, the weather data will be shown in the local time where the diary is originally written.</p> <p>To record timezone, add the following line into the tdiary.conf file in the directory tdiary.rb is: e.g. ENV['TZ'] = 'US/Pacific', or write it down the box below.</p> <p><input name="weather.tz" value="#{conf['weather.tz']}"></p> <h4>Display on a normal browser</h4> <p>Select from below:</p> <p><select name="weather.in_title"> <option value="false"#{' selected'unless conf['weather.in_title']}> Show weather above text <option value="true"#{' selected'if conf['weather.in_title']}> Show weather at right of title </select></p> <h4>Display on a mobile browser</h4> <p>Select from below:</p> <p><select name="weather.show_mobile"> <option value="true"#{' selected'if conf['weather.show_mobile']}> Show the weather on a mobile browser. <option value="false"#{' selected'unless conf['weather.show_mobile']}> Do not show the weather on a mobile browser. </select></p> <h4>Display to search engine robots</h4> <p>Select from below:</p> <p><select name="weather.show_robot"> <option value="true"#{' selected'if conf['weather.show_robot']}> Let robots know the weather. <option value="false"#{' selected'unless conf['weather.show_robot']}> Hide the weather from robots. </select></p> <h4>Other configurations</h4> <p>Other options can be configured by means of the tdiary.conf file. Please have a look in the plugin file: weather.rb if you want.</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/en/xmlrpc.rb����������������������������������������������������������0000664�0000000�0000000�00000000621�13626457307�0020441�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def label_xmlrpc_url; 'XML-RPC API URL'; end def label_xmlrpc_blogid; 'Blog ID'; end def label_xmlrpc_username; 'Username'; end def label_xmlrpc_password; 'Password'; end def label_xmlrpc_lastname; 'last name'; end def label_xmlrpc_firstname; 'first name'; end def label_xmlrpc_userid; 'User ID'; end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/footnote.rb�����������������������������������������������������������0000664�0000000�0000000�00000003445�13626457307�0020376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# footnote.rb # # fn: 脚注plugin # パラメタ: # text: 脚注本文 # mark: 脚注マーク('*') # # Copyright (C) 2007 TADA Tadashi <sho@spc.gr.jp> # Distributed under the GPL2 or any later version. # initialize variables @fn_fragment_fm = '' @fn_fragment_f = '' @fn_notes = [] @fn_marks = [] add_body_enter_proc do |date| fn_initialize( date ) '' end add_section_enter_proc do |date, index| fn_initialize( date, index ) unless @conf.style =~ /blog/i '' end def fn_initialize( date, section = 1 ) @fn_fragment_fm = sprintf( 'fm%s-%02d-%%02d', date.strftime( '%Y%m%d' ), section ) @fn_fragment_f = @fn_fragment_fm.sub( /^fm/, 'f' ) @fn_notes = [] @fn_marks = [] end def fn( text, mark = '*' ) @fn_notes += [text] @fn_marks += [mark] idx = @fn_notes.size r = %Q|<span class="footnote">| if feed? then r << %Q|#{mark}#{idx}| else r << %Q|<a | r << %Q|name="#{@fn_fragment_fm % idx}" | r << %Q|href="##{@fn_fragment_f % idx}" | r << %Q|title="#{h text}">| r << %Q|#{h mark}#{idx}| r << %Q|</a>| end r << %Q|</span>| end # print footnotes add_section_leave_proc do |date, index| @conf.style =~ /blog/i ? '' : fn_put end add_body_leave_proc do |date| fn_put end def fn_put if @fn_notes.size > 0 then r = %Q|<div class="footnote">\n| @fn_notes.each_with_index do |fn, idx| r << %Q|\t<p class="footnote">| if feed? then r << %Q|#{h @fn_marks[idx]}#{idx+1}| else r << %Q|<a | r << %Q|name="#{@fn_fragment_f % (idx+1)}" | r << %Q|href="##{@fn_fragment_fm % (idx+1)}">| r << %Q|#{h @fn_marks[idx]}#{idx+1}| r << %Q|</a>| end r << %Q| #{@fn_notes[idx]}</p>\n| end @fn_notes.clear r << %Q|</div>\n| else '' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/gradation.rb����������������������������������������������������������0000664�0000000�0000000�00000001677�13626457307�0020516�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# gradation.rb # # gradation.rb: 文字列をグラデーション表示 # パラメタ: # str: 文字列 # first_color: グラデーション開始色(16進 6桁指定) # last_color: グラデーション終了色(16進 6桁指定) # # Copyright (c) 2002 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # def gradation( str, first_color, last_color ) ary = str.split( //u ) len = ary.length - 1 result = "" r = first_color[0..1].hex.to_f g = first_color[2..3].hex.to_f b = first_color[4..5].hex.to_f rd = ((last_color[0..1].hex - r)/len) gd = ((last_color[2..3].hex - g)/len) bd = ((last_color[4..5].hex - b)/len) ary.each do |x| c = sprintf( '%02x%02x%02x', r, g, b ) result << %Q[<span style="color: ##{c}">#{h x}</span>] r += rd g += gd b += bd end result end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/gradient.rb�����������������������������������������������������������0000664�0000000�0000000�00000001640�13626457307�0020331�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# gradient.rb # # gradient.rb: 文字の大きさを変化させながら表示 # パラメタ: # str: 文字列 # first_size: 開始文字サイズ(数値、単位pt) # last_size: 開始文字サイズ(数値、単位pt) # # 例: 「こんなこともできます」を10ptから30ptに拡大 # <%=gradient 'こんなこともできます', 10, 30 %> # # Copyright (c) 2002 TADA Tadashi <sho@spc.gr.jp> # You can distribute this file under the GPL2 or any later version. # def gradient( str, first_size, last_size ) ary = str.split( //u ) len = ary.length - 1 result = "" fontsize = first_size.to_f sd = ( last_size - first_size ).to_f / len ary.each do |x| s = sprintf( '%d',fontsize.round ) result << %Q[<span style="font-size: #{s}pt;">#{h x}</span>] fontsize += sd end result end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/hide-mail-field.rb����������������������������������������������������0000664�0000000�0000000�00000002013�13626457307�0021441�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # hide-mail-field.rb: Hide E-mail field in TSUKKOMI form against spams. # # To enable this plugin effective, you have to add '@' or '.*' into E-mail # address field in spamfilter plugin. # # Copyright (C) 2007 by TADA Tadahi <sho@spc.gr.jp> # Distributed under GPL2 or any later version. # add_header_proc do if @mode == 'day' <<-STYLE <style type="text/css"><!-- form.comment div.mail { display: none; } --></style> STYLE else '' end end add_footer_proc do if @mode == 'day' <<-SCRIPT <script type="text/javascript"><!-- document.getElementsByName("mail")[0].value = ""; //--></script> SCRIPT else '' end end def comment_form_mobile_mail_field %Q|<INPUT NAME="mail" TYPE="hidden">| end add_conf_proc( 'hide-mail-field', @hide_mail_field_label_conf, 'security' ) do if @mode == 'saveconf' @conf['comment_description'] = @cgi.params['comment_description'][0] end hide_mail_field_conf_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/highlight.rb����������������������������������������������������������0000664�0000000�0000000�00000001132�13626457307�0020477�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # highlight.rb: Highlighting the element jumped from other pages. # # Copyright (C) 2003 by Ryuji SAKAI # Copyright (C) 2003 by Kazuhiro NISHIYAMA # Copyright (C) 2011 by MATSUOKA Kohei # You can redistribute it and/or modify it under GPL2 or any later version. # if @mode == 'day' and not bot? then enable_js('highlight.js') title = (@conf.html_title.gsub(/\\/, '\\\\\\') || '').gsub(/"/, '\\"') add_js_setting('$tDiary.title', %Q|"#{title}(#{@date.strftime('%Y-%m-%d')})"|) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vi: ts=3 sw=3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/html_anchor.rb��������������������������������������������������������0000664�0000000�0000000�00000001572�13626457307�0021036�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# html_anchor # # anchor: アンカーを「YYYYMMDD.html」「YYYYMM.html」形式に置き換える # tDiaryから自動的に呼び出されるので、プラグインファイルを # 設置するだけでよい。このプラグインを有効に使うためには、 # Webサーバ側の設定変更も必要。Webサーバの設定に関しては、 # 以下のサイトが参考になる。 # # http://tdiary-users.sourceforge.jp/cgi-bin/wiki.cgi?html%A4%C7%A5%A2%A5%AF%A5%BB%A5%B9%A4%B7%A4%BF%A4%A4 # # Copyright (c) 2002 TADA Tadashi <sho@spc.gr.jp> # Distributed under the GPL2 or any later version. # def anchor( s ) if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then if $2 then "#$1.html##$2" else "#$1.html" end else "" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/image.rb��������������������������������������������������������������0000664�0000000�0000000�00000020125�13626457307�0017615�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# image.rb # -pv- # # 名称: # 絵日記Plugin # # 概要: # 日記更新画面からの画像アップロード、本文への表示 # # 使う場所: # 本文 # # 使い方: # image( number, 'altword', thumbnail, size, place ) - 画像を表示します。 # number - 画像の番号0、1、2等 # altword - imgタグの altに入れる文字列 # thumbnail - サムネイル(小さな画像)を指定する(省略可) # size - 画像のサイズ(Array)。[width, height]の形式で指定(省略可) # place - imgタグのclass名(省略可)。省略時は'photo' # # image_left( number, 'altword', thumbnail, size ) - imageにclass=leftを追加します。 # image_right( number, 'altword', thumbnail, size ) - imageにclass=rightを追加します。 # # image_link( number, 'desc' ) - 画像へのリンクを生成します。 # number - 画像の番号0、1、2等 # desc - 画像の説明 # # その他: # tDiary version 1.5.4以降で動作します。 # tdiary.confで指定できるオプション: # @options['image.dir'] # 画像ファイルを保存するディレクトリ。無指定時は'./images/' # Webサーバの権限で書き込めるようにしておく必要があります。 # @options['image.url'] # 画像ファイルを保存するディレクトリのURL。無指定時は'./images/' # @options['image.maxwidth'] # sizeを指定しなかった場合に指定できる画像の最大表示幅。無指定時はnil # 表示のたびにファイルアクセスが入るので、重くなるかも? # # ライセンスについて: # Copyright (c) 2002,2003 Daisuke Kato <dai@kato-agri.com> # Copyright (c) 2002 Toshi Okada <toshi@neverland.to> # Copyright (c) 2003 Yoshimi KURUMA <yoshimik@iris.dti.ne.jp> # Distributed under the GPL2 or any later version. # unless @resource_loaded then def image_error_num( max ); "画像は1日#{h max}枚までです。不要な画像を削除してから追加してください"; end def image_error_size( max ); "画像の最大サイズは#{h max}バイトまでです"; end def image_label_list_caption; '絵日記(一覧・削除) - 画像をクリックすると本文に追加できます'; end def image_label_add_caption; '絵日記(追加)'; end def image_label_description; '画像の説明'; end def image_label_add_plugin; '本文に追加'; end def image_label_delete; 'チェックした画像の削除'; end def image_label_only_jpeg; 'JPEGのみ'; end def image_label_add_image; 'この画像をアップロードする'; end def image_label_drop_here; 'ここにファイルをドロップ'; end end def image( id, alt = 'image', thumbnail = nil, size = nil, place = 'photo' ) image = image_list( @image_date )[id.to_i] image_t = image_list( @image_date )[thumbnail.to_i] if thumbnail if size if size.kind_of?(Array) if size.length > 1 size = %Q| width="#{h size[0]}" height="#{h size[1]}"| elsif size.length > 0 size = %Q| width="#{h size[0]}"| end else size = %Q| width="#{size.to_i}"| end elsif @image_maxwidth then _, w, _ = image_info( "#{@image_dir}/#{image}" ) if w > @image_maxwidth then size = %Q[ width="#{h @image_maxwidth}"] else size = "" end end if thumbnail then %Q[<a href="#{h @image_url}/#{h image}"><img class="#{h place}" src="#{h @image_url}/#{h image_t}" alt="#{h alt}" title="#{h alt}"#{size}></a>] else %Q[<img class="#{h place}" src="#{h @image_url}/#{h image}" alt="#{h alt}" title="#{h alt}"#{size}>] end end def image_left( id, alt = "image", thumbnail = nil, width = nil ) image( id, alt, thumbnail, width, "left" ) end def image_right( id, alt = "image", thumbnail = nil, width = nil ) image( id, alt, thumbnail, width, "right" ) end def image_link( id, desc ) image = image_list( @image_date )[id.to_i] %Q[<a href="#{h @image_url}/#{h image}">#{desc}</a>] end # # initialize # @image_dir = (@options && @options['image.dir']) || File.join(TDiary.server_root, @cgi.is_a?(RackCGI) ? 'public/images' : 'images') @image_dir.chop! if /\/$/ =~ @image_dir FileUtils.mkdir_p @image_dir unless File.exist?(@image_dir) @image_url = @options && @options['image.url'] || "#{base_url}images/" @image_url.chop! if /\/$/ =~ @image_url @image_maxwidth = @options && @options['image.maxwidth'] || nil add_body_enter_proc do |date| @image_date = date.strftime( "%Y%m%d" ) "" end # # service methods below. # def image_info( f ) require 'fastimage' info = FastImage.new( f ) [info.type.to_s.sub( /jpeg/, 'jpg' ), info.size].flatten end def image_ext 'jpg|jpeg|gif|png' end def image_list( date ) list = [] reg = /#{date}_(\d+)\.(#{image_ext})$/ begin Dir::glob( @image_dir + "/#{date}_*" ) do |file| file = File.basename( file ) list[$1.to_i] = file if reg =~ file end rescue Errno::ENOENT end list end if /^(form|edit|formplugin|showcomment)$/ =~ @mode then enable_js( 'image.js' ) add_js_setting( '$tDiary.plugin.image' ) add_js_setting( '$tDiary.plugin.image.alt', %Q|'#{image_label_description}'| ) add_js_setting( '$tDiary.plugin.image.drop_here', %Q|'#{image_label_drop_here}'| ) end if /^formplugin$/ =~ @mode then maxnum = @options['image.maxnum'] || 1 maxsize = @options['image.maxsize'] || 10000 begin date = @date.strftime( "%Y%m%d" ) images = image_list( date ) if @cgi.params['plugin_image_addimage'][0] @cgi.params['plugin_image_file'].each do |file| extension, = image_info( file ) file.rewind if extension =~ /\A(#{image_ext})\z/i begin size = file.size rescue NameError size = file.stat.size end output = "#{@image_dir}/#{date}_#{images.length}.#{extension}" File::umask( 022 ) File::open( output, "wb" ) do |f| f.print file.read end end end elsif @cgi.params['plugin_image_delimage'][0] @cgi.params['plugin_image_id'].each do |id| file = "#{@image_dir}/#{images[id.to_i]}" if File::file?( file ) && File::exist?( file ) File::delete( file ) end end end rescue @image_message = $!.to_s end end add_form_proc do |date| r = '' tabidx = 1200 images = image_list( date.strftime( '%Y%m%d' ) ) if images.length > 0 then r << %Q[<div class="form"> <div class="caption"> #{image_label_list_caption} </div> <form id="plugin-image-delimage" class="update" method="post" action="#{h @update}"><div> #{csrf_protection} <table id="image-table"> <tr>] tmp = '' images.each_with_index do |img,id| next unless img _, img_w, img_h = image_info(File.join(@image_dir,img)) r << %Q[<td><img id="image-index-#{id}" class="image-img form" src="#{h @image_url}/#{h img}" alt="#{id}" width="#{h( (img_w && img_w > 160) ? 160 : (img_w ? img_w : 160) )}"></td>] img_info = '' if img_w && img_h img_info << %Q|<span class="image-width">#{img_w}</span> x <span class="image-height">#{img_h}</span>| end tmp << %Q[<td id="image-info-#{id}"> <label><input type="checkbox" tabindex="#{tabidx+id*2}" name="plugin_image_id" value="#{id}"> #{img_info}</label> </td>] end r << "</tr><tr>" r << tmp r << %Q[</tr> </table> <input type="hidden" name="plugin_image_delimage" value="true"> <input type="hidden" name="date" value="#{date.strftime( '%Y%m%d' )}"> <input type="submit" tabindex="#{tabidx+97}" name="plugin" value="#{image_label_delete}"> </div></form> </div>] end r << %Q[<div id="plugin-image-addimage" class="form"> <div class="caption"> #{image_label_add_caption} </div>] if @image_message then r << %Q[<p class="message">#{@image_message}</p>] end r << %Q[<form class="update" method="post" enctype="multipart/form-data" action="#{h @update}"><div> #{csrf_protection} <input type="hidden" name="plugin_image_addimage" value="true"> <input type="hidden" name="date" value="#{date.strftime( '%Y%m%d' )}"> <input type="file" tabindex="#{tabidx+98}" name="plugin_image_file" size="50" multiple="multiple"> <input type="submit" tabindex="#{tabidx+99}" name="plugin" value="#{h image_label_add_image}"> </div></form> </div>] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/�������������������������������������������������������������������0000775�0000000�0000000�00000000000�13626457307�0016600�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/amazon.rb����������������������������������������������������������0000664�0000000�0000000�00000010413�13626457307�0020411�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Japanese resource of amazon plugin # # Copyright (C) 2002 HAL99 <hal99@mtj.biglobe.ne.jp> # You can redistribute it and/or modify it under GPL2 or any later version. # # # isbn_image_left: 指定したISBNの書影をclass="left"で表示 # パラメタ: # asin: ASINまたはISBN(必須) # comment: コメント(省略可) # # isbn_image_right: 指定したISBNの書影をclass="right"で表示 # パラメタ: # asin: ASINまたはISBN(必須) # comment: コメント(省略可) # # isbn_image: 指定したISBNの書影をclass="amazon"で表示 # asin: ASINまたはISBN(必須) # comment: コメント(省略可) # # isbn_detail: 指定したISBNの書籍を書影付きで詳細表示 # asin: ASINまたはISBN(必須) # # isbn: amazonにアクセスしない簡易バージョン。 # asin: ASINまたはISBN(必須) # comment: コメント(必須) # # ASINとはアマゾン独自の商品管理IDです。 # 書籍のISBNをASINに入力すると書籍が表示されます。 # # それぞれ商品画像が見つからなかった場合は # <a href="amazonのページ">商品名</a> # のように商品名を表示します。 # コメントが記述されている場合は商品名がコメントの内容に変わります。 # # tdiary.confにおける設定: # @options['amazon.aid']: アソシエイトIDを指定することで、自分のア # ソシエイトプログラムを利用できます # このオプションは設定画面から変更可能です # @options['amazon.hideconf']: 設定画面上でアソシエイトIDを入力不可能 # にしたい場合、trueに設定します # @options['amazon.imgsize']: 表示するイメージのサイズを指定します # (0:大 1:中 2:小) # @options['amazon.hidename']: class="amazon"のときに商品名を表示したく # ない場合、trueに設定します # @options['amazon.default_image_base']: デフォルトのイメージを格納した # URLを指定します。無指定時にはtDiary.org # にあるものが使われます。自作したい場合には # プラグイン集amazonディレクトリにあるPNG # ファイルを参考にして下さい # @options['amazon.nodefault']: デフォルトのイメージを表示したくない場合 # trueに設定します # # # 注意:著作権が関連する為、www.amazon.co.jpのアソシエイトプログラムを # 確認の上利用して下さい。 # @amazon_default_country = 'jp' @amazon_item_name = /^Amazon.co.jp: (.*)<.*$/ @amazon_item_image = %r|(<img src="(http://images-jp\.amazon\.com/images/P/(.*MZZZZZZZ_?.jpg))".*?>)|i @amazon_label_conf ='Amazon' @amazon_label_aid = 'AmazonアソシエイトIDの指定' @amazon_label_aid_desc = '日本のAmazonが扱う商品にのみ適用されます。他の国のアソシエイトIDを利用する場合はtdiary.confで指定して下さい。なお指定しない場合には、Amazon認証Proxyサービスの指定するIDが使われますのでご注意下さい。' @amazon_label_imgsize = '表示するイメージのサイズ' @amazon_label_large = '大きい' @amazon_label_regular = '普通' @amazon_label_small = '小さい' @amazon_label_title = 'isbn_imageプラグインで商品名を' @amazon_label_hide = '表示しない' @amazon_label_show = '表示する' @amazon_label_bitly = 'bit.lyを使って商品のURLを' @amazon_label_bitly_enabled = '短縮する' @amazon_label_bitly_disabled = '短縮しない' @amazon_label_notfound = 'イメージが見つからないときは' @amazon_label_usetitle = '商品名を表示する' @amazon_label_usedefault = 'デフォルトのイメージを使う' @amazon_label_clearcache = 'キャッシュの削除' @amazon_label_clearcache_desc = 'イメージ関連情報のキャッシュを削除する(Amazon上の表示と矛盾がある場合に試して下さい)' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/bq.rb��������������������������������������������������������������0000664�0000000�0000000�00000000245�13626457307�0017530�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/bq.rb # def bq_cite_from( cite ) "#{cite}より引用" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/calendar2.rb�������������������������������������������������������0000664�0000000�0000000�00000000430�13626457307�0020755�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# calendar2.rb language recource for Japanese @calendar2_days_format = ["日", "月", "火", "水", "木", "金", "土"] @calendar2_navi_format = ["前", "%d年<br>%d月", "次"] # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/category-legacy.rb�������������������������������������������������0000664�0000000�0000000�00000015327�13626457307�0022214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/category-legacy.rb # # Copyright (c) 2004 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # def category_title info = Category::Info.new(@cgi, @years, @conf) mode = info.mode case mode when :year period = "#{info.year}年" when :half period = (info.month.to_i == 1 ? "上半期" : "下半期") period = "#{info.year}年 #{period}" if info.year when :quarter period = "第#{info.month.to_i}四半期" period = "#{info.year}年 #{period}" if info.year when :month period = "#{info.month.to_i}月" period = "#{info.year}年 #{period}" if info.year end period = " (#{period})" if period "[#{info.category.join('|')}#{period}]" end def category_init_local @conf['category.prev_year'] ||= '<< ($1)' @conf['category.next_year'] ||= '($1) >>' @conf['category.prev_half'] ||= '<< ($1-$2)' @conf['category.next_half'] ||= '($1-$2) >>' @conf['category.prev_quarter'] ||= '<< ($1-$2)' @conf['category.next_quarter'] ||= '($1-$2) >>' @conf['category.prev_month'] ||= '<< ($1-$2)' @conf['category.next_month'] ||= '($1-$2) >>' @conf['category.this_year'] ||= '年' @conf['category.this_half'] ||= '半期' @conf['category.this_quarter'] ||= '四半期' @conf['category.this_month'] ||= '月' @conf['category.all_diary'] ||= '全期間' @conf['category.all_category'] ||= '全カテゴリ' @conf['category.all'] ||= '全期間/全カテゴリ' end category_init_local @category_conf_label = 'カテゴリ' def category_conf_html r = <<HTML <h3 class="subtitle">カテゴリインデックスの作成</h3> <p> カテゴリの機能を利用するにはカテゴリインデックスをあらかじめ作成しておく必要があります。 カテゴリインデックスを作成するには 以下のチェックを入れてからOKボタンを押してください。 </p> <p><label for="category_initialize"> <input type="checkbox" id="category_initialize" name="category_initialize" value="1">カテゴリインデックスの作成 </label></p> <p> 日記の量やサーバの性能にもよりますが、数秒から数十秒でインデックスの作成は終了します。 </p> <h3 class="subtitle">日記編集サポート</h3> <p> 日記編集画面の「本文」の下にカテゴリ名を一覧表示することができます。 カテゴリ名をクリックすると「本文」にそのカテゴリ名が挿入されます(要JavaScript)。 </p> <p> <select name="category.edit_support"> <option value="1"#{" selected" if @conf['category.edit_support'] == 1}>一覧表示</option> <option value="2"#{" selected" if @conf['category.edit_support'] == 2}>ドロップダウンリスト</option> <option value="0"#{" selected" if @conf['category.edit_support'] == 0}>表示しない</option> </select> </p> <h3 class="subtitle">表示期間の初期状態</h3> <p> カテゴリ表示画面を表示した時の、最初の表示期間を指定します。 </p> <p> <select name="category.period"> HTML [ ['月', 'month', false], ['四半期', 'quarter', true], ['半期', 'half', false], ['年', 'year', false], ['全日記', 'all', false], ].each do |text, value, default| selected = @conf["category.period"] ? @conf["category.period"] == value : default r << <<HTML <option value="#{value}"#{" selected" if selected}>#{text}</option> HTML end r << <<HTML </select> </p> <h3 class="subtitle">ヘッダ</h3> <p> 画面上部に表示する文章を指定します。 「<%= category_navi %>」で、カテゴリに特化したナビゲーションボタンを表示することができます。 また「<%= category_list%>」でカテゴリ名一覧を表示することができます。 その他,各種プラグインやHTMLを記述できます。 </p> <h4>ヘッダ1</h4> <p>ナビゲーションボタンのすぐ下に表示されます。</p> <p><textarea name="category.header1" cols="60" rows="5">#{h @conf['category.header1']}</textarea></p> <h4>ヘッダ2</h4> <p>H1のすぐ下に表示されます。</p> <p><textarea name="category.header2" cols="60" rows="5">#{h @conf['category.header2']}</textarea></p> <h3 class="subtitle">ボタンラベル</h3> <p> ナビゲーションボタンのラベルを指定します。 ラベル中の$1と$2は,それぞれ「年」「月」を表す数値で置換されます。 </p> <table border="0"> <tr><th>ボタン名</th><th>ラベル</th><th>サンプル</th></tr> HTML [ ['前年', 'category.prev_year'], ['翌年', 'category.next_year'], ['前の半年', 'category.prev_half'], ['次の半年', 'category.next_half'], ['前四半期', 'category.prev_quarter'], ['次四半期', 'category.next_quarter'], ['先月', 'category.prev_month'], ['翌月', 'category.next_month'], ['今年', 'category.this_year'], ['現半期', 'category.this_half'], ['現四半期', 'category.this_quarter'], ['今月', 'category.this_month'], ['全日記', 'category.all_diary'], ['全カテゴリ', 'category.all_category'], ['全日記/全カテゴリ', 'category.all'], ].each do |button, name| r << <<HTML <tr> <td>#{button}</td> <td><input type="text" name="#{name}" value="#{h @conf[name]}" size="30"></td> <td><p><span class="adminmenu"><a>#{h @conf[name].sub(/\$1/, "2007").sub(/\$2/, "2")}</a></span></p></td> </tr> HTML end r << <<HTML </table> HTML end @category_icon_none_label = 'アイコンなし' @category_icon_conf_label = 'カテゴリアイコン' def category_icon_conf_html r = '' unless @conf.secure r << <<HTML <h3 class="subtitle">カテゴリアイコンの置き場所</h3> <p> カテゴリアイコン用の画像が保存されているディレクトリとそのURLを指定します。 </p> <p> <dl> <dt>ディレクトリ:</dt> <dd><input name="category.icon_dir" value="#{h @category_icon_dir}" size="30"></dd> <dt>URL:</dt> <dd><input name="category.icon_url" value="#{h @category_icon_url}" size="30"></dd> </dl> </p> <hr> HTML end str = '' @categories.each do |c| str << %Q|\t<tr>\n\t\t<td>#{c}</td>\n\t\t<td>\n| str << category_icon_select(c) str << %Q|<img src="#{h @category_icon_url}#{h @category_icon[c]}">| if @category_icon[c] str << %Q|</td>\n\t</tr>\n| end r << <<HTML <h3 class="subtitle">カテゴリアイコン</h3> <p> 各カテゴリのアイコンをドロップダウンリストから選択します。 <p> <table> <tr><th>カテゴリ</th><th>アイコン</th></tr> #{str} </table> </p> <hr> <h3 class="subtitle">アイコンサンプル</h3> <p> 選択可能なアイコン一覧です. アイコンにマウスカーソルを合わせるとアイコンのファイル名がポップアップ表示されます。 </p> <p> #{category_icon_sample} </p> HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/category.rb��������������������������������������������������������0000664�0000000�0000000�00000004051�13626457307�0020742�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # ja/category.rb : tDiary plugin for show category pages # # Copyright (C) 2016 TADA Tadashi # Distributed under the GPL2 or any later version. # @category_conf_label = 'カテゴリ' def category_conf_html r = <<-HTML <h3 class="subtitle">カテゴリインデックスの作成</h3> <p> カテゴリの機能を利用するにはカテゴリインデックスをあらかじめ作成しておく必要があります。 カテゴリインデックスを作成するには 以下のチェックを入れてからOKボタンを押してください。 </p> <p><label for="category_initialize"> <input type="checkbox" id="category_initialize" name="category_initialize" value="1">カテゴリインデックスの作成 </label></p> <p> 数秒から数十秒でインデックスの作成は終了しますが、日記の量が多い場合やサーバの性能が低い場合はタイムアウトしてしまう場合があります。この場合はオフラインで作成して下さい。 </p> <h3 class="subtitle">日記編集サポート</h3> <p> 日記編集画面の「本文」の下にカテゴリ名を一覧表示することができます。 カテゴリ名をクリックすると「本文」にそのカテゴリ名が挿入されます(要JavaScript)。 </p> <p> <select name="category.edit_support"> <option value="1"#{" selected" if @conf['category.edit_support'] == 1}>一覧表示</option> <option value="2"#{" selected" if @conf['category.edit_support'] == 2}>ドロップダウンリスト</option> <option value="0"#{" selected" if @conf['category.edit_support'] == 0}>表示しない</option> </select> </p> <h3 class="subtitle">表示順</h3> <p><label for="category.show_reverse"> <input type="checkbox" id="category.show_reverse" name="category.show_reverse" value="true"#{" checked" if @conf['category.show_reverse']}>リストを新しい順に表示 </label></p> HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/daily_theme.rb�����������������������������������������������������0000664�0000000�0000000�00000000621�13626457307�0021410�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/daily_theme.rb # # Copyright (c) 2005 SHIBATA Hiroshi <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. @daily_theme_label = '日替わりテーマ' @daily_theme_label_desc = '日替わりテーマで使用するテーマ名を、1行につき1つ入力してください。' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/disp_referrer.rb���������������������������������������������������0000664�0000000�0000000�00000114657�13626457307�0021776�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = 本日のリンク元もうちょっとだけ強化プラグイン((-$Id: disp_referrer.rb,v 1.46 2008-03-02 09:01:46 kazuhiko Exp $-)) 日本語リソース == 概要 アンテナからのリンク、サーチエンジンの検索結果を、通常のリンク元の下にま とめて表示します。サーチエンジンの検索結果は、検索語毎にまとめられます。 最新の日記の表示では、通常のリンク元以外のリンク元を隠します。 == 注意 以前の版(1.1.2.39以前)からコードのほとんどを実装しなおしたため、 * 検索エンジンに関する動作が違う * 廃止されたオプションがある * オプション名が変更された という非互換があります。基本的な設定はWWWブラウザからできるようになって いますので、我慢してください。すみません。 以前の版に比べると、 * キャッシュにより表示が高速化された((-手元では、キャッシュを使わない場 合にくらべて、1日分で2/3ほど、最新3日分で1/2ほどの実時間で日記が生成 されました-))。この機能は残念ながら、レンタル日記などsecure=trueな日記 では使えません。 * リンク元置換リストにないURLを比較的簡単にWWWブラウザからリストに追加で きるようになった * 置換後の文字列の最初に[]で囲まれた文字を入れることによって、ユーザー がカテゴリーを増設できるようになった。((-tDiary本体とは違い、1つの URLは1つのカテゴリーしか持てないことにご注意ください。-)) * 基本的な設定をWWWブラウザからできるようになった * disp_referrer.rbが無くても使える * Uconvライブラリがあればあるなりに、無ければないなりに動作する という利点があります。 == 使い方 このプラグインをインストールすることで、デフォルトでは、 * 一日分の日記の表示で、「本日のリンク元」がアンテナ、検索エンジン、その 他にまとめて表示されるようになります。置換後の文字列の最後の()を除いた タイトルでグループします。また、検索エンジンからのリンクは、キーワード 別にまとめられます。 * 最新の日記の表示で、「本日のリンク元」にアンテナや検索エンジンからのリ ンクが表示されなくなります。 リンク元URLのタイトルへの置換は、tDiary本体のリンク元置換リストを使いま す。 オプションについては下記をご覧ください。基本的なオプションは、tDiaryの設 定画面から、「リンク元もうちょっと強化」をクリックすることで設定できます。 初めて設定する時には、 Insecure: can't modify hash (SecurityError) というエラーが出る可能性があります。これはtDiaryの問題です。この場合には、 tDiaryを新しくして1.5.5.20030806以降を使うか、「基本」から何も変更せず に「OK」を押すことでエラーを回避できるでしょう。 リンク元置換リストやオプションを変更した場合は、キャッシュディレクトリ にあるキャッシュファイルdisp_referrer2.cacheやdisp_referrer2.cache~をプ ラグインの設定画面から更新する必要があります。このプラグインの設定画面か ら変更した項目については、変更時にキャッシュの更新もします。 リンク元は、以下のような基準で分類されます。 : 通常のリンク元(「本日のリンク元」) リンク元置換リストにあてはまるURLのうち、下記以外のもの。 @options['disp_referrer2.unknown.divide']=falseの場合は、リンク元置換 リストにあてはまらないURLもここに含まれます。 さらに、リンク元置換リストによって置換された後の文字列の最初に[]で囲ま れた文字列がある場合は、これをカテゴリーと解釈してカテゴリー別に表示を 分けます。この機能を抑制するには、WWWブラウザから設定画面を利用するか、 tdiary.confで@options['disp_referrer2.normal.categorize']=falseにして ください。このオプションを変更した場合にはキャッシュを更新する必要があ ります。 : アンテナ URLに /a/ antenna/ antenna. などの文字列が含まれるか、置換後の文字列に、 アンテナ links などの文字列が含まれるリンク元です。これらの条件は、 @options['disp_referrer2.antenna.url']や @options['disp_referrer2.antenna.title']によって変更できます。 tdiary.confを編集してください。キャッシュを更新する必要があります。 : その他 リンク元置換リストになかったURLです。あまり長いURLは、tDiary本体の置換 リストによって通常のリンク元に分類されてしまう可能性があります。 : 検索 このプラグインに含まれる検索エンジンのリストに一致したURLです。リスト はDispRef2Setup::Enginesにあります。うまく検索エンジンと認識されない URLは、ほとんどの場合、通常のリンク元に混ざって表示されてしまうでしょ う。このような場合は、URLを ((<URL:http://tdiary-users.sourceforge.jp/cgi-bin/wiki.cgi?disp_referrer2.rb>)) に知らせていただけると作者が喜びます。 === 環境 ruby-1.6.7と1.8.0で動作を確認しています。これ以外のバージョンのRubyでも 動作するかもしれません。 tdiary-1.5.3-20030509以降で使えます。これ以前のtDiary-1.5では、 00default.rbにbot?メソッドが定義されていないため、検索エンジンのクロール に対してリンク元が表示されてしまいます。 mod_rubyでの動作は今のところ確認していません。 === インストール方法 このファイルをtDiaryのpluginディレクトリ内にコピーしてください。このプラ グインの最新版は、 ((<URL:http://zunda.freeshell.org/d/plugin/disp_referrer2.rb>)) にあるはずです。 === オプション この日記で設定できるオプションの一覧は、DispRef2Setup::Defaultsにありま す。これらのオプションのkeyの最初に、「disp_referrer2.」を追加すること で、tdiary.confの@optionsのkeyとなり、tdiary.confから設定できるようにな ります。これらのオプションのうち、DispRef2URL::Cached_optionsに挙げられ ているものは、変更の際にキャッシュの更新が必要です。 また、tDiaryの設定画面から「リンク元もうちょっと強化」を選ぶことでWWWブ ラウザから設定できる項目もあります。 == 謝辞 このプラグインは、 * UTF-8文字列のEUC文字列への変換機能 * 一部の検索エンジン名とそのURL * 検索エンジンのロボットのクローリングの際にリンク元を表示しない機能 を、MUTOH Masaoさんのdisp_referrer.rbからコピー、編集して使わせていただ いています。(検索エンジンのロボットに関する機能は現在はtDiary本体にとり こまれています。) また、URLを解釈する機能の一部を、Rubyに付属のcgi.rbからコピー、編集して 使わせていただいています。 さらに、通常のリンク元を[]で囲まれた文字列を使ってカテゴリ分けするアイデ ィアは、kazuhikoさんのものです。 皆様に感謝いたします。 == Todos * parse_as_search高速化: hostnameのキャッシュ? == 著作権について Copyright (C) 2003 zunda <zunda at freeshell.org> Please note that some methods in this plugin are written by other authors as written in the comments. Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ../ChangeLog for changes after this. * Mon Sep 29, 2003 zunda <zunda at freeshell.org> - forgot to change arguments after changing initialize() * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - name.untaint to eval name * Thu Sep 25, 2003 zunda <zunda at freeshell.org> - use to_native instead of to_euc * Mon Sep 19, 2003 zunda <zunda at freeshell.org> - disp_referrer2.rb,v 1.1.2.104 commited as disp_referrer.rb * Mon Sep 1, 2003 zunda <zunda at freeshell.org> - more strcit check for infoseek search enigne * Wed Aug 27, 2003 zunda <zunda at freeshell.org> - rd.yahoo, Searchalot, Hotbot added * Tue Aug 12, 2003 zunda <zunda at freeshell.org> - search engine list cleaned up * Mon Aug 11, 2003 zunda <zunda at freeshell.org> - instance_eval for e[2] in the search engine list * Wed Aug 7, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - キャッシュの更新をより確実にするようにしました。WWWブラウザから置換 リストを作った場合にはリストの最初に追加されます。 - secure=trueな日記でその他のリンク元リストが表示できるようになりました。 - Regexp generation for Wiki sites * Wed Aug 6, 2003 zunda <zunda at freeshell.org> - WWW browser configuration interface - 主なオプションとリンク元置換リストの効率的な編集がWWWブラウザからで きるようになりました。secure=trueな日記では一部の機能は使えません。 * Sat Aug 2, 2003 zunda <zunda at freeshell.org> - Second version - basic functions re-implemented - オプションを命名しなおしました。また不要なオプションを消しました。 tdiary.confを編集していた方は、お手数ですが設定をしなおしてください。 - Noraライブラリとキャッシュの利用で高速化しました。 - 検索エンジンのリストをプラグインで持つようになりました。&や;を含む検 索文字列も期待通りに抽出できます。 * Mon Feb 17, 2003 zunda <zunda at freeshell.org> - First version =end # Message strings Disp_referrer2_name = 'リンク元もうちょっと強化' Disp_referrer2_abstract = <<'_END' <p> アンテナからのリンク、サーチエンジンの検索結果を、 通常のリンク元の下にまとめて表示します。 サーチエンジンの検索結果は、検索語毎にまとめられます。 </p> _END Disp_referrer2_cache_info = <<'_END' <p> 現在、キャッシュの大きさは%1$sバイトです。 </p> _END Disp_referrer2_update_info = <<'_END' <p> 「<a href="%1$s">リンク元</a>」の変更の後には、 このチェックボックス −<label for="dr2.cache.update"><input id="dr2.cache.update" name="dr2.cache.update" value="force" type="checkbox">キャッシュをクリアする</label>− チェックしてからOKをクリックして、 キャッシュのクリアをしてくさい。 </p> _END Disp_referrer2_move_to_refererlist = <<'_END' その他のリンク元の置換リストの編集に<a href="%s">移る</a>。 _END Disp_referrer2_move_to_config = <<'_END' 基本的な設定に<a href="%s">移る</a>。 _END Disp_referrer2_also_todayslink = <<'_END' リンク元置換リストは「<a href="%s">リンク元</a>」からも編集できます。 _END Disp_referrer2_antenna_label = 'アンテナ' Disp_referrer2_unknown_label = 'その他のリンク元' Disp_referrer2_search_label = '検索' Disp_referrer2_search_unknown_keyword = 'キーワード不明' Disp_referrer2_cache_label = '(%sのキャッシュ)' class DispRef2SetupIF # show options def show_options r = <<-_HTML <h3>リンク元の分類と表示</h3> <table> <tr> <td><input name="dr2.current_mode" value="#{Options}" type="hidden"> リンク元置換リストにないリンク元を <td><label for="dr2.unknown.divide.true"><input id="dr2.unknown.divide.true" name="dr2.unknown.divide" value="true" type="radio"#{' checked'if @setup['unknown.divide']}>#{DispRef2String::escapeHTML(@setup['unknown.label'])}として分ける</label> <td><label for="dr2.unknown.divide.false"><input id="dr2.unknown.divide.false" name="dr2.unknown.divide" value="false" type="radio"#{' checked'if not @setup['unknown.divide']}>通常のリンク元と混ぜる</label>。 <tr> <td>#{DispRef2String::escapeHTML(@setup['unknown.label'])}を <td><label for="dr2.unknown.hide.false"><input id="dr2.unknown.hide.false" name="dr2.unknown.hide" value="false" type="radio"#{' checked'if not @setup['unknown.hide']}>表示する</label> <td><label for="dr2.unknown.hide.true"><input id="dr2.unknown.hide.true" name="dr2.unknown.hide" value="true" type="radio"#{' checked'if @setup['unknown.hide']}>隠す</label>。 <tr> <td>リンク元置換リストの置換後の文字列の最初の[]をカテゴリー分けに <td><label for="dr2.normal.categorize.true"><input id="dr2.normal.categorize.true" name="dr2.normal.categorize" value="true" type="radio"#{' checked'if @setup['normal.categorize']}>使う</label> <td><label for="dr2.normal.categorize.false"><input id="dr2.normal.categorize.false" name="dr2.normal.categorize" value="false" type="radio"#{' checked'if not @setup['normal.categorize']}>使わない</label>。 <tr> <td>一日分の表示で、通常のリンク元以外のリンク元を <td><label for="dr2.long.only_normal.false"><input id="dr2.long.only_normal.false" name="dr2.long.only_normal" value="false" type="radio"#{' checked'if not @setup['long.only_normal']}>表示する</label> <td><label for="dr2.long.only_normal.true"><input id="dr2.long.only_normal.true" name="dr2.long.only_normal" value="true" type="radio"#{' checked'if @setup['long.only_normal']}>隠す</label>。 <tr> <td>最新の表示で、通常のリンク元以外のリンク元を <td><label for="dr2.short.only_normal.false"><input id="dr2.short.only_normal.false" name="dr2.short.only_normal" value="false" type="radio"#{' checked'if not @setup['short.only_normal']}>表示する</label> <td><label for="dr2.short.only_normal.true"><input id="dr2.short.only_normal.true" name="dr2.short.only_normal" value="true" type="radio"#{' checked'if @setup['short.only_normal']}>隠す</label>。 </table> <p>最新の表示で、通常のリンク元以外のリンク元を表示する場合には、このプラグインが無い場合とまったく同じ表示になります。</p> <h3>通常のリンク元のグループ化</h3> <table> <tr> <td>通常のリンク元を <td><label for="dr2.normal.group.true"><input id="dr2.normal.group.true" name="dr2.normal.group" value="true" type="radio"#{' checked'if @setup['normal.group']}>置換後の文字列でまとめる</label> <td><label for="dr2.normal.group.false"><input id="dr2.normal.group.false" name="dr2.normal.group" value="false" type="radio"#{' checked'if not @setup['normal.group']}>URL毎に分ける</label>。 <tr> <td>通常のリンク元を置換後の文字列でまとめる場合に、最後の()を <td><label for="dr2.normal.ignore_parenthesis.true"><input id="dr2.normal.ignore_parenthesis.true" name="dr2.normal.ignore_parenthesis" value="true" type="radio"#{' checked'if @setup['normal.ignore_parenthesis']}>無視する</label> <td><label for="dr2.normal.ignore_parenthesis.false"><input id="dr2.normal.ignore_parenthesis.false" name="dr2.normal.ignore_parenthesis" value="false" type="radio"#{' checked'if not @setup['normal.ignore_parenthesis']}>無視しない</label>。 </table> <h3>アンテナからのリンクのグループ化</h3> <table> <tr> <td>アンテナからのリンクを <td><label for="dr2.antenna.group.true"><input id="dr2.antenna.group.true" name="dr2.antenna.group" value="true" type="radio"#{' checked'if @setup['antenna.group']}>置換後の文字列でまとめる</label> <td><label for="dr2.antenna.group.false"><input id="dr2.antenna.group.false" name="dr2.antenna.group" value="false" type="radio"#{' checked'if not @setup['antenna.group']}>URL毎に分ける</label>。 <tr> <td>アンテナからのリンクを置換後の文字列でまとめる場合に、最後の()を <td><label for="dr2.antenna.ignore_parenthesis.true"><input id="dr2.antenna.ignore_parenthesis.true" name="dr2.antenna.ignore_parenthesis" value="true" type="radio"#{' checked'if @setup['antenna.ignore_parenthesis']}>無視する</label> <td><label for="dr2.antenna.ignore_parenthesis.false"><input id="dr2.antenna.ignore_parenthesis.false" name="dr2.antenna.ignore_parenthesis" value="false" type="radio"#{' checked'if not @setup['antenna.ignore_parenthesis']}>無視しない</label>。 </table> <h3>検索キーワードの表示</h3> <table> <tr> <td>検索エンジン名を <td><label for="dr2.search.expand.true"><input id="dr2.search.expand.true" name="dr2.search.expand" value="true" type="radio"#{' checked'if @setup['search.expand']}>表示する</label> <td><label for="dr2.search.expand.false"><input id="dr2.search.expand.false" name="dr2.search.expand" value="false" type="radio"#{' checked'if not @setup['search.expand']}>表示しない</label>。 </table> _HTML r << <<-_HTML <h3>キャッシュ</h3> <p>キャッシュ機能は、tDiary2形式(DefaultIO)使用時は利用できません。</p> <table> <tr> <td>キャッシュを <td><label for="dr2.no_cache.false"><input id="dr2.no_cache.false" name="dr2.no_cache" value="false" type="radio"#{' checked'if not @setup['no_cache']}>利用する</label> <td><label for="dr2.no_cache.true"><input id="dr2.no_cache.true" name="dr2.no_cache" value="true" type="radio"#{' checked'if @setup['no_cache']}>利用しない</label>。 <tr> <td>キャッシュの大きさを <td colspan="3"><input name="dr2.cache_max_size" value="#{DispRef2String::escapeHTML(@setup['cache_max_size'])}" type="text">バイトまでにする。 <tr> <td>今回の設定変更で、キャッシュを <td><label for="dr2.cache.update.force"><input id="dr2.cache.update.force" name="dr2.cache.update" value="force" type="radio">クリアする</label> <td><label for="dr2.cache.update.auto"><input id="dr2.cache.update.auto" name="dr2.cache.update" value="auto" type="radio" checked>必要ならクリアする</label> <td><label for="dr2.cache.update.never"><input id="dr2.cache.update.never" name="dr2.cache.update" value="never" type="radio">クリアしない</label>。 </table> <p>キャッシュの大きさの制限は目安です。これよりも大きくなる場合もあります。キャッシュの大きさの制限を0にすると、キャッシュの大きさを制限しなくなります。最後にKやMをつけると、キロバイト、メガバイト単位になります。</p> _HTML r end # shows URL list to be added to the referer_table or no_referer def show_unknown_list urls = DispRef2Cache.new( @setup ).urls( DispRef2URL::Unknown ).keys if urls.size == 0 then urls = DispRef2Latest.new( @cgi, 'latest.rhtml', @conf, @setup ).unknown_urls end urls.reject!{ |url| DispRef2String::url_match?( url, @setup['reflist.ignore_urls'] ) } r = <<-_HTML <h3>リンク元置換リスト</h3> <input name="dr2.current_mode" value="#{RefList}" type="hidden"> <p>リンク元無視リストに一致するURLはここには表示されません。</p> <p> リンク元置換リストや記録除外リストには入れたくないURLは、 無視リストに入れておくことで、 下記のリストに現れなくなります。 無視リストは、 下記のリストにURLを表示するかどうかの判断にだけ使われます。 <label for="dr2.clear_ignore_urls"><input id="dr2.clear_ignore_urls" name="dr2.clear_ignore_urls" value="true" type="checkbox">無視リストを空にする場合はチェック</label>して下さい。 </p> _HTML if urls.size > 0 then r << <<-_HTML <p>リンク元置換リストにない下記のURLを、 リンク元置換リストに入れる場合は、 下段の空白にタイトルを入力してください。 また、リンク元記録除外リストに追加するには、 チェックボックスをチェックしてください。 </p> <p> 正規表現はリンク元置換リストに追加するのに適当なものになっています。 確認して、不具合があれば編集してください。 リンク元置換リストにだけ追加する場合には、 もう少しマッチの条件が緩いものでもかまいません。 </p> <p> 最後の空欄は、リンク元置換リストに追加する際のタイトルです。 URL中に現れた「(〜)」は、 置換文字列中で「\\1」のような「数字」で利用できます。 また、sprintf('[tdiary:%d]', $1.to_i+1) といった、 スクリプト片も利用できます。 </p> _HTML if @cgi.auth_type and @cgi.remote_user and @setup['configure.use_link'] then r << <<-_HTML <p> それぞれのURLはリンクになっていますが、これをクリックすることで、 リンク先に、この日記の更新・設定用のURLが知られることになります。 適切なアクセス制限が無い場合にはクリックしないようにしてください。 </p> _HTML end r << <<-_HTML <p> ここにないURLは「<a href="#{DispRef2String::escapeHTML(@conf.update)}?conf=referer">リンク元</a>」から修正してください。 </p> <dl> _HTML i = 0 urls.sort.each do |url| shown_url = DispRef2String::escapeHTML( @setup.to_native( DispRef2String::unescape( url ) ) ) if @cgi.auth_type and @cgi.remote_user and @setup['configure.use_link'] then r << "<dt><a href=\"#{DispRef2String::escapeHTML(url)}\">#{shown_url}</a>" else r << "<dt>#{shown_url}" end r << <<-_HTML <dd> <label for="dr2.#{i}.noref"><input id="dr2.#{i}.noref" name="dr2.#{i}.noref" value="true" type="checkbox">除外リストに追加</label> <label for="dr2.#{i}.ignore"><input id="dr2.#{i}.ignore" name="dr2.#{i}.ignore" value="true" type="checkbox">無視リストに追加</label><br> <input name="dr2.#{i}.reg" value="#{DispRef2String::escapeHTML( DispRef2String::url_regexp( url ) )}" type="text" size="70"><br> <input name="dr2.#{i}.title" value="" type="text" size="70"> _HTML i += 1 end r << <<-_HTML <input name="dr2.urls" type="hidden" value="#{i}"> </dl> _HTML else r << <<-_HTML <p>現在、#{DispRef2String::escapeHTML(@setup['unknown.label'])}はありません。</p> _HTML end r << <<-_HTML <h3>アンテナのための正規表現</h3> <p>アンテナのURLや置換後の文字列にマッチする正規表現です。 これらの正規表現にマッチするリンク元は「アンテナ」に分類されます。</p> <ul> <li>URL: <input name="dr2.antenna.url" value="#{DispRef2String::escapeHTML( @setup.to_native( @setup['antenna.url'] ) )}" type="text" size="70"> <label for="dr2.antenna.url.default"><input id="dr2.antenna.url.default" name="dr2.antenna.url.default" value="true" type="checkbox">デフォルトに戻す</label> <li>置換後の文字列:<input name="dr2.antenna.title" value="#{DispRef2String::escapeHTML( @setup.to_native( @setup['antenna.title'] ) )}" type="text" size="70"> <label for="dr2.antenna.title.default"><input id="dr2.antenna.title.default" name="dr2.antenna.title.default" value="true" type="checkbox">デフォルトに戻す</label> </ul> _HTML r end end # Hash table of search engines # key: company name # value: array of: # [0]:url regexp [1]:title [2]:keys for search keyword [3]:cache regexp # keys - an Array of Strings for usual keys # - a String as a Ruby code to be sent to URL after regexp matching # - a Symbol to indicate the key contains URL to be recursively converted DispReferrer2_Google_cache = /cache:[^:]+:([^+]+)+/ DispReferrer2_Yahoofs = /u=(.+)/ DispReferrer2_Engines = { 'google' => [ [%r{\Ahttp://(?:[^./]+\.)*google\.([^/]+)/((?:hws/|m/)?search|blogsearch|custom|ie|m)}i, '".#{$1}のGoogle検索"', ['as_q', 'q', 'as_epq'], DispReferrer2_Google_cache], [%r{\Ahttp://.*?\bgoogle\.([^/]+)/.*url}i, '".#{$1}のGoogleのURL検索?"', ['as_q', 'q'], DispReferrer2_Google_cache], [%r{\Ahttp://.*?\bgoogle/search}i, '"たぶんGoogle検索"', ['as_q', 'q'], DispReferrer2_Google_cache], [%r{\Ahttp://eval.google\.([^/]+)}i, '".#{$1}のGoogle Accounts"', [], nil], [%r{\Ahttp://(?:images|www)\.google\.([^/]+)/(?:images|imgres|imglanding)}i, '".#{$1}のGoogleイメージ検索"', ['q'], DispReferrer2_Google_cache], [%r{\Ahttp://images\.google\.([^/]+)/imgres}i, '".#{$1}のGoogleイメージ検索"', [:prev], DispReferrer2_Google_cache], [%r{\Ahttp://translate\.google\.([^/]+)/translate}i, '".#{$1}のGoogle検索"', [:prev], DispReferrer2_Google_cache], ], 'yahoo' => [ [%r{\Ahttp://[^/]+\.rd\.yahoo\.([^/]+)}i, '".#{$1}のYahooのリダイレクタ"', 'split(/\*/)[1]', nil], [%r{\Ahttp://srd\.yahoo\.co\.jp/}i, '"Yahooのリダイレクタ"', [], nil], [%r{\Ahttp://rd[^/]+\.yahoo\.com/}i, '"Yahooのリダイレクタ"', [], nil], # エンジンは inktomi 製と見た。 [%r{\Ahttp://([a-z]{2})\.search\.yahoo\.com/}i, '".#{$1}のYahoo!検索"', ['p'], DispReferrer2_Google_cache], [%r{\Ahttp://(?:[^bm/]+|blog-search)\.yahoo\.([^/]+)/}i, '".#{$1}のYahoo!検索"', ['p', 'va', 'vp'], DispReferrer2_Google_cache], [%r{\Ahttp://wrs\.search\.yahoo\.([^/]+)/(?:.*)\bK=([^/]+)}i, 'keyword=$2; "#{$1}のYahoo!検索"', [], nil], [%r{\Ahttp://(?:image-search\.yahoo\.co\.jp/(?:search|detail)|images\.search\.yahoo\.co\.jp/bin/(?:search|query))}, '".co.jpのYahoo!画像検索"', ['p'], DispReferrer2_Google_cache], [%r{\Ahttp://images\.search\.yahoo\.(:?com|co\.jp)/search/images(?:/view)?}, '".comのYahoo!画像検索"', ['p'], DispReferrer2_Google_cache], ], 'netscape' => [[%r{\Ahttp://[^/]+\.netscape\.([^/]+)/}i, '".#{$1}のNetscape検索"', ['search', 'query'], DispReferrer2_Google_cache]], 'msn' => [[%r{\Ahttp://[^/]+\.MSN\.([^/]+)/}i, '".#{$1}のMSNサーチ"', ['q', 'MT'], nil ]], 'bing' => [[%r{\Ahttp://(www|jp)\.bing\.com/}i, '"Bing検索"', ['q'], nil ]], 'auone' => [[%r{\Ahttp://search\.auone.jp/}i, '"auOne検索"', ['q'], nil ]], 'metacrawler' => [[%r{\Ahttp://[^/]+\.metacrawler.com/}i, '"MetaCrawler"', ['q'], nil ]], 'metabot' => [[%r{\Ahttp://[^/]+\.metabot\.ru/}i, '"MetaBot.ru"', ['st'], nil ]], 'altavista' => [[%r{\Ahttp://(?:[^/]+\.)?altavista\.([^/]+)/}i, '".#{$1}のAltaVista検索"', ['q'], nil ]], 'infoseek' => [ [%r{\Ahttp://(www\.)?infoseek\.co\.jp/}i, '"Infoseek"', ['qt'], nil], [%r{\Ahttp://search\d*\.www\.infoseek\.co\.jp/(?:[IO]Titles|Seek|Web)}, '"Infoseekハイブリッド検索"', ['qt'], nil], ], 'odn' => [[%r{\Ahttp://[^/]+\.odn\.ne\.jp/}i, '"ODN検索"', ['QueryString', 'key'], nil ]], 'lycos' => [[%r{\Ahttp://[^/]+\.lycos\.([^/]+)/}i, '".#{$1}のLycos"', ['query', 'q', 'qt'], nil ]], 'fresheye' => [[%r{\Ahttp://[^/]+\.fresheye}i, '"フレッシュアイ"', ['kw'], nil ]], 'goo' => [ [%r{\Ahttp://((www|ocn|dictionary|kids|eco|oshiete|(?:[^/]+\.)?search|(?:[^/]+\.)?blog|community|machi|bb|dir|channel|ocnsearch)\.)?goo\.ne\.jp/}i, '"goo"', ['MT'], nil ], [%r{\Ahttp://bsearch\.goo\.ne\.jp/(?:movie\.jsp|video/)}i, '"goo動画検索"', ['MT'], nil ], [%r{\Ahttp://bsearch\.goo\.ne\.jp/audio\.jsp}i, '"goo音楽検索"', ['MT'], nil ], [%r{\Ahttp://bsearch\.goo\.ne\.jp/(?:image|imgdt)\.jsp}i, '"goo画像検索"', ['MT'], nil ], [%r{\Ahttp://(?:[^/]+\.)?image\.goo\.ne\.jp/}i, '"goo画像検索"', ['MT'], nil ], [%r{\Ahttp://(?:[^/]+\.)?mobile\.goo\.ne\.jp/search(?:_i)?.jsp}i, '"gooケータイサイト検索"', ['MT'], nil ], [%r{\Ahttp://((www|ocn|dictionary|kids|eco|oshiete|(?:[^/]+\.)?search|community|machi|bb|dir|channel|ocnsearch)\.)?goo\.ne\.jp/}i, '"goo"', ['MT'], nil ], ], 'nifty' => [ [%r{\Ahttp://search\.nifty\.com/}i, '"@nifty/@search"', ['q', 'Text', 'text'], DispReferrer2_Google_cache], [%r{\Ahttp://srchnavi\.nifty\.com/}i, '"@niftyのリダイレクタ"', ['title'], nil ], [%r{\Ahttp://azby\.search\.nifty\.com/}i, '"AzbyClub"', ['Text'], nil ], ], 'excite' => [[%r{\Ahttp://[^/]+\.excite\.([^/]+)/}i, '".#{$1}のExcite"', ['search', 's', 'query', 'qkw'], nil ]], 'biglobe' => [ [%r{\Ahttp://(?:[^/]+\.)?search\.biglobe\.ne\.jp/}i, '"BIGLOBEサーチ"', ['q'], nil ], [%r{\Ahttp://(?:[^/]+\.)?search\.biglobe\.ne\.jp/}i, '"BIGLOBEサーチ"', [], nil ], ], 'dion' => [[%r{\Ahttp://dir\.dion\.ne\.jp/}i, '"Dion"', ['QueryString', 'key'], nil ]], 'naver' => [[%r{\Ahttp://[^/]+\.naver\.co\.jp/}i, '"NAVER Japan"', ['query'], nil ]], 'webcrawler' => [[%r{\Ahttp://[^/]+\.webcrawler\.com/}i, '"WebCrawler"', ['qkw'], nil ]], 'euroseek' => [[%r{\Ahttp://[^/]+\.euroseek\.com/}i, '"Euroseek.com"', ['string'], nil ]], 'aol' => [ [%r{\Ahttp://[^/]+\.aol\.}i, '"AOLサーチ"', ['query', 'query_contain'], nil ], [%r{\Ahttp://aolsearch\.[^/]+\.aol\.com/redir_convert\.adp}i, '"AOLサーチ"', ['query_contain'], nil] ], 'alltheweb' => [ [%r{\Ahttp://[^/]+\.alltheweb\.com/}i, '"AlltheWeb.com"', ['q'], nil ], [%r{\Ahttp://[^/]+\.alltheweb\.com/}i, '"AlltheWeb.com"', [], nil ], ], 'kobe-u' => [ [%r{\Ahttp://bach\.scitec\.kobe-u\.ac\.jp/cgi-bin/metcha\.cgi}i, '"メッチャ検索エンジン"', ['q'], nil ], [%r{\Ahttp://bach\.istc\.kobe-u\.ac\.jp/cgi-bin/metcha\.cgi}i, '"メッチャ検索エンジン"', ['q'], nil ], ], 'tocc' => [[%r{\Ahttp://www\.tocc\.co\.jp/search/}i, '"TOCC/Search"', ['QRY'], nil ]], 'yappo' => [[%r{\Ahttp://i\.yappo\.jp/}i, '"iYappo"', [], nil ]], 'suomi24' => [[%r{\Ahttp://[^/]+\.suomi24\.([^/]+)/.*query}i, '"Suomi24"', ['q'], DispReferrer2_Google_cache]], 'earthlink' => [[%r{\Ahttp://search\.earthlink\.net/search}i, '"EarthLink Search"', ['as_q', 'q', 'query'], DispReferrer2_Google_cache]], 'infobee' => [[%r{\Ahttp://infobee\.ne\.jp/}i, '"新鮮情報検索"', ['MT'], nil ]], 't-online' => [[%r{\Ahttp://brisbane\.t-online\.de/}i, '"T-Online"', ['q'], DispReferrer2_Google_cache]], 'walla' => [[%r{\Ahttp://find\.walla\.co\.il/}i, '"Walla! Channels"', ['q'], nil ]], 'mysearch' => [[%r{\Ahttp://[^/]+\.mysearch\.com/}i, '"My Search"', ['searchfor'], nil ]], 'jword' => [[%r{\Ahttp://[^/]+\.jword\.jp/}i, '"JWord"', ['name', 'q'], nil ]], 'nytimes' => [[%r{\Ahttp://query\.nytimes\.com/search}i, '"New York Times: Search"', ['as_q', 'q', 'query'], DispReferrer2_Google_cache]], 'aaacafe' => [[%r{\Ahttp://search\.aaacafe\.ne\.jp/search}i, '"AAA!CAFE"', ['key'], nil]], 'virgilio' => [[%r{\Ahttp://search\.virgilio\.it/search}i, '"VIRGILIO Ricerca"', ['qs'], nil]], 'ceek' => [[%r{\Ahttp://www\.ceek\.jp/}i, '"ceek.jp"', ['q'], nil]], 'cnn' => [[%r{\Ahttp://websearch\.cnn\.com/}i, '"CNN.com"', ['query', 'as_q', 'q', 'as_epq'], DispReferrer2_Google_cache]], 'webferret' => [[%r{\Ahttp://webferret\.search\.com/}i, '"WebFerret"', 'split(/,/)[1]', nil]], 'eniro' => [[%r{\Ahttp://www\.eniro\.se/}i, '"Eniro"', ['query', 'as_q', 'q'], DispReferrer2_Google_cache]], 'passagen' => [[%r{\Ahttp://search\.evreka\.passagen\.se/}i, '"Eniro"', ['q', 'as_q', 'query'], DispReferrer2_Google_cache]], 'redbox' => [[%r{\Ahttp://www\.redbox\.cz/}i, '"RedBox"', ['srch'], nil]], 'odin' => [[%r{\Ahttp://odin\.ingrid\.org/}i, '"ODiN検索"', ['key'], nil]], 'kensaku' => [[%r{\Ahttp://www\.kensaku\.}i, '"kensaku.jp検索"', ['key'], nil]], 'hotbot' => [[%r{\Ahttp://www\.hotbot\.}i, '"HotBot Web Search"', ['MT'], nil ]], 'searchalot' => [[%r{\Ahttp://www\.searchalot\.}i, '"Searchalot"', ['q'], nil ]], 'cometsystems' => [[%r{\Ahttp://search\.cometsystems\.com/}i, '"Comet Web Search"', ['qry'], nil ]], 'bulkfeeds' => [ [%r{\Ahttp://bulkfeeds\.net/app/search2}i, '"Bulkfeeds: RSS Directory & Search"', ['q'], nil ], [%r{\Ahttp://bulkfeeds\.net/app/similar}i, '"Bulkfeeds Similarity Search"', ['url'], nil ], ], 'answerbus' => [ [%r{\Ahttp://www\.answerbus\.com/}i, '"AnswerBus"', [], nil ], [%r{\Ahttp://answerbus\.coli\.uni-sb\.de/cgi-bin/answerbus/answer.cgi}i, '"AnswerBus"', [], nil ], ], 'dogplile' => [[%r{\Ahttp://www.\dogpile\.com/info\.dogpl/search/web/}i, '"dogpile"', [], nil ]], 'www' => [[%r{\Ahttp://www\.google/search}i, '"Google検索?"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], # TLD missing 'planet' => [[%r{\Ahttp://www\.planet\.nl/planet/}i, '"Planet-Zoekpagina"', ['googleq', 'keyword'], DispReferrer2_Google_cache]], # googleq parameter has a strange prefix 'dcn' => [[%r{\Ahttp://www\.dcn\.to/~comment/cgi-bin/commenton\.cgi}i, '"メタサーチCOMMENTON"', ['q'], nil ]], 'ask' => [ [%r{\Ahttp://ask\.jp/web.asp}i, '"ask.jp"', ['q'], nil ], [%r{\Ahttp://jp\.ask\.com}i, '"ask.com"', ['q'], nil], ], 'searchscout' => [[%r{\Ahttp://results\.searchscout\.com/search}i, '"SearchSout"', ['k'], nil ]], 'inktomi' => [[%r{\Ahttp://rdrw1.inktomi.com/click}i, '"inktomi のリダイレクタ"', [], nil]], '3721' => [[%r{\Ahttp://(?:seek|nmsearch)\.3721\.com/}i, '"3721网頁搜索"', ['p','name'], nil]], 'yisou' => [[%r{\Ahttp://www\.yisou\.com/}i, '"一搜"', ['p'], nil]], 'devilfinder' => [[%r{\Ahttp://www\.devilfinder\.com/find.php}i, '"The Devilfinder"', ['q'], nil]], 'lyricsuniverse' => [[%r{\Ahttp://www\.lyricsuniverse\.com/}, '"LYRICS Universe"', [], nil]], 'vivisimo' => [[%r{\Ahttp://[^/]+\.vivisimo\.com/search}i, '"Vivisimo"', [], nil]], 'a9' => [[%r{\Ahttp://a9\.com/}i, '"A9"', ['q'], nil]], 'nttrd' => [[%r{\Ahttp://labs\.nttrd\.com/cgi-bin/index\.cgi}, '"gooラボ"', ['q'], nil]], 'whatis' => [[%r{\Ahttp://whatis\.techtarget\.com/wsearchResults/}i, '"WhatIs.com | web search"', ['query'], nil]], 'comcast' => [[%r{\Ahttp://www\.comcast\.net/qry/websearch}i, '"COMCAST"', ['query'], nil]], 'mywebsearch' => [[%r{\Ahttp://www\.mywebsearch\.com/jsp/GGmain.jsp}i, '"My Web Search"', ['seachfor'], nil]], 'wisenut' => [[%r{\Ahttp://www\.wisenut\.com/search/query.dll}, '"WiseNut"', ['q'], nil]], 'livedoor' => [[%r{\Ahttp://(sf|www|search)\.livedoor\.}i, '"Livedoor"', ['q'], nil ]], 'tkensaku' => [[%r{\Ahttp://www\.tkensaku\.com/sclient\.cgi}i, '"TKENSAKU"', ['value'], nil]], 'yahoofs' => [[%r{\Ahttp://cache\.yahoofs\.jp/(?:search/)?cache}i, '"Yahoo! cache"', ['p', 'w'], nil]], 'googlie' => [[%r{\Ahttp://www\.googlie\.com/search}i, '"Google検索(へのリダイレクタ)"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], 'toppg' => [[%r{\Ahttp://g\.toppg\.to/search}i, '"Google検索(へのリダイレクタ)"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], 'naoya' => [[%r{\Ahttp://naoya\.dyndns\.org/feedback/app/search}i, '"FeedBack"', ['keyword'], nil]], 'blogpeople' => [[%r{\Ahttp://bst\.blogpeople\.net/search_result\.jsp}i, '"blogpeople"', ['keyword'], nil]], 'matome' => [[%r{\Ahttp://\w+\.matome\.jp/(?:keyword|tag)/(.*(?=\.html\Z)|.*\Z)}i, 'keyword=$1; "まとめ検索"', [], nil]], '210' => [[%r{\Ahttp://210\.174\.160\.70/se_root.phtml}i, '"JWord(日本語キーワード)"', ['name'], nil]], # % whois 64.233.160 # NetRange: 64.233.160.0 - 64.233.191.255 # CIDR: 64.233.160.0/19 # NetName: GOOGLE '233' => [[%r{\Ahttp://64\.233\.(?:1[6-8][0-9]|190|191)\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], # % whois 66.102.0.0 # NetRange: 66.102.0.0 - 66.102.15.255 # CIDR: 66.102.0.0/20 # NetName: GOOGLE-2 '102' => [[%r{\Ahttp://66\.102\.(?:[0-9]|1[0-5])\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], # other google candidates: # % whois 216.239.37.104 # NetRange: 216.239.32.0 - 216.239.63.255 # CIDR: 216.239.32.0/19 # NetName: GOOGLE '216' => [[%r{\Ahttp://216\.239\.(?:3[2-9]|[4-5]\d|6[0-3])\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], # % whois 72.14.203.104 # NetRange: 72.14.192.0 - 72.14.239.255 # CIDR: 72.14.192.0/19, 72.14.224.0/20 # NetName: GOOGLE '14' => [[%r{\Ahttp://72\.14\.(?:19[2-9]|2\d\d)\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], # % whois 66.249.93.104 # NetRange: 66.249.64.0 - 66.249.95.255 # CIDR: 66.249.64.0/19 # NetName: GOOGLE '249' => [[%r{\Ahttp://66\.249\.(?:6[4-9]|[7-8]\d|9[0-5])\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], 'ezweb' => [[%r{\Ahttp://ezsch\.ezweb\.ne\.jp/search/}i, '"EZweb検索"', ['query'], nil]], 'overture' => [[%r{\Ahttp://(?:\w+\.)?overture\.com/}i, '"Overture検索"', ['Keywords'], nil]], 'multimeta' => [[%r{\Ahttp://(?:\w+\.)?multimeta\.com/}i, '"Multimeta検索"', ['suchbegriff'], nil]], 'starware' => [[%r{\Ahttp://search\.starware\.com/}i, '"Starware検索"', ['qry'], nil]], 'rambler' => [[%r{\Ahttp://\w+\.rambler\.ru/}i, '"Rambler"', ['words'], nil]], 'technorati' => [ [%r{\Ahttp://www\.technorati\.jp\/search\/search\.html}i, '"テクノラティ"', ['query'], nil], [%r{\Ahttp://www\.technorati\.jp\/search\/(.*)}i, 'keyword=$1; "テクノラティ"', [], nil], ], 'pagesupli' => [ [%r{\Ahttp://www\.pagesupli\.com/cgi-bin/nph-image.exe}i, '"pageone検索"', ['q'], nil], [%r{\Ahttp://www\.pagesupli\.com/\w+/(.*)}i, 'keyword=$1; "pageone検索"', [], nil], ], 'yahoogle' => [[%r{\Ahttp://www\.yahoogle\.jp/(?:yahoogle|google|yahoo)-\d+-(.+)\.html\Z}i, 'keyword=$1; "yahoogle!"', [], nil]], # $ whois 209.85.165.104 # NetRange: 209.85.128.0 - 209.85.255.255 # CIDR: 209.85.128.0/17 # NetName: GOOGLE '85' => [[%r{\Ahttp://209\.85\.(?:12[8-9]|1[3-9]\d|2\d\d)\.\d+/}i, '"Google検索"', [:prev, 'as_q', 'q'], DispReferrer2_Google_cache]], 'chew' => [[%r{\Ahttp://blog\.chew\.jp/result/(?:.*/)?(.+)}, 'keyword=$1; "YGブログ検索"', [], nil]], 'x0' => [[%r{\Ahttp://bloger\.x0\.com/result/(?:.*/)?(.+)}, 'keyword=$1; "YGブログ検索"', [], nil]], 'wordtantei' => [[%r{\Ahttp://wordtantei\.com/result/(?:.*/)?(.+)}, 'keyword=$1; "ワード探偵"', [], nil]], 'sfa-cms' => [[%r{\Ahttp://www\.sfa-cms\.(?:com|net)/word/(?:.*/)?(.+)}, 'keyword=$1; "入れ⇔替え検索"', [], nil]], 'hatena' => [[%r{\Ahttp://search\.hatena\.ne\.jp/}i, '"はてな検索"', ['word'], nil]], 'live' => [ [%r{\Ahttp://search\.live\.com/results\.aspx}i, '"Live Search"', ['q'], nil], [%r{\Ahttp://search\.live\.com/images/results\.aspx}i, '"Live Search(画像)"', ['q'], nil], [%r{\Ahttp://search\.live\.com/news/results\.aspx}i, '"Live Search(ニュース)"', ['q'], nil], ], 'rakuten' => [[%r{\Ahttp://websearch\.rakuten\.co\.jp}i, '"楽天ウェブ検索"', ['qt'], nil]], 'luna' => [[%r{\Ahttp://(:?s|ja\.msearch)\.luna\.tv/search\.aspx}i, '"luna"', ['q'], nil]], } # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/edit_today.rb������������������������������������������������������0000664�0000000�0000000�00000001126�13626457307�0021252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resources of edit_today plugin. @edit_today_caption = 'この日を編集' def edit_today_edit_label( date ) date.strftime( '%Y-%m-%dを編集' ) end def edit_today_conf_html <<-HTML <h3 class="subtitle">リンク文字列</h3> <p>編集ページへのリンクを示す文字列を指定します。画像が用意できれば、アイコンなども指定出来ます。</p> <p><input name="edit_today_caption" size="70" value="#{h @conf['edit_today.caption']}"></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/hide-mail-field.rb�������������������������������������������������0000664�0000000�0000000�00000001476�13626457307�0022047�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resource of hide-mail-field plugin @hide_mail_field_label_conf = 'メール欄隠し' def hide_mail_field_conf_html <<-HTML <h3>ツッコミの注意文</h3> <p>ツッコミフォームの上に表示する注意文を設定します。メール欄が消えていることを読者にきちんと知らせましょう。この欄は標準spamフィルタの設定ページにあるものと同じものです。<br> <textarea name="comment_description" cols="70" rows="5">#{h comment_description}</textarea><br> 例: ツッコミ・コメントがあればどうぞ! spam対策でE-mail欄は隠してあります。もしE-mail欄が見えていても、何も入力しないで下さい。</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/highlight.rb�������������������������������������������������������0000664�0000000�0000000�00000001440�13626457307�0021073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resource of highlight.rb # def highlight_conf_label; 'ハイライト'; end def highlight_conf_html <<-HTML <h3 class="subtitle">ハイライトの色設定</h3> <p>ジャンプした先のサブタイトルを<span style="color: #{h @conf['highlight.color']}; background: #{h @conf['highlight.background']}">サンプル</span>のようにハイライトします。</p> <table> <tr> <th>ハイライトの文字色</th> <td><input name="highlight.color" value="#{h @conf['highlight.color']}"></td> </tr> <tr> <th>ハイライトの背景色</th> <td><input name="highlight.background" value="#{h @conf['highlight.background']}"></td> </tr> </table> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/makerss.rb���������������������������������������������������������0000664�0000000�0000000�00000005401�13626457307�0020572�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# makerss.rb Japanese resources def makerss_tsukkomi_label( id ) "#{id[0,4]}-#{id[4,2]}-#{id[6,2]}のツッコミ[#{id[/[1-9]\d*$/]}]" end @makerss_conf_label = 'フィード(RSS)の生成' def makerss_conf_html <<-HTML <h3>フィード(RSS)の生成</h3> <p>フィードは他のプログラムに読みやすい形で、日記の内容を公開します。フィードに含まれる情報はフィードリーダーで読まれたり、更新通知サイトに転載されたりして利用されています。</p> #{%Q[<p class="message">「#{@makerss_full.file}」に書き込めません。<br>このファイルはWebサーバによって書き込み可能でなければなりません。</p>] unless @makerss_full.writable?} <ul> <li>フィードに本文全体を<select name="makerss.hidecontent"> <option value="f"#{' selected' unless @conf['makerss.hidecontent']}>含める</option> <option value="t"#{' selected' if @conf['makerss.hidecontent']}>含めない</option></select></li> <li>フィードに含める説明を<select name="makerss.shortdesc"> <option value="f"#{' selected' unless @conf['makerss.shortdesc']}>できるだけ長くする</option> <option value="t"#{' selected' if @conf['makerss.shortdesc']}>最初だけにする</option></select></li> <li>「#{ comment_new }」というリンクを挿入<select name="makerss.comment_link"> <option value="f"#{' selected' unless @conf['makerss.comment_link']}>する</option> <option value="t"#{' selected' if @conf['makerss.comment_link']}>しない</option></select></li> </ul> <h3>ツッコミ抜きのフィード</h3> <p>標準のフィードには、あなたが書いた日記本文だけでなく、読者によるツッコミも含まれます。もしツッコミを含まないフィードも配信したいのであれば、こちらも設定してください。なお、標準のフィードが全文を含む場合にはツッコミも全文配信され、そうでない場合にはツッコミの日付と投稿者のみが配信されます。</p> #{%Q[<p class="message">「#{@makerss_no_comments.file}」に書き込めません。<br>このファイルはWebサーバによって書き込み可能でなければなりません。</p>] if @conf['makerss.no_comments'] and !@makerss_no_comments.writable?} <ul> <li>ツッコミ抜きのフィードを<select name="makerss.no_comments"> <option value="t"#{' selected' if @conf['makerss.no_comments']}>配信する</option> <option value="f"#{' selected' unless @conf['makerss.no_comments']}>配信しない</option></select></li> </ul> HTML end @makerss_edit_label = 'ちょっとした修正(フィードを更新しない)' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/my-sequel.rb�������������������������������������������������������0000664�0000000�0000000�00000003324�13626457307�0021050�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # ja/my-sequel.rb # # show links to follow-up entries # # Copyright 2006 zunda <zunda at freeshell.org> and # NISHIMURA Takashi <nt at be.to> # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work under the terms # of GPL2 or any later version. # @my_sequel_plugin_name ||= '後日談へのリンク' @my_sequel_description ||= <<_END <p>myプラグインで過去の日記に言及すると、その日記からのリンクを表示します。</p> <p>設定が登録されるのは「OK」ボタンを押してからです。デフォルトの設定に戻す時でも、「OK」ボタンを押してください。</p> _END @my_sequel_restore_default_label ||= 'デフォルトに戻す' @my_sequel_default_hash ||= { :label => { :title => 'ラベル', :default => 'つづき: ', :description => '後日談へのリンクの前に表示される文字列です。', :index => 1, }, :date_format => { :title => 'リンク文字列', :default => @date_format, :description => '後日談へのリンクの文字列の書式です。%で始まる英字は次のように変換されます: 「%Y」(西暦年)、「%m」(月数値)、「%b」(短月名)、「%B」(長月名)、「%d」(日)、「%a」(短曜日名)、「%A」(長曜日名)。', :index => 2, }, :inner_css => { :title => 'スタイル', :default => <<'_END', font-size: 75%; text-align: right; margin: 0px; _END :description => '後日談へのリンクに設定されるCSSです。div.sequelに適用されます。', :index => 3, :textarea => {rows: 5}, }, } # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/pb-show.rb���������������������������������������������������������0000664�0000000�0000000�00000002147�13626457307�0020510�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resource of pb-show.rb # def pingback_today; '本日のPingbacks'; end def pingback_total( total ); "(全#{total}件)"; end def pb_show_conf_html <<-"HTML" <h3 class="subtitle">Pingback アンカー</h3> <p>他のweblogからのPingbackの先頭に挿入される、リンク用のアンカー文字列を指定します。なお「<span class="tanchor">_</span>」を指定すると、テーマによっては自動的に画像アンカーがつくようになります。</p> <p><input name="pingback_anchor" value="#{ h(@conf['pingback_anchor'] || @conf.comment_anchor ) }" size="40"></p> <h3 class="subtitle">Pingback リスト表示数</h3> <p>最新もしくは月別表示時に表示する、Pingbackの最大件数を指定します。なお、日別表示時にはここの指定にかかわらず最大100件のPingbackが表示されます。</p> <p>最大<input name="pingback_limit" value="#{ h(@conf['pingback_limit'] || @conf.comment_limit ) }" size="3">件</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/ping.rb������������������������������������������������������������0000664�0000000�0000000�00000001056�13626457307�0020064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ping.rb Japanese resources if /conf/ =~ @mode then @ping_label_conf = '更新通知' @ping_label_list = '通知先リスト' @ping_label_list_desc = '更新通知をするpingサービスのURLを、1行につき1つ入力してください。なお、あまりたくさん指定すると、途中でタイムアウトしてしまうかも知れません' @ping_label_timeout = 'タイムアウト(秒)' end @ping_label_send = '更新情報を送る' # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/preview.rb���������������������������������������������������������0000664�0000000�0000000�00000001154�13626457307�0020607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������@preview_label_conf = '日記のプレビュー' @preview_label_interval = '更新間隔 (秒)' @preview_label_interval_desc = 'プレビューを表示する間隔を秒単位で指定します。間隔を短くするとよりリアルタイムになりますが、その分サーバーに負荷がかかります。' @preview_label_min_width = '横並びで表示する画面サイズ (px)' @preview_label_min_width_desc = 'プレビュー画面を横並びで表示する幅をピクセル単位で指定します。ここで指定した幅より画面サイズが小さい場合は縦に並べて表示します。' ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/recent_comment.rb��������������������������������������������������0000664�0000000�0000000�00000004412�13626457307�0022130�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/recent_comment.rb # # Japanese resources for recent_comment.rb # # Copyright (c) 2005 Hiroshi SHIBATA <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. # if @mode == 'conf' || @mode == 'saveconf' add_conf_proc( 'recent_comment', '最近のツッコミ', 'tsukkomi' ) do saveconf_recent_comment recent_comment_init <<-HTML <h3 class="subtitle">表示するツッコミの数</h3> <p>最大 <input name="recent_comment.max" value="#{h( @conf['recent_comment.max'] )}" size="3" /> 件</p> <h3 class="subtitle">日付フォーマット</h3> <p>使用できる\'%\'文字については<a href="http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Time#strftime">Rubyのマニュアル</a>を参照.</p> <p><input name="recent_comment.date_format" value="#{h(@conf['recent_comment.date_format'])}" size="40" /></p> <h3 class="subtitle">一覧に表示しない名前</h3> <p>リストに表示しない名前を指定します.</p> <p><input name="recent_comment.except_list" size="60" value="#{h( @conf['recent_comment.except_list'] )}" /></p> <h3 class="subtitle">生成するHTMLのテンプレート</h3> <p>各ツッコミをどのようなHTMLで表示するかを指定します.</p> <textarea name="recent_comment.format" cols="70" rows="3">#{h( @conf['recent_comment.format'] )}</textarea> <p>テンプレート中の<em>$数字</em>はそれぞれ以下の内容で置き換えられます.必要のないものは指定しなくても構いません.</p> <dl> <dt>$2</dt><dd>ツッコミのURL.</dd> <dt>$3</dt><dd>ツッコミの短縮表示</dd> <dt>$4</dt><dd>ツッコミした人の名前</dd> <dt>$5</dt><dd>ツッコミの時刻.「日付フォーマット」で指定した形式で表示されます。</dd> </dl> <h3 class="subtitle">ツッコミがないときのメッセージ</h3> <p>表示するツッコミがない場合に表示する内容を指定します.</p> <p><input name="recent_comment.notfound_msg" value="#{h(@conf['recent_comment.notfound_msg'])}" size="40" /></p> HTML end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/recent_comment3.rb�������������������������������������������������0000664�0000000�0000000�00000005745�13626457307�0022225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/recent_comment3.rb # # Japanese resources for recent_comment3.rb # # Copyright (c) 2005 SHIBATA Hiroshi <h-sbt@nifty.com> # Distributed under the GPL2 or any later version. # if @mode == 'conf' || @mode == 'saveconf' add_conf_proc( 'recent_comment3', '最近のツッコミ', 'tsukkomi' ) do saveconf_recent_comment3 recent_comment3_init checked = "t" == @conf['recent_comment3.tree'] ? ' checked' : '' <<-HTML <h3 class="subtitle">表示するツッコミの数</h3> <p>最大 <input name="recent_comment3.max" value="#{h( @conf['recent_comment3.max'] )}" size="3" /> 件</p> <h3 class="subtitle">日付フォーマット</h3> <p>使用できる\'%\'文字については<a href="http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Time#strftime">Rubyのマニュアル</a>を参照.</p> <p><input name="recent_comment3.date_format" value="#{h( @conf['recent_comment3.date_format'] )}" size="40" /></p> <h3 class="subtitle">一覧に表示しない名前</h3> <p>リストに表示しない名前を","で区切って指定します.</p> <p><input name="recent_comment3.except_list" size="60" value="#{h( @conf['recent_comment3.except_list'] )}" /></p> <h3 class="subtitle">ツリー表示機能</h3> <p><label for="recent_comment3.tree"><input id="recent_comment3.tree" name="recent_comment3.tree" type="checkbox" value="t"#{checked} />ツリー表示機能を使用する</label></p> <h3 class="subtitle">ツリー表示時のタイトルの長さ</h3> <p>ツリー表示機能を使用する時のタイトルの長さを指定します。ツリー表示機能を使用しない場合には関係ありません。</p> <p>最大 <input name="recent_comment3.titlelen" value="#{h( @conf['recent_comment3.titlelen'] )}" size="3" /> 文字</p> <h3 class="subtitle">生成するHTMLのテンプレート</h3> <p>各ツッコミをどのようなHTMLで表示するかを指定します.</p> <textarea name="recent_comment3.format" cols="70" rows="3">#{h( @conf['recent_comment3.format'] )}</textarea> <p>テンプレート中の<em>$数字</em>はそれぞれ以下の内容で置き換えられます.必要のないものは指定しなくても構いません.</p> <dl> <dt>$2</dt><dd>ツッコミのURL.</dd> <dt>$3</dt><dd>ツッコミの短縮表示</dd> <dt>$4</dt><dd>ツッコミした人の名前</dd> <dt>$5</dt><dd>ツッコミの時刻.「日付フォーマット」で指定した形式で表示されます。</dd> </dl> <h3 class="subtitle">ツッコミがないときのメッセージ</h3> <p>表示するツッコミがない場合に表示する内容を指定します.</p> <p><input name="recent_comment.notfound_msg" value="#{h(@conf['recent_comment.notfound_msg'])}" size="40" /></p> HTML end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������tdiary-core-5.1.1/misc/plugin/ja/recent_rss.rb������������������������������������������������������0000664�0000000�0000000�00000001336�13626457307�0021277�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- indent-tabs-mode: t -*- # # Copyright (c) 2003-2005 Kouhei Sutou <kou@cozmixng.org> # Distributed under the GPL2 or any later version. # def label_recent_rss_title '外部RSSの表示' end def label_recent_rss_use_image_link_title '画像の扱い' end def label_recent_rss_use_image_link_description 'もしRSSにWebサイトの画像情報が含まれていたら,' + 'Webサイトへのリンクにテキストではなくその画像を用います.' end def label_recent_rss_not_use_image_link 'リンクに画像を用いない' end def label_recent_rss_use_image_link 'リンクに画像を用いる' end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/referer_scheme.rb��������������������������������������������������0000664�0000000�0000000�00000006004�13626457307�0022103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = Meta-scheme plugin((-$Id: referer_scheme.rb,v 1.9 2008-03-02 09:01:46 kazuhiko Exp $-)) 本日のリンク元置換リストの記述を楽にします。 == 利用方法 このプラグインを、プラグインのディレクトリに入れるかプラグイン選択プラグ インから有効にしてください。 次に、設定、リンク元から、リンク元置換リストを編集して、tdiary:や hatena:というプレフィックス(メタ・スキームと呼ぶことにします)をURLの前に 付けてください。 これにより、日付を置換するルールを書かないでも、置換後の文字列に自動的に 日付などを挿入することができます。 例えば、次のような記述をしてください。 * tdiary:http://tdiary.tdiary.net/ tDiary.net運営日誌 * tdiarynet:foo((-http://foo.tdiary.net/に展開されます-)) fooさんの日記 * hatena:bar((-http://d.hatena.ne.jp/bar/に展開されます-)) barさんの日記 この例では、URLに日付が含まれれば、(YYYY-MM-DD)という形式で追加します。 == 注意 tdiary:で始まるURLは、 * 括弧を使わないでください。 * /で終わらせてください。 tdiarynet:やhatena:で始まるURLは、 * 括弧を使わないでください。 * URLとしてはユーザーIDだけを指定してください。 == メタ・スキームの作り方 リンク元置換リストのURLの正規表現の文字列に対して、/^(\w+):/という正規表 現で一致する文字列がメタ・スキームとして検出されます。 def scheme_スキーム名( url, name ) : yield( url_variants, name_variants ) : end という@conf.referer_tableの特異メソッドをイテレータとして定義しておけば、 置換リストの記述に応じてこのメソッドが呼ばれます。urlには 「メタ・スキーム名:」を除いた正規表現が渡されることに注意してください。 == Copyright Copyright (C) 2003 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end unless @conf.referer_table.respond_to?( 'scheme_tdiarynet', true ) then class << @conf.referer_table private TdiaryNet = '\.tdiary\.net/' def scheme_tdiarynet( url, name ) TdiaryDates.each do |a| yield( "http://#{url}#{TdiaryNet}#{a[0]}", name + a[1] ) end yield( "http://#{url}#{TdiaryNet}.*", name ) end end end unless @conf.referer_table.respond_to?( 'scheme_hatena', true ) then class << @conf.referer_table HatenaHost = 'http://d(?:iary)?\.hatena\.ne\.jp/' def scheme_hatena( url, name ) [ ['(\d{4})(\d{2})(\d{2}).*', '(\1-\2-\3)'], ['(\d{4})(\d{2}).*', '(\1-\2)'], ].each do |a| yield( "#{HatenaHost}#{url}/#{a[0]}", name + a[1] ) end yield( "#{HatenaHost}#{url}/.*", name ) end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/search_control.rb��������������������������������������������������0000664�0000000�0000000�00000005104�13626457307�0022132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = ここだけ検索プラグイン((-$Id: search_control.rb,v 1.4 2008-03-02 09:01:46 kazuhiko Exp $-)) 日本語リソース == 概要 一日表示、最新表示などそれぞれについてGoogleなどの検索エンジンにインデッ クスしてもらうかどうかを制御します。 == 使い方 このプラグインをplugin/ディレクトリに配置するか、プラグイン選択プラグイ ンを使ってこのプラグインを有効にしてください。 設定画面から「ここだけ検索」をクリックすることで、どの表示モードでどのよ うな動作を期待するか設定することができます。デフォルトでは、一日分の表示 のみ、検索エンジンに登録されるようになっています。 実際に効果があるかどうかは、検索エンジンのロボットがメタタグを解釈して くれるかどうかにかかっています。 == License Copyright (C) 2003, 2004 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ../ChangeLog for changes after this. * Aug 28, 2003 zunda <zunda at freeshell.org> - 1.3 - simpler configuration display * Aug 26, 2003 zunda <zunda at freeshell.org> - 1.2 - no table in configuration view, thanks to Tada-san. * Aug 26, 2003 zunda <zunda at freeshell.org> - no nofollow - English translation =end ChangeLog # configuration unless defined?( Search_control_plugin_name ) then Search_control_plugin_name = 'ここだけ検索' Search_control_description_html = <<'_HTML' <p>メタタグを使って、検索エンジンのロボットに、 余分なページのインデックスを作らないようにお願いしてみます。 インデックスを作って欲しい表示だけにチェックをしてください。</p> <p>User agent(検索エンジンのロボットの名前)が指定されていると、 そのagentについて指定された動作をします。 一致するUser agentが無い場合はデフォルトの動作をします。</p> _HTML Search_control_delete_label = 'このagentを削除' Search_control_new_label = '記入したagentを追加' Search_control_default_label = 'デフォルト' Search_control_categories = [ [ '最新', 'latest' ], [ '一日分', 'day' ], [ '一月分', 'month' ], [ '長年', 'nyear' ], [ 'カテゴリー', 'category' ] ] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/search_form.rb�����������������������������������������������������0000664�0000000�0000000�00000002323�13626457307�0021415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# search_form.rb japanese resource. def googlej_form( button_name = "Google 検索", size = 20, default_text = "" ) first = %Q[<a href="https://www.google.com/"> <img src="https://www.google.com/logos/Logo_40wht.gif" style="border-width: 0px; vertical-align: middle;" alt="Google"></a>] last = %Q[<input type="hidden" name="hl" value="ja"><input type="hidden" name="ie" value="utf-8">] search_form( "https://www.google.com/search", "q", button_name, size, default_text, first, last ) end def google_form( button_name = "Google 検索", size = 20, default_text = "" ) googlej_form( button_name, size, default_text ) end def yahooj_form( button_name = "Yahoo! 検索", size = 20, default_text = "" ) first = %Q[<a href="https://www.yahoo.co.jp/"> <img src="http://img.yahoo.co.jp/images/yahoojp_sm.gif" style="border-width: 0px; vertical-align: middle;" alt="Yahoo! JAPAN"></a>] search_form( "https://search.yahoo.co.jp/bin/search", "p", button_name, size, default_text, first, "" ) end def yahoo_form( button_name = "Yahoo! 検索", size = 20, default_text = "" ) yahooj_form( button_name, size, default_text ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/tb-show.rb���������������������������������������������������������0000664�0000000�0000000�00000003665�13626457307�0020522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese resource of tb-show.rb # def tb_show_conf_html <<-"HTML" <h3 class="subtitle">TrackBack アンカー</h3> <p>他のweblogからのTrackBackの先頭に挿入される、リンク用のアンカー文字列を指定します。なお「<span class="tanchor">_</span>」を指定すると、テーマによっては自動的に画像アンカーがつくようになります。</p> <p><input name="trackback_anchor" value="#{ h(@conf['trackback_anchor'] || @conf.comment_anchor ) }" size="40"></p> <h3 class="subtitle">TrackBack 表示方法</h3> <p>最新もしくは月別時の表示方法を指定します。</p> <p><select name="trackback_shortview_mode"> #{ [["num_in_reflist", "リンク元一欄に数を表示(常に)"], ["num_in_reflist_if_exists", "リンク元一欄に数を表示(1件以上のみ)"], ["shortlist", "短い一覧を表示"] ].map{ |op| "<option value='#{op[0]}' #{'selected' if @conf['trackback_shortview_mode'] == op[0]}>#{op[1]}</option>\n" }.to_s } </select></p> <h3 class="subtitle">TrackBack リスト表示数</h3> <p>最新もしくは月別表示時に表示する、TrackBackの最大件数を指定します。なお、日別表示時にはここの指定にかかわらず最大100件のTrackBackが表示されます。</p> <p>最大<input name="trackback_limit" value="#{ h( @conf['trackback_limit'] || @conf.comment_limit )}" size="3">件</p> <h3 class="subtitle">TrackBack URL の表示設定</h3> <p>最新もしくは月別表示時に TrackBackURL を表示するかどうかを指定します。</p> <p><select name="trackback_disp_pingurl"> <option value="true" #{'selected' if @conf['trackback_disp_pingurl']}>表示</options> <option value="false" #{'selected' if !@conf['trackback_disp_pingurl']}>非表示</options> </select></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/todo.rb������������������������������������������������������������0000664�0000000�0000000�00000004065�13626457307�0020077�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ja/todo.rb # # Japanese resources for todo.rb # # Copyright (c) 2001,2002,2003 Junichiro KITA <kita@kitaj.no-ip.com> # Distributed under the GPL2 or any later version. # def todo_msg_today; "今日"; end def todo_msg_in_time(days); "あと#{days}日"; end def todo_msg_late(days); "#{days}日遅れ"; end def todo_config_label; "ToDo編集"; end add_conf_proc('ToDo', 'ToDoプラグイン') do saveconf_todo todo_init <<-HTML <h3 class="subtitle">使い方</h3> <p><a href="#{h @update}?conf=header">ヘッダ・フッタ</a>に'<%=todo%>'を追加して下さい.</p> <h3 class="subtitle">ToDo編集</h3> <p>一行に一つずつToDoを記述します.ToDoの形式は</p> <pre>優先度[期限] すること</pre> <p>です.「優先度」と「すること」の間は1つ以上のスペースで区切ります.</p> <p>優先度は省略可能です。優先度を指定する場合は1〜99の整数を指定します.それ以外の優先度を指定した場合,そのToDoは無視されます.</p> <p>期限は省略可能です.期限を指定する場合は'['と']'で囲むようにしてください.期限で指定した文字列をrubyの<a href="http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=ParseDate">ParseDateモジュール</a>で解析できれば,期限までの日数もあわせて表示します.</p> <p><textarea name="todo.todos" cols="70" rows="15">#{@todos.join("\n")}</textarea></p> <h3 class="subtitle">ToDoリストのタイトル</h3> <p>ToDoリストのタイトルを指定します。何も指定しないと、"ToDo:"が利用されます。</p> <p><input name="todo.title" value="#{h(@conf['todo.title']) if @conf['todo.title']}"></p> <h3 class="subtitle">表示するToDoの件数</h3> <p>表示するToDoの件数を表示します。何も指定しないと、10件が設定されます。</p> <p>最大<input name="todo.n" value="#{h @conf['todo.n']}" size="3">件</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/weather.rb���������������������������������������������������������0000664�0000000�0000000�00000046330�13626457307�0020572�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=begin = その日の天気プラグイン((-$Id: weather.rb,v 1.13 2008-03-02 09:01:46 kazuhiko Exp $-)) その日の天気を、その日の日記を最初に更新する時に取得して保存し、それぞれ の日の日記の上部に表示します。 == 入手方法 このファイルの最新版は、 ((<URL:http://zunda.freeshell.org/d/plugin/weather.rb>)) にあります。 == 使い方 === インストールと設定の方法 このファイルをpluginディレクトリにコピーしてください。漢字コードは EUC-JPです。 次に、tdiary.confを編集するか、WWWブラウザからtDiaryの設定画面から「その 日の天気」を選んで、天気データをいただいてくるURLを設定してください。 tdiary.confを編集する場合には、@options['weather.url']に設定してくださ い。両方で設定をした場合には、tDiaryの設定画面での設定が優先されます。 例えば、 NOAA National Weather Serviceを利用する場合には、 ((<URL:http://weather.noaa.gov/>))から、Select a country...で国名を選ん でGo!ボタンを押し、次に観測地点を選んでください。その時表示されたページ のURLを、例えば、 @options['weather.url'] = 'http://weather.noaa.gov/weather/current/RJTI.html' と書いてください。この例では東京ヘリポート((-どこにあるんだろ?-))の天気 が記録されます。情報の二次利用が制限されている場合がありますので、そのよ うなWWWページから情報を取得しないように注意してください。 さらに、将来日記のタイムゾーンが変化する可能性がある方は、今のタイムゾー ンを、@options['weather.tz']か、環境変数TZに設定しておくことをお勧めし ます。これによって、日記が引越した後も、天気データ取得時のタイムゾーン で天気を表示し続けることができます。tdiary.confに設定する場合は、例えば 日本標準時の場合は、 @options['weather.tz'] = 'Japan' と設定してください。 これで、新しい日の日記を書く度に、設定したURLから天候データを取得して、 表示するようになるはずです。天気は、 <div class="weather"><span class="weather">hh:mm現在<a href="取得元URL">天気(温度)</a></span></div> という形式でそれぞれの日の日記の上に表示されます。必要ならば、CSSを編集 してください。 div.weather { text-align: right; font-size: 75%; } などとしておけばいいでしょう。 日記に使用しているWWWサーバーからサーバーの権限でWWWページの閲覧ができる 必要があります。mod_rubyでの動作は今のところ確認していません。 デフォルトでは、携帯端末から閲覧された場合には天気を表示しないようになっ ています。携帯からでも天気を表示したい場合には、設定画面から設定するか、 tdiary.confに @options['weather.show_mobile'] = true を指定してください。 === 保存される天気データについて 天気データは、 * 書いてる日記の日付と現在の日付が一致し、 * その日の天気データがまだ取得されていないか、前回の取得時にエラーがあった 場合に、取得されます。 天気データは、@options['weather.dir']に設定したディレクトリか、 @cache_path/weather/ ディレクトリ以下に、年/年月.weather というファイ ル 名で保存されます。タブ区切りのテキストファイルですので必要に応じて編集 することができます。タブの数を変えてしまわないように気をつけて編集してく ださい。フォーマットの詳細は、Weather.to_sメソッドを参照してください。 天気データには、データの取得時刻が記録されています。また、データの取得元 から得られた、天気の更新時刻が記録されていることもあります。これらの時刻 は、世界標準時(UNIX時刻)に直されて記録されていて、日記に表示する時に現地 時刻に直しています。このため、天気を記録した時のタイムゾーンと、天気を表 示する時のタイムゾーンが異なってしまうと、例えば朝の天気だったものが夕方 の天気として表示されてしまうことになります。これを防ぐには、例えば、 @options['weather.tz'] = 'Japan' というオプションを設定して、データにタイムゾーンを記録するようにしてくだ さい。tdiary.confなどで、 ENV['TZ'] = 'Japan' などとして環境変数TZを設定することでも同様の効果が得られます。環境変数を 設定した場合は、tDiary全体の動作に影響がありますので留意してください。 なお、1.1.2.19かそれ以前のバージョンのweather.rbではタイムゾーンの情報が 天気データに記録されていません。お手数ですが、必要ならば、ファイルを編集 して、タイムゾーン情報を追加してください。記録ファイルは、デフォルトでは、 .../cache/weather/2003/200301.weather などにあります。取得元URLの次の数字がUNIX時刻ですので、それに続けて、空 白を一つと、Japanなどタイムゾーンを示す文字列を入力してください。データ 取得時にエラーがなければ、その後2つのタブに続いて、天気のデータが記録さ れているはずです。 === オプション ==== 必ず指定が必要な項目 : @options['weather.url'] 天気データを得られるWWWページのURL。 @options['weather.url'] = 'http://weather.noaa.gov/weather/current/RJTI.html' など。情報の二次利用が制限されている場合がありますので、そのようなWWW ページから情報を取得しないように注意してください。ブラウザから設定した 場合はそちらが優先されます。 ==== 指定しなくてもいい項目 : @options['weather.show_mobile'] = false trueの場合は、携帯端末からのアクセスの場合に、i_html_stringで生成され たCHTMLを表示します。falseの場合は、携帯端末からのアクセスの場合には天 気を表示しません。ブラウザから設定した場合はそちらが優先されます。 : @options['weather.tz'] データを取得した場所のタイムゾーン。コマンドライン上で例えば、 TZ=Japan date を実行して正しい時刻が表示される文字列を設定してください。Linuxでは、 /usr/share/zoneinfo以下のファイル名を指定すればいいはずです。ブラウザ から設定した場合はそちらが優先されます。このオプションが指定されてい ない場合、環境変数TZが設定されていればその値を使用します。そうでなけ ればタイムゾーンは記録しません。 天気データにタイムゾーンが記録されていない場合は、もし将来日記のタイム ゾーンが変更された場合に違う時刻を表示することになります。 日付の判定など、天気データの記録以外の時刻の管理には、日記全体のタイム ゾーンが用いられます。 : @options['weather.oldest'] = 21600 得られたデータが、このオプション(秒)より古い場合には、天気の取得エラー になり、次の日記の更新で再びデータを取得しようとします。デフォルトは6 時間(21600秒)です。このオプションがnilに設定されている場合には、どんな に古いデータでも受け入れます。 : @options['weather.show_error'] データ取得時にエラーがあった場合にそれを日記に表示したい場合にはtrueに します。デフォルトでは表示しません。 : @options['weather.dir'] データの保存場所。デフォルトは以下の通り。 "#{@cache_path}/weather/" この下に、年/年月.weather というファイルが作られます。これを、 @data_pathと同じにすると、日記のデータと同じディレクトリに天気のデータ を保存できるかもしれません。 : @options['weather.items'] WWWページから取得する項目。デフォルトは、ソースをご覧ください。 parse_htmlで得られる項目名をキー、記録する項目名を値としたハッシュです。 www.nws.noaa.govのフォーマットに合わせて、多少の単位の変動には耐えられ るようにしてあります。これを変更する場合には、parse_htmlメソッドも編 集する必要があるかもしれません。 : @options['weather.header'] HTTPリクエストヘッダに追加する項目のハッシュ @options['weather.header'] = {'Accept-language' => 'ja'} など。((-Accept-languageによって取得する言語を選べるサイトもあります。-)) デフォルトでは追加のヘッダは送信しません。 == 天候の翻訳について NWSからのデータは英語ですので、適当に日本語に直してから出力するようにし てあります。翻訳は、WeatherTranslatorモジュールによっていて、変換表は、 Weatherクラスに、Words_jaという配列定数として与えてあります。 語彙はまだまだ充分ではないと思います。知らない単語は英語のまま表示されま すので、Words_jaに適宜追加してください。 ((<URL:http://tdiary-users.sourceforge.jp/cgi-bin/wiki.cgi?weather%2Erb>)) に書いておくと、そのうち配布元で追加されるかもしれません。 == 細かい設定 天気データ取得元や好みに合わて、以下のメソッドを変更することで、より柔 軟な設定ができます。 === 表示に関するもの : Weather.html_string @data[item]を参照して、天気を表示するHTML断片を作ってください。 : Weather.error_html_string データ取得エラーがあった場合に、@errorを参照してエラーを表示するHTML断 片を作ってください。 携帯端末からの閲覧の際には、Weather.i_html_stringが使われます。エラーの 表示はできません。 === 天気データの取得に関するもの : Weather.parse_html( html, items ) ((|html|))文字列を解析して、((|items|))ハッシュに従って@data[item]を定 義してください。((|items|))には@optins['weather.items']または Weather_default_itemsが代入されます。返り値は利用されません。テーブル を用いた天気情報源ならば、このメソッドをあまり改造しないで使えるかも しれません。 == まだやるべきこと * 天気に応じたアイコンの表示 -どうやろうか? == 謝辞 その日の天気プラグインのアイディアを提供してくださったhsbtさん、実装のヒ ントを提供してくださったzoeさんに感謝します。また、NOAAの情報を提供して くださったkotakさんに感謝します。 The author appreciates National Weather Service ((<URL:http://weather.noaa.gov/>)) making such valuable data available in public domain as described in ((<URL:http://www.noaa.gov/wx.html>)). == Copyright Copyright 2003 zunda <zunda at freeshell.org> Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin == Instance variables =end @weather_plugin_name = 'その日の天気' =begin == Classes and methods === WeatherTranslator module We want Japanese displayed in a diary written in Japanese. --- Weather::Words_ja Array of arrays of a Regexp and a Statement to be executed. WeatherTranslator::S.tr accepts this kind of hash to translate a given string. =end require 'erb' class Weather Words_ja = [ [%r[\A(.*)/(.*)], '"#{S.new( $1 ).translate( table )}/#{S.new( $2 ).translate( table )}"'], [%r[\s*\b(greater|more) than (-?[\d.]+\s*\S*)\s*]i, '"#{S.new( $2 ).translate( table )}以上"'], [%r[^(.*?) with (.*)$]i, '"#{S.new( $2 ).translate( table )}ありの#{S.new( $1 ).translate( table )}"'], [%r[^(.*?) during the past hours?$]i, '"直前まで#{S.new( $1 ).translate( table )}"'], #[%r[\s*\b([\w\s]+?) in the vicinity]i, '"近辺で#{S.new( $1).translate( table )}"'], [%r[\s*\bin the vicinity\b\s*]i, '""'], # ... in the vicinityは無視されるようになっています。訳語が欲しい方は、 # 上のコメントアウトされている行のコメントを外してください。 [%r[\s*\bpatches of\b\s*]i, '""'], [%r[\s*\bdirection variable\b\s*]i, '"不定"'], [%r[\s*(-?[\d.]+)\s*\(?F\)?], '"華氏#{$1}度"'], [%r[\s*\bmile(\(?s\)?)?\s*]i, '"マイル"'], [%r[\s*\b(mostly |partly )clear\b\s*]i, '"晴"'], [%r[\s*\bclear\b\s*]i, '"快晴"'], [%r[\s*\b(mostly |partly )?cloudy\b\s*]i, '"曇"'], [%r[\s*\bbroken clouds\b\s*]i, '"曇"'], [%r[\s*\bfew clouds\b\s*]i, '"晴"'], [%r[\s*\bovercast( cloud deck)?\b\s*]i, '"曇"'], [%r[\s*\blight snow showers?\b\s*]i, '"にわか雪"'], [%r[\s*\blight snow\b\s*]i, '"小雪"'], [%r[\s*\blight drizzle\b\s*]i, '"小雨"'], [%r[\s*\blight rain showers?\b\s*]i, '"弱いにわか雨"'], [%r[\s*\bheavy rain showers?\b\s*]i, '"強いにわか雨"'], [%r[\s*\bheavy rain\b\s*]i, '"豪雨"'], [%r[\s*\b(rain )?showers?\b\s*]i, '"にわか雨"'], [%r[\s*\bdrizzle\b\s*]i, '"こぬか雨"'], [%r[\s*\blight rain\b\s*]i, '"霧雨"'], [%r[\s*\brain\b\s*]i, '"雨"'], [%r[\s*\bmist\b\s*]i, '"靄"'], [%r[\s*\bhaze\b\s*]i, '"霞"'], [%r[\s*\b(partial )?(freezing )?fog\b\s*]i, '"霧"'], [%r[\s*\bsnow\b\s*]i, '"雪"'], [%r[\s*\bthunder( storm)?\b\s*]i, '"雷"'], [%r[\s*\blightning\b\s*]i, '"稲光"'], [%r[\s*\bsand\b\s*]i, '"黄砂"'], [%r[\s*\bcumulonimbus clouds\b\s*]i, '"積乱雲"'], [%r[\s*\bscattered clouds\b\s*]i, '"ちぎれ雲"'], [%r[\s*\bcumulus clouds\b\s*]i, '"積雲"'], [%r[\Aunknown\z]i, '""'], [%r[\s*\btowering\b\s*]i, '""'], [%r[\s*\bobserved\b\s*]i, '""'], [%r[\s*\bC\b\s*], '"℃"'], ].freeze end =begin === Weather class Weather of a date. --- Weather.html_string --- Weather.error_html_string Returns an HTML fragment showing data or error, called from Weather.to_html. --- Weather.i_html_string Returns a CHTML fragment to be shown on a mobile browser. =end class Weather include ERB::Util def error_html_string %Q|<span class="weather">お天気エラー:<a href="#{h(@url)}">#{h( @error )}</a></span>| end # edit this method to define how you show the weather def html_string has_data = false r = '<span class="weather">' # time stamp if @tz then tzbak = ENV['TZ'] ENV['TZ'] = @tz # this is not thread safe... end if @data['timestamp'] then r << Time::at( @data['timestamp'].to_i ).strftime( '%H:%M' ).sub( /^0/, '' ) else r << Time::at( @time.to_i ).strftime( '%H:%M' ).sub( /^0/, '' ) end r << '現在' if @tz then ENV['TZ'] = tzbak end # weather r << %Q|<a href="#{h(@url)}">| if @data['weather'] then r << %Q|<span class="weather">#{h( WeatherTranslator::S.new( @data['weather']).translate( Words_ja ).compact )}</span>| has_data = true elsif @data['condition'] then r << %Q|<span class="condition">#{h( WeatherTranslator::S.new( @data['condition']).translate( Words_ja ).compact )}</span>| has_data = true end # temperature if @data['temperature(C)'] and t = @data['temperature(C)'].scan(/-?[\d.]+/)[-1] then r << %Q| <span class="temperature">#{sprintf( '%.0f', t )}℃</span>| has_data = true end r << "</a></span>" return has_data ? r : '' end # edit this method to define how you show the weather for a mobile agent def i_html_string r = '' # weather if @data['weather'] then r << %Q|<A HREF="#{u(@url)}">| r << h( WeatherTranslator::S.new( @data['weather']).translate( Words_ja ).compact ) r << "</A>" elsif @data['condition'] then r << %Q|<A HREF="#{u(@url)}">| r << h( WeatherTranslator::S.new( @data['condition']).translate( Words_ja ).compact ) r << "</A>" end return r end end # www configuration interface def weather_configure_html( conf ) station = Weather::extract_station_id(conf['weather.url']) station ||= conf['weather.url'] <<-HTML <h3 class="subtitle">その日の天気プラグイン</h3> <p>その日の天気を、その日の日記を最初に更新する時に取得して保存し、 それぞれの日の日記の上部に表示します。</p> <h4>天気データ</h4> <p>その日の天気を、例えばNOAA National Weather Serviceを利用する場合には、 <a href="http://weather.noaa.gov/">NOAA National Weather Service</a> から、Select a country...で国名を選んでGo!ボタンを押し、 次に観測地点を選んでください。 そして、その時表示されたページのURL (例えば東京ヘリポートの場合は<tt>http://weather.noaa.gov/weather/current/RJTI.html</tt>となります) を、以下に記入してください。 大文字4文字のStation IDでもかまいません。</p> <p><input name="weather.url" value="#{station}" size="50"></p> <p>将来日記のタイムゾーンが変化する可能性がある方は、 今のタイムゾーンを記録しておくことをお勧めします。 これによって、日記が引越した後も、 天気データ取得時のタイムゾーンで天気を表示し続けることができます。</p> <p>タイムゾーンを記録するには、例えば日本標準時の場合には、 tdiary.rbと同じディレクトリにあるtdiary.confに、 ENV['TZ'] = 'Japan'などと書き足すか、 以下に、Japanと記入してください。</p> <p><input name="weather.tz" value="#{conf['weather.tz']}"></p> <h4>WWWブラウザへの表示</h4> <p>下記から選んでください。</p> <p><select name="weather.in_title"> <option value="false"#{' selected'unless conf['weather.in_title']}> 本文の上に表示する <option value="true"#{' selected'if conf['weather.in_title']}> タイトルの横に表示する </select></p> <h4>携帯電話への表示</h4> <p>下記から選んでください。</p> <p><select name="weather.show_mobile"> <option value="true"#{' selected'if conf['weather.show_mobile']}> 携帯電話にも今日の天気を表示する <option value="false"#{' selected'unless conf['weather.show_mobile']}> 携帯電話には今日の天気を表示しない </select></p> <h4>検索エンジンなどのロボットへの表示</h4> <p>下記から選んでください。</p> <p><select name="weather.show_robot"> <option value="true"#{' selected'if conf['weather.show_robot']}> 検索エンジンなどのロボットにも今日の天気を知らせる <option value="false"#{' selected'unless conf['weather.show_robot']}> 検索エンジンなどのロボットには今日の天気を知らせない </select></p> <h4>その他の設定</h4> <p>この他にもいくつかtdiary.confから設定できる項目があります。 詳しくは、プラグインのファイル(weather.rb)をご覧ください。</p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/ja/xmlrpc.rb����������������������������������������������������������0000664�0000000�0000000�00000000634�13626457307�0020435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def label_xmlrpc_url; 'XML-RPC API 設置先URL'; end def label_xmlrpc_blogid; 'Blog ID'; end def label_xmlrpc_username; 'ユーザ名'; end def label_xmlrpc_password; 'パスワード'; end def label_xmlrpc_lastname; '名'; end def label_xmlrpc_firstname; '姓'; end def label_xmlrpc_userid; 'ユーザID'; end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/kw.rb�����������������������������������������������������������������0000664�0000000�0000000�00000007523�13626457307�0017163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# kw.rb # # kw: keyword link generator # Parameters: # keyword: keyword or InterWikiName (separated by ':'). # name: anchor string (optional). # title: title attribute (optional). # # @options['kw.dic'] # array of dictionary table array. an item of array is: # # [key, URL, style] # # key: nil or string of key. # If keyword is 'foo', it has key nil. # If keyword is 'google:foo', it has key 'google'. # URL: the URL for link. '$1' is replace by keyword. # style: encoding style as: 'euc-jp', 'sjis', 'jis', 'utf-8' or nil. # # if there isn't @options['kw.dic'], the plugin links to google. # # @options['kw.show_inter'] # Show InterWikiName. # If this options is true, the keyword 'google:foo' shows 'google:foo'. # But it is false, that shows only 'foo'. # The default of this option is true. # # Copyright (C) 2003, TADA Tadashi <sho@spc.gr.jp> # You can distribute this under GPL2 or any later version. # unless String.method_defined?(:encode) require 'nkf' end def kw_parse( str ) kw_list = [] str.each_line do |pair| k, u, s = pair.sub( /[\r\n]+/, '' ).split( /[ \t]+/, 3 ) k = nil if k == '' or k == 'nil' s = nil if s != 'euc-jp' && s != 'sjis' && s != 'jis' && s != 'utf-8' kw_list << [k, u, s] if u end kw_list end def kw_generate_dic kw_dic = {nil => ['https://www.google.com/search?ie=utf-8&q=$1', 'utf-8']} kw_list = [] case @conf['kw.dic'].class.to_s when "String" kw_list = kw_parse( @conf['kw.dic'] ) when "Array" kw_list = @conf['kw.dic'] end kw_list.each do |pair| kw_dic[pair[0]] = pair[1..-1] end kw_dic end def kw( keyword, name = nil, title = nil ) @kw_dic = kw_generate_dic unless @kw_dic show_inter = @options['kw.show_inter'] == nil ? true : @options['kw.show_inter'] inter, key = keyword.split( /:/, 2 ) unless key then inter = nil key = keyword end keyword = key unless show_inter name = keyword unless name title = title ? %Q[ title="#{h title}"] : '' unless @kw_dic.has_key?(inter) inter = nil end style = @kw_dic[inter][1] if String.method_defined?(:encode) if style key = key.encode({'jis'=>'ISO-2022-JP', 'sjis'=>'Shift_JIS'}[style] || style) end else key = case style when 'euc-jp' NKF::nkf( '-m0 -W -e', key ) when 'sjis' NKF::nkf( '-m0 -W -s', key ) when 'jis' NKF::nkf( '-m0 -W -j', key ) when 'utf-8' key else # none key end end %Q[<a href="#{h @kw_dic[inter][0].sub( /\$1/, u( key ))}"#{title}>#{h name}</a>] end # # config # unless @resource_loaded then def kw_label "キーワード" end def kw_desc <<-HTML <h3>リンクリストの指定</h3> <p>特定のサイトへのリンクを、簡単な記述で生成するためのプラグイン(kw)です。 「キー URL エンコードスタイル」と空白で区切って指定します。例えば、</p> <pre>google https://www.google.com/search?ie=utf-8&q=$1 utf-8</pre> <p>と指定すると、</p> <pre><%=kw('google:tdiary')%></pre> <p>のように日記に書けばgoogleでtdiaryを検索するリンクになります (記述方法はスタイルによって変わります)。なお、キーにnilを指定すると、 「google:」の部分を書かない場合の指定ができます。</p> HTML end end add_conf_proc( 'kw', kw_label ) do if @mode == 'saveconf' then kw_list = kw_parse( @conf.to_native( @cgi.params['kw.dic'][0] ) ) if kw_list.empty? then @conf.delete( 'kw.dic' ) else @conf['kw.dic'] = kw_list.collect{|a|a.join( ' ' )}.join( "\n" ) end end dic = kw_generate_dic if dic[nil] then dic['nil'] = dic[nil] dic.delete( nil ) end <<-HTML #{kw_desc} <p><textarea name="kw.dic" cols="60" rows="10">#{h dic.collect{|a|a.flatten.join( " " )}.join( "\n" )}</textarea></p> HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/list.rb���������������������������������������������������������������0000664�0000000�0000000�00000001255�13626457307�0017511�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# list.rb # # <ol> 順番付きリスト生成 # <%= ol l %> # パラメタ: # l: リスト文字列(\nくぎり) # # <ul> 順番無しリスト # <%= ul l , t %> # パラメタ: # l: リスト文字列(\nくぎり) # # Copyright (c) 2002 abbey <inlet@cello.no-ip.org> # Distributed under the GPL2 or any later version. # def ol( l, t = nil, s = nil ) apply_plugin( %Q[<ol>#{li l}</ol>] ) end def ul( l, t = nil) apply_plugin( %Q[<ul>#{li l}</ul>] ) end def li( text ) list = "" text.each_line do |line| list << ("<li>" + line.chomp + "</li>") end list end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/makelirs.rb�����������������������������������������������������������0000664�0000000�0000000�00000004304�13626457307�0020343�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# makelirs.rb # # 更新情報をLIRSフォーマットのファイルに吐き出す # # pluginディレクトリに置くだけで動作します。 # # tdiary.confにおいて、@options['makelirs.file']に # ファイル名を指定すると、そのファイルを出力先の # LIRSファイルとします。無指定時にはindex.rbと同じ # パスにantenna.lirsというファイルになります。 # いずれも、Webサーバから書き込める権限が必要です。 # # Copyright (C) 2002 by Kazuhiro NISHIYAMA # You can redistribute it and/or modify it under GPL2 or any later version. # add_header_proc do <<-LINK <!--link rel="alternate" type="application/x-lirs" title="lirs" href="#{File::basename( @options['makelirs.file'] || 'antenna.lirs' )}"--> LINK end add_update_proc do eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING ) unless Time.method_defined?(:utc_offset) class Time def utc_offset l = self.dup.localtime u = self.dup.utc if l.year != u.year off = l.year < u.year ? -1 : 1 elsif l.mon != u.mon off = l.mon < u.mon ? -1 : 1 elsif l.mday != u.mday off = l.mday < u.mday ? -1 : 1 else off = 0 end off = off * 24 + l.hour - u.hour off = off * 60 + l.min - u.min off = off * 60 + l.sec - u.sec return off end end end MODIFY_CLASS file = @options['makelirs.file'] || 'antenna.lirs' # create_lirs cgi = @cgi.clone conf = @conf.clone def cgi.mobile_agent?; false; end def cgi.mobile_agent?; false; end t = TDiaryLatest::new( cgi, "latest.rhtml", conf ) body = t.eval_rhtml # escape comma e = proc{|str| str.gsub(/[,\\]/){ "\\#{$&}" }.gsub( /[\r\n]/, '' ) } now = Time.now utc_offset = now.utc_offset uri = @index.dup uri[0, 0] = base_url if %r|^https?://|i !~ @index uri.gsub!( %r|/\./|, '/' ) lirs = "LIRS,#{t.last_modified.tv_sec},#{Time.now.tv_sec},#{utc_offset},#{body.size},#{e[uri]},#{e[@html_title]},#{e[@author_name]},,\n" File::open( file, 'w' ) do |o| o.puts lirs end begin File::utime( t.last_modified.tv_sec, t.last_modified.tv_sec, file ) rescue end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tdiary-core-5.1.1/misc/plugin/makerss.rb������������������������������������������������������������0000664�0000000�0000000�00000051230�13626457307�0020201�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# makerss.rb # # generate RSS file when updating. # # options configurable through settings: # @conf['makerss.hidecontent'] : hide full-text content. default: false # @conf['makerss.shortdesc'] : shorter description. default: false # @conf['makerss.comment_link'] : insert tsukkomi's link. default: false # # options to be edited in tdiary.conf: # @conf['makerss.file'] : local file name of RSS file. default: 'index.rdf'. # @conf['makerss.url'] : URL of RSS file. # @conf['makerss.no_comments.file'] : local file name of RSS file without # comments. default: 'no_comments.rdf'. # @conf['makerss.no_comments.url'] : URL of RSS file without TSUKOMI. # @conf.banner : URL of site banner image (can be relative) # @conf.description : desciption of the diary # @conf['makerss.partial'] : how much portion of body to be in description # used when makerss.shortdesc, default: 0.25 # @conf['makerss.suffix'] : strings which are appended to the title tag. # @conf['makerss.no_comments.suffix'] : strings which are appended to # the title tag of the commentless rdf. # # CAUTION: Before using, make 'index.rdf' and 'no_comments.rdf' file # into the directory of your diary, and permit writable to httpd. # # Copyright (c) 2009 TADA Tadashi <t@tdtds.jp> # Distributed under the GPL2 or any later version. # if /^append|replace|comment|showcomment|startup$/ =~ @mode then unless @conf.description @conf.description = @conf['whatsnew_list.rdf.description'] end module ::TDiary class RDFSection attr_reader :id, :time, :section def self.from_json(id, json) self.new(id, nil, nil, data: JSON.load(json)) end # 'id' has 'YYYYMMDDpNN' format (p or c). # 'time' is Last-Modified this section as a Time object. def initialize( id, time = nil, section = nil, opts = {} ) @id = id if opts[:data] @time = opts[:data]['time'] @is_comment = opts[:data]['is_comment'] @section = opts[:data]['section'] else @time = time_string(time) @is_comment = section.respond_to?(:name) @section = section_to_hash(section) end end def body? !@is_comment end def <=>( other ) other.time <=> @time end def to_json { 'id' => @id, 'time' => @time, 'section' => @section, 'is_comment' => @is_comment }.to_json end private def time_string(time) g = time.dup.gmtime l = Time::local( g.year, g.month, g.day, g.hour, g.min, g.sec ) tz = (g.to_i - l.to_i) zone = sprintf( "%+03d:%02d", tz / 3600, tz % 3600 / 60 ) time.strftime( "%Y-%m-%dT%H:%M:%S" ) + zone end def section_to_hash(section) sec ||= {} sec['body'] = section.respond_to?(:body_to_html) ? section.body_to_html : section.body sec['subtitle'] = section.subtitle_to_html if section.respond_to?(:subtitle_to_html) sec['visibility'] = section.visible? rescue true sec['category'] = section.categories rescue [] sec['name'] = section.name if section.respond_to?(:name) return sec end end end end @makerss_rsses = @makerss_rsses || [] class MakeRssFull include ERB::Util include TDiary::ViewHelper def initialize(conf, cgi = CGI.new) @conf, @cgi = conf, cgi @item_num = 0 end def title @conf['makerss.suffix'] || '' end def head( str ) @head = str @head.sub!( /<\/title>/, "#{h title}" ) end def foot( str ); @foot = str; end def image( str ); @image = str; end def banner( str ); @banner = str; end def item( seq, body, rdfsec ) @item_num += 1 return if @item_num > 15 @seq = '' unless @seq @seq << seq @body = '' unless @body @body << body end def xml xml = @head.to_s xml << @image.to_s xml << "\n" xml << @seq.to_s xml << "\n\n" xml << @banner.to_s xml << @body.to_s xml << @foot.to_s xml.gsub( /[\x00-\x1f]/ ){|s| s =~ /[\r\n\t]/ ? s : ""} end def file f = @conf['makerss.file'] || 'index.rdf' f = 'index.rdf' if f.empty? f =~ %r|^/| ? f : "#{document_root}/#{f}" end def writable? if FileTest::writable?( file ) then return true elsif FileTest::exist?( file ) return false else # try to create begin File::open( file, 'w' ){|f|} return true rescue return false end end end def write( encoder ) begin File::open( file, 'w' ) do |f| f.write( encoder.call( xml ) ) end rescue end end def url u = @conf['makerss.url'] || "#{base_url}#{File.basename(file)}" u = "#{base_url}#{File.basename(file)}" if u.empty? u end def document_root if @cgi.is_a?(RackCGI) File.join(TDiary.server_root, 'public') else TDiary.server_root end end end @makerss_rsses << MakeRssFull::new(@conf, @cgi) class MakeRssNoComments < MakeRssFull def title @conf['makerss.no_comments.suffix'] || '(without comments)' end def item( seq, body, rdfsec ) return unless rdfsec.body? super end def file f = @conf['makerss.no_comments.file'] || 'no_comments.rdf' f = 'no_comments.rdf' if f.empty? f =~ %r|^/| ? f : "#{document_root}/#{f}" end def write( encoder ) return unless @conf['makerss.no_comments'] super( encoder ) end def url return nil unless @conf['makerss.no_comments'] u = @conf['makerss.no_comments.url'] || "#{base_url}#{File.basename(file)}" u = "#{base_url}#{File.basename(file)}" if u.empty? u end end @makerss_rsses << MakeRssNoComments::new(@conf, @cgi) def makerss_update def get(db, id) json = db.get(id) return nil unless json RDFSection.from_json(id, json) rescue nil end def set(db, id, section) db.set(id, section.to_json) end date = @date.strftime( "%Y%m%d" ) diary = @diaries[date] uri = @conf.index.dup uri[0, 0] = base_url if %r|^https?://|i !~ @conf.index uri.gsub!( %r|/\./|, '/' ) rsses = @makerss_rsses transaction('makerss') do |db| begin if /^append|replace$/ =~ @mode then format = "#{date}p%02d" index = 0 diary.each_section do |section| index += 1 id = format % index if diary.visible? and !get(db, id) then set(db, id, RDFSection::new( id, Time::now, section )) elsif !diary.visible? and get(db, id) db.delete(id) elsif diary.visible? and get(db, id) if get(db, id).section['body'] != section.body_to_html or get(db, id).section['subtitle'] != section.subtitle_to_html then set(db, id, RDFSection::new( id, Time::now, section )) end end end loop do index += 1 id = format % index if get(db, id) then db.delete(id) else break end end elsif /^comment$/ =~ @mode and @conf.show_comment id = "#{date}c%02d" % diary.count_comments( true ) set(db, id, RDFSection::new( id, @comment.date, @comment )) elsif /^showcomment$/ =~ @mode index = 0 diary.each_comment do |comment| index += 1 id = "#{date}c%02d" % index if !get(db, id) and (@conf.show_comment and comment.visible? and /^(TrackBack|Pingback)$/i !~ comment.name) then set(db, id, RDFSection::new( id, comment.date, comment )) elsif get(db, id) and !(@conf.show_comment and comment.visible? and /^(TrackBack|Pingback)$/i !~ comment.name) db.delete(id) end end end rsses.each{|rss| rss.head( makerss_header( uri ) ) } db.keys.map{|k|get(db, k)}.sort.each_with_index do |rdfsec, idx| if rdfsec && rdfsec.section['visibility'] rsses.each {|rss| rss.item( makerss_seq( uri, rdfsec ), makerss_body( uri, rdfsec ), rdfsec ) } end if idx > 50 db.delete(rdfsec.id) end end end end if @conf.banner and not @conf.banner.empty? if /^http/ =~ @conf.banner rdf_image = @conf.banner else rdf_image = base_url + @conf.banner end rsses.each {|r| r.image( %Q[\n] ) } end rsses.each {|r| r.banner( makerss_banner( uri, rdf_image ) ) if rdf_image r.foot( makerss_footer ) r.write( Proc::new{|s| replace_entities( to_utf8( s ) )} ) } end def makerss_header( uri ) rdf_url = @conf['makerss.url'] || "#{base_url}index.rdf" rdf_url = "#{base_url}index.rdf" if rdf_url.empty? desc = @conf.description || '' copyright = Time::now.strftime( "Copyright %Y #{@conf.author_name}" ) copyright += " <#{@conf.author_mail}>" if @conf.author_mail and not @conf.author_mail.empty? copyright += ", copyright of comments by respective authors" %Q[ #{h @conf.html_title} #{h uri} #{h desc} #{h @conf.author_name} #{h copyright} ] end def makerss_seq( uri, rdfsec ) %Q|\n| end def makerss_banner( uri, rdf_image ) %Q[ #{h @conf.html_title} #{h rdf_image} #{h uri} ] end def makerss_desc_shorten( text ) if @conf['makerss.shortdesc'] then @conf['makerss.partial'] = 0.25 unless @conf['makerss.partial'] len = ( text.size.to_f * @conf['makerss.partial'] ).ceil.to_i len = 500 if len > 500 else len = 500 end @conf.shorten( text, len ) end def feed? @makerss_in_feed end def makerss_body( uri, rdfsec ) rdf = "" if rdfsec.body? then rdf = %Q|\n| rdf << %Q|#{h uri}#{anchor rdfsec.id}\n| rdf << %Q|#{h rdfsec.time}\n| a = rdfsec.id.scan( /(\d{4})(\d\d)(\d\d)/ ).flatten.map{|s| s.to_i} date = Time::local( *a ) old_apply_plugin = @conf['apply_plugin'] @conf['apply_plugin'] = true @makerss_in_feed = true subtitle = rdfsec.section['subtitle'] body_enter = body_enter_proc( date ) body = apply_plugin( rdfsec.section['body'] ) body_leave = body_leave_proc( date ) @makerss_in_feed = false sub = (subtitle || '').sub( /^(\[([^\]]+)\])+ */, '' ) sub = apply_plugin( sub, true ).strip if sub.empty? sub = @conf.shorten( remove_tag( body ).strip, 20 ) end rdf << %Q|#{sub}\n| rdf << %Q|#{h @conf.author_name}\n| rdfsec.section['category'].each do |category| rdf << %Q|#{h category}\n| end desc = remove_tag( body ).strip desc.gsub!( /&.*?;/, '' ) rdf << %Q|#{h makerss_desc_shorten( desc )}\n| unless @conf['makerss.hidecontent'] text = '' text << '

    ' + apply_plugin( subtitle.sub( /^(\[([^\]]+)\])+ */, '' ) ).strip + '

    ' if subtitle and not subtitle.empty? text << body_enter text << body text << body_leave unless text.empty? uri = @conf.index.dup uri[0, 0] = base_url unless %r|^https?://|i =~ uri uri.gsub!( %r|/\./|, '/' ) text = absolutify( text, uri ) text.gsub!( /\]\]>/, ']]]]>' ) rdf << %Q|#{comment_new}

    | end rdf << %Q|]]>
    \n| end end @conf['apply_plugin'] = old_apply_plugin rdf << "
    \n" else # TSUKKOMI rdf = %Q|\n| rdf << %Q|#{h uri}#{anchor rdfsec.id}\n| rdf << %Q|#{h rdfsec.time}\n| rdf << %Q|#{makerss_tsukkomi_label( rdfsec.id )} (#{h rdfsec.section['name']})\n| rdf << %Q|#{h rdfsec.section['name']}\n| text = rdfsec.section['body'] rdf << %Q|#{h makerss_desc_shorten( text )}\n| unless @conf['makerss.hidecontent'] rdf << %Q|' ).gsub( /

    \Z/, '' ).gsub( /\]\]>/, ']]]]>' )}]]>
    \n| end rdf << "
    \n" end rdf end def makerss_footer "
    \n" end add_update_proc do makerss_update unless @cgi.params['makerss_update'][0] == 'false' end add_header_proc { html = '' @makerss_rsses.each do |rss| next unless rss.url html << %Q|\t\n| end html } add_conf_proc( 'makerss', @makerss_conf_label, 'update' ) do if @mode == 'saveconf' then %w( hidecontent shortdesc comment_link no_comments).each do |s| item = "makerss.#{s}" @conf[item] = ( 't' == @cgi.params[item][0] ) end end @makerss_rsses.each do |rss| if rss.class == MakeRssFull then @makerss_full = rss elsif rss.class == MakeRssNoComments @makerss_no_comments = rss end end makerss_conf_html end add_edit_proc do checked = if @cgi.params['makerss_update'][0] == 'false' then ' checked' elsif @date < (Time::now - 30*24*60*60) # older over a month ' checked' else '' end <<-HTML
    HTML end add_startup_proc do makerss_update end def replace_entities( text ) unless @xml_entity_table then @xml_entity_table = { ' ' => ' ', '¡' => '¡', '¢' => '¢', '£' => '£', '¤' => '¤', '¥' => '¥', '¦' => '¦', '§' => '§', '¨' => '¨', '©' => '©', 'ª' => 'ª', '«' => '«', '¬' => '¬', '­' => '­', '®' => '®', '¯' => '¯', '°' => '°', '±' => '±', '²' => '²', '³' => '³', '´' => '´', 'µ' => 'µ', '¶' => '¶', '·' => '·', '¸' => '¸', '¹' => '¹', 'º' => 'º', '»' => '»', '¼' => '¼', '½' => '½', '¾' => '¾', '¿' => '¿', 'À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', '&Aelig;' => 'Æ', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ð' => 'Ð', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', '×' => '×', 'Ø' => 'Ø', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'Þ' => 'Þ', 'ß' => 'ß', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'æ' => 'æ', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ð' => 'ð', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', '÷' => '÷', 'ø' => 'ø', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'þ' => 'þ', 'ÿ' => 'ÿ', 'Œ' => 'Œ', 'œ' => 'œ', 'Š' => 'Š', 'š' => 'š', 'Ÿ' => 'Ÿ', 'ˆ' => 'ˆ', '˜' => '˜', ' ' => ' ', ' ' => ' ', ' ' => ' ', '‌' => '‌', '‍' => '‍', '‎' => '‎', '‏' => '‏', '–' => '–', '—' => '—', '‘' => '‘', '’' => '’', '‚' => '‚', '“' => '“', '”' => '”', '„' => '„', '†' => '†', '‡' => '‡', '‰' => '‰', '‹' => '‹', '›' => '›', '€' => '€', 'ƒ' => 'ƒ', 'Α' => 'Α', 'Β' => 'Β', 'Γ' => 'Γ', 'Δ' => 'Δ', 'Ε' => 'Ε', 'Ζ' => 'Ζ', 'Η' => 'Η', 'Θ' => 'Θ', 'Ι' => 'Ι', 'Κ' => 'Κ', 'Λ' => 'Λ', 'Μ' => 'Μ', 'Ν' => 'Ν', 'Ξ' => 'Ξ', 'Ο' => 'Ο', 'Π' => 'Π', 'Ρ' => 'Ρ', 'Σ' => 'Σ', 'Τ' => 'Τ', 'Υ' => 'Υ', 'Φ' => 'Φ', 'Χ' => 'Χ', 'Ψ' => 'Ψ', 'Ω' => 'Ω', 'α' => 'α', 'β' => 'β', 'γ' => 'γ', 'δ' => 'δ', 'ε' => 'ε', 'ζ' => 'ζ', 'η' => 'η', 'θ' => 'θ', 'ι' => 'ι', 'κ' => 'κ', 'λ' => 'λ', 'μ' => 'μ', 'ν' => 'ν', 'ξ' => 'ξ', 'ο' => 'ο', 'π' => 'π', 'ρ' => 'ρ', 'ς' => 'ς', 'σ' => 'σ', 'τ' => 'τ', 'υ' => 'υ', 'φ' => 'φ', 'χ' => 'χ', 'ψ' => 'ψ', 'ω' => 'ω', 'ϑ' => 'ϑ', 'ϒ' => 'ϒ', 'ϖ' => 'ϖ', '•' => '•', '…' => '…', '′' => '′', '″' => '″', '‾' => '‾', '⁄' => '⁄', '℘' => '℘', 'ℑ' => 'ℑ', 'ℜ' => 'ℜ', '™' => '™', 'ℵ' => 'ℵ', '←' => '←', '→' => '→', '↓' => '↓', '↔' => '↔', '↵' => '↵', '⇐' => '⇐', '⇑' => '⇑', '⇒' => '⇒', '⇓' => '⇓', '⇔' => '⇔', '∀' => '∀', '∂' => '∂', '∃' => '∃', '∅' => '∅', '∇' => '∇', '∈' => '∈', '∉' => '∉', '∋' => '∋', '∏' => '∏', '∑' => '∑', '−' => '−', '∗' => '∗', '√' => '√', '∝' => '∝', '∞' => '∞', '∠' => '∠', '∧' => '∧', '∨' => '∨', '∩' => '∩', '∪' => '∪', '∫' => '∫', '∴' => '∴', '∼' => '∼', '≅' => '≅', '≈' => '≈', '≠' => '≠', '≡' => '≡', '≤' => '≤', '≥' => '≥', '⊂' => '⊂', '⊃' => '⊃', '⊄' => '⊄', '⊆' => '⊆', '⊇' => '⊇', '⊕' => '⊕', '⊗' => '⊗', '⊥' => '⊥', '⋅' => '⋅', '⌈' => '⌈', '⌉' => '⌉', '⌊' => '⌊', '⌋' => '⌋', '⟨' => '〈', '⟩' => '〉', '◊' => '◊', '♠' => '♠', '♣' => '♣', '♥' => '♥', '♦' => '♦' } end text.gsub( /&[a-z]+;/im ) do |e| @xml_entity_table[e] || e end end # Copied from below which includes some tests # http://github.com/zunda/ruby-absolutify/tree/master def absolutify(html, baseurl) @@_absolutify_attr_regexp ||= Hash.new baseuri = URI.parse(CGI.escape(baseurl)) r = html.gsub(%r|<\S[^>]*/?>|) do |tag| type = tag.scan(/\A<(\S+)/)[0][0].downcase if attr = {'a' => 'href', 'img' => 'src'}[type] @@_absolutify_attr_regexp[attr] ||= %r|(.*#{attr}\s*=\s*)(['"]?)([^\2>]+?)(\2.*)|im m = tag.match(@@_absolutify_attr_regexp[attr]) unless m.nil? prefix = m[1] + m[2] location = m[3] postfix = m[4] begin uri = URI.parse(location) if uri.relative? location = (baseuri + location).to_s elsif not uri.host and uri.path path = uri.path path += '?' + uri.query if uri.query path += '#' + uri.fragment if uri.fragment location = (baseuri + path).to_s end tag = prefix + location + postfix rescue URI::InvalidURIError end end end tag end return r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/my-ex.rb000066400000000000000000000037201362645730700175740ustar00rootroot00000000000000# my-ex.rb # # my(拡張版): myプラグインを拡張し、title属性に参照先の内容を挿入します。 # 参照先がセクションの場合は(あれば)サブタイトルを、 # ツッコミの場合はツッコんだ人の名前と内容の一部を使います。 # パラメタ: # a: 自分の日記内のリンク先情報('YYYYMMDD#pNN' または 'YYYYMMDD#cNN') # URLをそのまま書くこともできます。 # str: リンクにする文字列 # # Copyright (c) 2002 TADA Tadashi # Distributed under the GPL2 or any later version. def my( a, str, title = nil ) date, frag = a.scan( /(\d{4}|\d{6}|\d{8}|\d{8}-\d+)[^\d]*(?:#?([pct]\d+))?$/ )[0] anc = frag ? "#{date}#{frag}" : date place, frag = frag.scan( /([cpt])(\d\d)/ )[0] if frag if date and frag and @diaries[date] then case place when 'p' section = nil idx = 1 @diaries[date].each_section do |s| section = s break if idx == frag.to_i idx += 1 end if section and section.subtitle then title = h( "#{apply_plugin(section.subtitle_to_html, true)}" ) title.sub!( /^(\[([^\]]+)\])+ */, '' ) end when 'c' com = nil @diaries[date].each_comment( frag.to_i ) {|c| com = c} if com then title = h( "[#{com.name}] #{com.shorten( @conf.comment_length )}" ) end when 't' unless @plugin_files.grep(/tb-show.rb\z/).empty? tb = nil @diaries[date].each_visible_trackback( frag.to_i ) {|t, idx| tb = t} if tb then _, name, _, excerpt = tb.body.split( /\n/,4 ) title = h( "[#{name}] #{@conf.shorten( excerpt, @conf.comment_length )}" ) end end end end index = /^https?:/ =~ @index ? '' : base_url index += @index.sub(%r|^\./|, '') if title then %Q[#{str}] else %Q[#{str}] end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/my-sequel.rb000066400000000000000000000340101362645730700204520ustar00rootroot00000000000000# # my-sequel.rb # # show links to follow-up entries # # Copyright 2006 zunda and # NISHIMURA Takashi # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work under the terms of GPL version 2 or later. # # Language resources can be found in the middle of this file. # Please search a line with `language resource' # require 'pstore' unless defined?(ERB) require 'erb' end class MySequel include ERB::Util extend ERB::Util class Conf include ERB::Util Prefix = 'my_sequel.' unless @conf then def self::to_native(str) return str end else def self::to_native(str) @conf.to_native(str) end end def self::handler_escape(string) string.gsub(/\r/n, '').gsub(/&/n, '&').gsub(/"/n, '"').gsub(/>/n, '>').gsub(/').replace(/"/g, '"').replace(/&/g, '&'); } function uncheck(element) { document.getElementById(element.id+".reset").checked = false; } function restore(element) { var text_id = element.id.replace(/\.reset$/, "") if (element.checked) { document.getElementById(text_id).value = unescape(default_values[text_id]); } } _END end def initialize(conf_hash) @default_hash = conf_hash @conf_hash = Hash.new end # takes configuration from @options trusting the input def merge_hash(hash) @default_hash.each_key do |key| prefixed = Prefix + key.to_s @conf_hash[key] = hash[prefixed] if hash.has_key?(prefixed) end end # takes configuration from @cgi.params def merge_params(params) @default_hash.each_key do |key| keystr = key.to_s if params[keystr+'.reset'] and params[keystr+'.reset'][0] then @conf_hash.delete(key) elsif params[keystr] then @conf_hash[key] = params[keystr][0] end end end # returns current configuration def [](key) if @conf_hash.has_key?(key) then return @conf_hash[key] else return @default_hash[key][:default] end end # returns hash of configured values def to_conf_hash(target_hash) @default_hash.each_key do |key| target_hash.delete(Prefix + key.to_s) end @conf_hash.each_pair do |key, value| target_hash[Prefix + key.to_s] = value end end # returns an HTML sniplet for configuration interface def html(restore_default_label) return @default_hash.keys.sort_by{|k| @default_hash[k][:index]}.map{|k| idattr = %Q| id="#{h k.to_s}"| idattr_reset = %Q| id="#{h k.to_s}.reset"| uncheck = ' onfocus="uncheck(this)"' restore = ' onchange="restore(this)" onclick="restore(this)"' r = %Q|\t

    #{h @default_hash[k][:title]}

    \n| description = @default_hash[k][:description] r += %Q|\t

    #{h description}

    \n| if description unless @default_hash[k][:textarea] r += %Q|\t

    | else cols = 70 rows = 10 if @default_hash[k][:textarea].respond_to?(:[]) then cols = @default_hash[k][:textarea][:cols] || cols rows = @default_hash[k][:textarea][:rows] || rows end r += %Q|\t

    | end name = "#{h k.to_s}.reset" r += %Q| - 

    \n| r }.join end # Javascript hash literal for default values def default_js_hash r = "default_values = {\n" r += @default_hash.keys.sort_by{|k| @default_hash[k][:index]}.map{|k| %Q|\t"#{h k}": "#{Conf::handler_escape(@default_hash[k][:default])}"| }.join(",\n") r += "\n};\n" return r end def handler_block return <<"_END" _END end end # CSS sniplet for sequels def self::css(inner_css) unless inner_css.strip.empty? return <<"_END" \t _END else return '' end end # cache directory for this plguin def self::cache_dir(cache_path) return File.join(cache_path, 'my_sequel') end # cache file for a month: #{yyyy}/#{yyyymm}.#{src or dst}.dat def self::cache_file(cache_path, anchor, direction) return File.join(MySequel.cache_dir(cache_path), MySequel.year(anchor), "#{MySequel.month(anchor)}.#{direction}.dat") end # unique for each month def self::cache_key(anchor) return MySequel.month(anchor) end # for each cache key for dates def self::each_cache_key(dates) dates = dates.is_a?(String) ? [dates] : dates dates.map{|ymd| MySequel.cache_key(ymd)}.uniq.each do |cache_file| yield(cache_file) end end # yyyy def self::year(anchor) return anchor.scan(/\d{4,4}/)[0] end # yyyymm def self::month(anchor) return anchor.scan(/\d{6,6}/)[0] end # yyyymmdd def self::date(anchor) if anchor.respond_to?(:localtime) return anchor.localtime.strftime("%Y%m%d") else return anchor.scan(/\d{8,8}/)[0] end end # add an entry to Array value of hash, making new Array if needed def self::push_to_hash(hash, key, element) unless hash.has_key?(key) hash[key] = Array.new begin hash[key] rescue SecurityError end end hash[key] << element hash end def initialize(cache_path) @link_srcs = Hash.new # key:dst anchor value:Array of src anchors @current_dsts = Hash.new # key:src anchor value:Array of dst anchors @cached_dsts = Hash.new # for restore_dsts and clean_srcs @vanished_dsts = Hash.new # key:src date value:Array of dst anchors @cache_path = cache_path end def restore(dates) restore_srcs(dates) restore_dsts(dates) end # HTML sniplet for sequels def html(dst_anchor, date_format, label) anchors = srcs(dst_anchor) if anchors and not anchors.empty? then r = %Q|
    #{h label}| r += anchors.map{|src_anchor| yield(src_anchor, Time.local(*(src_anchor.scan(/(\d{4,4})(\d\d)(\d\d)/)[0])).strftime(date_format)) }.join(', ') r += "
    \n" return r else return '' end end # Array of source anchors for a destination anchor, nil if none def srcs(dst_anchor) a = @link_srcs[dst_anchor] return nil if not a or a.empty? return a.uniq.sort end # starts a day - get ready to scan the diary for the section def clean_dsts(date) datestr = MySequel.date(date) @current_dsts.keys.each do |src_anchor| next unless MySequel.date(src_anchor) == datestr @current_dsts[src_anchor] = Array.new begin @current_dsts[src_anchor] rescue SecurityError end end end # adds a link def add(src_anchor, dst_anchor) MySequel.push_to_hash(@link_srcs, dst_anchor, src_anchor) MySequel.push_to_hash(@current_dsts, src_anchor, dst_anchor) end # detect vanished links def clean_srcs (@cached_dsts.keys + @current_dsts.keys).uniq.each do |src_anchor| if @cached_dsts[src_anchor] then if @current_dsts[src_anchor] then @vanished_dsts[src_anchor] = @cached_dsts[src_anchor] - @current_dsts[src_anchor] else @vanished_dsts[src_anchor] = @cached_dsts[src_anchor] end end @cached_dsts[src_anchor] = @current_dsts[src_anchor].dup end end # restores cached data for a month # calls the block for each root giving key and value def each_cached(anchor, direction) path = MySequel.cache_file(@cache_path, anchor, direction) begin PStore.new(path).transaction(true) do |db| db.roots.each do |cached_anchor| yield(cached_anchor, db[cached_anchor]) end end rescue TypeError # corrupted PStore data File.unlink(path) rescue PStore::Error # corrupted PStore data begin File.unlink(path) rescue Errno::ENOENT end rescue Errno::ENOENT # no cache yet end end private :each_cached # restores cached sources for a month def restore_srcs(dates) @srcs_loaded ||= Hash.new MySequel.each_cache_key(dates) do |cache_key| unless @srcs_loaded[cache_key] then each_cached(cache_key, 'src') do |anchor, array| unless @link_srcs.has_key?(anchor) @link_srcs[anchor] = array else @link_srcs[anchor] += array end end @srcs_loaded[cache_key] = true end end end # restores cached destinations def restore_dsts(dates) @dsts_loaded ||= Hash.new MySequel.each_cache_key(dates) do |cache_key| unless @dsts_loaded[cache_key] then each_cached(cache_key, 'dst') do |anchor, array| @cached_dsts[anchor] = array @current_dsts[anchor] = array.dup end @dsts_loaded[cache_key] = true end end end # hash for storing cache # key: path to cache # value: Hash # key: anchor # value: compacted and uniqed Array of anchor on the other side of link def hash_for_cache(link_hash, direction) r = Hash.new link_hash.each_pair do |pivot_anchor, anchor_array| c = anchor_array.compact.uniq path = MySequel.cache_file(@cache_path, pivot_anchor, direction) r[path] ||= Hash.new r[path][pivot_anchor] = c end return r end private :hash_for_cache # stores the data def store(cache_hash) cache_hash.each_pair do |path, h| d = File.dirname(path) Dir.mkdir(d) unless File.exist?(d) PStore.new(path).transaction do |db| h.each_pair do |k, v| unless v.empty? then db[k] = v else db.delete(k) end end end end end private :store # commits on-memory results to files def commit d = MySequel.cache_dir(@cache_path) Dir.mkdir(d) unless File.exist?(d) restore_srcs(@link_srcs.keys) restore_srcs(@vanished_dsts.values.flatten) @vanished_dsts.each_pair do |src_anchor, dst_anchors| dst_anchors.uniq.each do |dst_anchor| @link_srcs[dst_anchor].reject!{|anchor| anchor == src_anchor} end end store(hash_for_cache(@link_srcs, 'src')) store(hash_for_cache(@current_dsts, 'dst')) @vanished_dsts = Hash.new end end # register this plguin to tDiary unless defined?(Test::Unit) # language resource and configuration @my_sequel_plugin_name ||= 'Link to follow ups' @my_sequel_description ||= <<_END

    Shows links to follow-up entries, which have `my' link to the entry in the past.

    Do not forget to push the OK button to store the changes.

    _END @my_sequel_label_conf ||= 'Link label' @my_sequel_label ||= 'Follow up: ' @my_sequel_restore_default_label ||= 'Restore default' @my_sequel_default_hash ||= { :label => { :title => 'Link label', :default => 'Follow up: ', :description => 'Prefix for links to the follow-ups', :index => 1, }, :date_format => { :title => 'Link format', :default => @date_format, :description => 'Time format of links to the follow-ups. Sequences of % and a charactor are converted as follows: "%Y" to year, "%m" to month in number, "%b" to short name of month, "%B" to full name of month, "%d" to day of month, "%a" to short name of day of week, and "%A" to full name of day of week, for the follow-up.', :index => 2, }, :inner_css => { :title => 'CSS', :default => <<'_END', font-size: 75%; text-align: right; margin: 0px; _END :description => 'CSS for the links. The followoing is applied to div.sequel.', :index => 3, :textarea => {rows: 5}, }, } @my_sequel_conf = MySequel::Conf.new(@my_sequel_default_hash) @my_sequel_conf.merge_hash(@options) # configuration interface add_conf_proc( 'my-sequel', @my_sequel_plugin_name ) do if @mode == 'saveconf' then @my_sequel_conf.merge_params(@cgi.params) @my_sequel_conf.to_conf_hash(@conf) end <<"_HTML" #{@my_sequel_conf.handler_block}

    #{@my_sequel_plugin_name}

    #{@my_sequel_description} #{@my_sequel_conf.html(@my_sequel_restore_default_label).chomp} _HTML end @my_sequel = MySequel.new(@cache_path) @my_sequel_active = false # activate this plugin if header procs are called # - This avoids being called from makerss.rb add_header_proc do unless bot? @my_sequel_active = true @my_sequel.restore(@diaries.keys) MySequel.css(@my_sequel_conf[:inner_css]) end end # preparation for a day add_body_enter_proc do |date| if @my_sequel_active then if date then @my_sequel_date = MySequel.date(date) @my_sequel.clean_dsts(@my_sequel_date) else @my_sequel_date = nil end end '' end # preparation for a section add_section_enter_proc do |date, index| if @my_sequel_active and @my_sequel_date then @my_sequel_anchor = "#{@my_sequel_date}#p#{'%02d' % index}" end '' end # plugin function to be called from within sections alias :my_sequel_orig_my :my unless defined?(my_sequel_orig_my) def my(*args) if @my_sequel_active and @my_sequel_date and @my_sequel_anchor and @mode != 'preview' then dst_date, frag = args[0].scan(/(\d{8,8})(?:[^\d]*)(?:#?p(\d+))?$/)[0] if dst_date and dst_date < @my_sequel_date then dst_anchor = "#{dst_date}#{frag ? "#p%02d" % frag.to_i : ''}" @my_sequel.add(@my_sequel_anchor, dst_anchor) end end my_sequel_orig_my(*args) end # show sequels when leaving a section add_section_leave_proc do r = '' if @my_sequel_active and @my_sequel_date and @my_sequel_anchor and not bot? then r = @my_sequel.html(@my_sequel_anchor, @my_sequel_conf[:date_format], @my_sequel_conf[:label]){|src_anchor, anchor_str| my_sequel_orig_my(src_anchor, anchor_str) } end @my_sequel_anchor = nil r end # show sequels when leaving a day add_body_leave_proc do r = '' if @my_sequel_active and @my_sequel_date then unless bot? r = @my_sequel.html(@my_sequel_anchor, @my_sequel_conf[:date_format], @my_sequel_conf[:label]){|src_anchor, anchor_str| my_sequel_orig_my(src_anchor, anchor_str) } end end @my_sequel_date = nil r end # commit changes add_footer_proc do if @my_sequel_active then @my_sequel.clean_srcs @my_sequel.commit end '' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/navi_user.rb000066400000000000000000000011501362645730700205230ustar00rootroot00000000000000# navi_user.rb # # navi_user: 前日,翌日→前の日記,次の日記 # modeがday/commentのときに表示される「前日」「翌日」ナビゲーション # リンクを,「前の日記」,「次の日記」に変更するplugin.前の日記,次 # の日記がない場合は,ナビゲーションを表示しない.月またぎにも対応. # # Copyright (c) 2002 Junichiro KITA # Distributed under the GPL2 or any later version. # this plugin is obsoleted # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/number_anchor.rb000066400000000000000000000017011362645730700213540ustar00rootroot00000000000000# number_anchor.rb # # number_anchor: アンカーにid属性を付加する # アンカー画像を異なるものにするためのもの # 使用するさいは、設定画面のヘッダに # <%= use_number_anchor( アンカーの種数 ) %> # と書いてください。 # # Copyright (C) 2002 by zoe # Distributed under the GPL2 or any later version. # def use_number_anchor( n = 1 ) @use_number_anchor = true @total_anchor = n "" end alias :_orig_anchor :anchor def anchor( s ) if @use_number_anchor == true then if /^(\d+)#?([pct])?(\d*)?$/ =~ s then if $2 then n = $3.to_i if n && n > @total_anchor then n = (n % @total_anchor) end "#{_orig_anchor(s)}\" class=\"#$2#{'%02d' % n}" else _orig_anchor(s) end else "" end else _orig_anchor(s) end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/pb-show.rb000066400000000000000000000114541362645730700201170ustar00rootroot00000000000000# pb-show.rb # # functions: # * show Pingback ping URL in right of TSUKKOMI label. # * hide Pingbacks in TSUKKOMI. # * show Pingbacks above Today's Links. # # options: # @options['pb.cgi']: # the Pingback ping URL. './pb.rb' is default. # @options['pb.hide_if_no_pb']: # If true, hide 'Pingbacks(n)' when there is no Pingbacks. Default value is false. # # Copyright (c) 2003 TADA Tadashi # You can distribute this file under the GPL2 or any later version. # # Modified: by Junichiro Kita # Modified: by MoonWolf # # # # hide Pingbacks in TSUKKOMI # module ::TDiary module CommentManager def each_visible_pingback( limit = 3 ) i = 0 @comments.find_all {|com| com.visible_true? and /^Pingback$/ =~ com.name }[0,limit].each do |com| i += 1 # i starts with 1. yield com,i end end def each_visible_pingback_tail( limit = 3 ) i = 0 @comments.find_all {|com| com.visible_true? and /^Pingback$/ =~ com.name }.reverse[0,limit].reverse.each do |com| i += 1 # i starts with 1. yield com,i end end end end # # insert Pingbacks above Today's Link. # alias :referer_of_today_short_pb_backup :referer_of_today_short def referer_of_today_short( diary, limit ) r = referer_of_today_short_pb_backup( diary, limit ) return r unless @plugin_files.grep(/blog_style.rb\z/).empty? if diary and !bot? then count = 0 diary.each_visible_pingback( 100 ) {|t,count|} # count up r << %Q|Pingback#{'s' if count > 1}(#{h( count )})| unless count == 0 and @options['pb.hide_if_no_pb'] end r end def pingbacks_of_today_short( diary, limit = @conf['pingback_limit'] || 3 ) # for BlogKit only return if @plugin_files.grep(/blog_style.rb\z/).empty? fragment = 't%02d' today = anchor( diary.date.strftime( '%Y%m%d' ) ) count = 0 diary.each_visible_pingback( limit ) {|t,count|} # count up r = '' r << %Q!\t
    \n! r << %Q!\t\t
    \n! r << %Q!\t\t\t#{ pingback_today }#{ pingback_total( count ) }\n! r << %Q!\t\t
    \n! r << %Q!\t\t
    \n! r << %Q!\t\t\t

    Before...

    \n! if count > limit diary.each_visible_pingback_tail( limit ) do |t,i| sourceURI, targetURI = t.body.split( /\n/,2 ) r << %Q!\t\t\t

    \n! r << %Q!\t\t\t\t#{ h( @conf['pingback_anchor'] ) }\n! r << %Q!\t\t\t\t#{h( sourceURI )} to #{h( targetURI )}\n! r << %Q!\t\t\t

    \n! end r << %Q!\t\t
    \n! r << %Q!\t
    \n! r end def pingbacks_of_today_long( diary, limit = 100 ) count = 0 diary.each_visible_pingback( limit ) {|t,count|} # count up fragment = 'b%02d' today = anchor( @date.strftime( '%Y%m%d' ) ) r = '' r << %Q!\t
    \n! r << %Q!\t\t
    \n! r << %Q!\t\t\t#{ pingback_today }#{ pingback_total( count ) }\n! r << %Q!\t\t
    \n! r << %Q!\t\t
    \n! diary.each_visible_pingback( limit ) do |t,i| sourceURI, targetURI = t.body.split( /\n/,2 ) f = fragment % i r << %Q!\t\t\t
    \n! r << %Q!\t\t\t\t#{ @conf['pingback_anchor'] }\n! if bot? then r << %Q!\t\t\t\t#{ h( sourceURI + " to " + targetURI )}\n! else r << %Q!\t\t\t\t#{h( sourceURI )} to #{h targetURI}\n! end r << %Q!\t\t\t\t#{ comment_date( t.date ) }\n! r << %Q!\t\t\t
    \n! end r << %Q!\t\t
    \n! r << %Q!\t
    \n! r end # # show Pingback ping URL # add_body_enter_proc do |date| cgi = File.basename(@options['pb.cgi'] || './pb.rb') @pb_date = date @pb_id_url = %Q|#{h @index}#{anchor( @pb_date.strftime('%Y%m%d') )}| @pb_id_url[0, 0] = base_url if %r|^https?://|i !~ @conf.index @pb_id_url.gsub!( %r|/\./|, '/' ) @pb_url = %Q|#{h base_url}#{cgi}/#{@pb_date.strftime('%Y%m%d')}| '' end # configurations @conf['pingback_anchor'] ||= @conf.comment_anchor @conf['pingback_limit'] ||= @conf.comment_limit add_conf_proc( 'Pingback-Show', 'Pingback' ) do if @mode == 'saveconf' then @conf['pingback_anchor'] = @conf.to_native( @cgi.params['pingback_anchor'][0] ) @conf['pingback_limit'] = @cgi.params['pingback_limit'][0].to_i @conf['pingback_limit'] = 3 if @conf['pingback_limit'] < 1 end pb_show_conf_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/ping.rb000066400000000000000000000043701362645730700174740ustar00rootroot00000000000000# ping.rb # # ping to weblog ping servers. # # Copyright (c) 2004 TADA Tadashi # Distributed under the GPL2 or any later version. # # Modified: by MoonWolf # add_update_proc do if @conf['ping.list'] then list = @conf['ping.list'].split ping( list ) unless list.empty? end end def ping( list ) return unless @cgi.params['plugin_ping_send'][0] == 'true' xml = to_utf8( <<-XML ) weblogUpdates.ping #{@conf.html_title} #{base_url} XML require 'net/http' require 'timeout' threads = [] list.each do |url| u = URI::parse( url ) next unless u.host threads << Thread.start( u, xml ) do |u, xml| begin Timeout::timeout( @conf['ping.timeout'].to_i ) do Net::HTTP.start( u.host, u.port ) do |http| http.post( u.path, xml, 'Content-Type' => 'text/xml' ) end end rescue Exception,Timeout::Error end end end threads.each {|t| t.join } end add_conf_proc( 'ping', @ping_label_conf, 'update' ) do ping_conf_proc end def ping_conf_proc if @mode == 'saveconf' then @conf['ping.list'] = @cgi.params['ping.list'][0] @conf['ping.timeout'] = @cgi.params['ping.timeout'][0] end @conf['ping.list'] = '' unless @conf['ping.list'] @conf['ping.timeout'] = '3' unless @conf['ping.timeout'] <<-HTML

    #{@ping_label_list}

    #{@ping_label_list_desc}

    #{@ping_label_timeout}

    HTML end add_edit_proc do ping_edit_proc end def ping_edit_proc checked = ' checked' if @mode == 'preview' then checked = @cgi.params['plugin_ping_send'][0] == 'true' ? ' checked' : '' end <<-HTML
    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/pre_wrap.rb000066400000000000000000000007131362645730700203530ustar00rootroot00000000000000# # pre_wrap.rb: word wrapping style for preformat (
    )
    #
    # Copyright (C) 2010 TADA Tadashi 
    # You can redistribute it and/or modify it under GPL2 or any later version.
    #
    add_header_proc do
    	<<-STYLE
    		
    	STYLE
    end
    tdiary-core-5.1.1/misc/plugin/preview.rb000066400000000000000000000022501362645730700202130ustar00rootroot00000000000000# -*- coding: utf-8; -*-
    #
    # preview.rb: view preview automatically
    #
    # Copyright (c) MATSUOKA Kohei 
    # Distributed under the GPL2 or any later version.
    #
    
    @conf['preview.interval'] ||= 10
    @conf['preview.min_width'] ||= 896
    
    if /\A(form|edit|preview)\z/ === @mode then
    	enable_js('preview.js')
    	add_js_setting('$tDiary.plugin.preview')
    	add_js_setting('$tDiary.plugin.preview.interval', @conf['preview.interval'].to_json)
    	add_js_setting('$tDiary.plugin.preview.minWidth', @conf['preview.min_width'].to_json)
    end
    
    add_conf_proc('preview', @preview_label_conf, 'update') do
    	if @mode == 'saveconf'
    		@conf['preview.interval'] = @cgi.params['preview.interval'][0].to_i
    		@conf['preview.min_width'] = @cgi.params['preview.min_width'][0].to_i
    	end
    	ERB.new(%q{
    		

    <%= @preview_label_interval %>

    <%= @preview_label_interval_desc %>

    sec

    <%= @preview_label_min_width %>

    <%= @preview_label_min_width_desc %>

    px

    }).result(binding) end tdiary-core-5.1.1/misc/plugin/random_google.rb000066400000000000000000000155611362645730700213570ustar00rootroot00000000000000# random_google.rb # # random_google: 日記からランダムに抽出した単語をgoogleで検索するリンクを生成する # # 使い方: # tDiary1.5.5以降で導入されたconf_procに対応しているので,tDiaryの設定画面からどうぞ. # # Copyright (c) 2003 Junichiro KITA # Distributed under the GPL2 or any later version. # def random_google_pickup_word(date) analyzer = @conf['random_google.analyzer'] analyzer = @conf['random_google.analyzer_path'] if analyzer == "user_defined" analyzer = "internal" if analyzer == "" if analyzer == "internal" m = self.methods url_regexp = %r<(((http[s]{0,1}|ftp)://[\(\)%#!/0-9a-zA-Z_$@.&+-,'"*=;?:~-]+)|([0-9a-zA-Z_.-]+@[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+\.[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+))> @diaries[date.strftime('%Y%m%d')].to_src. gsub(url_regexp, ''). scan(/(?:[亜-瑤]{2,}|[ァ-ヶー]{2,}|[0-9A-Za-z]{2,})/).sort.uniq.reject {|i| m.include?(i)} else require 'open3' inn, out, err = Open3.popen3("#{analyzer} | sort | uniq") inn.puts @diaries[date.strftime('%Y%m%d')].to_src inn.close m = self.methods r = out.read.map do |l| word = l.split[0] if /\s(名詞|未知語)/.match(l) and !/(\W|\d)/.match(word) and # 記号とか数字は要らない !/\A[あ-ん]{1,2}\z/.match(word) and # 2文字以下のひらがなも要らんでしょ !m.include?(word) # Pluginのメソッドは除外した方がいいかも word else nil end end.compact out.close err.close r end end def random_google_init @conf['random_google.n'] ||= 2 @conf['random_google.caption'] ||= 'もしかしたら関連するかもしれないページ' @conf['random_google.popup'] ||= '本日のお題: $1' @conf['random_google.append'] ||= '' @conf['random_google.exception'] ||= '' @conf['random_google.analyzer'] ||= "internal" @conf['random_google.analyzer_path'] ||= "" end if /(latest|day)/ === @mode and !bot? add_body_enter_proc do |date| random_google_init exception = @conf['random_google.exception'].split words = random_google_pickup_word(date) - exception if words.empty? '' else r = [] @conf['random_google.n'].times do |i| r << words.delete_at(rand(words.size)) end append = @conf['random_google.append'].split rr = (r.compact + append).map {|i| u(i)}.join('+') # URL-escaped rrr = r.compact.map.to_a.join(' ') caption = @conf['random_google.caption'].gsub(/\$1/, h(rrr)) # only the words picked up are escaped popup = h(@conf['random_google.popup'].gsub(/\$1/, rrr)) # escaped <<-HTML HTML end end end def saveconf_random_google if @mode == 'saveconf' then @conf['random_google.n'] = @cgi.params['random_google_n'][0].to_i @conf['random_google.caption'] = @cgi.params['random_google_caption'][0] @conf['random_google.popup'] = @cgi.params['random_google_popup'][0] @conf['random_google.append'] = @cgi.params['random_google_append'][0] @conf['random_google.exception'] = @cgi.params['random_google_exception'][0] @conf['random_google.analyzer'] = @cgi.params['random_google_analyzer'][0] @conf['random_google.analyzer_path'] = @cgi.params['random_google_analyzer_path'][0] end end add_conf_proc('RandomGoogle', '関連するかもしれないページ検索') do saveconf_random_google random_google_init r = <<-HTML

    キーワードの数

    日記本文から抽出するキーワードの数

    表示関連

    googleへのリンクを示す文字列とリンクの上にマウスポインタを置いた時にポップアップする文字列を指定します.文字列中の $1 は抽出されたキーワードで置換されます.

    リンク:

    ポップアップ:

    追加するキーワード

    追加したいキーワードを指定します.複数指定する場合はキーワードをスペースで区切って指定してください.

    例)

    -site:example.com

    除外するキーワード

    除外したいキーワードを指定します.複数指定する場合はキーワードをスペースで区切って指定してください.

    例)

    a the

    HTML r << <<-HTML

    形態素解析器の利用

    キーワードの抽出に形態素解析器を利用するかどうかを指定します.形態素解析器を使用しない場合は/([亜-瑤]{2,}|[ァ-ヶー]{2,}|[0-9A-Za-z]{2,})/という正規表現でキーワードを抽出しますが,あまり精度はよくありません.

    ChasenやMeCabが標準パスにインストールされていない場合は「場所を指定する」を選択し,下の「形態素解析器のパス」で形態素解析器を絶対パスで指定して下さい.

    ChasenやMeCab以外の形態素解析器を利用したい場合も同様に「場所を指定する」を選択し,下の「形態素解析器のパス」で形態素解析器を絶対パスで指定して下さい.最初のカラムに形態素が出力され,かつ同じ行にその形態素の品詞(「名詞」等)が出力されるような形態素解析器であれば利用可能です.

    形態素解析器のパス

    利用する形態素解析器を絶対パスで指定します.

    例)

    /usr/local/bin/chasen

    HTML r end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/recent_comment.rb000066400000000000000000000050611362645730700215370ustar00rootroot00000000000000# recent_comment.rb # # recent_comment: 最近のツッコミをリストアップする # # Copyright (c) 2002 TADA Tadashi # You can distribute this file under the GPL2 or any later version. # def recent_comment_format(format, *args) format.gsub(/\$(\d)/) {|s| args[$1.to_i - 1]} end def recent_comment_init @conf['recent_comment.max'] ||= 3 @conf['recent_comment.date_format'] ||= "(%m-%d)" @conf['recent_comment.except_list'] ||= '' @conf['recent_comment.format'] ||= '$4 $5' @conf['recent_comment.notfound_msg'] ||= '' end def recent_comment( ob_max = 'OBSOLUTE', sep = 'OBSOLUTE', ob_form = 'OBSOLUTE', ob_except = 'OBSOLUTE' ) recent_comment_init max = @conf['recent_comment.max'] form = @conf['recent_comment.date_format'] except = @conf['recent_comment.except_list'] format = @conf['recent_comment.format'] notfound_msg = @conf['recent_comment.notfound_msg'] comments = [] date = {} index = {} @diaries.each_value do |diary| next unless diary.visible? diary.each_comment_tail( max ) do |comment, idx| if (except != '') && (/#{except}/ =~ comment.name) next end comments << comment date[comment.date] = diary.date index[comment.date] = idx end end result = [] comments.sort{|a,b| (a.date)<=>(b.date)}.reverse.each_with_index do |com,idx| break if idx >= max a = h(@index) + anchor("#{date[com.date].strftime( '%Y%m%d' )}#c#{'%02d' % index[com.date]}") # we can not escape anchor() to accomodate number_anchor.rb popup = h( com.shorten( @conf.comment_length ) ) str = h( com.name ) date_str = h( com.date.dup.strftime( form ) ) result << "
  • " result << recent_comment_format(format, idx, a, popup, str, date_str) result << "
  • \n" end if result.size == 0 notfound_msg else %Q|
      \n| + result.join( '' ) + "
    \n" end end if @mode == 'saveconf' def saveconf_recent_comment @conf['recent_comment.max'] = @cgi.params['recent_comment.max'][0].to_i @conf['recent_comment.date_format'] = @cgi.params['recent_comment.date_format'][0] @conf['recent_comment.except_list'] = @cgi.params['recent_comment.except_list'][0] @conf['recent_comment.format'] = @cgi.params['recent_comment.format'][0] @conf['recent_comment.notfound_msg'] = @cgi.params['recent_comment.notfound_msg'][0] end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/recent_comment3.rb000066400000000000000000000126611362645730700216260ustar00rootroot00000000000000# # recent_comment3: 最近のツッコミをリストアップする # # Copyright (c) 2002 Junichiro KITA # Distributed under the GPL2 or any later version. # require 'pstore' require 'fileutils' require 'time' require 'pathname' require 'tdiary/diary_container' def recent_comment3_format(format, *args) format.gsub(/\$(\d)/) {|s| args[$1.to_i - 1]} end def migrate_old_data # backward compatibility if File.exist?("#{@cache_path}/recent_comments") && !File.exist?("{#{@conf.data_path}/recent_comments") FileUtils.mv( "#{@cache_path}/recent_comments", "#{@conf.data_path}/recent_comments" ) end # workaround for "/foo//bar" doesn't equal "/foo/bar" if @conf['recent_comment3.cache'] && Pathname(@conf['recent_comment3.cache']).cleanpath == Pathname("#{@cache_path}/recent_comments").cleanpath @conf['recent_comment3.cache'] = "#{@conf.data_path}/recent_comments" end end def recent_comment3_init @conf['recent_comment3.cache'] ||= "#{@conf.data_path}/recent_comments" @conf['recent_comment3.cache_size'] ||= 50 @conf['recent_comment3.max'] ||= 3 @conf['recent_comment3.date_format'] ||= "(%m-%d)" @conf['recent_comment3.except_list'] ||= '' @conf['recent_comment3.format'] ||= '$4 $5' @conf['recent_comment3.tree'] ||= "" @conf['recent_comment3.titlelen'] ||= 20 @conf['recent_comment.notfound_msg'] ||= '' end def recent_comment3(ob_max = 'OBSOLUTE' ,sep = 'OBSOLUTE',ob_date_format = 'OBSOLUTE',*ob_except ) migrate_old_data recent_comment3_init cache = @conf['recent_comment3.cache'] date_format = @conf['recent_comment3.date_format'] excepts = @conf['recent_comment3.except_list'].split(/,/) format = @conf['recent_comment3.format'] titlelen = @conf['recent_comment3.titlelen'] notfound_msg = @conf['recent_comment.notfound_msg'] entries = {} tree_order =[] order = [] idx = 0 PStore.new(cache).transaction do |db| break unless db.root?('comments') db['comments'].each do |c| break if c.nil? || idx >= @conf['recent_comment3.max'] comment, date, serial = c next if excepts.include?(comment.name) || !comment.visible? a = h( @index ) + anchor("#{date.strftime('%Y%m%d')}#c#{'%02d' % serial}") # XXX handling Encoding::CompatibilityError popup = h(comment.shorten(@conf.comment_length)) rescue nil str = h(comment.name) date_str = h( comment.date.strftime(date_format) ) idx += 1 entry_date = "#{date.strftime('%Y%m%d')}" comment_str = entries[entry_date] if comment_str.nil? comment_str = [] tree_order << entry_date end comment_str << recent_comment3_format(format, idx, a, popup, str, date_str) entries[entry_date] = comment_str order << entry_date end db.abort end result = [] if @conf['recent_comment3.tree'] == "t" if entries.size == 0 notfound_msg else tree_order.each do |entry_date| a_entry = @index + anchor(entry_date) diary = DiaryContainer::find_by_day(@conf, entry_date) title = diary.diaries[entry_date].title.gsub( /<[^>]*>/, '' ) if diary if title.nil? || title.length == 0 || title.strip.delete(' ').delete(' ').length == 0 then date = Time.parse(entry_date) title = "#{date.strftime @date_format}" end result << "
  • " result << %Q|#{h( @conf.shorten( title, titlelen ) )}
    | entries[entry_date].sort.each do |comment_str| result << comment_str + "
    " end result << "
  • \n" end %Q|
      \n| + result.join( '' ) + "
    \n" end else if entries.size == 0 '' else order.each do | entry_date | result << "
  • #{entries[entry_date][0]}
  • \n" entries[entry_date].shift end %Q|
      \n| + result.join( '' ) + "
    \n" end end end add_update_proc do migrate_old_data recent_comment3_init date = @date.strftime( '%Y%m%d' ) cache = @conf['recent_comment3.cache'] size = @conf['recent_comment3.cache_size'] if @mode == 'comment' && @comment && @comment.visible? PStore.new(cache).transaction do |db| comment = @comment serial = 0 @diaries[date].each_comment { serial += 1 } db['comments'] = Array.new( size ) unless db.root?('comments') if db['comments'][0].nil? or comment != db['comments'][0][0] db['comments'].unshift([comment, @date, serial]).pop end end elsif @mode == 'showcomment' PStore.new( cache ).transaction do |db| break unless db.root?('comments') @diaries[date].each_comment do |dcomment| db['comments'].each do |c| break if c.nil? comment, cdate, _ = c next if cdate.strftime('%Y%m%d') != date if comment == dcomment && comment.date.to_s == dcomment.date.to_s comment.show = dcomment.visible? next end end end end end end if @mode == 'saveconf' def saveconf_recent_comment3 @conf['recent_comment3.max'] = @cgi.params['recent_comment3.max'][0].to_i @conf['recent_comment3.date_format'] = @cgi.params['recent_comment3.date_format'][0] @conf['recent_comment3.except_list'] = @cgi.params['recent_comment3.except_list'][0] @conf['recent_comment3.format'] = @cgi.params['recent_comment3.format'][0] @conf['recent_comment3.tree'] = @cgi.params['recent_comment3.tree'][0] @conf['recent_comment3.titlelen'] = @cgi.params['recent_comment3.titlelen'][0].to_i @conf['recent_comment.notfound_msg'] = @cgi.params['recent_comment.notfound_msg'][0] end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/recent_list.rb000066400000000000000000000062161362645730700210530ustar00rootroot00000000000000# # recent_list: 最近書いた日記のタイトル,サブタイトルを表示する # パラメタ(カッコ内は未指定時の値): # days: 何日分の日記を表示するか(20) # date_format: 日付表示フォーマット(日記の日付フォーマット) # title_with_body: trueで各パラグラフへのリンクのtitle属性にそのパラグラフの一部を指定(false) # show_size: trueで日記長を表示(false) # show_title: trueで各日のタイトルを表示(false) # # 注意: セキュアモードでは使えません。 # 備考: タイトルリストを日記に埋め込むは、レイアウトを工夫しなければ # なりません。ヘッダやフッタでtableタグを使ったり、CSSを書き換 # える必要があるでしょう。 # # Copyright (c) 2001,2002 Junichiro KITA # Distributed under the GPL2 or any later version. # require 'tdiary/diary_container' module ::TDiary class TDiaryMonthWithoutFilter < TDiaryMonth def referer_filter(referer); end end end def recent_list( days = 30, date_format = nil, title_with_body = nil, show_size = nil, show_title = nil ) days = days.to_i date_format ||= @conf.date_format result = %Q|
      \n| catch(:exit) { @years.keys.sort.reverse_each do |year| @years[year].sort.reverse_each do |month| m = DiaryContainer::find_by_month(@conf, "#{year}#{month}") m.diaries.keys.sort.reverse_each do |date| next unless m.diaries[date].visible? result << %Q|
    • #{m.diaries[date].date.strftime(date_format)}\n| if show_title and m.diaries[date].title result << %Q| #{m.diaries[date].title}| end if show_size == true s = 0 m.diaries[date].each_section do |section| s = s + section.to_s.size.to_i end result << ":#{s}" end result << %Q|\t
        \n| i = 1 if !@plugin_files.grep(/\/category.rb$/).empty? and m.diaries[date].categorizable? m.diaries[date].each_section do |section| if section.stripped_subtitle result << %Q|\t
      • #{i}. | \ << %Q|#{section.stripped_subtitle_to_html}
      • \n| end i += 1 end else m.diaries[date].each_section do |section| if section.subtitle result << %Q|\t
      • #{i}. | \ << %Q|#{section.subtitle_to_html}
      • \n| end i += 1 end end result << "\t
      \n
    • \n" days -= 1 throw :exit if days == 0 end end end } apply_plugin( result << "
    \n" ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/recent_namazu.rb000066400000000000000000000024411362645730700213670ustar00rootroot00000000000000# recent_namazu.rb # # recent_namazu: Namazu検索語新しい順 # namazi.cgiが作成する検索キーワードログ(NMZ.slog)から # 最新xx件分の検索語を表示します。 # パラメタ: # file: 検索キーワードログファイル名(絶対パス表記) # namazu: なまずcgi名 # limit: 表示件数(未指定時:5) # sep: セパレータ(未指定時:空白) # make_link: を生成するか?(未指定時:生成する) # # # Copyright (c) 2002 Hiroyuki Ikezoe # Distributed under the GPL2 or any later version. def recent_namazu(file, namazu, limit = 5, sep=' ', make_link = true) begin lines = [] log = open(file) if log.stat.size > 300 * limit then log.seek(-300 * limit,IO::SEEK_END) end log.each_line do |line| lines << line end result = [] lines.reverse.each_with_index do |line,idx| break if idx >= limit word = line.split(/\t/)[0] if make_link result << %Q[#{h( word )}] else result << h( word ) end end result.join( sep ) rescue %Q[

    #$! (#{$!.class})
    cannot read #{file}.

    ] end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/recent_rss.rb000066400000000000000000000161141362645730700207050ustar00rootroot00000000000000# -*- indent-tabs-mode: t -*- # recent_rss.rb: RSS recent plugin # # options: # @options['recent_rss.use-image-link'] : use image as link # instead of text if available. # # recent_rss: show recnet list from RSS # parameters (default): # url: URL of RSS # max: max of list itmes(5) # cache_time: cache time(second) of RSS(60*60) # show_modified: show modified time of the entry (true) # # Copyright (c) 2003-2005 Kouhei Sutou # Distributed under the GPL2 or any later version. # require "rss/rss" require "fileutils" RECENT_RSS_FIELD_SEPARATOR = "\0" RECENT_RSS_ENTRY_SEPARATOR = "\1" RECENT_RSS_VERSION = "0.0.6" RECENT_RSS_HTTP_HEADER = { "User-Agent" => "tDiary RSS recent plugin version #{RECENT_RSS_VERSION}. " << "Using RSS parser version is #{::RSS::VERSION}.", } def recent_rss( url, max = 5, cache_time = 3600, show_modified = true ) cache_file = "#{@cache_path}/recent_rss.#{CGI.escape(url)}" recent_rss_cache_rss(url, cache_file, cache_time.to_i) return '' unless test(?r, cache_file) rv = %Q|
    \n| site_info, *infos = recent_rss_read_from_cache(cache_file) if site_info title, url, time, image = site_info content = recent_rss_entry_to_html( title, url, time, image, show_modified ) rv << %Q|
    \n| rv << %Q|#{content}\n| rv << "
    \n" end have_entry = infos.size > 0 && max > 0 rv << %Q|
      \n| if have_entry i = 0 infos.each do |title, url, time, image| break if i >= max next if title.nil? rv << '
    1. ' rv << %Q[] rv << recent_rss_entry_to_html( title, url, time, image, show_modified ) rv << %Q[] rv << "
    2. \n" i += 1 end rv << "
    \n" if have_entry rv << "
    \n" rv end class InvalidResourceError < StandardError; end class RSSNotModified < StandardError; end require 'time' require 'timeout' require 'net/http' require 'uri/generic' require 'rss/parser' require 'rss/1.0' require 'rss/2.0' require 'rss/dublincore' begin require 'rss/image' rescue LoadError end def recent_rss_cache_rss(url, cache_file, cache_time) cached_time = nil cached_time = File.mtime(cache_file) if File.exist?(cache_file) if cached_time.nil? or Time.now > cached_time + cache_time begin uri = URI.parse(url) raise URI::InvalidURIError unless uri.is_a?(URI::HTTP) rss_source = recent_rss_fetch_rss(uri, cached_time) raise InvalidResourceError if rss_source.nil? # parse RSS rss = ::RSS::Parser.parse(rss_source, false) raise ::RSS::Error if rss.nil? # pre processing begin rss.output_encoding = @conf.charset || charset rescue ::RSS::UnknownConversionMethodError end rss_infos = [] rss.items.each do |item| recent_rss_pubDate_to_dc_date(item) if item.respond_to?(:image_item) and item.image_item image = item.image_item.about else image = nil end rss_infos << [item.title, item.link, item.dc_date, image] end recent_rss_pubDate_to_dc_date(rss.channel) rss_infos.unshift([ rss.channel.title, rss.channel.link, rss.channel.dc_date || rss.items.collect{|item| item.dc_date}.compact.first, rss.image && rss.image.url, ]) recent_rss_write_to_cache(cache_file, rss_infos) rescue RSSNotModified FileUtils.touch(cache_file) rescue URI::InvalidURIError recent_rss_write_to_cache(cache_file, [['Invalid URI', url]]) rescue InvalidResourceError, ::RSS::Error recent_rss_write_to_cache(cache_file, [['Invalid Resource', url]]) end end end def recent_rss_fetch_rss(uri, cache_time) rss = nil px_host, px_port = (@conf['proxy'] || '').split( /:/ ) px_port = 80 if px_host and !px_port begin Timeout::timeout( 10 ) do res = Net::HTTP::Proxy( px_host, px_port ).get_response( uri ) case res when Net::HTTPSuccess rss = res.body when Net::HTTPRedirection raise InvalidResourceError when Net::HTTPNotModified # not modified raise RSSNotModified else raise InvalidResourceError end end rescue Timeout::Error, SocketError, StandardError raise InvalidResourceError end rss end def recent_rss_http_header(cache_time) header = RECENT_RSS_HTTP_HEADER.dup if cache_time.respond_to?(:rfc2822) header["If-Modified-Since"] = cache_time.rfc2822 end header end def recent_rss_write_to_cache(cache_file, rss_infos) File.open(cache_file, 'w') do |f| f.flock(File::LOCK_EX) rss_infos.each do |info| f << info.join(RECENT_RSS_FIELD_SEPARATOR) f << RECENT_RSS_ENTRY_SEPARATOR end f.flock(File::LOCK_UN) end end def recent_rss_read_from_cache(cache_file) infos = [] File.open(cache_file) do |f| while info = f.gets(RECENT_RSS_ENTRY_SEPARATOR) info = info.chomp(RECENT_RSS_ENTRY_SEPARATOR) infos << info.split(RECENT_RSS_FIELD_SEPARATOR) end end infos.collect do |title, url, time, image| [ recent_rss_convert(title), recent_rss_convert(url), recent_rss_convert(time) {|t| Time.parse(t)}, recent_rss_convert(image), ] end end def recent_rss_convert(str) if str.nil? or str.empty? nil else if block_given? yield str else str end end end def recent_rss_entry_to_html(title, url, time, image = nil, show_modified = true ) rv = "" unless url.nil? rv << %Q[] end if image and @options['recent_rss.use-image-link'] rv << %Q[site image\n] else rv << h( title ) end rv << '' unless url.nil? rv << "(#{recent_rss_modified(time)})" if show_modified rv end # from RWiki def recent_rss_modified(t) return '-' unless t dif = (Time.now - t).to_i dif = dif / 60 return "#{dif}m" if dif <= 60 dif = dif / 60 return "#{dif}h" if dif <= 24 dif = dif / 24 return "#{dif}d" end # from RWiki def recent_rss_modified_class(t) return 'dangling' unless t dif = (Time.now - t).to_i dif = dif / 60 return "modified-hour" if dif <= 60 dif = dif / 60 return "modified-today" if dif <= 24 dif = dif / 24 return "modified-month" if dif <= 30 return "modified-year" if dif <= 365 return "modified-old" end def recent_rss_pubDate_to_dc_date(target) if target.respond_to?(:pubDate) class << target alias_method(:dc_date, :pubDate) end end end add_conf_proc('recent_rss', label_recent_rss_title) do item = 'recent_rss.use-image-link' if @mode == 'saveconf' @conf[item] = (@cgi.params[item][0] == 't') end <<-HTML

    #{label_recent_rss_use_image_link_title}

    #{label_recent_rss_use_image_link_description}

    HTML end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/referer-antibot.rb000066400000000000000000000032771362645730700216340ustar00rootroot00000000000000# referer-antibot.rb # # 検索エンジンの巡回BOTには「本日のリンク元」を見せないようにする # これにより、無関係な検索語でアクセスされることが減る(と予想される) # pluginディレクトリに入れるだけで動作する # # オプション: # @options['bot'] # ターゲットにする巡回BOTのUser-Agentを追加する配列。 # 無指定時は["googlebot", "Hatena Antenna", "moget@goo.ne.jp"]のみ。 # # なお、disp_referrer.rbプラグインには同等の機能が含まれているので、 # disp_referrerを導入済みの場合には入れる必要はない # # --------- # # This plugin hide Today's Link to search engin's robots. # It may reduce nose marked by robots. # # disp_referrer.rb plugin has already this function. You don't # need install this plugin with disp_referrer.rb. # # Options: # @options['bot'] # An array of User-Agent of search engine's robots. # Default setting is ["googlebot", "Hatena Antenna", "moget@goo.ne.jp"]. # # Copyright (C) 2002 MUTOH Masao # Modified by TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # short referer alias referer_of_today_short_antibot_backup referer_of_today_short def referer_of_today_short( diary, limit ) return '' if bot? referer_of_today_short_antibot_backup( diary, limit ) end # long referer alias referer_of_today_long_antibot_backup referer_of_today_long def referer_of_today_long( diary, limit ) return '' if bot? referer_of_today_long_antibot_backup( diary, limit ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/referer-utf8.rb000066400000000000000000000002261362645730700210510ustar00rootroot00000000000000# referer-utf8.rb # # this plugin is obsolete. # # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/referer_scheme.rb000066400000000000000000000044201362645730700215110ustar00rootroot00000000000000=begin = Meta-scheme plugin((-$Id: referer_scheme.rb,v 1.9 2005-07-23 08:07:52 zunda Exp $-)) Enables to prefix `meta' schemes to URL regexp of the refer_table. See #{lang}/referer_scheme.rb for a documentation. == Copyright Copyright (C) 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end unless @conf.referer_table.respond_to?( 'scheme_ymd', true ) then class << @conf.referer_table private def scheme_ymd( url, name ) [ ['.*?(\d{4})[-/]?(\d{2})[-/]?(\d{2}).*', '(\1-\2-\3)'], ['.*?(\d{4})[-/]?(\d{2}).*', '(\1-\2)'], ['.*?(\d{2})[-/]?(\d{2}).*', '(\1-\2)'], ['(.+)', '(\1)'], ].each do |path, date| yield( url + path, name + date ) end yield( url, name ) end end end unless @conf.referer_table.respond_to?( 'scheme_tdiary', true ) then class << @conf.referer_table TdiaryDates = [ ['(?:\\?date=)?(\d{4})(\d{2})(\d{2})-(\d+)(?:\.html)?.*', '(\1-\2-\3~)'], ['(?:\\?date=)?(\d{4})(\d{2})(\d{2})(?:\.html)?.*', '(\1-\2-\3)'], ['(?:\\?date=)?(\d{4})(\d{2})(?:\.html)?.*', '(\1-\2)'], ['(?:\\?date=)?(\d{2})(\d{2})(?:\.html)?.*', '(\1-\2)'], ] private def scheme_tdiary( url, name ) TdiaryDates.each do |a| yield( url + a[0], name + a[1] ) end yield( url + '.*' , name ) end end end unless @conf.referer_table.respond_to?( 'scheme_wiki', true ) then class << @conf.referer_table private def scheme_wiki( url, name ) ['\?([^;&$]*).*', '([^/]+)\/?$'].each do |p| yield( "#{url}#{p}", '\1 - ' + name ) end yield( url, name ) end end end unless @conf.referer_table.respond_to?( 'referer_scheme_each_orig' ) then class << @conf.referer_table # expands referer_table according to the meta-scheme alias referer_scheme_each_orig each def each self.referer_scheme_each_orig do |url, name| /^(\w+):/ =~ url if $1 && self.respond_to?( "scheme_#{$1}", true ) then self.send( "scheme_#{$1}", $', name ) do |expanded_url, expanded_name| yield( expanded_url, expanded_name ) end else yield( url, name ) end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/search-default.rb000066400000000000000000000137231362645730700214300ustar00rootroot00000000000000# # search-default.rb - site search plugin sample using DefaultIO. # # Copyright (C) 2003-2005 Minero Aoki # Copyright (C) 2012, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # def search_title '全文検索' end class WrongQuery < StandardError; end module DefaultIOSearch module_function def setup_patterns(query) patterns = split_string(query).map {|pat| check_pattern pat Regexp.new( Regexp.quote(pat), Regexp::IGNORECASE ) } raise WrongQuery, 'no pattern' if patterns.empty? raise WrongQuery, 'too many sub patterns' if patterns.length > 8 patterns end def check_pattern(pat) raise WrongQuery, 'no pattern' unless pat raise WrongQuery, 'empty pattern' if pat.empty? raise WrongQuery, "pattern too short: #{pat}" if pat.length < 2 raise WrongQuery, 'pattern too long' if pat.length > 128 end def split_string(str) str.split(/[\s ]+/ou).reject {|w| w.empty? } end INF = 1 / 0.0 def match_components(patterns, data_path) foreach_diary_from_latest(data_path) do |diary| next unless diary.visible? num = 1 diary.each_section do |sec| if patterns.all? {|re| re =~ sec.to_src } yield diary, fragment('p', num), sec end num += 1 end diary.each_visible_comment(INF) do |cmt, num| if patterns.all? {|re| re =~ cmt.body } yield diary, fragment('c', num), cmt end end end end def fragment(type, num) sprintf('%s%02d', type, num) end # # tDiary Implementation Dependent # def foreach_diary_from_latest(data_path, &block) foreach_data_file(data_path.sub(%r, '')) do |path| read_diaries(path).sort_by {|diary| diary.date }.reverse_each(&block) end end def foreach_data_file(data_path, &block) Dir.glob("#{data_path}/[0-9]*/*.td2").sort.reverse_each do |path| yield path end end def read_diaries(path) d = nil diaries = {} load_tdiary_textdb(path) do |header, body| begin d = diary_class(header['Format']).new(header['Date'], '', body) rescue ArgumentError next end d.show(header['Visible'] != 'false') diaries[d.ymd] = d end (Years[d.y] ||= []).push(d.m) if d load_comments diaries, path diaries.values end DIARY_CLASS_CACHE = {} def diary_class(style) c = DIARY_CLASS_CACHE[style] return c if c if TDiary.const_defined?('Style') require "tdiary/style/#{style.downcase}.rb" c = eval("TDiary::Style::#{style.capitalize}Diary") else require "tdiary/style/#{style.downcase}_style.rb" c = eval("TDiary::#{style.capitalize}Diary") end c.__send__(:include, DiaryClassDelta) DIARY_CLASS_CACHE[style] = c c end module DiaryClassDelta def ymd date().strftime('%Y%m%d') end def y_m_d date().strftime('%Y-%m-%d') end def y '%04d' % date().year end def m '%02d' % date().month end end def load_comments(diaries, path) cmtfile = path.sub(/2\z/, 'c') return unless File.file?(cmtfile) load_tdiary_textdb(cmtfile) do |header, body| c = TDiary::Comment.new(header['Name'], header['Mail'], body, Time.at(header['Last-Modified'].to_i)) c.show = (header['Visible'] != 'false') d = diaries[header['Date']] d.add_comment c if d end end def load_tdiary_textdb(path) File.open(path) {|f| ver = f.gets.strip raise "unkwnown format: #{ver}" unless ver == 'TDIARY2.00.00' or ver == 'TDIARY2.01.00' f.each('') do |header| h = {} header.strip.each_line do |line| begin n, v = *line.split(':', 2) rescue ArgumentError next end h[n.strip] = v.strip end body = f.gets("\n.\n").chomp(".\n") yield h, body end } end def short_html(component) # Section classes do not have common superclass, we can't use class here. case component.class.name when /Section/ section = component if section.subtitle sprintf('%s
    %s', tdiary2text(section.subtitle_to_html), tdiary2text(section.body_to_html)) else tdiary2text(section.body_to_html) end when /Comment/ cmt = component shorten(escape((cmt.name + ': ' + cmt.body))) else raise "must not happen: #{component.class}" end end def tdiary2text(html) re = Regexp.new('<[^>]*>', Regexp::EXTENDED) shorten(apply_tdiary_plugins(html).gsub(re, '')) end Years = {} TDiary::Plugin.__send__(:public, :apply_plugin) def apply_tdiary_plugins(html) #@plugin.apply_plugin(html, false) html end @plugin = nil # # Utils # HTML_ESCAPE_TABLE = { '&' => '&', '<' => '<', '>' => '>', '"' => '"' } def escape(str) tbl = HTML_ESCAPE_TABLE str.gsub(/[&"<>]/) {|ch| tbl[ch] } end def shorten(str, len = 200) matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{len - 3}}/u )[0] if $'.nil? || $'.empty? matched else matched + '...' end end end def search_input_form( q ) <<-HTML
    検索キーワード:
    HTML end def search_result unless @conf.io_class == (TDiary.const_defined?('DefaultIO') ? TDiary::DefaultIO : TDiary::IO::Default) return %Q|

    could not use this plugin under #{@conf.io_class}.

    | end query = CGI::unescape( @cgi.params['q'][0] ) begin patterns = DefaultIOSearch::setup_patterns(query) r = search_input_form( query ) r << '
    ' count = 0 too_many = false DefaultIOSearch::match_components(patterns, @conf.data_path) do |diary, fragment, component| count += 1 if count > 50 # TO MANY HITS too_many = true break end href = @conf.index + anchor( "#{diary.ymd}#{fragment}" ) r << %Q|
    #{h diary.y_m_d}
    | r << %Q|
    #{DefaultIOSearch::short_html(component)}
    | end r << '
    ' r << '
    ' r << "

    #{too_many ? 'too many' : count} hits.

    " r << '
    ' r rescue WrongQuery search_input_form( query ) + %Q|

    #{$!.message}

    | end end tdiary-core-5.1.1/misc/plugin/search_control.rb000066400000000000000000000132311362645730700215400ustar00rootroot00000000000000=begin = ここだけ検索プラグイン/search control plugin((-$Id: search_control.rb,v 1.11 2008-03-02 09:01:45 kazuhiko Exp $-)) Under revision! TODO: add/remove user agents == License Copyright (C) 2003, 2004 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog See ChangeLog for changes after this. * Aug 28, 2003 zunda - 1.3 - simpler configuration display * Aug 26, 2003 zunda - 1.2 - no table in configuration view, thanks to Tada-san. * Aug 26, 2003 zunda - no nofollow - English translation =end ChangeLog # Default values unless defined?( Search_control_agents ) then Search_control_agents = [ '', 'Comaneci_bot', ] Search_control_defaults = [ { # agent: generic 'latest' => 'f', 'day' => 't', 'month' => 'f', 'nyear' => 'f', 'category' => 'f', }, { # agent: 'Comaneci_bot' 'latest' => 't', 'day' => 'f', 'month' => 'f', 'nyear' => 'f', 'category' => 'f', }, ] # to be used for @options and in the HTML form Search_control_prefix = 'search_control' # functions used in this file # number of agents def _sc_nkey "#{Search_control_prefix}.agents" end # agent name key for agent number def _sc_akey( number ) "#{Search_control_prefix}.agent#{number.to_i > 0 ? number : ''}" end # views def _sc_vkey( view, number ) "#{Search_control_prefix}.#{number.to_i > 0 ? number : ''}#{view}.index" end def _sc_each_view Search_control_defaults[0].each_key do |view| yield( view ) end end def _sc_each_vkey( number ) _sc_each_view do |view| yield( _sc_vkey( view, number ) ) end end # keys in the form def _sc_newkey "#{Search_control_prefix}.newagent" end def _sc_delkey( number ) "#{Search_control_prefix}.delete#{number}" end end # defaults unless @conf[_sc_nkey] then @conf[_sc_nkey] = Search_control_agents.size end _sc_each_vkey( 0 ) do |vkey| @conf[vkey] = value unless @conf[vkey] end Search_control_defaults.each_with_index do |d, i| @conf[_sc_akey(i)] = Search_control_agents[i] unless @conf[_sc_akey(i)] and i > 0 d.each_pair do |view, value| vkey = _sc_vkey( view, i ) @conf[vkey] = value unless @conf[vkey] end end # configuration add_conf_proc( Search_control_prefix, Search_control_plugin_name ) do # receive the configurations from the form if 'saveconf' == @mode then # setting changes if @cgi.params[_sc_nkey][0] then @conf[_sc_nkey] = @cgi.params[_sc_nkey][0].to_i end (0...@conf[_sc_nkey]).each do |i| if i > 0 and @cgi.params[_sc_akey( i )][0] then agent = @cgi.params[_sc_akey( i )][0].strip unless agent.empty? then @conf[_sc_akey( i )] = agent end end _sc_each_vkey( i ) do |vkey| if 't' == @cgi.params[vkey][0] then @conf[vkey] = 't' else @conf[vkey] = 'f' end end end # deleted agents (@conf[_sc_nkey] - 1).downto( 1 ) do |i| if 't' == @cgi.params[_sc_delkey( i )][0] then (i...(@conf[_sc_nkey] - 1)).each do |j| @conf[_sc_akey( j )] = @conf[_sc_akey( j+1 )] _sc_each_view do |view| @conf[_sc_vkey( view, j ) ] = @conf[_sc_vkey( view, j+1 ) ] end end @conf[_sc_nkey] -= 1 @conf.delete( _sc_akey( @conf[_sc_nkey] ) ) _sc_each_vkey( @conf[_sc_nkey] ) do |vkey| @conf.delete( vkey ) end end end # new agent newagent = @cgi.params[_sc_newkey] ? @cgi.params[_sc_newkey][0].strip : nil if newagent and not newagent.empty? then @conf[_sc_akey( @conf[_sc_nkey] )] = newagent Search_control_defaults[0].each_pair do |view, value| @conf[_sc_vkey( view, @conf[_sc_nkey] )] = value end @conf[_sc_nkey] += 1 end end # show the HTML r = Search_control_description_html + "
      \n" r << %Q|
    • #{Search_control_new_label}\n| (@conf[_sc_nkey] - 1).downto( 1 ) do |i| r << %Q|
    • \n| name = "#{_sc_delkey( i )}" r << %Q|\n| r << "
        \n" Search_control_categories.each do |c| label = c[0] view = c[1] checked = 't' == @conf[_sc_vkey( view, i )] ? ' checked' : '' name = "#{_sc_vkey( view, i )}" r << %Q|
      • \n| end r << "
      \n" end r << %Q|
    • #{Search_control_default_label}\n| r << "
        \n" Search_control_categories.each do |c| label = c[0] view = c[1] checked = 't' == @conf[_sc_vkey( view, 0 )] ? ' checked' : '' name = "#{_sc_vkey( view, 0 )}" r << %Q|
      • \n| end r << "
      \n
    \n" r << %Q|| end add_header_proc do # agent number = '' # default agent if @cgi.user_agent then (1...@conf[_sc_nkey]).each do |i| if @cgi.user_agent.include?( @conf[_sc_akey( i )] ) then number = i.to_s break end end end # view view = '' follow = 'follow' if /^(latest|day|month|nyear)$/ =~ @mode then view = @mode elsif /^category/ =~ @mode then view = 'category' follow = 'nofollow' end # output sw = @conf[_sc_vkey( view, number )] if sw then %Q|\t\n| else '' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/search_form.rb000066400000000000000000000024331362645730700210250ustar00rootroot00000000000000# search_form.rb # # Show a form for search engines. # # Copyright (c) 2002 MUTOH Masao # Distributed under the same license terms as tDiary. # add_header_proc do @extract_search_keyword = '' if @cgi.referer then begin setup = DispRef2Setup::new( @conf, 1, true, nil, @mode ) disp_url = DispRef2URL::new( @cgi.referer ) disp_url.parse( setup ) if disp_url.category == :search then @extract_search_keyword = disp_url.key end rescue NameError end end '' end def extract_search_keyword h @extract_search_keyword end def search_form(url, query, button_name = "Search", size = 20, default_text = "", first_form = "", last_form = "") default_text = @extract_search_keyword if default_text.empty? %Q[ ] end def namazu_form( url, button_name = "Search", size = 20, default_text = "" ) search_form( url, "query", button_name, size, default_text ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/sn.rb000066400000000000000000000050111362645730700171500ustar00rootroot00000000000000=begin = 連番生成プラグイン sn.rb == 概要 各日付の日記内で通し番号を表示します。 == 使い方 sn( number ) number - 内部カウンタを指定した値にセットします。 sn_anchorid sn()メソッドは日記の各日付ごとに、1から始まる通し番号を表示します。 sn_anchorid()メソッドは現在のアンカーidの番号を表示します。 sn_anchorid()を設定オプション内のセクション/ツッコミアンカー として指定することによって,そのセクション/ツッコミアンカーの URLと結び付いた数値を表示することができます。 == 参考 anchor()はzoe氏作のnumber_anchor.rbを参考に作成しました。 = Sequential number generator plugin == Abstract Display sequential numbers for every date. == Usage sn( number ) number - Set the value of the internal counter to 'number'. sn_anchorid The sn() method displays sequential numbers starting at 1 for every date. The sn_anchorid() method displays a current number of the anchorid. If you use sn_anchorid() as a section/comment anchor in the setup option, you can display the number relevant to URL of the section/comment anchor. == reference Original anchor() appeared in the number_anchor.rb by zoe-san. == 著作権について (Copyright notice) Copyright (c) 2003 SAKAMOTO Hideki Distributed under the GPL2 or any later version. =end =begin Changelog 2003-09-23 SAKAMOTO Hideki * document corrected 2003-09-17 SAKAMOTO Hideki * add add_body_leave_proc 2003-09-13 SAKAMOTO Hideki * change @sn_section initialization: nil -> 0 * delete @sn_section clear line in sn() * add sn_anchorid method 2003-09-10 SAKAMOTO Hideki * write English document * force to use anchor-id in section anchor * delete 'sn.use_anchorid' option 2003-08-29 SAKAMOTO Hideki * first version =end add_body_enter_proc do |date| @sn_count = 1 @sn_idx = 0 "" end add_body_leave_proc do |date| @sn_count = 1 @sn_idx = 0 "" end alias :_orig_anchor_sn :anchor def anchor( s ) if /^(\d+)#?([pct])?(\d*)?$/ =~ s then if $2 then @sn_idx = $3.to_i end end _orig_anchor_sn(s) end def sn( number = nil ) if number then @sn_count = number.to_i else number = @sn_count end @sn_count += 1 %Q[#{'%d' % number}] end def sn_anchorid %Q[#{'%d' % @sn_idx}] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/speed_comment.rb000066400000000000000000000045571362645730700213700ustar00rootroot00000000000000# speed_comment.rb # # spped_comment: 最新・月毎表示時に簡易なツッコミフォームを表示する # pluginディレクトリに入れるだけで動きます。 # # Copyright (c) 2002 TADA Tadashi # Distributed under the GPL2 or any later version. # =begin ChangeLog 2003-09-24 TADA Tadashi * support cookie for name. * support conf_proc. 2002-03-24 TADA Tadashi * suppress output in mobile mode. 2002-03-12 TADA Tadashi * support insert into @header. =end add_body_leave_proc do |date| if /latest|month/ =~ @mode @conf['speed_comment.name_size'] = 20 unless @conf['speed_comment.name_size'] @conf['speed_comment.body_size'] = 40 unless @conf['speed_comment.body_size'] r = "" r << %Q[

    ] r << %Q[] r << %Q[] r << %Q[#{h( comment_name_label )} : ] r << %Q[#{h( comment_body_label )} : ] r << %Q[] r << %Q[

    ] else '' end end unless @resource_loaded then def speed_comment_label '簡易ツッコミ' end def speed_comment_html <<-HTML

    簡易ツッコミフォームのサイズ

    名前欄:

    本文欄:

    HTML end end add_conf_proc( 'speed_comment', speed_comment_label ) do if @mode == 'saveconf' then @conf['speed_comment.name_size'] = @cgi.params['speed_comment.name_size'][0].to_i @conf['speed_comment.name_size'] = 20 if @conf['speed_comment.name_size'] < 1 @conf['speed_comment.body_size'] = @cgi.params['speed_comment.body_size'][0].to_i @conf['speed_comment.body_size'] = 40 if @conf['speed_comment.body_size'] < 1 end speed_comment_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/src.rb000066400000000000000000000010511362645730700173170ustar00rootroot00000000000000# src.rb # # src: 外部ファイルを挿入する(HTMLエスケープ付き) # パラメタ: # file: ファイル名 # # Copyright (c) 2005 TADA Tadashi # You can distribute this file under the GPL2 or any later version. # def src( file ) h( File::readlines( file ).join ) end # # src_inline: テキストを挿入する(HTMLエスケープ付き) # # パラメタ: テキスト文字列 # def src_inline( str ) h( str ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/tb-show.rb000066400000000000000000000150171362645730700201220ustar00rootroot00000000000000# tb-show.rb # # functions: # * show TrackBack ping URL in right of TSUKKOMI label. # * hide TrackBacks in TSUKKOMI. # * show TrackBacks above Today's Links. # # options: # @options['tb.cgi']: # the TrackBack ping URL. './tb.rb' is default. # @options['tb.hide_if_no_tb']: # If true, hide 'TrackBacks(n)' when there is no TrackBacks. Default value is false. # # Copyright (c) 2003 TADA Tadashi # You can distribute this file under the GPL2 or any later version. # # Modified: by Junichiro Kita # # # If you want to show TrackBack Ping URL under comment_new link, try this. # # alias :comment_new_tb_backup :comment_new # def comment_new # cgi = @options['tb.cgi'] || './tb.rb' # url = "#{cgi}/#{@tb_date.strftime( '%Y%m%d' )}" # %Q|#{comment_new_tb_backup }]
    [TrackBack to #{@tb_url}| # end # # # show TrackBack ping URL # add_body_enter_proc do |date| cgi = File.basename(@options['tb.cgi'] || './tb.rb') @tb_date = date @tb_id_url = %Q|#{@index}#{anchor( @tb_date.strftime('%Y%m%d') )}| @tb_id_url[0, 0] = base_url if %r|^https?://|i !~ @conf.index @tb_id_url.gsub!( %r|/\./|, '/' ) @tb_url = %Q|#{base_url}#{cgi}/#{@tb_date.strftime('%Y%m%d')}| '' end # # make RDF # if @mode == 'day' and not bot? then add_body_leave_proc do |date| if @tb_url and @diaries[@tb_date.strftime('%Y%m%d')] then <<-TBRDF TBRDF else '' end end end # # hide TrackBacks in TSUKKOMI # eval( <TrackBack#{'s' if count > 1}(#{count})| unless count == 0 and @conf['tb.hide_if_no_tb'] end r end def trackbacks_of_today_short( diary, limit = @conf['trackback_limit'] || 3 ) is_blog_style = !@plugin_files.grep(/blog_style.rb\z/).empty? return unless is_blog_style || !diary.nil? && (@conf['trackback_shortview_mode'] == "shortlist" || @conf['trackback_disp_pingurl']) fragment = 't%02d' today = anchor( diary.date.strftime( '%Y%m%d' ) ) count = 0 diary.each_visible_trackback( -1 ) {|t,count|} # count up r = '' r << %Q!\t
    \n! r << %Q!\t\t
    \n! r << %Q!\t\t\t#{trackback_today}#{trackback_total( count )}\n! if count > 0 && (is_blog_style || @conf['trackback_shortview_mode'] == "shortlist") r << %Q!\t\t
    \n! return r << %Q!\t
    \n! unless is_blog_style || @conf['trackback_shortview_mode'] == "shortlist" r << %Q!\t\t
    \n! r << %Q!\t\t\t

    Before...

    \n! if count > limit diary.each_visible_trackback_tail( limit ) do |t,i| url, name, title, excerpt = t.body.split( /\n/,4 ) a = name || url a += ':' + title if title &&! title.empty? r << %Q!\t\t\t

    \n! r << %Q!\t\t\t\t#{@conf['trackback_anchor']}\n! r << %Q!\t\t\t\t#{h a}\n! r << %Q!\t\t\t\t#{h @conf.shorten( excerpt, @conf.comment_length )} \n! if excerpt r << %Q!\t\t\t

    \n! end r << %Q!\t\t
    \n! r << %Q!\t
    \n! r end def trackbacks_of_today_long( diary, limit = -1 ) count = 0 diary.each_visible_trackback( limit ) {|t,count|} # count up fragment = 't%02d' today = anchor( @date.strftime( '%Y%m%d' ) ) r = '' r << %Q!\t
    \n! r << %Q!\t\t
    \n! r << %Q!\t\t\t#{trackback_today}#{trackback_total( count )}\n! if count > 0 r << %Q!\t\t
    \n! r << %Q!\t\t
    \n! diary.each_visible_trackback( limit ) do |t,i| url, name, title, excerpt = t.body.split( /\n/,4 ) a = (name and name.length > 0) ? name : url a += ':' + title if title &&! title.empty? f = fragment % i excerpt = excerpt || '' if excerpt.length > 255 excerpt = @conf.shorten( excerpt, 252 ) end r << %Q!\t\t\t
    \n! r << %Q!\t\t\t\t#{@conf['trackback_anchor']}\n! if bot? then r << %Q!\t\t\t\t#{h a}\n! else r << %Q!\t\t\t\t#{h a}\n! end r << %Q!\t\t\t\t#{comment_date( t.date )}\n! r << %Q!\t\t\t
    \n! r << %Q!\t\t\t

    #{h( excerpt ).strip.gsub( /\n/,'
    ')}

    \n! if excerpt end r << %Q!\t\t
    \n! r << %Q!\t
    \n! r end # configurations @conf['trackback_anchor'] ||= @conf.comment_anchor @conf['trackback_limit'] ||= @conf.comment_limit add_conf_proc( 'tb-show', 'TrackBack', 'tsukkomi' ) do if @mode == 'saveconf' then @conf['trackback_anchor'] = @conf.to_native( @cgi.params['trackback_anchor'][0] ) @conf['trackback_shortview_mode'] = @cgi.params['trackback_shortview_mode'][0] if @conf['trackback_shortview_mode'] == "num_in_reflist_if_exists" @conf['tb.hide_if_no_tb'] = true @conf['trackback_shortview_mode'] = "num_in_reflist" elsif @conf['trackback_shortview_mode'] == "num_in_reflist" @conf['tb.hide_if_no_tb'] = false end @conf['trackback_limit'] = @cgi.params['trackback_limit'][0].to_i @conf['trackback_limit'] = 3 if @conf['trackback_limit'] < 1 @conf['trackback_disp_pingurl'] = @cgi.params['trackback_disp_pingurl'][0] == "true" ? true : false end tb_show_conf_html end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/theme_online.rb000066400000000000000000000016471362645730700212110ustar00rootroot00000000000000# theme_online.rb: choice theme from online repository on tDiary.org # # options: # @options['theme_online.url']: top level URL of another theme site # # Copyright (C) 2014 by TADA Tadashi # You can distribute and/or modify it under GPL2 or any later version. # require 'json' require 'open-uri' def theme_list_online(list) url = @options['theme_online.url'] || '//tdiary.github.io/tdiary-theme/' url = "http:#{url}" if url =~ %r|\A//| begin online_list = JSON.load(open(File.join(url, 'themes.json'), &:read))['themes'] list + online_list.keys.map do |t| title = online_list[t]['title'] label = t == title ? '' : " (#{title})" ["online/#{t}", "#{t}#{label}"] end rescue @logger.error "could not get theme list from online: #$!" list end end def theme_url_online(theme) url = @options['theme_online.url'] || '//tdiary.github.io/tdiary-theme/' File.join(url, "#{h theme}/#{h theme}.css") end tdiary-core-5.1.1/misc/plugin/title_list.rb000066400000000000000000000026251362645730700207140ustar00rootroot00000000000000# titile_list.rb # # title_list: 現在表示している月のタイトルリストを表示 # パラメタ(カッコ内は未指定時の値): # rev: 逆順表示(false) # # 備考: タイトルリストを日記に埋め込むには、レイアウトを工夫しなければ # なりません。ヘッダやフッタでtableタグを使ったり、CSSを書き換える必 # 要があるでしょう。 # # Copyright (c) 2005 TADA Tadashi # You can distribute this file under the GPL2 or any later version. # def title_list( rev = false ) result = %Q|
      \n| keys = @diaries.keys.sort keys = keys.reverse if rev keys.each do |date| next unless @diaries[date].visible? result << %Q[
    • #{h( @diaries[date].date.strftime( @date_format ) )}\n\t
        \n] if !@plugin_files.grep(/\/category.rb$/).empty? and @diaries[date].categorizable? @diaries[date].each_section do |section| result << %Q[\t
      • #{section.stripped_subtitle_to_html}
      • \n] if section.stripped_subtitle end else @diaries[date].each_section do |section| result << %Q[
      • #{section.subtitle_to_html}
      • \n] if section.subtitle end end result << "\t
      \n
    • \n" end apply_plugin( result << "
    \n" ) end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/title_tag.rb000066400000000000000000000054151362645730700205140ustar00rootroot00000000000000# Copyright (c) 2003 URABE Shyouhei # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this code, to deal in the code without restriction, including without # limitation the rights to use, copy, modify, merge, publish, distribute, # sublicense, and/or sell copies of the code, and to permit persons to whom the # code 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 code. # # THE CODE 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 CODE OR THE USE OR OTHER DEALINGS IN THE # CODE. # title_tag2.rb to enhance element of generating HTML # $Id: title_tag.rb,v 1.6 2008-03-02 09:01:45 kazuhiko Exp $ # To use, just put this file into plugin folder. alias :title_tag2 :title_tag module ::TDiary module Style module BaseDiary def all_subtitles_to_html titles = Array.new each_section do |section| titles << (section.subtitle_to_html || '').strip end return titles end def all_stripped_subtitles_to_html return all_subtitles_to_html unless categorizable? titles = Array.new each_section do |section| titles << (section.stripped_subtitle_to_html || '').strip end return titles end end end end def title_tag if @mode == 'day' and diary = @diaries[@date.strftime('%Y%m%d')] then if !diary.visible? then return title_tag2 end site_title = title_tag2.gsub( /<.*?>/, '') day_title = '' if !diary.title.empty? then day_title << apply_plugin(diary.title, true) << ':' end t2 = '' if @plugin_files.grep(/\/category.*\.rb$/).empty? then t2 << diary.all_subtitles_to_html.delete_if{|s|s.size == 0}.join(', ') else t2 << diary.all_stripped_subtitles_to_html.delete_if{|s|s.size == 0}.join(', ') end sub_part = "#{h day_title} #{@conf.shorten(apply_plugin(t2, true))}" if sub_part.size <= 1 return "<title>#{h( site_title )}" else return "#{sub_part} - #{h( site_title )}" end elsif @mode == 'categoryview' then return @conf.shorten("#{h( @html_title )}#{h( category_title() )}") else return title_tag2 end end # Local Variables: # mode: ruby # code: utf-8 # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # fill-column: 79 # default-justification: full # End: # vi: ts=3 sw=3 tdiary-core-5.1.1/misc/plugin/tlink.rb000066400000000000000000000076121362645730700176620ustar00rootroot00000000000000# tlink.rb # # title 属性付 anchor plugin # # 使い方 # <%= tlink( "URL", "文字列", "title 属性の中身(省略可)" ) %> # # 第 3 パラメータを省略した時、URL の末尾が c#?? ならば、 # そのツッコミの内容が最初の行だけ表示されます。 # 末尾が p#?? ならば、サブタイトルがあればサブタイトルが、 # なければ最初のパラグラフが表示されます。 # # 例. <%= tlink( "http://tdiary.tdiary.net/20020131.html#c01", "このツッコミ" ) %> # 出力結果: # このツッコミ # # Copyright(C) 2002 NT # Distributed under the GPL2 or any later version. # # Modified: by abbey # =begin ChangeLog 2003-03-03 NT * add the function to try regetting a subtitle. 2003-01-29 NT * fix a critical bug. 2003-01-28 NT * correspond to change in movile mode. 2002-11-19 NT * add require 'pstore'. 2002-07-01 NT * change some regular expressions. 2002-05-18 NT * remove "," from %Q[#{str}]. 2002-05-16 MUTOH Masao * cache mechanism support. * code cleanup(remove require 'cgi', getcomment rename to tlink_getcomment). 2002-05-05 NT * add URL to User-Agent 2002-04-21 abbey * add error shori 2002-04-20 NT * change User-Agent * modify some regular expressions 2002-04-19 NT * modify some regular expressions * add User-Agent 2002-04-18 abbey * adapt to port numbers except 80 * adapt to #pXX 2002-04-17 NT * create =end require 'net/http' require 'kconv' require 'pstore' def tlink_initialize dir = @cache_path + "/tlink" @tlink_path = dir + "/tlink.dat" Dir.mkdir(dir, 0700) unless FileTest.exist?(dir) PStore.new(@tlink_path).transaction do |db| if (db.root?('tlinkdata')) then @tlink_dic = db["tlinkdata"] else @tlink_dic = Hash.new end end end def tlink_finalize db = PStore.new(@tlink_path) db.transaction do begin db["tlinkdata"] = @tlink_dic rescue PStore::Error end end end def tlink_getcomment( url ) result = "" ref = base_url agent = { "User-Agent" => "DoCoMo (compatible; tDiary plugin; tlink; #{ref})" } host, path, frag = url.scan( %r[http://(.*?)/(.*)#((?:p|c)\d\d)] )[0] if /p0/ =~ frag frag = "(?:" + frag + "|" + frag.sub( /p/, "p#" ).sub( /#0/, "#" ) + ")" end port = 80 if /(.*):(\d+)/ =~ host host = $1 port = $2 end hata = 0 http = Net::HTTP.new( host, port ) begin http.open_timeout = 3 response , = http.get( "/#{path}", agent ) response.body.each { |line| if %r[(?:.*?) (.*?)] =~ line.toutf8 result = $1 break else hata = 1 end elsif hata == 1 && %r[^\t*(.*?)
    ] =~ line.toutf8 result = $1 hata = 0 break end } rescue result = "" end result = CGI::escapeHTML( result.gsub( %r[], "" ) ).gsub( /&nbsp;/, " " ) end tlink_initialize def tlink( url, str, title = nil ) unless title if @tlink_dic[url] && %r[#(p|c)\d\d$] =~ url && @tlink_dic[url] != '' title = @tlink_dic[url] elsif @tlink_dic[url] && %r[#(p|c)\d\d$] !~ url title = @tlink_dic[url] else if /#{url}/ =~ ENV["REDIRECT_URL"] && /#{url}/ =~ @date.strftime('%Y%m%d') else title = tlink_getcomment( url ) @tlink_dic[url] = title tlink_finalize end end end %Q[#{str}] end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/todo.rb000066400000000000000000000070011362645730700174760ustar00rootroot00000000000000# todo.rb # # todo: show ToDo lists. # # CSS samples for ToDo: # # div.todo { # font-size: 80%; # } # # div.todo-title { # font-weight: bold; # } # # div.todo-body { # } # # span.todo-priority { # font-weight: bold; # } # # span.todo-in-time { # } # # span.todo-today { # color: blue; # } # # span.todo-too-late { # color: red; # font-weight: bold; # } # # Copyright (c) 2001,2002,2003 Junichiro KITA # Distributed under the GPL2 or any later version. # require 'fileutils' require 'time' class ToDo attr_reader :prio, :todo, :limit def initialize(prio, todo, limit, deleted = nil) @prio, @todo, @limit, @deleted = prio, todo, limit, deleted end def deleted? @deleted != "" end def <=>(other) other.prio.to_i <=> @prio.to_i end def to_s r = "#{@deleted}#{@prio}" r << "[#{@limit}]" if @limit r << " #{@todo}" r.sub!(/^\s+/, '') r end end def todo_parse(src) todos = [] src.each do |l| deleted, prio, limit, todo = l.scan(/^(#?)(\d{0,2})(?:\[(.*)\])? *(.+)$/)[0] if (0..99).include? prio.to_i and todo todos.push ToDo.new(prio, todo, limit, deleted) end end if todos.size > 0 todos.sort! end todos end def todo_pretty_print(todos) s = '' s << %Q|
      \n| now = Time.now today = Time.local(now.year, now.month, now.day) todos.each_with_index do |x, idx| break if idx >= @conf['todo.n'] s << "
    • " s << %Q|| if x.deleted? s << %Q|#{if x.prio != '' then '%02d' % x.prio else '' end} #{apply_plugin x.todo}| if x.limit s << "(~#{x.limit}" ymd = Time.parse(x.limit) y = ymd.year m = ymd.month d = ymd.day y = today.year unless y if y and m and d limit = Time.local(y, m, d) diff = ((limit - today)/86400).to_i if diff > 0 s << %Q| #{todo_msg_in_time(diff)}| elsif diff == 0 s << %Q| #{todo_msg_today}| else s << %Q| #{todo_msg_late(diff.abs)}| end end s << ")" end s << %Q|| if x.deleted? s << "
    • \n" end s << %Q|
    \n| end @todos = [] # parsed todos. generated from @conf['todo.todos']. def todo_init @conf['todo.n'] ||= 10 @conf['todo.title'] ||= 'ToDo:' unless @conf['todo.todos'] begin @conf['todo.todos'] = File.readlines(todo_file).join if FileTest::exist?(todo_file) rescue end end @conf['todo.todos'] ||= '' @todos = todo_parse(@conf['todo.todos'].split(/\n/)) end def todo todo_init <

    #{@conf['todo.title']}

    #{todo_pretty_print(@todos)}
  • TODO end def navi_t(name = todo_config_label) %Q|#{name}\n| end # backward compatibility def todo_file if File.exist?( "#{@cache_path}/todo" ) then FileUtils.mv( "#{@cache_path}/todo", "#{@conf.data_path}/todo") end (@options && @options['todo.path'] || @conf.data_path) + "/todo" end # # for conf_proc # def config_options2(op2_key) op2_val = @cgi.params[op2_key][0] if (0 < op2_val.size) @conf[op2_key] = (block_given? ? yield(op2_val) : op2_val) else @conf.delete(op2_key) end end private :config_options2 def saveconf_todo if @mode == 'saveconf' then config_options2('todo.todos') config_options2('todo.title') config_options2('todo.n'){|op2_val| op2_val.to_i} end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/weather.rb000066400000000000000000000411041362645730700201720ustar00rootroot00000000000000=begin = その日の天気プラグイン / Weather-of-today plugin((-$Id: weather.rb,v 1.16 2008-03-02 09:01:45 kazuhiko Exp $-)) Records the weather when the diary is first updated for the date and displays it. その日の天気を、その日の日記を最初に更新する時に取得して保存し、それぞれ の日の日記の上部に表示します。 == Acknowledgements その日の天気プラグインのアイディアを提供してくださったhsbtさん、実装のヒ ントを提供してくださったzoeさんに感謝します。また、NOAAの情報を提供して くださったkotakさんに感謝します。 The author appreciates National Weather Service (()) making such valuable data available in public domain as described in (()). == Copyright Copyright 2003 zunda Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work under the terms of GPL version 2 or later. =end =begin ChangeLog * Mon Jan 14, 2008 SHIBATA Hiroshi - Hide output string in RSS feed. * Mon Sep 29, 2003 zunda - Japanese resources divided into a separate file, English resource created * Thu Jul 24, 2003 zunda - Syntax error in drizzle fixed * Mon Jul 21, 2003 zunda - changed regexp literals from %r|..| to %r[..] for Ruby 1.8.x. * Fri Jul 17, 2003 zunda - WWW configuration interface * Thu Jun 5, 2003 zunda - checks the age of data * Tue Jun 3, 2003 zunda - ignores `... in the vicinity', thank you kosaka-san. - now tests translations if executed as a stand alone script. * Mon May 26, 2003 zunda - fix typo on weaHTer.show_mobile and weHTer.show_error, thank you halchan. * Thu May 8, 2003 zunda - A with B, observed, * Mon May 5, 2003 zunda - mobile agent * Fri Mar 28, 2003 zunda - overcast, Thanks kotak san. * Fri Mar 21, 2003 zunda - mist: kiri -> kasumi, Thanks kotak san. * Sun Mar 16, 2003 zunda - option weather.tz, appropriate handling of timezone * Tue Mar 11, 2003 zunda - records: windchill, winddir with 'direction variable', gusting wind * Mon Mar 10, 2003 zunda - WeatherTranslator module * Sat Mar 8, 2003 zunda - values with units * Fri Mar 7, 2003 zunda - edited to work with NOAA/NWS * Fri Feb 28, 2003 zunda - first draft =end require 'net/http' require 'cgi' require 'timeout' require 'date' # DateTime.strptime =begin == Classes and methods === WeatherParser --- WeatherParser::parse =end =begin === WeatherTranslator module We want Japanese displayed in a diary written in Japanese. --- WeatherTranslator::S < String Extension of String class. It translates itself. --- WeatherTranslator::S.translate( table ) Translates self according to ((|table|)). =end module WeatherTranslator class S < String def translate( table ) return '' if not self or self.empty? table.each do |x| if x[0] =~ self then return S.new( S.new( $` ).translate( table ) + eval( x[1] ) + S.new( $' ).translate( table ) ) end end self end def compact S.new( self.split( /\/+/ ).uniq.join( '/' ) ) end end end =begin === Weather class Weather of a date. --- Weather( date ) A Weather is a weather datum for a ((|date|)) (a Time object). --- Weather.get( url, header, items ) Gets a WWW page from the ((|url|)) providing HTTP header in the ((|header|)) hash. The page is parsed calling Weahter.parse_html. Returns self. --- Weather.parse_html( html, items ) Parses an HTML page ((|html|)) and stores the data into @data according to ((|items|)). --- Weather.to_s Creates a line to be stored into the cache file which will be parsed with Weather.parse method. Data are stored with the following sequence and separated with a tab: date(string), url, acquisition time(UNIX time) timezone, error (or empty string), item, value, ... Each record is terminated with a new line. --- Weather.parse( string ) --- Weather::parse( string ) Parses the ((|string|)) made by Weather.to_s and returns the resulting Weather. --- Weather::date_to_s( date ) Returns ((|date|)) formatted as a String used in to_s method. Used to find a record for the date from a file. --- Weather.to_html( show_error = false ) Returns an HTML fragment for the weather. When show_error is true, returns an error message as an HTML fragment in case an error occured when getting the weather. --- Weather.to_i_html Returns a CHTML fragment for the weather. =end class Weather attr_reader :date, :time, :url, :error, :data, :tz # magic numbers WAITTIME = 10 MAXREDIRECT = 10 AVIATIONWEATHER_STATION_REGEXP = %r|(?:aviationweather.gov/adds/metars/\?.*station_ids=)([A-Z]{4,4})\b| NOAA_STATION_REGEXP = %r|(?:weather.noaa.gov/weather/current/)([A-Z]{4,4})\b| RAW_STATION_REGEXP = %r|\A([A-Z]{4,4})\z| STATION_URL_TEMPLATE = "http://www.aviationweather.gov/adds/metars/?station_ids=%s&std_trans=translated&chk_metars=on&hoursStr=most+recent+only" def Weather::extract_station_id(url) [AVIATIONWEATHER_STATION_REGEXP, NOAA_STATION_REGEXP, RAW_STATION_REGEXP].each do |r| m = r.match(url) return m[1] if m and m[1] end return nil end # edit this method according to the HTML we will get def parse_html( html, items ) htmlitems = Hash.new # weather data is in the 1st table in the HTML from aviationweather.gov table = html.scan( %r[(.*?)]mi ) return if not table or not table[0] or not table[0][0] table[0][0].scan( %r[(.*?)]mi ).collect {|a| a[0]}.each do |row| # *item* -> downcased *value* if %r[(.*?)\s*(.*?)]mi =~ row then item = $1 value = $2 item = item.gsub( /
    /i, '/' ).gsub( /<.*?>/m , '').strip.sub(/:$/, '').downcase value = value.gsub(/\&(nbsp|#160);/, ' ').gsub(/\./, '.').gsub(/\%/, '%').gsub(/\°/, '').gsub( /
    /i, '/' ).gsub( /<.*?>/m , '').strip # unit conversion settings units = [] case item when 'conditions at' # we have to convert the UTC time into UNIX time if /observed\s+(.*)$/ =~ value then value = DateTime.strptime($1, "%H%M %z %d %B %Y").to_time.to_i.to_s else raise StandardError, 'Parse error in "Conditions at"' end when 'visibility' # we want to preserve adjective phrase if possible if /(.+)miles?/i =~ value then htmlitems["#{item}(mile)"] = $1.strip end if /([^\(]+)km/i =~ value then htmlitems["#{item}(km)"] = $1.strip end when 'winds' # we want to preserve adjective phrase if possible %w(MPH knots m/s).each do |unit| speed = value.scan( /([\d.]+)\s*#{unit}/i ).collect { |x| x[0] } htmlitems["wind(#{unit})"] = speed.join(',') end if /([\d.]+)\s*degrees?/i =~ value then htmlitems["wind(deg)"] = $1 end if /from\s+(the\s+)?(\w+)/i =~ value then htmlitems["winddir"] = $2 + ($3 ? " #{$3}" : '') end if /(\(direction variable\))/i =~ value then htmlitems["#{item}dir"] << " #{$1}" end # just have to parse the value with the units when 'temperature' units = ['C', 'F'] when 'windchill' units = ['C', 'F'] when 'dewpoint' units = ['C', 'F'] when 'relative humidity' units = ['%'] when 'pressure (altimeter)' units = ['mb'] # mb (mbar) and hPa results in same number end # parse the value with the units if preferred and possible units.each do |unit| if /(-?[\d.]+)\s*\D?\(?#{unit}\b/i =~ value then number = $1 htmlitems["#{item}(#{unit})"] = number end end # record the value as read from the HTML htmlitems[item] = value end # if %r[(.*?)\s*(.*?)]mi =~ row end # table.scan( %r[(.*?)]mi ) ... do |row| # Obtain weather from Weather: or Clouds: weather = 'Unknown' # e.g.: FG -RA (fog, light rain) if /\((.*)\)/ =~ htmlitems['weather'] then weather = $1.strip # e.g.: few clouds at 3000 feet AGL elsif /(.*?)\s+at/ =~ htmlitems['clouds'] then weather = $1.strip end # Weather seemed to have been slash divided capitalized string htmlitems['weather'] = weather.split(/,\s*/).map{|e| e.strip.capitalize}.join('/') # translate the parsed HTML into the Weather hash with more generic key items.each do |from, to| if htmlitems[from] then # as specified in items @data[to] = htmlitems[from] elsif f = from.dup.sub!( /\([^)]+\)$/, '' ) \ and htmlitems[f] \ and t = to.dup.sub!( /\([^)]+\)$/, '' ) then # remove the units and try again if not found @data[t] = htmlitems[f] end end @time = Time::now end # check age of data def check_age( oldest_sec = nil ) if oldest_sec and @time and @data['timestamp'] and @data['timestamp'].to_i + oldest_sec < @time.to_i then @error = 'data too old' end end def initialize( date = nil, tz = nil, conf = nil ) @conf = conf @date = date or Time.now @data = Hash.new @error = nil @url = nil if tz and not tz.empty? then @tz = tz elsif ENV['TZ'] @tz = ENV['TZ'] else @tz = nil end end def fetch( url, limit, header ) raise ArgumentError, 'HTTP redirect too deep' if limit == 0 px_host, px_port = (@conf['proxy'] || '').split( /:/ ) px_port = 80 if px_host and !px_port u = URI::parse( url ) Net::HTTP::Proxy( px_host, px_port ).start( u.host, u.port ) do |http| case res = http.get( u.request_uri, header ) when Net::HTTPSuccess res.body when Net::HTTPRedirection fetch( res['location'], limit - 1 ) else raise ArgumentError, res.error! end end end def get( url, header = {}, items = {} ) @url = url.gsub(/[\t\n]/, '') @error = nil begin Timeout::timeout( WAITTIME ) do d = @conf.to_native( fetch( url, MAXREDIRECT, header ) ) parse_html( d, items ) end rescue Timeout::Error @error = 'Timeout' rescue @error = @conf.to_native( $!.message.gsub( /[\t\n]/, ' ' ) ) end self end def to_s tzstr = @tz ? " #{tz}" : '' r = "#{Weather::date_to_s( @date )}\t#{@url}\t#{@time.to_i}#{tzstr}\t#{@error}" @data.each do |item, value| r << "\t#{item}\t#{value}" if value and not value.empty? end r << "\n" end def parse( string ) i = string.chomp.split( /\t/ ) y, m, d = i.shift.scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] @date = Time::local( y, m, d ) @url = i.shift itime, @tz = i.shift.split( / +/, 2 ) @time = Time::at( itime.to_i ) error = i.shift if error and not error.empty? then @error = error else @error = nil end @data.clear while not i.empty? do @data[i.shift] = i.shift end self end def to_html( show_error = false ) @error ? (show_error ? error_html_string : '') : html_string end def to_i_html @error ? '' : i_html_string end def store( path, date ) ddir = File.dirname( Weather::file_path( path, date ) ) # mkdir_p logic copied from fileutils.rb # Copyright (c) 2000,2001 Minero Aoki # and edited (zunda.freeshell.org does not have fileutils.rb T_T dirstack = [] until FileTest.directory?( ddir ) do dirstack.push( ddir ) ddir = File.dirname( ddir ) end dirstack.reverse_each do |dir| Dir.mkdir dir end # finally we can write a file File::open( Weather::file_path( path, date ), 'a' ) do |fh| fh.puts( to_s ) end end class << self def parse( string ) new.parse( string ) end def date_to_s( date ) date.strftime( '%Y%m%d' ) end def file_path( path, date ) date.strftime( "#{path}/%Y/%Y%m.weather" ).gsub( /\/\/+/, '/' ) end def restore( path, date ) r = nil datestring = Weather::date_to_s( date ) begin File::open( file_path( path, date ), 'r' ) do |fh| fh.each( "\n" ) do |l| if /^#{datestring}\t/ =~ l then r = l # will use the last/newest data found in the file end end end rescue Errno::ENOENT end r ? Weather::parse( r ) : nil end end end =begin === Methods as a plugin weather method also can be used as a usual plug-in in your diary body. Please note that the argument is not a String but a Time object. --- weather( date = nil ) Returns an HTML flagment of the weather for the date. This will be provoked as a body_enter_proc. @date is used when ((|date|)) is nil. --- get_weather Access the URL to get the current weather information when: * @mode is append or replace, * @date is today, and * There is no cached data without an error for today This will be provoked as an update_proc. =end Weather_default_path = "#{@cache_path}/weather" Weather_default_items = { # UNIX time 'conditions at' => 'timestamp', # English phrases 'sky conditions' => 'condition', 'weather' => 'weather', # Direction (e.g. SE) 'winddir' => 'winddir', # English phrases when unit conversion failed, otherwise, key with (unit) 'wind(m/s)' => 'wind(m/s)', 'wind(deg)' => 'wind(deg)', 'visibility(km)' => 'visibility(km)', 'temperature(C)' => 'temperature(C)', 'windchill(C)' => 'windchill(C)', 'dewpoint(C)' => 'dewpoint(C)', 'relative humidity(%)' => 'humidity(%)', 'pressure (altimeter)(mb)' => 'pressure(hPa)', } # shows weather def weather( date = nil, wrap = true ) return '' if bot? and not @options['weather.show_robot'] path = @options['weather.dir'] || Weather_default_path w = Weather::restore( path, date || @date ) if w then %Q|#{wrap ? '
    ' : ' '}#{w.to_html( @options['weather.show_error'] )}#{wrap ? "
    \n" : ''}| else '' end end # gets weather when the diary is updated def get_weather return unless @options['weather.url'] return unless @mode == 'append' or @mode == 'replace' return unless @date.strftime( '%Y%m%d' ) == Time::now.strftime( '%Y%m%d' ) path = @options['weather.dir'] || Weather_default_path w = Weather::restore( path, @date ) if not w or w.error then items = @options['weather.items'] || Weather_default_items update_weather_url( @options ) w = Weather.new( @date, @options['weather.tz'], @conf ) w.get( @options['weather.url'], @options['weather.header'] || {}, items ) if @options.has_key?( 'weather.oldest' ) then oldest = @options['weather.oldest'] else oldest = 21600 end w.check_age( oldest ) w.store( path, @date ) end end # Update URL of weather information # # Around April, 2012, NOAA chnaged the URL of the current weather from # http://weather.noaa.gov/weather/current/#{station_id}.html # to # http://www.aviationweather.gov/adds/metars/?station_ids=#{station_id}&std_trans=translated&chk_metars=on&hoursStr=most+recent+only def update_weather_url( hash ) if hash['weather.url'] and match = hash['weather.url'].scan(%r[\Ahttp://weather.noaa.gov/weather/current/(\w{4,4}).html\z])[0] hash['weather.url'] = Weather::STATION_URL_TEMPLATE % match[0] end end # www configuration interface def configure_weather if( @mode == 'saveconf' ) then # weather.url station = Weather::extract_station_id( @cgi.params['weather.url'][0] ) if station @conf['weather.url'] = Weather::STATION_URL_TEMPLATE % station else @conf['weather.url'] = @cgi.params['weather.url'][0] end # weather.tz tz = @cgi.params['weather.tz'][0] unless tz.empty? then # need more checks @conf['weather.tz'] = tz else @conf['weather.tz'] = '' end %w(in_title show_mobile show_robot).each do |item| case @cgi.params["weather.#{item}"][0] when 'true' @conf["weather.#{item}"] = true when 'false' @conf["weather.#{item}"] = false end end end update_weather_url( @conf ) weather_configure_html( @conf ) end add_header_proc do <<"_END" \t _END end if not feed? and not @options['weather.in_title'] then add_body_enter_proc do |date| weather( date ) end end if not feed? and @options['weather.in_title'] then add_title_proc do |date, title| title + weather( date, false ) end end add_update_proc do get_weather end add_conf_proc( 'weather', @weather_plugin_name ) do configure_weather end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/whatsnew.rb000066400000000000000000000060121362645730700203720ustar00rootroot00000000000000# whatsnew.rb # # 名称: # What's Newプラグイン # # 概要: # 未読のセクションに指定したマークをつけることができます. # # 使い方: # tdiary.conf の @section_anchor の先頭に以下のように <%= whats_new %> を追加します. # # @section_anchor = '<%= whats_new %>_' # # セクションの未読/既読によって <%= whats_new %> の部分があらかじめ指 # 定したマークで置き換えられます.デフォルトでは未読セクションでは # "!!!NEW!!!",既読セクションでは "" に展開されます. # # 注:Revision が 1.1 の whats_new.rb の説明では, の中に # <%= whats_new %> を含めるように書いていましたが,sanchorで画像を # 表示するようなテーマでは,whats_new の出力と sanchor の画像が重 # なってしまうという問題がありました. # この変更に伴い,既読時のデフォルトは '' に変更しました. # # 置き換えられる文字列を変更したい場合は tdiary.conf 中で # # @options['whats_new.new_mark'] = 'NEW!' # @options['whats_new.read_mark'] = '既' # # のように指定します. # # Copyright (c) 2002 Junichiro KITA # Distributed under the GPL2 or any later version. # @whats_new = {} def whats_new return apply_plugin( @whats_new[:read_mark] ) unless @cgi @whats_new[:section] += 1 t = @whats_new[:current_date] + "%03d" % @whats_new[:section] if t > @whats_new[:this_time] @whats_new[:this_time] = t end # 初回もしくは cookie を使わない設定の場合は機能しない return apply_plugin( @whats_new[:read_mark] ) if @whats_new[:last_time] == "00000000000" if t > @whats_new[:last_time] apply_plugin( @whats_new[:new_mark] ) else apply_plugin( @whats_new[:read_mark] ) end end add_body_enter_proc do |date| if @cgi @whats_new[:current_date] = Time::at(date).strftime('%Y%m%d') @whats_new[:section] = 0 @whats_new[:last_time] end "" end add_header_proc do if @cgi if @cgi.cookies['tdiary_whats_new'][0] @whats_new[:this_time] = @whats_new[:last_time] = @cgi.cookies['tdiary_whats_new'][0] else # 初めて,もしくは cookie は使わない設定 @whats_new[:this_time] = @whats_new[:last_time] = "00000000000" end @whats_new[:new_mark] = @options['whats_new.new_mark'] || '!!!new!!!' @whats_new[:read_mark] = @options['whats_new.read_mark'] || '' end "" end add_footer_proc do if @cgi.script_name if @whats_new[:this_time] > @whats_new[:last_time] cookie_path = File::dirname(@cgi.script_name) cookie_path += '/' if cookie_path !~ /\/$/ cookie = CGI::Cookie::new({ 'name' => 'tdiary_whats_new', 'value' => [@whats_new[:this_time]], 'path' => cookie_path, 'expires' => Time::now.gmtime + 90*24*60*60 }) add_cookie(cookie) end end "" end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/misc/plugin/xmlrpc.rb000066400000000000000000000056631362645730700200520ustar00rootroot00000000000000# xmlrpc.rb # # XML-RPC API # # Copyright (c) 2004 MoonWolf # Distributed under the GPL2 or any later version. # add_header_proc do %Q!\t\n! end add_conf_proc('XMLRPC', 'XML-RPC API') do saveconf_xmlrpc xmlrpc_init <<-HTML

    #{label_xmlrpc_url}

    #{label_xmlrpc_blogid}

    #{label_xmlrpc_username}

    #{label_xmlrpc_password}

    #{label_xmlrpc_lastname}

    #{label_xmlrpc_firstname}

    #{label_xmlrpc_userid}

    HTML end # # for conf_proc # def xmlrpc_init @conf['xmlrpc.url'] ||= base_url + 'xmlrpc.rb' @conf['xmlrpc.blogid'] ||= 'devlog' @conf['xmlrpc.username'] ||= 'default' @conf['xmlrpc.password'] ||= '' @conf['xmlrpc.lastname'] ||= '' @conf['xmlrpc.firstname'] ||= 'default' @conf['xmlrpc.userid'] ||= 'default' end def saveconf_xmlrpc if @mode == 'saveconf' then @conf['xmlrpc.url'] = @cgi.params['xmlrpc.url'][0] || 'xmlrpc.rb' @conf['xmlrpc.blogid'] = @cgi.params['xmlrpc.blogid'][0] || 'default' @conf['xmlrpc.username'] = @cgi.params['xmlrpc.username'][0] || 'default' @conf['xmlrpc.password'] = @cgi.params['xmlrpc.password'][0] || '' @conf['xmlrpc.lastname'] = @cgi.params['xmlrpc.lastname'][0] || '' @conf['xmlrpc.firstname'] = @cgi.params['xmlrpc.firstname'][0] || 'default' @conf['xmlrpc.userid'] = @cgi.params['xmlrpc.userid'][0] || 'default' open('rsd.xml','w') {|f| f.write <<-EOS tDiary http://www.tdiary.org/ #{h base_url} EOS } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/plugin/xmlrpc/000077500000000000000000000000001362645730700175135ustar00rootroot00000000000000tdiary-core-5.1.1/misc/plugin/xmlrpc/README000066400000000000000000000022761362645730700204020ustar00rootroot00000000000000!機能 blogger API/metaWeblog API/MovableType APIでのtDiaryの更新ができます。 !インストール方法 xmlrpc.rb,ja/xmlrpc.rb,en/xmlrpc.rb,zh/xmlrpc.rbをpluginディレクトリにコピーします。 xmlrpc/xmlrpc.rbをtDiaryのインストールされているディレクトリ(index.rbなどと同じディレクトリ)にコピーします。xmlrpc.rbのパーミッションは、755などに変更する必要があります。 index.rbを設置したディレクトリにrsd.xmlというファイルを作成し、CGIから書き換えられるように書き込み権限を設定します。 !使用方法 設定画面から'XML-RPC API'を選択してXML-RPC APIの設定を行いOKボタンをクリックします。 あとはblogger API/metaWeblog API/MovableType APIに対応したツールからアクセスします。 たとえばubicast BloggerだとXMl-RPCエンドポイントという設定にはxmlrpc.rbのURLを指定します。 (MovableTypeの場合) http:////mt-xmlrpc.cgi (xmlrpc.rbの場合) http:////xmlrpc.rb rsd.xmlに対応したクライアントならサイトのトップページのURLを指定すればOKです。 tdiary-core-5.1.1/misc/plugin/xmlrpc/xmlrpc.rb000077500000000000000000000443311362645730700213550ustar00rootroot00000000000000#!/usr/bin/env ruby # xmlrpc.rb # # Copyright (c) 2004 MoonWolf # Distributed under the GPL2 or any later version. # BEGIN { $stdout.binmode } if FileTest::symlink?( __FILE__ ) then org_path = File::dirname( File::readlink( __FILE__ ) ) else org_path = File::dirname( __FILE__ ) end $:.unshift org_path require 'tdiary' require 'uri' require 'xmlrpc/server' if defined?(MOD_RUBY) server = XMLRPC::ModRubyServer.new else server = XMLRPC::CGIServer.new end include TDiary::ViewHelper @cgi = CGI::new @conf = ::TDiary::Config::new(@cgi) server.add_handler('blogger.newPost') do |appkey, blogid, username, password, content, publish| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s if username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] begin postid = Time.now.strftime("%Y%m%d") year, month, day = postid.scan(/(\d{4})(\d\d)(\d\d)/)[0] @cgi.params['date'] = [postid] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] || tdiary.instance_variable_get(:@io).diary_factory(time, '', '', @conf.style) title,body = content.split(/\n/,2) index = diary.add_section(title, body) src = diary.to_src @cgi.params.delete 'date' @cgi.params['old'] = [postid] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) postid + "%02d" % index rescue ::TDiary::ForceRedirect postid + "%02d" % index end else raise XMLRPC::FaultException.new(1,'userid or password incorrect') end end server.add_handler('blogger.editPost') do |appkey, postid, username, password, content, publish| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end begin @cgi.params['date'] = [postid[0,8]] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] src = '' i = 0 diary.each_section {|sec| i += 1 if i==index subtitle,body = content.split(/\n/,2) sec.subtitle = subtitle sec.body = (body || '').sub(/[\n\r]+\Z/, '') + "\n\n" end src << sec.to_src } @cgi.params.delete 'date' @cgi.params['old'] = [postid[0,8]] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) true rescue ::TDiary::ForceRedirect true rescue Exception raise XMLRPC::FaultException.new(1,$!.to_s + "\n" + $!.backtrace.join("\n")) end end server.add_handler('blogger.deletePost') do |appkey, postid, username, password| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end begin year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i @cgi.params['date'] = [postid[0,8]] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] diary.delete_section(index) src = diary.to_src @cgi.params.delete 'date' @cgi.params['old'] = [postid[0,8]] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) true rescue ::TDiary::ForceRedirect true rescue Exception raise XMLRPC::FaultException.new(1,$!.to_s + "\n" + $!.backtrace.join("\n")) end end server.add_handler('blogger.getRecentPosts') do |appkey, blogid, username, password, numberOfPosts| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end result = [] @cgi.params['title'] = [''] @cgi.params['body'] = [''] @cgi.params['hide'] = ['true'] @conf.latest_limit = numberOfPosts tdiary = ::TDiary::TDiaryLatest::new( @cgi, 'latest.rhtml', @conf ) tdiary.latest(numberOfPosts) {|diary| index = 0 diary.each_section {|sec| index += 1 postid = diary.date.strftime('%Y%m%d') + "%02d" % index author = sec.author || @conf['xmlrpc.userid'] body = sec.subtitle + "\n" + sec.body result << { 'postid' => postid, 'userid' => author, 'content' => body, 'dateCreated' => diary.last_modified.utc } } } result.sort {|a,b| b['postid']<=>a['postid'] }[0,numberOfPosts] end server.add_handler('blogger.getUsersBlogs') do |appkey, username, password| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end result = [ { 'blogid' => @conf['xmlrpc.blogid'], 'blogName' => @conf.html_title, 'url' => base_url } ] result end server.add_handler('blogger.getUserInfo') do |appkey, username, password| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end result = { 'nickname' => @conf.author_name, 'email' => @conf.author_mail, 'url' => base_url, 'lastname' => @conf['xmlrpc.lastname'], 'firstname' => @conf['xmlrpc.firstname'], 'userid' => @conf['xmlrpc.userid'] } result end server.add_handler('metaWeblog.newPost') do |blogid, username, password, content, publish| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end begin postid = Time.now.strftime("%Y%m%d") year, month, day = postid.scan(/(\d{4})(\d\d)(\d\d)/)[0] @cgi.params['date'] = [postid] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] || tdiary.instance_variable_get(:@io).diary_factory(time, '', '', @conf.style) index = diary.add_section(content['title'], content['description']) src = diary.to_src @cgi.params.delete 'date' @cgi.params['old'] = [postid] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) postid + "%02d" % index rescue ::TDiary::ForceRedirect postid + "%02d" % index end end server.add_handler('metaWeblog.editPost') do |postid, username, password, content, publish| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end begin @cgi.params['date'] = [postid[0,8]] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] src = '' i = 0 diary.each_section {|sec| i += 1 if i==index sec.subtitle = content['title'] sec.body = content['description'] || ''.sub(/[\n\r]+\Z/, '') + "\n\n" end src << sec.to_src } @cgi.params.delete 'date' @cgi.params['old'] = [postid[0,8]] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) true rescue ::TDiary::ForceRedirect true rescue Exception raise XMLRPC::FaultException.new(1,$!.to_s + "\n" + $!.backtrace.join("\n")) end end server.add_handler('metaWeblog.getPost') do |postid, username, password| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end @cgi.params['date'] = [postid[0,8]] tdiary = TDiary::TDiaryDay::new( @cgi, 'day.rhtml', @conf ) year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i date = Time::local( year, month, day ) + 12*60*60 diary = tdiary[date] i = 0 result = {} diary.each_section {|sec| i += 1 if i==index link = base_url + @conf.index.sub(%r|^\./|, '') + diary.date.strftime('%Y%m%d') + ".html\#p%02d" % i title = sec.stripped_subtitle || '' body = sec.body result = { 'userid' => @conf['xmlrpc.userid'], 'dateCreated' => diary.last_modified.utc, 'postid' => postid, 'description' => body, 'title' => title, 'link' => link, 'permaLink' => link, 'mt_excerpt' => '', 'mt_text_mode' => '', 'mt_allow_comments' => 1, 'mt_allow_pings' => 1, 'mt_convert_breaks' => '__default__', 'mt_keyword' => '' } break end } result end server.add_handler('metaWeblog.getRecentPosts') do |blogid, username, password, numberOfPosts| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end result = [] @cgi.params['title'] = [''] @cgi.params['body'] = [''] @cgi.params['hide'] = ['true'] @conf.latest_limit = numberOfPosts tdiary = ::TDiary::TDiaryLatest::new( @cgi, 'latest.rhtml', @conf ) tdiary.latest(numberOfPosts) {|diary| index = 0 diary.each_section {|sec| index += 1 postid = diary.date.strftime('%Y%m%d') + "%02d" % index link = base_url + @conf.index.sub(%r|^\./|, '') + diary.date.strftime('%Y%m%d') + ".html\#p%02d" % index title = sec.stripped_subtitle || '' body = sec.body author = sec.author || @conf['xmlrpc.userid'] result << { 'dateCreated' => diary.last_modified.utc, 'userid' => author, 'postid' => postid, 'description' => body, 'title' => title, 'link' => link, 'permaLink' => link, 'mt_excerpt' => '', 'mt_text_more' => '', 'mt_allow_comments' => 1, 'mt_allow_pings' => 1, 'mt_convert_breaks' => '__default__', 'mt_keywords' => '', } } } result.sort {|a,b| b['postid']<=>a['postid'] }[0,numberOfPosts] end server.add_handler('metaWeblog.newMediaObject') do |blogid, username, password, file| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end image_dir = @conf['image.dir'] || './images/' image_dir.chop! if /\/$/ =~ image_dir image_url = @conf['image.url'] || './images/' image_url.chop! if /\/$/ =~ image_url name = file['name'] bits = file['bits'] path = File.join(image_dir, name) open(path,'wb') {|f| f.write bits.to_s } {'url' => (URI.parse(base_url) + (image_url + '/' + name)).to_s } end server.add_handler('mt.getRecentPostTitles') do |blogid, username, password, numberOfPosts| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end result = [] @cgi.params['title'] = [''] @cgi.params['body'] = [''] @cgi.params['hide'] = ['true'] @conf.latest_limit = numberOfPosts tdiary = ::TDiary::TDiaryLatest::new( @cgi, 'latest.rhtml', @conf ) tdiary.latest(numberOfPosts) {|diary| index = 0 diary.each_section {|sec| index += 1 postid = diary.date.strftime('%Y%m%d') + "%02d" % index author = sec.author || @conf['xmlrpc.userid'] result << { 'dateCreated' => diary.last_modified.utc, 'userid' => author, 'postid' => postid, 'title' => sec.subtitle, } } } result.sort {|a,b| b['postid']<=>a['postid'] } end server.add_handler('mt.getCategoryList') do |blogid, username, password| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end @cgi.params['date'] = [Time.now.strftime('%Y%m%d')] tdiary = TDiary::TDiaryDay::new( @cgi, 'day.rhtml', @conf ) list = [] tdiary.calendar.each do |y, ms| ms.each do |m| ym = "#{y}#{m}" @cgi.params['date'] = [ym] m = ::TDiary::TDiaryMonth.new(@cgi, '', @conf) m.diaries.each do |ymd, diary| next if !diary.visible? diary.each_section do |s| list |= s.categories unless s.categories.empty? end end end end list = list.sort.uniq result = [] list.each {|c| result << { 'categoryId' => c, 'categoryName' => c } } result end server.add_handler('mt.getPostCategories') do |postid, username, password| unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end @cgi.params['date'] = [postid[0,8]] tdiary = TDiary::TDiaryDay::new( @cgi, 'day.rhtml', @conf ) result = [] year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] i = 0 diary.each_section {|sec| i += 1 if i==index sec.categories.each_with_index {|cat,j| result << { 'categoryName' => cat, 'categoryId' => cat, 'isPrimary' => j==0 } } break end } result end server.add_handler('mt.setPostCategories') do |postid, username, password, categories| ENV['REQUEST_METHOD'] = 'POST' ENV['HTTP_REFERER'] = (URI.parse(base_url) + @conf.update).to_s unless username == @conf['xmlrpc.username'] && password == @conf['xmlrpc.password'] raise XMLRPC::FaultException.new(1,'userid or password incorrect') end begin @cgi.params['date'] = [postid[0,8]] tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf ) year, month, day, index = postid.scan(/(\d{4})(\d\d)(\d\d)(\d\d)/)[0] index = index.to_i time = Time::local( year, month, day ) + 12*60*60 diary = tdiary[time] @cgi.params.delete 'date' src = '' i = 0 diary.each_section {|sec| i += 1 if i==index cats = [] categories.sort {|a,b| a['isPrimary']==true ? 0 : 1 }.each {|c| cats << c['categoryId'] } sec.categories = cats end src << sec.to_src } @cgi.params['old'] = [postid[0,8]] @cgi.params['hide'] = diary.visible? ? [] : ['true'] @cgi.params['title'] = [diary.title] @cgi.params['year'] = [postid[0..3]] @cgi.params['month'] = [postid[4..5]] @cgi.params['day'] = [postid[6..7]] @cgi.params['body'] = [src] @cgi.params['csrf_protection_key'] = [@conf.options['csrf_protection_key']] ::TDiary::TDiaryReplace::new( @cgi, nil, @conf ) true rescue ::TDiary::ForceRedirect true rescue Exception raise XMLRPC::FaultException.new(1,$!.to_s + "\n" + $!.backtrace.join("\n")) end end server.add_handler('mt.supportedMethods') do [ 'blogger.newPost', 'blogger.editPost', 'blogger.getRecentPosts', 'blogger.getUsersBlogs', 'blogger.getUserInfo', 'blogger.deletePost', 'metaWeblog.getPost', 'metaWeblog.newPost', 'metaWeblog.editPost', 'metaWeblog.getRecentPosts', 'metaWeblog.newMediaObject', 'mt.getCategoryList', 'mt.setPostCategories', 'mt.getPostCategories', 'mt.getTrackbackPings', 'mt.supportedTextFilters', 'mt.getRecentPostTitles', 'mt.publishPost' ] end server.add_handler('mt.supportedTextFilters') do ['__default__'] end server.add_handler('mt.getTrackbackPings') do |postid| @cgi.params['date'] = [postid[0,8]] tdiary = TDiary::TDiaryDay::new( @cgi, 'day.rhtml', @conf ) result = [] date = Time::local( *postid.scan( /^(\d{4})(\d\d)(\d\d)(\d\d)$/ )[0] ) + 12*60*60 tdiary[date].each_visible_trackback(100) {|com,i| url, _, title, _ = com.body.split( /\n/,4 ) result << { 'pingURL' => url, 'pingIP' => '127.0.0.1', 'pingTitle' => title, } } result end server.add_handler('mt.publishPost') do |postid, username, password| true end server.add_handler('mt.setNextScheduledPost') do |postid, dateCreated, username, password| true end server.serve # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/misc/templates/000077500000000000000000000000001362645730700167065ustar00rootroot00000000000000tdiary-core-5.1.1/misc/templates/Gemfile.local.erb000066400000000000000000000004221362645730700220370ustar00rootroot00000000000000gem 'tdiary' # use edge tDiary # gem 'tdiary', :git => 'git@github.com:tdiary/tdiary-core.git' # if you use tdiary-contrib gem, uncomment this line. # gem 'tdiary-contrib' # use edge tDiary contrib # gem 'tdiary-contrib', :git => 'git@github.com:tdiary/tdiary-contrib.git' tdiary-core-5.1.1/package.json000066400000000000000000000010731362645730700162440ustar00rootroot00000000000000{ "name": "tdiary-core", "version": "5.0.13", "description": "", "main": "", "directories": { "doc": "doc", "test": "test" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git://github.com/tdiary/tdiary-core.git" }, "author": "", "license": "GPL", "bugs": { "url": "https://github.com/tdiary/tdiary-core/issues" }, "homepage": "https://github.com/tdiary/tdiary-core", "devDependencies": { "jquery": "~3.4.1", "jasmine-jquery": "~2.1.1" } } tdiary-core-5.1.1/public/000077500000000000000000000000001362645730700152335ustar00rootroot00000000000000tdiary-core-5.1.1/public/.gitkeep000066400000000000000000000000001362645730700166520ustar00rootroot00000000000000tdiary-core-5.1.1/spec/000077500000000000000000000000001362645730700147075ustar00rootroot00000000000000tdiary-core-5.1.1/spec/acceptance/000077500000000000000000000000001362645730700167755ustar00rootroot00000000000000tdiary-core-5.1.1/spec/acceptance/append_comment_spec.rb000066400000000000000000000050741362645730700233330ustar00rootroot00000000000000require 'acceptance_helper' feature 'ツッコミの更新' do scenario 'ツッコミを入れてlatestとdayで表示する' do append_default_diary visit '/' click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! BODY click_button '投稿' expect(page).to have_content "Click here!" visit "/" within('div.day div.comment div.commentshort') { within('span.commentator') { expect(page).to have_content "alpha" } expect(page).to have_content "こんにちは!こんにちは!" } today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day div.comment div.commentbody') { within('div.commentator'){ t = Time.now within('span.commenttime'){ expect(page).to have_content "%04d年%02d月%02d日" % [t.year, t.month, t.day] } within('span.commentator'){ expect(page).to have_content "alpha" } } expect(page).to have_content "こんにちは!こんにちは!" } end scenario 'ツッコミを2回入れる' do append_default_diary append_default_comment visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "body", with: <<-BODY こんばんは!こんばんは! BODY click_button '投稿' expect(page).to have_content "Click here!" visit "/" within('div.day div.comment div.commentshort') { expect(page).to have_content "alpha" expect(page).to have_content "bravo" expect(page).to have_content "こんにちは!こんにちは!" expect(page).to have_content "こんばんは!こんばんは!" } today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day div.comment div.commentbody') { t = Time.now expect(page).to have_content "%04d年%02d月%02d日" % [t.year, t.month, t.day] expect(page).to have_content "alpha" expect(page).to have_content "bravo" expect(page).to have_content "こんにちは!こんにちは!" expect(page).to have_content "こんばんは!こんばんは!" } end scenario 'recent_comment3.rb' do append_default_diary visit '/' click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! BODY click_button '投稿' expect(page).to have_content "Click here!" visit "/" within('ol.recent-comment > li') do expect(page).to have_content "alpha" end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/append_diary_spec.rb000066400000000000000000000070561362645730700230030ustar00rootroot00000000000000require 'acceptance_helper' feature '日記の追記' do scenario '更新画面のデフォルト表示' do visit '/' click_link '追記' expect(page).to have_content('日記の更新') y, m, d = Date.today.to_s.split('-').map {|t| t.sub(/^0+/, "") } within('span.year') { expect(page).to have_field('year', with: y) } within('span.month') { expect(page).to have_field('month', with: m) } within('span.day') { expect(page).to have_field('day', with: d) } end scenario '今日の日記を書く' do append_default_diary visit '/' within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.day div.section'){ within('h3') { expect(page).to have_content "さて、テストである。" } expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" } today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.day div.section'){ within('h3') { expect(page).to have_content "さて、テストである。" } expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" } end scenario '日付を指定して新しく日記を書く' do append_default_diary('2001-04-23') visit '/' page.find('h2', text: '2001年04月23日').click_link '2001年04月23日' within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.day div.section'){ within('h3') { expect(page).to have_content "さて、テストである。" } expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" } end scenario '今日の日記を追記する' do append_default_diary visit '/' click_link '追記' within('div.title') { fill_in "title", with: "Hikiのテスト" } within('div.textarea') { fill_in "body", with: <<-BODY !さて、Hikiのテストである。 とみせかけてtDiary:-) BODY } click_button "追記" expect(page).to have_content "Click here!" visit '/' within('div.day span.title'){ expect(page).to have_content "Hikiのテスト" } within('div.body'){ expect(page).to have_content "さて、テストである。" expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" expect(page).to have_content "さて、Hikiのテストである。" expect(page).to have_content "とみせかけてtDiary:-)" } end scenario '日記のプレビュー' do visit '/' click_link '追記' within('div.title') { fill_in "title", with: "tDiaryのテスト" } within('div.textarea') { fill_in "body", with: <<-BODY !さて、テストである。 とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P BODY } click_button 'プレビュー' expect(page).to have_content "tDiaryのテスト" within('div.day div.section'){ within('h3') { expect(page).to have_content "さて、テストである。" } expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/bugfix/000077500000000000000000000000001362645730700202615ustar00rootroot00000000000000tdiary-core-5.1.1/spec/acceptance/bugfix/encoding_error_spec.rb000066400000000000000000000012101362645730700246110ustar00rootroot00000000000000require 'acceptance_helper' feature '1.9 でエンコーディングエラーとなるリファラ' do scenario 'invalid sequence な場合' do disable_plugin('disp_referrer') append_default_diary src_path = File.expand_path('../../../fixtures/invalid-sequence-volatile.tdr', __FILE__) dist_path = File.expand_path('../../../../tmp/data/volatile.tdr', __FILE__) FileUtils.cp_r src_path, dist_path visit "/?date=#{Date.today.strftime('%Y%m%d')}" expect(page).to have_content "さて、テストである。" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_comment_spec.rb000066400000000000000000000047771362645730700240400ustar00rootroot00000000000000require 'acceptance_helper' feature 'ツッコミ設定の利用' do scenario 'ツッコミを非表示にできる' do append_default_diary append_default_comment visit '/update.rb?conf=comment' select '非表示', from: 'show_comment' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' within('div.day div.comment') { expect(page).to have_no_css('div[class="commentshort"]') expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" } end scenario '月表示の時の表示数を変更できる' do append_default_diary append_default_comment visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "body", with: <<-BODY こんばんは!こんばんは! BODY click_button '投稿' expect(page).to have_content "Click here!" visit '/update.rb?conf=comment' fill_in 'comment_limit', with: '1' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' within('div.day div.comment div.commentshort') { expect(page).to have_no_content "alpha" expect(page).to have_content "bravo" expect(page).to have_no_content "こんにちは!こんにちは!" expect(page).to have_content "こんばんは!こんばんは!" } today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day div.comment div.commentbody') { expect(page).to have_content "alpha" expect(page).to have_content "bravo" expect(page).to have_content "こんにちは!こんにちは!" expect(page).to have_content "こんばんは!こんばんは!" } end scenario '1日あたりの最大数を変更できる' do append_default_diary append_default_comment visit '/update.rb?conf=comment' fill_in 'comment_limit_per_day', with: '1' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div#comment-form-section') { within('div.caption') { expect(page).to have_content('本日の日記はツッコミ数の制限を越えています。') } expect(page).to have_no_css('form') } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_default_spec.rb000066400000000000000000000124321362645730700240050ustar00rootroot00000000000000require 'acceptance_helper' feature '基本設定の利用' do scenario 'サイトの情報の設定' do visit '/update.rb?conf=default' fill_in "author_name", with: "ただただし" fill_in "html_title", with: "ただの日記" fill_in "author_mail", with: "t@tdtds.jp" fill_in "index_page", with: "http://www.example.com" fill_in "description", with: "ただただしによる日々の記録" fill_in "icon", with: "http://tdtds.jp/favicon.png" # TODO banner の値が fill_in されない #fill_in "banner", with: "http://sho.tdiary.net/images/banner.png" # TODO x_frame_open の設定 page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' # TODO その他の項目の反映を確認 # within('title') { page.should have_content('ただの日記') } visit '/update.rb?conf=default' expect(page).to have_field "author_name", with: "ただただし" expect(page).to have_field "html_title", with: "ただの日記" expect(page).to have_field "author_mail", with: "t@tdtds.jp" expect(page).to have_field "index_page", with: "http://www.example.com" expect(page).to have_field "description", with: "ただただしによる日々の記録" expect(page).to have_field "icon", with: "http://tdtds.jp/favicon.png" # TODO banner の値が fill_in されない # page.should have_field("banner", with: "http://sho.tdiary.net/images/banner.png") end scenario 'ヘッダ・フッタの設定' do visit '/update.rb?conf=header' fill_in "header", with: <<-HEADER <%= navi %>

    alpha

    HEADER fill_in "footer", with: <<-FOOTER
    FOOTER page.all('div.saveconf').first.click_button "OK" #within('title') { page.should have_content('(設定完了)') } click_link '最新' within('h1') { expect(page).to have_content('alpha') } within('div.sidebar') { expect(page).to have_content('bravo')} visit '/update.rb?conf=header' expect(page).to have_field "header", with: <<-HEADER <%= navi %>

    alpha

    HEADER expect(page).to have_field "footer", with: <<-FOOTER
    FOOTER end scenario '表示一版の設定' do today = Date.today yestarday = Date.today - 1 append_default_diary(today.to_s) append_default_diary(yestarday.to_s) append_default_comment visit '/update.rb?conf=display' fill_in 'section_anchor', with: '' fill_in 'comment_anchor', with: '' fill_in 'date_format', with: '%Y:%m:%d' fill_in 'latest_limit', with: 1 select '非表示', from: 'show_nyear' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' expect(page).to have_content('★') expect(page).to have_content('●') titles = page.all('h2 span.date a').map(&:text) expect(titles).to include("#{today.year}:#{'%02d' % today.month}:#{'%02d' % today.day}") expect(titles).not_to include("#{yestarday.year}:#{'%02d' % yestarday.month}:#{'%02d' % yestarday.day}") expect(page).not_to have_content("長年日記") end scenario 'ログレベルの選択の設定' do visit '/update.rb?conf=logger' select 'DEBUG', from: 'log_level' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' # TODO ログレベルの確認 visit '/update.rb?conf=logger' within('select option[selected]'){ expect(page).to have_content 'DEBUG' } end scenario '時差調整が保存される' do visit '/update.rb?conf=timezone' fill_in 'hour_offset', with: '-24' page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '追記' y, m, d = (Date.today - 1).to_s.split('-').map {|t| t.sub(/^0+/, "") } within('span.year') { expect(page).to have_field('year', with: y) } within('span.month') { expect(page).to have_field('month', with: m) } within('span.day') { expect(page).to have_field('day', with: d) } click_link '設定' click_link '時差調整' expect(page).to have_field('hour_offset', with: '-24.0') end scenario 'Rack 環境でテーマ選択が保存される', :exclude_selenium do visit '/update.rb?conf=theme' select 'Tdiary1', from: 'theme' page.all('div.saveconf').first.click_button "OK" click_link '最新' expect(page.body).to be_include('href="assets/base.css"') expect(page.body).to be_include('href="assets/tdiary1/tdiary1.css"') visit '/update.rb?conf=theme' within('select option[selected]'){ expect(page).to have_content 'Tdiary1' } end scenario 'Webrick 環境でテーマ選択が保存される', :exclude_rack do visit '/update.rb?conf=theme' select 'Tdiary1', from: 'theme' page.all('div.saveconf').first.click_button "OK" click_link '最新' within('head') { expect(page).to have_css('link[href="theme/base.css"]') expect(page).to have_css('link[href="theme/tdiary1/tdiary1.css"]') } visit '/update.rb?conf=theme' within('select option[selected]'){ expect(page).to have_content 'Tdiary1' } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_dnsbl_spec.rb000066400000000000000000000107121362645730700234620ustar00rootroot00000000000000require 'acceptance_helper' require 'resolv' feature 'spamフィルタ設定の利用', :exclude_selenium do scenario 'IPベースのブラックリストの spam-champuru が spamlookup に置き換わる' do visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "dnsbl.spam-champuru.livedoor.com" fill_in 'spamlookup.domain.list', with: "" fill_in 'spamlookup.safe_domain.list', with: "" page.all('div.saveconf').first.click_button 'OK' visit '/update.rb?conf=dnsblfilter' expect(page).to have_no_content "dnsbl.spam-champuru.livedoor.com" expect(page).to have_content "bsb.spamlookup.net" end scenario 'IPベースのブラックリストが動作する' do allow(IPSocket).to receive(:getaddress) { '127.0.0.1' } allow(Resolv).to receive(:getaddress) { '127.0.0.1' } append_default_diary visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.domain.list', with: "" fill_in 'spamlookup.safe_domain.list', with: "" page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.com BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario 'IPベースのブラックリストでセーフの場合' do allow(IPSocket).to receive(:getaddress) { raise Timeout::Error } append_default_diary visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.domain.list', with: "" fill_in 'spamlookup.safe_domain.list', with: "" page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.com BODY click_button '投稿' visit "/" expect(page).to have_content "alpha" expect(page).to have_content "こんにちは!こんにちは!" end scenario 'ドメインベースのブラックリストが動作する' do allow(Resolv).to receive(:getaddress) { '127.0.0.1' } append_default_diary visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "" fill_in 'spamlookup.domain.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.safe_domain.list', with: "" page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.com BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario 'ドメインベースのブラックリストでセーフの場合' do allow(Resolv).to receive(:getaddress) { raise Timeout::Error } append_default_diary visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "" fill_in 'spamlookup.domain.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.safe_domain.list', with: "" page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.com BODY click_button '投稿' visit "/" expect(page).to have_content "alpha" expect(page).to have_content "こんにちは!こんにちは!" end scenario 'ブラックリストに問い合わせないリストが動作する' do expect(IPSocket).to receive(:getaddress).exactly(0) expect(Resolv).to receive(:getaddress).exactly(0) append_default_diary visit '/update.rb?conf=dnsblfilter' fill_in 'spamlookup.ip.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.domain.list', with: "bsb.spamlookup.net" fill_in 'spamlookup.safe_domain.list', with: "www.example.com" page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.com BODY click_button '投稿' visit "/" expect(page).to have_content "alpha" expect(page).to have_content "こんにちは!こんにちは!" end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_filter_spec.rb000066400000000000000000000026051362645730700236470ustar00rootroot00000000000000require 'acceptance_helper' feature 'spamフィルタ設定の利用' do scenario '新入荷のプラグインが表示される' do visit '/update.rb?conf=sf' page.all('div.saveconf').first.click_button 'OK' expect(page).not_to have_content '新入荷' FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" click_link 'スパムフィルター選択' expect(page).to have_content '新入荷' expect(page).to have_content 'sample.rb' FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" end scenario 'スパムフィルター選択が保存される' do FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" visit '/update.rb?conf=sf' check "sf.sample.rb" page.all('div.saveconf').first.click_button 'OK' expect(page).to have_checked_field "sf.sample.rb" FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" end scenario 'プラグインが消えたら表示されない' do FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" visit '/update.rb?conf=sf' expect(page).to have_content 'sample.rb' FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" click_link 'スパムフィルター選択' expect(page).not_to have_content 'sample.rb' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_plugin_spec.rb000066400000000000000000000034011362645730700236530ustar00rootroot00000000000000require 'acceptance_helper' feature 'プラグイン選択設定の利用' do plugin_path = "#{TDiary.root}/misc/plugin/rspec.rb" scenario '新入荷のプラグインが表示される' do FileUtils.rm plugin_path if File.exist? plugin_path visit '/update.rb?conf=sp' page.all('div.saveconf').first.click_button 'OK' expect(page).not_to have_content '新入荷' FileUtils.touch plugin_path click_link 'プラグイン選択' expect(page).to have_content '新入荷' expect(page).to have_content 'rspec.rb' FileUtils.rm plugin_path end scenario 'プラグイン設定を保存する' do FileUtils.touch plugin_path visit '/update.rb?conf=sp' check "sp.rspec.rb" page.all('div.saveconf').first.click_button 'OK' expect(page).to have_checked_field "sp.rspec.rb" FileUtils.rm plugin_path end scenario 'プラグインが消えたら表示されない' do FileUtils.touch plugin_path visit '/update.rb?conf=sp' expect(page).to have_content 'rspec.rb' FileUtils.rm plugin_path click_link 'プラグイン選択' expect(page).not_to have_content 'rspec.rb' end scenario '外部の Javascript を追加するプラグインを有効にする' do visit '/update.rb?conf=sp' check "sp.category_autocomplete.rb" page.all('div.saveconf').first.click_button 'OK' visit '/update.rb' expect(page.body).to be_include('caretposition.js') expect(page.body).to be_include('category_autocomplete.js') expect(page.body).to be_include('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') expect(page.body).not_to be_include('//ajax.googleapis.com/ajax/libs/jqueryui/1.12/1/jquery-ui.min.js?') end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_referer_spec.rb000066400000000000000000000034301362645730700240110ustar00rootroot00000000000000require 'acceptance_helper' feature 'リンク元設定の利用' do scenario 'リンク元の非表示設定' do append_default_diary visit '/update.rb?conf=referer' select('非表示', from: 'show_referer') page.all('div.saveconf').first.click_button "OK" # within('title') { page.should have_content('(設定完了)') } click_link '最新' today = Date.today.strftime("%Y年%m月%d日") page.find('h2', text: today).click_link today within('div.day') { expect(page).to have_no_css('div[class="refererlist"]') } end scenario 'リンク元記録の除外設定が動いている' do append_default_diary visit '/update.rb?conf=referer' fill_in 'no_referer', with: '^http://www\.example\.com/.*' page.all('div.saveconf').first.click_button('OK') # within('title') { page.should have_content('(設定完了)') } click_link '最新' today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day div.refererlist') { expect(page).to have_no_link('http://www.example.com') } end scenario 'リンク元の置換が動いている', :exclude_selenium do append_default_diary visit '/update.rb?conf=referer' fill_in 'referer_table', with: <<-REFERER ^http://www\.example\.com/.* alice ^http://www\.example\.net/.* bob REFERER page.all('div.saveconf').first.click_button('OK') # within('title') { page.should have_content('(設定完了)') } click_link '最新' today = Date.today.strftime('%Y年%m月%d日') page.find('h2', text: today).click_link today within('div.day div.refererlist') { expect(page).to have_link "alice" expect(page).to have_no_link "http://www.example.com" } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/save_conf_security_spec.rb000066400000000000000000000164241362645730700242350ustar00rootroot00000000000000require 'acceptance_helper' feature 'spamフィルタ設定の利用' do scenario 'おすすめフィルタの内容が保存される' do visit '/update.rb?conf=sp' page.all('div.saveconf').first.click_button 'OK' visit '/update.rb?conf=recommendfilter' check 'recommend.filter' page.all('div.saveconf').first.click_button 'OK' visit '/update.rb?conf=sp' expect(page).to have_checked_field 'sp.hide-mail-field.rb' end scenario 'CSRF対策の設定が保存される' do visit '/update.rb?conf=csrf_protection' # workaround for capybara-2.0 Ambiguous matcher # choose "check_key" page.find('input[type=radio][name=check_key][value=true]').set(true) page.all('div.saveconf').first.click_button 'OK' visit '/update.rb?conf=csrf_protection' expect(page).to have_selector 'input[name="check_key"][value="true"][checked]' end scenario 'spamと判定されたツッコミを捨てる' do append_default_diary visit '/update.rb?conf=spamfilter' select '捨てる', from: 'spamfilter.filter_mode' fill_in "spamfilter.max_uris", with: 1 page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.org http://www.example.org BODY click_button '投稿' visit '/update.rb' fill_in "year", with: Date.today.year fill_in "month", with: Date.today.month fill_in "day", with: Date.today.day click_button 'この日付の日記を編集' expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario 'URLの数によるspam判定' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.max_uris", with: 1 page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.org http://www.example.org BODY click_button '投稿' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "body", with: <<-BODY こんばんは!こんばんは! http://www.example.org BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" expect(page).to have_content "bravo" expect(page).to have_content "こんばんは!こんばんは!" end scenario 'URLの割合によるspam判定' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.max_rate", with: 50 page.all('div.saveconf').first.click_button 'OK' # capybara-2.0 can't find title element # within('title') { page.should have_content('(設定完了)') } visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! http://www.example.org http://www.example.org http://www.example.org BODY click_button '投稿' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "body", with: <<-BODY こんばんは!こんばんは! こんばんは!こんばんは! http://www.example.org BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" expect(page).to have_content "bravo" expect(page).to have_content "こんばんは!こんばんは!" end scenario 'キーワードでツッコミがはじかれる' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.bad_comment_patts", with: <<-BODY こんにちは! BODY page.all('div.saveconf').first.click_button 'OK' # within('title') { page.should have_content('(設定完了)') } visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario 'メールアドレスでツッコミがはじかれる' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.bad_mail_patts", with: <<-BODY example.com BODY page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "mail", with: "admin@example.com" fill_in "body", with: <<-BODY こんにちは!こんにちは! BODY click_button '投稿' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "mail", with: "t@tdtds.jp" fill_in "body", with: <<-BODY こんばんは!こんばんは! BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" expect(page).to have_content "bravo" expect(page).to have_content "こんばんは!こんばんは!" end scenario 'URLでツッコミがはじかれる' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.bad_uri_patts", with: <<-BODY example BODY page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは! http://www.example.com BODY click_button '投稿' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "bravo" fill_in "body", with: <<-BODY example こんにちは! BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは! http://www.example.com" expect(page).to have_content "bravo" expect(page).to have_content "example こんにちは!" end scenario 'IPアドレスでツッコミが弾かれる' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in "spamfilter.bad_ip_addrs", with: <<-BODY 127.0.0.1 BODY page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: <<-BODY こんにちは!こんにちは! BODY click_button '投稿' visit "/" expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario 'ツッコミの注意文が保存されて表示される' do append_default_diary visit '/update.rb?conf=spamfilter' fill_in 'comment_description', with: 'これはツッコミの注意文です' page.all('div.saveconf').first.click_button 'OK' visit "/" click_link 'ツッコミを入れる' expect(page).to have_content 'これはツッコミの注意文です' end scenario 'スパムフィルターのログ記録の設定が保存される' do append_default_diary visit '/update.rb?conf=spamfilter' expect(page).to have_field 'filter.debug_mode' select '記録しない', from: 'filter.debug_mode' page.all('div.saveconf').first.click_button 'OK' visit '/update.rb?conf=spamfilter' within('select[name="filter.debug_mode"] option[selected]'){ expect(page).to have_content '記録しない' } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/support/000077500000000000000000000000001362645730700205115ustar00rootroot00000000000000tdiary-core-5.1.1/spec/acceptance/support/helpers.rb000066400000000000000000000023271362645730700225040ustar00rootroot00000000000000module HelperMethods def append_default_diary(ymd = Date.today.to_s) date = Date.parse(ymd) visit '/update.rb' fill_in "year", with: date.year fill_in "month", with: date.month fill_in "day", with: date.day fill_in "title", with: "tDiaryのテスト" fill_in "body", with: <<-BODY !さて、テストである。 とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P BODY click_button "追記" end def append_default_comment(ymd = Date.today.to_s) visit "/" date = Date.parse(ymd).strftime('%Y年%m月%d日') page.find('h2', text: date).click_link date click_link 'ツッコミを入れる' fill_in "name", with: "alpha" fill_in "body", with: 'こんにちは!こんにちは!' click_button '投稿' end def enable_plugin(name) visit '/update.rb?conf=sp' check "sp.#{name}.rb" page.all('div.saveconf').first.click_button 'OK' end def disable_plugin(name) visit '/update.rb?conf=sp' uncheck "sp.#{name}.rb" page.all('div.saveconf').first.click_button 'OK' end end RSpec.configuration.include(HelperMethods) # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/support/paths.rb000066400000000000000000000001521362645730700221530ustar00rootroot00000000000000module NavigationHelpers def homepage "/" end end RSpec.configuration.include(NavigationHelpers) tdiary-core-5.1.1/spec/acceptance/update_diary_spec.rb000066400000000000000000000064401362645730700230120ustar00rootroot00000000000000require 'acceptance_helper' feature '日記の更新' do scenario '特定の日記の内容を更新する' do visit '/update.rb' fill_in "year", with: '2001' fill_in "month", with: '4' fill_in "day", with: '23' fill_in "title", with: "tDiaryのテスト" fill_in "body", with: <<-BODY !さて、テストである。 とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P !もう一度テストである。 本当に動くかな? BODY click_button "追記" visit '/' page.find('h2', text: '2001年04月23日').click_link '2001年04月23日' within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.body'){ expect(page).to have_content "さて、テストである。" expect(page).to have_content "もう一度テストである。" expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" expect(page).to have_content "本当に動くかな?" } visit '/update.rb' fill_in "year", with: '2001' fill_in "month", with: '4' fill_in "day", with: '23' click_button 'この日付の日記を編集' fill_in "body", with: <<-BODY !もう一度テストである。 本当に動くかな? BODY click_button "登録" visit '/' page.find('h2', text: '2001年04月23日').click_link '2001年04月23日' within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.body'){ expect(page).to have_no_content "さて、テストである。" expect(page).to have_content "もう一度テストである。" expect(page).to have_no_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" expect(page).to have_content "本当に動くかな?" } end scenario '日記の削除' do append_default_diary visit '/update.rb' fill_in "year", with: Date.today.year fill_in "month", with: Date.today.month fill_in "day", with: Date.today.day click_button 'この日付の日記を編集' within('div.textarea') { fill_in "body", with: '' } click_button "登録" expect(page).to have_content "Click here!" visit '/' within('div.day') { expect(page).to have_no_css('h3') } end scenario '日記を隠す' do append_default_diary visit '/update.rb' fill_in "year", with: Date.today.year fill_in "month", with: Date.today.month fill_in "day", with: Date.today.day click_button 'この日付の日記を編集' check 'hide' click_button "登録" expect(page).to have_content "Click here!" visit '/' expect(page).to have_no_css('div[class="day"]') end scenario '編集画面に前の日記と次の日記のリンク表示される' do append_default_diary('20010502') append_default_diary('20010503') append_default_diary('20010504') visit '/update.rb' fill_in "year", with: '2001' fill_in "month", with: '5' fill_in "day", with: '3' click_button 'この日付の日記を編集' expect(page).to have_content('«前の日記(2001年05月02日)') expect(page).to have_content('次の日記(2001年05月04日)»') end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/acceptance/view_category_spec.rb000066400000000000000000000015621362645730700232070ustar00rootroot00000000000000require 'acceptance_helper' feature 'カテゴリ機能の動作' do scenario 'カテゴリ機能が動く' do enable_plugin('category') visit '/' click_link '追記' within('span.year') { fill_in "year", with: '2001' } within('span.month') { fill_in "month", with: '4' } within('span.day') { fill_in "day", with: '23' } within('div.textarea') { fill_in "body", with: <<-BODY ![category] さて、テストである。 とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P ![tdiary] もう一度テストである。 本当に動くかな? BODY } click_button "追記" visit '/' page.find('a', text: "category").click expect(page).to have_content '[category]' end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/view_comment_spec.rb000066400000000000000000000036431362645730700230360ustar00rootroot00000000000000require 'acceptance_helper' feature 'ツッコミの表示' do scenario 'ツッコミを隠す' do append_default_diary append_default_comment visit '/' click_link '追記' click_button "この日付の日記を編集" uncheck 'commentcheckboxr0' click_button 'ツッコミ表示状態変更' visit '/' expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" today = Date.today.strftime("%Y年%m月%d日") page.find('h2', text: today).click_link today expect(page).to have_no_content "alpha" expect(page).to have_no_content "こんにちは!こんにちは!" end scenario "日付表示だと絵文字を表示できる", :exclude_selenium do append_default_diary visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "寿司" fill_in "body", with: <<-BODY :sushi: は美味しい BODY click_button '投稿' visit "/" today = Date.today.strftime("%Y年%m月%d日") page.find('h2', text: today).click_link today within('div.day div.comment div.commentbody') { expect(page.body).to be_include "sushi は美味しい" } end scenario "一覧表示でも絵文字を表示できる", :exclude_selenium do append_default_diary visit "/" click_link 'ツッコミを入れる' fill_in "name", with: "寿司" fill_in "body", with: <<-BODY :sushi: は美味しい BODY click_button '投稿' visit "/" within('div.day div.comment div.commentshort') { expect(page.body).to be_include "sushi は美味しい" } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/view_diary_spec.rb000066400000000000000000000102751362645730700225030ustar00rootroot00000000000000require 'acceptance_helper' feature '日記を読む' do scenario '最新の日記の表示' do visit '/' # capybara-2.0 can't find header content. # within('title') { page.should have_content('【日記のタイトル】') } within('h1') { expect(page).to have_content('【日記のタイトル】') } expect(page).to have_css('a[href="update.rb"]') expect(page).to have_css('a[href="update.rb?conf=default"]') end scenario '月またぎの日記の表示' do append_default_diary('20100430') append_default_diary('20100501') before_day = '2010年04月30日' after_day = '2010年05月01日' visit '/' page.find('h2', text: before_day).click_link "#{before_day}" within('div.adminmenu'){ expect(page).to have_content "次の日記(#{after_day})"} click_link "次の日記(#{after_day})" within('div.day') { expect(page).to have_content "#{after_day}" } within('div.adminmenu'){ expect(page).to have_content "前の日記(#{before_day})"} click_link "前の日記(#{before_day})" within('div.day') { expect(page).to have_content "#{before_day}" } end scenario 'n日前の日記をまとめて表示' do 1.upto(11) {|i| append_default_diary("201005%02d" % i) } visit '/' within('div.main') { expect(page).to have_content "#{Date.parse('20100502').strftime('%Y年%m月%d日')}" expect(page).to have_content "#{Date.parse('20100511').strftime('%Y年%m月%d日')}" expect(page).to have_no_content "#{Date.parse('20100501').strftime('%Y年%m月%d日')}" } click_link "前10日分" within('div.main') { expect(page).to have_no_content "#{Date.parse('20100502').strftime('%Y年%m月%d日')}" expect(page).to have_no_content "#{Date.parse('20100511').strftime('%Y年%m月%d日')}" expect(page).to have_content "#{Date.parse('20100501').strftime('%Y年%m月%d日')}" } end scenario 'n年日記機能を表示' do append_default_diary('20010423') append_default_diary('20020423') append_default_diary('20030423') visit '/' page.find('h2', text: "2001年04月23日").click_link '2001年04月23日' click_link '長年日記' titles = page.all('h2 span.date a').map(&:text) expect(titles).to include '2001年04月23日' expect(titles).to include '2002年04月23日' expect(titles).to include '2003年04月23日' end scenario '指定をした日を表示' do append_default_diary('2001-04-23') visit '/?date=20010423' within('div.day span.title'){ expect(page).to have_content "tDiaryのテスト" } within('div.day div.section'){ within('h3') { expect(page).to have_content "さて、テストである。" } expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" } end scenario '1ヶ月を表示' do append_default_diary('20010101') visit '/' click_link '追記' within('span.year') { fill_in "year", with: 2001 } within('span.month') { fill_in "month", with: 01 } within('span.day') { fill_in "day", with: 31 } within('div.title') { fill_in "title", with: "tDiaryのテスト" } within('div.textarea') { fill_in "body", with: <<-BODY !さて、月末である。 今月も終わる BODY } click_button "追記" visit '/' click_link '追記' within('span.year') { fill_in "year", with: 2001 } within('span.month') { fill_in "month", with: 02 } within('span.day') { fill_in "day", with: 01 } within('div.title') { fill_in "title", with: "tDiaryのテスト" } within('div.textarea') { fill_in "body", with: <<-BODY !さて、月始めである。 今月も始まる BODY } click_button "追記" visit '/?date=200101' within('div.main'){ expect(page).to have_content "さて、テストである。" expect(page).to have_content "さて、月末である。" expect(page).to have_no_content "さて、月始めである。" expect(page).to have_content "とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P" expect(page).to have_content "今月も終わる" expect(page).to have_no_content "今月も始まる" } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance/view_referer_spec.rb000066400000000000000000000015461362645730700230260ustar00rootroot00000000000000require 'acceptance_helper' feature 'リンク元の表示', exclude_selenium: true do scenario '日表示にリンク元が表示されている' do append_default_diary visit '/' today = Date.today.strftime("%Y年%m月%d日") page.find('h2', text: today).click_link today within('div.day') { expect(page).to have_css('div[class="refererlist"]') within('div.refererlist') { expect(page).to have_content "http://www.example.com" } } end scenario '更新画面にリンク元が表示されている' do append_default_diary visit "/" today = Date.today.strftime("%Y年%m月%d日") page.find('h2', text: today).click_link today within('div.day div.refererlist') { expect(page).to have_link "http://www.example.com" } end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/acceptance_helper.rb000066400000000000000000000032641362645730700206660ustar00rootroot00000000000000require 'spec_helper' Dir["#{File.dirname(__FILE__)}/acceptance/support/**/*.rb"].each {|f| require f} require 'tdiary/application' Capybara.app = Rack::Builder.new do map '/' do run TDiary::Dispatcher.index end map '/index.rb' do run TDiary::Dispatcher.index end map '/update.rb' do run TDiary::Dispatcher.update end end # FIXME: TDiary::Application has auth middleware in update.rb, so it cannot be tested. # Capybara.app = TDiary::Application.new Capybara.save_path = File.dirname(__FILE__) + '/../tmp/capybara' RSpec.configure do |config| fixture_conf = File.expand_path('../fixtures/just_installed.conf', __FILE__) work_data_dir = File.expand_path('../../tmp/data', __FILE__) tdiary_conf = File.expand_path("../fixtures/tdiary.conf.#{ENV['TEST_MODE'] || 'rack'}", __FILE__) work_conf = File.expand_path('../../tdiary.conf', __FILE__) config.before(:all) do FileUtils.cp_r tdiary_conf, work_conf, verbose: false end config.after(:all) do FileUtils.rm_rf work_conf end config.before(:each) do FileUtils.mkdir_p work_data_dir FileUtils.cp_r(fixture_conf, File.join(work_data_dir, "tdiary.conf"), verbose: false) unless fixture_conf.empty? end config.after(:each) do FileUtils.rm_rf work_data_dir end if ENV['TEST_MODE'] == 'webrick' Capybara.default_driver = :selenium Capybara.app_host = 'http://localhost:' + (ENV['PORT'] || '19292') end excludes = case ENV['TEST_MODE'] when 'webrick' [:exclude_selenium] else # rack [:exclude_rack] end excludes.each do |exclude| config.filter_run_excluding exclude end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/core/000077500000000000000000000000001362645730700156375ustar00rootroot00000000000000tdiary-core-5.1.1/spec/core/application_spec.rb000066400000000000000000000024761362645730700215120ustar00rootroot00000000000000require 'spec_helper' require 'rack/test' require 'tdiary/application' describe TDiary::Application do include Rack::Test::Methods before do end describe '#call' do let(:app) { TDiary::Application.new } context "when is accessed to index" it do get '/' expect(last_response.status).to eq 200 end context "when is accessed to update" do it do get '/update.rb' expect(last_response.status).to eq 401 end end context "with base_dir" do before do TDiary.configuration.options['base_url'] = 'http://example.com/diary/' end after do TDiary.configuration.options['base_url'] = '' end let(:app) { TDiary::Application.new } it do get '/diary/' expect(last_response.status).to eq 200 end context "when access to root directory" do it do get '/' expect(last_response.status).to eq 404 end end end context "when the application raises exception" do before do allow(TDiary::Dispatcher).to receive_message_chain(:index).and_return( lambda {|env| raise StandardError.new } ) end it do get '/' expect(last_response.status).to eq 500 expect(last_response.body).to match(/^StandardError/) end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/compatible_spec.rb000066400000000000000000000030631362645730700213170ustar00rootroot00000000000000require 'spec_helper' require 'tdiary/compatible' require 'fileutils' describe PStore, "auto convert library" do before do # rake specで動かすと、comppatible.rb が既に読み込まれてしまっているため、 # このPStoreがASCII-8BITではなくUTF-8になってしまう。 # そのため、下記と同様の ascii8bit-pstore.db をテストフィクスチャとしている。 # PStore.new(@dbfile).transaction do |db| # db["key1".to_8bit] = "val1".to_8bit # db["key2".to_8bit] = 2 # db["key3".to_8bit] = [1, :sym, "string".to_8bit] # end dbfilename = '../fixtures/ascii8bit-pstore.db' dbfile_orig = File.join(File.dirname(__FILE__), dbfilename) @dbfile = File.join(File.dirname(__FILE__), "#{dbfilename}.work") FileUtils.cp dbfile_orig, @dbfile end after do FileUtils.rm @dbfile end it "should convert an encoding to UTF-8 automatically" do PStore.new(@dbfile).transaction do |db| expect(db["key1"].encoding).to eq(Encoding::UTF_8) expect(db["key2"]).to eq(2) expect(db["key3"][2].encoding).to eq(Encoding::UTF_8) end end it "1回目のtransactionではMashal.loadが3回呼ばれる" do expect(Marshal).to receive(:load).exactly(3).and_return({}) PStore.new(@dbfile).transaction {} end it "2回目のtransactionではMashal.loadが1回だけ呼ばれる" do expect(Marshal).to receive(:load).exactly(4).and_return({}) PStore.new(@dbfile).transaction {} PStore.new(@dbfile).transaction {} end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/configuration_spec.rb000066400000000000000000000013351362645730700220470ustar00rootroot00000000000000require 'spec_helper' require 'tdiary' require 'tdiary/configuration' describe TDiary::Configuration do let(:tdiary_conf) { File.expand_path("../../fixtures/tdiary.conf.webrick", __FILE__) } let(:work_conf) { File.expand_path('../../../tdiary.conf', __FILE__) } before do FileUtils.cp_r tdiary_conf, work_conf, verbose: false end after do FileUtils.rm_rf work_conf end describe "TDiary.configuration" do before do @obj = TDiary.configuration end it { expect(@obj.class).to eq TDiary::Configuration } it "singleton" do expect(@obj).to eq TDiary.configuration end end it "TDiary.configuration.attribute" do expect(TDiary.configuration.style).to eq("Wiki") end end tdiary-core-5.1.1/spec/core/core_ext_spec.rb000066400000000000000000000047071362645730700210160ustar00rootroot00000000000000require 'spec_helper' require 'tdiary/core_ext' describe "core extension library" do describe 'String#make_link' do it 'エスケープされて出力される' do expect("<\"alice&bob\">".make_link).to eq "<"alice&bob">" end context 'httpを含む場合' do it { expect("http://example.com".make_link).to eq "http://example.com" } end context 'メールアドレスのようなものを含む場合' do it { expect("shibata.hiroshi@gmail.com".make_link).to eq "shibata.hiroshi@gmail.com" } end end describe "String#emojify!" do context "emojify" do before { @result = ":sushi: は美味しい".emojify } it do expect(@result).to eq "sushi は美味しい" end end context "大文字でもemojify" do before { @result = ":SUSHI: は美味しい".emojify } it do expect(@result).to eq "sushi は美味しい" end end context "+1でもemojify" do before { @result = "いいね!:+1:".emojify } it do expect(@result).to eq "いいね!plus1" end end context "plus1でもemojify" do before { @result = "いいね!:plus1:".emojify } it do expect(@result).to eq "いいね!plus1" end end context "thumbsupでもemojify" do before { @result = "いいね!:thumbsup:".emojify } it do expect(@result).to eq "いいね!thumbsup" end end context "絵文字に変換しない" do [ ":: は美味しい", "foo::bar::baz" ].each do |str| describe str do it { expect(str.emojify).to eq str } end end end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/diary_container_spec.rb000066400000000000000000000040101362645730700223430ustar00rootroot00000000000000require 'spec_helper' require 'tdiary' require 'tdiary/cache/file' require 'tdiary/io/default' require 'tdiary/diary_container' describe TDiary::DiaryContainer do let(:conf) { TDiary::Configuration.new } let(:today) { Time.local(2005, 1, 20, 12, 0, 0) } let(:tdiary_conf_org) { File.join(TDiary::root, "spec/fixtures/tdiary.conf.webrick") } let(:tdiary_conf) { File.join(TDiary::root, "tdiary.conf") } before do # create sample confing FileUtils.cp_r tdiary_conf_org, tdiary_conf, verbose: false # create sample diary tdiary = DummyTDiary.new tdiary.conf = conf io = TDiary::IO::Default.new(tdiary) io.transaction(today) do |diaries| date = today.strftime('%Y%m%d') diary = io.diary_factory(date, "foo", "", "wiki") diaries[date] = diary.append("bar") TDiary::TDiaryBase::DIRTY_DIARY end end after do FileUtils.rm_f tdiary_conf ["/tmp/data/#{today.year}"].each do |dir| FileUtils.rm_rf File.join(TDiary.root, dir) end end context "with find_by_month" do let(:diary) { TDiary::DiaryContainer.find_by_month(conf, "200501") } it { expect(diary).to be_a_kind_of TDiary::DiaryContainer } describe "#conf" do subject { diary.conf } it { expect(subject).to be_a_kind_of TDiary::Configuration } end describe "#diaries" do subject { diary.diaries } it { expect(subject).to be_a_kind_of Hash } it { expect(subject.keys).to include('20050120') } it { expect(subject.values).to include(be_a_kind_of TDiary::Style::WikiDiary) } end end context "with find_by_day" do let(:diary) { TDiary::DiaryContainer.find_by_day(conf, "20050120") } it { expect(diary).to be_a_kind_of TDiary::DiaryContainer } describe "#conf" do subject { diary.conf } it { expect(subject).to be_a_kind_of TDiary::Configuration } end describe "#diaries" do subject { diary.diaries } it { expect(subject).to be_a_kind_of Hash } it { expect(subject.keys).to include('20050120') } it { expect(subject.values).to include(be_a_kind_of TDiary::Style::WikiDiary) } end end end tdiary-core-5.1.1/spec/core/io/000077500000000000000000000000001362645730700162465ustar00rootroot00000000000000tdiary-core-5.1.1/spec/core/io/default_spec.rb000066400000000000000000000067061362645730700212420ustar00rootroot00000000000000require 'spec_helper' require 'tdiary/cache/file' require 'tdiary/io/default' describe TDiary::IO::Default do it 'is_a TDiary::IO::Base' do expect(TDiary::IO::Default.ancestors.include?(TDiary::IO::Base)).to be_truthy end describe "#save_cgi_conf and #load_cgi_conf" do let(:conf) do conf = DummyConf.new conf.data_path = TDiary.root + "/tmp/" conf end it { expect(TDiary::IO::Default.load_cgi_conf(conf)).to be_nil } context "given body" do before do TDiary::IO::Default.save_cgi_conf(conf, 'foo') end it { expect(TDiary::IO::Default.load_cgi_conf(conf)).to eq 'foo' } context "update" do before do TDiary::IO::Default.save_cgi_conf(conf, 'bar') end it { expect(TDiary::IO::Default.load_cgi_conf(conf)).to eq 'bar' } end end end describe "#transaction" do let(:io) { TDiary::IO::Default.new(DummyTDiary.new) } let(:today) { Time.now.strftime( '%Y%m%d' ) } before do io.transaction( Time.now ) do |diaries| @diaries = diaries diary = io.diary_factory(today, "foo", "", "wiki") @diaries[today] = diary.append("bar", "hsbt") TDiary::TDiaryBase::DIRTY_DIARY end end subject { File.open(TDiary.root + "/tmp/#{Time.now.year}/#{Time.now.strftime('%Y%m')}.td2").read } it { expect(subject).to be_include "foo" } it { expect(subject).to be_include "bar" } it "restore diary" do io.transaction( Time.now ) do |diaries| @diaries = diaries expect(@diaries[today].title).to eq "foo" expect(@diaries[today].to_src).to be_include "bar" TDiary::TDiaryBase::DIRTY_DIARY end end context "update diary" do before do io.transaction( Time.now ) do |diaries| @diaries = diaries @diaries[today].replace(today, "buzz", "alice") TDiary::TDiaryBase::DIRTY_DIARY end end subject { File.open(TDiary.root + "/tmp/#{Time.now.year}/#{Time.now.strftime('%Y%m')}.td2").read } it "update contents of diary" do expect(subject).to_not be_nil expect(subject).to_not be_include "foo" expect(subject).to_not be_include "bar" expect(subject).to be_include "buzz" expect(subject).to be_include "alice" end end end describe "#style" do context "given Foo style" do let(:io) { TDiary::IO::Default.new(DummyTDiary.new) } before do TDiary::Style.const_set(:FooSection, Class.new) TDiary::Style.const_set(:FooDiary, Class.new) end it "activates a style automatically" do style = io.style("Foo") expect(style).to eq TDiary::Style::FooDiary expect(style).to be < TDiary::Style::BaseDiary expect(style).to be < TDiary::Style::CategorizableDiary expect(TDiary::Style::FooSection).to be < TDiary::Style::BaseSection end it "raises a BadStyleError when style is unknown" do expect { io.style("Bar") }.to raise_error(TDiary::BadStyleError) end after do TDiary::Style.send(:remove_const, :FooSection) TDiary::Style.send(:remove_const, :FooDiary) end end end before(:all) do ["/tmp/tdiary.conf", "/tmp/#{Time.now.year}"].each do |file| FileUtils.rm_rf TDiary.root + file end end after(:all) do ["/tmp/tdiary.conf", "/tmp/#{Time.now.year}"].each do |file| FileUtils.rm_rf TDiary.root + file end end end tdiary-core-5.1.1/spec/core/plugin_spec.rb000066400000000000000000000307541362645730700205050ustar00rootroot00000000000000require 'spec_helper' require File.dirname(__FILE__) + "/../plugin/plugin_helper" require 'tdiary/plugin' describe TDiary::Plugin do before do config = PluginFake::Config.new config.plugin_path = 'spec/fixtures/plugin' @plugin = TDiary::Plugin.new({ conf: config, debug: true }) end describe '#load_plugin' do before { @plugin.load_plugin('spec/fixtures/plugin/sample.rb') } subject { @plugin } it '読み込まれたプラグインのメソッドを呼び出せること' do expect(subject.sample).to eq 'sample plugin' end it 'プラグイン一覧が @plugin_files で取得できること' do # TODO: 実際にはPlugin.newした時点でload_pluginが呼ばれている # @plugin_filesの追加もinitializeメソッド内で実行されている expect(subject.instance_variable_get(:@plugin_files)).to include('spec/fixtures/plugin/sample.rb') end context 'リソースファイルが存在する場合' do before do @plugin.instance_variable_get(:@conf).lang = 'ja' @plugin.load_plugin('spec/fixtures/plugin/sample.rb') end it 'Confファイルで指定した言語に対応するリソースが読み込まれること' do expect(@plugin.sample_ja).to eq 'サンプルプラグイン' end end end describe '#eval_src' do before do @src = ERB::new('hello <%= sample %><%= undefined_method %>').src @plugin.instance_variable_set(:@debug, false) end subject { @plugin.eval_src(@src) } it 'Pluginオブジェクト内でソースが実行されること' do is_expected.to eq 'hello sample plugin' end context 'debugモードがONの場合' do before { @plugin.instance_variable_set(:@debug, true) } it 'Plugin内のエラーが通知されること' do expect { subject }.to raise_error(NameError) end end end describe '#header_proc' do before do @plugin.__send__(:add_header_proc, ){ 'header1 ' } @plugin.__send__(:add_header_proc, ){ 'header2' } end subject { @plugin.__send__(:header_proc) } it 'add_header_procで登録したブロックが実行されること' do is_expected.to eq 'header1 header2' end end describe '#footer_proc' do before do @plugin.__send__(:add_footer_proc, ){ 'footer1 ' } @plugin.__send__(:add_footer_proc, ){ 'footer2' } end subject { @plugin.__send__(:footer_proc) } it 'add_footer_procで登録したブロックが実行されること' do is_expected.to eq 'footer1 footer2' end end describe '#update_proc' do let (:proc1) { lambda {} } let (:proc2) { lambda {} } before do @plugin.__send__(:add_update_proc, &proc1) @plugin.__send__(:add_update_proc, &proc2) end subject { @plugin.__send__(:update_proc) } it 'add_update_procで登録したブロックが実行されること' do expect(proc1).to receive(:call) expect(proc2).to receive(:call) # should_receiveの場合はsubjectが使えないため明示的に実行 @plugin.__send__(:update_proc) end it '空の文字列を返すこと' do is_expected.to eq '' end end describe '#title_proc' do let (:proc1) { lambda {|date, title| "title1" } } let (:proc2) { lambda {|date, title| "title2" } } let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_title_proc, &proc1) @plugin.__send__(:add_title_proc, &proc2) end subject { @plugin.__send__(:title_proc, date, 'title') } it 'add_title_procで登録したブロックを実行し、最後の結果を返すこと' do is_expected.to eq 'title2' end it '前のprocの結果が次のprocに渡されること' do expect(proc1).to receive(:call).with(date, 'title').and_return('title1') expect(proc2).to receive(:call).with(date, 'title1') @plugin.__send__(:title_proc, date, 'title') end it 'apply_pluginメソッドを呼び出すこと' do expect(@plugin).to receive(:apply_plugin) # should_receiveの場合はsubjectが使えないため明示的に実行 @plugin.__send__(:title_proc, date, 'title') end end describe '#body_enter_proc' do let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_body_enter_proc, ){|date| 'body1 ' } @plugin.__send__(:add_body_enter_proc, ){|date| 'body2' } end subject { @plugin.__send__(:body_enter_proc, date) } it 'add_body_enter_procで登録したブロックが実行されること' do is_expected.to eq 'body1 body2' end end describe '#body_leave_proc' do before do @plugin.__send__(:add_body_leave_proc, ){|date| 'body1 ' } @plugin.__send__(:add_body_leave_proc, ){|date| 'body2' } end subject { @plugin.__send__(:body_leave_proc, @date) } it 'add_body_leave_procで登録したブロックが実行されること' do is_expected.to eq 'body1 body2' end end describe '#section_enter_proc' do let (:proc1) { lambda {|date, index| 'section1 ' } } let (:proc2) { lambda {|date, index| 'section2' } } let (:date1) { Time.local(2012, 1, 2) } let (:date2) { Time.local(2012, 1, 3) } before do @plugin.__send__(:add_section_enter_proc, &proc1) @plugin.__send__(:add_section_enter_proc, &proc2) end subject { @plugin.__send__(:section_enter_proc, date1) } it 'add_section_enter_procで登録したブロックを実行し、結果を連結して返すこと' do is_expected.to eq 'section1 section2' end it '呼ばれた回数に応じてセクション番号の数が増加すること (日付単位)' do expect(proc1).to receive(:call).with(date1, 1) @plugin.__send__(:section_enter_proc, date1) expect(proc1).to receive(:call).with(date1, 2) @plugin.__send__(:section_enter_proc, date1) expect(proc1).to receive(:call).with(date2, 1) @plugin.__send__(:section_enter_proc, date2) end end describe '#subtitle_proc' do let (:proc1) { lambda {|date, index, subtitle| "subtitle1" } } let (:proc2) { lambda {|date, index, subtitle| "subtitle2" } } let (:date1) { Time.local(2012, 1, 2) } let (:date2) { Time.local(2012, 1, 3) } before do @plugin.__send__(:add_subtitle_proc, &proc1) @plugin.__send__(:add_subtitle_proc, &proc2) end subject { @plugin.__send__(:subtitle_proc, date1, 'subtitle') } it 'add_subtitle_procで登録したブロックを実行し、最後の結果を返すこと' do is_expected.to eq 'subtitle2' end it '前のprocの結果が次のprocに渡されること' do expect(proc1).to receive(:call).with(date1, 1, 'subtitle').and_return('subtitle1') expect(proc2).to receive(:call).with(date1, 1, 'subtitle1') @plugin.__send__(:section_enter_proc, date1) @plugin.__send__(:subtitle_proc, date1, 'subtitle') end it 'apply_pluginメソッドを呼び出すこと' do expect(@plugin).to receive(:apply_plugin) # should_receiveの場合はsubjectが使えないため明示的に実行 @plugin.__send__(:subtitle_proc, date1, 'title') end end describe '#section_leave_proc' do let (:proc1) { lambda {|date, index| 'section1 ' } } let (:proc2) { lambda {|date, index| 'section2' } } let (:date1) { Time.local(2012, 1, 2) } let (:date2) { Time.local(2012, 1, 3) } before do @plugin.__send__(:add_section_leave_proc, &proc1) @plugin.__send__(:add_section_leave_proc, &proc2) end subject { @plugin.__send__(:section_leave_proc, date1) } it 'add_section_leave_procで登録したブロックを実行し、結果を連結して返すこと' do is_expected.to eq 'section1 section2' end it '呼ばれた回数に応じてセクション番号の数が増加すること (日付単位)' do # セクション番号はsection_enter_procの呼び出し回数で決定する expect(proc1).to receive(:call).with(date1, 1) @plugin.__send__(:section_enter_proc, date1) @plugin.__send__(:section_leave_proc, date1) expect(proc1).to receive(:call).with(date1, 2) @plugin.__send__(:section_enter_proc, date1) @plugin.__send__(:section_leave_proc, date1) expect(proc1).to receive(:call).with(date2, 1) @plugin.__send__(:section_enter_proc, date2) @plugin.__send__(:section_leave_proc, date2) end end describe '#comment_leave_proc' do let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_comment_leave_proc ){|date| 'comment1 ' } @plugin.__send__(:add_comment_leave_proc ){|date| 'comment2' } end subject { @plugin.__send__(:comment_leave_proc, date) } it 'add_comment_leave_procで登録したブロックが実行されること' do is_expected.to eq 'comment1 comment2' end end describe '#edit_proc' do let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_edit_proc){|date| 'edit1 ' } @plugin.__send__(:add_edit_proc){|date| 'edit2' } end subject { @plugin.__send__(:edit_proc, date) } it 'add_edit_procで登録したブロックが実行されること' do is_expected.to eq 'edit1 edit2' end end describe '#form_proc' do let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_form_proc){|date| 'form1 ' } @plugin.__send__(:add_form_proc){|date| 'form2' } end subject { @plugin.__send__(:form_proc, date) } it 'add_form_procで登録したブロックが実行されること' do is_expected.to eq 'form1 form2' end end describe '#add_conf_proc' do let(:proc) { lambda { 'conf' } } subject { @plugin.__send__(:add_conf_proc, 'key1', 'label1', nil, &proc) } context '@modeがconfの場合' do before { @plugin.instance_variable_set(:@mode, 'conf') } it 'コールバックを登録すること' do is_expected.to include('label1') end end context '@modeがsaveconfの場合' do before { @plugin.instance_variable_set(:@mode, 'saveconf') } it 'コールバックを登録すること' do is_expected.to include('label1') end end context '@modeがconf, saveconf以外の場合' do before { @plugin.instance_variable_set(:@mode, 'edit') } it 'コールバックの登録を無視すること' do is_expected.to be_nil end end end describe '#conf_proc' do let (:date) { Time.local(2012, 1, 2) } before do @plugin.instance_variable_set(:@mode, 'conf') @plugin.__send__(:add_conf_proc, 'key1', 'label1', nil){ 'conf1' } @plugin.__send__(:add_conf_proc, 'key2', 'label2', nil){ 'conf2' } end subject { @plugin.__send__(:conf_proc, 'key1') } it 'add_conf_procで登録したブロックのうち、keyが一致するものを実行して結果を返すこと' do is_expected.to eq 'conf1' end end describe '#remove_tag' do before { @string = 'test example.com' } subject { @plugin.__send__(:remove_tag, @string) } it '文字列からタグが除去されること' do is_expected.to eq 'test example.com' end end describe '#apply_plugin' do before do @plugin.instance_variable_get(:@conf).options['apply_plugin'] = true end subject { @plugin.__send__(:apply_plugin, '<%= sample %>') } it 'プラグインが再実行されること' do is_expected.to eq 'sample plugin' end context '解釈できない文字列を渡された場合' do subject { @plugin.__send__(:apply_plugin, '<%= undefined_method %>') } it { is_expected.to include 'Invalid Text' } end context '文字列がnilの場合' do subject { @plugin.__send__(:apply_plugin, nil) } it { is_expected.to eq '' } end context 'remove_tagがtrueの場合' do it 'remove_tagメソッドを呼び出すこと' do expect(@plugin).to receive(:remove_tag) @plugin.__send__(:apply_plugin, '', true) end end end describe '#content_proc' do let (:proc1) { lambda {|date| "contents1" } } let (:proc2) { lambda {|date| "contents2" } } let (:date) { Time.local(2012, 1, 2) } before do @plugin.__send__(:add_content_proc, 'key1', &proc1) @plugin.__send__(:add_content_proc, 'key2', &proc2) end subject { @plugin.__send__(:content_proc, 'key1', date) } it 'add_content_procで登録したブロックのうち、keyに相当するものを実行すること' do is_expected.to eq 'contents1' end context 'keyに相当するブロックが存在しない場合' do subject { @plugin.__send__(:content_proc, 'unregistered_key', date) } it { expect { subject }.to raise_error(TDiary::PluginError) } end end describe '#startup_proc' do let (:proc) { lambda { "some plugin" } } let (:app) { lambda { "tdiary application" } } before do @plugin.__send__(:add_startup_proc, &proc) end it 'add_startup_procで登録したブロックが実行されること' do expect(proc).to receive(:call).with(app) @plugin.__send__(:startup_proc, app) end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/rack/000077500000000000000000000000001362645730700165575ustar00rootroot00000000000000tdiary-core-5.1.1/spec/core/rack/html_anchor_spec.rb000066400000000000000000000032701362645730700224160ustar00rootroot00000000000000require 'spec_helper' require 'rack/test' require 'tdiary/rack/html_anchor' describe TDiary::Rack::HtmlAnchor do include Rack::Test::Methods describe "html anchor" do let(:app) { TDiary::Rack::HtmlAnchor.new( lambda{|env| [200, {}, ['Awesome']]} )} it 'should not do anything for root access' do get '/' expect(last_request.params['date']).to eq(nil) expect(last_request.query_string).to eq('') end it 'should remove the file name from PATH_INFO' do get '/20120501.html' expect(last_request.env['PATH_INFO']).to eq('/') get '/diary/20120501.html' expect(last_request.env['PATH_INFO']).to eq('/diary/') end it 'should add date query' do get '/diary/0501.html' expect(last_request.params['date']).to eq("0501") get '/0501.html' expect(last_request.params['date']).to eq("0501") get '/201205.html' expect(last_request.params['date']).to eq("201205") get '/20120501.html' expect(last_request.params['date']).to eq("20120501") end it 'should add date query when using section_permalink_anchor plugin' do get '/20120501p01.html' expect(last_request.params['date']).to eq("20120501") expect(last_request.params['p']).to eq("01") end it 'should replace date query' do get '/20120501.html?date=20120101' expect(last_request.params['date']).to eq("20120501") end it 'should not break original query' do get '/?date=20120501' expect(last_request.params['date']).to eq("20120501") get '/index.rb?date=20120501' expect(last_request.params['date']).to eq("20120501") get '/index.rb?date=20120501&p=01' expect(last_request.params['date']).to eq("20120501") expect(last_request.params['p']).to eq("01") end end end tdiary-core-5.1.1/spec/core/rack/static_spec.rb000066400000000000000000000017751362645730700214170ustar00rootroot00000000000000require 'spec_helper' require 'rack/test' require 'tdiary/rack/static' describe TDiary::Rack::Static do include Rack::Test::Methods describe "reserve static files" do let(:app) { TDiary::Rack::Static.new( lambda{|env| [500, {}, ['Internal Server Error']]}, ['doc'])} it 'should return the file in static directory' do get '/README.md' expect(last_response).to be_ok end it 'should run the app if file is not exist' do get '/index.rb' expect(last_response.status).to be 500 end it 'should run the app when post method' do post '/index.rb' expect(last_response.status).to be 500 end end describe "resurve mutiple static files" do let(:app) { TDiary::Rack::Static.new( lambda{|env| [500, {}, ['Internal Server Error']]}, ['js', 'theme'])} it 'should return the file in js directory' do get '/00default.js' expect(last_response).to be_ok end it 'should return the file in theme directory' do get '/base.css' expect(last_response).to be_ok end end end tdiary-core-5.1.1/spec/core/rack/valid_request_path_spec.rb000066400000000000000000000031761362645730700240100ustar00rootroot00000000000000require 'spec_helper' require 'rack/test' require 'tdiary/rack/valid_request_path' describe TDiary::Rack::ValidRequestPath do include Rack::Test::Methods describe "valid request" do let(:app) { TDiary::Rack::ValidRequestPath.new( lambda{|env| [200, {}, ['Awesome']]} )} it 'should return 200 for latest' do get '/' expect(last_response).to be_ok end it 'should return 200 for a nyear' do get '/0501.html' expect(last_response).to be_ok end it 'should return 200 for a month' do get '/201205.html' expect(last_response).to be_ok end it 'should return 200 for a day' do get '/20120501.html' expect(last_response).to be_ok end it 'should return 200 for a day with section_permalink_anchor plugin' do get '/20120501p01.html' expect(last_response).to be_ok end it 'should return 200 for a day with query' do get '/?date=20120501' expect(last_response).to be_ok end it 'should return 200 for a day with query and section_permalink_anchor plugin' do get '/?date=20120501&p=01' expect(last_response).to be_ok end it 'should return 200 for a day with index.rb and query' do get '/index.rb?date=20120501' expect(last_response).to be_ok end it 'should return 404 for access to the invalid file' do get '/20120501' expect(last_response.status).to be 404 get '/invalid' expect(last_response.status).to be 404 head '/invalid' expect(last_response.status).to be 404 expect(last_response.body.length).to be 0 end it 'should return 404 for access to the invalid directory' do get '/invalid/' expect(last_response.status).to eq(404) end end end tdiary-core-5.1.1/spec/core/style/000077500000000000000000000000001362645730700167775ustar00rootroot00000000000000tdiary-core-5.1.1/spec/core/style/tdiary_style_spec.rb000066400000000000000000000127471362645730700230650ustar00rootroot00000000000000require 'spec_helper' require 'tdiary' require 'tdiary/style/tdiary' describe TDiary::Style::TdiaryDiary do before :all do klass = TDiary::Style::TdiaryDiary klass.send(:include, TDiary::Style::BaseDiary) klass.send(:include, TDiary::Style::CategorizableDiary) end before do @diary = TDiary::Style::TdiaryDiary.new(Time::at( 1041346800 ), "TITLE", "") end describe '#append' do before do @source = <<-'EOF' subTitle

    honbun

    subTitle2

    honbun

    EOF @diary.append(@source) end context 'HTML' do before do @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end context 'CHTML' do before do @html = <<-'EOF' <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %> <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end context 'to_src' do it { expect(@diary.to_src).to eq @source } end end describe '#replace' do before do source = <<-'EOF' subTitle

    honbun

    subTitle2

    honbun

    EOF @diary.append(source) replaced = <<-'EOF' replaceTitle

    replace

    replaceTitle2

    replace

    EOF @diary.replace(Time::at( 1041346800 ), "TITLE", replaced) @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "replaceTitle" ) %>

    replace

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "replaceTitle2" ) %>

    replace

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end describe '#add_section' do before do source = <<-'EOF' subTitle

    honbun

    EOF @diary.append(source) @diary.add_section('subTitle2', '

    honbun

    ') @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end describe '#delete_section' do before do source = <<-'EOF' subTitle

    honbun

    subTitle2

    honbun

    EOF @diary.append(source) @diary.delete_section(1) @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end describe 'test_tdiary_style2' do before do source = <<-'EOF' <subTitle

    honbun

    EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end context 'CHTML' do before do @html = <<-'EOF' <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    honbun

    <%= section_leave_proc( Time::at( 1041346800 ) ) %> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end describe 'test_tdiary_style_plugin' do before do source = <<-'EOF' subTitle <%= plugin %> <%= plugin %> aaa <%= plugin %> a<%=ho ge%>b <%=ho ge%> EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    <%= plugin %> <%= plugin %> aaa <%= plugin %> a<%=ho ge%>b <%=ho ge%><%= section_leave_proc( Time::at( 1041346800 ) ) %>
    EOF end it { expect(@diary.to_html).to eq @html.chomp } end context 'CHTML' do before do @html = <<-'EOF' <%= section_enter_proc( Time::at( 1041346800 ) ) %>

    <%= subtitle_proc( Time::at( 1041346800 ), "subTitle" ) %>

    <%= plugin %> <%= plugin %> aaa <%= plugin %> a<%=ho ge%>b <%=ho ge%><%= section_leave_proc( Time::at( 1041346800 ) ) %> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/style/wiki_style_spec.rb000066400000000000000000000215711362645730700225270ustar00rootroot00000000000000require 'spec_helper' require 'tdiary' require 'tdiary/style/wiki' describe TDiary::Style::WikiDiary do before :all do klass = TDiary::Style::WikiDiary klass.send(:include, TDiary::Style::BaseDiary) klass.send(:include, TDiary::Style::CategorizableDiary) TDiary::Style::WikiSection.send(:include, TDiary::Style::BaseSection) end before do @diary = TDiary::Style::WikiDiary.new(Time::at( 1041346800 ), "TITLE", "") end describe '#append' do before do @source = <<-'EOF' ! subTitle honbun !! subTitleH4 honbun EOF @diary.append(@source) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    subTitleH4

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    subTitleH4

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end context 'to_src' do it { expect(@diary.to_src).to eq @source } end end describe '#replace' do before do source = <<-'EOF' ! subTitle honbun !! subTitleH4 honbun EOF @diary.append(source) replaced = <<-'EOF' ! replaceTitle replace !! replaceTitleH4 replace EOF @diary.replace(Time.at( 1041346800 ), "TITLE", replaced) @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "replaceTitle" ) %>

    replace

    replaceTitleH4

    replace

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end describe '#add_section' do before do source = <<-'EOF' ! subTitle honbun !! subTitleH4 honbun EOF @diary.append(source) @diary.add_section('subTitle2', 'honbun') @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    subTitleH4

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end describe '#delete_section' do before do source = <<-'EOF' ! subTitle honbun ! subTitle2 honbun EOF @diary.append(source) @diary.delete_section(1) @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle2" ) %>

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end describe 'test_wiki_style2' do before do source = <<-'EOF' subTitle honbun honbun EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end describe 'test_wiki_style3' do before do source = <<-'EOF' subTitle honbun honbun ! subTitle honbun EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%> <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    honbun

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end describe 'test_wiki_style_plugin' do before do source = <<-'EOF' ! subTitle {{plugin}} {{plugin}} aaa {{plugin}} a{{ho ge}}b {{ho ge}} EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    <%=plugin %> <%=plugin %> aaa

    <%=plugin %>

    a<%=ho ge %>b

    <%=ho ge %>

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    <%=plugin %> <%=plugin %> aaa

    <%=plugin %>

    a<%=ho ge %>b

    <%=ho ge %>

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end describe 'test_wiki_style_kw' do before do source = <<-'EOF' ! subTitle [[aaa]] [[aaa|bbb]] [[aaa'bbb|ccc]] [[aaa|aaa]] [[aaa:鯖]] [[aaa|bbb:ccc]] [[aaa'bbb|bbb:ccc]] [[鯖|http://ja.wikipedia.org/wiki/%E9%AF%96]] http://ja.wikipedia.org/wiki/%E9%AF%96 {{''}} EOF @diary.append(source) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    <%=kw 'aaa', 'aaa'%>

    aaa

    aaa'bbb

    <%=kw 'aaa', 'aaa'%>

    <%=kw 'aaa:鯖'%>

    <%=kw 'bbb:ccc', 'aaa'%>

    <%=kw 'bbb:ccc', 'aaa\'bbb'%>

    http://ja.wikipedia.org/wiki/%E9%AF%96

    <%='' %>

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    <%=kw 'aaa', 'aaa'%>

    aaa

    aaa'bbb

    <%=kw 'aaa', 'aaa'%>

    <%=kw 'aaa:鯖'%>

    <%=kw 'bbb:ccc', 'aaa'%>

    <%=kw 'bbb:ccc', 'aaa\'bbb'%>

    http://ja.wikipedia.org/wiki/%E9%AF%96

    <%='' %>

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end describe 'test_append_without_subtitle' do before do source = <<-'EOF' ! subTitle body EOF sourceappend = <<-'EOF' appended body EOF @diary.append(source) @diary.append(sourceappend) end context 'HTML' do before do @html = <<-'EOF'
    <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    body

    appended body

    <%=section_leave_proc( Time.at( 1041346800 ) )%>
    EOF end it { expect(@diary.to_html).to eq @html } end context 'CHTML' do before do @html = <<-'EOF' <%=section_enter_proc( Time.at( 1041346800 ) )%>

    <%= subtitle_proc( Time.at( 1041346800 ), "subTitle" ) %>

    body

    appended body

    <%=section_leave_proc( Time.at( 1041346800 ) )%> EOF end it { expect(@diary.to_html({}, :CHTML)).to eq @html } end end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: tdiary-core-5.1.1/spec/core/tdiary_spec.rb000066400000000000000000000015251362645730700204750ustar00rootroot00000000000000require 'spec_helper' require 'fileutils' describe TDiary do describe 'LOAD_PATH' do before do @root_path = File.expand_path(File.dirname(__FILE__) + '/../..') @loaded_paths = $LOAD_PATH.map{|path| File.expand_path(path)} end it "include misc path into load path" do expect(@loaded_paths).to be_include @root_path + '/misc/lib' end context 'append gem' do before do FileUtils.mkdir_p @root_path + '/misc/lib/foo-0.0.1/lib' load @root_path + '/lib/tdiary.rb' @loaded_paths = $LOAD_PATH.map{|path| File.expand_path(path)} end it "include append gem path into load path" do expect(@loaded_paths).to be_include @root_path + '/misc/lib/foo-0.0.1/lib' end after do FileUtils.rm_rf @root_path + '/misc/lib/foo-0.0.1' end end end end tdiary-core-5.1.1/spec/fixtures/000077500000000000000000000000001362645730700165605ustar00rootroot00000000000000tdiary-core-5.1.1/spec/fixtures/ascii8bit-pstore.db000066400000000000000000000001451362645730700222600ustar00rootroot00000000000000{ I" key1:ETI" val1;TI" key2;TiI" key3;T[i:symI" string;T:__ruby_versionI" 1.9.2;Ftdiary-core-5.1.1/spec/fixtures/invalid-sequence-volatile.tdr000066400000000000000000000014231362645730700243440ustar00rootroot00000000000000TDIARY2.01.00 Date: 20110903 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBT&squery=%90%F3%91%90+TX+%89%FC%8ED&p=%90%F3%91%90ROX 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBB&squery=%91%7C%8F%9C%8B%40+%83S%83%7E&p=%91%7C%8F%9C%8B%40+%94R%82%A6%82%C8%82%A2 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBB&squery=%90%BC%90V%88%E4%91%E5%8Et&p=%90%BC%90V%88%E4%91%E5%8Et+%8E%9E%8A%D4&ySiD=23NjTh_AUPlo.gySXLMi&guid=ON 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBB&squery=%83Z%83b%83g%83A%83b%83v&p=WINDOWS%83Z%83b%83g%83A%83b%83v 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBB&squery=%82%A2%82%E2%82%E7%82%B5%82%A2%8B%B3%89%C8%8F%91&p=%82%A2%82%E2%82%E7%82%B5%82%A2%8B%B3%89%C8%8F%91%82%F0%82%C2%82%AD%82%E9%89%EF&ySiD=ajxjTqpWDxBP406zDtDL&guid=ON . tdiary-core-5.1.1/spec/fixtures/jpB00H91KK26.xml000066400000000000000000000464561362645730700210540ustar00rootroot00000000000000
    7b5b52d5-0cd2-4f9b-a332-7ff730f0749d 0.0122226640000000 True ASIN B00H91KK26 Medium All B00H91KK26 http://www.amazon.co.jp/maaash-jp-IRKit-001-IRKit-iPhone-iPad%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E5%A4%96%E5%87%BA%E5%85%88%E3%81%8B%E3%82%89%E3%82%A8%E3%82%A2%E3%82%B3%E3%83%B3%E7%AD%89%E3%81%AE%E5%AE%B6%E9%9B%BB%E3%82%92%E6%93%8D%E4%BD%9C%E3%81%A7%E3%81%8D%E3%82%8B%E5%AD%A6%E7%BF%92%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3/dp/B00H91KK26%3FSubscriptionId%3DAKIAIXYTNSOEGXJVP5SQ%26tag%3Dhsbtdiary-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00H91KK26 Add To Wishlist http://www.amazon.co.jp/gp/registry/wishlist/add-item.html%3Fasin.0%3DB00H91KK26%26SubscriptionId%3DAKIAIXYTNSOEGXJVP5SQ%26tag%3Dhsbtdiary-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB00H91KK26 Tell A Friend http://www.amazon.co.jp/gp/pdp/taf/B00H91KK26%3FSubscriptionId%3DAKIAIXYTNSOEGXJVP5SQ%26tag%3Dhsbtdiary-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB00H91KK26 All Customer Reviews http://www.amazon.co.jp/review/product/B00H91KK26%3FSubscriptionId%3DAKIAIXYTNSOEGXJVP5SQ%26tag%3Dhsbtdiary-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB00H91KK26 All Offers http://www.amazon.co.jp/gp/offer-listing/B00H91KK26%3FSubscriptionId%3DAKIAIXYTNSOEGXJVP5SQ%26tag%3Dhsbtdiary-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB00H91KK26 790 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL75_.jpg 53 75 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL160_.jpg 114 160 http://ecx.images-amazon.com/images/I/31HuSy3ACXL.jpg 356 500 http://ecx.images-amazon.com/images/I/31MfCSF9ujL._SL30_.jpg 23 30 http://ecx.images-amazon.com/images/I/31MfCSF9ujL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31MfCSF9ujL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31MfCSF9ujL._SL110_.jpg 83 110 http://ecx.images-amazon.com/images/I/31MfCSF9ujL._SL160_.jpg 120 160 http://ecx.images-amazon.com/images/I/31MfCSF9ujL.jpg 376 500 http://ecx.images-amazon.com/images/I/31wAZ4hn92L._SL30_.jpg 22 30 http://ecx.images-amazon.com/images/I/31wAZ4hn92L._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31wAZ4hn92L._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31wAZ4hn92L._SL110_.jpg 82 110 http://ecx.images-amazon.com/images/I/31wAZ4hn92L._SL160_.jpg 120 160 http://ecx.images-amazon.com/images/I/31wAZ4hn92L.jpg 375 500 http://ecx.images-amazon.com/images/I/313dMQCO1sL._SL30_.jpg 22 30 http://ecx.images-amazon.com/images/I/313dMQCO1sL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/313dMQCO1sL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/313dMQCO1sL._SL110_.jpg 82 110 http://ecx.images-amazon.com/images/I/313dMQCO1sL._SL160_.jpg 120 160 http://ecx.images-amazon.com/images/I/313dMQCO1sL.jpg 375 500 http://ecx.images-amazon.com/images/I/31yzffM286L._SL30_.jpg 22 30 http://ecx.images-amazon.com/images/I/31yzffM286L._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31yzffM286L._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31yzffM286L._SL110_.jpg 82 110 http://ecx.images-amazon.com/images/I/31yzffM286L._SL160_.jpg 120 160 http://ecx.images-amazon.com/images/I/31yzffM286L.jpg 375 500 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL._SL30_.jpg 22 30 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL._SL75_.jpg 56 75 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL._SL110_.jpg 82 110 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL._SL160_.jpg 119 160 http://ecx.images-amazon.com/images/I/31yBmiV6F%2BL.jpg 372 500 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL30_.jpg 21 30 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL75_.jpg 53 75 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL75_.jpg 53 75 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL110_.jpg 78 110 http://ecx.images-amazon.com/images/I/31HuSy3ACXL._SL160_.jpg 114 160 http://ecx.images-amazon.com/images/I/31HuSy3ACXL.jpg 356 500 エレクトロニクス maaash.jp 4580499150012 4580499150012 iPhone, iPad, iPodTouchのiOS7以降対応 Android 2.3以降対応 無線LAN:2.4GHzのb,g対応 (5GHz帯のaは未対応) DHCPでIPアドレスとDNSサーバのIPアドレスを取得できること(IPアドレス指定はできません) 電源:USBマイクロBケーブル(別売り) 67 244 244 7700 JPY ¥ 7,700 maaash.jp IRKit-001 IRKit-001 122 366 12 350 1 IRKit-001 CE REMOTE_CONTROL maaash.jp 65 x 62 x 17 [mm] maaash.jp IRKit - iPhone,iPadを使って外出先からエアコン等の家電を操作できる学習リモコン 7700 JPY ¥ 7,700 2 0 0 0 Product Description IRKitは、WiFi機能の付いたオープンソースな赤外線リモコンデバイス。<br> 家庭のエアコンやテレビ、ライトなど、赤外線で操作できる家電を、<br> WiFiをとおして、iPhoneやiPadなどから操作できるようにするものです。<br> <br> IRKitは、公式のリモコンアプリから操作できるほか、<br> IRKit iOS-SDKを使えば、<br> 任意のタイミングで赤外線信号を送ることのできるiOSアプリを簡単につくることができます。<br> <br> 例えば<br> * 位置情報を使いiPhoneが家の近くに来たら自動でエアコンを付けるアプリ<br> <br> * ソーシャルと連携してFacebook友だちの見ているテレビにチャンネルを合わせるアプリ<br> など、家電を操作する様々なアプリの可能性があるでしょう。<br> <br> また、JavaScriptを使ってブラウザから赤外線信号を送ることもできます。<br> <br> IRKitデバイス自体にHTTPサーバがあり、<br> JSON形式の赤外線情報を HTTP POSTリクエストにのせて送ることで、赤外線信号を送ることができるのです。<br> <br> また、IRKitと同じWiFiにいなくても、外出先から赤外線信号を送るための、インターネット上にあるサーバのAPIも公開しています。<br> <br> IRKitデバイスは、Arduino Derivative(派生)のプロダクトです。<br> 未使用のピンは引き出してあるので、温度センサや明るさセンサなどを追加し、ArduinoIDEを使ってプログラムを書き込めば、<br> よりスマートなリモコンをつくることもできます。<br> 詳しくは http://getirkit.com/ をご覧ください 0 tdiary-core-5.1.1/spec/fixtures/just_installed.conf000066400000000000000000000000421362645730700224470ustar00rootroot00000000000000tdiary_version = "2.3.3.20100515" tdiary-core-5.1.1/spec/fixtures/plugin/000077500000000000000000000000001362645730700200565ustar00rootroot00000000000000tdiary-core-5.1.1/spec/fixtures/plugin/ja/000077500000000000000000000000001362645730700204505ustar00rootroot00000000000000tdiary-core-5.1.1/spec/fixtures/plugin/ja/sample.rb000066400000000000000000000000631362645730700222550ustar00rootroot00000000000000def sample_ja 'サンプルプラグイン' end tdiary-core-5.1.1/spec/fixtures/plugin/sample.rb000066400000000000000000000000711362645730700216620ustar00rootroot00000000000000def sample 'sample plugin' end add_header_proc do end tdiary-core-5.1.1/spec/fixtures/sample.rb000066400000000000000000000002541362645730700203670ustar00rootroot00000000000000module TDiary::Filter class SampleFilter < Filter end end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: # vim: ts=3 tdiary-core-5.1.1/spec/fixtures/tdiary.conf.gem000066400000000000000000000156501362645730700215010ustar00rootroot00000000000000@data_path = File.expand_path("tmp/data", File.dirname(__FILE__)) @style = 'Wiki' @index = './' @update = 'update.rb' @options['apply_plugin'] = true @options['sp.path'] = [ 'misc/plugin' ] @accesskey_enabled = false @options['bot'] = [ '^BlogLines/', '^blogmap', 'MI[CK]AN/', '^NG/', '^samidare', '^TAMATEBAKO/' ] @options['sp.selected'] = "amazon.rb append-css.rb calendar2.rb category.rb comment_mail-smtp.rb disp_referrer.rb dropdown_calendar.rb footnote.rb highlight.rb image.rb jdate.rb kw.rb makerss.rb my-ex.rb recent_comment3.rb recent_list.rb " @options['dropdown_calendar.label'] = '過去の日記' @options['makerss.file'] = 'index.rdf' @options['makerss.no_comments.file'] = 'no_comments.rdf' @options['spamfilter.bad_comment_patts'] = "(href=|casino|gambling|betting|fastsearch\\.eu\\.com|ganzao|poker|holdem|hold.em|roulette|drug|tramadol|viagra|fioricet|oxycontin|biaxin|aldara|business cards|home depot|slot.?machine|insurance|getblog2|video-game|Good site|internet-all\\.com|deai|tdfms|comu2|omaha)\r\n" @options['spamfilter.bad_ip_addrs'] = "" @options['spamfilter.bad_mail_patts'] = "(mu@alloha\\.info|mumu2004@mail\\.com|zhongleibo|dfd@12\\.com|anonimous|aol\\.|yahoo\\.|google\\.|hotmail\\.|msn\\.|leroy\\.|ablare\\.|gmx\\.|lorazepam|\\.co$)" @options['spamfilter.bad_uri_patts'] = "" @options['spamfilter.bad_uri_patts_for_mails'] = false @options['spamfilter.debug_file'] = "" @options['spamfilter.debug_mode'] = false @options['spamfilter.filter_mode'] = true @options['spamfilter.max_uris'] = "2" @options['spamfilter.resolv_check'] = false @options['spamfilter.resolv_check_mode'] = false @options['spamlookup.domain.list'] = "bsb.spamlookup.net\r\nmulti.surbl.org\r\nrbl.bulkfeeds.jp" @options['spamlookup.safe_domain.list'] = "search.yahoo.co.jp\r\nwww.google.com\r\nwww.google.co.jp\r\nsearch.msn.co.jp" @html_title = %Q[【日記のタイトル】(→サイトの情報で変更しましょう)] @header = <

    <%= @conf.html_title %>

    HEADER @footer = <