├── .coveralls.yml ├── .devcontainer ├── Dockerfile ├── Gemfile.local ├── README.md ├── devcontainer.json ├── run-app.sh ├── setup-app.sh └── tdiary.conf ├── .dockerignore ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── release-checklist.md ├── dependabot.yml └── workflows │ ├── build-image.yml │ └── ci.yml ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── ChangeLog ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Procfile ├── README.md ├── Rakefile ├── app.json ├── benchmark ├── benchmark_amazon_plugin.rb └── benchmark_io_default.rb ├── bin └── tdiary ├── config.ru ├── data └── .htaccess ├── doc ├── HOWTO-authenticate-in-rack.md ├── HOWTO-make-io.md ├── HOWTO-make-plugin.md ├── HOWTO-make-theme.md ├── HOWTO-testing-tDiary.md ├── HOWTO-use-plugin.md ├── HOWTO-write-tDiary.en.md ├── HOWTO-write-tDiary.md ├── INSTALL-cgi.md ├── INSTALL-paas.md ├── INSTALL-rack.md ├── INSTALL.md ├── README.en.md ├── README.md ├── UPGRADE.md └── doc.css ├── dot.htaccess ├── index.fcgi ├── index.rb ├── js ├── 00default.js ├── 01conf.js ├── 02edit.js ├── amazon.js ├── amazon_bitly.js ├── calendar3.js ├── caretposition.js ├── category.js ├── category_autocomplete.js ├── comment_ajax.js ├── comment_emoji_autocomplete.js ├── draft.js ├── highlight.js ├── image.js └── preview.js ├── lib ├── aws │ ├── pa_api.rb │ └── sig_v4.rb ├── rack │ └── server.rb ├── tdiary.rb └── tdiary │ ├── admin.rb │ ├── application.rb │ ├── author_only_base.rb │ ├── base.rb │ ├── cache │ └── file.rb │ ├── cli.rb │ ├── comment.rb │ ├── comment_manager.rb │ ├── compatible.rb │ ├── configuration.rb │ ├── core_ext.rb │ ├── diary_container.rb │ ├── dispatcher.rb │ ├── dispatcher │ ├── index_main.rb │ └── update_main.rb │ ├── environment.rb │ ├── extensions.rb │ ├── extensions │ └── core.rb │ ├── filter.rb │ ├── filter │ ├── default.rb │ └── spam.rb │ ├── io │ ├── base.rb │ ├── default.rb │ ├── plugin_pstore.rb │ └── pstore.rb │ ├── lang │ ├── en.rb │ └── ja.rb │ ├── plugin.rb │ ├── plugin │ ├── 00default.rb │ ├── 03purge_cache.rb │ ├── 05referer.rb │ ├── 10spamfilter.rb │ ├── 50sp.rb │ ├── 60sf.rb │ ├── 90migrate.rb │ ├── en │ │ ├── 00default.rb │ │ ├── 05referer.rb │ │ ├── 10spamfilter.rb │ │ ├── 50sp.rb │ │ └── 60sf.rb │ └── ja │ │ ├── 00default.rb │ │ ├── 05referer.rb │ │ ├── 10spamfilter.rb │ │ ├── 50sp.rb │ │ └── 60sf.rb │ ├── rack.rb │ ├── rack │ ├── auth.rb │ ├── auth │ │ ├── basic.rb │ │ ├── omniauth.rb │ │ └── omniauth │ │ │ └── authorization.rb │ ├── html_anchor.rb │ ├── session.rb │ ├── static.rb │ └── valid_request_path.rb │ ├── referer_manager.rb │ ├── request.rb │ ├── response.rb │ ├── server.rb │ ├── style.rb │ ├── style │ ├── tdiary.rb │ └── wiki.rb │ ├── tasks.rb │ ├── tasks │ ├── assets.rake │ ├── auth.rake │ ├── db.rake │ ├── doc.rake │ ├── heroku.rake │ ├── mongodb.rake │ ├── rdoc.rake │ ├── release.rake │ ├── rspec.rake │ ├── server.rake │ └── test.rake │ ├── version.rb │ ├── view.rb │ └── view_helper.rb ├── misc ├── convert2.rb ├── filter │ ├── antispamservice.rb │ ├── limitdays.rb │ ├── linkcheck.rb │ └── plugin │ │ ├── antispamservice.rb │ │ ├── en │ │ └── antispamservice.rb │ │ └── ja │ │ └── antispamservice.rb ├── lib │ ├── README │ ├── compatible.rb │ └── fcgi_patch.rb ├── migrate.rb ├── paas │ └── heroku │ │ ├── Gemfile.local │ │ ├── Gemfile.lock │ │ ├── misc │ │ └── plugin │ │ │ └── system_update.rb │ │ └── tdiary.conf ├── plugin │ ├── ChangeLog.DO_NOT_UPDATE │ ├── a.rb │ ├── amazon.rb │ ├── amp.rb │ ├── append-css.rb │ ├── bq.rb │ ├── calendar2.rb │ ├── calendar3.rb │ ├── category-legacy.rb │ ├── category.rb │ ├── category_autocomplete.rb │ ├── comment_ajax.rb │ ├── comment_emoji_autocomplete.rb │ ├── comment_mail-qmail.rb │ ├── comment_mail-sendmail.rb │ ├── comment_mail-smtp.rb │ ├── comment_rank.rb │ ├── counter.rb │ ├── daily_theme.rb │ ├── disp_referrer.rb │ ├── doctype-html401tr.rb │ ├── draft.rb │ ├── dropdown_calendar.rb │ ├── edit_today.rb │ ├── en │ │ ├── a.rb │ │ ├── amazon.rb │ │ ├── append-css.rb │ │ ├── bq.rb │ │ ├── calendar2.rb │ │ ├── category-legacy.rb │ │ ├── category.rb │ │ ├── counter.rb │ │ ├── daily_theme.rb │ │ ├── disp_referrer.rb │ │ ├── dropdown_calendar.rb │ │ ├── edit_today.rb │ │ ├── hide-mail-field.rb │ │ ├── highlight.rb │ │ ├── image.rb │ │ ├── kw.rb │ │ ├── makerss.rb │ │ ├── pb-show.rb │ │ ├── ping.rb │ │ ├── preview.rb │ │ ├── recent_comment.rb │ │ ├── recent_comment3.rb │ │ ├── recent_rss.rb │ │ ├── referer_scheme.rb │ │ ├── search_control.rb │ │ ├── search_form.rb │ │ ├── speed_comment.rb │ │ ├── tb-show.rb │ │ ├── todo.rb │ │ ├── weather.rb │ │ └── xmlrpc.rb │ ├── footnote.rb │ ├── gradation.rb │ ├── gradient.rb │ ├── hide-mail-field.rb │ ├── highlight.rb │ ├── html_anchor.rb │ ├── image.rb │ ├── ja │ │ ├── amazon.rb │ │ ├── bq.rb │ │ ├── calendar2.rb │ │ ├── category-legacy.rb │ │ ├── category.rb │ │ ├── daily_theme.rb │ │ ├── disp_referrer.rb │ │ ├── edit_today.rb │ │ ├── hide-mail-field.rb │ │ ├── highlight.rb │ │ ├── makerss.rb │ │ ├── my-sequel.rb │ │ ├── pb-show.rb │ │ ├── ping.rb │ │ ├── preview.rb │ │ ├── recent_comment.rb │ │ ├── recent_comment3.rb │ │ ├── recent_rss.rb │ │ ├── referer_scheme.rb │ │ ├── search_control.rb │ │ ├── search_form.rb │ │ ├── tb-show.rb │ │ ├── todo.rb │ │ ├── weather.rb │ │ └── xmlrpc.rb │ ├── kw.rb │ ├── list.rb │ ├── makelirs.rb │ ├── makerss.rb │ ├── my-ex.rb │ ├── my-sequel.rb │ ├── navi_user.rb │ ├── number_anchor.rb │ ├── pb-show.rb │ ├── ping.rb │ ├── pre_wrap.rb │ ├── preview.rb │ ├── random_google.rb │ ├── recent_comment.rb │ ├── recent_comment3.rb │ ├── recent_list.rb │ ├── recent_namazu.rb │ ├── recent_rss.rb │ ├── referer-antibot.rb │ ├── referer-utf8.rb │ ├── referer_scheme.rb │ ├── search-default.rb │ ├── search_control.rb │ ├── search_form.rb │ ├── sn.rb │ ├── speed_comment.rb │ ├── src.rb │ ├── tb-show.rb │ ├── theme_online.rb │ ├── title_list.rb │ ├── title_tag.rb │ ├── tlink.rb │ ├── todo.rb │ ├── weather.rb │ ├── whatsnew.rb │ ├── xmlrpc.rb │ └── xmlrpc │ │ ├── README │ │ └── xmlrpc.rb └── templates │ └── Gemfile.local.erb ├── package-lock.json ├── package.json ├── public └── .gitkeep ├── spec ├── acceptance │ ├── append_comment_spec.rb │ ├── append_diary_spec.rb │ ├── bugfix │ │ └── encoding_error_spec.rb │ ├── save_conf_comment_spec.rb │ ├── save_conf_default_spec.rb │ ├── save_conf_dnsbl_spec.rb │ ├── save_conf_filter_spec.rb │ ├── save_conf_plugin_spec.rb │ ├── save_conf_referer_spec.rb │ ├── save_conf_security_spec.rb │ ├── support │ │ ├── helpers.rb │ │ └── paths.rb │ ├── update_diary_spec.rb │ ├── view_category_spec.rb │ ├── view_comment_spec.rb │ ├── view_diary_spec.rb │ └── view_referer_spec.rb ├── acceptance_helper.rb ├── core │ ├── application_spec.rb │ ├── compatible_spec.rb │ ├── configuration_spec.rb │ ├── core_ext_spec.rb │ ├── diary_container_spec.rb │ ├── io │ │ └── default_spec.rb │ ├── plugin_spec.rb │ ├── rack │ │ ├── html_anchor_spec.rb │ │ ├── static_spec.rb │ │ └── valid_request_path_spec.rb │ ├── style │ │ ├── tdiary_style_spec.rb │ │ └── wiki_style_spec.rb │ └── tdiary_spec.rb ├── fixtures │ ├── ascii8bit-pstore.db │ ├── invalid-sequence-volatile.tdr │ ├── jpB00H91KK26.xml │ ├── just_installed.conf │ ├── plugin │ │ ├── ja │ │ │ └── sample.rb │ │ └── sample.rb │ ├── sample.rb │ ├── tdiary.conf.gem │ ├── tdiary.conf.rack │ └── tdiary.conf.webrick ├── javascripts │ ├── 00default_spec.js │ ├── fixtures │ │ └── 00default.html │ └── helpers │ │ └── setup.js ├── plugin │ ├── amp_spec.rb │ ├── bq_spec.rb │ ├── makerss_spec.rb │ └── plugin_helper.rb ├── spec_helper.rb └── support │ ├── jasmine.json │ └── jasmine.mjs ├── tdiary.conf.beginner ├── tdiary.conf.sample ├── tdiary.conf.sample-en ├── tdiary.gemspec ├── test ├── disp_referrer_test.rb ├── my-sequel_test.rb ├── test_helper.rb ├── test_plugin_helper.rb ├── test_plugin_helper_test.rb ├── weather-ADDS-METARS-PHTO-140131.html ├── weather-ADDS-METARS-RJAA-130131.html ├── weather-ADDS-METARS-RJAA-130227.html └── weather_test.rb ├── theme ├── base.css ├── conf.block.png ├── conf.css ├── default │ ├── README │ ├── body.png │ └── default.css ├── help.png ├── loading.gif ├── logo │ ├── bitter.svg │ ├── pale.svg │ ├── soft.svg │ └── vivid.svg ├── ogimage.png ├── tdiary1 │ ├── README │ └── tdiary1.css └── tdiary2 │ ├── README │ └── tdiary2.css ├── tmp └── .gitkeep ├── update.fcgi ├── update.rb ├── vendor └── .gitkeep └── views ├── amp.rhtml ├── category.rhtml ├── conf.rhtml ├── day.rhtml ├── diary.rhtml ├── footer.rhtml ├── header.rhtml ├── latest.rhtml ├── mail.rtxt ├── month.rhtml ├── plugin_error.rhtml ├── preview.rhtml ├── preview.rhtml.en ├── referer.rhtml ├── search.rhtml ├── tdiary.rconf ├── update.rhtml └── update.rhtml.en /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.154.2/containers/ruby/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Ruby version: 2, 2.7, 2.6, 2.5 4 | ARG VARIANT="2" 5 | FROM mcr.microsoft.com/vscode/devcontainers/ruby:0-${VARIANT} 6 | LABEL maintainer "@tdtds " 7 | 8 | # [Option] Install Node.js 9 | ARG INSTALL_NODE="true" 10 | ARG NODE_VERSION="lts/*" 11 | RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi 12 | 13 | # [Optional] Uncomment this section to install additional OS packages. 14 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 15 | && apt-get -y install --no-install-recommends apt-utils libidn11-dev sqlite3 libsqlite3-dev 16 | 17 | # [Optional] Uncomment this line to install additional gems. 18 | ARG CORE="/workspaces/core" 19 | ENV HTPASSWD="${CORE}/.devcontainer/.htpasswd" 20 | 21 | # [Optional] Uncomment this line to install global node packages. 22 | EXPOSE 9292 23 | CMD "${CORE}/.devcontainer/run-app.sh" -------------------------------------------------------------------------------- /.devcontainer/Gemfile.local: -------------------------------------------------------------------------------- 1 | gem 'tdiary-contrib' 2 | gem 'puma' -------------------------------------------------------------------------------- /.devcontainer/README.md: -------------------------------------------------------------------------------- 1 | # Docker image for tdiary development 2 | 3 | Your editor is vscode? See bottom of this document. 4 | 5 | ## how to build an image 6 | 7 | ``` 8 | % docker build -t tdiary-devel .devcontainer 9 | ``` 10 | 11 | ## how to run in the Docker 12 | 13 | ``` 14 | % docker run -v $(pwd):/workspace -p 9292:9292 -it --rm tdiary-devel 15 | ``` 16 | 17 | or debugging `contrib` in the parent directory: 18 | 19 | ``` 20 | % docker run -v $(pwd):/usr/src/app -v $(pwd)/../contrib:/usr/src/contrib -p 9292:9292 -it --rm tdiary-devel 21 | ``` 22 | 23 | ## develoment on vscode remote-container 24 | 25 | 1. Open the folder of this repository by Remte-Container Extention, then starting build a image automatically. 26 | 2. Only at first, run `.devcontainer/setup-app.sh` for making `tdiary.conf` and `.htpasswd`. 27 | 3. Open Debug (`Ctrl + Shift + D`) and start "Debug tDiary". 28 | 4. Open [`http://localhost:9292`](http://localhost:9292) in your browser. -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.154.2/containers/ruby 3 | { 4 | "name": "tDiary-core", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | "args": { 8 | // Update 'VARIANT' to pick a Ruby version: 2, 2.7, 2.6, 2.5 9 | "VARIANT": "3", 10 | // Options 11 | "INSTALL_NODE": "false", 12 | "NODE_VERSION": "lts/*" 13 | } 14 | }, 15 | 16 | // Set *default* container specific settings.json values on container create. 17 | "settings": { 18 | //"terminal.integrated.shell.linux": "/bin/bash" 19 | }, 20 | 21 | // Add the IDs of extensions you want installed when the container is created. 22 | "extensions": [ 23 | "rebornix.Ruby", 24 | "KoichiSasada.vscode-rdbg", 25 | "github.vscode-pull-request-github" 26 | ], 27 | 28 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 29 | "forwardPorts": [9292], 30 | 31 | // Use 'postCreateCommand' to run commands after the container is created. 32 | "postCreateCommand": "/workspaces/core/.devcontainer/setup-app.sh", 33 | 34 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 35 | "remoteUser": "vscode" 36 | 37 | } -------------------------------------------------------------------------------- /.devcontainer/run-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source `dirname $0`/setup-app.sh 3 | bundle exec rackup -o 0.0.0.0 -p 9292 4 | -------------------------------------------------------------------------------- /.devcontainer/setup-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cp .devcontainer/tdiary.conf . 3 | cp .devcontainer/Gemfile.local . 4 | bundle config set path vendor/bundle 5 | bundle config set with development:test 6 | bundle install --jobs=4 --retry=3 7 | bundle exec rake assets:copy 8 | gem install debug 9 | #git ls-remote -q > /dev/null 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | .htpasswd 3 | vendor/bundle 4 | public/assets/* 5 | tdiary.pid -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.rb] 4 | indent_size = 3 5 | indent_style = tab 6 | tab_width = 3 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: 不具合の報告 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug / 不具合の説明** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce / 再現手順** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior / 期待した動作** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots / スクリーンショット** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment / 動作環境** 27 | - OS: 28 | - Browser: 29 | - tDiary Version: 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/release-checklist.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: release checklist 3 | about: 毎回のリリース作業チェックリストを提供する 4 | title: X.Y.Z リリース作業 on YYYY-MM-29 5 | labels: release 6 | assignees: '' 7 | 8 | --- 9 | 10 | リリース作業リスト 11 | - [ ] lib/tdiary/tasks/release.rake` と `.github/workflow/ci.yml` に今回サポートを追加/停止するrubyのバージョンが含まれるか確認、修正する 12 | - [ ] [releases](https://github.com/tdiary/tdiary-core/releases)にエントリを追加してリリースノートを書く 13 | - [ ] coreおよびblogkitのChangeLogに「release L.M.N」のエントリを追加する 14 | - [ ] 以下のファイルのバージョンをあげてcommitする 15 | - coreの lib/tdiary/version.rb 16 | - blogkitの lib/tdiary/blogkit/version.rb 17 | - contribの lib/tdiary/contrib/version.rb 18 | - [ ] core / blogkit / contrib / theme に tag を打つ (`git pull --tags; git tag vL.M.N; git push origin vL.M.N`) 19 | - [ ] 以下の各リポジトリ配下で`bundle clean; bundle exec rake release` コマンドを実行する (gemを最新にしてrubygemsにアップロード) 20 | - core 21 | - blogkit 22 | - contrib 23 | - [ ] core配下で`bundle exec rake package:stable package:release` コマンドを実行する(GitHub に tar.gz をアップロードする。GITHUB_ACCESS_TOKEN環境変数が必要なので注意, see #573) 24 | - [ ] themeのmasterブランチをgh-pagesブランチへmerge、pushする (`git checkout gh-pages; git merge master; git push origin gh-pages`) 25 | - [ ] core配下で `docker build . -t tdiary/tdiary:L.M.N` を実行してから、`push` する (`L.M`, `L`, `latest` も同様) 26 | - [ ] tdiary.org の以下のエントリーを書く 27 | - [ダウンロード](https://github.com/tdiary/tdiary.github.io/blob/master/download.md) 28 | - [サイドバー](https://github.com/tdiary/tdiary.github.io/blob/master/_includes/sidebar.html) 29 | - [リリースしましたのエントリ](https://github.com/tdiary/tdiary.github.io/tree/master/_posts) (`YYYY-MM-DD-release-L_M_N.md` 形式で) 30 | - [ ] 3ヶ月後の次のリリースの [issue](https://github.com/tdiary/tdiary-core/issues/new) と [project](https://github.com/orgs/tdiary/projects/new) を作る 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | time: '20:00' 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: jasmine 11 | versions: 12 | - ">= 3.0.a, < 4" 13 | - package-ecosystem: 'github-actions' 14 | directory: '/' 15 | schedule: 16 | interval: 'weekly' 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ubuntu 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: build (${{ matrix.ruby }}/${{ matrix.test_mode }}) 8 | strategy: 9 | matrix: 10 | ruby: [ '3.4', '3.3', '3.2', '3.1' ] 11 | test_mode: [ rack, gem ] 12 | runs-on: ubuntu-latest 13 | services: 14 | memcached: 15 | image: memcached:latest 16 | ports: 17 | - 11211:11211 18 | steps: 19 | - uses: actions/checkout@v4 20 | - name: Set up Ruby 21 | uses: ruby/setup-ruby@v1 22 | with: 23 | ruby-version: ${{ matrix.ruby }} 24 | - uses: actions/setup-node@v4 25 | with: 26 | node-version: '22' 27 | if: matrix.test_mode == 'rack' 28 | - name: Install dependencies 29 | run: | 30 | echo 'gemspec' > Gemfile.local 31 | bundle install --without server --jobs=3 --retry=3 32 | npm install 33 | - name: Run test 34 | run: bundle exec tdiary test 35 | if: matrix.test_mode == 'gem' 36 | - name: Run test (rack) 37 | run: | 38 | bundle exec rake spec test 39 | npm install 40 | npm test 41 | env: 42 | OPENSSL_CONF: /etc/ssl 43 | if: matrix.test_mode == 'rack' 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | .htpasswd 3 | coverage 4 | coverage.* 5 | data/* 6 | !data/.htaccess 7 | log 8 | pkg 9 | tmp 10 | rdoc 11 | index.rdf 12 | /tdiary.conf 13 | vendor/bundle/ 14 | spec/reports 15 | doc/*.html 16 | .rspec 17 | .ruby-version 18 | /Gemfile.local 19 | spec/javascripts/lib 20 | node_modules 21 | public/assets 22 | tdiary.pid -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug tDiary", 6 | "type": "rdbg", 7 | "request": "launch", 8 | "cwd": "${workspaceRoot}", 9 | "script": "bin/tdiary", 10 | "args": [ 11 | "server", "-p", "9292" 12 | ], 13 | "useBundler": true 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "rake", 6 | "task": "spec", 7 | "problemMatcher": [], 8 | "label": "rake: spec", 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.1 2 | LABEL maintainer "@tdtds " 3 | 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | COPY [ "Gemfile", "Gemfile.lock", "/usr/src/app/" ] 8 | RUN apt update && apt install -y apt-utils libidn11-dev; \ 9 | echo 'gem "puma" \n\ 10 | gem "tdiary-contrib" \n\ 11 | gem "tdiary-style-gfm" \n\ 12 | gem "tdiary-style-rd" \n'\ 13 | > Gemfile.local; \ 14 | gem install bundler && \ 15 | bundle --path=vendor/bundle --without=development:test --jobs=4 --retry=3 16 | 17 | COPY . /usr/src/app/ 18 | RUN if [ ! -e tdiary.conf ]; then cp tdiary.conf.beginner tdiary.conf; fi && \ 19 | bundle && \ 20 | bundle exec rake assets:copy 21 | 22 | VOLUME [ "/usr/src/app/data", "/usr/src/app/public" ] 23 | EXPOSE 9292 24 | ENV PORT=9292 25 | ENV HTPASSWD=data/.htpasswd 26 | ENV RACK_ENV=deployment 27 | CMD bundle exec rackup -o 0.0.0.0 -p ${PORT} 28 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rack' 4 | gem 'rack-session' 5 | gem 'rackup' 6 | gem 'hikidoc' 7 | gem 'fastimage' 8 | gem 'emot' 9 | gem 'mail' 10 | gem 'rake' 11 | 12 | group :development do 13 | gem 'pit', require: false 14 | gem 'racksh', require: false 15 | gem 'redcarpet' 16 | gem 'octokit' 17 | gem 'mime-types' 18 | 19 | group :test do 20 | gem 'test-unit' 21 | gem 'rspec' 22 | gem 'capybara', require: 'capybara/rspec' 23 | gem 'date', '>= 3.1.1' # for compatibility of capybara 24 | gem 'selenium-webdriver' 25 | gem 'launchy' 26 | gem 'sequel' 27 | gem 'sqlite3' 28 | gem 'simplecov', require: false 29 | gem "rexml" 30 | gem "webrick" 31 | end 32 | end 33 | 34 | # https://github.com/redmine/redmine/blob/master/Gemfile#L89 35 | local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") 36 | if File.exist?(local_gemfile) 37 | puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` 38 | instance_eval File.read(local_gemfile) 39 | end 40 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -p $PORT 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tDiary 2 | 3 | [![Gem Version](https://badge.fury.io/rb/tdiary.png)](https://rubygems.org/gems/tdiary) [![Build Status](https://github.com/tdiary/tdiary-core/actions/workflows/ci.yml/badge.svg)](https://github.com/tdiary/tdiary-core/actions/workflows/ci.yml) [![Code Climate](https://codeclimate.com/github/tdiary/tdiary-core.png)](https://codeclimate.com/github/tdiary/tdiary-core) 4 | 5 | ## tDiary, The TSUKKOMI-able Weblog. 6 | 7 | At first, see [doc/README-en.md](https://github.com/tdiary/tdiary-core/blob/master/doc/README.en.md) 8 | 9 | ## tDiary, ツッコミ可能なWeb日記システム 10 | 11 | tDiaryはWeb日記(いわゆるブログ)を実現するオープンソースソフトウェアです。ブログサービスをレンタルするのではなく、自分でWeb日記を運用する人のためのツールです。 12 | 13 | tDiaryには以下のような特徴があります。 14 | 15 | ### 長く日記を続けられます 16 | 17 | 日記は大切な自分史です。安心して長く日記を書き続けられるように、tDiaryは最低でも25年間はプロジェクトを維持することを目標に開発を続けています。2016年現在で15周年になるので、あと10年間はtDiaryで日記を書き続けることができます。 18 | 19 | ### レンタルサーバーユーザにやさしい 20 | 21 | 必要なのはRuby(2.1.0以降に対応)だけ。単独でCGIとして動作し、基本機能はデータベースや追加のライブラリを必要としません。 22 | 23 | ### プラグインで拡張できます 24 | 25 | 豊富なプラグインで、さまざまな機能を追加できます。ブログツールとして必要な機能はほとんどプラグインとして揃っています。 26 | 27 | ### テーマで好きなデザインを選べます 28 | 29 | 300種類を超えるデザイン・テーマを選べます。ユーザが作成したテーマを一堂に集めたテーマ・ギャラリーも見てください。 30 | 31 | ### その他 32 | 33 | インストールにはドキュメント(doc/INSTALL.html)を参照して下さい。動作にはruby(2.1.0以降)と、CGIもしくはRackをサポートするWebサーバが必要です。 34 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift 'lib' 2 | 3 | require 'tdiary/environment' 4 | require 'tdiary/tasks' 5 | 6 | require 'rake' 7 | require 'rake/clean' 8 | require 'bundler/gem_tasks' if File.exist?('tdiary.gemspec') 9 | 10 | CLEAN.include( 11 | "tmp", 12 | "data", 13 | "index.rdf" 14 | ) 15 | CLOBBER.include( 16 | "rdoc", 17 | "coverage" 18 | ) 19 | 20 | # Local Variables: 21 | # mode: ruby 22 | # indent-tabs-mode: t 23 | # tab-width: 3 24 | # ruby-indent-level: 3 25 | # End: 26 | # vim: ts=3 27 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tDiary", 3 | "website": "https://tdiary.org/", 4 | "repository": "https://github.com/tdiary/tdiary-core", 5 | "addons": [ 6 | "sendgrid", 7 | "memcachier" 8 | ], 9 | "scripts": { 10 | "postdeploy": "bundle exec rake mongodb:index" 11 | }, 12 | "env": { 13 | "TWITTER_KEY": { 14 | "required": true 15 | }, 16 | "TWITTER_SECRET": { 17 | "required": true 18 | }, 19 | "TWITTER_NAME": { 20 | "required": true, 21 | "description": "only the Twitter user can log into this diary" 22 | }, 23 | "MONGODB_URI": { 24 | "required": true, 25 | "description": "specify your MongoDB URI, for example on https://www.mongodb.com/cloud/atlas" 26 | }, 27 | "RACK_ENV": "production" 28 | }, 29 | "buildpacks": [ 30 | { 31 | "url": "https://github.com/tdiary/heroku-buildpack-tdiary" 32 | }, 33 | { 34 | "url": "https://github.com/heroku/heroku-buildpack-ruby" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /benchmark/benchmark_amazon_plugin.rb: -------------------------------------------------------------------------------- 1 | def enable_js(*args); end 2 | def add_conf_proc(*args); end 3 | def h(args); args; end 4 | 5 | class Dummyconf 6 | def [](*args); 7 | if args[0] == 'amazon.imgsize' 8 | 0 9 | end 10 | end 11 | def []=(*args); end 12 | 13 | def to_native( str, charset = nil ) 14 | str = str.dup 15 | if str.encoding == Encoding::ASCII_8BIT 16 | str.force_encoding(charset || 'utf-8') 17 | end 18 | unless str.valid_encoding? 19 | str.encode!('utf-16be', {invalid: :replace, undef: :replace}) 20 | end 21 | unless str.encoding == Encoding::UTF_8 22 | str.encode!('utf-8', {invalid: :replace, undef: :replace}) 23 | end 24 | str 25 | end 26 | end 27 | @conf = Dummyconf.new 28 | 29 | require 'benchmark/ips' 30 | Benchmark.ips do |x| 31 | xml = File.read('../spec/fixtures/jpB00H91KK26.xml') 32 | require_relative '../misc/plugin/amazon' 33 | x.report('rexml') do 34 | item = AmazonItem.new(xml) 35 | amazon_detail_html( item ) 36 | end 37 | x.report('oga') do 38 | require 'oga' 39 | item = AmazonItem.new(xml, :oga) 40 | amazon_detail_html(item) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /benchmark/benchmark_io_default.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | PATH = File::dirname( __FILE__ ) 3 | class << self 4 | def root 5 | File.expand_path(File.join(library_root, '..')) 6 | end 7 | 8 | # directory where tDiary libraries is located 9 | def library_root 10 | File.expand_path('..', __FILE__) 11 | end 12 | 13 | # directory where the server was started 14 | def server_root 15 | Dir.pwd 16 | end 17 | end 18 | end 19 | require_relative '../lib/tdiary/cache/file' 20 | require_relative '../lib/tdiary/io/default' 21 | 22 | class DummyTDiary 23 | attr_accessor :conf 24 | 25 | def initialize 26 | @conf = DummyConf.new 27 | @conf.data_path = TDiary.root + "/tmp/" 28 | end 29 | 30 | def ignore_parser_cache 31 | false 32 | end 33 | end 34 | 35 | class DummyConf 36 | attr_accessor :data_path 37 | 38 | def cache_path 39 | TDiary.root + "/tmp/cache" 40 | end 41 | 42 | def options 43 | {} 44 | end 45 | 46 | def style 47 | "wiki" 48 | end 49 | end 50 | 51 | conf = DummyConf.new 52 | conf.data_path = TDiary.root + '/tmp/data/' 53 | diary = DummyTDiary.new 54 | diary.conf = conf 55 | io = TDiary::IO::Default.new(diary) 56 | 57 | require 'benchmark/ips' 58 | 59 | Benchmark.ips do |x| 60 | x.report('calendar') do 61 | io.calendar 62 | end 63 | 64 | x.report('calendar2') do 65 | io.calendar2 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /bin/tdiary: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | lib = File.expand_path('../../lib/', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | require 'tdiary/cli' 6 | 7 | TDiary::CLI.start 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | $:.unshift( File.join(File::expand_path(File::dirname( __FILE__ )), 'lib' ) ) 2 | require 'tdiary/application' 3 | 4 | use ::Rack::Reloader unless ENV['RACK_ENV'] == 'production' 5 | run TDiary::Application.new 6 | -------------------------------------------------------------------------------- /data/.htaccess: -------------------------------------------------------------------------------- 1 | Order allow,deny 2 | Deny from all 3 | -------------------------------------------------------------------------------- /doc/HOWTO-testing-tDiary.md: -------------------------------------------------------------------------------- 1 | How to testing tDiary 2 | ===================== 3 | 4 | 概要 5 | -- 6 | 7 | tDiary-3.0.1.20101011 以降のバージョンでは tDiary を test するための仕組みがいくつか導入されています。具体的には以下の2点です。 8 | 9 | - Capybara と steak を使った End-to-End のテスト方法 10 | - RSpec2 による単体テスト方法 11 | 12 | 前者の方法は tDiary の内部構造に意識せずに、初期データからブラウザに表示される内容をテストする方法であり、後者の方法はプラグインや特定のメソッドをテストするたびに用いられる方法です。 13 | 14 | テスト可能な tDiary 最終目標は cgi.rb に依存する仕組みから Rack のインタフェースに載せ替えた上で、tDiary の各モジュールに対してテストを実行できるようにすることです。 15 | 16 | 必要なもの 17 | ----- 18 | 19 | tDiary でテストを実行するためには以下の環境を用意する必要があります。 20 | 21 | - Ruby 2.1.0 以降 22 | - Bundler 1.3.5 以降 23 | 24 | 動かし方 25 | ---- 26 | 27 | tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。 28 | 29 | ``` 30 | bundle install 31 | ``` 32 | 33 | Ruby をインストールしているディレクトリへの書き込み権限がない場合は --path オプションを付けることで任意のディレクトリに依存 gem をインストールすることができます。 34 | 35 | ``` 36 | bundle install --path ~/.bundle 37 | ``` 38 | 39 | bundler によるインストールが完了すると、tDiary でテストを実行できるようになります。以下のコマンドを実行すると、tDiary に付属しているテストが全て実行されます。 40 | 41 | ``` 42 | bundle exec rake spec 43 | ``` 44 | 45 | テストのディレクトリ構成と Rake タスク 46 | ---------------------- 47 | 48 | tDiary に用意されているテストは以下の3種類で構成されています。この構成は今後も変更される可能性もあるので、Rake -T コマンドを実行して Rake タスクの内容を確認するようにしてください。 49 | 50 | - spec:core: core(tDiary本体)に関わるテストを実行します。 51 | - spec:plugin: misc/plugin 配下に存在するプラグインファイルのテストを実行します。 52 | - spec:acceptance: 日記の作成や削除について、HTTPリクエストからデータの保存までの End-to-End のテストを実行します 53 | -------------------------------------------------------------------------------- /doc/INSTALL-paas.md: -------------------------------------------------------------------------------- 1 | # Install to PaaS 2 | 3 | ## 概要 4 | 5 | tDiary-3.1.3 以降のバージョンでは tDiary を [Heroku](http://www.heroku.com) のような PasS で動かすことが可能です。PaaS を利用することで、3.1.3 以前のバージョンで必要とされていた Apache のような http サーバーの用意や CGI として動作させるための環境設定を行う事なく、 tDiary を動かして日記を書くことが可能となります。 6 | 7 | ## 動かし方 - Heroku の場合 8 | 9 | Webブラウザだけあれば動作させることが可能です。 10 | 11 | 日記の更新時にTwitterのOAuthを使って認証するようになっています。あらかじめ[Twitter Developpers](https://developer.twitter.com/en/apps)にてアプリケーションを作成し、API key と API secret key を取得しておきます。 12 | 13 | 続いて GitHub 上にある[tDiaryのリポジトリ](https://github.com/tdiary/tdiary-core)から、Herokuボタンを使ってデプロイしてください(トップページ下部のREADMEにあります)。 14 | 15 | Heroku の New App ページになったら、下記の情報を入力して、Deploy for Free ボタンを押します。 16 | 17 | * App Name (任意) 18 | * TWITTER_KEY: Twitter の API key 19 | * TWITTER_SECRET: Twitter の API secret key 20 | * TWITTER_NAME: 認証に使う Twitter のユーザ名 21 | 22 | 「Deployed to Heroku」まで進めば利用可能です。「View it」のリンクから日記に飛んで下さい。 23 | 24 | 【注意】View itから飛んだ先のURLは https://~ になっています。いったん http://~ にしないと認証が通らないので注意してください。なお、設定画面で「日記のURL」を https://~ に変更することで https での利用が可能です。 25 | 26 | また、tDiary 5.10 より、amazonプラグインを利用する場合に特別な設定が必要になっています。[tDiary 5.1.0のリリース](http://www.tdiary.org/20191129.html)にある方法でAmazon PA-APIのアクセスキーとシークレットキーを取得し、Herokuの環境変数(Settings→Config Vars)にてぞれぞれ以下の変数に指定します。 27 | 28 | * AMAZON_ACCESS_KEY 29 | * AMAZON_SECRET_KEY 30 | 31 | あとはtDiaryの設定画面から、AmazonのアソシエイトIDを指定すれば利用できます。 32 | 33 | ## memcache アドオンを使う方法 - Heroku の場合 34 | 35 | Heroku で アドオンの追加・削除を行うことが出来るユーザーは memcache アドオンを使うことで、より高速に日記キャッシュデータを扱えるようになります。tDiary on Heroku で memcache アドオンを使う方法を以下に解説します。 36 | 37 | tdiary-core の deploy ブランチに切り替えます。 38 | 39 | ``` 40 | git checkout deploy 41 | ``` 42 | 43 | heroku コマンドを用いて memcache アドオンを有効にします。 44 | 45 | ``` 46 | heroku addons:add memcache 47 | ``` 48 | 49 | Gemfile の以下の行を有効にします。 50 | 51 | ``` 52 | gem 'dalli' 53 | ``` 54 | 55 | tdiary.conf を以下のように変更します。 56 | 57 | ``` 58 | # require 'tdiary/cache/file' 59 | # To use memcache addon 60 | require 'tdiary/cache/memcached' 61 | ``` 62 | 63 | この状態を Heroku に反映させます。 64 | 65 | ``` 66 | git add . 67 | git commit -m "enable memcache" 68 | git push heroku deploy:master 69 | ``` 70 | 71 | git push コマンドが完了すると memcached をキャッシュの保存先とした tDiary が利用可能となります。 72 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | ツッコミのできるWeb日記システム 2 | ================= 3 | 4 | tDiaryでできること 5 | ------------ 6 | 7 | tDiaryは、いわゆるWeb日記を支援するシステムです。tDiaryには以下の特徴があります。 8 | 9 | ### 更新や設定までブラウザからできる 10 | 11 | 日記の参照だけでなく、日記の更新、設定までもWebブラウザから実行できます。ブラウザさえあれば面倒なメンテナンスは不要。手軽に使えて、長く続けられます。 12 | 13 | ### 「ツッコミ」が入れられる 14 | 15 | 日記の読者が、日記に「ツッコミ」を入れられます。ようするに、日付ごとに掲示板がついています。これを通じて、読者とのコミュニケーションが生まれます。 ツッコミがあったことを著者にメールで知らせる機能もあります。 16 | 17 | ### 「本日のリンク元」(Referer)機能 18 | 19 | 他の日記等からリンクされると、Refererヘッダを見てそのURLを表示します。どこかで自分の日記が話題にされていることがすぐにわかるように、従来のWeb日記コミュニケーションで使われている手法をわかりやすくサポートしています。 20 | 21 | ### 携帯端末対応 22 | 23 | iモードに限らず、ほとんどの携帯電話やPalm・ザウルスなどの携帯端末からも日記を参照できます。専用の特別なURLは必要なく、自動認識して最適なページを生成します。通信料金のシビアな端末向けには無駄を省いた小さなページを送るようになっています。 24 | 25 | ### CSSを使ったテーマ機能 26 | 27 | スタイルシートを使って見た目をがらりを変えることができます。これは「テーマ」と呼ばれ、別パッケージとして配布されているテーマ集には、100を越えるテーマが収録されています。もちろん自分で作ることも可能です。テーマは設定画面で簡単に切り替えることができます。 28 | 29 | ### プラグインによる機能追加 30 | 31 | プラグインというモジュールを追加することで、日記の機能を増やしたり変更したりすることが可能です。詳しくは[HOWTO-use-plugin.md](HOWTO-use-plugin.md)(使い方)・[HOWTO-make-plugin.md](HOWTO-make-plugin.md)(作り方)を参照してください。 32 | 33 | ### 記述形式や保存形式を変更できる 34 | 35 | 日記を記述する形式(スタイル機能)や、データの保存形式(IO機能)が選択可能です。スタイルはmisc/styleの下に複数収められています。IOは現在、1.4系までの旧tDiary互換のPStoreIOと、2.0系以降の新しいテキスト形式であるDefaultIOがあります。詳しくは[HOWTO-make-io.md](HOWTO-make-io.md)を参照してください。 36 | 37 | ### Rubyで書かれている 38 | 39 | 重要なポイントでしょう:-) ruby 2.1.0以上が必要です。 40 | 41 | セクション(段落)アンカーや過去の日記の参照など、一般的なWeb日記システムの持つ機能は基本的にサポートしています。 42 | 43 | tDiaryのインストールと設定 44 | ---------------- 45 | 46 | [INSTALL.md](INSTALL.md)を参照してください。 47 | 48 | 著作権、サポートなど 49 | ---------- 50 | 51 | tDiary本体は、原作者であるただただし(t@tdtds.jp)が、GPL2ないしその後継ライセンスの元で配布、改変を許可するフリーソフトウェアです。 52 | 53 | また、tDiaryフルセットに付属するテーマ、プラグインはすべて、それぞれの原作者が著作権を有します。ライセンス等に関しては個々のファイルを参照してください。 54 | 55 | tDiaryは[http://www.tdiary.org/](http://www.tdiary.org/)でサポートを行っています。ご意見・ご要望はこちらへどうぞ。パッチ歓迎です。 56 | 57 | -------------------------------------------------------------------------------- /doc/doc.css: -------------------------------------------------------------------------------- 1 | /* 2 | doc.css: CSS for tDiary documents 3 | 4 | 2002-11-13 TADA Tadashi 5 | * created 6 | */ 7 | 8 | body { 9 | color: #000; 10 | background-color: #fff; 11 | line-height: 130%; 12 | } 13 | 14 | h1 { 15 | color: #fff; 16 | background-color: #32c832; 17 | border-style: solid; 18 | border-width: 0px 0px 2px 0px; 19 | border-color: #166416; 20 | padding: 4px; 21 | } 22 | 23 | div.footer { 24 | margin-right: 4px; 25 | text-align: right; 26 | clear: both; 27 | font-size: 80%; 28 | } 29 | 30 | a:link, a:visited { 31 | color: #32c832; 32 | background-color: transparent; 33 | text-decoration: none; 34 | } 35 | 36 | a:hover { 37 | text-decoration: underline; 38 | } 39 | 40 | hr.sep { 41 | display: none; 42 | } 43 | 44 | h2 { 45 | border-style: solid; 46 | border-color: #32c832; 47 | border-width: 0px 0px 1px 0px; 48 | } 49 | 50 | h3 { 51 | margin: 1em; 52 | } 53 | 54 | h4 { 55 | margin: 2em; 56 | } 57 | 58 | p { 59 | margin-left: 3em; 60 | } 61 | 62 | pre, p.sample { 63 | border-style: solid; 64 | border-color: #32c832; 65 | border-width: 1px 1px 1px 3px; 66 | margin-left: 5em; 67 | padding: 4px; 68 | } 69 | 70 | div.sample { 71 | border-style: solid; 72 | border-color: #32c832; 73 | border-width: 1px 1px 1px 3px; 74 | margin-left: 5em; 75 | padding: 4px; 76 | } 77 | 78 | dl { 79 | margin-left: 5em; 80 | } 81 | 82 | dt { 83 | font-weight: bold; 84 | } 85 | 86 | dd { 87 | margin-bottom: 0.5em; 88 | } 89 | 90 | ul, ol { 91 | margin-left: 5em; 92 | } 93 | 94 | li { 95 | margin-bottom: 0.5em; 96 | } 97 | 98 | table { 99 | color: #fff; 100 | background-color: #32c832; 101 | } 102 | 103 | th { 104 | color: #fff; 105 | background-color: #166416; 106 | padding: 0.2em; 107 | text-align: left; 108 | } 109 | 110 | td { 111 | color: #000; 112 | background-color: #fff; 113 | padding: 0.2em; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /dot.htaccess: -------------------------------------------------------------------------------- 1 | Options +ExecCGI 2 | 3 | # if you run tDiary with symbolic link, use settings below. 4 | #Options +FollowSymLinks 5 | 6 | # if making anchor style as 'YYYYMMDD.html', add some settings below. 7 | # SEE header of html_anchor.rb plugin. 8 | 9 | AddHandler cgi-script .rb 10 | DirectoryIndex index.rb 11 | AddType application/xml .rdf 12 | 13 | 14 | deny from all 15 | 16 | 17 | 18 | deny from all 19 | 20 | 21 | 22 | AuthName tDiary 23 | AuthType Basic 24 | AuthUserFile /home/foo/.htpasswd 25 | Require user foo 26 | 27 | 28 | -------------------------------------------------------------------------------- /index.fcgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # index.fcgi $Revision: 1.35 $ 4 | # 5 | # Copyright (C) 2004, Akinori MUSHA 6 | # Copyright (C) 2006, moriq 7 | # Copyright (C) 2006-2009, Kazuhiko 8 | # You can redistribute it and/or modify it under GPL2 or any later version. 9 | # 10 | require 'fcgi' 11 | # workaround untaint LOAD_PATH for rubygems library path is always tainted. 12 | $:.each{|path| path if path.include?('fcgi') } 13 | 14 | if FileTest::symlink?( __FILE__ ) then 15 | org_path = File::dirname( File::readlink( __FILE__ ) ) 16 | else 17 | org_path = File::dirname( __FILE__ ) 18 | end 19 | load "#{org_path}/misc/lib/fcgi_patch.rb" 20 | 21 | FCGI.each_cgi do |cgi| 22 | begin 23 | ENV.clear 24 | ENV.update(cgi.env_table) 25 | class << CGI; self; end.class_eval do 26 | define_method(:new) {|*args| cgi } 27 | end 28 | dir = File::dirname( cgi.env_table["SCRIPT_FILENAME"] || __FILE__ ) 29 | Dir.chdir(dir) do 30 | load 'index.rb' 31 | end 32 | ensure 33 | class << CGI 34 | remove_method :new 35 | end 36 | end 37 | end 38 | 39 | # Local Variables: 40 | # mode: ruby 41 | # indent-tabs-mode: t 42 | # tab-width: 3 43 | # ruby-indent-level: 3 44 | # End: 45 | -------------------------------------------------------------------------------- /index.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: ascii-8bit; -*- 3 | # 4 | # index.rb 5 | # 6 | # Copyright (C) 2001-2009, TADA Tadashi 7 | # You can redistribute it and/or modify it under GPL2 or any later version. 8 | # 9 | BEGIN { $stdout.binmode } 10 | 11 | begin 12 | if FileTest::symlink?( __FILE__ ) then 13 | org_path = File::dirname( File::readlink( __FILE__ ) ) 14 | else 15 | org_path = File::dirname( __FILE__ ) 16 | end 17 | $:.unshift( (org_path + '/lib') ) unless $:.include?( org_path + '/lib' ) 18 | require 'tdiary' 19 | 20 | encoding_error = {} 21 | cgi = CGI::new(accept_charset: "UTF-8") do |name, value| 22 | encoding_error[name] = value 23 | end 24 | if encoding_error.empty? 25 | @cgi = cgi 26 | else 27 | @cgi = CGI::new(accept_charset: 'shift_jis') 28 | @cgi.params = cgi.params 29 | end 30 | 31 | request = TDiary::Request.new( ENV, @cgi ) 32 | status, headers, body = TDiary::Dispatcher.index.dispatch_cgi( request, @cgi ) 33 | 34 | TDiary::Dispatcher.send_headers( status, headers ) 35 | require 'rackup/handler/cgi' 36 | ::Rackup::Handler::CGI.send_body(body) 37 | rescue Exception 38 | if @cgi then 39 | print @cgi.header( 'status' => CGI::HTTP_STATUS['SERVER_ERROR'], 'type' => 'text/html' ) 40 | else 41 | print "Status: 500 Internal Server Error\n" 42 | print "content-type: text/html\n\n" 43 | end 44 | puts "

500 Internal Server Error

" 45 | puts "
"
46 | 	puts CGI::escapeHTML( "#{$!} (#{$!.class})" )
47 | 	puts ""
48 | 	puts CGI::escapeHTML( $@.join( "\n" ) )
49 | 	puts "
" 50 | puts "
#{' ' * 500}
" 51 | end 52 | 53 | # Local Variables: 54 | # mode: ruby 55 | # indent-tabs-mode: t 56 | # tab-width: 3 57 | # ruby-indent-level: 3 58 | # End: 59 | -------------------------------------------------------------------------------- /js/02edit.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | $(document).ready(function() { 4 | var form, targetArea; 5 | form = $('textarea'); 6 | targetArea = $('div.update > div.form').first(); 7 | if (form.width() < targetArea.width() / 2.5) { 8 | form.width(targetArea.width() / 2.5); 9 | } 10 | if (form.height() < targetArea.height() / 1.5) { 11 | return form.height(targetArea.height() / 1.5); 12 | } 13 | }); 14 | 15 | }).call(this); 16 | -------------------------------------------------------------------------------- /js/amazon.js: -------------------------------------------------------------------------------- 1 | /* 2 | * amazon.js : 3 | * * remove height / width infomation of images 4 | * 5 | * Copyright (C) 2015 by TADA Tadashi 6 | * You can distribute it under GPL2 or any later version. 7 | */ 8 | 9 | $(function(){ 10 | if($(window).width() <= 360) { 11 | $('img.amazon').attr('height', null).attr('width', null); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /js/amazon_bitly.js: -------------------------------------------------------------------------------- 1 | /* 2 | * amazon_bitly.js : replace amazon URL using bit.ly (amzn.to). 3 | * 4 | * Copyright (C) 2011 by TADA Tadashi 5 | * You can distribute it under GPL2 or any later version. 6 | */ 7 | 8 | $(function(){ 9 | function shorten(link){ 10 | var url = link.attr('href'); 11 | var api = 'http://api.bit.ly/v3/shorten' 12 | + '?format=json' 13 | + '&longUrl=' + encodeURIComponent(url) 14 | + '&login=' + $tDiary.plugin.bitly.login 15 | + '&apiKey=' + $tDiary.plugin.bitly.apiKey; 16 | 17 | $.ajax({ 18 | type: 'GET', 19 | url: api, 20 | dataType: 'jsonp', 21 | success: function(data){ 22 | if (data['data']){ 23 | link.attr('href',data['data']['url']); 24 | } 25 | else{ 26 | //console.warn('fail to short: ' + link.attr('href')); 27 | } 28 | } 29 | }); 30 | } 31 | 32 | $(window).on('scroll', function(event){ 33 | var bottom = $(window).height() + $(window).scrollTop(); 34 | //console.warn('window.bottom: ' + bottom); 35 | $('a[href*="://www.amazon.co.jp/"]').each(function(){ 36 | var a = $(this); 37 | if (bottom > a.offset().top){ 38 | //console.warn('appear!: ' + a.text()); 39 | shorten(a); 40 | } 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /js/category.js: -------------------------------------------------------------------------------- 1 | /* 2 | category.js: javascript for category.rb plugin of tDiary 3 | 4 | Copyright (C) 2011 by TADA Tadashi 5 | You can redistribute it and/or modify it under GPL2 or any later version. 6 | */ 7 | 8 | $(function(){ 9 | // insert clicked category item into textarea of update form 10 | function insertCategoryItem(item) { 11 | $('#body').insertAtCaret( '[' + item.text() + ']' ); 12 | } 13 | 14 | $('.category-item') 15 | .hover(function(){ 16 | $(this).css('cursor', 'pointer'); 17 | }, function(){ 18 | $(this).css('cursor', 'default'); 19 | }) 20 | .click(function(){ 21 | insertCategoryItem($(this)); 22 | }); 23 | 24 | $('#category-candidate').change(function(){ 25 | $('option:selected', this).each(function(){ 26 | insertCategoryItem($(this)); 27 | }); 28 | }); 29 | 30 | // reverse list of category 31 | $('ul.category').each(function(){ 32 | var ul = $(this); 33 | ul.append(ul.children().toArray().reverse()); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /js/comment_ajax.js: -------------------------------------------------------------------------------- 1 | /** 2 | * comment_ajax.js: 3 | * 4 | * Copyright (C) 2013 by MATSUOKA Kohei 5 | * You can distribute it under GPL2 or any later version. 6 | */ 7 | 8 | $(function() { 9 | $(document).on('submit', 'form.comment', function(e) { 10 | e.preventDefault(); 11 | var form = $(this); 12 | $('').attr('name', 'comment').appendTo(form); 13 | $(':submit', form).attr('disabled', 'disabled'); 14 | $('div.button input', form).hide(); 15 | $('div.button', form).append('
') 16 | $.post(form.attr('action'), form.serialize(), function(data) { 17 | $('#loading-button').remove(); 18 | $('div.button input', form).show(); 19 | form[0].reset(); 20 | $(':submit', form).removeAttr('disabled'); 21 | // $(data) is a diary HTML of the day 22 | $('div.comment:first', form.parents('div.day')) 23 | .after($('div.comment', $(data))) 24 | .remove(); 25 | }, 'html'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /js/highlight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * highlight.js: Highlighting the element jumped from other pages. 3 | * 4 | * Copyright (C) 2003 by Ryuji SAKAI 5 | * Copyright (C) 2003 by Kazuhiro NISHIYAMA 6 | * Copyright (C) 2011 by MATSUOKA Kohei 7 | * You can distribute it under GPL2 or any later version. 8 | */ 9 | 10 | $(function() { 11 | function highlight(anchor) { 12 | // clear current highlight 13 | $(".highlight").removeClass("highlight"); 14 | 15 | // change document title 16 | var target = $(anchor).parent(); 17 | if (target.filter('h3').length > 0) { 18 | document.title = target.children("a").attr("title") + " - " + $tDiary.title; 19 | } 20 | 21 | target.addClass("highlight"); 22 | } 23 | 24 | // bind click event to anchors 25 | $(document.anchors) 26 | .filter(function() { 27 | return $(this).attr("name").match(/^[pc]/); 28 | }) 29 | .on("click", function() { 30 | highlight(this); 31 | }) 32 | 33 | if (document.location.hash) { 34 | highlight($('[name=' + document.location.hash.replace(/[^\w]/g, "") + ']')[0]); 35 | } 36 | }); 37 | -------------------------------------------------------------------------------- /lib/aws/sig_v4.rb: -------------------------------------------------------------------------------- 1 | # 2 | # A Simple impl of AWS Signature V4 for PA-API GetItems 3 | # 4 | require 'openssl' 5 | 6 | module AWS 7 | module SigV4 8 | def self.canonical_request(host, payload, time_stamp) 9 | headers = { 10 | 'Content-Encoding' => 'amz-1.0', 11 | 'Host' => host, 12 | 'X-Amz-Content-Sha256' => OpenSSL::Digest::SHA256.hexdigest(payload), 13 | 'X-Amz-Date' => time_stamp, 14 | 'X-Amz-Target' => "com.amazon.paapi5.v1.ProductAdvertisingAPIv1.GetItems", 15 | } 16 | [ 17 | "POST", 18 | "/paapi5/getitems", 19 | '', 20 | headers.keys.sort.map{|k|"#{k.downcase}:#{headers[k]}"}.join("\n") + "\n", 21 | headers.keys.sort.map{|k|k.downcase}.join(';'), 22 | OpenSSL::Digest::SHA256.hexdigest(payload) 23 | ].join("\n") 24 | end 25 | def self.string2sign(host, payload, time_stamp) 26 | [ 27 | 'AWS4-HMAC-SHA256', 28 | time_stamp, 29 | "#{time_stamp[0,8]}/us-west-2/ProductAdvertisingAPI/aws4_request", 30 | OpenSSL::Digest::SHA256.hexdigest(canonical_request(host, payload, time_stamp)) 31 | ].join("\n") 32 | end 33 | def self.signature(secret, time_stamp, region, host, payload) 34 | k_secret = secret 35 | k_date = hmac("AWS4" + k_secret, time_stamp[0,8]) 36 | k_region = hmac(k_date, region) 37 | k_service = hmac(k_region, 'ProductAdvertisingAPI') 38 | k_credential = hmac(k_service, "aws4_request") 39 | OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), k_credential, string2sign(host, payload, time_stamp)) 40 | end 41 | def self.hmac(key, value) 42 | OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value) 43 | end 44 | end 45 | end -------------------------------------------------------------------------------- /lib/rack/server.rb: -------------------------------------------------------------------------------- 1 | require 'rackup/server' 2 | module Rack 3 | Server = ::Rackup::Server 4 | end 5 | -------------------------------------------------------------------------------- /lib/tdiary/comment.rb: -------------------------------------------------------------------------------- 1 | # 2 | # class Comment 3 | # Management a comment. 4 | # 5 | module TDiary 6 | class Comment 7 | attr_reader :name, :mail, :body, :date 8 | 9 | def initialize( name, mail, body, date = Time::now ) 10 | @name, @mail, @body, @date = name, mail, body, date 11 | @show = true 12 | end 13 | 14 | def shorten( length = 120 ) 15 | matched = body.gsub( /\n/, ' ' ).scan( /^.{0,#{length - 2}}/u )[0] 16 | 17 | unless $'.empty? then 18 | matched + '..' 19 | else 20 | matched 21 | end 22 | end 23 | 24 | def visible?; @show; end 25 | def show=( s ); @show = s; end 26 | 27 | def ==( c ) 28 | (@name == c.name) and (@mail == c.mail) and (@body == c.body) 29 | end 30 | end 31 | end 32 | 33 | # Local Variables: 34 | # mode: ruby 35 | # indent-tabs-mode: t 36 | # tab-width: 3 37 | # ruby-indent-level: 3 38 | # End: 39 | # vim: ts=3 40 | -------------------------------------------------------------------------------- /lib/tdiary/compatible.rb: -------------------------------------------------------------------------------- 1 | # ENV#[] raises an exception on secure mode 2 | class CGI 3 | ENV = ::ENV.to_hash 4 | end 5 | 6 | # Auto convert ASCII_8BIT pstore data (created by Ruby-1.8) to UTF-8. 7 | require 'pstore' 8 | class PStoreRuby18Exception < Exception; end 9 | 10 | class PStore 11 | alias compatible_transaction_original transaction unless defined?(compatible_transaction_original) 12 | def transaction(*args, &block) 13 | begin 14 | compatible_transaction_original(*args, &block) 15 | rescue PStoreRuby18Exception 16 | # first loaded the pstore file (it's created by Ruby-1.8) 17 | # force convert ASCII_8BIT pstore data to UTF_8 18 | file = open_and_lock_file(@filename, false) 19 | table = Marshal::load(file, proc {|obj| 20 | if obj.respond_to?('force_encoding') && obj.encoding == Encoding::ASCII_8BIT 21 | obj.force_encoding('UTF-8') 22 | end 23 | obj 24 | }) 25 | table[:__ruby_version] = RUBY_VERSION 26 | if on_windows? 27 | save_data_with_fast_strategy(Marshal::dump(table), file) 28 | else 29 | save_data_with_atomic_file_rename_strategy(Marshal::dump(table), file) 30 | end 31 | retry 32 | end 33 | end 34 | 35 | private 36 | 37 | def load(content) 38 | table = Marshal::load(content) 39 | raise PStoreRuby18Exception.new if !table[:__ruby_version] || table[:__ruby_version] < '1.9' 40 | # hide __ruby_version to caller 41 | table.delete(:__ruby_version) 42 | table 43 | end 44 | 45 | def dump(table) 46 | table[:__ruby_version] = RUBY_VERSION 47 | Marshal::dump(table) 48 | end 49 | end 50 | 51 | # Local Variables: 52 | # mode: ruby 53 | # indent-tabs-mode: t 54 | # tab-width: 3 55 | # ruby-indent-level: 3 56 | # End: 57 | -------------------------------------------------------------------------------- /lib/tdiary/diary_container.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | class DiaryContainer 3 | # YYYYMMDD 4 | def self.find_by_day(conf, date) 5 | # date: YYYYMMDD 6 | m = date.match(/^(?\d{4})(?\d{2})(?\d{2})$/) 7 | raise ArgumentError.new("date must be YYYYMMDD format") unless m 8 | new(conf, m[:year], m[:month], m[:day]) 9 | end 10 | 11 | def self.find_by_month(conf, date) 12 | # date: YYYYMM 13 | m = date.match(/^(?\d{4})(?\d{2})$/) 14 | raise ArgumentError.new("date must be YYYYMM format") unless m 15 | new(conf, m[:year], m[:month]) 16 | end 17 | 18 | def initialize(conf, year, month, day = nil) 19 | cgi = FakeCGI.new 20 | if year && month && day 21 | cgi.params['date'] = ["#{year}#{month}#{day}"] 22 | @controller = TDiaryDayWithoutFilter::new(cgi, '', conf) 23 | elsif year && month 24 | cgi.params['date'] = ["#{year}#{month}"] 25 | @controller = TDiaryMonthWithoutFilter::new(cgi, '', conf) 26 | else 27 | raise StandardError.new 28 | end 29 | end 30 | 31 | def conf 32 | @controller.conf 33 | end 34 | 35 | def diaries 36 | # Hash of 'YYYYMMDD' => TDiary::Style::WikiDiary 37 | @controller.diaries 38 | end 39 | 40 | class FakeCGI < CGI 41 | def refeter; nil end 42 | def user_agent; nil; end 43 | def mobile_agent?; nil; end 44 | def request_method; 'GET'; end 45 | end 46 | end 47 | end 48 | 49 | # Local Variables: 50 | # mode: ruby 51 | # indent-tabs-mode: t 52 | # tab-width: 3 53 | # ruby-indent-level: 3 54 | # End: 55 | # vim: ts=3 -------------------------------------------------------------------------------- /lib/tdiary/environment.rb: -------------------------------------------------------------------------------- 1 | # name spaces reservation 2 | module TDiary; end 3 | module TDiary::Cache; end 4 | 5 | # Set up gems listed in the Gemfile. 6 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __FILE__) 7 | 8 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 9 | 10 | # FIXME: workaround fix for tainted path from Gemfile.local 11 | $LOAD_PATH.each{|lp| $LOAD_PATH << $LOAD_PATH.shift.dup} 12 | 13 | if defined?(Bundler) 14 | env = [:default, :rack] 15 | env << :development if ENV['RACK_ENV'].nil? || ENV['RACK_ENV'].empty? 16 | env << ENV['RACK_ENV'].intern if ENV['RACK_ENV'] 17 | env = env.reject{|e| 18 | (Bundler.settings.without rescue Bundler.settings[:without]).include? e 19 | } 20 | Bundler.require *env 21 | end 22 | 23 | # Bundler.require doesn't load gems specified in .gemspec 24 | # see: https://github.com/bundler/bundler/issues/1041 25 | # 26 | # load gems dependented by tdiary 27 | tdiary_spec = Bundler.definition.specs.find {|spec| spec.name == 'tdiary'} 28 | if tdiary_spec 29 | tdiary_spec.dependent_specs.each {|dep_spec| 30 | begin 31 | require dep_spec.name 32 | rescue LoadError => e 33 | STDERR.puts "failed require '#{dep_spec.name}'" 34 | STDERR.puts e 35 | end 36 | } 37 | end 38 | -------------------------------------------------------------------------------- /lib/tdiary/extensions.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module Extensions 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /lib/tdiary/extensions/core.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module Extensions 3 | class Core 4 | def self.sp_path 5 | end 6 | 7 | def self.assets_path 8 | %w(js theme).map {|path| 9 | [TDiary.root, TDiary.server_root].map {|base_dir| 10 | File.join(base_dir, path) 11 | } 12 | } 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/tdiary/filter.rb: -------------------------------------------------------------------------------- 1 | # 2 | # module/class Filter 3 | # 4 | module TDiary 5 | module Filter 6 | class Filter 7 | include ViewHelper 8 | 9 | DEBUG_NONE = 0 10 | DEBUG_SPAM = 1 11 | DEBUG_FULL = 2 12 | 13 | def initialize( cgi, conf ) 14 | @cgi, @conf = cgi, conf 15 | 16 | if @conf.options.include?('filter.debug_mode') 17 | @debug_mode = @conf.options['filter.debug_mode'] 18 | else 19 | @debug_mode = DEBUG_NONE 20 | end 21 | end 22 | 23 | def comment_filter( diary, comment ) 24 | true 25 | end 26 | 27 | def referer_filter( referer ) 28 | true 29 | end 30 | 31 | def debug( msg, level = DEBUG_SPAM ) 32 | return if @debug_mode == DEBUG_NONE 33 | return if @debug_mode == DEBUG_SPAM and level == DEBUG_FULL 34 | 35 | TDiary.logger.info("#{@cgi.remote_addr}->#{(@cgi.params['date'][0] || 'no date').dump}: #{msg}") 36 | end 37 | end 38 | end 39 | end 40 | 41 | # Local Variables: 42 | # mode: ruby 43 | # indent-tabs-mode: t 44 | # tab-width: 3 45 | # ruby-indent-level: 3 46 | # End: 47 | # vim: ts=3 48 | -------------------------------------------------------------------------------- /lib/tdiary/filter/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # default.rb: included TDiary::Filter::DefaultFilter class 3 | # 4 | # Copyright (C) 2001-2005, TADA Tadashi 5 | # You can redistribute it and/or modify it under GPL2 or any later version. 6 | # 7 | 8 | module TDiary 9 | module Filter 10 | class DefaultFilter < Filter 11 | def comment_filter( diary, comment ) 12 | if 'POST' != @cgi.request_method then 13 | return false 14 | end 15 | if comment.name.strip.empty? or comment.body.strip.empty? then 16 | return false 17 | end 18 | idx = 1 19 | diary.each_comment( -1 ) do |com| 20 | return false if idx >= @conf.comment_limit_per_day 21 | return false if comment == com 22 | idx += 1 23 | end 24 | true 25 | end 26 | 27 | def referer_filter( referer ) 28 | if not referer then 29 | false 30 | #elsif /[\x00-\x20\x7f-\xff]/ =~ referer then 31 | # false 32 | elsif @conf.bot =~ @cgi.user_agent 33 | false 34 | elsif %r|^https?://|i =~ referer 35 | ref = CGI::unescape( referer.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) ).force_encoding('ASCII-8BIT') 36 | @conf.no_referer.each do |noref| 37 | return false if /#{noref.dup.force_encoding('ASCII-8BIT')}/i =~ ref 38 | end 39 | true 40 | else 41 | false 42 | end 43 | end 44 | end 45 | end 46 | end 47 | 48 | # Local Variables: 49 | # mode: ruby 50 | # indent-tabs-mode: t 51 | # tab-width: 3 52 | # ruby-indent-level: 3 53 | # End: 54 | -------------------------------------------------------------------------------- /lib/tdiary/io/plugin_pstore.rb: -------------------------------------------------------------------------------- 1 | # 2 | # module io/plugin_pstore 3 | # default plugin storage implemented by PStore 4 | # 5 | require 'pstore' 6 | 7 | module TDiary 8 | module IO 9 | module PluginPStore 10 | # returning storage object 11 | def plugin_open(conf) 12 | storage = Pathname(conf.data_path) + 'plugin' 13 | storage.mkpath 14 | return storage 15 | end 16 | 17 | def plugin_close(storage_object) 18 | end 19 | 20 | def plugin_transaction(storage_object, plugin_name) 21 | PStore.new(storage_object + "#{plugin_name}.db").transaction do |db| 22 | # define methods of plugin storage interface 23 | # PStore has 'delete' method as same function 24 | def db.get(key) 25 | self[key] 26 | end 27 | def db.set(key, value) 28 | self[key] = value 29 | end 30 | # def db.delete( key ) 31 | # 32 | # end 33 | def db.keys 34 | self.roots 35 | end 36 | 37 | yield db 38 | end 39 | end 40 | end 41 | end 42 | end 43 | 44 | # Local Variables: 45 | # mode: ruby 46 | # indent-tabs-mode: t 47 | # tab-width: 3 48 | # ruby-indent-level: 3 49 | # End: 50 | # vim: ts=3 51 | -------------------------------------------------------------------------------- /lib/tdiary/lang/en.rb: -------------------------------------------------------------------------------- 1 | # 2 | # tDiary language setup: English(en) 3 | # 4 | # Copyright (C) 2001-2011, TADA Tadashi 5 | # You can redistribute it and/or modify it under GPL2 or any later version. 6 | # 7 | 8 | # 9 | # 'html_lang' method returns String of HTML language attribute. 10 | # 11 | def html_lang 12 | 'en-US' 13 | end 14 | 15 | # 16 | # 'encoding' method returns String of HTTP or HTML charactor encoding. 17 | # 18 | def encoding 19 | 'UTF-8' 20 | end 21 | 22 | def encoding_old 23 | 'UTF-8' 24 | end 25 | 26 | # 27 | # 'migrate_to_utf8' method converts string to UTF-8, but dummy in en. 28 | # 29 | def migrate_to_utf8( str ) 30 | str.dup 31 | end 32 | 33 | # 34 | # 'shorten' method cuts string length. 35 | # 36 | def shorten( str, length = 120 ) 37 | matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{length - 2}}/u )[0] 38 | unless $'.empty? 39 | matched + '..' 40 | else 41 | matched 42 | end 43 | end 44 | 45 | # 46 | # 'comment_length' returns length of shorten comment on recent or monthly view. 47 | # 48 | def comment_length 49 | 120 50 | end 51 | 52 | # Local Variables: 53 | # mode: ruby 54 | # indent-tabs-mode: t 55 | # tab-width: 3 56 | # ruby-indent-level: 3 57 | # End: 58 | -------------------------------------------------------------------------------- /lib/tdiary/lang/ja.rb: -------------------------------------------------------------------------------- 1 | # 2 | # tDiary language setup: Japanese(ja) 3 | # 4 | # Copyright (C) 2001-2011, TADA Tadashi 5 | # You can redistribute it and/or modify it under GPL2. or any later version 6 | # 7 | 8 | def html_lang 9 | 'ja-JP' 10 | end 11 | 12 | def encoding 13 | 'UTF-8' 14 | end 15 | 16 | def encoding_old 17 | 'EUC-JP' 18 | end 19 | 20 | def migrate_to_utf8( str ) 21 | to_native( str, encoding_old ) 22 | end 23 | 24 | def shorten( str, len = 120 ) 25 | matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{len - 2}}/u )[0] 26 | if $'.nil? || $'.empty? 27 | matched 28 | else 29 | matched + '..' 30 | end 31 | end 32 | 33 | def comment_length 34 | 60 35 | end 36 | 37 | # Local Variables: 38 | # mode: ruby 39 | # indent-tabs-mode: t 40 | # tab-width: 3 41 | # ruby-indent-level: 3 42 | # End: 43 | -------------------------------------------------------------------------------- /lib/tdiary/plugin/03purge_cache.rb: -------------------------------------------------------------------------------- 1 | # 2 | # 01purge_cache.rb: trigger purging caches by update diary or comment 3 | # 4 | # Copyright (C) 2020, TADA Tadashi 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | # usage: 8 | # add_purge_cache_proc do |pages| 9 | # pages.each do |page| 10 | # purge_cache_on_a_cdn(base_url + page) 11 | # end 12 | # end 13 | # 14 | @purge_cache_procs = [] 15 | 16 | def add_purge_cache_proc(&proc) 17 | @purge_cache_procs << proc 18 | end 19 | 20 | add_update_proc do 21 | unless @purge_cache_procs.empty? 22 | @purge_cache_procs.empty? 23 | date = @date.strftime('%Y%m%d') 24 | days = @diaries.keys.sort 25 | diary = @diaries[date] 26 | categories = [] 27 | diary.each_section do |section| 28 | categories += section.categories 29 | end 30 | pages = [ 31 | anchor("#{@date.strftime('%Y%m%d')}"), 32 | anchor("#{@date.strftime('%m%d')}"), 33 | anchor("#{@date.strftime('%Y%m')}"), 34 | (0...@conf.latest_limit).map{|i| 35 | days[days.index(date)+i] 36 | }.compact.map{|day| 37 | anchor("#{day}-#{@conf.latest_limit}") 38 | }, 39 | categories.map{|c| "?category=#{c}"} 40 | ].flatten 41 | @purge_cache_procs.each{|proc| proc.call(pages)} 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/tdiary/plugin/en/50sp.rb: -------------------------------------------------------------------------------- 1 | # English resources of 50sp.rb 2 | 3 | =begin 4 | = Select-plugin plugin 5 | 6 | == Abstract 7 | Selects which plugin to be actually used. 8 | 9 | == Usage 10 | Put this file into the plugin/ directory. 11 | 12 | Next, move the plugins you want to be optional into another directory. 13 | In the example below, these plugins are assumed to be in 14 | plugin/selectable directory. 15 | 16 | Finally, edit the tdiary.conf file in the same directory as tdiary.rb 17 | and add the following line: 18 | @conf.options['sp.path'] = 'misc/plugin' 19 | to indicate the directory you have put the optional plugins. It can be 20 | an absolute path. 21 | 22 | == Options 23 | :@conf.options['sp.path'] 24 | Directory name where the optional plugins are, relative from the 25 | directory where tdiary.rb is or absolute. 26 | 27 | :@conf.options['sp.usenew'] 28 | Define true if you want to the users to try a newly installed plugin. 29 | Newly installed plugins are detected next time when the user configures 30 | this plugin. 31 | 32 | == Copyright notice 33 | Copyright (C) 2003 zunda 34 | 35 | Permission is granted for use, copying, modification, distribution, and 36 | distribution of modified versions of this work under the terms of GPL version 2 or later. 37 | =end 38 | 39 | @sp_label = 'Plugin selection' 40 | @sp_label_description = '

Selects which plugins you want to use.

' 41 | @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!

' 42 | @sp_label_new = '

New! Give it a try.

' 43 | @sp_label_used = '

Being used

' 44 | @sp_label_notused = '

Currently not used

' 45 | @sp_label_noplugin = '

There is no optional plugins.

' 46 | 47 | # Local Variables: 48 | # mode: ruby 49 | # indent-tabs-mode: t 50 | # tab-width: 3 51 | # ruby-indent-level: 3 52 | # End: 53 | -------------------------------------------------------------------------------- /lib/tdiary/plugin/en/60sf.rb: -------------------------------------------------------------------------------- 1 | # English resources of 60sf.rb 2 | # Based on English resources of 50sp.rb Revision: 1.2 3 | # Modified by KURODA Hiraku 4 | 5 | =begin 6 | = Select-spamfilter plugin 7 | 8 | == Abstract 9 | Selects which filter to be actually used. 10 | 11 | == Usage 12 | Put this file into the plugin/ directory. 13 | 14 | Next, move the filterss you want to be optional into another directory. 15 | In the example below, these filters are assumed to be in 16 | filter/selectable directory. 17 | 18 | Finally, edit the tdiary.conf file in the same directory as tdiary.rb 19 | and add the following line: 20 | @conf.options['sf.path'] = 'misc/filter' 21 | to indicate the directory you have put the optional filters. It can be 22 | an absolute path. 23 | 24 | == Options 25 | :@conf.options['sf.path'] 26 | Directory name where the optional filters are, relative from the 27 | directory where tdiary.rb is or absolute. 28 | 29 | :@conf.options['sf.usenew'] 30 | Define true if you want to the users to try a newly installed filter. 31 | Newly installed filters are detected next time when the user configures 32 | this plugin. 33 | 34 | == Copyright notice 35 | Copyright (C) 2003 zunda 36 | 37 | Permission is granted for use, copying, modification, distribution, and 38 | distribution of modified versions of this work under the terms of GPL version 2 or later. 39 | 40 | Original version of these files is for selecting plugins. 41 | Modifying for selecting filters is by KURODA Hiraku 42 | Feb. 2008 43 | =end 44 | 45 | @sf_label = 'Filter selection' 46 | @sf_label_description = '

Selects which filters you want to use.

' 47 | @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!

' 48 | @sf_label_new = '

New! Give it a try.

' 49 | @sf_label_used = '

Being used

' 50 | @sf_label_notused = '

Currently not used

' 51 | @sf_label_nofilter = '

There is no optional filters.

' 52 | 53 | # Local Variables: 54 | # mode: ruby 55 | # indent-tabs-mode: t 56 | # tab-width: 3 57 | # ruby-indent-level: 3 58 | # End: 59 | -------------------------------------------------------------------------------- /lib/tdiary/plugin/ja/05referer.rb: -------------------------------------------------------------------------------- 1 | # 2 | # 05referer.rb: Japanese resource of referer plugin 3 | # 4 | # Copyright (C) 2006, TADA Tadashi 5 | # You can redistribute it and/or modify it under GPL2 or any later version. 6 | # 7 | 8 | def referer_today; '本日のリンク元'; end 9 | def volatile_referer; '以前の日記へのリンク元'; end 10 | 11 | def label_no_referer; 'リンク元記録除外リスト'; end 12 | def label_only_volatile; '以前の日記へのリンク元に記録するリスト'; end 13 | def label_referer_table; 'リンク置換リスト'; end 14 | 15 | add_conf_proc( 'referer', 'リンク元', 'referer' ) do 16 | saveconf_referer 17 | 18 | <<-HTML 19 |

リンク元の表示

20 |

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

21 |

25 |

#{label_no_referer}

26 |

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

27 |

既存設定はこちら

28 |

29 |

#{label_only_volatile}

30 |

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

31 |

既存設定はこちら

32 |

33 |

#{label_referer_table}

34 |

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

35 |

既存設定はこちら

36 |

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

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

' 51 | @sp_label_please_select = '

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

' 52 | @sp_label_new = '

新入荷!お試しください

' 53 | @sp_label_used = '

使用中

' 54 | @sp_label_notused = '

休憩中

' 55 | @sp_label_noplugin = '

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

' 56 | 57 | # Local Variables: 58 | # mode: ruby 59 | # indent-tabs-mode: t 60 | # tab-width: 3 61 | # ruby-indent-level: 3 62 | # End: 63 | -------------------------------------------------------------------------------- /lib/tdiary/plugin/ja/60sf.rb: -------------------------------------------------------------------------------- 1 | # Japanese resources of 60sf.rb 2 | # Based on 50sp.rb 3 | # Modified by KURODA Hiraku. 4 | 5 | =begin 6 | = スパムフィルター選択プラグイン 7 | Please see below for an English description. 8 | 9 | == 概要 10 | どのフィルターを使うのか選びます 11 | 12 | 選択したフィルターはデフォルトのフィルターによる判定の後で適用されます。 13 | 14 | == 使い方 15 | このプラグインをplugin/ディレクトリに配置してください。 16 | 17 | 次に、tdiary.rbと同じ場所にあるtdiary.confに、 18 | @conf.options['sf.path'] = 'misc/filter' 19 | などと、選択できるフィルターのあるディレクトリをtdiary.rbのあるディレク 20 | トリからの相対パスか絶対パスで指定してください。 21 | 22 | フィルターに設定用のプラグインが付属している場合は、フィルター用ディレク 23 | トリの下にpluginディレクトリを作り、その中に入れておくと、フィルターを 24 | ロードした後でプラグインもロードされます。 25 | 26 | 例えばベイズフィルタをmisc/filterに置いた場合は次のようなディレクトリ 27 | 構成になります。 28 | 29 | misc/filter/ 30 | |-- plugin/ 31 | | |-- en/spambayes.rb 32 | | |-- ja/spambayes.rb 33 | | `-- spambayes.rb 34 | `-- spambayes.rb 35 | 36 | == オプション 37 | :@conf.options['sf.path'] 38 | 'filter/selectable'などと、選択できるフィルターのあるディレクトリを、 39 | tdiary.rbのあるディレクトリからの相対パスか絶対パスで指定してください。 40 | 41 | :@conf.options['sf.usenew'] 42 | 新しくインストールされたフィルターをデフォルトで使うようにする場合は 43 | trueに設定してください。新しくインストールされたフィルターを検出するの 44 | は、次にフィルターが選択される時です。 45 | 46 | == 著作権について (Copyright notice) 47 | Copyright (C) 2003 zunda 48 | 49 | Permission is granted for use, copying, modification, distribution, and 50 | distribution of modified versions of this work under the terms of GPL version 2 or later. 51 | 52 | Original version of these files is for selecting plugins. 53 | Modifying for selecting filters is by KURODA Hiraku 54 | Feb. 2008 55 | =end 56 | 57 | 58 | @sf_label = 'スパムフィルター選択' 59 | @sf_label_description = '

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

' 60 | @sf_label_please_select = '

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

' 61 | @sf_label_new = '

新入荷!お試しください

' 62 | @sf_label_used = '

使用中

' 63 | @sf_label_notused = '

休憩中

' 64 | @sf_label_noplugin = '

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

' 65 | 66 | # Local Variables: 67 | # mode: ruby 68 | # indent-tabs-mode: t 69 | # tab-width: 3 70 | # ruby-indent-level: 3 71 | # End: 72 | -------------------------------------------------------------------------------- /lib/tdiary/rack.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module Rack 3 | autoload :HtmlAnchor, 'tdiary/rack/html_anchor' 4 | autoload :ValidRequestPath, 'tdiary/rack/valid_request_path' 5 | autoload :Session, 'tdiary/rack/session' 6 | autoload :Static, 'tdiary/rack/static' 7 | autoload :Auth, 'tdiary/rack/auth' 8 | end 9 | end 10 | 11 | # Local Variables: 12 | # mode: ruby 13 | # indent-tabs-mode: t 14 | # tab-width: 3 15 | # ruby-indent-level: 3 16 | # End: 17 | # vim: ts=3 18 | -------------------------------------------------------------------------------- /lib/tdiary/rack/auth.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module Rack 3 | class Auth 4 | autoload :Basic, 'tdiary/rack/auth/basic' 5 | autoload :OmniAuth, 'tdiary/rack/auth/omniauth' 6 | 7 | def initialize(app) 8 | if defined? ::OmniAuth 9 | @app = TDiary::Rack::Auth::OmniAuth.new(app) 10 | else 11 | @app = TDiary::Rack::Auth::Basic.new(app, ENV['HTPASSWD'] || '.htpasswd') 12 | end 13 | end 14 | 15 | def call(env) 16 | @app.call(env) 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/tdiary/rack/auth/basic.rb: -------------------------------------------------------------------------------- 1 | require 'rack' 2 | require 'webrick/httpauth/htpasswd' 3 | 4 | module TDiary 5 | module Rack 6 | class Auth 7 | class PasswordFileNotFound < StandardError; end 8 | 9 | class Basic 10 | def initialize(app, file = '.htpasswd') 11 | @authenticator = ::Rack::Auth::Basic.new(app) do |user, pass| 12 | unless File.exist?(file) 13 | raise PasswordFileNotFound.new("#{file} is not found. Please create it by htpasswd program.") 14 | end 15 | htpasswd = WEBrick::HTTPAuth::Htpasswd.new(file) 16 | crypted = htpasswd.get_passwd(nil, user, false) 17 | crypted == pass.crypt(crypted) if crypted 18 | end 19 | end 20 | 21 | def call(env) 22 | begin 23 | @authenticator.call(env) 24 | rescue PasswordFileNotFound => e 25 | [403, {"content-type" => "text/plain"}, [e.message]] 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | 33 | # Local Variables: 34 | # mode: ruby 35 | # indent-tabs-mode: t 36 | # tab-width: 3 37 | # ruby-indent-level: 3 38 | # End: 39 | -------------------------------------------------------------------------------- /lib/tdiary/rack/auth/omniauth/authorization.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth' 2 | 3 | module TDiary 4 | module Rack 5 | class Auth 6 | class OmniAuth 7 | class Authorization 8 | def initialize(app, provider, &block) 9 | @app = app 10 | @provider = provider 11 | @authz = block 12 | end 13 | 14 | def call(env) 15 | if not authenticate?(env) 16 | # phase 1: request phase 17 | login(env) 18 | elsif env['REQUEST_PATH'].match(%r|auth/#{@provider}/callback|) 19 | # phase 2: callback phase 20 | callback(env) 21 | else 22 | # phase 3: authorization phase 23 | auth = env['rack.session']['auth'] 24 | env['REMOTE_USER'] = "#{auth.uid}@#{auth.provider}" 25 | return forbidden unless @authz.call(auth) 26 | @app.call(env) 27 | end 28 | end 29 | 30 | def login(env) 31 | STDERR.puts "use #{@provider} authentication strategy" 32 | req = ::Rack::Request.new(env) 33 | env['rack.session']['tdiary.auth.redirect'] = "#{req.base_url}#{req.fullpath}" 34 | redirect = File.join("#{req.base_url}#{req.path}", "#{::OmniAuth.config.path_prefix}/#{@provider}") 35 | [302, {'content-type' => 'text/plain', 'location' => redirect}, []] 36 | end 37 | 38 | def logout(env) 39 | env['rack.session']['user_id'] = nil 40 | end 41 | 42 | def forbidden 43 | [403, {'content-type' => 'text/plain'}, ['forbidden']] 44 | end 45 | 46 | def callback(env) 47 | # reset sesstion to prevend session fixation attack 48 | # see: http://www.ipa.go.jp/security/vuln/documents/website_security.pdf (section 1.4) 49 | env['rack.session.options'][:renew] = true 50 | auth = env['omniauth.auth'] 51 | env['rack.session']['auth'] = auth 52 | env['REMOTE_USER'] = "#{auth.uid}@#{auth.provider}" 53 | redirect = env['rack.session']['tdiary.auth.redirect'] || '/' 54 | [302, {'content-type' => 'text/plain', 'location' => redirect}, []] 55 | end 56 | 57 | def authenticate?(env) 58 | env['omniauth.auth'] || env['rack.session']['auth'] 59 | end 60 | end 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lib/tdiary/rack/html_anchor.rb: -------------------------------------------------------------------------------- 1 | require 'rack/request' 2 | 3 | module TDiary 4 | module Rack 5 | class HtmlAnchor 6 | def initialize( app ) 7 | @app = app 8 | end 9 | 10 | def call( env ) 11 | if env['PATH_INFO'].match(/(.*\/)([0-9\-]+)(p(\d\d))?\.html$/) 12 | env["PATH_INFO"] = $1 13 | date = $2 14 | anchor = $4 15 | env["QUERY_STRING"] += "&" unless env["QUERY_STRING"].empty? 16 | env["QUERY_STRING"] += "date=#{date}" 17 | env["QUERY_STRING"] += "&p=#{anchor}" if anchor 18 | end 19 | @app.call( env ) 20 | end 21 | end 22 | end 23 | end 24 | 25 | # Local Variables: 26 | # mode: ruby 27 | # indent-tabs-mode: t 28 | # tab-width: 3 29 | # ruby-indent-level: 3 30 | # End: 31 | -------------------------------------------------------------------------------- /lib/tdiary/rack/session.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rack/session/dalli' 3 | rescue LoadError 4 | end 5 | 6 | module TDiary 7 | module Rack 8 | class Session 9 | def initialize(app) 10 | @app = session_middleware(app) 11 | end 12 | 13 | def call(env) 14 | @app.call(env) 15 | end 16 | 17 | private 18 | 19 | def session_middleware(app) 20 | if ::Rack::Session.const_defined? :Dalli 21 | ::Rack::Session::Dalli.new( 22 | app, 23 | expire_after: 2592000 24 | ) 25 | else 26 | ::Rack::Session::Pool.new( 27 | app, 28 | expire_after: 2592000 29 | ) 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/tdiary/rack/static.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rack/files' 3 | rescue LoadError 4 | require 'rack/file' 5 | end 6 | 7 | module TDiary 8 | module Rack 9 | class Static 10 | def initialize( app, base_dir ) 11 | @app = app 12 | @file = base_dir.map{|dir| ::Rack::Files.new(dir) } 13 | end 14 | 15 | def call( env ) 16 | result = [] 17 | 18 | @file.each do |f| 19 | result = f.call(env) 20 | break if result[0].to_i < 400 || result[0].to_i >= 500 21 | end 22 | 23 | if result[0].to_i >= 400 && result[0].to_i < 500 24 | @app.call( env ) 25 | else 26 | result 27 | end 28 | end 29 | end 30 | end 31 | end 32 | 33 | # Local Variables: 34 | # mode: ruby 35 | # indent-tabs-mode: t 36 | # tab-width: 3 37 | # ruby-indent-level: 3 38 | # End: 39 | -------------------------------------------------------------------------------- /lib/tdiary/rack/valid_request_path.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module Rack 3 | class ValidRequestPath 4 | def initialize( app ) 5 | @app = app 6 | end 7 | 8 | def call( env ) 9 | valid_paths = [ 10 | %r{^/$}, 11 | %r{^/index\.(rb|cgi)$}, 12 | %r{^/([0-9\-p]+)\.html$} 13 | ] 14 | valid_paths.each do |path| 15 | return @app.call(env) if env['PATH_INFO'].match(path) 16 | end 17 | 18 | body = "Not Found: #{env['PATH_INFO']}" 19 | if env["REQUEST_METHOD"] == "HEAD" 20 | [404, {'content-type' => 'text/plain', 'content-length' => body.length.to_s}, []] 21 | else 22 | [404, {'content-type' => 'text/plain'}, [body]] 23 | end 24 | end 25 | end 26 | end 27 | end 28 | 29 | # Local Variables: 30 | # mode: ruby 31 | # indent-tabs-mode: t 32 | # tab-width: 3 33 | # ruby-indent-level: 3 34 | # End: 35 | -------------------------------------------------------------------------------- /lib/tdiary/referer_manager.rb: -------------------------------------------------------------------------------- 1 | # 2 | # module RefererManager 3 | # Management referers in a day. Include in Diary class. 4 | # 5 | 6 | module TDiary 7 | module RefererManager 8 | private 9 | # 10 | # call this method when initialize 11 | # 12 | def init_referers 13 | @referers = {} 14 | @new_referer = true # for compatibility 15 | end 16 | 17 | public 18 | def add_referer( ref, count = 1 ) 19 | newer_referer 20 | ref = ref.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) 21 | if /^([^:]+:\/\/)([^\/]+)/ =~ ref 22 | ref = $1 + $2.downcase + $' 23 | end 24 | begin 25 | uref = CGI::unescape( ref ) 26 | rescue ::Encoding::CompatibilityError 27 | return 28 | end 29 | if pair = @referers[uref] then 30 | pair = [pair, ref] if pair.class != Array # for compatibility 31 | @referers[uref] = [pair[0] + count, pair[1]] 32 | else 33 | @referers[uref] = [count, ref] 34 | end 35 | end 36 | 37 | def clear_referers 38 | @referers = {} 39 | end 40 | 41 | def count_referers 42 | @referers.size 43 | end 44 | 45 | def each_referer( limit = 10 ) 46 | newer_referer 47 | # dirty workaround to avoid recursive sort that 48 | # causes SecurityError in @secure=true 49 | # environment since 50 | # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=16081 51 | @referers.values.sort_by{|e| "%08d_%s" % e}.reverse.each_with_index do |ary,idx| 52 | break if idx >= limit 53 | yield ary[0], ary[1] 54 | end 55 | end 56 | 57 | private 58 | def newer_referer 59 | unless @new_referer then # for compatibility 60 | @referers.keys.each do |ref| 61 | count = @referers[ref] 62 | if count.class != Array then 63 | @referers.delete( ref ) 64 | @referers[CGI::unescape( ref )] = [count, ref] 65 | end 66 | end 67 | @new_referer = true 68 | end 69 | end 70 | end 71 | end 72 | 73 | # Local Variables: 74 | # mode: ruby 75 | # indent-tabs-mode: t 76 | # tab-width: 3 77 | # ruby-indent-level: 3 78 | # End: 79 | # vim: ts=3 80 | -------------------------------------------------------------------------------- /lib/tdiary/response.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | class Response < ::Rack::Response 3 | end 4 | end 5 | 6 | # Local Variables: 7 | # mode: ruby 8 | # indent-tabs-mode: t 9 | # tab-width: 3 10 | # ruby-indent-level: 3 11 | # End: 12 | -------------------------------------------------------------------------------- /lib/tdiary/tasks.rb: -------------------------------------------------------------------------------- 1 | Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f } 2 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/assets.rake: -------------------------------------------------------------------------------- 1 | namespace :assets do 2 | desc "copy assets files" 3 | task :copy do 4 | require 'fileutils' 5 | assets_path = File.dirname(__FILE__) + '/../../../public/assets' 6 | 7 | FileUtils.mkdir_p assets_path 8 | FileList['{js,theme}/*'].each do |file| 9 | FileUtils.cp_r(file, "#{assets_path}/#{Pathname.new(file).basename}") 10 | end 11 | end 12 | end 13 | 14 | # Local Variables: 15 | # mode: ruby 16 | # indent-tabs-mode: t 17 | # tab-width: 3 18 | # ruby-indent-level: 3 19 | # End: 20 | # vim: ts=3 21 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/auth.rake: -------------------------------------------------------------------------------- 1 | namespace :auth do 2 | namespace :password do 3 | desc "create password" 4 | task :create do 5 | require 'webrick/httpauth/htpasswd' 6 | puts 'create .htpasswd file' 7 | print 'Username: ' 8 | ARGV.replace([]) 9 | username = gets().chop 10 | print 'New password: ' 11 | system "stty -echo" 12 | password = $stdin.gets.chop 13 | puts 14 | print 'Re-type new password: ' 15 | password2 = $stdin.gets.chop 16 | puts 17 | system "stty echo" 18 | if password != password2 19 | raise StandardError, 'password verification error' 20 | else 21 | htpasswd = WEBrick::HTTPAuth::Htpasswd.new('.htpasswd') 22 | htpasswd.set_passwd(nil, username, password) 23 | htpasswd.flush 24 | puts "Adding password for user #{username}" 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/doc.rake: -------------------------------------------------------------------------------- 1 | desc "generate document files" 2 | task :doc do 3 | require 'redcarpet' 4 | require 'pathname' 5 | FileList['doc/*.md'].each do |md| 6 | target = Pathname.new(md) 7 | header = <<-HEADER 8 | 9 | 10 | 11 | #{target.basename('.md')} 12 | 13 | 14 | 15 | HEADER 16 | footer = <<-FOOTER 17 | 18 | 19 | FOOTER 20 | html = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true).render(File.open(md).read) 21 | open(target.sub(/\.md\z/, '.html'), 'w') {|f| f.write(header + html + footer)} 22 | end 23 | end 24 | 25 | # Local Variables: 26 | # mode: ruby 27 | # indent-tabs-mode: t 28 | # tab-width: 3 29 | # ruby-indent-level: 3 30 | # End: 31 | # vim: ts=3 32 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/heroku.rake: -------------------------------------------------------------------------------- 1 | namespace :heroku do 2 | file 'tdiary.conf' => ['tdiary.conf.heroku'] do |t| 3 | FileUtils.cp(t.prerequisites.first, t.name) 4 | end 5 | 6 | file '.htpasswd' do 7 | Rake::Task["auth:password:create"].invoke 8 | end 9 | 10 | task :install => ['.htpasswd', 'tdiary.conf'] do |t| 11 | sh "git checkout -b deploy" 12 | sh "git add -f #{t.prerequisites.join(' ')}" 13 | sh "git commit -m 'deploy'" 14 | sh "git push heroku deploy:master" 15 | # FIXME: heroku command does not work in rake env 16 | # sh "heroku run rake db:create" 17 | end 18 | 19 | task :update do 20 | # sh "git pull origin master:deploy" 21 | # sh "git push heroku deploy:master" 22 | raise NotImplementedError 23 | end 24 | 25 | task :clean do 26 | sh "git checkout master" 27 | sh "git branch -D deploy" 28 | end 29 | end 30 | 31 | # Local Variables: 32 | # mode: ruby 33 | # indent-tabs-mode: t 34 | # tab-width: 3 35 | # ruby-indent-level: 3 36 | # End: 37 | # vim: ts=3 38 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/mongodb.rake: -------------------------------------------------------------------------------- 1 | namespace :mongodb do 2 | desc "make index into mongoDB" 3 | task :index do 4 | require 'erb' 5 | require 'tdiary' 6 | conf = TDiary::Config.new 7 | TDiary::DiaryContainer.new(conf, '2015', '01') 8 | TDiary::IO::MongoDB::Diary.create_indexes 9 | TDiary::IO::MongoDB::Comment.create_indexes 10 | TDiary::IO::MongoDB::Plugin.create_indexes 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/rdoc.rake: -------------------------------------------------------------------------------- 1 | desc "generate rdoc files" 2 | task :rdoc do 3 | root_dir = File.dirname(__FILE__) 4 | 5 | dirlist = Dir.glob(root_dir + "/rdoc/**/").sort { 6 | |a,b| b.split('/').size <=> a.split('/').size 7 | } 8 | dirlist.each {|d| 9 | Dir.foreach(d) {|f| 10 | File::delete(d + f) if !(/\.+$/ =~ f) 11 | } 12 | Dir.rmdir(d) 13 | } 14 | 15 | `cd #{root_dir} && rdoc --all --charset=UTF8 --op=rdoc --inline-source README ChangeLog index.rb update.rb tdiary.rb tdiary/* misc/* plugin/*` 16 | end 17 | 18 | # Local Variables: 19 | # mode: ruby 20 | # indent-tabs-mode: t 21 | # tab-width: 3 22 | # ruby-indent-level: 3 23 | # End: 24 | # vim: ts=3 25 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | if defined? RSpec 2 | require 'rspec/core/rake_task' 3 | 4 | desc 'Run the code in spec' 5 | RSpec::Core::RakeTask.new(:spec) do |t| 6 | t.pattern = "spec/**/*_spec.rb" 7 | end 8 | 9 | namespace :spec do 10 | %w(core plugin acceptance).each do |dir| 11 | desc "Run the code examples in spec/#{dir}" 12 | RSpec::Core::RakeTask.new(dir.to_sym) do |t| 13 | t.pattern = "spec/#{dir}/**/*_spec.rb" 14 | end 15 | end 16 | 17 | namespace :acceptance do 18 | desc 'Run the code examples in spec/acceptance with cgi mode' 19 | task :cgi do 20 | ENV['TEST_MODE'] = 'webrick' 21 | Rake::Task["spec:acceptance"].invoke 22 | end 23 | end 24 | 25 | desc 'Displayed code coverage with SimpleCov' 26 | task :coverage do 27 | ENV['COVERAGE'] = 'simplecov' 28 | Rake::Task["spec"].invoke 29 | end 30 | end 31 | end 32 | 33 | # Local Variables: 34 | # mode: ruby 35 | # indent-tabs-mode: t 36 | # tab-width: 3 37 | # ruby-indent-level: 3 38 | # End: 39 | # vim: ts=3 40 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/server.rake: -------------------------------------------------------------------------------- 1 | # 2 | # server: script for running standalone tdiary cgi server. 3 | # 4 | # Copyright (C) 2008-2010, Kakutani Shintaro 5 | # You can redistribute it and/or modify it under GPL2 or any later version. 6 | 7 | task :server do 8 | $:.unshift File.expand_path('../../../', __FILE__) 9 | require 'tdiary' 10 | 11 | unless File.exist?(TDiary.root + '/tdiary.conf') 12 | FileUtils.cp_r(TDiary.root + '/spec/fixtures/tdiary.conf.webrick', 13 | TDiary.root + '/tdiary.conf', :verbose => false) 14 | end 15 | unless File.directory?(TDiary.root + '/tmp/data') 16 | FileUtils.mkdir_p(TDiary.root + '/tmp/data/log') 17 | File.open(TDiary.root + '/tmp/data/tdiary.conf', 'w') do |f| 18 | f.write "tdiary_version = \"#{TDIARY_VERSION}\"" 19 | end 20 | File.chmod(0644, TDiary.root + '/tmp/data/tdiary.conf') 21 | end 22 | 23 | opts = { 24 | :daemon => ENV['DAEMON'], 25 | :bind => ENV['BIND'] || '0.0.0.0', 26 | :port => ENV['PORT'] || 19292, 27 | :logger => $stderr, 28 | :access_log => $stderr, 29 | } 30 | 31 | TDiary::Server.run( opts ) 32 | end 33 | -------------------------------------------------------------------------------- /lib/tdiary/tasks/test.rake: -------------------------------------------------------------------------------- 1 | if defined? Test::Unit 2 | require 'rake/testtask' 3 | 4 | Rake::TestTask.new do |t| 5 | t.libs << "test" 6 | t.test_files = FileList['test/**/*_test.rb'] 7 | t.verbose = true 8 | end 9 | end 10 | 11 | # Local Variables: 12 | # mode: ruby 13 | # indent-tabs-mode: t 14 | # tab-width: 3 15 | # ruby-indent-level: 3 16 | # End: 17 | # vim: ts=3 18 | -------------------------------------------------------------------------------- /lib/tdiary/version.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | VERSION = '5.4.0.beta3' 3 | end 4 | -------------------------------------------------------------------------------- /lib/tdiary/view_helper.rb: -------------------------------------------------------------------------------- 1 | module TDiary 2 | module ViewHelper 3 | def bot? 4 | @conf.bot =~ @cgi.user_agent 5 | end 6 | 7 | def base_url 8 | if @conf.options['base_url'] && @conf.options['base_url'].length > 0 9 | @conf.options['base_url'] 10 | else 11 | @cgi.base_url 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /misc/filter/limitdays.rb: -------------------------------------------------------------------------------- 1 | # 2 | # limitdays.rb: 3 | # 4 | # Copyright (C) SHIBATA Hiroshi 2008. 5 | # Distributed under GPL2 or any later version. 6 | # 7 | 8 | module TDiary::Filter 9 | class LimitdaysFilter < Filter 10 | def comment_filter( diary, comment ) 11 | if @conf.options.include?('spamfilter.date_limit') && 12 | @conf.options['spamfilter.date_limit'] && 13 | /\A\d+\z/ =~ @conf.options['spamfilter.date_limit'].to_s 14 | @date_limit = @conf.options['spamfilter.date_limit'].to_s.to_i 15 | else 16 | @date_limit = nil 17 | end 18 | 19 | if @date_limit 20 | now = Time.now 21 | today = Time.local(now.year, now.month, now.day) 22 | limit = today - 24 * 60 * 60 * @date_limit 23 | if diary.date < limit 24 | debug( "too old: #{diary.date} (limit >= #{limit})" ) 25 | comment.show = false 26 | return false 27 | end 28 | end 29 | return true 30 | end 31 | end 32 | end 33 | 34 | # Local Variables: 35 | # mode: ruby 36 | # indent-tabs-mode: t 37 | # tab-width: 3 38 | # ruby-indent-level: 3 39 | # End: 40 | -------------------------------------------------------------------------------- /misc/filter/plugin/en/antispamservice.rb: -------------------------------------------------------------------------------- 1 | # 2 | # en/antispamservice.rb: English resource of Antispam filter setup plugin. $Revision: 1.2 $ 3 | # 4 | 5 | @antispam_label_conf = 'Antispam service filter' 6 | @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.' 7 | 8 | @antispam_label_service = 'Select Antispam Service' 9 | 10 | @antispam_label_key = 'API Key' 11 | @antispam_desc_key = 'API Key' 12 | @antispam_warn_key = 'Invalid API Key.' 13 | 14 | 15 | # Local Variables: 16 | # mode: ruby 17 | # indent-tabs-mode: t 18 | # tab-width: 3 19 | # ruby-indent-level: 3 20 | # End: 21 | -------------------------------------------------------------------------------- /misc/filter/plugin/ja/antispamservice.rb: -------------------------------------------------------------------------------- 1 | # 2 | # ja/antispamservice.rb: Japanese resource of Antispam filter setup plugin. $Revision: 1.2 $ 3 | # 4 | 5 | @antispam_label_conf = 'Antispamサービス フィルタ' 6 | @antispam_desc = 'Antispamサービス フィルタは、APIとして提供されるspam判定サービスを使って、ツッコミやTrackBackのspamを排除するフィルタです。このサービスを利用するには、使用するサービスのAPI Keyを取得して、以下に設定する必要があります。' 7 | 8 | @antispam_label_service = '使用するspam判定サービスの選択' 9 | 10 | @antispam_label_key = 'API Key' 11 | @antispam_desc_key = 'API Key' 12 | @antispam_warn_key = 'API Keyが正しくありません。サービスの提供元によって拒絶されました。' 13 | 14 | # Local Variables: 15 | # mode: ruby 16 | # indent-tabs-mode: t 17 | # tab-width: 3 18 | # ruby-indent-level: 3 19 | # End: 20 | -------------------------------------------------------------------------------- /misc/lib/README: -------------------------------------------------------------------------------- 1 | This directory is for libraries: 2 | 3 | * for compatibility with ruby 1.8 and 1.9. 4 | * for patching about charctor encoding. 5 | -------------------------------------------------------------------------------- /misc/lib/compatible.rb: -------------------------------------------------------------------------------- 1 | # move to tdiary/compatible.rb 2 | -------------------------------------------------------------------------------- /misc/paas/heroku/Gemfile.local: -------------------------------------------------------------------------------- 1 | ruby '~> 3.2.2' 2 | gem 'puma', require: false 3 | gem 'tdiary-io-mongodb', git: 'https://github.com/tdiary/tdiary-io-mongodb.git' 4 | gem 'tdiary-contrib', git: 'https://github.com/tdiary/tdiary-contrib.git' 5 | gem 'tdiary-style-gfm' 6 | gem 'tdiary-style-rd' 7 | gem 'omniauth' 8 | gem 'omniauth-github' 9 | gem 'dalli' 10 | gem 'rack-session' 11 | gem 'connection_pool' 12 | gem 'memcachier' 13 | -------------------------------------------------------------------------------- /misc/plugin/append-css.rb: -------------------------------------------------------------------------------- 1 | # append-css.rb 2 | # 3 | # Append CSS fragment via Preferences Page. 4 | # 5 | # Copyright (c) 2002 TADA Tadashi 6 | # Distributed under the GPL2 or any later version. 7 | # 8 | add_header_proc do 9 | if @mode !~ /conf$/ && @conf['append-css.css'] && @conf['append-css.css'].length > 0 && !bot? 10 | <<-HTML if @conf['append-css.css'] 11 | 14 | HTML 15 | else 16 | '' 17 | end 18 | end 19 | 20 | unless @resource_loaded 21 | def append_css_label 22 | 'CSSの追加' 23 | end 24 | 25 | def append_css_desc 26 | <<-HTML 27 |

CSS断片

28 |

現在指定してあるテーマに、スタイルシートを追加設定する場合、 29 | 以下にCSSの断片を入力してください。

30 | HTML 31 | end 32 | end 33 | 34 | add_conf_proc( 'append-css', append_css_label, 'theme' ) do 35 | if @mode == 'saveconf' 36 | @conf['append-css.css'] = @cgi.params['append-css.css'][0] 37 | end 38 | 39 | <<-HTML 40 | #{append_css_desc} 41 |

42 | HTML 43 | end 44 | 45 | # Local Variables: 46 | # mode: ruby 47 | # indent-tabs-mode: t 48 | # tab-width: 3 49 | # ruby-indent-level: 3 50 | # End: 51 | -------------------------------------------------------------------------------- /misc/plugin/bq.rb: -------------------------------------------------------------------------------- 1 | # bq.rb 2 | # 3 | # bq: blockquoteを使った引用を生成する 4 | # パラメタ: 5 | # src: 引用するテキスト 6 | # title: 引用元のタイトル 7 | # url: 引用元のURL 8 | # 9 | # 引用元タイトルをうまく表示するには、スタイルシートでp.sourceを 10 | # 定義する必要があります。スタイルの例: 11 | # 12 | # p.source { 13 | # margin-top: 0.3em; 14 | # text-align: right; 15 | # font-size: 90%; 16 | # } 17 | # 18 | # Copyright (C) 2002 s.sawada 19 | # You can redistribute it and/or modify it under GPL2 or any later version. 20 | # 21 | def bq( src, title = nil, url = nil ) 22 | if url 23 | result = %Q[
\n] 24 | elsif title 25 | result = %Q[
\n] 26 | else 27 | result = %Q[
\n] 28 | end 29 | result << %Q[

#{src.gsub( /\n/, "

\n

" )}

\n].sub( %r[

], '' ) 30 | result << %Q[
\n] 31 | if url 32 | cite = %Q[#{title}] 33 | result << %Q[

[#{bq_cite_from cite}]

\n] 34 | elsif title 35 | cite = %Q[#{title}] 36 | result << %Q[

[#{bq_cite_from cite}]

\n] 37 | end 38 | 39 | result 40 | end 41 | 42 | # Local Variables: 43 | # mode: ruby 44 | # indent-tabs-mode: t 45 | # tab-width: 3 46 | # ruby-indent-level: 3 47 | # End: 48 | -------------------------------------------------------------------------------- /misc/plugin/category_autocomplete.rb: -------------------------------------------------------------------------------- 1 | # 2 | # category_autocomplete.rb : Support the automatic input of the category 3 | # using jQuery UI autocomplete. 4 | # 5 | # Copyright (C) 2010-2012, tamoot 6 | # You can redistribute it and/or modify it under GPL2 or any later version. 7 | # 8 | 9 | if /\A(?:form|preview|append|edit|update)\z/ =~ @mode 10 | add_header_proc do 11 | %Q|| 12 | end 13 | 14 | enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') 15 | enable_js('caretposition.js') 16 | enable_js('category_autocomplete.js') 17 | 18 | if @categories.size > 0 19 | categories_json = @categories.map{ |c| "\"#{c}\"" } 20 | add_js_setting('$tDiary.plugin.category_autocomplete') 21 | add_js_setting('$tDiary.plugin.category_autocomplete.candidates', 22 | "[#{categories_json.join(",")}]") 23 | end 24 | end 25 | 26 | # Local Variables: 27 | # mode: ruby 28 | # indent-tabs-mode: t 29 | # tab-width: 3 30 | # ruby-indent-level: 3 31 | # End: 32 | # vim: ts=3 33 | -------------------------------------------------------------------------------- /misc/plugin/comment_ajax.rb: -------------------------------------------------------------------------------- 1 | if @mode == 'day' and not bot? then 2 | enable_js('comment_ajax.js') 3 | add_js_setting('$tDiary.plugin.comment_ajax') 4 | add_js_setting('$tDiary.plugin.comment_ajax.theme', %Q["#{theme_url}"]) 5 | end 6 | 7 | # Local Variables: 8 | # mode: ruby 9 | # indent-tabs-mode: t 10 | # tab-width: 3 11 | # ruby-indent-level: 3 12 | # End: 13 | # vi: ts=3 sw=3 14 | -------------------------------------------------------------------------------- /misc/plugin/comment_emoji_autocomplete.rb: -------------------------------------------------------------------------------- 1 | # 2 | # comment_emoji_autocomplete.rb : Support the automatic input of the emoji 3 | # using jQuery UI autocomplete. 4 | # 5 | # Copyright (C) 2013, tamoot 6 | # You can redistribute it and/or modify it under GPL2 or any later version. 7 | # 8 | 9 | if /\A(?:day)\z/ =~ @mode 10 | add_header_proc do 11 | %Q|| 12 | end 13 | 14 | enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') 15 | enable_js('caretposition.js') 16 | enable_js('comment_emoji_autocomplete.js') 17 | end 18 | 19 | # Local Variables: 20 | # mode: ruby 21 | # indent-tabs-mode: t 22 | # tab-width: 3 23 | # ruby-indent-level: 3 24 | # End: 25 | # vim: ts=3 26 | -------------------------------------------------------------------------------- /misc/plugin/comment_mail-qmail.rb: -------------------------------------------------------------------------------- 1 | # comment_mail_qmail.rb 2 | # 3 | # qmailを使ってツッコミをメールで知らせる 4 | # 入れるだけで動作する。 5 | # 6 | # Options: 7 | # 設定画面から指定できるもの(ツッコミメール系プラグイン共通): 8 | # @options['comment_mail.enable'] 9 | # メールを送るかどうかを指定する。true(送る)かfalse(送らない)。 10 | # 無指定時はfalse。 11 | # @options['comment_mail.header'] 12 | # メールのSubjectに使う文字列。振り分け等に便利なように指定する。 13 | # 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が 14 | # 付く。ただし指定文字列中に、%に続く英字があった場合、それを 15 | # 日付フォーマット指定を見なす。つまり「日付」の部分は 16 | # 自動的に付加されなくなる(コメント番号は付加される)。 17 | # 無指定時には空文字。 18 | # @options['comment_mail.receivers'] 19 | # メールを送るアドレス文字列。カンマで区切って複数指定できる。 20 | # 無指定時には日記筆者のアドレスになる。 21 | # 22 | # tdiary.confでのみ指定できるもの: 23 | # @options['comment_mail.qmail'] 24 | # qmail_injectコマンドのパスを指定する。 25 | # 無指定時には「'/var/qmail/bin/qmail-inject'」。 26 | # 27 | # Copyright (c) 2003 TADA Tadashi 28 | # You can distribute this file under the GPL2 or any later version. 29 | # 30 | def comment_mail( text, to ) 31 | begin 32 | qmail = @conf['comment_mail.qmail'] || '/var/qmail/bin/qmail-inject' 33 | open( %Q[|'#{qmail.gsub(/'/, '')}' -f '#{@conf.author_mail.gsub( /'/, '' )}' '#{to.map{|x|x.gsub(/'/,'')}.join("' '")}'], 'w' ) do |o| 34 | o.write( text ) 35 | end 36 | rescue 37 | $stderr.puts $! 38 | end 39 | end 40 | 41 | add_update_proc do 42 | comment_mail_send if @mode == 'comment' 43 | end 44 | 45 | add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do 46 | comment_mail_basic_setting 47 | comment_mail_basic_html 48 | end 49 | 50 | 51 | # Local Variables: 52 | # mode: ruby 53 | # indent-tabs-mode: t 54 | # tab-width: 3 55 | # ruby-indent-level: 3 56 | # End: 57 | -------------------------------------------------------------------------------- /misc/plugin/comment_mail-sendmail.rb: -------------------------------------------------------------------------------- 1 | # comment_mail_sendmail.rb 2 | # 3 | # sendmailを使ってツッコミをメールで知らせる 4 | # 入れるだけで動作する。 5 | # 6 | # Options: 7 | # 設定画面から指定できるもの(ツッコミメール系プラグイン共通): 8 | # @options['comment_mail.enable'] 9 | # メールを送るかどうかを指定する。true(送る)かfalse(送らない)。 10 | # 無指定時はfalse。 11 | # @options['comment_mail.header'] 12 | # メールのSubjectに使う文字列。振り分け等に便利なように指定する。 13 | # 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が 14 | # 付く。ただし指定文字列中に、%に続く英字があった場合、それを 15 | # 日付フォーマット指定を見なす。つまり「日付」の部分は 16 | # 自動的に付加されなくなる(コメント番号は付加される)。 17 | # 無指定時には空文字。 18 | # @options['comment_mail.receivers'] 19 | # メールを送るアドレス文字列。カンマで区切って複数指定できる。 20 | # 無指定時には日記筆者のアドレスになる。 21 | # 22 | # tdiary.confでのみ指定できるもの: 23 | # @options['comment_mail.sendmail'] 24 | # sendmailコマンドのパスを指定する。 25 | # 無指定時には「'/usr/sbin/sendmail'」。 26 | # 27 | # Copyright (c) 2003 TADA Tadashi 28 | # You can distribute this file under the GPL2 or any later version. 29 | # 30 | def comment_mail( text, to ) 31 | begin 32 | sendmail = @conf['comment_mail.sendmail'] || '/usr/sbin/sendmail' 33 | open( %Q[|'#{sendmail.gsub(/'/, '')}' '#{to.map{|x|x.gsub(/'/, '')}.join("' '")}'], 'w' ) do |o| 34 | o.write( text ) 35 | end 36 | rescue 37 | $stderr.puts $! 38 | end 39 | end 40 | 41 | add_update_proc do 42 | comment_mail_send if @mode == 'comment' 43 | end 44 | 45 | add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do 46 | comment_mail_basic_setting 47 | comment_mail_basic_html 48 | end 49 | 50 | # Local Variables: 51 | # mode: ruby 52 | # indent-tabs-mode: t 53 | # tab-width: 3 54 | # ruby-indent-level: 3 55 | # End: 56 | -------------------------------------------------------------------------------- /misc/plugin/comment_rank.rb: -------------------------------------------------------------------------------- 1 | # comment_rank.rb 2 | # 3 | # comment_rank: ツッコミの数でランキング 4 | # パラメタ: 5 | # max: 最大表示数(未指定時:5) 6 | # sep: セパレータ(未指定時:空白) 7 | # except: 無視する名前(いくつもある場合は,で区切って並べる) 8 | # 9 | # Copyright (c) 2002 TADA Tadashi 10 | # You can distribute this file under the GPL2 or any later version. 11 | # 12 | # 13 | def comment_rank( max = 5, sep = ' ', *except ) 14 | name = Hash::new(0) 15 | @diaries.each_value do |diary| 16 | diary.each_comment do |comment| 17 | next if except.include?(comment.name) 18 | name[comment.name] += 1 19 | end 20 | end 21 | result = [] 22 | name.sort{|a,b| (a[1])<=>(b[1])}.reverse.each_with_index do |ary,idx| 23 | break if idx >= max 24 | result << "#{idx+1}.#{h ary[0]}(#{ary[1].to_s})" 25 | end 26 | result.join( sep ) 27 | end 28 | 29 | 30 | # Local Variables: 31 | # mode: ruby 32 | # indent-tabs-mode: t 33 | # tab-width: 3 34 | # ruby-indent-level: 3 35 | # End: 36 | -------------------------------------------------------------------------------- /misc/plugin/daily_theme.rb: -------------------------------------------------------------------------------- 1 | # daily_theme.rb 2 | # 3 | # Copyright (c) 2005 SHIBATA Hiroshi 4 | # Distributed under the GPL2 or any later version. 5 | # 6 | 7 | def css_tag 8 | theme_name = File::basename( @css, '.css' ) 9 | css_url = @css 10 | 11 | if @mode =~ /conf$/ 12 | css_url = "#{h theme_url}/conf.css" 13 | theme_name = 'conf' 14 | elsif @conf.options.include?('daily_theme.list') && @conf.options['daily_theme.list'].size > 0 15 | theme_list = @conf.options['daily_theme.list'].split(/\n/) 16 | index = Time.now.yday % theme_list.size 17 | theme_name = theme_list[index].strip 18 | css_url = "#{h theme_url}/#{u theme_name}/#{u theme_name}.css" 19 | end 20 | 21 | <<-CSS 22 | 23 | 24 | CSS 25 | end 26 | 27 | add_conf_proc( 'daily_theme', @daily_theme_label, 'theme' ) do 28 | daily_theme_conf_proc 29 | end 30 | 31 | def daily_theme_conf_proc 32 | if @mode == 'saveconf' 33 | if @cgi.params['daily_theme.list'] && @cgi.params['daily_theme.list'][0] 34 | @conf['daily_theme.list'] = @cgi.params['daily_theme.list'][0] 35 | else 36 | @conf['daily_theme.list'] = nil 37 | end 38 | end 39 | 40 | # initialize Theme list 41 | @conf['daily_theme.list'] = "default" unless @conf['daily_theme.list'] 42 | 43 | <<-HTML 44 |

#{@daily_theme_label}

45 |

#{@daily_theme_label_desc}

46 |

47 | HTML 48 | end 49 | 50 | # Local Variables: 51 | # mode: ruby 52 | # indent-tabs-mode: t 53 | # tab-width: 3 54 | # ruby-indent-level: 3 55 | # End: 56 | -------------------------------------------------------------------------------- /misc/plugin/doctype-html401tr.rb: -------------------------------------------------------------------------------- 1 | # 2 | # define DOCTYPE: HTML 4.01 Tr without DTD's URL (for compatible mode) 3 | # 4 | # Copyright (c) 2005 TADA Tadashi 5 | # You can distribute this file under the GPL2 or any later version. 6 | # 7 | def doctype 8 | %Q[] 9 | end 10 | 11 | # Local Variables: 12 | # mode: ruby 13 | # indent-tabs-mode: t 14 | # tab-width: 3 15 | # ruby-indent-level: 3 16 | # End: 17 | -------------------------------------------------------------------------------- /misc/plugin/draft.rb: -------------------------------------------------------------------------------- 1 | # 2 | # draft.rb: save draft data to Web Storage automatically 3 | # 4 | # Copyright (c) MATSUOKA Kohei 5 | # Distributed under the GPL2 or any later version. 6 | # 7 | if /\A(form|edit|preview|showcomment)\z/ === @mode then 8 | enable_js('draft.js') 9 | end 10 | 11 | add_edit_proc do 12 | <<-EOS 13 |
14 | 下書き: 15 | 16 | 17 |
18 | EOS 19 | end 20 | -------------------------------------------------------------------------------- /misc/plugin/dropdown_calendar.rb: -------------------------------------------------------------------------------- 1 | # dropdown_calendar.rb 2 | # 3 | # calendar: カレンダーをドロップダウンリストに置き換えるプラグイン 4 | # パラメタ: なし 5 | # 6 | # Copyright (C) 2003 TADA Tadashi 7 | # You can redistribute it and/or modify it under GPL2 or any later version. 8 | # 9 | 10 | @dropdown_calendar_label = '過去の日記' unless @resource_loaded 11 | 12 | def calendar 13 | result = %Q[
\n] 14 | result << %Q[
\n] 15 | result << %Q[\n" 24 | result << "
\n
" 25 | end 26 | 27 | # Local Variables: 28 | # mode: ruby 29 | # indent-tabs-mode: t 30 | # tab-width: 3 31 | # ruby-indent-level: 3 32 | # End: 33 | -------------------------------------------------------------------------------- /misc/plugin/edit_today.rb: -------------------------------------------------------------------------------- 1 | # edit_today.rb : add link to edit after title of each days. 2 | # 3 | # Copyright (C) 2007 by NOB 4 | # You can redistribute it and/or modify it under GPL2 or any later version. 5 | # 6 | 7 | def edit_today_init 8 | @conf['edit_today.caption'] ||= @edit_today_caption 9 | end 10 | 11 | add_title_proc do |date,title| 12 | edit_today_link( date, title ) 13 | end 14 | 15 | def edit_today_link( date, title ) 16 | unless /^(day|preview)$/ =~ @mode 17 | edit_today_init 18 | caption = @conf['edit_today.caption'] 19 | <<-HTML 20 | #{title}\n 21 | #{caption} 22 | 23 | HTML 24 | else 25 | title 26 | end 27 | end 28 | 29 | def edit_today_saveconf 30 | if @mode == 'saveconf' then 31 | @conf['edit_today.caption'] = @cgi.params['edit_today_caption'][0] 32 | end 33 | end 34 | 35 | add_conf_proc( 'edit_today', @edit_today_caption, 'update' ) do 36 | edit_today_saveconf 37 | edit_today_init 38 | edit_today_conf_html 39 | end 40 | 41 | # Local Variables: 42 | # mode: ruby 43 | # indent-tabs-mode: t 44 | # tab-width: 3 45 | # ruby-indent-level: 3 46 | # End: 47 | -------------------------------------------------------------------------------- /misc/plugin/en/a.rb: -------------------------------------------------------------------------------- 1 | def a_conf_label; "Edit the dictionary file for the anchor plugin(a.rb)"; end 2 | def a_conf_explain; "

A row is an anchor. The format is: key URL name. name is omittable. If you omit name, the key used as name.

e.g.) tdiary http://www.tdiary.org/ tDiary Official Website

"; end 3 | 4 | 5 | # Local Variables: 6 | # mode: ruby 7 | # indent-tabs-mode: t 8 | # tab-width: 3 9 | # ruby-indent-level: 3 10 | # End: 11 | -------------------------------------------------------------------------------- /misc/plugin/en/append-css.rb: -------------------------------------------------------------------------------- 1 | def append_css_label 2 | 'Append CSS' 3 | end 4 | 5 | def append_css_desc 6 | <<-HTML 7 |

CSS elements

8 |

If you want to append some elements of style sheet, specify below.

9 | HTML 10 | end 11 | 12 | # Local Variables: 13 | # mode: ruby 14 | # indent-tabs-mode: t 15 | # tab-width: 3 16 | # ruby-indent-level: 3 17 | # End: 18 | -------------------------------------------------------------------------------- /misc/plugin/en/bq.rb: -------------------------------------------------------------------------------- 1 | # en/bq.rb 2 | # 3 | def bq_cite_from( cite ) 4 | "cite from #{cite}" 5 | end 6 | 7 | # Local Variables: 8 | # mode: ruby 9 | # indent-tabs-mode: t 10 | # tab-width: 3 11 | # ruby-indent-level: 3 12 | # End: 13 | -------------------------------------------------------------------------------- /misc/plugin/en/calendar2.rb: -------------------------------------------------------------------------------- 1 | # calendar2.rb language recource for English 2 | 3 | @calendar2_days_format = %w(Su Mo Tu We Th Fr Sa) 4 | @calendar2_navi_format = ["<-", "%d
%d", "->"] 5 | 6 | 7 | # Local Variables: 8 | # mode: ruby 9 | # indent-tabs-mode: t 10 | # tab-width: 3 11 | # ruby-indent-level: 3 12 | # End: 13 | -------------------------------------------------------------------------------- /misc/plugin/en/category.rb: -------------------------------------------------------------------------------- 1 | # 2 | # en/category.rb : tDiary plugin for show category pages 3 | # 4 | # Copyright (C) 2016 TADA Tadashi 5 | # Distributed under the GPL2 or any later version. 6 | # 7 | 8 | @category_conf_label = 'Category' 9 | 10 | def category_conf_html 11 | r = <<-HTML 12 |

Build category index

13 |

14 | To use the category feature, you should build category index. 15 | Check the box below and press OK to build category index. 16 |

17 |

20 |

21 | 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. 22 |

23 | 24 |

Edit Support

25 |

26 | Category names can be shown under the 'Article' form. 27 |

28 |

29 | 34 |

35 | 36 |

Display Order

37 |

40 | HTML 41 | r 42 | end 43 | 44 | # Local Variables: 45 | # mode: ruby 46 | # indent-tabs-mode: t 47 | # tab-width: 3 48 | # ruby-indent-level: 3 49 | # End: 50 | # vim: ts=3 51 | -------------------------------------------------------------------------------- /misc/plugin/en/daily_theme.rb: -------------------------------------------------------------------------------- 1 | # en/daily_theme.rb 2 | # 3 | # Copyright (c) 2005 SHIBATA Hiroshi 4 | # Distributed under the GPL2 or any later version. 5 | 6 | @daily_theme_label = 'Daily Theme' 7 | @daily_theme_label_desc = 'List of theme name.' 8 | 9 | # Local Variables: 10 | # mode: ruby 11 | # indent-tabs-mode: t 12 | # tab-width: 3 13 | # ruby-indent-level: 3 14 | # End: 15 | -------------------------------------------------------------------------------- /misc/plugin/en/dropdown_calendar.rb: -------------------------------------------------------------------------------- 1 | # English resource of dropdown_calendar.rb 2 | # 3 | # calendar: replace calendar with dropdown style. 4 | # Parameter: none. 5 | # 6 | 7 | @dropdown_calendar_label = 'Past Diaries' 8 | 9 | # Local Variables: 10 | # mode: ruby 11 | # indent-tabs-mode: t 12 | # tab-width: 3 13 | # ruby-indent-level: 3 14 | # End: 15 | -------------------------------------------------------------------------------- /misc/plugin/en/edit_today.rb: -------------------------------------------------------------------------------- 1 | # English resources of edit_today plugin. 2 | 3 | @edit_today_caption = 'Edit' 4 | 5 | def edit_today_edit_label( date ) 6 | date.strftime( 'Edit %Y-%m-%d' ) 7 | end 8 | 9 | def edit_today_conf_html 10 | <<-HTML 11 |

Link String

12 |

Specify string to link to edit page. If you have image file, you can specify icon on this link.

13 |

14 | HTML 15 | end 16 | 17 | # Local Variables: 18 | # mode: ruby 19 | # indent-tabs-mode: t 20 | # tab-width: 3 21 | # ruby-indent-level: 3 22 | # End: 23 | -------------------------------------------------------------------------------- /misc/plugin/en/hide-mail-field.rb: -------------------------------------------------------------------------------- 1 | # English resource of hide-mail-field plugin 2 | 3 | @hide_mail_field_label_conf = 'Hide Mail Field' 4 | 5 | def hide_mail_field_conf_html 6 | <<-HTML 7 |

Description of TSUKKOMI

8 |

Show messeges about hidden of E-mail field for your subscribers. This field is as same as in default spam filter preferences.
9 |

10 | 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."

11 | HTML 12 | end 13 | 14 | # Local Variables: 15 | # mode: ruby 16 | # indent-tabs-mode: t 17 | # tab-width: 3 18 | # ruby-indent-level: 3 19 | # End: 20 | -------------------------------------------------------------------------------- /misc/plugin/en/highlight.rb: -------------------------------------------------------------------------------- 1 | # Japanese resource of highlight.rb 2 | # 3 | 4 | def highlight_conf_label; 'Highlight'; end 5 | 6 | def highlight_conf_html 7 | <<-HTML 8 |

Color Settings of Highlight

9 |

Highlights subtitle jumped from other pages as THIS.

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Text color of highlight
Background color of highlight
21 | HTML 22 | end 23 | 24 | # Local Variables: 25 | # mode: ruby 26 | # indent-tabs-mode: t 27 | # tab-width: 3 28 | # ruby-indent-level: 3 29 | # End: 30 | -------------------------------------------------------------------------------- /misc/plugin/en/image.rb: -------------------------------------------------------------------------------- 1 | # 2 | # English resource of image plugin 3 | # 4 | 5 | # 6 | # Image Diary - Upload images and insert to diary. 7 | # 8 | # image( number, 'altword', thumbnail, size, place ) - show an image. 9 | # number - image ID as 0, 1, 2... 10 | # altword - alt strings of the img element. 11 | # thumbnail - image ID of thumbnail (optional) 12 | # size - array format of image size (optional), as [width, height] 13 | # place - class name of tag (optional), "place" is default. 14 | # 15 | # image_left( number, 'altword', thumbnail, size ) - show an image with "class=left" 16 | # image_right( number, 'altword', thumbnail, size ) - show an image with "class=right" 17 | # 18 | # image_link( number, 'desc' ) - make link to an image. 19 | # number - image ID as 0, 1, 2... 20 | # desc - description of the image. 21 | # 22 | # options in tdiary.conf: 23 | # @options['image.dir'] 24 | # Directory of uploading images. Default is './images/'. 25 | # You have to set parmission to writable by web server. 26 | # @options['image.url'] 27 | # URL of the image directory. Default is './images/'. 28 | # @options['image.maxwidth'] 29 | # Max display width of image without specified 'size' parameter. 30 | # 31 | def image_error_num( max ); "You can add images upto #{h max} par a day."; end 32 | def image_error_size( max ); "You can add images upto #{h max} bytes par an image."; end 33 | def image_label_list_caption; 'Image Diary (List/Delete) - Click an image to insert'; end 34 | def image_label_add_caption; 'Image Diary (Add)'; end 35 | def image_label_description; 'Description of the image'; end 36 | def image_label_add_plugin; 'Add to the article'; end 37 | def image_label_delete; 'Delete checked images'; end 38 | def image_label_only_jpeg; 'Only JPEG'; end 39 | def image_label_add_image; 'Upload the image'; end 40 | def image_label_drop_here; 'Drop files here'; end 41 | 42 | # Local Variables: 43 | # mode: ruby 44 | # indent-tabs-mode: t 45 | # tab-width: 3 46 | # ruby-indent-level: 3 47 | # End: 48 | -------------------------------------------------------------------------------- /misc/plugin/en/kw.rb: -------------------------------------------------------------------------------- 1 | def kw_label 2 | "Keyword" 3 | end 4 | 5 | def kw_desc 6 | <<-HTML 7 |

kw(KeyWord) plugin generate a Link by simple words. You can specify keywords 8 | as space sepalated value: "keyword URL". For example,

9 |
google http://www.google.com/search?q=$1
10 |

then you specify in your diary as:

11 |
<%=kw 'google:tdiary' %>
12 |

so it will be translated to link of seraching 'tdiary' at Google.

13 | HTML 14 | end 15 | 16 | 17 | # Local Variables: 18 | # mode: ruby 19 | # indent-tabs-mode: t 20 | # tab-width: 3 21 | # ruby-indent-level: 3 22 | # End: 23 | -------------------------------------------------------------------------------- /misc/plugin/en/pb-show.rb: -------------------------------------------------------------------------------- 1 | # English resource of pb-show.rb 2 | # 3 | def pingback_today; "Today's Pingbacks"; end 4 | def pingback_total( total ); "(Total: #{total})"; end 5 | def pb_show_conf_html 6 | <<-"HTML" 7 |

Pingback anchor

8 |

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.

9 |

10 |

Number of Pingbacks

11 |

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

12 |

Pingbacks

13 | HTML 14 | end 15 | 16 | # Local Variables: 17 | # mode: ruby 18 | # indent-tabs-mode: t 19 | # tab-width: 3 20 | # ruby-indent-level: 3 21 | # End: 22 | -------------------------------------------------------------------------------- /misc/plugin/en/ping.rb: -------------------------------------------------------------------------------- 1 | # ping.rb English resources 2 | if /conf/ =~ @mode then 3 | @ping_label_conf = 'Update ping' 4 | @ping_label_list = 'List of ping servers' 5 | @ping_label_list_desc = 'Specify URLs of ping request.' 6 | @ping_label_timeout = 'Timeout(sec)' 7 | end 8 | 9 | @ping_label_send = 'Sending ping' 10 | 11 | # Local Variables: 12 | # mode: ruby 13 | # indent-tabs-mode: t 14 | # tab-width: 3 15 | # ruby-indent-level: 3 16 | # End: 17 | -------------------------------------------------------------------------------- /misc/plugin/en/preview.rb: -------------------------------------------------------------------------------- 1 | @preview_label_conf = 'preview' 2 | @preview_label_interval = 'refresh interval' 3 | @preview_label_interval_desc = 'Specify the interval at which to display the preview in seconds.' 4 | @preview_label_min_width = 'side by side screen width' 5 | @preview_label_min_width_desc = 'Specifies the width to display the preview screen side-by-side in pixels.' 6 | -------------------------------------------------------------------------------- /misc/plugin/en/recent_comment.rb: -------------------------------------------------------------------------------- 1 | # en/recent_comment.rb 2 | # 3 | # English resources for recent_comment.rb 4 | # 5 | # Copyright (c) 2005 Hiroshi SHIBATA 6 | # Distributed under the GPL2 or any later version. 7 | # 8 | 9 | if @mode == 'conf' || @mode == 'saveconf' 10 | add_conf_proc( 'recent_comment', 'Recent TSUKKOMI', 'tsukkomi' ) do 11 | saveconf_recent_comment 12 | recent_comment_init 13 | <<-HTML 14 |

The number of display comment

15 |

Max item

16 |

Date format

17 |

Refer to Ruby's Manualfor the \'%\' character that can be used.

18 |

19 |

Non display name in recent comment list

20 |

Specified The name not displayed in the list.

21 |

22 |

HTML Template for generate

23 |

Specify how each comment is rendered.

24 | 25 |

$digit in the template is replaced as follows.

26 |
27 |
$2
comment's URL
28 |
$3
comment's shortening display
29 |
$4
name of comment's author
30 |
$5
when the comment is received
31 |
32 |

Message for no comment

33 |

Specify the message to be shown when there is no comment entry.

34 |

35 | HTML 36 | end 37 | end 38 | 39 | # Local Variables: 40 | # mode: ruby 41 | # indent-tabs-mode: t 42 | # tab-width: 3 43 | # ruby-indent-level: 3 44 | # End: 45 | -------------------------------------------------------------------------------- /misc/plugin/en/recent_rss.rb: -------------------------------------------------------------------------------- 1 | # -*- indent-tabs-mode: t -*- 2 | # 3 | # Copyright (c) 2003-2005 Kouhei Sutou 4 | # Distributed under the GPL2 or any later version. 5 | # 6 | 7 | def label_recent_rss_title 8 | 'External RSS display' 9 | end 10 | 11 | def label_recent_rss_use_image_link_title 12 | 'Image treatment' 13 | end 14 | 15 | def label_recent_rss_use_image_link_description 16 | "Select whether you use image as link instead of text or not " + 17 | "if the RSS has Web site's image information." 18 | end 19 | 20 | def label_recent_rss_not_use_image_link 21 | "don't use image as link" 22 | end 23 | 24 | def label_recent_rss_use_image_link 25 | "use image as link" 26 | end 27 | 28 | # Local Variables: 29 | # mode: ruby 30 | # indent-tabs-mode: t 31 | # tab-width: 3 32 | # ruby-indent-level: 3 33 | # End: 34 | -------------------------------------------------------------------------------- /misc/plugin/en/referer_scheme.rb: -------------------------------------------------------------------------------- 1 | =begin 2 | = Meta-scheme plugin((-$Id: referer_scheme.rb,v 1.5 2004-02-26 08:09:24 tadatadashi Exp $-)) 3 | Makes it easier to edit the referer table. 4 | 5 | == Usage 6 | Enable this plug-in by coping into the plugin directory or selecting 7 | from the plug-in selection plug-in. 8 | 9 | Then, edit the `Rule of conversion URL to words' in `Today's Link' of 10 | `Preference'. Add prefixes (meta-scheme) like `tdiary:'. 11 | 12 | This adds the date of the diaries or blogs according to their URLs. 13 | 14 | For example, set the `Rule' as 15 | * tdiary:http://tdiary.tdiary.net/ tDiary.net management journal. 16 | For this example, date is added with a (YYYY-MM-DD) format if the 17 | information is contained in the URL. 18 | 19 | == Notes 20 | For URLs with tdiary:, 21 | * Do not use parenthesis `(' and `)' 22 | * End the URL with a '/' 23 | 24 | == How to make a meta-scheme 25 | Meta-schems are extracted from the user's Rule with a Regexp: /^(\w+):/. 26 | Define singleton methods of @conf.referer_table as iterators: 27 | def scheme_( url, name ) 28 | : 29 | yield( url_variants, name_variants ) 30 | : 31 | end 32 | The singleton methods are called according to the user's Rule with the 33 | `:' part omitted in the url. 34 | 35 | == Copyright 36 | Copyright (C) 2003 zunda 37 | 38 | Permission is granted for use, copying, modification, distribution, and 39 | distribution of modified versions of this work under the terms of GPL version 2 or later. 40 | =end 41 | 42 | # Local Variables: 43 | # mode: ruby 44 | # indent-tabs-mode: t 45 | # tab-width: 3 46 | # ruby-indent-level: 3 47 | # End: 48 | -------------------------------------------------------------------------------- /misc/plugin/en/search_form.rb: -------------------------------------------------------------------------------- 1 | # search_form.rb English resource. 2 | 3 | def google_form( button_name = "Google Search", size = 20, default_text = "" ) 4 | first = %Q[ 5 | Google] 7 | search_form( "https://www.google.com/search", "q", button_name, size, default_text, first, '' ) 8 | end 9 | 10 | def yahoo_form( button_name = "Yahoo! Search", size = 20, default_text = "" ) 11 | first = %Q[ 12 | [Yahoo!]] 14 | search_form( "https://search.yahoo.com/search", "p", button_name, size, default_text, first, "" ) 15 | end 16 | 17 | # Local Variables: 18 | # mode: ruby 19 | # indent-tabs-mode: t 20 | # tab-width: 3 21 | # ruby-indent-level: 3 22 | # End: 23 | -------------------------------------------------------------------------------- /misc/plugin/en/speed_comment.rb: -------------------------------------------------------------------------------- 1 | def speed_comment_label 2 | 'Speed TSUKKOMI' 3 | end 4 | 5 | def speed_comment_html 6 | <<-HTML 7 |

Size of the form of Speed TSUKKOMI

8 |

Name:

9 |

Body:

10 | HTML 11 | end 12 | 13 | 14 | # Local Variables: 15 | # mode: ruby 16 | # indent-tabs-mode: t 17 | # tab-width: 3 18 | # ruby-indent-level: 3 19 | # End: 20 | -------------------------------------------------------------------------------- /misc/plugin/en/tb-show.rb: -------------------------------------------------------------------------------- 1 | # English resource of tb-show.rb 2 | # 3 | 4 | def tb_show_conf_html 5 | <<-"HTML" 6 |

TrackBack anchor

7 |

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.

8 |

9 |

TrackBack display style

10 |

In Latest or Month mode, you can specify style of trackbacks displayed.

11 |

19 |

Number of TrackBacks

20 |

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

21 |

TrackBacks

22 |

Show TrackBack URL

23 |

In Latest or Month mode, you can specify TrackBack URL will be shown or not in each days.

24 |

28 | HTML 29 | end 30 | 31 | 32 | # Local Variables: 33 | # mode: ruby 34 | # indent-tabs-mode: t 35 | # tab-width: 3 36 | # ruby-indent-level: 3 37 | # End: 38 | -------------------------------------------------------------------------------- /misc/plugin/en/todo.rb: -------------------------------------------------------------------------------- 1 | # en/todo.rb 2 | # 3 | # English resources for todo.rb 4 | # 5 | # Copyright (c) 2001,2002,2003 Junichiro KITA 6 | # Distributed under the GPL2 or any later version. 7 | # 8 | 9 | def todo_msg_today; "today"; end 10 | def todo_msg_in_time(days); "#{days} day(s) left to go"; end 11 | def todo_msg_late(days); "#{days} day(s) delay"; end 12 | def todo_config_label; "Edit ToDo"; end 13 | 14 | add_conf_proc('ToDo', 'ToDo plugin') do 15 | saveconf_todo 16 | todo_init 17 | 18 | <<-HTML 19 |

How to use

20 |

put '<%=todo%>' in the Header/Footer.

21 |

Edit ToDo

22 |

Each line has one ToDo entry, which is in the form of:

23 |
priority[deadline] what to do
24 |

'priority' and 'what to do' is separated by a apace character.

25 |

Priority is optional. If you specify priority, put an integer between 1 and 99, otherwise the entry is ignored.

26 |

Deadline is optional. If you specify deadline, put '[' and ']' around deadline. Deadline is parsed by ParseDate module

27 |

28 | 29 |

Title for ToDo

30 |

31 | 32 |

Max number of ToDo entries to be displayed

33 |

entries

34 | HTML 35 | end 36 | 37 | # Local Variables: 38 | # mode: ruby 39 | # indent-tabs-mode: t 40 | # tab-width: 3 41 | # ruby-indent-level: 3 42 | # End: 43 | # vim: ts=3 44 | -------------------------------------------------------------------------------- /misc/plugin/en/xmlrpc.rb: -------------------------------------------------------------------------------- 1 | def label_xmlrpc_url; 'XML-RPC API URL'; end 2 | def label_xmlrpc_blogid; 'Blog ID'; end 3 | def label_xmlrpc_username; 'Username'; end 4 | def label_xmlrpc_password; 'Password'; end 5 | def label_xmlrpc_lastname; 'last name'; end 6 | def label_xmlrpc_firstname; 'first name'; end 7 | def label_xmlrpc_userid; 'User ID'; end 8 | 9 | # Local Variables: 10 | # mode: ruby 11 | # indent-tabs-mode: t 12 | # tab-width: 3 13 | # ruby-indent-level: 3 14 | # End: 15 | -------------------------------------------------------------------------------- /misc/plugin/footnote.rb: -------------------------------------------------------------------------------- 1 | # footnote.rb 2 | # 3 | # fn: 脚注plugin 4 | # パラメタ: 5 | # text: 脚注本文 6 | # mark: 脚注マーク('*') 7 | # 8 | # Copyright (C) 2007 TADA Tadashi 9 | # Distributed under the GPL2 or any later version. 10 | 11 | # initialize variables 12 | @fn_fragment_fm = '' 13 | @fn_fragment_f = '' 14 | @fn_notes = [] 15 | @fn_marks = [] 16 | 17 | add_body_enter_proc do |date| 18 | fn_initialize( date ) 19 | '' 20 | end 21 | 22 | add_section_enter_proc do |date, index| 23 | fn_initialize( date, index ) unless @conf.style =~ /blog/i 24 | '' 25 | end 26 | 27 | def fn_initialize( date, section = 1 ) 28 | @fn_fragment_fm = sprintf( 'fm%s-%02d-%%02d', date.strftime( '%Y%m%d' ), section ) 29 | @fn_fragment_f = @fn_fragment_fm.sub( /^fm/, 'f' ) 30 | @fn_notes = [] 31 | @fn_marks = [] 32 | end 33 | 34 | def fn( text, mark = '*' ) 35 | @fn_notes += [text] 36 | @fn_marks += [mark] 37 | idx = @fn_notes.size 38 | 39 | r = %Q|| 40 | if feed? then 41 | r << %Q|#{mark}#{idx}| 42 | else 43 | r << %Q|| 47 | r << %Q|#{h mark}#{idx}| 48 | r << %Q|| 49 | end 50 | r << %Q|| 51 | end 52 | 53 | # print footnotes 54 | add_section_leave_proc do |date, index| 55 | @conf.style =~ /blog/i ? '' : fn_put 56 | end 57 | 58 | add_body_leave_proc do |date| 59 | fn_put 60 | end 61 | 62 | def fn_put 63 | if @fn_notes.size > 0 then 64 | r = %Q|
\n| 65 | @fn_notes.each_with_index do |fn, idx| 66 | r << %Q|\t

| 67 | if feed? then 68 | r << %Q|#{h @fn_marks[idx]}#{idx+1}| 69 | else 70 | r << %Q|| 73 | r << %Q|#{h @fn_marks[idx]}#{idx+1}| 74 | r << %Q|| 75 | end 76 | r << %Q| #{@fn_notes[idx]}

\n| 77 | end 78 | @fn_notes.clear 79 | r << %Q|
\n| 80 | else 81 | '' 82 | end 83 | end 84 | 85 | # Local Variables: 86 | # mode: ruby 87 | # indent-tabs-mode: t 88 | # tab-width: 3 89 | # ruby-indent-level: 3 90 | # End: 91 | # vim: ts=3 92 | -------------------------------------------------------------------------------- /misc/plugin/gradation.rb: -------------------------------------------------------------------------------- 1 | # gradation.rb 2 | # 3 | # gradation.rb: 文字列をグラデーション表示 4 | # パラメタ: 5 | # str: 文字列 6 | # first_color: グラデーション開始色(16進 6桁指定) 7 | # last_color: グラデーション終了色(16進 6桁指定) 8 | # 9 | # Copyright (c) 2002 TADA Tadashi 10 | # You can distribute this file under the GPL2 or any later version. 11 | # 12 | def gradation( str, first_color, last_color ) 13 | ary = str.split( //u ) 14 | len = ary.length - 1 15 | result = "" 16 | r = first_color[0..1].hex.to_f 17 | g = first_color[2..3].hex.to_f 18 | b = first_color[4..5].hex.to_f 19 | rd = ((last_color[0..1].hex - r)/len) 20 | gd = ((last_color[2..3].hex - g)/len) 21 | bd = ((last_color[4..5].hex - b)/len) 22 | ary.each do |x| 23 | c = sprintf( '%02x%02x%02x', r, g, b ) 24 | result << %Q[#{h x}] 25 | r += rd 26 | g += gd 27 | b += bd 28 | end 29 | result 30 | end 31 | 32 | 33 | # Local Variables: 34 | # mode: ruby 35 | # indent-tabs-mode: t 36 | # tab-width: 3 37 | # ruby-indent-level: 3 38 | # End: 39 | -------------------------------------------------------------------------------- /misc/plugin/gradient.rb: -------------------------------------------------------------------------------- 1 | # gradient.rb 2 | # 3 | # gradient.rb: 文字の大きさを変化させながら表示 4 | # パラメタ: 5 | # str: 文字列 6 | # first_size: 開始文字サイズ(数値、単位pt) 7 | # last_size: 開始文字サイズ(数値、単位pt) 8 | # 9 | # 例: 「こんなこともできます」を10ptから30ptに拡大 10 | # <%=gradient 'こんなこともできます', 10, 30 %> 11 | # 12 | # Copyright (c) 2002 TADA Tadashi 13 | # You can distribute this file under the GPL2 or any later version. 14 | # 15 | def gradient( str, first_size, last_size ) 16 | ary = str.split( //u ) 17 | len = ary.length - 1 18 | result = "" 19 | fontsize = first_size.to_f 20 | sd = ( last_size - first_size ).to_f / len 21 | ary.each do |x| 22 | s = sprintf( '%d',fontsize.round ) 23 | result << %Q[#{h x}] 24 | fontsize += sd 25 | end 26 | result 27 | end 28 | 29 | 30 | # Local Variables: 31 | # mode: ruby 32 | # indent-tabs-mode: t 33 | # tab-width: 3 34 | # ruby-indent-level: 3 35 | # End: 36 | -------------------------------------------------------------------------------- /misc/plugin/hide-mail-field.rb: -------------------------------------------------------------------------------- 1 | # 2 | # hide-mail-field.rb: Hide E-mail field in TSUKKOMI form against spams. 3 | # 4 | # To enable this plugin effective, you have to add '@' or '.*' into E-mail 5 | # address field in spamfilter plugin. 6 | # 7 | # Copyright (C) 2007 by TADA Tadahi 8 | # Distributed under GPL2 or any later version. 9 | # 10 | add_header_proc do 11 | if @mode == 'day' 12 | <<-STYLE 13 | 16 | STYLE 17 | else 18 | '' 19 | end 20 | end 21 | 22 | add_footer_proc do 23 | if @mode == 'day' 24 | <<-SCRIPT 25 | 28 | SCRIPT 29 | else 30 | '' 31 | end 32 | end 33 | 34 | add_conf_proc( 'hide-mail-field', @hide_mail_field_label_conf, 'security' ) do 35 | if @mode == 'saveconf' 36 | @conf['comment_description'] = @cgi.params['comment_description'][0] 37 | end 38 | hide_mail_field_conf_html 39 | end 40 | 41 | # Local Variables: 42 | # mode: ruby 43 | # indent-tabs-mode: t 44 | # tab-width: 3 45 | # ruby-indent-level: 3 46 | # End: 47 | -------------------------------------------------------------------------------- /misc/plugin/highlight.rb: -------------------------------------------------------------------------------- 1 | # 2 | # highlight.rb: Highlighting the element jumped from other pages. 3 | # 4 | # Copyright (C) 2003 by Ryuji SAKAI 5 | # Copyright (C) 2003 by Kazuhiro NISHIYAMA 6 | # Copyright (C) 2011 by MATSUOKA Kohei 7 | # You can redistribute it and/or modify it under GPL2 or any later version. 8 | # 9 | 10 | if @mode == 'day' and not bot? then 11 | enable_js('highlight.js') 12 | title = (@conf.html_title.gsub(/\\/, '\\\\\\') || '').gsub(/"/, '\\"') 13 | add_js_setting('$tDiary.title', %Q|"#{title}(#{@date.strftime('%Y-%m-%d')})"|) 14 | end 15 | 16 | # Local Variables: 17 | # mode: ruby 18 | # indent-tabs-mode: t 19 | # tab-width: 3 20 | # ruby-indent-level: 3 21 | # End: 22 | # vi: ts=3 sw=3 23 | -------------------------------------------------------------------------------- /misc/plugin/html_anchor.rb: -------------------------------------------------------------------------------- 1 | # html_anchor 2 | # 3 | # anchor: アンカーを「YYYYMMDD.html」「YYYYMM.html」形式に置き換える 4 | # tDiaryから自動的に呼び出されるので、プラグインファイルを 5 | # 設置するだけでよい。このプラグインを有効に使うためには、 6 | # Webサーバ側の設定変更も必要。Webサーバの設定に関しては、 7 | # 以下のサイトが参考になる。 8 | # 9 | # 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 10 | # 11 | # Copyright (c) 2002 TADA Tadashi 12 | # Distributed under the GPL2 or any later version. 13 | # 14 | 15 | def anchor( s ) 16 | if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then 17 | if $2 then 18 | "#$1.html##$2" 19 | else 20 | "#$1.html" 21 | end 22 | else 23 | "" 24 | end 25 | end 26 | 27 | 28 | # Local Variables: 29 | # mode: ruby 30 | # indent-tabs-mode: t 31 | # tab-width: 3 32 | # ruby-indent-level: 3 33 | # End: 34 | -------------------------------------------------------------------------------- /misc/plugin/ja/bq.rb: -------------------------------------------------------------------------------- 1 | # ja/bq.rb 2 | # 3 | def bq_cite_from( cite ) 4 | "#{cite}より引用" 5 | end 6 | 7 | # Local Variables: 8 | # mode: ruby 9 | # indent-tabs-mode: t 10 | # tab-width: 3 11 | # ruby-indent-level: 3 12 | # End: 13 | -------------------------------------------------------------------------------- /misc/plugin/ja/calendar2.rb: -------------------------------------------------------------------------------- 1 | # calendar2.rb language recource for Japanese 2 | 3 | @calendar2_days_format = ["日", "月", "火", "水", "木", "金", "土"] 4 | @calendar2_navi_format = ["前", "%d年
%d月", "次"] 5 | 6 | # Local Variables: 7 | # mode: ruby 8 | # indent-tabs-mode: t 9 | # tab-width: 3 10 | # ruby-indent-level: 3 11 | # End: 12 | -------------------------------------------------------------------------------- /misc/plugin/ja/category.rb: -------------------------------------------------------------------------------- 1 | # 2 | # ja/category.rb : tDiary plugin for show category pages 3 | # 4 | # Copyright (C) 2016 TADA Tadashi 5 | # Distributed under the GPL2 or any later version. 6 | # 7 | 8 | @category_conf_label = 'カテゴリ' 9 | 10 | def category_conf_html 11 | r = <<-HTML 12 |

カテゴリインデックスの作成

13 |

14 | カテゴリの機能を利用するにはカテゴリインデックスをあらかじめ作成しておく必要があります。 15 | カテゴリインデックスを作成するには 16 | 以下のチェックを入れてからOKボタンを押してください。 17 |

18 |

21 |

22 | 数秒から数十秒でインデックスの作成は終了しますが、日記の量が多い場合やサーバの性能が低い場合はタイムアウトしてしまう場合があります。この場合はオフラインで作成して下さい。 23 |

24 | 25 |

日記編集サポート

26 |

27 | 日記編集画面の「本文」の下にカテゴリ名を一覧表示することができます。 28 | カテゴリ名をクリックすると「本文」にそのカテゴリ名が挿入されます(要JavaScript)。 29 |

30 |

31 | 36 |

37 | 38 |

表示順

39 |

42 | HTML 43 | r 44 | end 45 | 46 | # Local Variables: 47 | # mode: ruby 48 | # indent-tabs-mode: t 49 | # tab-width: 3 50 | # ruby-indent-level: 3 51 | # End: 52 | # vim: ts=3 53 | -------------------------------------------------------------------------------- /misc/plugin/ja/daily_theme.rb: -------------------------------------------------------------------------------- 1 | # ja/daily_theme.rb 2 | # 3 | # Copyright (c) 2005 SHIBATA Hiroshi 4 | # Distributed under the GPL2 or any later version. 5 | 6 | @daily_theme_label = '日替わりテーマ' 7 | @daily_theme_label_desc = '日替わりテーマで使用するテーマ名を、1行につき1つ入力してください。' 8 | 9 | # Local Variables: 10 | # mode: ruby 11 | # indent-tabs-mode: t 12 | # tab-width: 3 13 | # ruby-indent-level: 3 14 | # End: 15 | -------------------------------------------------------------------------------- /misc/plugin/ja/edit_today.rb: -------------------------------------------------------------------------------- 1 | # Japanese resources of edit_today plugin. 2 | 3 | @edit_today_caption = 'この日を編集' 4 | 5 | def edit_today_edit_label( date ) 6 | date.strftime( '%Y-%m-%dを編集' ) 7 | end 8 | 9 | def edit_today_conf_html 10 | <<-HTML 11 |

リンク文字列

12 |

編集ページへのリンクを示す文字列を指定します。画像が用意できれば、アイコンなども指定出来ます。

13 |

14 | HTML 15 | end 16 | 17 | # Local Variables: 18 | # mode: ruby 19 | # indent-tabs-mode: t 20 | # tab-width: 3 21 | # ruby-indent-level: 3 22 | # End: 23 | -------------------------------------------------------------------------------- /misc/plugin/ja/hide-mail-field.rb: -------------------------------------------------------------------------------- 1 | # Japanese resource of hide-mail-field plugin 2 | 3 | @hide_mail_field_label_conf = 'メール欄隠し' 4 | 5 | def hide_mail_field_conf_html 6 | <<-HTML 7 |

ツッコミの注意文

8 |

ツッコミフォームの上に表示する注意文を設定します。メール欄が消えていることを読者にきちんと知らせましょう。この欄は標準spamフィルタの設定ページにあるものと同じものです。
9 |
10 | 例: ツッコミ・コメントがあればどうぞ! spam対策でE-mail欄は隠してあります。もしE-mail欄が見えていても、何も入力しないで下さい。

11 | HTML 12 | end 13 | 14 | # Local Variables: 15 | # mode: ruby 16 | # indent-tabs-mode: t 17 | # tab-width: 3 18 | # ruby-indent-level: 3 19 | # End: 20 | -------------------------------------------------------------------------------- /misc/plugin/ja/highlight.rb: -------------------------------------------------------------------------------- 1 | # Japanese resource of highlight.rb 2 | # 3 | 4 | def highlight_conf_label; 'ハイライト'; end 5 | 6 | def highlight_conf_html 7 | <<-HTML 8 |

ハイライトの色設定

9 |

ジャンプした先のサブタイトルをサンプルのようにハイライトします。

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
ハイライトの文字色
ハイライトの背景色
21 | HTML 22 | end 23 | 24 | # Local Variables: 25 | # mode: ruby 26 | # indent-tabs-mode: t 27 | # tab-width: 3 28 | # ruby-indent-level: 3 29 | # End: 30 | -------------------------------------------------------------------------------- /misc/plugin/ja/makerss.rb: -------------------------------------------------------------------------------- 1 | # makerss.rb Japanese resources 2 | def makerss_tsukkomi_label( id ) 3 | "#{id[0,4]}-#{id[4,2]}-#{id[6,2]}のツッコミ[#{id[/[1-9]\d*$/]}]" 4 | end 5 | 6 | @makerss_conf_label = 'フィード(RSS)の生成' 7 | 8 | def makerss_conf_html 9 | <<-HTML 10 |

フィード(RSS)の生成

11 |

フィードは他のプログラムに読みやすい形で、日記の内容を公開します。フィードに含まれる情報はフィードリーダーで読まれたり、更新通知サイトに転載されたりして利用されています。

12 | #{%Q[

「#{@makerss_full.file}」に書き込めません。
このファイルはWebサーバによって書き込み可能でなければなりません。

] unless @makerss_full.writable?} 13 |
    14 |
  • フィードに本文全体を
  • 17 |
  • フィードに含める説明を
  • 20 |
  • 「#{ comment_new }」というリンクを挿入
  • 23 |
24 | 25 |

ツッコミ抜きのフィード

26 |

標準のフィードには、あなたが書いた日記本文だけでなく、読者によるツッコミも含まれます。もしツッコミを含まないフィードも配信したいのであれば、こちらも設定してください。なお、標準のフィードが全文を含む場合にはツッコミも全文配信され、そうでない場合にはツッコミの日付と投稿者のみが配信されます。

27 | #{%Q[

「#{@makerss_no_comments.file}」に書き込めません。
このファイルはWebサーバによって書き込み可能でなければなりません。

] if @conf['makerss.no_comments'] and !@makerss_no_comments.writable?} 28 |
    29 |
  • ツッコミ抜きのフィードを
  • 32 |
33 | HTML 34 | end 35 | 36 | @makerss_edit_label = 'ちょっとした修正(フィードを更新しない)' 37 | 38 | # Local Variables: 39 | # mode: ruby 40 | # indent-tabs-mode: t 41 | # tab-width: 3 42 | # ruby-indent-level: 3 43 | # End: 44 | -------------------------------------------------------------------------------- /misc/plugin/ja/my-sequel.rb: -------------------------------------------------------------------------------- 1 | # 2 | # ja/my-sequel.rb 3 | # 4 | # show links to follow-up entries 5 | # 6 | # Copyright 2006 zunda and 7 | # NISHIMURA Takashi 8 | # 9 | # Permission is granted for use, copying, modification, distribution, 10 | # and distribution of modified versions of this work under the terms 11 | # of GPL2 or any later version. 12 | # 13 | 14 | @my_sequel_plugin_name ||= '後日談へのリンク' 15 | @my_sequel_description ||= <<_END 16 |

myプラグインで過去の日記に言及すると、その日記からのリンクを表示します。

17 |

設定が登録されるのは「OK」ボタンを押してからです。デフォルトの設定に戻す時でも、「OK」ボタンを押してください。

18 | _END 19 | @my_sequel_restore_default_label ||= 'デフォルトに戻す' 20 | @my_sequel_default_hash ||= { 21 | :label => { 22 | :title => 'ラベル', 23 | :default => 'つづき: ', 24 | :description => '後日談へのリンクの前に表示される文字列です。', 25 | :index => 1, 26 | }, 27 | :date_format => { 28 | :title => 'リンク文字列', 29 | :default => @date_format, 30 | :description => '後日談へのリンクの文字列の書式です。%で始まる英字は次のように変換されます: 「%Y」(西暦年)、「%m」(月数値)、「%b」(短月名)、「%B」(長月名)、「%d」(日)、「%a」(短曜日名)、「%A」(長曜日名)。', 31 | :index => 2, 32 | }, 33 | :inner_css => { 34 | :title => 'スタイル', 35 | :default => <<'_END', 36 | font-size: 75%; 37 | text-align: right; 38 | margin: 0px; 39 | _END 40 | :description => '後日談へのリンクに設定されるCSSです。div.sequelに適用されます。', 41 | :index => 3, 42 | :textarea => {rows: 5}, 43 | }, 44 | } 45 | 46 | # Local Variables: 47 | # mode: ruby 48 | # indent-tabs-mode: t 49 | # tab-width: 3 50 | # ruby-indent-level: 3 51 | # End: 52 | -------------------------------------------------------------------------------- /misc/plugin/ja/pb-show.rb: -------------------------------------------------------------------------------- 1 | # Japanese resource of pb-show.rb 2 | # 3 | 4 | def pingback_today; '本日のPingbacks'; end 5 | def pingback_total( total ); "(全#{total}件)"; end 6 | def pb_show_conf_html 7 | <<-"HTML" 8 |

Pingback アンカー

9 |

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

10 |

11 |

Pingback リスト表示数

12 |

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

13 |

最大

14 | HTML 15 | end 16 | 17 | # Local Variables: 18 | # mode: ruby 19 | # indent-tabs-mode: t 20 | # tab-width: 3 21 | # ruby-indent-level: 3 22 | # End: 23 | -------------------------------------------------------------------------------- /misc/plugin/ja/ping.rb: -------------------------------------------------------------------------------- 1 | # ping.rb Japanese resources 2 | if /conf/ =~ @mode then 3 | @ping_label_conf = '更新通知' 4 | @ping_label_list = '通知先リスト' 5 | @ping_label_list_desc = '更新通知をするpingサービスのURLを、1行につき1つ入力してください。なお、あまりたくさん指定すると、途中でタイムアウトしてしまうかも知れません' 6 | @ping_label_timeout = 'タイムアウト(秒)' 7 | end 8 | 9 | @ping_label_send = '更新情報を送る' 10 | 11 | # Local Variables: 12 | # mode: ruby 13 | # indent-tabs-mode: t 14 | # tab-width: 3 15 | # ruby-indent-level: 3 16 | # End: 17 | -------------------------------------------------------------------------------- /misc/plugin/ja/preview.rb: -------------------------------------------------------------------------------- 1 | @preview_label_conf = '日記のプレビュー' 2 | @preview_label_interval = '更新間隔 (秒)' 3 | @preview_label_interval_desc = 'プレビューを表示する間隔を秒単位で指定します。間隔を短くするとよりリアルタイムになりますが、その分サーバーに負荷がかかります。' 4 | @preview_label_min_width = '横並びで表示する画面サイズ (px)' 5 | @preview_label_min_width_desc = 'プレビュー画面を横並びで表示する幅をピクセル単位で指定します。ここで指定した幅より画面サイズが小さい場合は縦に並べて表示します。' 6 | -------------------------------------------------------------------------------- /misc/plugin/ja/recent_comment.rb: -------------------------------------------------------------------------------- 1 | # ja/recent_comment.rb 2 | # 3 | # Japanese resources for recent_comment.rb 4 | # 5 | # Copyright (c) 2005 Hiroshi SHIBATA 6 | # Distributed under the GPL2 or any later version. 7 | # 8 | 9 | if @mode == 'conf' || @mode == 'saveconf' 10 | add_conf_proc( 'recent_comment', '最近のツッコミ', 'tsukkomi' ) do 11 | saveconf_recent_comment 12 | recent_comment_init 13 | <<-HTML 14 |

表示するツッコミの数

15 |

最大

16 |

日付フォーマット

17 |

使用できる\'%\'文字についてはRubyのマニュアルを参照.

18 |

19 |

一覧に表示しない名前

20 |

リストに表示しない名前を指定します.

21 |

22 |

生成するHTMLのテンプレート

23 |

各ツッコミをどのようなHTMLで表示するかを指定します.

24 | 25 |

テンプレート中の$数字はそれぞれ以下の内容で置き換えられます.必要のないものは指定しなくても構いません.

26 |
27 |
$2
ツッコミのURL.
28 |
$3
ツッコミの短縮表示
29 |
$4
ツッコミした人の名前
30 |
$5
ツッコミの時刻.「日付フォーマット」で指定した形式で表示されます。
31 |
32 |

ツッコミがないときのメッセージ

33 |

表示するツッコミがない場合に表示する内容を指定します.

34 |

35 | HTML 36 | end 37 | end 38 | 39 | # Local Variables: 40 | # mode: ruby 41 | # indent-tabs-mode: t 42 | # tab-width: 3 43 | # ruby-indent-level: 3 44 | # End: 45 | -------------------------------------------------------------------------------- /misc/plugin/ja/recent_rss.rb: -------------------------------------------------------------------------------- 1 | # -*- indent-tabs-mode: t -*- 2 | # 3 | # Copyright (c) 2003-2005 Kouhei Sutou 4 | # Distributed under the GPL2 or any later version. 5 | # 6 | 7 | def label_recent_rss_title 8 | '外部RSSの表示' 9 | end 10 | 11 | def label_recent_rss_use_image_link_title 12 | '画像の扱い' 13 | end 14 | 15 | def label_recent_rss_use_image_link_description 16 | 'もしRSSにWebサイトの画像情報が含まれていたら,' + 17 | 'Webサイトへのリンクにテキストではなくその画像を用います.' 18 | end 19 | 20 | def label_recent_rss_not_use_image_link 21 | 'リンクに画像を用いない' 22 | end 23 | 24 | def label_recent_rss_use_image_link 25 | 'リンクに画像を用いる' 26 | end 27 | 28 | # Local Variables: 29 | # mode: ruby 30 | # indent-tabs-mode: t 31 | # tab-width: 3 32 | # ruby-indent-level: 3 33 | # End: 34 | -------------------------------------------------------------------------------- /misc/plugin/ja/search_control.rb: -------------------------------------------------------------------------------- 1 | =begin 2 | = ここだけ検索プラグイン((-$Id: search_control.rb,v 1.4 2008-03-02 09:01:46 kazuhiko Exp $-)) 3 | 日本語リソース 4 | 5 | == 概要 6 | 一日表示、最新表示などそれぞれについてGoogleなどの検索エンジンにインデッ 7 | クスしてもらうかどうかを制御します。 8 | 9 | == 使い方 10 | このプラグインをplugin/ディレクトリに配置するか、プラグイン選択プラグイ 11 | ンを使ってこのプラグインを有効にしてください。 12 | 13 | 設定画面から「ここだけ検索」をクリックすることで、どの表示モードでどのよ 14 | うな動作を期待するか設定することができます。デフォルトでは、一日分の表示 15 | のみ、検索エンジンに登録されるようになっています。 16 | 17 | 実際に効果があるかどうかは、検索エンジンのロボットがメタタグを解釈して 18 | くれるかどうかにかかっています。 19 | 20 | == License 21 | Copyright (C) 2003, 2004 zunda 22 | 23 | Permission is granted for use, copying, modification, distribution, and 24 | distribution of modified versions of this work under the terms of GPL version 2 or later. 25 | =end 26 | 27 | =begin ChangeLog 28 | See ../ChangeLog for changes after this. 29 | 30 | * Aug 28, 2003 zunda 31 | - 1.3 32 | - simpler configuration display 33 | 34 | * Aug 26, 2003 zunda 35 | - 1.2 36 | - no table in configuration view, thanks to Tada-san. 37 | 38 | * Aug 26, 2003 zunda 39 | - no nofollow 40 | - English translation 41 | =end ChangeLog 42 | 43 | # configuration 44 | unless defined?( Search_control_plugin_name ) then 45 | Search_control_plugin_name = 'ここだけ検索' 46 | Search_control_description_html = <<'_HTML' 47 |

メタタグを使って、検索エンジンのロボットに、 48 | 余分なページのインデックスを作らないようにお願いしてみます。 49 | インデックスを作って欲しい表示だけにチェックをしてください。

50 |

User agent(検索エンジンのロボットの名前)が指定されていると、 51 | そのagentについて指定された動作をします。 52 | 一致するUser agentが無い場合はデフォルトの動作をします。

53 | _HTML 54 | Search_control_delete_label = 'このagentを削除' 55 | Search_control_new_label = '記入したagentを追加' 56 | Search_control_default_label = 'デフォルト' 57 | Search_control_categories = [ 58 | [ '最新', 'latest' ], 59 | [ '一日分', 'day' ], 60 | [ '一月分', 'month' ], 61 | [ '長年', 'nyear' ], 62 | [ 'カテゴリー', 'category' ] 63 | ] 64 | end 65 | 66 | # Local Variables: 67 | # mode: ruby 68 | # indent-tabs-mode: t 69 | # tab-width: 3 70 | # ruby-indent-level: 3 71 | # End: 72 | -------------------------------------------------------------------------------- /misc/plugin/ja/search_form.rb: -------------------------------------------------------------------------------- 1 | # search_form.rb japanese resource. 2 | 3 | def googlej_form( button_name = "Google 検索", size = 20, default_text = "" ) 4 | first = %Q[ 5 | Google] 7 | last = %Q[] 8 | search_form( "https://www.google.com/search", "q", button_name, size, default_text, first, last ) 9 | end 10 | 11 | def google_form( button_name = "Google 検索", size = 20, default_text = "" ) 12 | googlej_form( button_name, size, default_text ) 13 | end 14 | 15 | def yahooj_form( button_name = "Yahoo! 検索", size = 20, default_text = "" ) 16 | first = %Q[ 17 | Yahoo! JAPAN] 19 | search_form( "https://search.yahoo.co.jp/bin/search", "p", button_name, size, default_text, first, "" ) 20 | end 21 | 22 | def yahoo_form( button_name = "Yahoo! 検索", size = 20, default_text = "" ) 23 | yahooj_form( button_name, size, default_text ) 24 | end 25 | 26 | # Local Variables: 27 | # mode: ruby 28 | # indent-tabs-mode: t 29 | # tab-width: 3 30 | # ruby-indent-level: 3 31 | # End: 32 | -------------------------------------------------------------------------------- /misc/plugin/ja/tb-show.rb: -------------------------------------------------------------------------------- 1 | # Japanese resource of tb-show.rb 2 | # 3 | 4 | def tb_show_conf_html 5 | <<-"HTML" 6 |

TrackBack アンカー

7 |

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

8 |

9 |

TrackBack 表示方法

10 |

最新もしくは月別時の表示方法を指定します。

11 |

20 |

TrackBack リスト表示数

21 |

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

22 |

最大

23 |

TrackBack URL の表示設定

24 |

最新もしくは月別表示時に TrackBackURL を表示するかどうかを指定します。

25 |

29 | HTML 30 | end 31 | 32 | # Local Variables: 33 | # mode: ruby 34 | # indent-tabs-mode: t 35 | # tab-width: 3 36 | # ruby-indent-level: 3 37 | # End: 38 | -------------------------------------------------------------------------------- /misc/plugin/ja/todo.rb: -------------------------------------------------------------------------------- 1 | # ja/todo.rb 2 | # 3 | # Japanese resources for todo.rb 4 | # 5 | # Copyright (c) 2001,2002,2003 Junichiro KITA 6 | # Distributed under the GPL2 or any later version. 7 | # 8 | 9 | def todo_msg_today; "今日"; end 10 | def todo_msg_in_time(days); "あと#{days}日"; end 11 | def todo_msg_late(days); "#{days}日遅れ"; end 12 | def todo_config_label; "ToDo編集"; end 13 | 14 | add_conf_proc('ToDo', 'ToDoプラグイン') do 15 | saveconf_todo 16 | todo_init 17 | 18 | <<-HTML 19 |

使い方

20 |

ヘッダ・フッタに'<%=todo%>'を追加して下さい.

21 |

ToDo編集

22 |

一行に一つずつToDoを記述します.ToDoの形式は

23 |
優先度[期限] すること
24 |

です.「優先度」と「すること」の間は1つ以上のスペースで区切ります.

25 |

優先度は省略可能です。優先度を指定する場合は1〜99の整数を指定します.それ以外の優先度を指定した場合,そのToDoは無視されます.

26 |

期限は省略可能です.期限を指定する場合は'['と']'で囲むようにしてください.期限で指定した文字列をrubyのParseDateモジュールで解析できれば,期限までの日数もあわせて表示します.

27 |

28 | 29 |

ToDoリストのタイトル

30 |

ToDoリストのタイトルを指定します。何も指定しないと、"ToDo:"が利用されます。

31 |

32 | 33 |

表示するToDoの件数

34 |

表示するToDoの件数を表示します。何も指定しないと、10件が設定されます。

35 |

最大

36 | HTML 37 | end 38 | 39 | # Local Variables: 40 | # mode: ruby 41 | # indent-tabs-mode: t 42 | # tab-width: 3 43 | # ruby-indent-level: 3 44 | # End: 45 | # vim: ts=3 46 | -------------------------------------------------------------------------------- /misc/plugin/ja/xmlrpc.rb: -------------------------------------------------------------------------------- 1 | def label_xmlrpc_url; 'XML-RPC API 設置先URL'; end 2 | def label_xmlrpc_blogid; 'Blog ID'; end 3 | def label_xmlrpc_username; 'ユーザ名'; end 4 | def label_xmlrpc_password; 'パスワード'; end 5 | def label_xmlrpc_lastname; '名'; end 6 | def label_xmlrpc_firstname; '姓'; end 7 | def label_xmlrpc_userid; 'ユーザID'; end 8 | 9 | # Local Variables: 10 | # mode: ruby 11 | # indent-tabs-mode: t 12 | # tab-width: 3 13 | # ruby-indent-level: 3 14 | # End: 15 | -------------------------------------------------------------------------------- /misc/plugin/list.rb: -------------------------------------------------------------------------------- 1 | # list.rb 2 | # 3 | #
    順番付きリスト生成 4 | # <%= ol l %> 5 | # パラメタ: 6 | # l: リスト文字列(\nくぎり) 7 | # 8 | #
      順番無しリスト 9 | # <%= ul l , t %> 10 | # パラメタ: 11 | # l: リスト文字列(\nくぎり) 12 | # 13 | # Copyright (c) 2002 abbey 14 | # Distributed under the GPL2 or any later version. 15 | # 16 | 17 | def ol( l, t = nil, s = nil ) 18 | apply_plugin( %Q[
        #{li l}
      ] ) 19 | end 20 | 21 | def ul( l, t = nil) 22 | apply_plugin( %Q[
        #{li l}
      ] ) 23 | end 24 | 25 | def li( text ) 26 | list = "" 27 | text.each_line do |line| 28 | list << ("
    • " + line.chomp + "
    • ") 29 | end 30 | list 31 | end 32 | 33 | 34 | # Local Variables: 35 | # mode: ruby 36 | # indent-tabs-mode: t 37 | # tab-width: 3 38 | # ruby-indent-level: 3 39 | # End: 40 | -------------------------------------------------------------------------------- /misc/plugin/my-ex.rb: -------------------------------------------------------------------------------- 1 | # my-ex.rb 2 | # 3 | # my(拡張版): myプラグインを拡張し、title属性に参照先の内容を挿入します。 4 | # 参照先がセクションの場合は(あれば)サブタイトルを、 5 | # ツッコミの場合はツッコんだ人の名前と内容の一部を使います。 6 | # パラメタ: 7 | # a: 自分の日記内のリンク先情報('YYYYMMDD#pNN' または 'YYYYMMDD#cNN') 8 | # URLをそのまま書くこともできます。 9 | # str: リンクにする文字列 10 | # 11 | # Copyright (c) 2002 TADA Tadashi 12 | # Distributed under the GPL2 or any later version. 13 | 14 | def my( a, str, title = nil ) 15 | date, frag = a.scan( /(\d{4}|\d{6}|\d{8}|\d{8}-\d+)[^\d]*(?:#?([pct]\d+))?$/ )[0] 16 | anc = frag ? "#{date}#{frag}" : date 17 | place, frag = frag.scan( /([cpt])(\d\d)/ )[0] if frag 18 | if date and frag and @diaries[date] then 19 | case place 20 | when 'p' 21 | section = nil 22 | idx = 1 23 | @diaries[date].each_section do |s| 24 | section = s 25 | break if idx == frag.to_i 26 | idx += 1 27 | end 28 | if section and section.subtitle then 29 | title = h( "#{apply_plugin(section.subtitle_to_html, true)}" ) 30 | title.sub!( /^(\[([^\]]+)\])+ */, '' ) 31 | end 32 | when 'c' 33 | com = nil 34 | @diaries[date].each_comment( frag.to_i ) {|c| com = c} 35 | if com then 36 | title = h( "[#{com.name}] #{com.shorten( @conf.comment_length )}" ) 37 | end 38 | when 't' 39 | unless @plugin_files.grep(/tb-show.rb\z/).empty? 40 | tb = nil 41 | @diaries[date].each_visible_trackback( frag.to_i ) {|t, idx| tb = t} 42 | if tb then 43 | _, name, _, excerpt = tb.body.split( /\n/,4 ) 44 | title = h( "[#{name}] #{@conf.shorten( excerpt, @conf.comment_length )}" ) 45 | end 46 | end 47 | end 48 | end 49 | index = /^https?:/ =~ @index ? '' : base_url 50 | index += @index.sub(%r|^\./|, '') 51 | if title then 52 | %Q[#{str}] 53 | else 54 | %Q[#{str}] 55 | end 56 | end 57 | 58 | # Local Variables: 59 | # mode: ruby 60 | # indent-tabs-mode: t 61 | # tab-width: 3 62 | # ruby-indent-level: 3 63 | # End: 64 | -------------------------------------------------------------------------------- /misc/plugin/navi_user.rb: -------------------------------------------------------------------------------- 1 | # navi_user.rb 2 | # 3 | # navi_user: 前日,翌日→前の日記,次の日記 4 | # modeがday/commentのときに表示される「前日」「翌日」ナビゲーション 5 | # リンクを,「前の日記」,「次の日記」に変更するplugin.前の日記,次 6 | # の日記がない場合は,ナビゲーションを表示しない.月またぎにも対応. 7 | # 8 | # Copyright (c) 2002 Junichiro KITA 9 | # Distributed under the GPL2 or any later version. 10 | 11 | # this plugin is obsoleted 12 | 13 | # Local Variables: 14 | # mode: ruby 15 | # indent-tabs-mode: t 16 | # tab-width: 3 17 | # ruby-indent-level: 3 18 | # End: 19 | -------------------------------------------------------------------------------- /misc/plugin/number_anchor.rb: -------------------------------------------------------------------------------- 1 | # number_anchor.rb 2 | # 3 | # number_anchor: アンカーにid属性を付加する 4 | # アンカー画像を異なるものにするためのもの 5 | # 使用するさいは、設定画面のヘッダに 6 | # <%= use_number_anchor( アンカーの種数 ) %> 7 | # と書いてください。 8 | # 9 | # Copyright (C) 2002 by zoe 10 | # Distributed under the GPL2 or any later version. 11 | # 12 | 13 | def use_number_anchor( n = 1 ) 14 | @use_number_anchor = true 15 | @total_anchor = n 16 | "" 17 | end 18 | 19 | alias :_orig_anchor :anchor 20 | 21 | def anchor( s ) 22 | if @use_number_anchor == true then 23 | if /^(\d+)#?([pct])?(\d*)?$/ =~ s then 24 | if $2 then 25 | n = $3.to_i 26 | if n && n > @total_anchor then 27 | n = (n % @total_anchor) 28 | end 29 | "#{_orig_anchor(s)}\" class=\"#$2#{'%02d' % n}" 30 | else 31 | _orig_anchor(s) 32 | end 33 | else 34 | "" 35 | end 36 | else 37 | _orig_anchor(s) 38 | end 39 | end 40 | 41 | # Local Variables: 42 | # mode: ruby 43 | # indent-tabs-mode: t 44 | # tab-width: 3 45 | # ruby-indent-level: 3 46 | # End: 47 | -------------------------------------------------------------------------------- /misc/plugin/pre_wrap.rb: -------------------------------------------------------------------------------- 1 | # 2 | # pre_wrap.rb: word wrapping style for preformat (
      )
       3 | #
       4 | # Copyright (C) 2010 TADA Tadashi 
       5 | # You can redistribute it and/or modify it under GPL2 or any later version.
       6 | #
       7 | add_header_proc do
       8 | 	<<-STYLE
       9 | 		
      18 | 	STYLE
      19 | end
      20 | 
      
      
      --------------------------------------------------------------------------------
      /misc/plugin/preview.rb:
      --------------------------------------------------------------------------------
       1 | # -*- coding: utf-8; -*-
       2 | #
       3 | # preview.rb: view preview automatically
       4 | #
       5 | # Copyright (c) MATSUOKA Kohei 
       6 | # Distributed under the GPL2 or any later version.
       7 | #
       8 | 
       9 | @conf['preview.interval'] ||= 10
      10 | @conf['preview.min_width'] ||= 896
      11 | 
      12 | if /\A(form|edit|preview)\z/ === @mode then
      13 | 	enable_js('preview.js')
      14 | 	add_js_setting('$tDiary.plugin.preview')
      15 | 	add_js_setting('$tDiary.plugin.preview.interval', @conf['preview.interval'].to_json)
      16 | 	add_js_setting('$tDiary.plugin.preview.minWidth', @conf['preview.min_width'].to_json)
      17 | end
      18 | 
      19 | add_conf_proc('preview', @preview_label_conf, 'update') do
      20 | 	if @mode == 'saveconf'
      21 | 		@conf['preview.interval'] = @cgi.params['preview.interval'][0].to_i
      22 | 		@conf['preview.min_width'] = @cgi.params['preview.min_width'][0].to_i
      23 | 	end
      24 | 	ERB.new(%q{
      25 | 		

      <%= @preview_label_interval %>

      26 |
      27 |

      <%= @preview_label_interval_desc %>

      28 |

      sec

      29 |
      30 |

      <%= @preview_label_min_width %>

      31 |
      32 |

      <%= @preview_label_min_width_desc %>

      33 |

      px

      34 |
      35 | }).result(binding) 36 | end 37 | -------------------------------------------------------------------------------- /misc/plugin/recent_namazu.rb: -------------------------------------------------------------------------------- 1 | # recent_namazu.rb 2 | # 3 | # recent_namazu: Namazu検索語新しい順 4 | # namazi.cgiが作成する検索キーワードログ(NMZ.slog)から 5 | # 最新xx件分の検索語を表示します。 6 | # パラメタ: 7 | # file: 検索キーワードログファイル名(絶対パス表記) 8 | # namazu: なまずcgi名 9 | # limit: 表示件数(未指定時:5) 10 | # sep: セパレータ(未指定時:空白) 11 | # make_link: を生成するか?(未指定時:生成する) 12 | # 13 | # 14 | # Copyright (c) 2002 Hiroyuki Ikezoe 15 | # Distributed under the GPL2 or any later version. 16 | 17 | def recent_namazu(file, namazu, limit = 5, sep=' ', make_link = true) 18 | begin 19 | lines = [] 20 | log = open(file) 21 | if log.stat.size > 300 * limit then 22 | log.seek(-300 * limit,IO::SEEK_END) 23 | end 24 | log.each_line do |line| 25 | lines << line 26 | end 27 | 28 | result = [] 29 | lines.reverse.each_with_index do |line,idx| 30 | break if idx >= limit 31 | word = line.split(/\t/)[0] 32 | if make_link 33 | result << %Q[#{h( word )}] 34 | else 35 | result << h( word ) 36 | end 37 | end 38 | result.join( sep ) 39 | rescue 40 | %Q[

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

      ] 41 | end 42 | end 43 | 44 | # Local Variables: 45 | # mode: ruby 46 | # indent-tabs-mode: t 47 | # tab-width: 3 48 | # ruby-indent-level: 3 49 | # End: 50 | -------------------------------------------------------------------------------- /misc/plugin/referer-antibot.rb: -------------------------------------------------------------------------------- 1 | # referer-antibot.rb 2 | # 3 | # 検索エンジンの巡回BOTには「本日のリンク元」を見せないようにする 4 | # これにより、無関係な検索語でアクセスされることが減る(と予想される) 5 | # pluginディレクトリに入れるだけで動作する 6 | # 7 | # オプション: 8 | # @options['bot'] 9 | # ターゲットにする巡回BOTのUser-Agentを追加する配列。 10 | # 無指定時は["googlebot", "Hatena Antenna", "moget@goo.ne.jp"]のみ。 11 | # 12 | # なお、disp_referrer.rbプラグインには同等の機能が含まれているので、 13 | # disp_referrerを導入済みの場合には入れる必要はない 14 | # 15 | # --------- 16 | # 17 | # This plugin hide Today's Link to search engin's robots. 18 | # It may reduce nose marked by robots. 19 | # 20 | # disp_referrer.rb plugin has already this function. You don't 21 | # need install this plugin with disp_referrer.rb. 22 | # 23 | # Options: 24 | # @options['bot'] 25 | # An array of User-Agent of search engine's robots. 26 | # Default setting is ["googlebot", "Hatena Antenna", "moget@goo.ne.jp"]. 27 | # 28 | # Copyright (C) 2002 MUTOH Masao 29 | # Modified by TADA Tadashi 30 | # You can redistribute it and/or modify it under GPL2 or any later version. 31 | # 32 | 33 | # short referer 34 | alias referer_of_today_short_antibot_backup referer_of_today_short 35 | def referer_of_today_short( diary, limit ) 36 | return '' if bot? 37 | referer_of_today_short_antibot_backup( diary, limit ) 38 | end 39 | 40 | # long referer 41 | alias referer_of_today_long_antibot_backup referer_of_today_long 42 | def referer_of_today_long( diary, limit ) 43 | return '' if bot? 44 | referer_of_today_long_antibot_backup( diary, limit ) 45 | end 46 | 47 | # Local Variables: 48 | # mode: ruby 49 | # indent-tabs-mode: t 50 | # tab-width: 3 51 | # ruby-indent-level: 3 52 | # End: 53 | -------------------------------------------------------------------------------- /misc/plugin/referer-utf8.rb: -------------------------------------------------------------------------------- 1 | # referer-utf8.rb 2 | 3 | # 4 | # this plugin is obsolete. 5 | # 6 | 7 | # Local Variables: 8 | # mode: ruby 9 | # indent-tabs-mode: t 10 | # tab-width: 3 11 | # ruby-indent-level: 3 12 | # End: 13 | -------------------------------------------------------------------------------- /misc/plugin/search_form.rb: -------------------------------------------------------------------------------- 1 | # search_form.rb 2 | # 3 | # Show a form for search engines. 4 | # 5 | # Copyright (c) 2002 MUTOH Masao 6 | # Distributed under the same license terms as tDiary. 7 | # 8 | 9 | add_header_proc do 10 | @extract_search_keyword = '' 11 | if @cgi.referer then 12 | begin 13 | setup = DispRef2Setup::new( @conf, 1, true, nil, @mode ) 14 | disp_url = DispRef2URL::new( @cgi.referer ) 15 | disp_url.parse( setup ) 16 | if disp_url.category == :search then 17 | @extract_search_keyword = disp_url.key 18 | end 19 | rescue NameError 20 | end 21 | end 22 | '' 23 | end 24 | 25 | def extract_search_keyword 26 | h @extract_search_keyword 27 | end 28 | 29 | 30 | def search_form(url, query, button_name = "Search", size = 20, default_text = "", first_form = "", last_form = "") 31 | default_text = @extract_search_keyword if default_text.empty? 32 | %Q[ 33 | 41 | ] 42 | end 43 | 44 | def namazu_form( url, button_name = "Search", size = 20, default_text = "" ) 45 | search_form( url, "query", button_name, size, default_text ) 46 | end 47 | 48 | # Local Variables: 49 | # mode: ruby 50 | # indent-tabs-mode: t 51 | # tab-width: 3 52 | # ruby-indent-level: 3 53 | # End: 54 | -------------------------------------------------------------------------------- /misc/plugin/src.rb: -------------------------------------------------------------------------------- 1 | # src.rb 2 | # 3 | # src: 外部ファイルを挿入する(HTMLエスケープ付き) 4 | # パラメタ: 5 | # file: ファイル名 6 | # 7 | # Copyright (c) 2005 TADA Tadashi 8 | # You can distribute this file under the GPL2 or any later version. 9 | # 10 | def src( file ) 11 | h( File::readlines( file ).join ) 12 | end 13 | 14 | # 15 | # src_inline: テキストを挿入する(HTMLエスケープ付き) 16 | # 17 | # パラメタ: テキスト文字列 18 | # 19 | def src_inline( str ) 20 | h( str ) 21 | end 22 | 23 | 24 | # Local Variables: 25 | # mode: ruby 26 | # indent-tabs-mode: t 27 | # tab-width: 3 28 | # ruby-indent-level: 3 29 | # End: 30 | -------------------------------------------------------------------------------- /misc/plugin/theme_online.rb: -------------------------------------------------------------------------------- 1 | # theme_online.rb: choice theme from online repository on tDiary.org 2 | # 3 | # options: 4 | # @options['theme_online.url']: top level URL of another theme site 5 | # 6 | # Copyright (C) 2014 by TADA Tadashi 7 | # You can distribute and/or modify it under GPL2 or any later version. 8 | # 9 | require 'json' 10 | require 'open-uri' 11 | 12 | def theme_list_online(list) 13 | url = @options['theme_online.url'] || '//tdiary.github.io/tdiary-theme/' 14 | url = "http:#{url}" if url =~ %r|\A//| 15 | begin 16 | online_list = JSON.load(open(File.join(url, 'themes.json'), &:read))['themes'] 17 | list + online_list.keys.map do |t| 18 | title = online_list[t]['title'] 19 | label = t == title ? '' : " (#{title})" 20 | ["online/#{t}", "#{t}#{label}"] 21 | end 22 | rescue 23 | @logger.error "could not get theme list from online: #$!" 24 | list 25 | end 26 | end 27 | 28 | def theme_url_online(theme) 29 | url = @options['theme_online.url'] || '//tdiary.github.io/tdiary-theme/' 30 | File.join(url, "#{h theme}/#{h theme}.css") 31 | end 32 | -------------------------------------------------------------------------------- /misc/plugin/title_list.rb: -------------------------------------------------------------------------------- 1 | # titile_list.rb 2 | # 3 | # title_list: 現在表示している月のタイトルリストを表示 4 | # パラメタ(カッコ内は未指定時の値): 5 | # rev: 逆順表示(false) 6 | # 7 | # 備考: タイトルリストを日記に埋め込むには、レイアウトを工夫しなければ 8 | # なりません。ヘッダやフッタでtableタグを使ったり、CSSを書き換える必 9 | # 要があるでしょう。 10 | # 11 | # Copyright (c) 2005 TADA Tadashi 12 | # You can distribute this file under the GPL2 or any later version. 13 | # 14 | def title_list( rev = false ) 15 | result = %Q|
        \n| 16 | keys = @diaries.keys.sort 17 | keys = keys.reverse if rev 18 | keys.each do |date| 19 | next unless @diaries[date].visible? 20 | result << %Q[
      • #{h( @diaries[date].date.strftime( @date_format ) )}\n\t
          \n] 21 | if !@plugin_files.grep(/\/category.rb$/).empty? and @diaries[date].categorizable? 22 | @diaries[date].each_section do |section| 23 | result << %Q[\t
        • #{section.stripped_subtitle_to_html}
        • \n] if section.stripped_subtitle 24 | end 25 | else 26 | @diaries[date].each_section do |section| 27 | result << %Q[
        • #{section.subtitle_to_html}
        • \n] if section.subtitle 28 | end 29 | end 30 | result << "\t
        \n
      • \n" 31 | end 32 | apply_plugin( result << "
      \n" ) 33 | end 34 | 35 | # Local Variables: 36 | # mode: ruby 37 | # indent-tabs-mode: t 38 | # tab-width: 3 39 | # ruby-indent-level: 3 40 | # End: 41 | -------------------------------------------------------------------------------- /misc/plugin/xmlrpc/README: -------------------------------------------------------------------------------- 1 | !機能 2 | 3 | blogger API/metaWeblog API/MovableType APIでのtDiaryの更新ができます。 4 | 5 | !インストール方法 6 | xmlrpc.rb,ja/xmlrpc.rb,en/xmlrpc.rb,zh/xmlrpc.rbをpluginディレクトリにコピーします。 7 | xmlrpc/xmlrpc.rbをtDiaryのインストールされているディレクトリ(index.rbなどと同じディレクトリ)にコピーします。xmlrpc.rbのパーミッションは、755などに変更する必要があります。 8 | index.rbを設置したディレクトリにrsd.xmlというファイルを作成し、CGIから書き換えられるように書き込み権限を設定します。 9 | 10 | !使用方法 11 | 12 | 設定画面から'XML-RPC API'を選択してXML-RPC APIの設定を行いOKボタンをクリックします。 13 | 14 | あとはblogger API/metaWeblog API/MovableType APIに対応したツールからアクセスします。 15 | たとえばubicast BloggerだとXMl-RPCエンドポイントという設定にはxmlrpc.rbのURLを指定します。 16 | 17 | (MovableTypeの場合) http:////mt-xmlrpc.cgi 18 | (xmlrpc.rbの場合) http:////xmlrpc.rb 19 | 20 | rsd.xmlに対応したクライアントならサイトのトップページのURLを指定すればOKです。 21 | -------------------------------------------------------------------------------- /misc/templates/Gemfile.local.erb: -------------------------------------------------------------------------------- 1 | gem 'tdiary' 2 | # use edge tDiary 3 | # gem 'tdiary', :git => 'git@github.com:tdiary/tdiary-core.git' 4 | 5 | # if you use tdiary-contrib gem, uncomment this line. 6 | # gem 'tdiary-contrib' 7 | # use edge tDiary contrib 8 | # gem 'tdiary-contrib', :git => 'git@github.com:tdiary/tdiary-contrib.git' 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tdiary-core", 3 | "version": "5.0.13", 4 | "description": "", 5 | "main": "", 6 | "directories": { 7 | "doc": "doc", 8 | "test": "test" 9 | }, 10 | "scripts": { 11 | "test": "npm run test:js", 12 | "test:js": "jasmine" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git://github.com/tdiary/tdiary-core.git" 17 | }, 18 | "author": "", 19 | "license": "GPL", 20 | "bugs": { 21 | "url": "https://github.com/tdiary/tdiary-core/issues" 22 | }, 23 | "homepage": "https://github.com/tdiary/tdiary-core", 24 | "devDependencies": { 25 | "jquery": "~3.5.0", 26 | "jasmine-jquery": "~2.1.1", 27 | "jasmine": "^5.1.0", 28 | "jsdom": "^24.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/public/.gitkeep -------------------------------------------------------------------------------- /spec/acceptance/bugfix/encoding_error_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature '1.9 でエンコーディングエラーとなるリファラ' do 4 | scenario 'invalid sequence な場合' do 5 | disable_plugin('disp_referrer') 6 | 7 | append_default_diary 8 | 9 | src_path = File.expand_path('../../../fixtures/invalid-sequence-volatile.tdr', __FILE__) 10 | dist_path = File.expand_path('../../../../tmp/data/volatile.tdr', __FILE__) 11 | FileUtils.cp_r src_path, dist_path 12 | 13 | visit "/?date=#{Date.today.strftime('%Y%m%d')}" 14 | 15 | expect(page).to have_content "さて、テストである。" 16 | end 17 | end 18 | 19 | # Local Variables: 20 | # mode: ruby 21 | # indent-tabs-mode: t 22 | # tab-width: 3 23 | # ruby-indent-level: 3 24 | # End: 25 | # vim: ts=3 26 | -------------------------------------------------------------------------------- /spec/acceptance/save_conf_filter_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'spamフィルタ設定の利用' do 4 | scenario '新入荷のプラグインが表示される' do 5 | visit '/update.rb?conf=sf' 6 | 7 | page.all('div.saveconf').first.click_button 'OK' 8 | expect(page).not_to have_content '新入荷' 9 | 10 | FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" 11 | 12 | click_link 'スパムフィルター選択' 13 | expect(page).to have_content '新入荷' 14 | expect(page).to have_content 'sample.rb' 15 | 16 | FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" 17 | end 18 | 19 | scenario 'スパムフィルター選択が保存される' do 20 | FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" 21 | 22 | visit '/update.rb?conf=sf' 23 | check "sf.sample.rb" 24 | page.all('div.saveconf').first.click_button 'OK' 25 | 26 | expect(page).to have_checked_field "sf.sample.rb" 27 | 28 | FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" 29 | end 30 | 31 | scenario 'プラグインが消えたら表示されない' do 32 | FileUtils.cp_r "#{TDiary.root}/spec/fixtures/sample.rb", "#{TDiary.root}/misc/filter/" 33 | 34 | visit '/update.rb?conf=sf' 35 | expect(page).to have_content 'sample.rb' 36 | 37 | FileUtils.rm "#{TDiary.root}/misc/filter/sample.rb" 38 | click_link 'スパムフィルター選択' 39 | expect(page).not_to have_content 'sample.rb' 40 | end 41 | end 42 | 43 | # Local Variables: 44 | # mode: ruby 45 | # indent-tabs-mode: t 46 | # tab-width: 3 47 | # ruby-indent-level: 3 48 | # End: 49 | # vim: ts=3 50 | -------------------------------------------------------------------------------- /spec/acceptance/save_conf_plugin_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'プラグイン選択設定の利用' do 4 | plugin_path = "#{TDiary.root}/misc/plugin/rspec.rb" 5 | 6 | scenario '新入荷のプラグインが表示される' do 7 | FileUtils.rm plugin_path if File.exist? plugin_path 8 | 9 | visit '/update.rb?conf=sp' 10 | page.all('div.saveconf').first.click_button 'OK' 11 | expect(page).not_to have_content '新入荷' 12 | 13 | FileUtils.touch plugin_path 14 | 15 | click_link 'プラグイン選択' 16 | 17 | expect(page).to have_content '新入荷' 18 | expect(page).to have_content 'rspec.rb' 19 | 20 | FileUtils.rm plugin_path 21 | end 22 | 23 | scenario 'プラグイン設定を保存する' do 24 | FileUtils.touch plugin_path 25 | 26 | visit '/update.rb?conf=sp' 27 | 28 | check "sp.rspec.rb" 29 | page.all('div.saveconf').first.click_button 'OK' 30 | 31 | expect(page).to have_checked_field "sp.rspec.rb" 32 | 33 | FileUtils.rm plugin_path 34 | end 35 | 36 | scenario 'プラグインが消えたら表示されない' do 37 | FileUtils.touch plugin_path 38 | 39 | visit '/update.rb?conf=sp' 40 | expect(page).to have_content 'rspec.rb' 41 | 42 | FileUtils.rm plugin_path 43 | 44 | click_link 'プラグイン選択' 45 | expect(page).not_to have_content 'rspec.rb' 46 | end 47 | 48 | scenario '外部の Javascript を追加するプラグインを有効にする' do 49 | visit '/update.rb?conf=sp' 50 | 51 | check "sp.category_autocomplete.rb" 52 | page.all('div.saveconf').first.click_button 'OK' 53 | 54 | visit '/update.rb' 55 | 56 | expect(page.body).to be_include('caretposition.js') 57 | expect(page.body).to be_include('category_autocomplete.js') 58 | expect(page.body).to be_include('//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js') 59 | expect(page.body).not_to be_include('//ajax.googleapis.com/ajax/libs/jqueryui/1.12/1/jquery-ui.min.js?') 60 | end 61 | end 62 | # Local Variables: 63 | # mode: ruby 64 | # indent-tabs-mode: t 65 | # tab-width: 3 66 | # ruby-indent-level: 3 67 | # End: 68 | # vim: ts=3 69 | -------------------------------------------------------------------------------- /spec/acceptance/save_conf_referer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'リンク元設定の利用' do 4 | scenario 'リンク元の非表示設定' do 5 | append_default_diary 6 | visit '/update.rb?conf=referer' 7 | select('非表示', from: 'show_referer') 8 | 9 | page.all('div.saveconf').first.click_button "OK" 10 | # within('title') { page.should have_content('(設定完了)') } 11 | 12 | click_link '最新' 13 | today = Date.today.strftime("%Y年%m月%d日") 14 | page.find('h2', text: today).click_link today 15 | within('div.day') { expect(page).to have_no_css('div[class="refererlist"]') } 16 | end 17 | 18 | scenario 'リンク元記録の除外設定が動いている' do 19 | append_default_diary 20 | visit '/update.rb?conf=referer' 21 | fill_in 'no_referer', with: '^http://www\.example\.com/.*' 22 | 23 | page.all('div.saveconf').first.click_button('OK') 24 | # within('title') { page.should have_content('(設定完了)') } 25 | 26 | click_link '最新' 27 | today = Date.today.strftime('%Y年%m月%d日') 28 | page.find('h2', text: today).click_link today 29 | within('div.day div.refererlist') { expect(page).to have_no_link('http://www.example.com') } 30 | end 31 | 32 | scenario 'リンク元の置換が動いている', :exclude_selenium do 33 | append_default_diary 34 | visit '/update.rb?conf=referer' 35 | fill_in 'referer_table', with: <<-REFERER 36 | ^http://www\.example\.com/.* alice 37 | ^http://www\.example\.net/.* bob 38 | REFERER 39 | 40 | page.all('div.saveconf').first.click_button('OK') 41 | # within('title') { page.should have_content('(設定完了)') } 42 | 43 | click_link '最新' 44 | today = Date.today.strftime('%Y年%m月%d日') 45 | page.find('h2', text: today).click_link today 46 | within('div.day div.refererlist') { 47 | expect(page).to have_link "alice" 48 | expect(page).to have_no_link "http://www.example.com" 49 | } 50 | end 51 | end 52 | 53 | # Local Variables: 54 | # mode: ruby 55 | # indent-tabs-mode: t 56 | # tab-width: 3 57 | # ruby-indent-level: 3 58 | # End: 59 | # vim: ts=3 60 | -------------------------------------------------------------------------------- /spec/acceptance/support/helpers.rb: -------------------------------------------------------------------------------- 1 | module HelperMethods 2 | def append_default_diary(ymd = Date.today.to_s) 3 | date = Date.parse(ymd) 4 | visit '/update.rb' 5 | fill_in "year", with: date.year 6 | fill_in "month", with: date.month 7 | fill_in "day", with: date.day 8 | fill_in "title", with: "tDiaryのテスト" 9 | fill_in "body", with: <<-BODY 10 | !さて、テストである。 11 | とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P 12 | BODY 13 | click_button "追記" 14 | end 15 | 16 | def append_default_comment(ymd = Date.today.to_s) 17 | visit "/" 18 | date = Date.parse(ymd).strftime('%Y年%m月%d日') 19 | page.find('h2', text: date).click_link date 20 | click_link 'ツッコミを入れる' 21 | fill_in "name", with: "alpha" 22 | fill_in "body", with: 'こんにちは!こんにちは!' 23 | click_button '投稿' 24 | end 25 | 26 | def enable_plugin(name) 27 | visit '/update.rb?conf=sp' 28 | check "sp.#{name}.rb" 29 | page.all('div.saveconf').first.click_button 'OK' 30 | end 31 | 32 | def disable_plugin(name) 33 | visit '/update.rb?conf=sp' 34 | uncheck "sp.#{name}.rb" 35 | page.all('div.saveconf').first.click_button 'OK' 36 | end 37 | end 38 | 39 | RSpec.configuration.include(HelperMethods) 40 | 41 | # Local Variables: 42 | # mode: ruby 43 | # indent-tabs-mode: t 44 | # tab-width: 3 45 | # ruby-indent-level: 3 46 | # End: 47 | # vim: ts=3 48 | -------------------------------------------------------------------------------- /spec/acceptance/support/paths.rb: -------------------------------------------------------------------------------- 1 | module NavigationHelpers 2 | def homepage 3 | "/" 4 | end 5 | end 6 | 7 | RSpec.configuration.include(NavigationHelpers) 8 | -------------------------------------------------------------------------------- /spec/acceptance/view_category_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'カテゴリ機能の動作' do 4 | scenario 'カテゴリ機能が動く' do 5 | enable_plugin('category') 6 | 7 | visit '/' 8 | click_link '追記' 9 | 10 | within('span.year') { fill_in "year", with: '2001' } 11 | within('span.month') { fill_in "month", with: '4' } 12 | within('span.day') { fill_in "day", with: '23' } 13 | within('div.textarea') { 14 | fill_in "body", with: <<-BODY 15 | ![category] さて、テストである。 16 | とりあえず自前の環境ではちゃんと動いているが、きっと穴がいっぱいあるに違いない:-P 17 | 18 | ![tdiary] もう一度テストである。 19 | 本当に動くかな? 20 | BODY 21 | } 22 | 23 | click_button "追記" 24 | 25 | visit '/' 26 | page.find('a', text: "category").click 27 | expect(page).to have_content '[category]' 28 | end 29 | end 30 | 31 | # Local Variables: 32 | # mode: ruby 33 | # indent-tabs-mode: t 34 | # tab-width: 3 35 | # ruby-indent-level: 3 36 | # End: 37 | # vim: ts=3 38 | -------------------------------------------------------------------------------- /spec/acceptance/view_comment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'ツッコミの表示' do 4 | scenario 'ツッコミを隠す' do 5 | append_default_diary 6 | append_default_comment 7 | 8 | visit '/' 9 | click_link '追記' 10 | click_button "この日付の日記を編集" 11 | uncheck 'commentcheckboxr0' 12 | click_button 'ツッコミ表示状態変更' 13 | visit '/' 14 | expect(page).to have_no_content "alpha" 15 | expect(page).to have_no_content "こんにちは!こんにちは!" 16 | 17 | today = Date.today.strftime("%Y年%m月%d日") 18 | page.find('h2', text: today).click_link today 19 | expect(page).to have_no_content "alpha" 20 | expect(page).to have_no_content "こんにちは!こんにちは!" 21 | end 22 | 23 | scenario "日付表示だと絵文字を表示できる", :exclude_selenium do 24 | append_default_diary 25 | 26 | visit "/" 27 | click_link 'ツッコミを入れる' 28 | fill_in "name", with: "寿司" 29 | fill_in "body", with: <<-BODY 30 | :sushi: は美味しい 31 | BODY 32 | click_button '投稿' 33 | 34 | visit "/" 35 | today = Date.today.strftime("%Y年%m月%d日") 36 | page.find('h2', text: today).click_link today 37 | within('div.day div.comment div.commentbody') { 38 | expect(page.body).to be_include "sushi は美味しい" 39 | } 40 | end 41 | 42 | scenario "一覧表示でも絵文字を表示できる", :exclude_selenium do 43 | append_default_diary 44 | 45 | visit "/" 46 | click_link 'ツッコミを入れる' 47 | fill_in "name", with: "寿司" 48 | fill_in "body", with: <<-BODY 49 | :sushi: は美味しい 50 | BODY 51 | click_button '投稿' 52 | 53 | visit "/" 54 | within('div.day div.comment div.commentshort') { 55 | expect(page.body).to be_include "sushi は美味しい" 56 | } 57 | end 58 | end 59 | 60 | # Local Variables: 61 | # mode: ruby 62 | # indent-tabs-mode: t 63 | # tab-width: 3 64 | # ruby-indent-level: 3 65 | # End: 66 | # vim: ts=3 67 | -------------------------------------------------------------------------------- /spec/acceptance/view_referer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_helper' 2 | 3 | feature 'リンク元の表示', exclude_selenium: true do 4 | scenario '日表示にリンク元が表示されている' do 5 | append_default_diary 6 | visit '/' 7 | today = Date.today.strftime("%Y年%m月%d日") 8 | page.find('h2', text: today).click_link today 9 | within('div.day') { 10 | expect(page).to have_css('div[class="refererlist"]') 11 | within('div.refererlist') { expect(page).to have_content "http://www.example.com" } 12 | } 13 | end 14 | 15 | scenario '更新画面にリンク元が表示されている' do 16 | append_default_diary 17 | visit "/" 18 | today = Date.today.strftime("%Y年%m月%d日") 19 | page.find('h2', text: today).click_link today 20 | within('div.day div.refererlist') { expect(page).to have_link "http://www.example.com" } 21 | end 22 | end 23 | 24 | # Local Variables: 25 | # mode: ruby 26 | # indent-tabs-mode: t 27 | # tab-width: 3 28 | # ruby-indent-level: 3 29 | # End: 30 | # vim: ts=3 31 | -------------------------------------------------------------------------------- /spec/acceptance_helper.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | Dir["#{File.dirname(__FILE__)}/acceptance/support/**/*.rb"].each {|f| require f} 4 | 5 | require 'tdiary/application' 6 | Capybara.app = Rack::Builder.new do 7 | map '/' do 8 | run TDiary::Dispatcher.index 9 | end 10 | 11 | map '/index.rb' do 12 | run TDiary::Dispatcher.index 13 | end 14 | 15 | map '/update.rb' do 16 | run TDiary::Dispatcher.update 17 | end 18 | end 19 | 20 | # FIXME: TDiary::Application has auth middleware in update.rb, so it cannot be tested. 21 | # Capybara.app = TDiary::Application.new 22 | 23 | Capybara.save_path = File.dirname(__FILE__) + '/../tmp/capybara' 24 | 25 | RSpec.configure do |config| 26 | fixture_conf = File.expand_path('../fixtures/just_installed.conf', __FILE__) 27 | work_data_dir = File.expand_path('../../tmp/data', __FILE__) 28 | 29 | tdiary_conf = File.expand_path("../fixtures/tdiary.conf.#{ENV['TEST_MODE'] || 'rack'}", __FILE__) 30 | work_conf = File.expand_path('../../tdiary.conf', __FILE__) 31 | 32 | config.before(:all) do 33 | FileUtils.cp_r tdiary_conf, work_conf, verbose: false 34 | end 35 | 36 | config.after(:all) do 37 | FileUtils.rm_rf work_conf 38 | end 39 | 40 | config.before(:each) do 41 | FileUtils.mkdir_p work_data_dir 42 | FileUtils.cp_r(fixture_conf, File.join(work_data_dir, "tdiary.conf"), verbose: false) unless fixture_conf.empty? 43 | end 44 | 45 | config.after(:each) do 46 | FileUtils.rm_rf work_data_dir 47 | end 48 | 49 | if ENV['TEST_MODE'] == 'webrick' 50 | Capybara.default_driver = :selenium 51 | Capybara.app_host = 'http://localhost:' + (ENV['PORT'] || '19292') 52 | end 53 | 54 | excludes = case ENV['TEST_MODE'] 55 | when 'webrick' 56 | [:exclude_selenium] 57 | else # rack 58 | [:exclude_rack] 59 | end 60 | excludes.each do |exclude| 61 | config.filter_run_excluding exclude 62 | end 63 | end 64 | 65 | # Local Variables: 66 | # mode: ruby 67 | # indent-tabs-mode: t 68 | # tab-width: 3 69 | # ruby-indent-level: 3 70 | # End: 71 | # vim: ts=3 72 | -------------------------------------------------------------------------------- /spec/core/application_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'rack/test' 3 | require 'tdiary/application' 4 | 5 | describe TDiary::Application do 6 | include Rack::Test::Methods 7 | 8 | before do 9 | end 10 | 11 | describe '#call' do 12 | let(:app) { TDiary::Application.new } 13 | 14 | context "when is accessed to index" 15 | it do 16 | get '/' 17 | expect(last_response.status).to eq 200 18 | end 19 | 20 | context "when is accessed to update" do 21 | it do 22 | get '/update.rb' 23 | expect(last_response.status).to eq 401 24 | end 25 | end 26 | 27 | context "with base_dir" do 28 | before do 29 | TDiary.configuration.options['base_url'] = 'http://example.com/diary/' 30 | end 31 | 32 | after do 33 | TDiary.configuration.options['base_url'] = '' 34 | end 35 | 36 | let(:app) { TDiary::Application.new } 37 | 38 | it do 39 | get '/diary/' 40 | expect(last_response.status).to eq 200 41 | end 42 | 43 | context "when access to root directory" do 44 | it do 45 | get '/' 46 | expect(last_response.status).to eq 404 47 | end 48 | end 49 | end 50 | 51 | context "when the application raises exception" do 52 | before do 53 | allow(TDiary::Dispatcher).to receive_message_chain(:index).and_return( 54 | lambda {|env| raise StandardError.new } 55 | ) 56 | end 57 | 58 | it do 59 | get '/' 60 | expect(last_response.status).to eq 500 61 | expect(last_response.body).to match(/^StandardError/) 62 | end 63 | end 64 | end 65 | end 66 | 67 | # Local Variables: 68 | # mode: ruby 69 | # indent-tabs-mode: t 70 | # tab-width: 3 71 | # ruby-indent-level: 3 72 | # End: 73 | -------------------------------------------------------------------------------- /spec/core/compatible_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'tdiary/compatible' 4 | require 'fileutils' 5 | 6 | describe PStore, "auto convert library" do 7 | before do 8 | # rake specで動かすと、comppatible.rb が既に読み込まれてしまっているため、 9 | # このPStoreがASCII-8BITではなくUTF-8になってしまう。 10 | # そのため、下記と同様の ascii8bit-pstore.db をテストフィクスチャとしている。 11 | # PStore.new(@dbfile).transaction do |db| 12 | # db["key1".to_8bit] = "val1".to_8bit 13 | # db["key2".to_8bit] = 2 14 | # db["key3".to_8bit] = [1, :sym, "string".to_8bit] 15 | # end 16 | dbfilename = '../fixtures/ascii8bit-pstore.db' 17 | dbfile_orig = File.join(File.dirname(__FILE__), dbfilename) 18 | @dbfile = File.join(File.dirname(__FILE__), "#{dbfilename}.work") 19 | FileUtils.cp dbfile_orig, @dbfile 20 | end 21 | 22 | after do 23 | FileUtils.rm @dbfile 24 | end 25 | 26 | it "should convert an encoding to UTF-8 automatically" do 27 | PStore.new(@dbfile).transaction do |db| 28 | expect(db["key1"].encoding).to eq(Encoding::UTF_8) 29 | expect(db["key2"]).to eq(2) 30 | expect(db["key3"][2].encoding).to eq(Encoding::UTF_8) 31 | end 32 | end 33 | 34 | it "1回目のtransactionではMashal.loadが3回呼ばれる" do 35 | expect(Marshal).to receive(:load).exactly(3).and_return({}) 36 | PStore.new(@dbfile).transaction {} 37 | end 38 | 39 | it "2回目のtransactionではMashal.loadが1回だけ呼ばれる" do 40 | expect(Marshal).to receive(:load).exactly(4).and_return({}) 41 | PStore.new(@dbfile).transaction {} 42 | PStore.new(@dbfile).transaction {} 43 | end 44 | end 45 | 46 | # Local Variables: 47 | # mode: ruby 48 | # indent-tabs-mode: t 49 | # tab-width: 3 50 | # ruby-indent-level: 3 51 | # End: 52 | -------------------------------------------------------------------------------- /spec/core/configuration_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | require 'tdiary' 4 | require 'tdiary/configuration' 5 | 6 | describe TDiary::Configuration do 7 | let(:tdiary_conf) { File.expand_path("../../fixtures/tdiary.conf.webrick", __FILE__) } 8 | let(:work_conf) { File.expand_path('../../../tdiary.conf', __FILE__) } 9 | 10 | before do 11 | FileUtils.cp_r tdiary_conf, work_conf, verbose: false 12 | end 13 | 14 | after do 15 | FileUtils.rm_rf work_conf 16 | end 17 | 18 | describe "TDiary.configuration" do 19 | before do 20 | @obj = TDiary.configuration 21 | end 22 | 23 | it { expect(@obj.class).to eq TDiary::Configuration } 24 | it "singleton" do 25 | expect(@obj).to eq TDiary.configuration 26 | end 27 | end 28 | 29 | it "TDiary.configuration.attribute" do 30 | expect(TDiary.configuration.style).to eq("Wiki") 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /spec/core/rack/html_anchor_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'rack/test' 3 | require 'tdiary/rack/html_anchor' 4 | 5 | describe TDiary::Rack::HtmlAnchor do 6 | include Rack::Test::Methods 7 | 8 | describe "html anchor" do 9 | let(:app) { TDiary::Rack::HtmlAnchor.new( 10 | lambda{|env| [200, {}, ['Awesome']]} )} 11 | 12 | it 'should not do anything for root access' do 13 | get '/' 14 | expect(last_request.params['date']).to eq(nil) 15 | expect(last_request.query_string).to eq('') 16 | end 17 | 18 | it 'should remove the file name from PATH_INFO' do 19 | get '/20120501.html' 20 | expect(last_request.env['PATH_INFO']).to eq('/') 21 | get '/diary/20120501.html' 22 | expect(last_request.env['PATH_INFO']).to eq('/diary/') 23 | end 24 | 25 | it 'should add date query' do 26 | get '/diary/0501.html' 27 | expect(last_request.params['date']).to eq("0501") 28 | get '/0501.html' 29 | expect(last_request.params['date']).to eq("0501") 30 | get '/201205.html' 31 | expect(last_request.params['date']).to eq("201205") 32 | get '/20120501.html' 33 | expect(last_request.params['date']).to eq("20120501") 34 | end 35 | 36 | it 'should add date query when using section_permalink_anchor plugin' do 37 | get '/20120501p01.html' 38 | expect(last_request.params['date']).to eq("20120501") 39 | expect(last_request.params['p']).to eq("01") 40 | end 41 | 42 | it 'should replace date query' do 43 | get '/20120501.html?date=20120101' 44 | expect(last_request.params['date']).to eq("20120501") 45 | end 46 | 47 | it 'should not break original query' do 48 | get '/?date=20120501' 49 | expect(last_request.params['date']).to eq("20120501") 50 | get '/index.rb?date=20120501' 51 | expect(last_request.params['date']).to eq("20120501") 52 | get '/index.rb?date=20120501&p=01' 53 | expect(last_request.params['date']).to eq("20120501") 54 | expect(last_request.params['p']).to eq("01") 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/core/rack/static_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'rack/test' 3 | require 'tdiary/rack/static' 4 | 5 | describe TDiary::Rack::Static do 6 | include Rack::Test::Methods 7 | 8 | describe "reserve static files" do 9 | let(:app) { TDiary::Rack::Static.new( 10 | lambda{|env| [500, {}, ['Internal Server Error']]}, ['doc'])} 11 | 12 | it 'should return the file in static directory' do 13 | get '/README.md' 14 | expect(last_response).to be_ok 15 | end 16 | 17 | it 'should run the app if file is not exist' do 18 | get '/index.rb' 19 | expect(last_response.status).to be 500 20 | end 21 | 22 | it 'should run the app when post method' do 23 | post '/index.rb' 24 | expect(last_response.status).to be 500 25 | end 26 | end 27 | 28 | describe "resurve mutiple static files" do 29 | let(:app) { TDiary::Rack::Static.new( 30 | lambda{|env| [500, {}, ['Internal Server Error']]}, ['js', 'theme'])} 31 | 32 | it 'should return the file in js directory' do 33 | get '/00default.js' 34 | expect(last_response).to be_ok 35 | end 36 | 37 | it 'should return the file in theme directory' do 38 | get '/base.css' 39 | expect(last_response).to be_ok 40 | end 41 | 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/core/rack/valid_request_path_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'rack/test' 3 | require 'tdiary/rack/valid_request_path' 4 | 5 | describe TDiary::Rack::ValidRequestPath do 6 | include Rack::Test::Methods 7 | 8 | describe "valid request" do 9 | let(:app) { TDiary::Rack::ValidRequestPath.new( 10 | lambda{|env| [200, {}, ['Awesome']]} )} 11 | 12 | it 'should return 200 for latest' do 13 | get '/' 14 | expect(last_response).to be_ok 15 | end 16 | 17 | it 'should return 200 for a nyear' do 18 | get '/0501.html' 19 | expect(last_response).to be_ok 20 | end 21 | 22 | it 'should return 200 for a month' do 23 | get '/201205.html' 24 | expect(last_response).to be_ok 25 | end 26 | 27 | it 'should return 200 for a day' do 28 | get '/20120501.html' 29 | expect(last_response).to be_ok 30 | end 31 | 32 | it 'should return 200 for a day with section_permalink_anchor plugin' do 33 | get '/20120501p01.html' 34 | expect(last_response).to be_ok 35 | end 36 | 37 | it 'should return 200 for a day with query' do 38 | get '/?date=20120501' 39 | expect(last_response).to be_ok 40 | end 41 | 42 | it 'should return 200 for a day with query and section_permalink_anchor plugin' do 43 | get '/?date=20120501&p=01' 44 | expect(last_response).to be_ok 45 | end 46 | 47 | it 'should return 200 for a day with index.rb and query' do 48 | get '/index.rb?date=20120501' 49 | expect(last_response).to be_ok 50 | end 51 | 52 | it 'should return 404 for access to the invalid file' do 53 | get '/20120501' 54 | expect(last_response.status).to be 404 55 | get '/invalid' 56 | expect(last_response.status).to be 404 57 | head '/invalid' 58 | expect(last_response.status).to be 404 59 | expect(last_response.body.length).to be 0 60 | end 61 | 62 | it 'should return 404 for access to the invalid directory' do 63 | get '/invalid/' 64 | expect(last_response.status).to eq(404) 65 | end 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /spec/core/tdiary_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'fileutils' 3 | 4 | describe TDiary do 5 | describe 'LOAD_PATH' do 6 | before do 7 | @root_path = File.expand_path(File.dirname(__FILE__) + '/../..') 8 | @loaded_paths = $LOAD_PATH.map{|path| File.expand_path(path)} 9 | end 10 | 11 | it "include misc path into load path" do 12 | expect(@loaded_paths).to be_include @root_path + '/misc/lib' 13 | end 14 | 15 | context 'append gem' do 16 | before do 17 | FileUtils.mkdir_p @root_path + '/misc/lib/foo-0.0.1/lib' 18 | load @root_path + '/lib/tdiary.rb' 19 | @loaded_paths = $LOAD_PATH.map{|path| File.expand_path(path)} 20 | end 21 | 22 | it "include append gem path into load path" do 23 | expect(@loaded_paths).to be_include @root_path + '/misc/lib/foo-0.0.1/lib' 24 | end 25 | 26 | after do 27 | FileUtils.rm_rf @root_path + '/misc/lib/foo-0.0.1' 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/fixtures/ascii8bit-pstore.db: -------------------------------------------------------------------------------- 1 | { I" key1:ETI" val1;TI" key2;TiI" key3;T[i:symI" string;T:__ruby_versionI" 2 | 1.9.2;F -------------------------------------------------------------------------------- /spec/fixtures/invalid-sequence-volatile.tdr: -------------------------------------------------------------------------------- 1 | TDIARY2.01.00 2 | Date: 20110903 3 | 4 | 1 http://search.mobile.yahoo.co.jp/onesearch/?sbox=SBT&squery=%90%F3%91%90+TX+%89%FC%8ED&p=%90%F3%91%90ROX 5 | 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 6 | 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 7 | 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 8 | 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 9 | . 10 | -------------------------------------------------------------------------------- /spec/fixtures/just_installed.conf: -------------------------------------------------------------------------------- 1 | tdiary_version = "2.3.3.20100515" 2 | -------------------------------------------------------------------------------- /spec/fixtures/plugin/ja/sample.rb: -------------------------------------------------------------------------------- 1 | def sample_ja 2 | 'サンプルプラグイン' 3 | end 4 | 5 | -------------------------------------------------------------------------------- /spec/fixtures/plugin/sample.rb: -------------------------------------------------------------------------------- 1 | def sample 2 | 'sample plugin' 3 | end 4 | 5 | add_header_proc do 6 | end 7 | -------------------------------------------------------------------------------- /spec/fixtures/sample.rb: -------------------------------------------------------------------------------- 1 | module TDiary::Filter 2 | class SampleFilter < Filter 3 | end 4 | end 5 | 6 | # Local Variables: 7 | # mode: ruby 8 | # indent-tabs-mode: t 9 | # tab-width: 3 10 | # ruby-indent-level: 3 11 | # End: 12 | # vim: ts=3 13 | -------------------------------------------------------------------------------- /spec/javascripts/00default_spec.js: -------------------------------------------------------------------------------- 1 | describe("$tDiary", function() { 2 | beforeEach(function() { 3 | }); 4 | 5 | it("should exist a global $tDiary object", function() { 6 | expect($tDiary).toEqual(jasmine.any(Object)); 7 | expect($tDiary.plugin).toEqual(jasmine.any(Object)); 8 | }); 9 | }); 10 | 11 | describe("$", function() { 12 | describe("#makePluginTag", function() { 13 | describe("when Wiki style", function() { 14 | beforeEach(function() { 15 | $tDiary.style = 'wiki'; 16 | }); 17 | 18 | it('should create wiki style plugin tag', function() { 19 | var tag = $.makePluginTag("plugin_name", ["param1", "param2"]); 20 | expect(tag).toEqual('{{plugin_name "param1", "param2"}}'); 21 | loadFixtures('00default.html'); 22 | }); 23 | }); 24 | }); 25 | 26 | describe("#insertAtCaret", function() { 27 | beforeEach(function() { 28 | loadFixtures('00default.html'); 29 | }); 30 | it('should insert text to the textarea', function() { 31 | $('#body').insertAtCaret('[category] '); 32 | expect($('#body').val()).toEqual('[category] sample diary'); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /spec/javascripts/fixtures/00default.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spec/plugin/bq_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../plugin_helper', __FILE__) 2 | 3 | describe "bq plugin w/" do 4 | def setup_bq_plugin( mode ) 5 | fake_plugin(:bq) { |plugin| 6 | plugin.mode = mode 7 | } 8 | end 9 | 10 | describe "src only." do 11 | before do 12 | plugin = setup_bq_plugin('lateste') 13 | @body_snippet = plugin.bq('foo') 14 | end 15 | 16 | it { expect(@body_snippet).to eq(expected_html_body( 17 | src: 'foo')) } 18 | end 19 | 20 | def expected_html_body(options) 21 | %|
      \n

      #{options[:src]}

      \n
      \n| 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..')) 2 | 3 | ENV['RACK_ENV'] = "test" 4 | 5 | require 'tdiary/environment' 6 | 7 | if ENV['COVERAGE'] = 'simplecov' 8 | require 'simplecov' 9 | 10 | SimpleCov.start do 11 | add_filter '/spec/' 12 | add_filter '/test/' 13 | add_filter '/vendor/' 14 | end 15 | end 16 | 17 | require 'tdiary' 18 | 19 | RSpec.configure do |config| 20 | config.expect_with :rspec do |c| 21 | c.syntax = :expect 22 | end 23 | end 24 | 25 | class DummyTDiary 26 | attr_accessor :conf 27 | 28 | def initialize 29 | @conf = DummyConf.new 30 | @conf.data_path = TDiary.root + "/tmp/" 31 | end 32 | 33 | def ignore_parser_cache 34 | false 35 | end 36 | end 37 | 38 | class DummyConf 39 | attr_accessor :data_path 40 | 41 | def cache_path 42 | TDiary.root + "/tmp/cache" 43 | end 44 | 45 | def options 46 | {} 47 | end 48 | 49 | def style 50 | "wiki" 51 | end 52 | end 53 | 54 | # Local Variables: 55 | # mode: ruby 56 | # indent-tabs-mode: t 57 | # tab-width: 3 58 | # ruby-indent-level: 3 59 | # End: 60 | # vim: ts=3 61 | -------------------------------------------------------------------------------- /spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec/javascripts", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ], 9 | "env": { 10 | "stopOnFailure": false, 11 | "random": false 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/support/jasmine.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | spec_dir: "spec/javascripts", 3 | spec_files: [ 4 | "**/*[sS]pec.js" 5 | ], 6 | helpers: [ 7 | "helpers/**/*.js" 8 | ], 9 | env: { 10 | stopSpecOnExpectationFailure: false, 11 | random: false, 12 | forbidDuplicateNames: true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tdiary.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('../lib', __FILE__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'tdiary/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "tdiary" 7 | spec.version = TDiary::VERSION 8 | spec.authors = ["TADA Tadashi", "SHIBATA Hiroshi", "MATSUOKA Kohei"] 9 | spec.email = ["support@tdiary.org"] 10 | spec.summary = %q{a TSUKKOMI-able Web-log} 11 | spec.description = %q{tDiary is so called Weblog.} 12 | spec.homepage = "http://www.tdiary.org/" 13 | spec.license = "GPL2" 14 | 15 | spec.files = Dir[ 16 | 'ChangeLog', 17 | 'config.ru', 18 | 'Gemfile', 19 | 'Gemfile.lock', 20 | 'README.md', 21 | 'Rakefile', 22 | 'tdiary.conf*', 23 | 'bin/**/*', 24 | 'doc/**/*', 25 | 'js/**/*', 26 | 'lib/**/*', 27 | 'misc/**/*', 28 | 'public/**/*', 29 | 'theme/**/*', 30 | 'vendor/**/*', 31 | 'views/**/*' 32 | ] 33 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 34 | spec.require_paths = ["lib"] 35 | 36 | spec.required_ruby_version = '>= 2.6' 37 | 38 | spec.add_dependency 'emot' 39 | spec.add_dependency 'fastimage' 40 | spec.add_dependency 'hikidoc' 41 | spec.add_dependency 'mail' 42 | spec.add_dependency 'rack' 43 | spec.add_dependency 'nkf' 44 | spec.add_dependency 'rake' 45 | spec.add_dependency 'thor' 46 | spec.add_dependency 'rexml' 47 | spec.add_dependency 'webrick' 48 | spec.add_dependency "bundler", ">= 1.3", "< 3.0" 49 | end 50 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ['..', '../misc/plugin'].each do |path| 2 | $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), path)) 3 | end 4 | 5 | require 'tdiary/environment' 6 | require 'test/unit' 7 | -------------------------------------------------------------------------------- /test/test_plugin_helper_test.rb: -------------------------------------------------------------------------------- 1 | # Test cases for test_plugin_helper.rb 2 | require File.expand_path('../test_helper', __FILE__) 3 | require File.expand_path('../test_plugin_helper', __FILE__) 4 | 5 | class TestPluginTestHelper < Test::Unit::TestCase 6 | include TDiary::PluginTestHelper 7 | 8 | def test_absolute_path_of 9 | abspath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'tdiary', 'plugin', '00default.rb')) 10 | assert_equal(abspath, TDiary::PluginTestHelper.absolute_path_of('lib/tdiary/plugin/00default.rb')) 11 | end 12 | 13 | def test_resource_absolute_path_of 14 | abspath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'tdiary', 'plugin', 'en', '00default.rb')) 15 | assert_equal(abspath, TDiary::PluginTestHelper.resource_absolute_path_of('lib/tdiary/plugin/00default.rb', 'en')) 16 | end 17 | 18 | def test_resource_relative_path_of 19 | abspath = File.join('lib', 'tdiary', 'plugin', 'en', '00default.rb') 20 | assert_equal(abspath, TDiary::PluginTestHelper.resource_relative_path_of('lib/tdiary/plugin/00default.rb', 'en')) 21 | end 22 | 23 | def test_new_plugin 24 | assert_nothing_raised do 25 | TDiary::StubPlugin::new_plugin('lib/tdiary/plugin/00default.rb', 'en') 26 | end 27 | end 28 | 29 | def test_load_plugin 30 | assert_nothing_raised do 31 | TDiary::StubPlugin::load_plugin('lib/tdiary/plugin/00default.rb', 'en') 32 | end 33 | end 34 | 35 | def test_plugin_conf 36 | plugin = TDiary::StubPlugin::load_plugin('lib/tdiary/plugin/00default.rb', 'en') 37 | assert_nothing_raised do 38 | plugin.conf['key'] = 'value' 39 | end 40 | assert_equal('value', plugin.conf['key']) 41 | end 42 | 43 | def test_plugin_options 44 | plugin = TDiary::StubPlugin::load_plugin('lib/tdiary/plugin/00default.rb', 'en') 45 | assert_nothing_raised do 46 | plugin.options['key'] = 'value' 47 | end 48 | assert_equal('value', plugin.options['key']) 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /test/weather-ADDS-METARS-RJAA-130131.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/test/weather-ADDS-METARS-RJAA-130131.html -------------------------------------------------------------------------------- /test/weather-ADDS-METARS-RJAA-130227.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/test/weather-ADDS-METARS-RJAA-130227.html -------------------------------------------------------------------------------- /theme/conf.block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/theme/conf.block.png -------------------------------------------------------------------------------- /theme/default/README: -------------------------------------------------------------------------------- 1 | Title: tDiary3デフォルト 2 | Revision: $Revision: 1.0 $ 3 | Author: ただただし 4 | Access: t@tdtds.jp 5 | License: GPL2 or any later version 6 | Comment: tDiary 3.1に付属するデフォルトテーマ 7 | 8 | ChangeLog 9 | 2011-07-18 TADA Tadashi 10 | * ported from gustav. 11 | 12 | -------------------------------------------------------------------------------- /theme/default/body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/theme/default/body.png -------------------------------------------------------------------------------- /theme/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/theme/help.png -------------------------------------------------------------------------------- /theme/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/theme/loading.gif -------------------------------------------------------------------------------- /theme/ogimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/theme/ogimage.png -------------------------------------------------------------------------------- /theme/tdiary1/README: -------------------------------------------------------------------------------- 1 | Title: tDiary1デフォルト 2 | Revision: $Revision: 1.2 $ 3 | Author: ただただし 4 | Access: sho@spc.gr.jp 5 | License: GPL2 or any later version 6 | Comment: tDiary 1.4までのデフォルトテーマ 7 | 8 | -------------------------------------------------------------------------------- /theme/tdiary2/README: -------------------------------------------------------------------------------- 1 | Title: tDiary2デフォルト 2 | Revision: $Revision: 2.0 $ 3 | Author: ただただし 4 | Access: t@tdtds.jp 5 | License: GPL2 or any later version 6 | Comment: tDiary 2.0に付属するデフォルトテーマ 7 | 8 | ChangeLog 9 | 2011-07-16 TADA Tadashi 10 | * renamed from default. 11 | 12 | 2003-04-17 TADA Tadashi 13 | * add table settings. 14 | 15 | 2003-03-12 TADA Tadashi 16 | * little modified. 17 | 18 | 2003-02-03 TADA Tadashi 19 | * add h4. 20 | -------------------------------------------------------------------------------- /tmp/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/tmp/.gitkeep -------------------------------------------------------------------------------- /update.fcgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # index.fcgi $Revision: 1.35 $ 4 | # 5 | # Copyright (C) 2004, Akinori MUSHA 6 | # Copyright (C) 2006, moriq 7 | # Copyright (C) 2011, Kazuhiko 8 | # You can redistribute it and/or modify it under GPL2 or any later version. 9 | # 10 | require 'fcgi' 11 | # workaround untaint LOAD_PATH for rubygems library path is always tainted. 12 | $:.each{|path| path if path.include?('fcgi') } 13 | 14 | if FileTest::symlink?( __FILE__ ) then 15 | org_path = File::dirname( File::readlink( __FILE__ ) ) 16 | else 17 | org_path = File::dirname( __FILE__ ) 18 | end 19 | load "#{org_path}/misc/lib/fcgi_patch.rb" 20 | 21 | FCGI.each_cgi do |cgi| 22 | begin 23 | ENV.clear 24 | ENV.update(cgi.env_table) 25 | class << CGI; self; end.class_eval do 26 | define_method(:new) {|*args| cgi } 27 | end 28 | dir = File::dirname( cgi.env_table["SCRIPT_FILENAME"] || __FILE__ ) 29 | Dir.chdir(dir) do 30 | load 'update.rb' 31 | end 32 | ensure 33 | class << CGI 34 | remove_method :new 35 | end 36 | end 37 | end 38 | 39 | # Local Variables: 40 | # mode: ruby 41 | # indent-tabs-mode: t 42 | # tab-width: 3 43 | # ruby-indent-level: 3 44 | # End: 45 | -------------------------------------------------------------------------------- /update.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: ascii-8bit; -*- 3 | # 4 | # update.rb 5 | # 6 | # Copyright (C) 2001-2009, TADA Tadashi 7 | # You can redistribute it and/or modify it under GPL2 or any later version. 8 | # 9 | BEGIN { $stdout.binmode } 10 | 11 | begin 12 | if FileTest::symlink?( __FILE__ ) then 13 | org_path = File::dirname( File::readlink( __FILE__ ) ) 14 | else 15 | org_path = File::dirname( __FILE__ ) 16 | end 17 | $:.unshift( (org_path + '/lib') ) unless $:.include?( org_path + '/lib' ) 18 | require 'tdiary' 19 | 20 | encoding_error = {} 21 | cgi = CGI::new(accept_charset: "UTF-8") do |name, value| 22 | encoding_error[name] = value 23 | end 24 | if encoding_error.empty? 25 | @cgi = cgi 26 | else 27 | @cgi = CGI::new(accept_charset: 'shift_jis') 28 | @cgi.params = cgi.params.dup 29 | end 30 | 31 | request = TDiary::Request.new( ENV, @cgi ) 32 | status, headers, body = TDiary::Dispatcher.update.dispatch_cgi( request, @cgi ) 33 | 34 | TDiary::Dispatcher.send_headers( status, headers ) 35 | require 'rackup/handler/cgi' 36 | ::Rackup::Handler::CGI.send_body(body) 37 | rescue Exception 38 | if @cgi then 39 | print @cgi.header( 'status' => '500 Internal Server Error', 'type' => 'text/html' ) 40 | else 41 | print "Status: 500 Internal Server Error\n" 42 | print "content-type: text/html\n\n" 43 | end 44 | puts "

      500 Internal Server Error

      " 45 | puts "
      "
      46 | 	puts CGI::escapeHTML( "#{$!} (#{$!.class})" )
      47 | 	puts ""
      48 | 	puts CGI::escapeHTML( $@.join( "\n" ) )
      49 | 	puts "
      " 50 | puts "
      #{' ' * 500}
      " 51 | end 52 | 53 | # Local Variables: 54 | # mode: ruby 55 | # indent-tabs-mode: t 56 | # tab-width: 3 57 | # ruby-indent-level: 3 58 | # End: 59 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tdiary/tdiary-core/9ebf572e4f49cf0037ce3011d8c2e2ce23f033b3/vendor/.gitkeep -------------------------------------------------------------------------------- /views/amp.rhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= amp_header_proc %> 6 | 7 | <%= amp_title %> 8 | 9 | 10 | 11 | 14 | 15 | 16 | <%= amp_body_enter_proc %> 17 |
      18 |
      19 | <%= navi_user %> 20 |
      21 |
      22 |

      <%= amp_title %>

      23 |
      24 |

      <%= amp_day_title(diary) %>

      25 |
      26 | <%= amp_body(diary) %> 27 |
      28 |
      29 |
      30 | 32 |
      33 | 34 | 35 | -------------------------------------------------------------------------------- /views/category.rhtml: -------------------------------------------------------------------------------- 1 | <%%= navi %> 2 | <%=@conf['category.header1'] %> 3 |

      <%=h @conf.html_title %> <%%=h category_title %>

      4 | <%= @conf['category.header2'] %> 5 |
      6 | <%%= category_list_sections %> 7 |
      8 | <%%= category_form %> 9 |
      10 | -------------------------------------------------------------------------------- /views/conf.rhtml: -------------------------------------------------------------------------------- 1 | <%%=navi%> 2 |

      <%=h @conf.html_title %>(<%%=h navi_preference%>) - <%%=h conf_label( <%=@key.dump%> )%><%%=help( <%=@key.dump%> + '.rb' )%>

      3 | <%%= old_ruby_alert %> 4 | 14 | 17 |
      18 | 19 | <%=@csrf_protection%> 20 |
      21 | <%%=conf_proc( <%=@key.dump%> )%> 22 |
      23 |
      24 | -------------------------------------------------------------------------------- /views/day.rhtml: -------------------------------------------------------------------------------- 1 | <%= @conf.header %> 2 |
      3 | 4 | <% 5 | if @diary then 6 | param = { 7 | 'date_format' => @conf.date_format, 8 | 'index' => @conf.index, 9 | 'section_anchor' => @conf.section_anchor, 10 | 'comment_anchor' => @conf.comment_anchor, 11 | 'long_mode' => true, 12 | 'show_referer' => @conf.show_referer, 13 | 'referer_limit' => 100, 14 | 'referer_table' => @conf.referer_table, 15 | 'show_comment' => @conf.show_comment, 16 | 'comment_limit' => -1, 17 | 'multi_user' => @conf.multi_user, 18 | 'cookie_name' => cookie_name, 19 | 'cookie_mail' => cookie_mail, 20 | 'anchor' => true, 21 | 'hide_comment_form' => @conf.hide_comment_form, 22 | 'show_nyear' => @conf.show_nyear, 23 | 'bot' => @conf.bot =~ @cgi.user_agent, 24 | } %> 25 | <%= @diary.eval_rhtml( param ) %><% 26 | else %> 27 |

      28 | <%%=no_diary%> 29 |

      <% 30 | end %> 31 |
      32 | 33 | <%= @conf.footer %> 34 | -------------------------------------------------------------------------------- /views/footer.rhtml: -------------------------------------------------------------------------------- 1 | <%%=footer_proc%> 2 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /views/header.rhtml: -------------------------------------------------------------------------------- 1 | <%%=doctype%> 2 | 3 | 4 | <%%=header_proc%> 5 | 6 | > 7 |
8 | <% if @error then %>

Security Error?
9 | <%=h @error[0].to_s %>
<%=h @error[1][0] %> 10 |

<% end %> 11 | -------------------------------------------------------------------------------- /views/latest.rhtml: -------------------------------------------------------------------------------- 1 | <%= @conf.header %> 2 |
3 | 4 | <% 5 | param = { 6 | 'date_format' => @conf.date_format, 7 | 'index' => @conf.index, 8 | 'section_anchor' => @conf.section_anchor, 9 | 'comment_anchor' => @conf.comment_anchor, 10 | 'long_mode' => false, 11 | 'show_referer' => @conf.show_referer, 12 | 'referer_limit' => @conf.referer_limit, 13 | 'referer_table' => @conf.referer_table, 14 | 'show_comment' => @conf.show_comment, 15 | 'comment_limit' => @conf.comment_limit, 16 | 'multi_user' => @conf.multi_user, 17 | 'show_nyear' => @conf.show_nyear, 18 | 'comment_length' => @conf.comment_length, 19 | 'hide_comment_form' => @conf.hide_comment_form, 20 | } 21 | latest( @conf.latest_limit ) do |diary| %> 22 | <%= diary.eval_rhtml( param ) %> 23 |
<% 24 | end %> 25 | 26 | <%= @conf.footer %> 27 | 28 | -------------------------------------------------------------------------------- /views/mail.rtxt: -------------------------------------------------------------------------------- 1 | From: <%= name %> <<%= mail %>> 2 | To: <%= receivers.join(', ') %> 3 | Date: <%= date %> 4 | Message-Id: <%= message_id %> 5 | Subject: <%= subject_header %>-<%= serial %> 6 | <%= name %> 7 | MIME-Version: 1.0 8 | content-type: text/plain; charset=utf-8 9 | Content-Transfer-Encoding: base64 10 | Errors-To: <%= receivers[0] %> 11 | X-Mailer: tDiary <%= TDIARY_VERSION %> 12 | X-URL: http://www.tdiary.org/ 13 | -------------------------------------------------------------------------------- /views/month.rhtml: -------------------------------------------------------------------------------- 1 | <%= @conf.header %> 2 |
3 | 4 | <% 5 | param = { 6 | 'date_format' => @conf.date_format, 7 | 'index' => @conf.index, 8 | 'section_anchor' => @conf.section_anchor, 9 | 'comment_anchor' => @conf.comment_anchor, 10 | 'long_mode' => false, 11 | 'show_referer' => @conf.show_referer, 12 | 'referer_limit' => @conf.referer_limit, 13 | 'referer_table' => @conf.referer_table, 14 | 'show_comment' => @conf.show_comment, 15 | 'comment_limit' => @conf.comment_limit, 16 | 'multi_user' => @conf.multi_user, 17 | 'show_nyear' => @conf.show_nyear, 18 | 'comment_length' => @conf.comment_length, 19 | 'hide_comment_form' => @conf.hide_comment_form, 20 | } 21 | each_day do |diary| %> 22 | <%= diary.eval_rhtml( param ) %> 23 |
<% 24 | end %> 25 | 26 | <%= @conf.footer %> 27 | 28 | -------------------------------------------------------------------------------- /views/plugin_error.rhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Plugin Error 6 | 7 | 8 |

Plugin Error

9 | <% 10 | if self.kind_of?( TDiary::TDiaryAdmin ) and @date then 11 | update = %Q[Edit(#{@date.strftime( '%Y-%m-%d' )})] 12 | else 13 | update = %Q[Update] 14 | end 15 | %> 16 |

17 | Errors in plugins? 18 | Retry to <%= update %> or Configure. 19 |

20 |
21 | <%=h $!.class %>
22 |
<%=h $! %>
23 |
<%=h $!.backtrace.join("\n") %>
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /views/referer.rhtml: -------------------------------------------------------------------------------- 1 |
2 | <% if @cgi.params['referer'][0] == 'no' then %> 3 |

<%%=label_no_referer%>

4 |
5 |
    6 | <%= (@conf.no_referer - @conf.no_referer2).collect{|r| "
  • #{h r}
  • \n" }.join %> 7 |
8 |
9 | <% elsif @cgi.params['referer'][0] == 'volatile' %> 10 |

<%%=label_only_volatile%>

11 |
12 |
    13 | <%= (@conf.only_volatile - @conf.only_volatile2).collect{|r| "
  • #{h r}
  • \n" }.join %> 14 |
15 |
16 | <% else %> 17 |

<%%=label_referer_table%>

18 |
19 | 20 | <%= (@conf.referer_table - @conf.referer_table2).collect{|r,n| "\n" }.join %> 21 |
#{h r}#{h n}
22 |
23 | <% end %> 24 |
25 | -------------------------------------------------------------------------------- /views/search.rhtml: -------------------------------------------------------------------------------- 1 | <%# search.rhtml %> 2 | <%= @conf.header %> 3 |
4 |
5 |

<%%= search_title %>

6 |
7 | <%%= search_result %> 8 |
9 |
10 |
11 |
12 |
13 | 14 | <%= @conf.footer %> 15 | --------------------------------------------------------------------------------