mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-16 23:39:22 +01:00
Compare commits
No commits in common. "master-2023-05-18" and "gh-pages" have entirely different histories.
master-202
...
gh-pages
8
.editorconfig
Normal file
8
.editorconfig
Normal file
@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = space
|
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,2 +1 @@
|
||||
sandbox export-ignore
|
||||
.git* export-ignore
|
||||
* text=auto eol=lf
|
||||
|
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
||||
* @Mikaela
|
5
.github/renovate.json5
vendored
Normal file
5
.github/renovate.json5
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/** @format */
|
||||
|
||||
{
|
||||
extends: ["local>Mikaela/shell-things:.renovate-shared"],
|
||||
}
|
25
.github/workflows/html5validator.yml.disabled
vendored
Normal file
25
.github/workflows/html5validator.yml.disabled
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: HTML5 Validator
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # Required will all actions
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.1
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
|
||||
- name: Jekyll build
|
||||
run: |
|
||||
bundle exec jekyll build --drafts --profile
|
||||
|
||||
- name: Checks HTML5 validity
|
||||
uses: Cyb3r-Jak3/html5validator-action@v7.2.0
|
||||
with:
|
||||
root: _site/
|
||||
blacklist: n r or ir
|
91
.github/workflows/test.yml
vendored
91
.github/workflows/test.yml
vendored
@ -1,91 +0,0 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
# Sources of supported versions:
|
||||
# * https://github.com/actions/python-versions/blob/main/versions-manifest.json
|
||||
# * https://downloads.python.org/pypy/versions.json
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- python-version: "3.12.0-alpha.3"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.11"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.10"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
- python-version: "3.10"
|
||||
with-opt-deps: false
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.9"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
- python-version: "pypy-3.9"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.8"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.7"
|
||||
with-opt-deps: true
|
||||
runs-on: ubuntu-22.04
|
||||
- python-version: "3.7"
|
||||
with-opt-deps: false
|
||||
runs-on: ubuntu-22.04
|
||||
- python-version: "pypy-3.7"
|
||||
with-opt-deps: false
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
- python-version: "3.6"
|
||||
with-opt-deps: false
|
||||
runs-on: ubuntu-20.04
|
||||
- python-version: "pypy-3.6"
|
||||
with-opt-deps: false
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Upgrade pip
|
||||
run: |
|
||||
python3 -m pip install --upgrade pip
|
||||
|
||||
- name: Install optional dependencies
|
||||
if: ${{ matrix.with-opt-deps }}
|
||||
run: |
|
||||
python3 -m pip install --upgrade pip
|
||||
pip3 install -r requirements.txt
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
LIMNORIA_WARN_OLD_PYTHON=0 python3 setup.py install
|
||||
|
||||
- name: Test with unittest
|
||||
run: |
|
||||
supybot-test test -v --plugins-dir=./plugins/ --no-network
|
||||
|
||||
- name: Test with irctest
|
||||
if: "${{ matrix.with-opt-deps && matrix.python-version != 'pypy-3.7' && matrix.python-version != 'pypy-3.9' }}"
|
||||
run: |
|
||||
git clone https://github.com/ProgVal/irctest.git
|
||||
cd irctest
|
||||
pip3 install -r requirements.txt
|
||||
make limnoria PYTEST_ARGS=-vs
|
20
.gitignore
vendored
20
.gitignore
vendored
@ -23,18 +23,10 @@ supybot.egg-info/
|
||||
test-conf/
|
||||
test-data/
|
||||
test-logs/
|
||||
doc-conf/
|
||||
doc-data/
|
||||
doc-logs/
|
||||
src/version.py
|
||||
INSTALL
|
||||
README.txt
|
||||
conf/
|
||||
data/
|
||||
logs/
|
||||
*.conf
|
||||
*.conf.bak
|
||||
|
||||
# Intellij PyCharm / IDEA related files
|
||||
*.iml
|
||||
.idea
|
||||
_site
|
||||
.sass-cache
|
||||
vendor/
|
||||
.bundle
|
||||
node_modules/
|
||||
pnpm-lock.yaml
|
||||
|
27
.mailmap
27
.mailmap
@ -1,27 +0,0 @@
|
||||
<jamessan@users.sourceforge.net> <vega.james@gmail.com>
|
||||
<jemfinch@users.sourceforge.net> <jemfinch@finchers.us>
|
||||
<jemfinch@users.sourceforge.net> <jfincher@monoid.(none)>
|
||||
<mikaela.suomalainen@outlook.com> <Mkaysi@users.noreply.github.com>
|
||||
<nyuszika7h@openmailbox.org> <liemininyuszika@gmail.com>
|
||||
<nyuszika7h@openmailbox.org> <litemininyuszika@gmail.com>
|
||||
<nyuszika7h@openmailbox.org> <nyuszika7h@cadoth.co>
|
||||
<nyuszika7h@openmailbox.org> <nyuszika7h@cadoth.net>
|
||||
<nyuszika7h@openmailbox.org> <nyuszika7h@gmail.com>
|
||||
<nyuszika7h@openmailbox.org> <nyuszika7h@outlook.com>
|
||||
<progval@progval.net> <progval+github@progval.net>
|
||||
<progval@progval.net> <progval@gmail.com>
|
||||
<shadowninja@minetest.net> <ShadowNinja@users.noreply.github.com>
|
||||
Daniel Folkinshteyn <nanotube@users.sourceforge.net> Daniel F <dfolkins@a90.(none)>
|
||||
Daniel Folkinshteyn <nanotube@users.sourceforge.net> nanotube <nanotube@users.sf.net>
|
||||
James Lu <james@overdrivenetworks.com> <GLolol1@hotmail.com>
|
||||
James Lu <james@overdrivenetworks.com> <glolol1@hotmail.com>
|
||||
James Lu <james@overdrivenetworks.com> <glolol@overdrive.pw>
|
||||
James Lu <james@overdrivenetworks.com> <GLolol@overdrivenetworks.com>
|
||||
James McCoy <jamessan@users.sourceforge.net>
|
||||
Ken Spencer <ken@electrocode.net> Iota Spencer <iota@electrocode.net>
|
||||
Mikaela Suomalainen <mikaela.suomalainen@outlook.com> Mika Suomalainen <mika.henrik.mainio@hotmail.com>
|
||||
Mikaela Suomalainen <mikaela.suomalainen@outlook.com> Mika Suomalainen <mkaysi@outlook.com>
|
||||
Mikaela Suomalainen <mikaela.suomalainen@outlook.com> Mika Suomalainen <mkaysi@users.sourceforge.net>
|
||||
Mikaela Suomalainen <mikaela.suomalainen@outlook.com> Mika Suomalainen <s.mika95@gmail.com>
|
||||
Mikaela Suomalainen <mikaela.suomalainen@outlook.com> Mikaela Suomalainen <mkaysi@outlook.com>
|
||||
Tannn3r <tannn3r@gmail.com> <tanman8r@gmail.com>
|
87
.pre-commit-config.yaml
Normal file
87
.pre-commit-config.yaml
Normal file
@ -0,0 +1,87 @@
|
||||
# @format
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Aminda Suomalainen <suomalainen+git@mikaela.info>
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.ci for more information
|
||||
ci:
|
||||
# I don't need so many duplicated notifications on the same thing as I keep
|
||||
# autoupdating manually too. Besides it just creates extra branch I never
|
||||
# touch.
|
||||
# https://github.com/pre-commit-ci/issues/issues/83
|
||||
autoupdate_schedule: quarterly
|
||||
skip: [pnpm-install-dev, prettier]
|
||||
|
||||
# Use pypy3 for the Python hooks. Except don't, see .gitlab-ci.yml
|
||||
#default_language_version:
|
||||
# python: pypy3
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
args: ["--markdown-linebreak-ext", "md,markdown"]
|
||||
exclude_types: [svg, tsv]
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-json
|
||||
- id: check-merge-conflict
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: destroyed-symlinks
|
||||
- id: detect-private-key
|
||||
- id: fix-byte-order-marker
|
||||
- id: check-merge-conflict
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=auto]
|
||||
- id: pretty-format-json
|
||||
args: [--autofix, --no-ensure-ascii]
|
||||
|
||||
- repo: https://github.com/pre-commit-ci/pre-commit-ci-config
|
||||
rev: v1.6.1
|
||||
hooks:
|
||||
- id: check-pre-commit-ci-config
|
||||
|
||||
- repo: https://github.com/thlorenz/doctoc
|
||||
rev: v2.2.0
|
||||
hooks:
|
||||
- id: doctoc
|
||||
args: [--update-only, --notitle]
|
||||
|
||||
- repo: https://github.com/python-jsonschema/check-jsonschema
|
||||
rev: 0.28.6
|
||||
hooks:
|
||||
- id: check-dependabot
|
||||
- id: check-github-workflows
|
||||
- id: check-gitlab-ci
|
||||
|
||||
# - repo: https://github.com/fsfe/reuse-tool
|
||||
# rev: v3.0.2
|
||||
# hooks:
|
||||
# - id: reuse
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pnpm-install-dev
|
||||
name: Install pnpm dev dependencies
|
||||
entry: corepack pnpm install -D
|
||||
language: system
|
||||
always_run: true
|
||||
#verbose: true
|
||||
pass_filenames: false
|
||||
- id: prettier
|
||||
name: prettier
|
||||
entry: corepack pnpm exec prettier --cache --ignore-unknown --write
|
||||
language: system
|
||||
|
||||
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
|
||||
rev: "2.7.3"
|
||||
hooks:
|
||||
- id: editorconfig-checker
|
||||
alias: ec
|
||||
args: [-disable-max-line-length]
|
5
.prettierignore
Normal file
5
.prettierignore
Normal file
@ -0,0 +1,5 @@
|
||||
_includes/
|
||||
_layouts/
|
||||
_sass/
|
||||
css/
|
||||
feed.xml
|
7
.prettierrc
Normal file
7
.prettierrc
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"insertPragma": true,
|
||||
"proseWrap": "always",
|
||||
"singleAttributePerLine": true,
|
||||
"plugins": ["prettier-plugin-sh"],
|
||||
"overrides": [{ "files": ".prettierrc", "options": { "parser": "json" } }]
|
||||
}
|
1
.ruby-version
Normal file
1
.ruby-version
Normal file
@ -0,0 +1 @@
|
||||
3.3.3
|
4
.travis.yml
Normal file
4
.travis.yml
Normal file
@ -0,0 +1,4 @@
|
||||
# @format
|
||||
|
||||
language: ruby
|
||||
script: "bundle exec jekyll build"
|
@ -1,37 +0,0 @@
|
||||
# Contributing to Limnoria
|
||||
|
||||
## Guidelines
|
||||
|
||||
Follow the [Style Guidelines].
|
||||
|
||||
When adding a string that will be shown on IRC, always internationalize
|
||||
it (wrap it in a call to `_()`).
|
||||
When making a trivial change to an internationalized string that does not
|
||||
affect the meaning of the string (typo fix, etc.), please update the
|
||||
`msgid` entry in localization file. It helps preserve the translation
|
||||
without the translator having to review it.
|
||||
|
||||
Last rule: you shouldn't add a mandatory dependency. Limnoria does not
|
||||
come with any (besides Python), so please try to keep all dependencies
|
||||
optional.
|
||||
|
||||
[Style Guidelines]:https://limnoria.readthedocs.io/en/latest/develop/style.html
|
||||
|
||||
## Sending patches
|
||||
|
||||
When you send a pull request, **send it to the testing branch**.
|
||||
It will be merged to master when it's considered to be stable enough to be
|
||||
supported.
|
||||
|
||||
Don't fear that you spam Limnoria by sending many pull requests. According
|
||||
to @ProgVal, it's easier for them to accept pull requests than to
|
||||
cherry-pick everything manually.
|
||||
|
||||
Having at least one test case in any non-trivial pull-request
|
||||
is very appreciated.
|
||||
|
||||
See also [Contributing to Limnoria] at [Limnoria documentation].
|
||||
|
||||
[Contributing to Limnoria]:https://limnoria.readthedocs.io/en/latest/contribute/index.html
|
||||
|
||||
[Limnoria documentation]:https://limnoria.readthedocs.io/
|
8
Gemfile
Normal file
8
Gemfile
Normal file
@ -0,0 +1,8 @@
|
||||
source "https://rubygems.org"
|
||||
ruby file: ".ruby-version"
|
||||
# For now this is a GitHub Pages hosted website.
|
||||
# Ref: https://github.com/Mikaela/mikaela.github.io/issues/153
|
||||
gem 'github-pages', group: :jekyll_plugins
|
||||
gem 'jekyll-seo-tag'
|
||||
# Required for `bundle exec jekyll serve`
|
||||
gem "webrick"
|
274
Gemfile.lock
Normal file
274
Gemfile.lock
Normal file
@ -0,0 +1,274 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (7.1.3.4)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
base64 (0.2.0)
|
||||
bigdecimal (3.1.8)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.23.10)
|
||||
concurrent-ruby (1.3.3)
|
||||
connection_pool (2.4.1)
|
||||
dnsruby (1.72.1)
|
||||
simpleidn (~> 0.2.1)
|
||||
drb (2.2.1)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.9.1)
|
||||
faraday (2.9.2)
|
||||
faraday-net_http (>= 2.0, < 3.2)
|
||||
faraday-net_http (3.1.0)
|
||||
net-http
|
||||
ffi (1.17.0-x86_64-linux-gnu)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (4.1.0)
|
||||
github-pages (231)
|
||||
github-pages-health-check (= 1.18.2)
|
||||
jekyll (= 3.9.5)
|
||||
jekyll-avatar (= 0.8.0)
|
||||
jekyll-coffeescript (= 1.2.2)
|
||||
jekyll-commonmark-ghpages (= 0.4.0)
|
||||
jekyll-default-layout (= 0.1.5)
|
||||
jekyll-feed (= 0.17.0)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.16.1)
|
||||
jekyll-include-cache (= 0.2.1)
|
||||
jekyll-mentions (= 1.6.0)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.16.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.3)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.8.0)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.2.0)
|
||||
jekyll-theme-cayman (= 0.2.0)
|
||||
jekyll-theme-dinky (= 0.2.0)
|
||||
jekyll-theme-hacker (= 0.2.0)
|
||||
jekyll-theme-leap-day (= 0.2.0)
|
||||
jekyll-theme-merlot (= 0.2.0)
|
||||
jekyll-theme-midnight (= 0.2.0)
|
||||
jekyll-theme-minimal (= 0.2.0)
|
||||
jekyll-theme-modernist (= 0.2.0)
|
||||
jekyll-theme-primer (= 0.6.0)
|
||||
jekyll-theme-slate (= 0.2.0)
|
||||
jekyll-theme-tactile (= 0.2.0)
|
||||
jekyll-theme-time-machine (= 0.2.0)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.13.0)
|
||||
kramdown (= 2.4.0)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.4)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.13.6, < 2.0)
|
||||
rouge (= 3.30.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.18.2)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (>= 4, < 8)
|
||||
public_suffix (>= 3.0, < 6.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.14.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.9.5)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (>= 0.7, < 2)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (>= 1.17, < 3)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (>= 1.7, < 4)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-avatar (0.8.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-coffeescript (1.2.2)
|
||||
coffee-script (~> 2.2)
|
||||
coffee-script-source (~> 1.12)
|
||||
jekyll-commonmark (1.4.0)
|
||||
commonmarker (~> 0.22)
|
||||
jekyll-commonmark-ghpages (0.4.0)
|
||||
commonmarker (~> 0.23.7)
|
||||
jekyll (~> 3.9.0)
|
||||
jekyll-commonmark (~> 1.4.0)
|
||||
rouge (>= 2.0, < 5.0)
|
||||
jekyll-default-layout (0.1.5)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-feed (0.17.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.16.1)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (>= 4, < 7, != 4.4.0)
|
||||
jekyll-include-cache (0.2.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-mentions (1.6.0)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.3)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.8.0)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
jekyll-theme-architect (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-cayman (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-dinky (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-merlot (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-midnight (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-minimal (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-modernist (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.6.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-slate (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-tactile (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-time-machine (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.13.0)
|
||||
gemoji (>= 3, < 5)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.4)
|
||||
listen (3.9.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.24.1)
|
||||
mutex_m (0.2.0)
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
nokogiri (1.16.6-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (5.1.1)
|
||||
racc (1.8.0)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.11.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.3.1)
|
||||
strscan
|
||||
rouge (3.30.0)
|
||||
rubyzip (2.3.2)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sawyer (0.9.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
simpleidn (0.2.3)
|
||||
strscan (3.1.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
typhoeus (1.4.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (1.8.0)
|
||||
uri (0.13.0)
|
||||
webrick (1.8.1)
|
||||
|
||||
PLATFORMS
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages
|
||||
jekyll-seo-tag
|
||||
webrick
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.3.3p89
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.11
|
28
LICENSE.md
28
LICENSE.md
@ -1,28 +0,0 @@
|
||||
Copyright (c) 2002-2009 Jeremiah Fincher and others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author of this software nor the name of
|
||||
contributors to this software may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Portions of the included source code are copyright by its original author(s)
|
||||
and remain subject to its associated license.
|
@ -1,6 +0,0 @@
|
||||
include LICENSE.md
|
||||
include README.md
|
||||
include Makefile
|
||||
include .travis.yml
|
||||
include requirements.txt
|
||||
include test/*.py
|
42
Makefile
42
Makefile
@ -1,42 +0,0 @@
|
||||
PYTHON=`which python3`
|
||||
DESTDIR=/
|
||||
PROJECT=limnoria
|
||||
|
||||
all:
|
||||
@echo "make source - Create source package"
|
||||
@echo "make install - Install on local system"
|
||||
@echo "make buildrpm - Generate a rpm package"
|
||||
@echo "make builddeb_py2 - Generate a deb package for Python 2"
|
||||
@echo "make builddeb_py3 - Generate a deb package for Python 3"
|
||||
@echo "make clean - Get rid of scratch and byte files"
|
||||
|
||||
test:
|
||||
PATH=./scripts/:${PATH} PYTHONPATH=. $(PYTHON) ./scripts/supybot-test test --plugins-dir=plugins/
|
||||
|
||||
source:
|
||||
$(PYTHON) setup.py sdist $(COMPILE)
|
||||
|
||||
install:
|
||||
$(PYTHON) setup.py install --root $(DESTDIR) $(COMPILE)
|
||||
|
||||
buildrpm:
|
||||
$(PYTHON) setup.py bdist_rpm
|
||||
|
||||
builddeb_py2:
|
||||
cp debian/control.py2 debian/control
|
||||
debuild -us -uc
|
||||
rm debian/control
|
||||
|
||||
builddeb_py3:
|
||||
cp debian/control.py3 debian/control
|
||||
debuild -us -uc
|
||||
rm debian/control
|
||||
|
||||
clean:
|
||||
$(PYTHON) setup.py clean
|
||||
$(MAKE) -f $(CURDIR)/debian/rules clean
|
||||
rm -rf build/ MANIFEST
|
||||
find . -name '*.pyc' -delete
|
||||
rm debian/control
|
||||
|
||||
.PHONY: test
|
66
README.md
66
README.md
@ -1,63 +1,11 @@
|
||||
Limnoria is a multipurpose Python IRC bot, designed for flexibility and robustness,
|
||||
while being easy to install, set up, and maintain.
|
||||
<!-- @format -->
|
||||
|
||||
It aims to be an adequate replacement for most existing IRC bots.
|
||||
It includes a very flexible and powerful
|
||||
[ACL system](https://docs.limnoria.net/use/capabilities.html)
|
||||
for controlling access to commands,
|
||||
an equality powerful
|
||||
[configuration system](https://docs.limnoria.net/use/configuration.html)
|
||||
to customize your bot,
|
||||
as well as more than 60 builtin [plugins](https://limnoria.net/plugins.xhtml)
|
||||
providing around 400 actual commands.
|
||||
# Mikaela's fork of Limnoria.
|
||||
|
||||
There are also dozens of third-party [plugins](https://limnoria.net/plugins.xhtml)
|
||||
written by dozens of independent developers,
|
||||
and it is very easy to
|
||||
[write your own](https://docs.limnoria.net/develop/plugin_tutorial.html)
|
||||
with only basic knowledge of Python.
|
||||
There are mainly two branches. This one which you are looking at, gh-pages which
|
||||
is the source of <https://supybot.mikaela.info/>.
|
||||
|
||||
It is the successor of
|
||||
[Supybot](https://sourceforge.net/projects/supybot/)
|
||||
since 2010 and provides many new features, but keeps full compatibility
|
||||
with existing configurations and plugins.
|
||||
|
||||
# Support
|
||||
|
||||
## Documentation
|
||||
|
||||
If this is your first install, there is an [install guide](https://docs.limnoria.net/en/latest/use/install.html).
|
||||
You will probably be pointed to it if you ask on IRC how to install
|
||||
Limnoria.
|
||||
TL;DR version:
|
||||
|
||||
```
|
||||
sudo apt-get install python3 python3-pip python3-wheel
|
||||
pip3 install --user limnoria
|
||||
# You might need to add $HOME/.local/bin to your PATH
|
||||
supybot-wizard
|
||||
```
|
||||
|
||||
There is extensive documentation at [docs.limnoria.net] and at
|
||||
[Gribble wiki]. We took the time to write it; you should take the time to
|
||||
read it.
|
||||
|
||||
[docs.limnoria.net]:https://docs.limnoria.net/
|
||||
[Gribble wiki]:https://sourceforge.net/p/gribble/wiki/Main_Page/
|
||||
|
||||
## IRC channels
|
||||
|
||||
### In English
|
||||
|
||||
If you have any trouble, feel free to swing by [#limnoria](ircs://irc.libera.chat:6697/#limnoria) on
|
||||
[Libera.Chat](https://libera.chat/) and ask questions. We'll be happy to help
|
||||
wherever we can. And by all means, if you find anything hard to
|
||||
understand or think you know of a better way to do something,
|
||||
*please* post it on the [issue tracker] so we can improve the bot!
|
||||
|
||||
[issue tracker]:https://github.com/ProgVal/Limnoria/issues
|
||||
|
||||
### In Other languages
|
||||
|
||||
Only in French at the moment, located at [#limnoria-fr on Libera.Chat](ircs://irc.libera.chat:6697/#libera-fr).
|
||||
**testing** which will be synced with [ProgVal/Limnoria] when needed. It is used
|
||||
as base for my changes which will be pull requested.
|
||||
|
||||
[ProgVal/Limnoria]: https://github.com/ProgVal/Limnoria.git
|
||||
|
435
RELNOTES
435
RELNOTES
@ -1,435 +0,0 @@
|
||||
Version 0.83.5
|
||||
|
||||
The minimum supported Python version has been bumped to 2.6.
|
||||
|
||||
utils.str.perlVariableSubstitute is deprecated in favor of using Python's
|
||||
string.Template directly. perlVariableSubstitute will be removed in a future
|
||||
release.
|
||||
|
||||
Factoids' config variable supybot.plugins.Factoids.factoidPrefix has been
|
||||
replaced by supybot.plugins.Factoids.format, which allows the user to
|
||||
determine exactly how replies to Factoid queries are formatted.
|
||||
|
||||
supybot-botchk no longer runs supybot inside an instance of /bin/sh.
|
||||
|
||||
|
||||
Version 0.83.4.1
|
||||
|
||||
Simple bug-fix release for a couple changes that were introduced last minute
|
||||
before the previous release.
|
||||
|
||||
No incompatibilities.
|
||||
|
||||
|
||||
Version 0.83.4
|
||||
|
||||
This release contains fixes for Python2.6 compability as well as a re-written
|
||||
Google plugin which uses the AJAX API. The re-written plugin gained a
|
||||
translate command and no longer needs an API key.
|
||||
|
||||
ChannelLogger has a new config variable, supybot.plugins.ChannelLogger.enable,
|
||||
which can be used on a per-channel basis to determine whether that channel is
|
||||
logged.
|
||||
|
||||
The RSS announce command has been restructured into the commands "announce
|
||||
list", "announce remove", and "announce add" in order to simplify the
|
||||
command's use.
|
||||
|
||||
The supybot.directories.plugins config variable now determines its global
|
||||
directory dynamically instead of adding the directory to the value. This
|
||||
means values like '/usr/lib/python2.5/site-packages/supybot/plugins' can be
|
||||
removed from the variable. This should help ease transitioning a Supybot
|
||||
config from one Python release to another.
|
||||
|
||||
Incompatibilities:
|
||||
supybot.plugins.Google.safeSearch has been renamed to
|
||||
supybot.plugins.Google.searchFilter
|
||||
|
||||
supybot.plugins.Channel.banmask has been removed in favor of a new
|
||||
supybot.protocols.irc.banmask config variable. This general config variable
|
||||
is used by the various commands which would need to know what style of banmask
|
||||
to use.
|
||||
|
||||
Version 0.83.3
|
||||
|
||||
Overdue bug fix and Python2.5-compatible release. No significant changes to
|
||||
worry about from the user perspective.
|
||||
|
||||
|
||||
Version 0.83.2
|
||||
|
||||
Mainly bug fix release. The most noticeable change being a value of
|
||||
'default' for supybot.drivers.module will use Socket instead of Twisted.
|
||||
|
||||
|
||||
Version 0.83.1
|
||||
|
||||
No incompatibilities, just fixing an important bug with plugin loading.
|
||||
|
||||
|
||||
Version 0.83.0
|
||||
|
||||
This far overdue release contains mostly bug-fixes.
|
||||
|
||||
Incompatibilities:
|
||||
Changed the prefixName keyword argument (which appears in various places
|
||||
in callbacks.py and the reply-related irc methods) to prefixNick.
|
||||
|
||||
|
||||
Version 0.83.0rc3
|
||||
|
||||
This release candidate contains mostly bug-fixes.
|
||||
|
||||
Incompatibilities:
|
||||
utils.changeFunctionName was moved to utils.python.changeFunctionName
|
||||
|
||||
|
||||
Version 0.83.0rc2
|
||||
|
||||
This release candidate contains a few bug-fixes and some plugins we
|
||||
forgot in the last RC. Otherwise, everything is compatible.
|
||||
|
||||
|
||||
Version 0.83.0rc1
|
||||
|
||||
There have been some fairly significant changes since our last release.
|
||||
This means that you should uninstall your previous version before
|
||||
installing this version.
|
||||
|
||||
First, plugins are now a directory of files rather than a single file.
|
||||
This makes it much easier for an individual plugin to supply any
|
||||
3rd-party modules it may depend on and resolves some bugs we had with
|
||||
reloading plugins. supybot-plugin-create (nee supybot-newplugin) has
|
||||
been updated to reflect this. A side effect of using a directory-based
|
||||
plugin is that @load/@reload are now case-sensitive. "@load foo" is not
|
||||
the same as "@load Foo".
|
||||
|
||||
As part of the conversion to the new plugin format, some plugins were
|
||||
broken up into more focused plugins. Also, not all of the plugins that
|
||||
we used to ship are part of this release. Some we moved to the
|
||||
supybot-plugins package and some others (which would be candidates for
|
||||
supybot-plugins) have yet to be converted to the new format.
|
||||
|
||||
Second, we've updated the scripts that ship with Supybot. As noted in
|
||||
the previous section, supybot-newplugin is now named
|
||||
supybot-plugin-create. We've also added the following scripts:
|
||||
|
||||
supybot-botchk - Handy script for starting the bot and keeping it
|
||||
running. Ideal for having cron automatically start the
|
||||
bot.
|
||||
supybot-plugin-doc - Generates documentation for the specified
|
||||
plugin(s). Currently, the documentation is
|
||||
generated using Structured TeXt so that it can
|
||||
easily be uploaded to our website.
|
||||
supybot-plugin-package - The beginning of a script to make a plugin
|
||||
package which can be uploaded to our website
|
||||
for general consumption.
|
||||
supybot-test - Runs a plugin's test suite.
|
||||
|
||||
Third, we've broken supybot.utils into focused sub-modules. There's no
|
||||
longer a supybot.fix module and we now have the following modules:
|
||||
|
||||
supybot.utils.file - utilities for dealing with files (e.g. the old
|
||||
supybot.utils.transactionalFile is now
|
||||
supybot.utils.file.AtomicFile)
|
||||
supybot.utils.iter - utilities for dealing with iterables (all, any,
|
||||
partition, groupBy, choice, etc)
|
||||
supybot.utils.gen - general purpose utilities which are imported into
|
||||
the supybot.utils namespace
|
||||
supybot.utils.net - utilities for dealing with the network
|
||||
supybot.utils.python - utilities for dealing with Python
|
||||
supybot.utils.seq - utilities for dealing with sequences
|
||||
supybot.utils.str - utilities for dealing with strings (including our
|
||||
new format() function)
|
||||
supybot.utils.structures - general purpose structures used in Supybot
|
||||
supybot.utils.web - utilities for dealing with the web (used to be
|
||||
supybot.webutils)
|
||||
|
||||
Fourth, we've added source-nested plugins (using the class
|
||||
callbacks.Commands). This allows you to group similar commands
|
||||
together. Some examples are:
|
||||
|
||||
Channel.{ban add,ban list,ban remove}
|
||||
User.{hostmask add,hostmask list,hostmask remove}
|
||||
|
||||
Fifth, we've removed the privmsgs module. All of the functionality
|
||||
that was offered in that module is now available by using commands.wrap.
|
||||
Use of this is documented at:
|
||||
http://supybot.com/documentation/help/tutorial/wrap
|
||||
|
||||
Sixth, we've renamed some plugin-related API changes. Some classes had
|
||||
their names changed. The old names are still available for
|
||||
backwards-compatibility.
|
||||
|
||||
callbacks.Privmsg -> callbacks.Plugin
|
||||
callbacks.PrivmsgCommandAndRegexp -> callbacks.PluginRegexp
|
||||
callbacks.IrcObjectProxy -> callbacks.NestedCommandsIrcProxy
|
||||
|
||||
callbacks.PrivmsgRegexp was removed since its functionality is covered
|
||||
by setting using PluginRegexp.
|
||||
|
||||
Also, the prototype for a plugin's __init__ method changed:
|
||||
|
||||
def __init__(self): -> def __init__(self, irc):
|
||||
|
||||
Remember to pass the irc object on when you call the parent class's
|
||||
__init__ method.
|
||||
|
||||
|
||||
Version 0.80.0
|
||||
|
||||
We *finally* hit 0.80.0! This release is completely compatible with
|
||||
the last release candidate.
|
||||
|
||||
An update to Babelfish may cause an error message to be displayed in
|
||||
the console when the bot is first run. The error message should be
|
||||
gone when the bot is restarted.
|
||||
|
||||
We also have a new community website at http://www.supybot.com/ where
|
||||
our users can submit their own plugins, view/download other people's
|
||||
plugins and discuss all things Supybot-related.
|
||||
|
||||
|
||||
Version 0.80.0rc3
|
||||
|
||||
Another bugfix release. This one was pretty important as it actually
|
||||
makes supybot.database.plugins.channelSpecific work properly.
|
||||
|
||||
|
||||
Version 0.80.0rc2
|
||||
|
||||
supybot.databases.plugins.channelSpecific.channel was renamed to
|
||||
supybot.databases.plugins.channelSpecific.link.
|
||||
|
||||
supybot.databases.plugins.channelSpecific.link.allow was added, which
|
||||
determines whether a channel will allow other channels to link to its
|
||||
database.
|
||||
|
||||
Infobot is no longer deprecated and the following changes were made to
|
||||
its config variables:
|
||||
supybot.plugins.Infobot.answerUnaddressedQuestions was renamed to
|
||||
supybot.plugins.Infobot.unaddressed.answerQuestions.
|
||||
supybot.plugins.Infobot.snarfUnaddressedDefinitions was renamed to
|
||||
supybot.plugins.Infobot.unaddressed.snarfDefinitions.
|
||||
supybot.plugins.Infobot.unaddressed.replyExistingFactoid was added to
|
||||
determine whether the bot will reply when someone attempts to create a
|
||||
duplicate factoid.
|
||||
|
||||
|
||||
Version 0.80.0pre6
|
||||
|
||||
Another bugfix release. No incompatibilities known. The only
|
||||
registry change is that supybot.databases.users.hash has been
|
||||
removed.
|
||||
|
||||
|
||||
Version 0.80.0pre5
|
||||
|
||||
Completely bugfix release. No incompatibilies known.
|
||||
|
||||
|
||||
Version 0.80.0pre4
|
||||
|
||||
Mainly a bug fix release. This will likely be the last release before
|
||||
0.80.0final, but we're gonna let it stew for a couple weeks to attempt
|
||||
to catch any lingering bugs.
|
||||
|
||||
ansycoreDrivers is now deprecated in favor of socketDrivers or
|
||||
twistedDrivers.
|
||||
|
||||
supybot.databases.plugins.channelSpecific.channel is now a channelValue
|
||||
so that you can link specific channels together (instead of all channels
|
||||
being linked together).
|
||||
|
||||
For those of you that use eval and/or exec, they have been removed from
|
||||
the Owner plugin and are now in sandbox/Debug.py (which you'll have to
|
||||
grab from CVS).
|
||||
|
||||
|
||||
Version 0.80.0pre3
|
||||
|
||||
The database format for the Note plugin has changed to a flatfile
|
||||
format; use tools/noteConvert.py to convert it to the new format.
|
||||
|
||||
Ditto that for the URL database.
|
||||
|
||||
FunDB is deprecated and will be removed at the next major release;
|
||||
use tools/fundbConvert.py to convert your old FunDB databases to Lart
|
||||
and Praise databases.
|
||||
|
||||
If you had turned off supybot.databases.plugins.channelSpecific, your
|
||||
non-channel-specific database files had gone directly into your data/
|
||||
directory. We had some problems with poor interactions between that
|
||||
configuration variable and channel capabilities, though, so we
|
||||
changed the implementation so that non-channel-specific databases are
|
||||
considered databases of a single (configurable) channel (defaulting
|
||||
to "#"). This will also help others who are converting from
|
||||
channel-specific to non-channel-specific databases, but for you
|
||||
who've already made the switch, you'll need to move your database
|
||||
files again, from data/ to data/# (or whatever channel you might
|
||||
change that variable to).
|
||||
|
||||
supybot.channels doesn't exist anymore; now the only list of channels
|
||||
to join is per-network, in supybot.networks.<network>.channels.
|
||||
|
||||
We weren't serializing supybot.replies.* properly in older versions.
|
||||
Now we are, but the old, improperly serialized versions won't work
|
||||
properly. Remove from your configuration file all variables
|
||||
beginning with "supybot.replies" before you start the bot.
|
||||
|
||||
The URL database has been changed again, but it will use a different
|
||||
filename so you shouldn't run into conflicts, just a newly-empty
|
||||
database.
|
||||
|
||||
We upgraded the SOAP stuff in others; you may do well to do a
|
||||
setup.py install --clean this time around.
|
||||
|
||||
|
||||
Version 0.80.0pre2
|
||||
|
||||
Many more bugs have been fixed. A few more plugins have been updated
|
||||
to use our new-style database abstraction. If it seems like your
|
||||
databases are suddenly empty, look for a new database file named
|
||||
Plugin.dbtype.db. We've also added a few more configuration variables.
|
||||
|
||||
|
||||
Version 0.80.0pre1
|
||||
|
||||
Tons of bugs fixed, many features and plugins added. Everything
|
||||
should be entirely compatible; many more configuration variables have
|
||||
been added.
|
||||
|
||||
|
||||
Version 0.79.9999
|
||||
|
||||
Some more bugs fixed, added a few features and a couple configuration
|
||||
variabless. This should hopefully be the last release before 0.80.0,
|
||||
which will finally bring us to pure Beta status.
|
||||
|
||||
|
||||
Version 0.79.999
|
||||
|
||||
Some bugs fixed, but the ones that were fixed were pretty big. This
|
||||
is, of course, completely compatible with the last release.
|
||||
|
||||
|
||||
Version 0.79.99
|
||||
|
||||
Many bugs fixed, thanks to the users who reported them. We're
|
||||
getting asymptotically closer to 0.80.0 -- maybe this'll be the last
|
||||
one, maybe we'll have to release an 0.79.999 -- either way, we're
|
||||
getting close :) Check out the ChangeLog for the fixes and a few new
|
||||
features.
|
||||
|
||||
|
||||
Version 0.79.9
|
||||
|
||||
We've changed so much stuff in this release that we've given up on
|
||||
users upgrading their configuration files for the new release. So
|
||||
do a clean install (python2.3 setup.py install --clean), run the
|
||||
wizard again, and kick some butt.
|
||||
|
||||
(It's rumored that you can save most of your old configuration by
|
||||
appending your new configuration at the end of your old configuration
|
||||
and running supybot with that new configuration file. This, of
|
||||
course, comes with no warranty or guarantee of utility -- try it if
|
||||
you want, but backup your original configuration file!)
|
||||
|
||||
|
||||
Version 0.77.2
|
||||
|
||||
This is a drop-in replacement for 0.77.1, with two exceptions. The
|
||||
configuration variable formerly known as
|
||||
"supybot.plugins.Services.password" is now known as
|
||||
"supybot.plugins.Services.NickServ.password", due to the fact that
|
||||
there might be different passwords for NickServ and ChanServ (and
|
||||
ChanServ passwords are per-channel, whereas NickServ passwords are
|
||||
global). If you're using the Services plugin, you'll need to make
|
||||
this change in order to continue identifying with services. The
|
||||
configuration variable formerly known as
|
||||
"supybot.plugins.Babelfish.disabledLanguages" is now known as
|
||||
"supybot.plugins.Babelfish.languages". The configuration variable now
|
||||
accepts the languages that *will* be translated as opposed to ones
|
||||
that are *not* translated.
|
||||
|
||||
Tests and the developer sandbox are not longer delivered with our
|
||||
release tarballs. If you're a developer and you want these, you
|
||||
should either check out CVS or download one of our weekly CVS
|
||||
snapshots, available at http://supybot.sourceforge.net/snapshots/ .
|
||||
|
||||
|
||||
Version 0.77.1
|
||||
|
||||
This is a drop-in replacement for 0.77.0 -- no incompatibilities, to
|
||||
out knowledge. Simply install over your old installation and restart
|
||||
your bot :)
|
||||
|
||||
|
||||
Version 0.77.0
|
||||
|
||||
Setup.py will automatically remove your old installations for you, no
|
||||
need to worry about that yourself.
|
||||
|
||||
Configuration has been *entirely* redone. Read the new
|
||||
GETTING_STARTED document to see how to work with configuration
|
||||
variables now. Your old botscripts from earlier versions *will not*
|
||||
work with the new configuration method. We'd appreciate it if you'd
|
||||
rerun the wizard in order for us to find any bugs that remain in it
|
||||
before we officially declare ourselves Beta. Note also that because
|
||||
of the new configuration method, the interface for plugins' configure
|
||||
function has changed: there are no longer any onStart or afterConnect
|
||||
arguments, so all configuration should be performed via the registry.
|
||||
|
||||
Channel capabilities have been changed; rather than being
|
||||
#channel.capability, they're now #channel,capability. It's a bit
|
||||
uglier, we know, but dots can be valid in channel names, and we
|
||||
needed the dot for handling plugin.command capabilities.
|
||||
tools/ircdbConvert.py should update this for you.
|
||||
|
||||
The on-disk format of the user/channel databases has changed to be far
|
||||
more readable. A conversion utility is included, as mentioned before:
|
||||
tools/ircdbConvert.py. Run this with no arguments to see the
|
||||
directions for using it.
|
||||
|
||||
Uh, we were just kidding about the upgrade script in 0.76.0 :) It'll
|
||||
be a little while longer. We do have several little upgrade scripts,
|
||||
though.
|
||||
|
||||
|
||||
Version 0.76.1
|
||||
|
||||
Almost entirely bugfixes, just some minor (and some less minor) bugs
|
||||
that need to get in before we really start hacking on the next
|
||||
version. Should be *entirely* compatible with 0.76.0.
|
||||
|
||||
|
||||
Version 0.76.0
|
||||
|
||||
Major bugfix release. A great number of bugs fixed. This is the last
|
||||
release without an upgrade script.
|
||||
|
||||
The only hiccup in the upgrade from 0.75.0 should be that you'll need
|
||||
to update your botscript to reflect the removal of the debug module.
|
||||
We'd rather you use supybot-wizard to generate a new botscript, of
|
||||
course, but if you insist on modifying your existing botscript, take a
|
||||
look at
|
||||
<http://cvs.sourceforge.net/viewcvs.py/supybot/supybot/src/template.py?r1=1.20&r2=1.21>
|
||||
to see what you need to do.
|
||||
|
||||
|
||||
Version 0.75.0
|
||||
|
||||
Don't forget to reinstall (i.e., run "python setup.py install" as
|
||||
root). Sometimes it even does good to remove the old installation;
|
||||
$PYTHON/site-packages/supybot can be removed with no problems
|
||||
whatsoever.
|
||||
|
||||
You will need to re-run supybot-wizard and generate a new botscript.
|
||||
|
||||
The Infobot plugin has been removed from this release; it's not ready
|
||||
for prime time. If you're interested in getting it running (i.e., you
|
||||
want full Infobot compatibility and aren't satisfied with either
|
||||
MoobotFactoids or Factoids) then swing over to #supybot and we can
|
||||
discuss the tests. We simply don't know enough about Infobot to make
|
||||
sure our Infobot plugin is an exact replica, and need someone's help
|
||||
with making the changes necessary for that.
|
71
Relaybot.markdown
Normal file
71
Relaybot.markdown
Normal file
@ -0,0 +1,71 @@
|
||||
---
|
||||
layout: page
|
||||
title: Ignoring RelayBot
|
||||
permalink: /Relaybot.html
|
||||
---
|
||||
|
||||
<!-- @format -->
|
||||
|
||||
RelayBot is the bot which relays between #supybot,#limnoria at a couple of
|
||||
networks (TODO/FIXME, which ones?). It is currently using the
|
||||
[LinkRelay](https://github.com/ProgVal/Supybot-plugins/tree/master/LinkRelay)
|
||||
plugin to do this.
|
||||
|
||||
It's sometimes considered as annoyance as it has lately mostly spammed with join
|
||||
(part messages aren't working, because of a bug (2014-06-23)) messages of people
|
||||
who usually say nothing and this is why this page is here to tell how to ignore
|
||||
it on various client.
|
||||
|
||||
We(who? I?) encourage you to ignore only notices from RelayBot instead of
|
||||
everything as there are people whom should be heard at OFTC (mainly main Supybot
|
||||
developer). (TODO/FIXME: is this the case in 2021?)
|
||||
|
||||
Related links:
|
||||
|
||||
- [LinkRelay plugin](https://github.com/ProgVal/Supybot-plugins/tree/master/LinkRelay)
|
||||
- [Feature request for smart filtering of joins/quits/parts](https://github.com/ProgVal/Supybot-plugins/issues/66)
|
||||
- [Feature request for RELAYMSG for more native look&feel](https://github.com/ProgVal/Supybot-plugins/issues/338)
|
||||
|
||||
Hostmask of RelayBot on Libera.Chat 2021-06-06:
|
||||
|
||||
- `RelayBot!~limnoria@helium.progval.net`
|
||||
- This is absolute hostmask, also known as NUH (`nick!user@host`)
|
||||
- `RelayBot*!*@helium.progval.net`
|
||||
- This is recommended hostmask as it matches RelayBot even if it cannot use
|
||||
it's primary nickname or networks cannot connect to it's identd.
|
||||
|
||||
## HexChat
|
||||
|
||||
From the "Window" menu you can find "Ignore list". Click "Add" and add one of
|
||||
the hostmasks mentioned above (the lower is recommended).
|
||||
|
||||
Uncheck the other checkboxes than "Notice" and you can close the window and you
|
||||
won't see spamming.
|
||||
|
||||
## KVIRC
|
||||
|
||||
I am not primarily KVIRC user and I cannot say anything else than right click
|
||||
RelayBot and select something that matches only RelayBot.
|
||||
|
||||
**WARNING: KVIRC makes it very easy to also ignore pinkieval which you don't
|
||||
want to do as they are author of Limnoria and help people often!**
|
||||
|
||||
## Linkinus
|
||||
|
||||
According to another person, there is a GUI where you can easily ignore notices
|
||||
from specific hostmask.
|
||||
|
||||
## WeeChat
|
||||
|
||||
`/filter add relaybotnotices * irc_notice+nick_RelayBot *`
|
||||
|
||||
This creates a new filter with the name "relaybotnotices" which filters all
|
||||
notices from the nickname "RelayBot".
|
||||
|
||||
---
|
||||
|
||||
This page is very likely missing many IRC clients. Could you
|
||||
[open an issue](https://github.com/mikaela/limnoria/issues) about how to do this
|
||||
with your IRC client that isn't mentioned here?
|
||||
|
||||
---
|
145
Supybot.markdown
Normal file
145
Supybot.markdown
Normal file
@ -0,0 +1,145 @@
|
||||
---
|
||||
layout: page
|
||||
title: Security issues
|
||||
permalink: /Supybot.html
|
||||
---
|
||||
|
||||
<!-- @format -->
|
||||
|
||||
Supybot git repository was declared dead on 2018-05-10 and archived on GitHub.
|
||||
[v0.84.0 was the last release at that time](https://github.com/Supybot/Supybot/releases/tag/v0.84.0).
|
||||
0.83.4.1 used to be a very common release available through several Linux
|
||||
distributions for years and thus I made this page, which I guess is now
|
||||
available more of for historical reasons.
|
||||
|
||||
**_WARNING: most of the content originates from 2014!_**
|
||||
|
||||
## The issues of 0.83.4.1.
|
||||
|
||||
### 1. Anyone can crash it and computer where it's running on
|
||||
|
||||
And this is very easy. Just run the command
|
||||
|
||||
`!misc last --regexp m/(.*\w){512}/`
|
||||
|
||||
where ! is the prefix character.
|
||||
|
||||
Misc is loaded by default and cannot be unloaded without modifying the config.
|
||||
|
||||
- [Limnoria issue #157](https://github.com/ProgVal/Limnoria/issues/157)
|
||||
- Fixing commits:
|
||||
[3526d5d](https://github.com/ProgVal/Limnoria/commit/3526d5dabf587457a43af8bee8d4db21986e8222)
|
||||
&
|
||||
[e11dc28](https://github.com/ProgVal/Limnoria/commit/e11dc28025de877b1b6cf059013eef88337b7e44)
|
||||
- [Ubuntu bug #996947](https://bugs.launchpad.net/ubuntu/+source/supybot/+bug/996947)
|
||||
- [Debian bug #672214](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672214)
|
||||
|
||||
### 2. The previous wasn't the only way to do this
|
||||
|
||||
Everyone can also make the bot count an equation, which brings it and the host
|
||||
computer down.
|
||||
|
||||
For example:
|
||||
|
||||
`!math calc factorial(999999)`
|
||||
|
||||
This requires Math plugin which comes with Supybot, but isn't load by default.
|
||||
|
||||
- [Limnoria issue #354](https://github.com/ProgVal/Limnoria/issues/354)
|
||||
- Fixing commit:
|
||||
[695078e](https://github.com/ProgVal/Limnoria/commit/695078edeb91e5ff1eec728fedf0e0c27b55c505)
|
||||
- [Ubuntu bug #996950](https://bugs.launchpad.net/ubuntu/+source/supybot/+bug/996950)
|
||||
- [Debian bug 672215](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672215)
|
||||
|
||||
### 3. Anyone can access network services via the bot.
|
||||
|
||||
I don't have example command for this, but it happens by nesting "format cut"
|
||||
and "misc tell".
|
||||
|
||||
What does this mean? Anyone can tell the bot to ghost someone else on same
|
||||
account, take over a channel by telling the bot to give flags (if it has correct
|
||||
flags), change password of the account and everything else what you do with
|
||||
network services.
|
||||
|
||||
- _This was only reported at IRC and I am unable to find issue report or fixing
|
||||
commit. ~~Mikaela on 2015-01-04._
|
||||
|
||||
### 4. Web page with special characters in \<title\> can be used to send DCC/CTCP commands.
|
||||
|
||||
This doesn't mean only things like CTCP actions (also known as /me), but known
|
||||
problems with old routers ( `FF ? DCC SEND “ff???f??????????????” 0 0 0` ) which
|
||||
make them reconnect to the internet.
|
||||
|
||||
Usage:
|
||||
|
||||
- `!web title <malicious.page.here>`
|
||||
- `!web fetch <malicious.page.here>`
|
||||
|
||||
_This was only reported at IRC and I am unable to find issue report or fixing
|
||||
commit. ~~Mikaela on 2015-01-04._
|
||||
|
||||
### 5. Web Titlte/Fetch can be used for DoS
|
||||
|
||||
They are vulnerable to queries to servers which have custom headers which can
|
||||
lead to DoS.
|
||||
|
||||
_This was only reported at IRC and I am unable to find issue report or fixing
|
||||
commit. ~~Mikaela on 2015-01-04._
|
||||
|
||||
### 6. QuoteGrabs grab command also works in PM
|
||||
|
||||
and can grab private content such as `user register` or `user identify` or with
|
||||
the case of owner possibly NickServ passwords and others not so nice things.
|
||||
|
||||
- _It appears this issue was only reported at IRC._
|
||||
- Fixing commit:
|
||||
[a3346343679f3bdf8c77d9efb5a2097e215d51df](https://github.com/ProgVal/Limnoria/commit/a3346343679f3bdf8c77d9efb5a2097e215d51df)
|
||||
|
||||
### Are these issues publicly known?
|
||||
|
||||
**Of course they are.** Issue reports are below the actual issues.
|
||||
|
||||
The first issue has been also used to take down some of
|
||||
[Ubuntu IRC bots](https://wiki.ubuntu.com/IRC/Bots) several times. At least
|
||||
UbotX (I don't remember the number) and meetingology.
|
||||
|
||||
Some of these issues are fixed in git repository, but most people aren't using
|
||||
it. If you wish to start using it, please scroll down to installation
|
||||
instructions lower this page even though [Limnoria] and [gribble] are more
|
||||
recommended.
|
||||
|
||||
### How to avoid them?
|
||||
|
||||
You can add anticapability for these commands using `owner defaultcapability`,
|
||||
but that is only a temporary solution. There can also be other issues.
|
||||
|
||||
There are also two active Supybot forks, known as [Limnoria] and [Gribble],
|
||||
which are actively developed and have fixed these issues. If you want permanent
|
||||
solution, you should install either of them.
|
||||
|
||||
## Possibly interesting links
|
||||
|
||||
- [Comparsion of commit activity between Limnoria, Gribble and Supybot](https://www.openhub.net/p/compare?project_0=Limnoria&project_1=Gribble%3A+Support+Bottie&project_2=Supybot).
|
||||
- [Gribble's modifications to stock Supybot](https://sourceforge.net/p/gribble/wiki/Gribble_Project_Git_Repository/)
|
||||
- [Limnoria's modifications to Gribble.](https://github.com/ProgVal/Limnoria/wiki/LGC)
|
||||
- Features of Gribble are fully merged to Limnoria.
|
||||
|
||||
Your current botname.conf is **100% compatible with forks**.
|
||||
|
||||
[Join Supybot channels on LiberaChat!](ircs://irc.libera.chat:6697/#supybot,#gribble,#limnoria)
|
||||
|
||||
[Limnoria]: https://github.com/ProgVal/Limnoria
|
||||
[Gribble]: http://github.com/nanotube/supybot_fixes
|
||||
|
||||
## Installing forks
|
||||
|
||||
_This section has been removed in order to not duplicate
|
||||
[Limnoria's documentation.](http://doc.supybot.aperio.fr/en/latest/use/install.html)_
|
||||
|
||||
---
|
||||
|
||||
Do you know issue that isn't mentioned here? If it's not already reported,
|
||||
please report it
|
||||
on [Limnoria's issue tracker.](https://github.com/ProgVal/Limnoria/issues) If
|
||||
it's known, but just not reported here,
|
||||
[please feel free to add it.](https://github.com/Mikaela/limnoria/edit/gh-pages/Supybot.markdown)
|
38
_config.yml
Normal file
38
_config.yml
Normal file
@ -0,0 +1,38 @@
|
||||
# @format
|
||||
|
||||
theme: minima
|
||||
title: Mikaela's Supybot site
|
||||
tagline: Things official documentation may not tell you
|
||||
author:
|
||||
name: "Aminda Suomalainen"
|
||||
url: "https://aminda.eu/"
|
||||
description: > # this means to ignore newlines until "baseurl:"
|
||||
Mikaela's Supybot site where nowadays the only content is security issues of
|
||||
stock Supybot.
|
||||
baseurl: "" # the subpath of your site, e.g. /blog/
|
||||
url: "https://supybot.mikaela.info/" # the base hostname & protocol for your site
|
||||
github_username: Mikaela
|
||||
lang: en
|
||||
timezone: Etc/UTC
|
||||
encoding: utf-8
|
||||
plugins:
|
||||
# - jekyll-mentions
|
||||
- jekyll-redirect-from
|
||||
- jekyll-sitemap
|
||||
- jekyll-seo-tag
|
||||
sitemap:
|
||||
file: "/sitemap.xml"
|
||||
include: [robots.txt]
|
||||
robots: nofollow, noai
|
||||
icon: https://github.com/ProgVal/Supybot-website/raw/master/static/logo.png
|
||||
markdown: kramdown
|
||||
kramdown:
|
||||
parse_block_html: true
|
||||
#webmaster_verifications:
|
||||
#google:
|
||||
#bing:
|
||||
defaults:
|
||||
- scope:
|
||||
path: "*"
|
||||
values:
|
||||
image: https://github.com/ProgVal/Supybot-website/raw/master/static/logo.png
|
32
_includes/footer.html
Normal file
32
_includes/footer.html
Normal file
@ -0,0 +1,32 @@
|
||||
<footer class="site-footer h-card">
|
||||
<data class="u-url" href="{{ "/" | relative_url }}"></data>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<h2 class="footer-heading">{{ site.title | escape }}</h2>
|
||||
|
||||
<div class="footer-col-wrapper">
|
||||
<div class="footer-col footer-col-1">
|
||||
<ul class="contact-list">
|
||||
<li class="p-name">
|
||||
<a rel="me prefetch" href="{{ site.author.url }}">{{ site.author.name }}</a><br>
|
||||
{{ site.title | escape }}
|
||||
</li>
|
||||
{%- if site.email -%}
|
||||
<li><a class="u-email" href="mailto:{{ site.email }}">{{ site.email }}</a></li>
|
||||
{%- endif -%}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-2">
|
||||
{%- include social.html -%}
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-3">
|
||||
<p>{{- site.description | escape -}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</footer>
|
12
_includes/head.html
Normal file
12
_includes/head.html
Normal file
@ -0,0 +1,12 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!---->
|
||||
{%- seo -%}
|
||||
<!---->
|
||||
<meta name="robots" content="{% if page.robots %}{{ page.robots }} {% else %}{{ site.robots }} {% endif %}">
|
||||
<link rel="icon" href="https://github.com/ProgVal/Supybot-website/raw/master/static/logo.png">
|
||||
<link rel="stylesheet" href="{{ "/assets/main.css" | prepend: site.baseurl }}">
|
||||
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}">
|
||||
</head>
|
210
_sass/_base.scss
Normal file
210
_sass/_base.scss
Normal file
@ -0,0 +1,210 @@
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset some basic elements
|
||||
*/
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic styling
|
||||
*/
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $base-font-size;
|
||||
line-height: $base-line-height;
|
||||
font-weight: 300;
|
||||
color: $text-color;
|
||||
background-color: $background-color;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set `margin-bottom` to maintain vertical rhythm
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
%vertical-rhythm {
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
img {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lists
|
||||
*/
|
||||
ul, ol {
|
||||
margin-left: $spacing-unit;
|
||||
}
|
||||
|
||||
li {
|
||||
> ul,
|
||||
> ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Headings
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
a {
|
||||
color: $brand-color;
|
||||
//text-decoration: none;
|
||||
text-decoration: underline;
|
||||
|
||||
&:visited {
|
||||
//color: darken($brand-color, 15%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $text-color;
|
||||
//text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Blockquotes
|
||||
*/
|
||||
blockquote {
|
||||
color: $grey-color;
|
||||
border-left: 4px solid $grey-color-light;
|
||||
padding-left: $spacing-unit / 2;
|
||||
font-size: 18px;
|
||||
letter-spacing: -1px;
|
||||
font-style: italic;
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Code formatting
|
||||
*/
|
||||
pre,
|
||||
code {
|
||||
font-family: $monospace-font-family;
|
||||
font-size: 15px;
|
||||
border: 1px solid; //$grey-color-light;
|
||||
border-radius: 3px;
|
||||
background-color: revert; //#eef;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 8px 12px;
|
||||
overflow-x: scroll;
|
||||
|
||||
> code {
|
||||
border: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper
|
||||
*/
|
||||
.wrapper {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: $spacing-unit;
|
||||
padding-left: $spacing-unit;
|
||||
@extend %clearfix;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit}));
|
||||
padding-right: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clearfix
|
||||
*/
|
||||
%clearfix {
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
.icon {
|
||||
|
||||
> svg {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
path {
|
||||
fill: $grey-color;
|
||||
}
|
||||
}
|
||||
}
|
236
_sass/_layout.scss
Normal file
236
_sass/_layout.scss
Normal file
@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Site header
|
||||
*/
|
||||
.site-header {
|
||||
border-top: 5px solid $grey-color-dark;
|
||||
border-bottom: 1px solid $grey-color-light;
|
||||
min-height: 56px;
|
||||
|
||||
// Positioning context for the mobile navigation icon
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
line-height: 56px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
float: left;
|
||||
|
||||
&,
|
||||
&:visited {
|
||||
color: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
line-height: 56px;
|
||||
|
||||
.menu-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: $text-color;
|
||||
line-height: $base-line-height;
|
||||
|
||||
// Gaps between nav items, but not on the first one
|
||||
&:not(:first-child) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 30px;
|
||||
background-color: $background-color;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 5px;
|
||||
text-align: right;
|
||||
|
||||
.menu-icon {
|
||||
display: block;
|
||||
float: right;
|
||||
width: 36px;
|
||||
height: 26px;
|
||||
line-height: 0;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
> svg {
|
||||
width: 18px;
|
||||
height: 15px;
|
||||
|
||||
path {
|
||||
fill: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
clear: both;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover .trigger {
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Site footer
|
||||
*/
|
||||
.site-footer {
|
||||
border-top: 1px solid $grey-color-light;
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.footer-heading {
|
||||
font-size: 18px;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.contact-list,
|
||||
.social-media-list {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.footer-col-wrapper {
|
||||
font-size: 15px;
|
||||
color: $grey-color;
|
||||
margin-left: -$spacing-unit / 2;
|
||||
@extend %clearfix;
|
||||
}
|
||||
|
||||
.footer-col {
|
||||
float: left;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.footer-col-1 {
|
||||
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
|
||||
width: calc(35% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
|
||||
width: calc(20% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
|
||||
width: calc(45% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
.footer-col-1,
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
|
||||
width: calc(50% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
.footer-col {
|
||||
float: none;
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Page content
|
||||
*/
|
||||
.page-content {
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.post-list {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
|
||||
> li {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: $small-font-size;
|
||||
color: $grey-color;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts
|
||||
*/
|
||||
.post-header {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
margin-bottom: $spacing-unit;
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 26px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
67
_sass/_syntax-highlighting.scss
Normal file
67
_sass/_syntax-highlighting.scss
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Syntax highlighting styles
|
||||
*/
|
||||
.highlight {
|
||||
background: #fff;
|
||||
@extend %vertical-rhythm;
|
||||
|
||||
.c { color: #998; font-style: italic } // Comment
|
||||
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||
.k { font-weight: bold } // Keyword
|
||||
.o { font-weight: bold } // Operator
|
||||
.cm { color: #998; font-style: italic } // Comment.Multiline
|
||||
.cp { color: #999; font-weight: bold } // Comment.Preproc
|
||||
.c1 { color: #998; font-style: italic } // Comment.Single
|
||||
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
|
||||
.gd { color: #000; background-color: #fdd } // Generic.Deleted
|
||||
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
|
||||
.ge { font-style: italic } // Generic.Emph
|
||||
.gr { color: #a00 } // Generic.Error
|
||||
.gh { color: #999 } // Generic.Heading
|
||||
.gi { color: #000; background-color: #dfd } // Generic.Inserted
|
||||
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
|
||||
.go { color: #888 } // Generic.Output
|
||||
.gp { color: #555 } // Generic.Prompt
|
||||
.gs { font-weight: bold } // Generic.Strong
|
||||
.gu { color: #aaa } // Generic.Subheading
|
||||
.gt { color: #a00 } // Generic.Traceback
|
||||
.kc { font-weight: bold } // Keyword.Constant
|
||||
.kd { font-weight: bold } // Keyword.Declaration
|
||||
.kp { font-weight: bold } // Keyword.Pseudo
|
||||
.kr { font-weight: bold } // Keyword.Reserved
|
||||
.kt { color: #458; font-weight: bold } // Keyword.Type
|
||||
.m { color: #099 } // Literal.Number
|
||||
.s { color: #d14 } // Literal.String
|
||||
.na { color: #008080 } // Name.Attribute
|
||||
.nb { color: #0086B3 } // Name.Builtin
|
||||
.nc { color: #458; font-weight: bold } // Name.Class
|
||||
.no { color: #008080 } // Name.Constant
|
||||
.ni { color: #800080 } // Name.Entity
|
||||
.ne { color: #900; font-weight: bold } // Name.Exception
|
||||
.nf { color: #900; font-weight: bold } // Name.Function
|
||||
.nn { color: #555 } // Name.Namespace
|
||||
.nt { color: #000080 } // Name.Tag
|
||||
.nv { color: #008080 } // Name.Variable
|
||||
.ow { font-weight: bold } // Operator.Word
|
||||
.w { color: #bbb } // Text.Whitespace
|
||||
.mf { color: #099 } // Literal.Number.Float
|
||||
.mh { color: #099 } // Literal.Number.Hex
|
||||
.mi { color: #099 } // Literal.Number.Integer
|
||||
.mo { color: #099 } // Literal.Number.Oct
|
||||
.sb { color: #d14 } // Literal.String.Backtick
|
||||
.sc { color: #d14 } // Literal.String.Char
|
||||
.sd { color: #d14 } // Literal.String.Doc
|
||||
.s2 { color: #d14 } // Literal.String.Double
|
||||
.se { color: #d14 } // Literal.String.Escape
|
||||
.sh { color: #d14 } // Literal.String.Heredoc
|
||||
.si { color: #d14 } // Literal.String.Interpol
|
||||
.sx { color: #d14 } // Literal.String.Other
|
||||
.sr { color: #009926 } // Literal.String.Regex
|
||||
.s1 { color: #d14 } // Literal.String.Single
|
||||
.ss { color: #990073 } // Literal.String.Symbol
|
||||
.bp { color: #999 } // Name.Builtin.Pseudo
|
||||
.vc { color: #008080 } // Name.Variable.Class
|
||||
.vg { color: #008080 } // Name.Variable.Global
|
||||
.vi { color: #008080 } // Name.Variable.Instance
|
||||
.il { color: #099 } // Literal.Number.Integer.Long
|
||||
}
|
70
assets/main.scss
Normal file
70
assets/main.scss
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
# front-matter
|
||||
---
|
||||
|
||||
/** @format */
|
||||
|
||||
@charset "utf-8";
|
||||
$base-font-family: ui-sans-serif, system-ui, "Liberation Sans", Arimo, Arial,
|
||||
sans-serif;
|
||||
$monospace-font-family: ui-monospace, "Liberation Mono", Cousine, "Courier New",
|
||||
monospace;
|
||||
|
||||
@import "{{ site.theme }}";
|
||||
|
||||
:root {
|
||||
color-scheme: dark light !important;
|
||||
}
|
||||
|
||||
* {
|
||||
// box-sizing: border-box !important;
|
||||
color: revert !important;
|
||||
background-color: revert !important;
|
||||
//margin: auto !important;
|
||||
// line-height: 1.2 !important;
|
||||
font-size: revert;
|
||||
//padding: auto !important;
|
||||
overflow-wrap: break-word !important;
|
||||
hyphens: auto !important;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
font-size: 0.8em !important;
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 50% !important;
|
||||
display: block;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
@media (min-width: 395px) {
|
||||
display: float !important;
|
||||
float: right !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Customize the dark theme to be more me
|
||||
@media (prefers-color-scheme: dark) {
|
||||
* {
|
||||
color: #ffb700 !important;
|
||||
border-color: #ffb700 !important;
|
||||
background-color: #000000 !important;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
color-scheme: only dark !important;
|
||||
color: #ffb700 !important;
|
||||
background-color: #000000 !important;
|
||||
color: #ffb700 !important;
|
||||
}
|
||||
|
||||
// I don't want links to be restored to amber'
|
||||
a {
|
||||
color: revert !important;
|
||||
}
|
||||
}
|
30
feed.xml
Normal file
30
feed.xml
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
layout: null
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ site.title | xml_escape }}</title>
|
||||
<description>{{ site.description | xml_escape }}</description>
|
||||
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
|
||||
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||
{% for post in site.posts limit:10 %}
|
||||
<item>
|
||||
<title>{{ post.title | xml_escape }}</title>
|
||||
<description>{{ post.content | xml_escape }}</description>
|
||||
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
|
||||
<link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>
|
||||
<guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
|
||||
{% for tag in post.tags %}
|
||||
<category>{{ tag | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
{% for cat in post.categories %}
|
||||
<category>{{ cat | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
26
index.markdown
Normal file
26
index.markdown
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<!-- @format -->
|
||||
|
||||
**_WARNING: most of the content on this site originates from 2014!_**
|
||||
|
||||
Welcome to Mikaela's Supybot pages.
|
||||
|
||||
This site isn't official and won't help with most of issues. In case you are
|
||||
looking for the official sites, they are here:
|
||||
|
||||
- [Limnoria's website](https://limnoria.net/)
|
||||
- [Limnoria official documentation](https://docs.limnoria.net/)
|
||||
- [Supybook](https://hoxu.github.io/supybook/devel/)
|
||||
- [Gribble Wiki](https://sourceforge.net/p/gribble/wiki/Main_Page/)
|
||||
|
||||
I also have
|
||||
[something in my gist repo](https://gitea.blesmrt.net/mikaela/gist/src/branch/master/irc/limnoria/)
|
||||
at 2021-06-11 16:07 UTC
|
||||
[opinionated titlefetching instructions](https://gitea.blesmrt.net/mikaela/gist/src/branch/master/irc/limnoria/titlefetching.md).
|
||||
|
||||
If you cannot find what you are looking for from them, please come to IRC and
|
||||
ask. The Support channels are
|
||||
[#supybot,#limnoria on irc.libera.chat](ircs://irc.libera.chat:6697/%23supybot%2c%23limnoria)
|
1802
locales/de.po
1802
locales/de.po
File diff suppressed because it is too large
Load Diff
2251
locales/fi.po
2251
locales/fi.po
File diff suppressed because it is too large
Load Diff
2127
locales/fr.po
2127
locales/fr.po
File diff suppressed because it is too large
Load Diff
100
locales/fr.py
100
locales/fr.py
@ -1,100 +0,0 @@
|
||||
# -*- encoding: utf8 -*-
|
||||
###
|
||||
# Copyright (c) 2010, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
"""
|
||||
Supybot utility functions localization in French.
|
||||
"""
|
||||
|
||||
def pluralize(s):
|
||||
"""Returns the plural of s.
|
||||
"""
|
||||
lowered = s.lower()
|
||||
if lowered.endswith('ou') and \
|
||||
lowered in ['bijou', 'caillou', 'chou', 'genou', 'hibou', 'joujou',
|
||||
'pou']:
|
||||
return s + 'x'
|
||||
elif lowered.endswith('al') and \
|
||||
lowered not in ['bal', 'carnaval', 'chacal', 'festival', 'récital',
|
||||
'régal', 'cal', 'étal', 'aval', 'caracal', 'val', 'choral',
|
||||
'corral', 'galgal', 'gayal']:
|
||||
return s[0:-2] + 'aux'
|
||||
elif lowered.endswith('ail') and \
|
||||
lowered not in ['bail', 'corail', 'émail', 'soupirail', 'travail',
|
||||
'ventail', 'vitrail', 'aspirail', 'fermail']:
|
||||
return s[0:-3] + 'aux'
|
||||
elif lowered.endswith('eau'):
|
||||
return s + 'x'
|
||||
elif lowered == 'pare-feu':
|
||||
return s
|
||||
elif lowered.endswith('eu') and \
|
||||
lowered not in ['bleu', 'pneu', 'émeu', 'enfeu']:
|
||||
# Note: when 'lieu' is a fish, it has a 's' ; else, it has a 'x'
|
||||
return s + 'x'
|
||||
else:
|
||||
return s + 's'
|
||||
|
||||
def depluralize(s):
|
||||
"""Returns the singular of s."""
|
||||
lowered = s.lower()
|
||||
if lowered.endswith('aux') and \
|
||||
lowered in ['baux', 'coraux', 'émaux', 'soupiraux', 'travaux',
|
||||
'ventaux', 'vitraux', 'aspiraux', 'fermaux']:
|
||||
return s[0:-3] + 'ail'
|
||||
elif lowered.endswith('aux'):
|
||||
return s[0:-3] + 'al'
|
||||
else:
|
||||
return s[0:-1]
|
||||
|
||||
def ordinal(i):
|
||||
"""Returns i + the ordinal indicator for the number.
|
||||
|
||||
Example: ordinal(3) => '3ème'
|
||||
"""
|
||||
i = int(i)
|
||||
if i == 1:
|
||||
return '1er'
|
||||
else:
|
||||
return '%sème' % i
|
||||
|
||||
def be(i):
|
||||
"""Returns the form of the verb 'être' based on the number i."""
|
||||
# Note: this function is used only for the third person
|
||||
if i == 1:
|
||||
return 'est'
|
||||
else:
|
||||
return 'sont'
|
||||
|
||||
def has(i):
|
||||
"""Returns the form of the verb 'avoir' based on the number i."""
|
||||
# Note: this function is used only for the third person
|
||||
if i == 1:
|
||||
return 'a'
|
||||
else:
|
||||
return 'ont'
|
2132
locales/it.po
2132
locales/it.po
File diff suppressed because it is too large
Load Diff
1512
locales/messages.pot
1512
locales/messages.pot
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-adduser.1
|
||||
.\"
|
||||
.TH LIMNORIA-ADDUSER 1 "APRIL 2005"
|
||||
.SH NAME
|
||||
limnoria-adduser \- Adds a user to a Limnoria users.conf file
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-adduser
|
||||
.RI [ options ] " users.conf
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-adduser
|
||||
adds a user to the specified users.conf file.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-u " NAME" "\fR,\fP \-\^\-username=" NAME
|
||||
Specifies the username to use for the new user.
|
||||
.TP
|
||||
.BR \-p " PASSWORD" "\fR,\fP \-\^\-password=" PASSWORD
|
||||
Specifies the password to use for the new user.
|
||||
.TP
|
||||
.BR \-c " CAPABILITY" "\fR,\fP \-\^\-capability=" CAPABILITY
|
||||
Capability the user should have; this option may be given
|
||||
multiple times.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-plugin-doc (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,54 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-botchk.1
|
||||
.\"
|
||||
.TH LIMNORIA-BOTCHK 1 "APRIL 2005"
|
||||
.SH NAME
|
||||
limnoria-botchk \- A script to start Limnoria if it's not already running.
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-botchk
|
||||
.RI [ options ]
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-botchk
|
||||
is a script that will start Limnoria if it detects that one is not currently
|
||||
running. This can be useful for scheduling
|
||||
.IR limnoria (1)
|
||||
to run via
|
||||
.IR cron (8).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-v ", " \-\^\-verbose
|
||||
Use verbose output when running the script.
|
||||
.TP
|
||||
.BI \-\^\-botdir= BOTDIR
|
||||
Determines which directory the bot be started in.
|
||||
.TP
|
||||
.BI \-\^\-pidfile= PIDFILE
|
||||
Specifies the name of the pidfile to look for. This should be relative
|
||||
to the given botdir.
|
||||
.TP
|
||||
.BI \-\^\-limnoria= LIMNORIA
|
||||
Specifies the location of
|
||||
.IR limnoria (1).
|
||||
If this is not given, it is assumed that
|
||||
.IR limnoria (1)
|
||||
is in the user's $PATH.
|
||||
.TP
|
||||
.BI \-\^\-conffile= CONFFILE
|
||||
Specifies the path to the bot's configuration file. This will be used
|
||||
when (re)starting the bot.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-doc (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,43 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-plugin-create.1
|
||||
.\"
|
||||
.TH LIMNORIA-PLUGIN-CREATE 1 "APRIL 2005"
|
||||
.SH NAME
|
||||
limnoria-plugin-create \- A wizard for creating Limnoria plugins
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-plugin-create
|
||||
.RI [ options ]
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-plugin-create
|
||||
is a wizard that creates a template python source file for a new
|
||||
.IR limnoria (1)
|
||||
plugin.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BI \-n " NAME" "\fR,\fP \-\^\-name=" NAME
|
||||
Sets the name for the plugin.
|
||||
.TP
|
||||
.BR \-t ", " \-\^\-thread
|
||||
Makes the plugin threaded.
|
||||
.TP
|
||||
.BI \-\^\-real\-name= REALNAME
|
||||
Specify what real name the copyright is assigned to.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-doc (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,48 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-plugin-doc.1
|
||||
.\"
|
||||
.TH LIMNORIA-PLUGIN-DOC 1 "May 2009"
|
||||
.SH NAME
|
||||
limnoria-plugin-doc \- Generates the documentation for a Limnoria plugin
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-plugin-doc
|
||||
.RI [ options ]
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-plugin-doc
|
||||
is used to generate documentation (StructuredText or reStructuredText format)
|
||||
for a
|
||||
.IR limnoria (1)
|
||||
plugin.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-c ", " \-\^\-clean
|
||||
Clean the various data/conf/log directories after generating the docs.
|
||||
.TP
|
||||
.BR \-o ", " \-\^\-output\-dir= \fIOUTPUTDIR
|
||||
Specifies the directory in which to write the documentation for the plugin.
|
||||
.TP
|
||||
.BR \-f ", " \-\^\-format= \fIFORMAT
|
||||
Specifies which output format to use. Choices are 'rst' or 'stx'.
|
||||
.TP
|
||||
.BI \-\^\-plugins\-dir= PLUGINSDIRS
|
||||
Looks in the given directory for plugins and generates documentation for all of
|
||||
them.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,35 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-reset-password.1
|
||||
.\"
|
||||
.TH LIMNORIA-RESET-PASSWORD 1 "JUNE 2022"
|
||||
.SH NAME
|
||||
limnoria-reset-password \- Changes a user's password in a Limnoria users.conf file
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-reset-password
|
||||
.RI [ options ] " users.conf
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-reset-password
|
||||
changes a user's password in a Limnoria users.conf file
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-u " NAME" "\fR,\fP \-\^\-username=" NAME
|
||||
Specifies the username to use for the new user.
|
||||
.TP
|
||||
.BR \-p " PASSWORD" "\fR,\fP \-\^\-password=" PASSWORD
|
||||
Specifies the new password to use for the new user.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-adduser (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by Valentin Lorentz
|
||||
<progval plus limnoria at progval dot net>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
||||
|
@ -1,51 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-test.1
|
||||
.\"
|
||||
.TH LIMNORIA-TEST 1 "OCTOBER 2005"
|
||||
.SH NAME
|
||||
limnoria-test \- Runs the test suite for a Limnoria plugin
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-test
|
||||
.RI [ options ] " plugins
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-test
|
||||
Runs the test suite for a Limnoria plugin
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-c ", " \-\^\-clean
|
||||
Cleans the various data/conf/logs directories before running tests.
|
||||
.TP
|
||||
.BR \-t " TIMEOUT" "\fR,\fP \-\^\-timeout=" TIMEOUT
|
||||
Specifies the timeout for tests to return responses.
|
||||
.TP
|
||||
.BR \-v ", " \-\^\-verbose
|
||||
Sets the verbose flag, logging extra information about each test that runs.
|
||||
.TP
|
||||
.BR \-\^\-no\-network
|
||||
Prevents the network-based tests from being run.
|
||||
.TP
|
||||
.BR \-\^\-trace
|
||||
Traces all calls made. Unless you're really in a pinch, you probably
|
||||
shouldn't do this; it results in copious amounts of output.
|
||||
.TP
|
||||
.BR "\fR,\fP \-\^\-plugins\-dir=" PLUGINSDIR
|
||||
Looks in the given directory for plugins and loads the tests for all of them.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-doc (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,42 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria-wizard.1
|
||||
.\"
|
||||
.TH LIMNORIA-WIZARD 1 "SEPTEMBER 2004"
|
||||
.SH NAME
|
||||
limnoria-wizard \- A wizard for creating Limnoria configuration files
|
||||
.SH SYNOPSIS
|
||||
.B limnoria-wizard
|
||||
.RI [ options ]
|
||||
.SH DESCRIPTION
|
||||
.B limnoria-wizard
|
||||
is an in-depth wizard that provides a nice user interface for creating
|
||||
configuration files for
|
||||
.IR limnoria (1).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.B \-\^\-allow\-root
|
||||
Determines whether the wizard will be allowed to run as root. You do not
|
||||
want this. Do not do it. Even if you think you want it, you do not.
|
||||
.TP
|
||||
.B \-\^\-no\-network
|
||||
Determines whether the wizard will be allowed to run without a network
|
||||
connection.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-doc (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1,66 +0,0 @@
|
||||
.\" Process this file with
|
||||
.\" groff -man -Tascii limnoria.1
|
||||
.\"
|
||||
.TH LIMNORIA 1 "JULY 2009"
|
||||
.SH NAME
|
||||
limnoria - A robust and user friendly Python IRC bot
|
||||
.SH SYNOPSIS
|
||||
.B limnoria
|
||||
.RI [ options ] " configFile
|
||||
.SH DESCRIPTION
|
||||
.B Limnoria
|
||||
is a robust, user-friendly, and programmer-friendly Python IRC bot.
|
||||
It aims to be an adequate replacement for most existing IRC bots. It
|
||||
includes a very flexible and powerful ACL system for controlling access
|
||||
to commands, as well as more than 50 builtin plugins providing around
|
||||
400 actual commands.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\^\-version
|
||||
Show version of program.
|
||||
.TP
|
||||
.BR \-h ", " \-\^\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.BR \-P ", " \-\^\-profile
|
||||
Enable profiling.
|
||||
.TP
|
||||
.BI \-n " NICK" "\fR,\fP \-\^\-nick=" NICK
|
||||
Nick the bot should use.
|
||||
.TP
|
||||
.BI \-u " USER" "\fR,\fP \-\^\-user=" USER
|
||||
Full username the bot should use.
|
||||
.TP
|
||||
.BI \-i " IDENT" "\fR,\fP \-\^\-ident=" IDENT
|
||||
Ident the bot should use.
|
||||
.TP
|
||||
.BR \-d ", " \-\^\-daemon
|
||||
Determines whether the bot will daemonize. This is a no-op on
|
||||
non-POSIX systems.
|
||||
.TP
|
||||
.B \-\^\-allow\-default\-owner
|
||||
Determines whether the bot will allow its defaultCapabilities not to
|
||||
include "\-owner", thus giving all users the owner capability by
|
||||
default. This is dumb, hence we require a command-line option to
|
||||
enable it.
|
||||
.TP
|
||||
.B \-\^\-allow\-root
|
||||
Determines whether the bot will be allowed to run as root. You do not
|
||||
want this. Do not do it. Even if you think you want it, you do not.
|
||||
.TP
|
||||
.B \-\^\-debug
|
||||
Determines whether some extra debugging stuff will be logged by this
|
||||
script.
|
||||
.SH "SEE ALSO"
|
||||
.IR python (1),
|
||||
.IR limnoria-test (1),
|
||||
.IR limnoria-botchk (1),
|
||||
.IR limnoria-wizard (1),
|
||||
.IR limnoria-adduser (1),
|
||||
.IR limnoria-plugin-doc (1),
|
||||
.IR limnoria-plugin-create (1)
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by James McCoy
|
||||
<vega dot james at gmail dot com>. Permission is granted to copy,
|
||||
distribute and/or modify this document under the terms of the Limnoria
|
||||
license, a BSD-style license.
|
@ -1 +0,0 @@
|
||||
limnoria-adduser.1
|
@ -1 +0,0 @@
|
||||
limnoria-botchk.1
|
@ -1 +0,0 @@
|
||||
limnoria-plugin-create.1
|
@ -1 +0,0 @@
|
||||
limnoria-plugin-doc.1
|
@ -1 +0,0 @@
|
||||
limnoria-reset-password.1
|
@ -1 +0,0 @@
|
||||
limnoria-test.1
|
@ -1 +0,0 @@
|
||||
limnoria-wizard.1
|
@ -1 +0,0 @@
|
||||
limnoria.1
|
7
package.json
Normal file
7
package.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"prettier": "3.3.0",
|
||||
"prettier-plugin-sh": "0.14.0"
|
||||
},
|
||||
"packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a"
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
.. _plugin-Admin:
|
||||
|
||||
Documentation for the Admin plugin for Supybot
|
||||
==============================================
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
These are commands useful for administrating the bot; they all require their
|
||||
caller to have the 'admin' capability. This plugin is loaded by default.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This plugin provides access to administrative commands, such as
|
||||
adding capabilities, managing ignore lists, and joining channels.
|
||||
This is a core Supybot plugin that should not be removed!
|
||||
|
||||
.. _commands-Admin:
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
.. _command-admin-acmd:
|
||||
|
||||
acmd <command> [<arg> ...]
|
||||
Perform <command> (with associated <arg>s on all channels on current network.
|
||||
|
||||
.. _command-admin-capability.add:
|
||||
|
||||
capability add <name|hostmask> <capability>
|
||||
Gives the user specified by <name> (or the user to whom <hostmask> currently maps) the specified capability <capability>
|
||||
|
||||
.. _command-admin-capability.remove:
|
||||
|
||||
capability remove <name|hostmask> <capability>
|
||||
Takes from the user specified by <name> (or the user to whom <hostmask> currently maps) the specified capability <capability>
|
||||
|
||||
.. _command-admin-channels:
|
||||
|
||||
channels takes no arguments
|
||||
Returns the channels the bot is on.
|
||||
|
||||
.. _command-admin-clearq:
|
||||
|
||||
clearq takes no arguments
|
||||
Clears the current send queue for this network.
|
||||
|
||||
.. _command-admin-ignore.add:
|
||||
|
||||
ignore add <hostmask|nick> [<expires>]
|
||||
This will set a persistent ignore on <hostmask> or the hostmask currently associated with <nick>. <expires> is an optional argument specifying when (in "seconds from now") the ignore will expire; if it isn't given, the ignore will never automatically expire.
|
||||
|
||||
.. _command-admin-ignore.list:
|
||||
|
||||
ignore list takes no arguments
|
||||
Lists the hostmasks that the bot is ignoring.
|
||||
|
||||
.. _command-admin-ignore.remove:
|
||||
|
||||
ignore remove <hostmask|nick>
|
||||
This will remove the persistent ignore on <hostmask> or the hostmask currently associated with <nick>.
|
||||
|
||||
.. _command-admin-join:
|
||||
|
||||
join <channel> [<key>]
|
||||
Tell the bot to join the given channel. If <key> is given, it is used when attempting to join the channel.
|
||||
|
||||
.. _command-admin-nick:
|
||||
|
||||
nick [<nick>] [<network>]
|
||||
Changes the bot's nick to <nick>. If no nick is given, returns the bot's current nick.
|
||||
|
||||
.. _conf-Admin:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
.. _conf-supybot.plugins.Admin.public:
|
||||
|
||||
|
||||
supybot.plugins.Admin.public
|
||||
This config variable defaults to "True", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin is publicly visible.
|
||||
|
@ -1,59 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2004-2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
"""
|
||||
These are commands useful for administrating the bot; they all require their
|
||||
caller to have the 'admin' capability. This plugin is loaded by default.
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
__author__ = supybot.authors.jemfinch
|
||||
__maintainer__ = supybot.authors.limnoria_core
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you\'re keeping the plugin in CVS or some similar system.
|
||||
__version__ = "%%VERSION%%"
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
from . import config
|
||||
from . import plugin
|
||||
from importlib import reload
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
|
||||
if world.testing:
|
||||
from . import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
@ -1,47 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2004-2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Admin')
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified themself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('Admin', True)
|
||||
|
||||
Admin = conf.registerPlugin('Admin')
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,270 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2011-10-31 13:37+0100\n"
|
||||
"Last-Translator: Florian Besser <fbesser@gmail.com>\n"
|
||||
"Language-Team: German <fbesser@gmail.com>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
"X-Poedit-Country: Germany\n"
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"This plugin provides access to administrative commands, such as\n"
|
||||
" adding capabilities, managing ignore lists, and joining channels.\n"
|
||||
" This is a core Supybot plugin that should not be removed!"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:57
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr "Nick/Kanal temporär nicht verfügbar."
|
||||
|
||||
#: plugin.py:85
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr "Kann %s nicht beitreten, der Kanal ist voll."
|
||||
|
||||
#: plugin.py:93
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr "Kann %s nicht beitreten, ich wurde nicht eingeladen."
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "Cannot join %s, I am banned."
|
||||
msgstr "Ich kann %s nicht betreten, ich bin gebannt."
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr "Ich kann %s nicht beitreten, mein Schlüsselwort ist falsch."
|
||||
|
||||
#: plugin.py:117 plugin.py:126
|
||||
msgid "Cannot join %s, I'm not identified with NickServ."
|
||||
msgstr "Ich kann %s nicht betreten, ich bin nicht mit NickServ identifiziert."
|
||||
|
||||
#: plugin.py:156
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is "
|
||||
"used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Kanal> [<Schlüssel>]\n"
|
||||
"\n"
|
||||
"Sagt dem Bot dem angegeben Kanal beizutreten. Falls <Schlüssel> angegeben "
|
||||
"wird, wird dieser benutzt um zu versuchen den Kanal zu betreten."
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "channel"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr "Ich bin schon zu nah an den maximalen Kanälen für dieses Netzwerk."
|
||||
|
||||
#: plugin.py:178
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"hat keine Argumente\n"
|
||||
"\n"
|
||||
"Listet die Hostmasken auf, die der Bot ignoriert."
|
||||
|
||||
#: plugin.py:187
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr "Momentan bin ich in keinen Kanälen."
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr "Meine Verbindung ist begrenzt, I kann meinen Nick nicht wechseln."
|
||||
|
||||
#: plugin.py:200
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr "Jemand anderes benutzt diesen Nick schon."
|
||||
|
||||
#: plugin.py:207
|
||||
#, fuzzy
|
||||
msgid "I can't change nick, I'm currently banned in %s."
|
||||
msgstr "Ich kann meinen Nick nicht ändern, der Server sagte %q."
|
||||
|
||||
#: plugin.py:215
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr "Ich kann meinen Nick nicht ändern, der Server sagte %q."
|
||||
|
||||
#: plugin.py:229
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"[<nick>] [<network>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<Nick>]\n"
|
||||
"\n"
|
||||
"Ändert den Nick des Bots zu <Nick>. Falls <Nick> nicht angegeben wird, wird "
|
||||
"der momentane Botnick zurückgegeben."
|
||||
|
||||
#: plugin.py:248
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom "
|
||||
"<hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Name|Hostmaske> <Fähigkeit>\n"
|
||||
"\n"
|
||||
"Gibt dem angebenen Benutzer <Name> (oder dem auf den die <Hostmaske> "
|
||||
"zutrifft) die angegebene Fähigkeit."
|
||||
|
||||
#: plugin.py:268
|
||||
msgid ""
|
||||
"The \"owner\" capability can't be added in the bot. Use the supybot-adduser "
|
||||
"program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr ""
|
||||
"Die \"owner\" Fähigkeit kann nicht über den Bot hinzugefügt werden. Benutze "
|
||||
"das supybot-adduser Programm (oder verändere users.conf per Hand) um die "
|
||||
"Besitzer Fähigkeit hinzuzufügen."
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr "Du kannst keine Fähigkeiten hinzufügen, die du nicht hast."
|
||||
|
||||
#: plugin.py:284
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability "
|
||||
"<capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Name|Hostmaske> <Fähigkeit>\n"
|
||||
"\n"
|
||||
"Nimmt dem Benutzer der durch <Name> (oder dem Benutzer auf den momentan "
|
||||
"<Hostmaske> zeigt) angeben wird die angegeben Fähigkeit <Fähigkeit>."
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr "Der Benutzer hat diese Fähigkeit nicht."
|
||||
|
||||
#: plugin.py:298
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr "Du kannst keine Fähigkeiten entfernen, die du nicht hast."
|
||||
|
||||
#: plugin.py:306
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional "
|
||||
"argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will "
|
||||
"expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Hostmaske|Nick> [<Ablaufzeitpunkt>]\n"
|
||||
"\n"
|
||||
"Es wird eine beständige Ignorierung auf <Hostmaske> oder auf die Hostmaske "
|
||||
"die momentan mit <Nick> verbunden wird gesetzt. <Ablaufzeitpunkt> ist "
|
||||
"optional, das legt fest wann die Ignorierung abläuft;falls dies nicht "
|
||||
"angegeben wird, wird die Ignorierung niemals ablaufen."
|
||||
|
||||
#: plugin.py:319
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Hostmaske|Nick>\n"
|
||||
"\n"
|
||||
"Wird die beständige Ignorierung, von <Hostmaske> oder der Hostmaske die "
|
||||
"momentan mit dem <Nick> verbunden wird, aufheben."
|
||||
|
||||
#: plugin.py:328
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr "%s war nicht in der Datenbank für Ignorierungen."
|
||||
|
||||
#: plugin.py:333
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"hat keine Argumente\n"
|
||||
"\n"
|
||||
"Listet die Hostmasken auf, die der Bot ignoriert."
|
||||
|
||||
#: plugin.py:341
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr "Momentan ignoriere ich niemanden global."
|
||||
|
||||
#: plugin.py:345
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Clears the current send queue for this network.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"hat keine Argumente\n"
|
||||
"\n"
|
||||
"Leert die momentane Sendenwarteschlange für dieses Netzwerk."
|
||||
|
||||
#: plugin.py:354
|
||||
msgid ""
|
||||
"<command> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Perform <command> (with associated <arg>s on all channels on current "
|
||||
"network."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "takes no arguments\n"
|
||||
#~ "\n"
|
||||
#~ " Returns the channels the bot is on. Must be given in private, in "
|
||||
#~ "order\n"
|
||||
#~ " to protect the secrecy of secret channels.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "hat keine Argumenten\n"
|
||||
#~ "\n"
|
||||
#~ "Gibt die Kanäle aus in denen der Bot sich befindet. Dieser Befehl muss "
|
||||
#~ "privat gegeben werden, um das Geheimnis der geheimen Kanale zu wahren."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "[<channel>] [<reason>]\n"
|
||||
#~ "\n"
|
||||
#~ " Tells the bot to part the list of channels you give it. "
|
||||
#~ "<channel> is\n"
|
||||
#~ " only necessary if you want the bot to part a channel other than "
|
||||
#~ "the\n"
|
||||
#~ " current channel. If <reason> is specified, use it as the part\n"
|
||||
#~ " message.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "[<Kanal>] [<Grund>]\n"
|
||||
#~ "\n"
|
||||
#~ "Sagt dem Bot die Liste von angebenen Kanälen zu verlassen. <Kanal> ist "
|
||||
#~ "nur notwendig, falls der Bot einen anderen Kanal als den Momentanen "
|
||||
#~ "verlassen soll. Falls <Grund> angegeben wird, wird dies als "
|
||||
#~ "Verlassensnachricht verwendet."
|
||||
|
||||
#~ msgid "I'm not in %s."
|
||||
#~ msgstr "Ich bin nicht in %s."
|
||||
|
||||
#~ msgid "That nick is currently banned."
|
||||
#~ msgstr "Dieser Nick ist momentan gebannt."
|
@ -1,295 +0,0 @@
|
||||
# Admin plugin in Limnoria.
|
||||
# Copyright (C) 2011 Limnoria
|
||||
# Mikaela Suomalainen <mikaela.suomalainen@outlook.com>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Finnish translation of Admin plugin in Supybot\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2014-12-20 12:19+0200\n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fi_FI\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"This plugin provides access to administrative commands, such as\n"
|
||||
" adding capabilities, managing ignore lists, and joining channels.\n"
|
||||
" This is a core Supybot plugin that should not be removed!"
|
||||
msgstr ""
|
||||
"Tämä plugin antaa pääsyn ylläpitäviin komentoihin, kuten valtuuksien "
|
||||
"lisäämiseen,\n"
|
||||
" ignore-listojen hallintaan ja kanaville liittymiseen. Tämä on ydin Supybot-"
|
||||
"plugin, jota ei pitäisi poistaa!s"
|
||||
|
||||
#: plugin.py:57
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr "Nimimerkki/kanava on väliaikaisesti saavuttamattomissa."
|
||||
|
||||
#: plugin.py:85
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr "Ei voida liittyä kanavalle %s, se on täynnä."
|
||||
|
||||
#: plugin.py:93
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr "Ei voi liittyä kanavalle %s, minua ei ole kutsuttu."
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "Cannot join %s, I am banned."
|
||||
msgstr "Ei voi liittyä kanavalle %s, se on antanut minulle porttikiellon."
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr "En voi liittyä kanavalle %s, minun avainsana oli väärä."
|
||||
|
||||
#: plugin.py:117 plugin.py:126
|
||||
msgid "Cannot join %s, I'm not identified with NickServ."
|
||||
msgstr "En voi liittyä kanavalle %s, koska en ole tunnistautunut NickServille."
|
||||
|
||||
#: plugin.py:156
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is "
|
||||
"used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> [<avain>]\n"
|
||||
"\n"
|
||||
" Käskee botin liittyä annetulle kanavalle. Jos <avain> on annettu, "
|
||||
"sitä käytetään\n"
|
||||
" yrittäessä liittyä kanavalle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "channel"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr "Minä olen jo liian lähellä kanavien maksimimäärää tässä verkossa."
|
||||
|
||||
#: plugin.py:178
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ei ota parametrejä\n"
|
||||
"\n"
|
||||
" Luetteloi hostmaskit jotka ovat botin huomiotta jättämis listalla.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:187
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr "En juuri nyt ole millään kanavalla."
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr "Minun yhteyteni on rajoitettu. En voi vaihtaa nimimerkkiä."
|
||||
|
||||
#: plugin.py:200
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr "Joku muu käyttää jo tuota nimimerkkiä."
|
||||
|
||||
#: plugin.py:207
|
||||
#, fuzzy
|
||||
msgid "I can't change nick, I'm currently banned in %s."
|
||||
msgstr "Minä en voi vaihtaa nimimerkkiä, koska palvelin sanoi %q"
|
||||
|
||||
#: plugin.py:215
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr "Minä en voi vaihtaa nimimerkkiä, koska palvelin sanoi %q"
|
||||
|
||||
#: plugin.py:229
|
||||
msgid ""
|
||||
"[<nick>] [<network>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<nimimerkki>] [<verkko>]\n"
|
||||
"\n"
|
||||
" Vaihtaa botin nimimerkin <nimimerkiksi>. Mikäli nimimerkkiä ei anneta, "
|
||||
"botin nykyinen\n"
|
||||
" nimimerkki palautetaan.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:248
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom "
|
||||
"<hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi|hostmask> <valtuus>\n"
|
||||
"\n"
|
||||
" Antaa <nimen> määrittämälle käyttäjälle (tai käyttäjälle jonka "
|
||||
"<hostmask>\n"
|
||||
" ilmoittaa) määritetyn valtuuden <valtuus>\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:268
|
||||
msgid ""
|
||||
"The \"owner\" capability can't be added in the bot. Use the supybot-adduser "
|
||||
"program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr ""
|
||||
"\"Owner\" valtuutta ei voi lisätä botissa. Käytä supybot-adduser ohjelmaa "
|
||||
"(tai muokkaa users.conf tiedostoa itse) lisätäksesi owner valtuuden."
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr "Et voi lisätä valtuuksia, joita sinulla ei ole."
|
||||
|
||||
#: plugin.py:284
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability "
|
||||
"<capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi|hostmask> <valtuus>\n"
|
||||
"\n"
|
||||
" Ottaa <nimen> määrittämältä käyttäjältä (tai käyttäjältä "
|
||||
"johon\n"
|
||||
" <hostmask> sopii) määritetyn valtuuden <valtuus>\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr "Tuolla käyttäjällä ei tuota valtuutta."
|
||||
|
||||
#: plugin.py:298
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr "Sinä et voi poistaa valtuuksia, joita sinulla ei ole."
|
||||
|
||||
#: plugin.py:306
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional "
|
||||
"argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will "
|
||||
"expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nimimerkki> [<vanhentuu>]\n"
|
||||
"\n"
|
||||
" Tämä asettaa pysyvän huomiotta jättämisen <hostmaskiin> tai "
|
||||
"hostmaskiin,\n"
|
||||
" joka on tällä hetkellä yhdistetty <nimimerkkiin>. <Vanhentuminen> on "
|
||||
"vaihtoehtoinen paremetri,\n"
|
||||
" joka määrittää (\"sekuntit\") joiden jälkeen huomiotta jättäminen "
|
||||
"poistetaan; jos\n"
|
||||
" sitä ei ole annettu, huomiotta jättäminen ei vanhene ikinä "
|
||||
"automaattisesti.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:319
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nimimerkki>\n"
|
||||
"\n"
|
||||
" Tämä poistaa pysyvän huomiotta jättämisen <hostmaskista> tai\n"
|
||||
" hostmaskista joka on tällä hetkellä yhdistetty <nimimerkkiin>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:328
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr "%s ei ollut huomiotta jätettävien tietokannassa."
|
||||
|
||||
#: plugin.py:333
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ei ota parametrejä\n"
|
||||
"\n"
|
||||
" Luetteloi hostmaskit jotka ovat botin huomiotta jättämis listalla.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:341
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr "En tällä hetkellä jätä ketään huomioitta globaalisti."
|
||||
|
||||
#: plugin.py:345
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Clears the current send queue for this network.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"ei ota parametrejä\n"
|
||||
"\n"
|
||||
" Tyhjentää nykyisen lähetysjonon tälle verkolle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:354
|
||||
msgid ""
|
||||
"<command> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Perform <command> (with associated <arg>s on all channels on current "
|
||||
"network."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "takes no arguments\n"
|
||||
#~ "\n"
|
||||
#~ " Returns the channels the bot is on. Must be given in private, in "
|
||||
#~ "order\n"
|
||||
#~ " to protect the secrecy of secret channels.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "Ei ota parametrejä\n"
|
||||
#~ "\n"
|
||||
#~ " Palauttaa listan kanavista, joilla botti on. Täytyy antaa "
|
||||
#~ "yksityisviestillä salaistenkanavien\n"
|
||||
#~ " salaisuuden suojelemiseksi.\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid ""
|
||||
#~ "[<channel>] [<reason>]\n"
|
||||
#~ "\n"
|
||||
#~ " Tells the bot to part the list of channels you give it. "
|
||||
#~ "<channel> is\n"
|
||||
#~ " only necessary if you want the bot to part a channel other than "
|
||||
#~ "the\n"
|
||||
#~ " current channel. If <reason> is specified, use it as the part\n"
|
||||
#~ " message.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "[<kanava>] [<syy>]\n"
|
||||
#~ "\n"
|
||||
#~ " Käskee botin poistua kanavilta, jotka annat sille. <Kanava> on\n"
|
||||
#~ " vaadittu jos haluat botin poistuvat muulta, kuin \n"
|
||||
#~ " nykyiseltä kanavalta. Jos <syy> on määritetty, sitä käytetään\n"
|
||||
#~ " poistumisviestissä.\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid "I'm not in %s."
|
||||
#~ msgstr "Minä en ole kanavalla %s."
|
||||
|
||||
#~ msgid "That nick is currently banned."
|
||||
#~ msgstr "Tuolla nimimerkillä on tällähetkellä porttikielto."
|
@ -1,268 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: ProgVal <progval@gmail.com>\n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-SourceCharset: Ascii\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"This plugin provides access to administrative commands, such as\n"
|
||||
" adding capabilities, managing ignore lists, and joining channels.\n"
|
||||
" This is a core Supybot plugin that should not be removed!"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:57
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr "Nick/canal temporairement indisponible"
|
||||
|
||||
#: plugin.py:85
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr "Ne peut joindre %s, il est plein."
|
||||
|
||||
#: plugin.py:93
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr "Ne peut joindre %s, pas invité."
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "Cannot join %s, I am banned."
|
||||
msgstr "Ne peut joindre %s, j'y suis banni."
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr "Ne peut joindre %s, mon mot de passe est mauvais."
|
||||
|
||||
#: plugin.py:117 plugin.py:126
|
||||
msgid "Cannot join %s, I'm not identified with NickServ."
|
||||
msgstr "Ne peut joindre %s, je ne suis pas identifié auprès de NickServ."
|
||||
|
||||
#: plugin.py:156
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is "
|
||||
"used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canal> [<clef>]\n"
|
||||
"\n"
|
||||
"Dit au bot de rejoindre le canal donné. Si la <clef> est donnée, elle est "
|
||||
"utilisée pour rejoindre le canal."
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "channel"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr "Je suis déjà sur un nombre de canaux trop grand pour ce réseau."
|
||||
|
||||
#: plugin.py:178
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ne prend pas d'argument\n"
|
||||
"\n"
|
||||
"Liste les masques d'hôte que le bot ignore."
|
||||
|
||||
#: plugin.py:187
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr "Je ne suis actuellement sur aucun canal."
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr "Ma connexion est restreinte, je ne peux changer de nick."
|
||||
|
||||
#: plugin.py:200
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr "Quelqu'un d'autre utilise déjà ce nick."
|
||||
|
||||
#: plugin.py:207
|
||||
#, fuzzy
|
||||
msgid "I can't change nick, I'm currently banned in %s."
|
||||
msgstr "Je ne peux changer de nick, le serveur a dit %q."
|
||||
|
||||
#: plugin.py:215
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr "Je ne peux changer de nick, le serveur a dit %q."
|
||||
|
||||
#: plugin.py:229
|
||||
msgid ""
|
||||
"[<nick>] [<network>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<nick>] [<réseau>]\n"
|
||||
"\n"
|
||||
"Change le nick du bot à <nick>. Si aucun nick n'est donné, retourne le nick "
|
||||
"actuel du bot."
|
||||
|
||||
#: plugin.py:248
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom "
|
||||
"<hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nom|masque d'hôte> <capacité>\n"
|
||||
"\n"
|
||||
"Donne la <capacité> à l'utilisateur spécifié par <nom> (ou l'utilisateur à "
|
||||
"qui correspond <masque d'hôte>)."
|
||||
|
||||
#: plugin.py:268
|
||||
msgid ""
|
||||
"The \"owner\" capability can't be added in the bot. Use the supybot-adduser "
|
||||
"program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr ""
|
||||
"La capacité \"owner\" ne peut être ajoutée via le bot. Utilisez le programme "
|
||||
"supybot-adduser (ou éditez le fichier users.conf vous-même) pour ajouter la "
|
||||
"capacité owner."
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr "Vous ne pouvez ajouter des capacités que vous n'avez pas."
|
||||
|
||||
#: plugin.py:284
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability "
|
||||
"<capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nom|masque d'hôte> <capacité>\n"
|
||||
"\n"
|
||||
"Retire la <capacité> à l'utilisateur spécifié par le <nom> (ou celui à qui "
|
||||
"correspond le <masque d'hôte>)."
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr "Cet utilisateur n'a pas cette capacité."
|
||||
|
||||
#: plugin.py:298
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr "Vous ne pouvez retirer des capacités que vous n'avez pas."
|
||||
|
||||
#: plugin.py:306
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional "
|
||||
"argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will "
|
||||
"expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<masque d'hôte|nick> [<expiration>]\n"
|
||||
"\n"
|
||||
"Ajoute un masque d'ignorance persistant sur le <masque d'hôte>, ou sur le "
|
||||
"masque d'hôte de <nick>. <expiration> est un argument optionnel spécifiant "
|
||||
"quand (en \"secondes à partir de maintenant\") l'ignorance expirera ; si "
|
||||
"elle n'est pas donnée, l'ignorance n'expirera jamais."
|
||||
|
||||
#: plugin.py:319
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<masque d'hôte|nick>\n"
|
||||
"\n"
|
||||
"Ceci retirera le masque d'ignorance persistant sur le <masque d'hôte>, ou "
|
||||
"sur le masque d'hôte associé au <nick>."
|
||||
|
||||
#: plugin.py:328
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr "%s n'étais pas dans ma base de données d'ignorance."
|
||||
|
||||
#: plugin.py:333
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ne prend pas d'argument\n"
|
||||
"\n"
|
||||
"Liste les masques d'hôte que le bot ignore."
|
||||
|
||||
#: plugin.py:341
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr "Je n'ignore actuellement personne globalement."
|
||||
|
||||
#: plugin.py:345
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Clears the current send queue for this network.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ne prend pas d'argument\n"
|
||||
"\n"
|
||||
"Vide la queue en attente pour ce réseau."
|
||||
|
||||
#: plugin.py:354
|
||||
msgid ""
|
||||
"<command> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Perform <command> (with associated <arg>s on all channels on current "
|
||||
"network."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "takes no arguments\n"
|
||||
#~ "\n"
|
||||
#~ " Returns the channels the bot is on. Must be given in private, in "
|
||||
#~ "order\n"
|
||||
#~ " to protect the secrecy of secret channels.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "Ne prend pas d'argument \n"
|
||||
#~ "\n"
|
||||
#~ "Retourne les canaux sur lesquels le bot est. Doit être en privé, dans le "
|
||||
#~ "but d'éviter que les canaux secrets ne soient divulgués."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "[<channel>] [<reason>]\n"
|
||||
#~ "\n"
|
||||
#~ " Tells the bot to part the list of channels you give it. "
|
||||
#~ "<channel> is\n"
|
||||
#~ " only necessary if you want the bot to part a channel other than "
|
||||
#~ "the\n"
|
||||
#~ " current channel. If <reason> is specified, use it as the part\n"
|
||||
#~ " message.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "[<canal>] [<raison>]\n"
|
||||
#~ "\n"
|
||||
#~ "Dit au bot de partir de la liste de canaux que vous avez donnée. <canal> "
|
||||
#~ "n'est nécessaire que si vous voulez que le bot parte d'un autre canal que "
|
||||
#~ "l'actuel. Si la <raison> est spécifiée, elle est utilisée comme message "
|
||||
#~ "de départ."
|
||||
|
||||
#~ msgid "I'm not in %s."
|
||||
#~ msgstr "Je ne suis pas sur %s."
|
||||
|
||||
#~ msgid "That nick is currently banned."
|
||||
#~ msgstr "Ce nick est banni."
|
@ -1,287 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2012-03-15 20:25+0100\n"
|
||||
"Last-Translator: skizzhg <skizzhg@gmx.com>\n"
|
||||
"Language-Team: Italian <skizzhg@gmx.com>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"This plugin provides access to administrative commands, such as\n"
|
||||
" adding capabilities, managing ignore lists, and joining channels.\n"
|
||||
" This is a core Supybot plugin that should not be removed!"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:57
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr "Nick/canale temporaneamente non disponibile."
|
||||
|
||||
#: plugin.py:85
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr "Non posso entrare in %s, è pieno."
|
||||
|
||||
#: plugin.py:93
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr "Non posso entrare in %s, non sono stato invitato."
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "Cannot join %s, I am banned."
|
||||
msgstr "Non posso entrare in %s, sono stato bannato."
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr "Non posso entrare in %s, la password era sbagliata."
|
||||
|
||||
#: plugin.py:117 plugin.py:126
|
||||
msgid "Cannot join %s, I'm not identified with NickServ."
|
||||
msgstr "Non posso entrare in %s, non sono identificato con NickServ."
|
||||
|
||||
#: plugin.py:156
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is "
|
||||
"used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canale> [<password>]\n"
|
||||
"\n"
|
||||
" Dice al bot di entrare nel canale specificato. Se <password> è "
|
||||
"fornita,\n"
|
||||
" viene usata quando si tenta di entrare nel canale.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "channel"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr "Sono già troppo vicino al numero massimo di canali per questa rete."
|
||||
|
||||
#: plugin.py:178
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Non necessita argomenti\n"
|
||||
"\n"
|
||||
" Elenca le hostmask che il bot sta ignorando.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:187
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr "Al momento non sono in nessun canale."
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr "La mia connessione è limitata, non posso cambiare nick."
|
||||
|
||||
#: plugin.py:200
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr "Qualcun altro sta utilizzando questo nick."
|
||||
|
||||
#: plugin.py:207
|
||||
#, fuzzy
|
||||
msgid "I can't change nick, I'm currently banned in %s."
|
||||
msgstr "Non posso cambiare nick, il server ha detto %q."
|
||||
|
||||
#: plugin.py:215
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr "Non posso cambiare nick, il server ha detto %q."
|
||||
|
||||
#: plugin.py:229
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"[<nick>] [<network>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<nick>]\n"
|
||||
"\n"
|
||||
" Cambia il nick del bot in <nick>. Se non ne viene fornito uno, "
|
||||
"restituisce\n"
|
||||
" quello attuale.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:248
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom "
|
||||
"<hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nome|hostmask> <capacità>\n"
|
||||
"\n"
|
||||
" Dà all'utente specificato da <nome> (o quello a cui corrisponde\n"
|
||||
" <hostmask> attualmente) la <capacità> specificata.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:268
|
||||
msgid ""
|
||||
"The \"owner\" capability can't be added in the bot. Use the supybot-adduser "
|
||||
"program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr ""
|
||||
"La capacità \"owner\" non può essere aggiunta al bot. Utilizzare il "
|
||||
"programma supybot-adduser (o modificare il file users.conf) per aggiungerla."
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr "Non puoi aggiungere capacità che non hai."
|
||||
|
||||
#: plugin.py:284
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability "
|
||||
"<capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nome|hostmask> <capacità>\n"
|
||||
"\n"
|
||||
" Rimuove l'utente specificato da <nome> (o quello a cui "
|
||||
"corrisponde\n"
|
||||
" <hostmask> attualmente) la <capacità> specificata\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr "Questo utente non ha tale capacità."
|
||||
|
||||
#: plugin.py:298
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr "Non puoi rimuovere capacità che non hai."
|
||||
|
||||
#: plugin.py:306
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional "
|
||||
"argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will "
|
||||
"expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nick> [<scadenza>]\n"
|
||||
"\n"
|
||||
" Imposta un ignore permanente su <hostmask> o l'hostmask "
|
||||
"attualmente\n"
|
||||
" associata a <nick>. <scadenza> è un argomento opzionale per "
|
||||
"specificare\n"
|
||||
" quando (in \"secondi a partire da subito\") scadrà l'ignore; se "
|
||||
"non fornito,\n"
|
||||
" questo non scadrà mai.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:319
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" Rimuove l'ignore persistente su <hostmask> o l'attuale hostmask "
|
||||
"associata a <nick>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:328
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr "%s non è nel mio database degli ignorati."
|
||||
|
||||
#: plugin.py:333
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Non necessita argomenti\n"
|
||||
"\n"
|
||||
" Elenca le hostmask che il bot sta ignorando.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:341
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr "Al momento non sto ignorando nessuno."
|
||||
|
||||
#: plugin.py:345
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Clears the current send queue for this network.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"non necessita argomenti\n"
|
||||
"\n"
|
||||
" Pulisce l'attuale coda dei messaggi da inviare (interrompe il flood) "
|
||||
"per questa rete.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:354
|
||||
msgid ""
|
||||
"<command> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Perform <command> (with associated <arg>s on all channels on current "
|
||||
"network."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "takes no arguments\n"
|
||||
#~ "\n"
|
||||
#~ " Returns the channels the bot is on. Must be given in private, in "
|
||||
#~ "order\n"
|
||||
#~ " to protect the secrecy of secret channels.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "non necessita argomenti\n"
|
||||
#~ "\n"
|
||||
#~ " Restituisce i canali dove è presente il bot. Deve essere "
|
||||
#~ "richiesto in\n"
|
||||
#~ " privato per preservare la segretezza dei canali privati.\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid ""
|
||||
#~ "[<channel>] [<reason>]\n"
|
||||
#~ "\n"
|
||||
#~ " Tells the bot to part the list of channels you give it. "
|
||||
#~ "<channel> is\n"
|
||||
#~ " only necessary if you want the bot to part a channel other than "
|
||||
#~ "the\n"
|
||||
#~ " current channel. If <reason> is specified, use it as the part\n"
|
||||
#~ " message.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "[<canale>] [<motivo>]\n"
|
||||
#~ "\n"
|
||||
#~ " Fornisce al bot l'elenco dei canali da cui uscire. <canale> è "
|
||||
#~ "necessario\n"
|
||||
#~ " solo se si vuole far uscire il bot da un canale diverso da quello "
|
||||
#~ "attuale.\n"
|
||||
#~ " Se <motivo> viene specificato, verrà usato come messaggio di "
|
||||
#~ "uscita.\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid "I'm not in %s."
|
||||
#~ msgstr "Non sono in %s."
|
||||
|
||||
#~ msgid "That nick is currently banned."
|
||||
#~ msgstr "Il nick è attualmente bannato."
|
@ -1,199 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: plugin.py:46
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin provides access to administrative commands, such as\n"
|
||||
" adding capabilities, managing ignore lists, and joining channels.\n"
|
||||
" This is a core Supybot plugin that should not be removed!"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:57
|
||||
#, docstring
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:85
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:93
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "Cannot join %s, I am banned."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:117 plugin.py:126
|
||||
msgid "Cannot join %s, I'm not identified with NickServ."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:156
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "channel"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:178
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:187
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:200
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:207
|
||||
msgid "I can't change nick, I'm currently banned in %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:215
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:229
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<nick>] [<network>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:248
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom <hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:268
|
||||
msgid "The \"owner\" capability can't be added in the bot. Use the supybot-adduser program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:284
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:298
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:306
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:319
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:328
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:333
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:341
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:345
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Clears the current send queue for this network.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:354
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<command> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Perform <command> (with associated <arg>s on all channels on current network."
|
||||
msgstr ""
|
||||
|
@ -1,367 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2002-2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.ircdb as ircdb
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.ircmsgs as ircmsgs
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.schedule as schedule
|
||||
import supybot.callbacks as callbacks
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Admin')
|
||||
|
||||
class Admin(callbacks.Plugin):
|
||||
"""This plugin provides access to administrative commands, such as
|
||||
adding capabilities, managing ignore lists, and joining channels.
|
||||
This is a core Supybot plugin that should not be removed!"""
|
||||
def __init__(self, irc):
|
||||
self.__parent = super(Admin, self)
|
||||
self.__parent.__init__(irc)
|
||||
self.joins = {}
|
||||
self.pendingNickChanges = {}
|
||||
|
||||
@internationalizeDocstring
|
||||
def do437(self, irc, msg):
|
||||
"""Nick/channel temporarily unavailable."""
|
||||
target = msg.args[0]
|
||||
t = time.time() + 30
|
||||
if irc.isChannel(target):
|
||||
# Let's schedule a rejoin.
|
||||
networkGroup = conf.supybot.networks.get(irc.network)
|
||||
def rejoin():
|
||||
irc.queueMsg(networkGroup.channels.join(target))
|
||||
# We don't need to schedule something because we'll get another
|
||||
# 437 when we try to join later.
|
||||
schedule.addEvent(rejoin, t)
|
||||
self.log.info('Scheduling a rejoin to %s at %s; '
|
||||
'Channel temporarily unavailable.', target, t)
|
||||
else:
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
if irc is not None:
|
||||
def nick():
|
||||
irc.queueMsg(ircmsgs.nick(target))
|
||||
schedule.addEvent(nick, t)
|
||||
self.log.info('Scheduling a nick change to %s at %s; '
|
||||
'Nick temporarily unavailable.', target, t)
|
||||
else:
|
||||
self.log.debug('Got 437 without Admin.nick being called.')
|
||||
|
||||
def do471(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc, msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, it\'s full.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 471 without Admin.join being called.')
|
||||
|
||||
def do473(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc, msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, I was not invited.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 473 without Admin.join being called.')
|
||||
|
||||
def do474(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc, msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, I am banned.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 474 without Admin.join being called.')
|
||||
|
||||
def do475(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc, msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, my keyword was wrong.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 475 without Admin.join being called.')
|
||||
|
||||
def do477(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc,msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, I\'m not identified with '
|
||||
'NickServ.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 477 without Admin.join being called.')
|
||||
|
||||
def do515(self, irc, msg):
|
||||
try:
|
||||
channel = msg.args[1]
|
||||
(irc, msg) = self.joins.pop(channel)
|
||||
irc.error(_('Cannot join %s, I\'m not identified with '
|
||||
'NickServ.') % channel)
|
||||
except KeyError:
|
||||
self.log.debug('Got 515 without Admin.join being called.')
|
||||
|
||||
def doJoin(self, irc, msg):
|
||||
if msg.prefix == irc.prefix:
|
||||
try:
|
||||
del self.joins[msg.args[0]]
|
||||
except KeyError:
|
||||
s = 'Joined a channel without Admin.join being called.'
|
||||
self.log.debug(s)
|
||||
|
||||
def doInvite(self, irc, msg):
|
||||
channel = msg.args[1]
|
||||
if channel not in irc.state.channels:
|
||||
if conf.supybot.alwaysJoinOnInvite.get(channel)() or \
|
||||
ircdb.checkCapability(msg.prefix, 'admin'):
|
||||
self.log.info('Invited to %s by %s.', channel, msg.prefix)
|
||||
networkGroup = conf.supybot.networks.get(irc.network)
|
||||
irc.queueMsg(networkGroup.channels.join(channel))
|
||||
conf.supybot.networks.get(irc.network).channels().add(channel)
|
||||
else:
|
||||
self.log.warning('Invited to %s by %s, but '
|
||||
'supybot.alwaysJoinOnInvite was False and '
|
||||
'the user lacked the "admin" capability.',
|
||||
channel, msg.prefix)
|
||||
|
||||
@internationalizeDocstring
|
||||
def join(self, irc, msg, args, channel, key):
|
||||
"""<channel> [<key>]
|
||||
|
||||
Tell the bot to join the given channel. If <key> is given, it is used
|
||||
when attempting to join the channel.
|
||||
"""
|
||||
if not irc.isChannel(channel):
|
||||
irc.errorInvalid(_('channel'), channel, Raise=True)
|
||||
networkGroup = conf.supybot.networks.get(irc.network)
|
||||
networkGroup.channels().add(channel)
|
||||
if key:
|
||||
networkGroup.channels.key.get(channel).setValue(key)
|
||||
maxchannels = irc.state.supported.get('maxchannels', sys.maxsize)
|
||||
if len(irc.state.channels) + 1 > maxchannels:
|
||||
irc.error(_('I\'m already too close to maximum number of '
|
||||
'channels for this network.'), Raise=True)
|
||||
irc.queueMsg(networkGroup.channels.join(channel))
|
||||
irc.noReply()
|
||||
self.joins[channel] = (irc, msg)
|
||||
join = wrap(join, ['validChannel', additional('something')])
|
||||
|
||||
@internationalizeDocstring
|
||||
def channels(self, irc, msg, args):
|
||||
"""takes no arguments
|
||||
|
||||
Returns the channels the bot is on.
|
||||
"""
|
||||
L = irc.state.channels.keys()
|
||||
if L:
|
||||
utils.sortBy(ircutils.toLower, L)
|
||||
irc.reply(format('%L', L), private=True)
|
||||
else:
|
||||
irc.reply(_('I\'m not currently in any channels.'))
|
||||
channels = wrap(channels)
|
||||
|
||||
def do484(self, irc, msg):
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
if irc is not None:
|
||||
irc.error(_('My connection is restricted, I can\'t change nicks.'))
|
||||
else:
|
||||
self.log.debug('Got 484 without Admin.nick being called.')
|
||||
|
||||
def do433(self, irc, msg):
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
if irc is not None:
|
||||
irc.error(_('Someone else is already using that nick.'))
|
||||
else:
|
||||
self.log.debug('Got 433 without Admin.nick being called.')
|
||||
|
||||
def do435(self, irc, msg):
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
if irc is not None:
|
||||
irc.error(_('I can\'t change nick, I\'m currently banned in %s.') %
|
||||
msg.args[2])
|
||||
else:
|
||||
self.log.debug('Got 435 without Admin.nick being called.')
|
||||
|
||||
def do438(self, irc, msg):
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
if irc is not None:
|
||||
irc.error(format(_('I can\'t change nicks, the server said %q.'),
|
||||
msg.args[2]), private=True)
|
||||
else:
|
||||
self.log.debug('Got 438 without Admin.nick being called.')
|
||||
|
||||
def doNick(self, irc, msg):
|
||||
if msg.nick == irc.nick or msg.args[0] == irc.nick:
|
||||
try:
|
||||
del self.pendingNickChanges[irc]
|
||||
except KeyError:
|
||||
self.log.debug('Got NICK without Admin.nick being called.')
|
||||
|
||||
@internationalizeDocstring
|
||||
def nick(self, irc, msg, args, nick, network):
|
||||
"""[<nick>] [<network>]
|
||||
|
||||
Changes the bot's nick to <nick>. If no nick is given, returns the
|
||||
bot's current nick.
|
||||
"""
|
||||
network = network or irc.network
|
||||
if nick:
|
||||
group = getattr(conf.supybot.networks, network)
|
||||
group.nick.setValue(nick)
|
||||
irc.queueMsg(ircmsgs.nick(nick))
|
||||
self.pendingNickChanges[irc.getRealIrc()] = irc
|
||||
else:
|
||||
irc.reply(irc.nick)
|
||||
nick = wrap(nick, [additional('nick'), additional('something')])
|
||||
|
||||
class capability(callbacks.Commands):
|
||||
|
||||
@internationalizeDocstring
|
||||
def add(self, irc, msg, args, user, capability):
|
||||
"""<name|hostmask> <capability>
|
||||
|
||||
Gives the user specified by <name> (or the user to whom <hostmask>
|
||||
currently maps) the specified capability <capability>
|
||||
"""
|
||||
# Ok, the concepts that are important with capabilities:
|
||||
#
|
||||
### 1) No user should be able to elevate their privilege to owner.
|
||||
### 2) Admin users are *not* superior to #channel.ops, and don't
|
||||
### have God-like powers over channels.
|
||||
### 3) We assume that Admin users are two things: non-malicious and
|
||||
### and greedy for power. So they'll try to elevate their
|
||||
### privilege to owner, but they won't try to crash the bot for
|
||||
### no reason.
|
||||
|
||||
# Thus, the owner capability can't be given in the bot. Admin
|
||||
# users can only give out capabilities they have themselves (which
|
||||
# will depend on supybot.capabilities and its child default) but
|
||||
# generally means they can't mess with channel capabilities.
|
||||
if ircutils.strEqual(capability, 'owner'):
|
||||
irc.error(_('The "owner" capability can\'t be added in the '
|
||||
'bot. Use the supybot-adduser program (or edit the '
|
||||
'users.conf file yourself) to add an owner '
|
||||
'capability.'))
|
||||
return
|
||||
if ircdb.isAntiCapability(capability) or \
|
||||
ircdb.checkCapability(msg.prefix, capability):
|
||||
user.addCapability(capability)
|
||||
ircdb.users.setUser(user)
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('You can\'t add capabilities you don\'t have.'))
|
||||
add = wrap(add, ['otherUser', 'lowered'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def remove(self, irc, msg, args, user, capability):
|
||||
"""<name|hostmask> <capability>
|
||||
|
||||
Takes from the user specified by <name> (or the user to whom
|
||||
<hostmask> currently maps) the specified capability <capability>
|
||||
"""
|
||||
if ircdb.checkCapability(msg.prefix, capability) or \
|
||||
ircdb.isAntiCapability(capability):
|
||||
try:
|
||||
user.removeCapability(capability)
|
||||
ircdb.users.setUser(user)
|
||||
irc.replySuccess()
|
||||
except KeyError:
|
||||
irc.error(_('That user doesn\'t have that capability.'))
|
||||
else:
|
||||
s = _('You can\'t remove capabilities you don\'t have.')
|
||||
irc.error(s)
|
||||
remove = wrap(remove, ['otherUser','lowered'])
|
||||
|
||||
class ignore(callbacks.Commands):
|
||||
|
||||
@internationalizeDocstring
|
||||
def add(self, irc, msg, args, hostmask, expires):
|
||||
"""<hostmask|nick> [<expires>]
|
||||
|
||||
This will set a persistent ignore on <hostmask> or the hostmask
|
||||
currently associated with <nick>. <expires> is an optional argument
|
||||
specifying when (in "seconds from now") the ignore will expire; if
|
||||
it isn't given, the ignore will never automatically expire.
|
||||
"""
|
||||
ircdb.ignores.add(hostmask, expires)
|
||||
irc.replySuccess()
|
||||
add = wrap(add, ['hostmask', additional('expiry', 0)])
|
||||
|
||||
@internationalizeDocstring
|
||||
def remove(self, irc, msg, args, hostmask):
|
||||
"""<hostmask|nick>
|
||||
|
||||
This will remove the persistent ignore on <hostmask> or the
|
||||
hostmask currently associated with <nick>.
|
||||
"""
|
||||
try:
|
||||
ircdb.ignores.remove(hostmask)
|
||||
irc.replySuccess()
|
||||
except KeyError:
|
||||
irc.error(_('%s wasn\'t in the ignores database.') % hostmask)
|
||||
remove = wrap(remove, ['hostmask'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def list(self, irc, msg, args):
|
||||
"""takes no arguments
|
||||
|
||||
Lists the hostmasks that the bot is ignoring.
|
||||
"""
|
||||
# XXX Add the expirations.
|
||||
if ircdb.ignores.hostmasks:
|
||||
irc.reply(format('%L', (list(map(repr,ircdb.ignores.hostmasks)))))
|
||||
else:
|
||||
irc.reply(_('I\'m not currently globally ignoring anyone.'))
|
||||
list = wrap(list)
|
||||
|
||||
def clearq(self, irc, msg, args):
|
||||
"""takes no arguments
|
||||
|
||||
Clears the current send queue for this network.
|
||||
"""
|
||||
irc.queue.reset()
|
||||
irc.replySuccess()
|
||||
clearq = wrap(clearq)
|
||||
|
||||
def acmd(self, irc, msg, args, commandAndArgs):
|
||||
"""<command> [<arg> ...]
|
||||
|
||||
Perform <command> (with associated <arg>s on all channels on current network."""
|
||||
for channel in irc.state.channels:
|
||||
msg = ircmsgs.IrcMsg(msg=msg, args=(channel,) + msg.args[1:])
|
||||
self.Proxy(irc.getRealIrc(), msg, commandAndArgs)
|
||||
acmd = wrap(acmd, ['admin', many('something')])
|
||||
|
||||
|
||||
|
||||
|
||||
Class = Admin
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,140 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2002-2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
class AdminTestCase(PluginTestCase):
|
||||
plugins = ('Admin', 'Utilities')
|
||||
def testChannels(self):
|
||||
def getAfterJoinMessages():
|
||||
m = self.irc.takeMsg()
|
||||
self.assertEqual(m.command, 'MODE')
|
||||
m = self.irc.takeMsg()
|
||||
self.assertEqual(m.command, 'MODE')
|
||||
m = self.irc.takeMsg()
|
||||
self.assertEqual(m.command, 'WHO')
|
||||
self.assertRegexp('channels', 'not.*in any')
|
||||
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
||||
getAfterJoinMessages()
|
||||
self.assertRegexp('channels', '#foo')
|
||||
self.irc.feedMsg(ircmsgs.join('#bar', prefix=self.prefix))
|
||||
getAfterJoinMessages()
|
||||
self.assertRegexp('channels', '#bar and #foo')
|
||||
self.irc.feedMsg(ircmsgs.join('#Baz', prefix=self.prefix))
|
||||
getAfterJoinMessages()
|
||||
self.assertRegexp('channels', '#bar, #Baz, and #foo')
|
||||
|
||||
def testIgnoreAddRemove(self):
|
||||
self.assertNotError('admin ignore add foo!bar@baz')
|
||||
self.assertError('admin ignore add alsdkfjlasd')
|
||||
self.assertNotError('admin ignore remove foo!bar@baz')
|
||||
self.assertError('admin ignore remove foo!bar@baz')
|
||||
|
||||
def testIgnoreList(self):
|
||||
self.assertNotError('admin ignore list')
|
||||
self.assertNotError('admin ignore add foo!bar@baz')
|
||||
self.assertNotError('admin ignore list')
|
||||
self.assertNotError('admin ignore add foo!bar@baz')
|
||||
self.assertRegexp('admin ignore list', 'foo')
|
||||
|
||||
def testCapabilityAdd(self):
|
||||
self.assertError('capability add foo bar')
|
||||
u = ircdb.users.newUser()
|
||||
u.name = 'foo'
|
||||
ircdb.users.setUser(u)
|
||||
self.assertNotError('capability add foo bar')
|
||||
self.assertError('addcapability foo baz')
|
||||
self.assertIn('bar', u.capabilities)
|
||||
ircdb.users.delUser(u.id)
|
||||
|
||||
def testCapabilityRemove(self):
|
||||
self.assertError('capability remove foo bar')
|
||||
u = ircdb.users.newUser()
|
||||
u.name = 'foo'
|
||||
ircdb.users.setUser(u)
|
||||
self.assertNotError('capability add foo bar')
|
||||
self.assertIn('bar', u.capabilities)
|
||||
self.assertError('removecapability foo bar')
|
||||
self.assertNotError('capability remove foo bar')
|
||||
self.assertNotIn('bar', u.capabilities)
|
||||
ircdb.users.delUser(u.id)
|
||||
|
||||
def testJoin(self):
|
||||
m = self.getMsg('join #foo')
|
||||
self.assertEqual(m.command, 'JOIN')
|
||||
self.assertEqual(m.args[0], '#foo')
|
||||
m = self.getMsg('join #foo key')
|
||||
self.assertEqual(m.command, 'JOIN')
|
||||
self.assertEqual(m.args[0], '#foo')
|
||||
self.assertEqual(m.args[1], 'key')
|
||||
|
||||
def testNick(self):
|
||||
try:
|
||||
m = self.getMsg('nick foobar')
|
||||
self.assertEqual(m.command, 'NICK')
|
||||
self.assertEqual(m.args[0], 'foobar')
|
||||
finally:
|
||||
conf.supybot.networks.test.nick.setValue('')
|
||||
|
||||
def testAddCapabilityOwner(self):
|
||||
self.assertError('admin capability add %s owner' % self.nick)
|
||||
|
||||
def testJoinOnOwnerInvite(self):
|
||||
self.irc.feedMsg(ircmsgs.invite(conf.supybot.nick(), '#foo', prefix=self.prefix))
|
||||
m = self.getMsg(' ')
|
||||
self.assertEqual(m.command, 'JOIN')
|
||||
self.assertEqual(m.args[0], '#foo')
|
||||
|
||||
def testNoJoinOnUnprivilegedInvite(self):
|
||||
try:
|
||||
world.testing = False
|
||||
for channel in '#foo', '#foo\u0009':
|
||||
self.irc.feedMsg(ircmsgs.invite(conf.supybot.nick(), channel, prefix='foo!bar@baz'))
|
||||
self.assertResponse('somecommand',
|
||||
'Error: "somecommand" is not a valid command.')
|
||||
finally:
|
||||
world.testing = True
|
||||
|
||||
def testAcmd(self):
|
||||
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
||||
self.irc.feedMsg(ircmsgs.join('#bar', prefix=self.prefix))
|
||||
while self.irc.takeMsg():
|
||||
pass
|
||||
msgs = []
|
||||
msg = self.getMsg('acmd echo hi $channel')
|
||||
while msg:
|
||||
msgs.append(msg)
|
||||
msg = self.irc.takeMsg()
|
||||
self.assertCountEqual(
|
||||
[(msg.command,) + msg.args for msg in msgs],
|
||||
[("PRIVMSG", "#foo", "hi #foo"), ("PRIVMSG", "#bar", "hi #bar")])
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
@ -1,157 +0,0 @@
|
||||
.. _plugin-Aka:
|
||||
|
||||
Documentation for the Aka plugin for Supybot
|
||||
============================================
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
This plugin allows the user to create various aliases (known as "Akas", since
|
||||
Alias is the name of another plugin Aka is based on) to other commands or
|
||||
combinations of other commands (via nested commands).
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This plugin allows users to define aliases to commands and combinations
|
||||
of commands (via nesting).
|
||||
|
||||
Importing from Alias
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add an aka, Alias, which eases the transitioning to Aka from Alias.
|
||||
|
||||
First we will load Alias and Aka::
|
||||
|
||||
<jamessan> @load Alias
|
||||
<bot> jamessan: The operation succeeded.
|
||||
<jamessan> @load Aka
|
||||
<bot> jamessan: The operation succeeded.
|
||||
|
||||
Then we import the Alias database to Aka in case it exists and unload
|
||||
Alias::
|
||||
|
||||
<jamessan> @importaliasdatabase
|
||||
<bot> jamessan: The operation succeeded.
|
||||
<jamessan> @unload Alias
|
||||
<bot> jamessan: The operation succeeded.
|
||||
|
||||
And now we will finally add the Aka ``alias`` itself::
|
||||
|
||||
<jamessan> @aka add "alias" "aka $1 $*"
|
||||
<bot> jamessan: The operation succeeded.
|
||||
|
||||
Now you can use Aka as you used Alias before.
|
||||
|
||||
Trout
|
||||
^^^^^
|
||||
|
||||
Add an aka, ``trout``, which expects a word as an argument::
|
||||
|
||||
<jamessan> @aka add trout "reply action slaps $1 with a large trout"
|
||||
<bot> jamessan: The operation succeeded.
|
||||
<jamessan> @trout me
|
||||
* bot slaps me with a large trout
|
||||
|
||||
This ``trout`` aka requires the plugin ``Reply`` to be loaded since it
|
||||
provides the ``action`` command.
|
||||
|
||||
Random percentage
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add an aka, ``randpercent``, which returns a random percentage value::
|
||||
|
||||
@aka add randpercent "squish [dice 1d100]%"
|
||||
|
||||
This requires the ``Filter`` and ``Games`` plugins to be loaded.
|
||||
|
||||
Note that nested commands in an alias should be quoted, or they will only
|
||||
run once when you create the alias, and not each time the alias is
|
||||
called. (In this case, not quoting the nested command would mean that
|
||||
``@randpercent`` always responds with the same value!)
|
||||
|
||||
.. _commands-Aka:
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
.. _command-aka-add:
|
||||
|
||||
add [--channel <#channel>] <name> <command>
|
||||
Defines an alias <name> that executes <command>. The <command> should be in the standard "command argument [nestedcommand argument]" arguments to the alias; they'll be filled with the first, second, etc. arguments. $1, $2, etc. can be used for required arguments. @1, @2, etc. can be used for optional arguments. $* simply means "all arguments that have not replaced $1, $2, etc.", ie. it will also include optional arguments.
|
||||
|
||||
.. _command-aka-remove:
|
||||
|
||||
remove [--channel <#channel>] <name>
|
||||
Removes the given alias, if unlocked.
|
||||
|
||||
.. _command-aka-lock:
|
||||
|
||||
lock [--channel <#channel>] <alias>
|
||||
Locks an alias so that no one else can change it.
|
||||
|
||||
.. _command-aka-unlock:
|
||||
|
||||
unlock [--channel <#channel>] <alias>
|
||||
Unlocks an alias so that people can define new aliases over it.
|
||||
|
||||
.. _command-aka-importaliasdatabase:
|
||||
|
||||
importaliasdatabase takes no arguments
|
||||
Imports the Alias database into Aka's, and clean the former.
|
||||
|
||||
.. _command-aka-show:
|
||||
|
||||
show [--channel <#channel>] <alias>
|
||||
This command shows the content of an Aka.
|
||||
|
||||
.. _command-aka-list:
|
||||
|
||||
list [--channel <#channel>] [--keys] [--unlocked|--locked]
|
||||
Lists all Akas defined for <channel>. If <channel> is not specified, lists all global Akas. If --keys is given, lists only the Aka names and not their commands.
|
||||
|
||||
.. _command-aka-set:
|
||||
|
||||
set [--channel <#channel>] <name> <command>
|
||||
Overwrites an existing alias <name> to execute <command> instead. The <command> should be in the standard "command argument [nestedcommand argument]" arguments to the alias; they'll be filled with the first, second, etc. arguments. $1, $2, etc. can be used for required arguments. @1, @2, etc. can be used for optional arguments. $* simply means "all arguments that have not replaced $1, $2, etc.", ie. it will also include optional arguments.
|
||||
|
||||
.. _command-aka-search:
|
||||
|
||||
search [--channel <#channel>] <query>
|
||||
Searches Akas defined for <channel>. If <channel> is not specified, searches all global Akas.
|
||||
|
||||
.. _conf-Aka:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
.. _conf-supybot.plugins.Aka.maximumWordsInName:
|
||||
|
||||
|
||||
supybot.plugins.Aka.maximumWordsInName
|
||||
This config variable defaults to "5", is not network-specific, and is not channel-specific.
|
||||
|
||||
The maximum number of words allowed in a command name. Setting this to an high value may slow down your bot on long commands.
|
||||
|
||||
.. _conf-supybot.plugins.Aka.public:
|
||||
|
||||
|
||||
supybot.plugins.Aka.public
|
||||
This config variable defaults to "True", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin is publicly visible.
|
||||
|
||||
.. _conf-supybot.plugins.Aka.web:
|
||||
|
||||
|
||||
supybot.plugins.Aka.web
|
||||
This is a group of:
|
||||
|
||||
.. _conf-supybot.plugins.Aka.web.enable:
|
||||
|
||||
|
||||
supybot.plugins.Aka.web.enable
|
||||
This config variable defaults to "False", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether the Akas will be browsable through the HTTP server.
|
||||
|
@ -1,70 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2013-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
###
|
||||
|
||||
"""
|
||||
This plugin allows the user to create various aliases (known as "Akas", since
|
||||
Alias is the name of another plugin Aka is based on) to other commands or
|
||||
combinations of other commands (via nested commands).
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = ""
|
||||
|
||||
__author__ = supybot.authors.progval
|
||||
__maintainer__ = supybot.authors.limnoria_core
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
# This is a url where the most recent plugin package can be downloaded.
|
||||
__url__ = '' # 'http://supybot.com/Members/yourname/Aka/download'
|
||||
|
||||
from . import config
|
||||
from . import plugin
|
||||
from importlib import reload
|
||||
# In case we're being reloaded.
|
||||
reload(config)
|
||||
reload(plugin)
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
|
||||
if world.testing:
|
||||
from . import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
@ -1,64 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2013-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
_ = PluginInternationalization('Aka')
|
||||
except:
|
||||
# Placeholder that allows to run the plugin on a bot
|
||||
# without the i18n module
|
||||
_ = lambda x:x
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified themself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('Aka', True)
|
||||
|
||||
|
||||
Aka = conf.registerPlugin('Aka')
|
||||
# This is where your configuration variables (if any) should go. For example:
|
||||
# conf.registerGlobalValue(Aka, 'someConfigVariableName',
|
||||
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
|
||||
conf.registerGlobalValue(Aka, 'maximumWordsInName',
|
||||
registry.Integer(5, _("""The maximum number of words allowed in a
|
||||
command name. Setting this to an high value may slow down your bot
|
||||
on long commands.""")))
|
||||
|
||||
conf.registerGroup(Aka, 'web')
|
||||
conf.registerGlobalValue(Aka.web, 'enable',
|
||||
registry.Boolean(False, _("""Determines whether the Akas will be
|
||||
browsable through the HTTP server.""")))
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
@ -1 +0,0 @@
|
||||
# Stub so local is a module, used for third-party modules
|
@ -1,376 +0,0 @@
|
||||
# Aka plugin for Limnoria
|
||||
# Copyright (C) 2014 Limnoria
|
||||
# Mikaela Suomalainen <mikaela.suomalainen@outlook.com>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Aka plugin for Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2014-12-20 13:57+0200\n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fi\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: config.py:55
|
||||
msgid ""
|
||||
"The maximum number of words allowed in a\n"
|
||||
" command name. Setting this to an high value may slow down your bot\n"
|
||||
" on long commands."
|
||||
msgstr ""
|
||||
"Komennon nimessä sallittujen merkkien enimmäismäärä.\n"
|
||||
" Korkean arvon asettaminen tähän voi hidastaa bottiasi pitkien komentojen "
|
||||
"kanssa."
|
||||
|
||||
#: config.py:61
|
||||
msgid ""
|
||||
"Determines whether the Akas will be\n"
|
||||
" browsable through the HTTP server."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:141 plugin.py:274 plugin.py:732
|
||||
msgid "This Aka already exists."
|
||||
msgstr "Tämä Aka on jo olemassa."
|
||||
|
||||
#: plugin.py:170 plugin.py:182 plugin.py:196 plugin.py:301 plugin.py:318
|
||||
#: plugin.py:335 plugin.py:912
|
||||
msgid "This Aka does not exist."
|
||||
msgstr "Tätä Akaa ei ole olemassa."
|
||||
|
||||
#: plugin.py:303
|
||||
msgid "This Aka is already locked."
|
||||
msgstr "Tämä Aka on jo lukittu."
|
||||
|
||||
#: plugin.py:320
|
||||
msgid "This Aka is already unlocked."
|
||||
msgstr "Tämä Aka on jo avattu."
|
||||
|
||||
#: plugin.py:465
|
||||
#, fuzzy
|
||||
msgid "By %s at %s"
|
||||
msgstr "Lukinnut %s aikaan %s"
|
||||
|
||||
#: plugin.py:501
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
"\n"
|
||||
" Importing from Alias\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, Alias, which eases the transitioning to Aka from Alias.\n"
|
||||
"\n"
|
||||
" First we will load Alias and Aka::\n"
|
||||
"\n"
|
||||
" <jamessan> @load Alias\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @load Aka\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" Then we import the Alias database to Aka in case it exists and unload\n"
|
||||
" Alias::\n"
|
||||
"\n"
|
||||
" <jamessan> @importaliasdatabase\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @unload Alias\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" And now we will finally add the Aka ``alias`` itself::\n"
|
||||
"\n"
|
||||
" <jamessan> @aka add \"alias\" \"aka $1 $*\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" Now you can use Aka as you used Alias before.\n"
|
||||
"\n"
|
||||
" Trout\n"
|
||||
" ^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, trout, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @aka add trout \"reply action slaps $1 with a large trout"
|
||||
"\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" This ``trout`` aka requires the plugin ``Reply`` to be loaded since it\n"
|
||||
" provides the ``action`` command.\n"
|
||||
"\n"
|
||||
" LastFM\n"
|
||||
" ^^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, ``lastfm``, which expects a last.fm username and replies "
|
||||
"with\n"
|
||||
" their most recently played item::\n"
|
||||
"\n"
|
||||
" @aka add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [web urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" This ``lastfm`` aka requires the following plugins to be loaded: "
|
||||
"``RSS``,\n"
|
||||
" ``Format`` and ``Web``.\n"
|
||||
"\n"
|
||||
" ``RSS`` provides ``rss``, ``Format`` provides ``concat`` and ``Web`` "
|
||||
"provides\n"
|
||||
" ``urlquote``.\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and ``@lastfm`` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:699
|
||||
msgid "You've attempted more nesting than is currently allowed on this bot."
|
||||
msgstr ""
|
||||
"Olet yrittänyt sisällyttää enemmän komentoja, kuin tässä botti sallii juuri "
|
||||
"nyt."
|
||||
|
||||
#: plugin.py:703
|
||||
msgid " at least"
|
||||
msgstr "ainakin"
|
||||
|
||||
#: plugin.py:712
|
||||
msgid "Locked by %s at %s"
|
||||
msgstr "Lukinnut %s aikaan %s"
|
||||
|
||||
#: plugin.py:717
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<a global alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q.%s"
|
||||
msgstr ""
|
||||
"<alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias komennolle %q.%s"
|
||||
|
||||
#: plugin.py:718 plugin.py:722
|
||||
msgid "argument"
|
||||
msgstr "parametri"
|
||||
|
||||
#: plugin.py:721
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<an alias on %s,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q.%s"
|
||||
msgstr ""
|
||||
"<alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias komennolle %q.%s"
|
||||
|
||||
#: plugin.py:729
|
||||
msgid "You can't overwrite commands in this plugin."
|
||||
msgstr "Et voi ylikirjoittaa tämän lisä-osan komentoja."
|
||||
|
||||
#: plugin.py:734
|
||||
msgid "This Aka has too many spaces in its name."
|
||||
msgstr "Tämän Akan nimessä on liian monta välilyöntiä."
|
||||
|
||||
#: plugin.py:739
|
||||
msgid "Can't mix $* and optional args (@1, etc.)"
|
||||
msgstr ""
|
||||
"$*:ä ja vapaaehtoisia parametrejä (@1, jne.) ei voida sekoittaa keskenään"
|
||||
|
||||
#: plugin.py:746
|
||||
msgid "This Aka is locked."
|
||||
msgstr "Tämä Aka on lukittu."
|
||||
|
||||
#: plugin.py:750
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" arguments that have not replaced $1, $2, etc.\", ie. it will also\n"
|
||||
" include optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[--channel <#kanava>] <nimi> <komento>\n"
|
||||
"\n"
|
||||
"Määrittää aliaksen <nimi>, joka suorittaa <komennon>. <Komennon>\n"
|
||||
" pitäisi olla tavallisessa muodossa \"komento parametri [sisällytettykomento "
|
||||
"parametri]\"\n"
|
||||
" parametreinä aliakselle; ne täytetään ensimmäisenä, toisena, jne.\n"
|
||||
" parametreinä. $1, $2, jne. voidaan käyttää vaadittuina parametreinä. @1, "
|
||||
"@2,\n"
|
||||
" jne. voidaan käyttää vapaaehtoisina parametreinä. $* tarkoittaa "
|
||||
"yksinkertaisesti \"kaikki\n"
|
||||
" jotka eivät ole korvanneet $1, $2, jne.\", esim. se sisältää vapaa-ehtoiset "
|
||||
"parametrit.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:764 plugin.py:796 plugin.py:827 plugin.py:859 plugin.py:882
|
||||
#: plugin.py:905 plugin.py:951 plugin.py:994
|
||||
msgid "%r is not a valid channel."
|
||||
msgstr "%r ei ole kelvollinen kanava."
|
||||
|
||||
#: plugin.py:782
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name> <command>\n"
|
||||
"\n"
|
||||
" Overwrites an existing alias <name> to execute <command> instead. "
|
||||
"The\n"
|
||||
" <command> should be in the standard \"command argument "
|
||||
"[nestedcommand\n"
|
||||
" argument]\" arguments to the alias; they'll be filled with the "
|
||||
"first,\n"
|
||||
" second, etc. arguments. $1, $2, etc. can be used for required\n"
|
||||
" arguments. @1, @2, etc. can be used for optional arguments. $* "
|
||||
"simply\n"
|
||||
" means \"all arguments that have not replaced $1, $2, etc.\", ie. it "
|
||||
"will\n"
|
||||
" also include optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[--kanava <#kanava>] <nimi> <komento>\n"
|
||||
" Ylikirjoittaa olemassa olevan aliaksen <nimi> suorittamaan <komennon> "
|
||||
"sensijaan. <Komennon>\n"
|
||||
" pitäisi olla standardissa \"komento parametri [sisäkkäinen komento\" "
|
||||
"parametreinä aliakselle; ne täytetään\n"
|
||||
" ensimmäisillä, toisilla jne. parametreillä. $1, $2, jne. voidaan käyttää "
|
||||
"vaadittuihin parametreihin. $*\n"
|
||||
" yksinkertaisesti tarkoittaa \"kaikki parametrin, joita ei ole korvattu $1, "
|
||||
"$2 jne.\", esimerkiksi. se sisällyttää\n"
|
||||
" myös kaikki vapaaehtoiset parametrit."
|
||||
|
||||
#: plugin.py:819
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[--channel <#kanava>] <nimi>\n"
|
||||
"\n"
|
||||
" Poistaa annetun aliaksen, ellei se ole lukittu.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:841
|
||||
msgid ""
|
||||
"Check if the user has any of the required capabilities to manage\n"
|
||||
" the regexp database."
|
||||
msgstr ""
|
||||
"Tarkistaa onko käyttäjällä vaadittu valtuus säännöllisten lausekkeiden\n"
|
||||
" tietokannan hallintaan."
|
||||
|
||||
#: plugin.py:851
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[--channel <#kanava>] <alias>\n"
|
||||
"\n"
|
||||
" Lukitsee aliaksen estäen muita muokkaamasta sitä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:874
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[--channel <#kanava>] <alias>\n"
|
||||
"\n"
|
||||
" Avaa aliaksen, jotta kaikki voivat määrittää uusia aliaksia sen päälle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:897
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" This command shows the content of an Aka.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<komento> <#kanava> <alias>\n"
|
||||
"\n"
|
||||
" Tämä komento näyttää Akan sisällön."
|
||||
|
||||
#: plugin.py:917
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Imports the Alias database into Aka's, and clean the former."
|
||||
msgstr ""
|
||||
"ei ota parametrejä\n"
|
||||
"\n"
|
||||
" Tuo Aliaksen tietokannan Akaan ja tyhjentää aiemman."
|
||||
|
||||
#: plugin.py:922
|
||||
msgid "Alias plugin is not loaded."
|
||||
msgstr "Alias lisä-osa ei ole ladattu."
|
||||
|
||||
#: plugin.py:933
|
||||
msgid "Error occured when importing the %n: %L"
|
||||
msgstr "Virhe komennon %n tuomisessa: %L"
|
||||
|
||||
#: plugin.py:941
|
||||
msgid ""
|
||||
"[--channel <#channel>] [--keys] [--unlocked|--locked]\n"
|
||||
"\n"
|
||||
" Lists all Akas defined for <channel>. If <channel> is not "
|
||||
"specified,\n"
|
||||
" lists all global Akas. If --keys is given, lists only the Aka names\n"
|
||||
" and not their commands."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:960
|
||||
msgid "--locked and --unlocked are incompatible options."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:980
|
||||
msgid "No Akas found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:985
|
||||
msgid ""
|
||||
"[--channel <#channel>] <query>\n"
|
||||
"\n"
|
||||
" Searches Akas defined for <channel>. If <channel> is not specified,\n"
|
||||
" searches all global Akas."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:1004
|
||||
msgid "No matching Akas were found."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Aka is the improved version of the Alias plugin. It stores akas outside\n"
|
||||
#~ " of the bot.conf, which doesn't have risk of corrupting the bot.conf "
|
||||
#~ "file\n"
|
||||
#~ " (this often happens when there are Unicode issues). Aka also\n"
|
||||
#~ " introduces multi-worded akas."
|
||||
#~ msgstr ""
|
||||
#~ "Aka on paranneltu versio Alias pluginista. Se tallentaa akat bot.conf-"
|
||||
#~ "tiedoston ulkopuolelle, jollla ei ole\n"
|
||||
#~ " riskiä korruptoida bot.conf tiedostoa (joka tapahtuu usein Unicode-"
|
||||
#~ "ongelmien kanssa). Aka\n"
|
||||
#~ " tukee myös useamman akan pituisia akoja."
|
||||
|
||||
#~ msgid "There can be only one $* in an alias."
|
||||
#~ msgstr "Aliaksessa voi olla vain yksi $*."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Add the help for 'plugin help Aka' here\n"
|
||||
#~ " This should describe *how* to use this plugin."
|
||||
#~ msgstr ""
|
||||
#~ "Lisää ohje komentoa 'plugin help Aka' varten tähän.\n"
|
||||
#~ " Tämän pitäisi kuvata *kuinka* tätä lisä-osaa käytetään."
|
@ -1,289 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: config.py:55
|
||||
msgid ""
|
||||
"The maximum number of words allowed in a\n"
|
||||
" command name. Setting this to an high value may slow down your bot\n"
|
||||
" on long commands."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:61
|
||||
msgid ""
|
||||
"Determines whether the Akas will be\n"
|
||||
" browsable through the HTTP server."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:141 plugin.py:274 plugin.py:732
|
||||
msgid "This Aka already exists."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:170 plugin.py:182 plugin.py:196 plugin.py:301 plugin.py:318
|
||||
#: plugin.py:335 plugin.py:912
|
||||
msgid "This Aka does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:303
|
||||
msgid "This Aka is already locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:320
|
||||
msgid "This Aka is already unlocked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:465
|
||||
msgid "By %s at %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:501
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
"\n"
|
||||
" Importing from Alias\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, Alias, which eases the transitioning to Aka from Alias.\n"
|
||||
"\n"
|
||||
" First we will load Alias and Aka::\n"
|
||||
"\n"
|
||||
" <jamessan> @load Alias\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @load Aka\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" Then we import the Alias database to Aka in case it exists and unload\n"
|
||||
" Alias::\n"
|
||||
"\n"
|
||||
" <jamessan> @importaliasdatabase\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @unload Alias\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" And now we will finally add the Aka ``alias`` itself::\n"
|
||||
"\n"
|
||||
" <jamessan> @aka add \"alias\" \"aka $1 $*\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
"\n"
|
||||
" Now you can use Aka as you used Alias before.\n"
|
||||
"\n"
|
||||
" Trout\n"
|
||||
" ^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, trout, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @aka add trout \"reply action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" This ``trout`` aka requires the plugin ``Reply`` to be loaded since it\n"
|
||||
" provides the ``action`` command.\n"
|
||||
"\n"
|
||||
" LastFM\n"
|
||||
" ^^^^^^\n"
|
||||
"\n"
|
||||
" Add an aka, ``lastfm``, which expects a last.fm username and replies with\n"
|
||||
" their most recently played item::\n"
|
||||
"\n"
|
||||
" @aka add lastfm \"rss [format concat http://ws.audioscrobbler.com/1.0/user/ [format concat [web urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" This ``lastfm`` aka requires the following plugins to be loaded: ``RSS``,\n"
|
||||
" ``Format`` and ``Web``.\n"
|
||||
"\n"
|
||||
" ``RSS`` provides ``rss``, ``Format`` provides ``concat`` and ``Web`` provides\n"
|
||||
" ``urlquote``.\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and ``@lastfm`` would always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:699
|
||||
msgid "You've attempted more nesting than is currently allowed on this bot."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:703
|
||||
msgid " at least"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:712
|
||||
msgid "Locked by %s at %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:717
|
||||
msgid ""
|
||||
"<a global alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q.%s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:718 plugin.py:722
|
||||
msgid "argument"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:721
|
||||
msgid ""
|
||||
"<an alias on %s,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q.%s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:729
|
||||
msgid "You can't overwrite commands in this plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:734
|
||||
msgid "This Aka has too many spaces in its name."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:739
|
||||
msgid "Can't mix $* and optional args (@1, etc.)"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:746
|
||||
msgid "This Aka is locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:750
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, @2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" arguments that have not replaced $1, $2, etc.\", ie. it will also\n"
|
||||
" include optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:764 plugin.py:796 plugin.py:827 plugin.py:859 plugin.py:882
|
||||
#: plugin.py:905 plugin.py:951 plugin.py:994
|
||||
msgid "%r is not a valid channel."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:782
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name> <command>\n"
|
||||
"\n"
|
||||
" Overwrites an existing alias <name> to execute <command> instead. The\n"
|
||||
" <command> should be in the standard \"command argument [nestedcommand\n"
|
||||
" argument]\" arguments to the alias; they'll be filled with the first,\n"
|
||||
" second, etc. arguments. $1, $2, etc. can be used for required\n"
|
||||
" arguments. @1, @2, etc. can be used for optional arguments. $* simply\n"
|
||||
" means \"all arguments that have not replaced $1, $2, etc.\", ie. it will\n"
|
||||
" also include optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:819
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:841
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Check if the user has any of the required capabilities to manage\n"
|
||||
" the regexp database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:851
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:874
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:897
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <alias>\n"
|
||||
"\n"
|
||||
" This command shows the content of an Aka.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:917
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Imports the Alias database into Aka's, and clean the former."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:922
|
||||
msgid "Alias plugin is not loaded."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:933
|
||||
msgid "Error occured when importing the %n: %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:941
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] [--keys] [--unlocked|--locked]\n"
|
||||
"\n"
|
||||
" Lists all Akas defined for <channel>. If <channel> is not specified,\n"
|
||||
" lists all global Akas. If --keys is given, lists only the Aka names\n"
|
||||
" and not their commands."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:960
|
||||
msgid "--locked and --unlocked are incompatible options."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:980
|
||||
msgid "No Akas found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:985
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--channel <#channel>] <query>\n"
|
||||
"\n"
|
||||
" Searches Akas defined for <channel>. If <channel> is not specified,\n"
|
||||
" searches all global Akas."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:1004
|
||||
msgid "No matching Akas were found."
|
||||
msgstr ""
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,345 +0,0 @@
|
||||
# -*- coding: utf8 -*-
|
||||
###
|
||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||
# Copyright (c) 2013-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.httpserver as httpserver
|
||||
import supybot.plugin as plugin
|
||||
import supybot.registry as registry
|
||||
from supybot.utils.minisix import u
|
||||
|
||||
from . import plugin as Aka
|
||||
|
||||
class FunctionsTest(SupyTestCase):
|
||||
def testFindBiggestDollar(self):
|
||||
self.assertEqual(Aka.findBiggestDollar(''), 0)
|
||||
self.assertEqual(Aka.findBiggestDollar('foo'), 0)
|
||||
self.assertEqual(Aka.findBiggestDollar('$0'), 0)
|
||||
self.assertEqual(Aka.findBiggestDollar('$1'), 1)
|
||||
self.assertEqual(Aka.findBiggestDollar('$2'), 2)
|
||||
self.assertEqual(Aka.findBiggestDollar('$2 $10'), 10)
|
||||
self.assertEqual(Aka.findBiggestDollar('$3'), 3)
|
||||
self.assertEqual(Aka.findBiggestDollar('$3 $2 $1'), 3)
|
||||
self.assertEqual(Aka.findBiggestDollar('foo bar $1'), 1)
|
||||
self.assertEqual(Aka.findBiggestDollar('foo $2 $1'), 2)
|
||||
self.assertEqual(Aka.findBiggestDollar('foo $0 $1'), 1)
|
||||
self.assertEqual(Aka.findBiggestDollar('foo $1 $3'), 3)
|
||||
self.assertEqual(Aka.findBiggestDollar('$10 bar $1'), 10)
|
||||
|
||||
class AkaChannelTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Aka', 'Conditional', 'Filter', 'Math', 'Utilities',
|
||||
'Format', 'Reply', 'String')
|
||||
|
||||
def testHistsearch(self):
|
||||
self.assertNotError(
|
||||
r'aka add histsearch "last --from [cif true '
|
||||
r'\"echo test\" \"echo test\"] '
|
||||
r'--regexp [concat \"m/$1/\" [re s/g// \"@2\"]]"')
|
||||
self.assertResponse('echo foo', 'foo')
|
||||
self.assertResponse('histsearch .*foo.*', '@echo foo')
|
||||
|
||||
def testDoesNotOverwriteCommands(self):
|
||||
# We don't have dispatcher commands anymore
|
||||
#self.assertError('aka add aka "echo foo bar baz"')
|
||||
self.assertError('aka add add "echo foo bar baz"')
|
||||
self.assertError('aka add remove "echo foo bar baz"')
|
||||
self.assertError('aka add lock "echo foo bar baz"')
|
||||
self.assertError('aka add unlock "echo foo bar baz"')
|
||||
|
||||
def testAkaHelp(self):
|
||||
self.assertNotError(r'aka add slashdot "foo \"bar\" baz"')
|
||||
self.assertRegexp('help slashdot', r'Alias for "foo \\"bar\\" baz".')
|
||||
self.assertNotError('aka add nonascii echo éé')
|
||||
self.assertRegexp('help nonascii', r'Alias for "echo éé".')
|
||||
|
||||
self.assertNotError('aka remove slashdot')
|
||||
self.assertNotError('aka add --channel %s slashdot foo' % self.channel)
|
||||
self.assertRegexp('help aka slashdot', "an alias on %s.*Alias for .*foo"
|
||||
% self.channel)
|
||||
self.assertNotError('aka remove --channel %s slashdot' % self.channel)
|
||||
|
||||
def testShow(self):
|
||||
self.assertNotError('aka add foo bar')
|
||||
self.assertResponse('show foo', 'bar $*')
|
||||
self.assertNotError('aka add "foo bar" baz')
|
||||
self.assertResponse('show "foo bar"', 'baz $*')
|
||||
|
||||
def testRemove(self):
|
||||
self.assertNotError('aka add foo echo bar')
|
||||
self.assertResponse('foo', 'bar')
|
||||
self.assertNotError('aka remove foo')
|
||||
self.assertError('foo')
|
||||
|
||||
def testDollars(self):
|
||||
self.assertNotError('aka add rot26 "rot13 [rot13 $1]"')
|
||||
self.assertResponse('rot26 foobar', 'foobar')
|
||||
|
||||
def testMoreDollars(self):
|
||||
self.assertNotError('aka add rev "echo $3 $2 $1"')
|
||||
self.assertResponse('rev foo bar baz', 'baz bar foo')
|
||||
|
||||
def testAllArgs(self):
|
||||
self.assertNotError('aka add swap "echo $2 $1 $*"')
|
||||
self.assertResponse('swap 1 2 3 4 5', '2 1 3 4 5')
|
||||
self.assertError('aka add foo "echo $1 @1 $*"')
|
||||
self.assertNotError('aka add moo echo $1 $*')
|
||||
self.assertError('moo')
|
||||
self.assertResponse('moo foo', 'foo')
|
||||
self.assertResponse('moo foo bar', 'foo bar')
|
||||
|
||||
self.assertNotError('aka add spam "echo [echo $*]"')
|
||||
self.assertResponse('spam egg', 'egg')
|
||||
self.assertResponse('spam egg bacon', 'egg bacon')
|
||||
|
||||
self.assertNotError('aka add doublespam "echo [echo $* $*]"')
|
||||
self.assertResponse('doublespam egg', 'egg egg')
|
||||
self.assertResponse('doublespam egg bacon', 'egg bacon egg bacon')
|
||||
|
||||
def testExpansionBomb(self):
|
||||
self.assertNotError('aka add bomb "bomb $* $* $* $* $*"')
|
||||
# if the mitigation doesn't work, this test will eat all memory on the
|
||||
# system.
|
||||
self.assertResponse('bomb foo', "Error: You've attempted more nesting "
|
||||
"than is currently allowed on this bot.")
|
||||
|
||||
def testChannel(self):
|
||||
self.assertNotError('aka add channel echo $channel')
|
||||
self.assertResponse('aka channel', self.channel)
|
||||
|
||||
def testAddRemoveAka(self):
|
||||
cb = self.irc.getCallback('Aka')
|
||||
cb._add_aka('global', 'foobar', 'echo sbbone')
|
||||
cb._db.lock_aka('global', 'foobar', 'evil_admin')
|
||||
self.assertResponse('foobar', 'sbbone')
|
||||
self.assertRegexp('aka list', 'foobar')
|
||||
self.assertRaises(Aka.AkaError, cb._remove_aka, 'global', 'foobar')
|
||||
cb._remove_aka('global', 'foobar', evenIfLocked=True)
|
||||
self.assertNotRegexp('aka list', 'foobar')
|
||||
self.assertError('foobar')
|
||||
|
||||
def testOptionalArgs(self):
|
||||
self.assertNotError('aka add myrepr "repr @1"')
|
||||
self.assertResponse('myrepr foo', '"foo"')
|
||||
self.assertResponse('myrepr ""', '""')
|
||||
|
||||
def testRequiredAndOptional(self):
|
||||
self.assertNotError('aka add reqopt "echo req=$1, opt=@1"')
|
||||
self.assertResponse('reqopt foo bar', 'req=foo, opt=bar')
|
||||
self.assertResponse('reqopt foo', 'req=foo, opt=')
|
||||
|
||||
def testNoExtraSpaces(self):
|
||||
self.assertNotError('aka add foo "action takes $1\'s money"')
|
||||
self.assertResponse('foo bar', '\x01ACTION takes bar\'s money\x01')
|
||||
|
||||
def testNoExtraQuotes(self):
|
||||
self.assertNotError('aka add myre "echo s/$1/$2/g"')
|
||||
self.assertResponse('myre foo bar', 's/foo/bar/g')
|
||||
|
||||
def testSimpleAkaWithoutArgsImpliesDollarStar(self):
|
||||
self.assertNotError('aka add exo echo')
|
||||
self.assertResponse('exo foo bar baz', 'foo bar baz')
|
||||
|
||||
def testChannelPriority(self):
|
||||
self.assertNotError('aka add spam "echo foo"')
|
||||
self.assertNotError('aka add --channel %s spam "echo bar"' %
|
||||
self.channel)
|
||||
self.assertResponse('spam', 'bar')
|
||||
|
||||
self.assertNotError('aka add --channel %s egg "echo baz"' %
|
||||
self.channel)
|
||||
self.assertNotError('aka add egg "echo qux"')
|
||||
self.assertResponse('egg', 'baz')
|
||||
|
||||
def testComplicatedNames(self):
|
||||
self.assertNotError(u('aka add café "echo coffee"'))
|
||||
self.assertResponse(u('café'), 'coffee')
|
||||
|
||||
self.assertNotError('aka add "foo bar" "echo spam"')
|
||||
self.assertResponse('foo bar', 'spam')
|
||||
self.assertNotError('aka add "foo" "echo egg"')
|
||||
self.assertResponse('foo', 'egg')
|
||||
# You could expect 'spam' here, but in fact, this is dangerous.
|
||||
# Just imagine this session:
|
||||
# <evil_user> aka add "echo foo" quit
|
||||
# <bot> The operation succeeded.
|
||||
# ...
|
||||
# <owner> echo foo
|
||||
# * bot has quit
|
||||
self.assertResponse('foo bar', 'egg')
|
||||
|
||||
def testNoOverride(self):
|
||||
self.assertNotError('aka add "echo foo" "echo bar"')
|
||||
self.assertResponse('echo foo', 'foo')
|
||||
self.assertNotError('aka add foo "echo baz"')
|
||||
self.assertNotError('aka add "foo bar" "echo qux"')
|
||||
self.assertResponse('foo bar', 'baz')
|
||||
|
||||
def testRecursivity(self):
|
||||
self.assertNotError('aka add fact '
|
||||
r'"cif [nceq $1 0] \"echo 1\" '
|
||||
r'\"calc $1 * [fact [calc $1 - 1]]\""')
|
||||
self.assertResponse('fact 4', '24')
|
||||
self.assertRegexp('fact 50', 'more nesting')
|
||||
|
||||
def testDollarStarNesting(self):
|
||||
self.assertResponse('aka add alias aka $*', 'The operation succeeded.')
|
||||
self.assertResponse('alias add a+ aka add $*', 'The operation succeeded.')
|
||||
self.assertResponse('a+ spam echo egg', 'The operation succeeded.')
|
||||
self.assertResponse('spam', 'egg')
|
||||
|
||||
def testIgnore(self):
|
||||
self.assertResponse('aka add test ignore', 'The operation succeeded.')
|
||||
self.assertNoResponse('test')
|
||||
|
||||
|
||||
class AkaTestCase(PluginTestCase):
|
||||
plugins = ('Aka', 'Alias', 'User', 'Utilities')
|
||||
|
||||
def testMaximumLength(self):
|
||||
self.assertNotError('aka add "foo bar baz qux quux" "echo test"')
|
||||
self.assertError('aka add "foo bar baz qux quux corge" "echo test"')
|
||||
|
||||
def testAkaLockedHelp(self):
|
||||
self.assertNotError('register evil_admin foo')
|
||||
|
||||
self.assertNotError('aka add slashdot foo')
|
||||
self.assertRegexp('help aka slashdot', "a global alias.*Alias for .*foo")
|
||||
self.assertNotRegexp('help aka slashdot', 'Locked by')
|
||||
self.assertNotError('aka lock slashdot')
|
||||
self.assertRegexp('help aka slashdot', 'Locked by evil_admin')
|
||||
self.assertNotError('aka unlock slashdot')
|
||||
self.assertNotRegexp('help aka slashdot', 'Locked by')
|
||||
|
||||
def testAliasImport(self):
|
||||
self.assertNotError('alias add foo "echo bar"')
|
||||
self.assertNotError(u('alias add baz "echo café"'))
|
||||
self.assertNotError('aka add qux "echo quux"')
|
||||
self.assertResponse('alias foo', 'bar')
|
||||
self.assertResponse('alias baz', 'café')
|
||||
self.assertRegexp('aka foo', 'there is no command named')
|
||||
self.assertResponse('aka qux', 'quux')
|
||||
|
||||
self.assertNotError('aka importaliasdatabase')
|
||||
|
||||
self.assertRegexp('alias foo', 'there is no command named')
|
||||
self.assertResponse('aka foo', 'bar')
|
||||
self.assertResponse('aka baz', 'café')
|
||||
self.assertResponse('aka qux', 'quux')
|
||||
|
||||
self.assertNotError('alias add foo "echo test"')
|
||||
self.assertNotError('alias add spam "echo egg"')
|
||||
self.assertNotError('alias lock spam')
|
||||
|
||||
self.assertRegexp('aka importaliasdatabase',
|
||||
r'the 1 following command: foo \(This Aka already exists.\)$')
|
||||
self.assertResponse('aka foo', 'bar')
|
||||
self.assertResponse('alias foo', 'test')
|
||||
self.assertRegexp('alias spam', 'there is no command named')
|
||||
self.assertResponse('aka spam', 'egg')
|
||||
|
||||
def testList(self):
|
||||
self.assertNotError('aka add foo bar')
|
||||
self.assertRegexp('aka list', r'foo.*?bar \$\*')
|
||||
self.assertNotError('aka add "foo bar" baz')
|
||||
self.assertRegexp('aka list', r'foo.*?bar \$\*.*?foo bar.*?baz \$\*')
|
||||
|
||||
def testListLockedUnlocked(self):
|
||||
self.assertNotError('register tacocat hunter2')
|
||||
|
||||
self.assertNotError('aka add foo bar')
|
||||
self.assertNotError('aka add abcd echo hi')
|
||||
self.assertNotError('aka lock foo')
|
||||
self.assertRegexp('aka list --locked', 'foo')
|
||||
self.assertNotRegexp('aka list --locked', 'abcd')
|
||||
self.assertNotRegexp('aka list --unlocked', 'foo')
|
||||
self.assertRegexp('aka list --unlocked', 'abcd')
|
||||
# Can't look up both.
|
||||
self.assertError('aka list --locked --unlocked abcd')
|
||||
|
||||
def testSearch(self):
|
||||
self.assertNotError('aka add foo bar')
|
||||
self.assertNotError('aka add "many words" "much command"')
|
||||
self.assertRegexp('aka search f', 'foo')
|
||||
self.assertError('aka search abcdefghijklmnop')
|
||||
self.assertRegexp('aka search many', 'many words')
|
||||
# This should be case insensitive too.
|
||||
self.assertRegexp('aka search MaNY', 'many words')
|
||||
|
||||
class AkaWebUITestCase(ChannelHTTPPluginTestCase):
|
||||
plugins = ('Aka',)
|
||||
config = {
|
||||
'servers.http.keepAlive': True,
|
||||
'plugins.Aka.web.enable': False,
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(ChannelHTTPPluginTestCase, self).setUp()
|
||||
httpserver.startServer()
|
||||
|
||||
def tearDown(self):
|
||||
httpserver.stopServer()
|
||||
super(ChannelHTTPPluginTestCase, self).tearDown()
|
||||
|
||||
def testToggleWebEnable(self):
|
||||
self.assertHTTPResponse('/aka/', 404)
|
||||
self.assertNotError('config plugins.Aka.web.enable True')
|
||||
self.assertHTTPResponse('/aka/', 200)
|
||||
self.assertNotError('config plugins.Aka.web.enable False')
|
||||
self.assertHTTPResponse('/aka/', 404)
|
||||
|
||||
def testGlobalPage(self):
|
||||
self.assertNotError('config plugins.Aka.web.enable True')
|
||||
|
||||
self.assertNotError('aka add foo1 echo 1')
|
||||
self.assertNotError('aka add --channel #foo foo2 echo 2')
|
||||
self.assertNotError('aka add --channel #bar foo3 echo 3')
|
||||
|
||||
(respCode, body) = self.request('/aka/list/global')
|
||||
self.assertEqual(respCode, 200)
|
||||
self.assertIn(b'foo1', body)
|
||||
self.assertNotIn(b'foo2', body)
|
||||
self.assertNotIn(b'foo3', body)
|
||||
|
||||
def testChannelPage(self):
|
||||
self.assertNotError('config plugins.Aka.web.enable True')
|
||||
|
||||
self.assertNotError('aka add foo1 echo 1')
|
||||
self.assertNotError('aka add --channel #foo foo2 echo 2')
|
||||
self.assertNotError('aka add --channel #bar foo3 echo 3')
|
||||
|
||||
(respCode, body) = self.request('/aka/list/%23foo')
|
||||
self.assertEqual(respCode, 200)
|
||||
self.assertIn(b'foo1', body)
|
||||
self.assertIn(b'foo2', body)
|
||||
self.assertNotIn(b'foo3', body)
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,101 +0,0 @@
|
||||
.. _plugin-Alias:
|
||||
|
||||
Documentation for the Alias plugin for Supybot
|
||||
==============================================
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
Allows aliases for other commands. NOTE THAT IT'S RECOMMENDED TO USE Aka
|
||||
PLUGIN INSTEAD!
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This plugin allows users to define aliases to commands and combinations
|
||||
of commands (via nesting).
|
||||
This plugin is only kept for backward compatibility, you should use the
|
||||
built-in Aka plugin instead (you can migrate your existing aliases using
|
||||
the 'importaliasdatabase' command.
|
||||
|
||||
To add an alias, ``trout``, which expects a word as an argument::
|
||||
|
||||
<jamessan> @alias add trout "action slaps $1 with a large trout"
|
||||
<bot> jamessan: The operation succeeded.
|
||||
<jamessan> @trout me
|
||||
* bot slaps me with a large trout
|
||||
|
||||
Add an alias, ``randpercent``, which returns a random percentage value::
|
||||
|
||||
@alias add randpercent "squish [dice 1d100]%"
|
||||
|
||||
This requires the ``Filter`` and ``Games`` plugins to be loaded.
|
||||
|
||||
Note that nested commands in an alias should be quoted, or they will only
|
||||
run once when you create the alias, and not each time the alias is
|
||||
called. (In this case, not quoting the nested command would mean that
|
||||
``@randpercent`` always responds with the same value!)
|
||||
|
||||
.. _commands-Alias:
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
.. _command-alias-add:
|
||||
|
||||
add <name> <command>
|
||||
Defines an alias <name> that executes <command>. The <command> should be in the standard "command argument [nestedcommand argument]" arguments to the alias; they'll be filled with the first, second, etc. arguments. $1, $2, etc. can be used for required arguments. @1, @2, etc. can be used for optional arguments. $* simply means "all remaining arguments," and cannot be combined with optional arguments.
|
||||
|
||||
.. _command-alias-list:
|
||||
|
||||
list [--locked|--unlocked]
|
||||
Lists alias names of a particular type, defaults to all aliases if no --locked or --unlocked option is given.
|
||||
|
||||
.. _command-alias-lock:
|
||||
|
||||
lock <alias>
|
||||
Locks an alias so that no one else can change it.
|
||||
|
||||
.. _command-alias-remove:
|
||||
|
||||
remove <name>
|
||||
Removes the given alias, if unlocked.
|
||||
|
||||
.. _command-alias-unlock:
|
||||
|
||||
unlock <alias>
|
||||
Unlocks an alias so that people can define new aliases over it.
|
||||
|
||||
.. _conf-Alias:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
.. _conf-supybot.plugins.Alias.aliases:
|
||||
|
||||
|
||||
supybot.plugins.Alias.aliases
|
||||
This is a group of:
|
||||
|
||||
.. _conf-supybot.plugins.Alias.escapedaliases:
|
||||
|
||||
|
||||
supybot.plugins.Alias.escapedaliases
|
||||
This is a group of:
|
||||
|
||||
.. _conf-supybot.plugins.Alias.public:
|
||||
|
||||
|
||||
supybot.plugins.Alias.public
|
||||
This config variable defaults to "True", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin is publicly visible.
|
||||
|
||||
.. _conf-supybot.plugins.Alias.validName:
|
||||
|
||||
|
||||
supybot.plugins.Alias.validName
|
||||
This config variable defaults to "^[^\\x00-\\x20]+$", is not network-specific, and is not channel-specific.
|
||||
|
||||
Regex which alias names must match in order to be valid
|
||||
|
@ -1,65 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
"""
|
||||
Allows aliases for other commands. NOTE THAT IT'S RECOMMENDED TO USE Aka
|
||||
PLUGIN INSTEAD!
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = ""
|
||||
|
||||
__author__ = supybot.authors.jemfinch
|
||||
__maintainer__ = supybot.authors.limnoria_core
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
from . import config
|
||||
from . import plugin
|
||||
from importlib import reload
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
from .plugin import findBiggestDollar, AliasError, escapeAlias, unescapeAlias # for the tests.
|
||||
|
||||
if world.testing:
|
||||
from . import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,50 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Alias')
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified themself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('Alias', True)
|
||||
|
||||
Alias = conf.registerPlugin('Alias')
|
||||
conf.registerGroup(Alias, 'aliases')
|
||||
conf.registerGroup(Alias, 'escapedaliases')
|
||||
conf.registerGlobalValue(Alias, 'validName',
|
||||
registry.String(r'^[^\x00-\x20]+$', _("""Regex which alias names must match in order to be valid""")))
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,175 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2012-04-27 15:36+0200\n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: German <fbesser@gmail.com>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
"X-Poedit-Country: GERMANY\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Gibt den Kanal aus über den die Nachricht kam oder der Kanal der in den "
|
||||
"Argumenten gegeben wurde.\n"
|
||||
"\n"
|
||||
"Falls der Kanal in den Argumenten angegeben wurde, werden die Argumente "
|
||||
"bearbeitet (der Kanal wird entfernt."
|
||||
|
||||
#: plugin.py:110
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or "
|
||||
"pipes>."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr "mindestens"
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<ein Alias, %s %n>\n"
|
||||
"\n"
|
||||
"Alias für %q."
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr "Argument"
|
||||
|
||||
#: plugin.py:239
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases "
|
||||
"using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies "
|
||||
"with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Alias>\n"
|
||||
"\n"
|
||||
"Versperrt ein Alias, sodass er nicht verändert werden kann."
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr "Es gibt keinen Alias mit diesem Namen."
|
||||
|
||||
#: plugin.py:370
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Alias>\n"
|
||||
"\n"
|
||||
"Entsperrt den Alias, sodass andere Personen ihn verändern können."
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Dieser Name ist nicht zulässig. Probiere anstatt %q."
|
||||
|
||||
#: plugin.py:426
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional "
|
||||
"arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Name> <Alias>\n"
|
||||
"\n"
|
||||
"Definiert einen Alias <Name> der <Alias> ausführt. <Alias> sollte in der "
|
||||
"Standardform \"Befehl Argument [verschachtelter Befehl Argument\" angegeben "
|
||||
"werden."
|
||||
|
||||
#: plugin.py:449
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Name>\n"
|
||||
"\n"
|
||||
"Entfernt den gegeben Alias, falls er nicht gesperrt ist."
|
||||
|
||||
#: plugin.py:463
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if "
|
||||
"no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
#, fuzzy
|
||||
msgid "There are no aliases."
|
||||
msgstr "Es gibt keinen Alias mit diesem Namen."
|
@ -1,204 +0,0 @@
|
||||
# Alias plugin in Limnoria.
|
||||
# Copyright (C) 2011, 2012 Limnoria
|
||||
# Mikaela Suomalainen <mkaysi@outlook.com>, 2011, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Alias plugin\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2014-12-20 13:47+0200\n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: suomi <>\n"
|
||||
"Language: fi_FI\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: \n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Palauttaa kanavan, jolta viesti tuli tai kanavan, joka on annettu "
|
||||
"parametreissä.\n"
|
||||
"\n"
|
||||
" Jos kanava annetaan parametreissä, parametriä muokataan (kanava\n"
|
||||
" poistetaan).\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:110
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or "
|
||||
"pipes>."
|
||||
msgstr ""
|
||||
"Salaa [a-z0-9.]+ sisään [a-z][a-z0-9].\n"
|
||||
" Muoto: a<ohitettujen merkkien määrä>a(<index>d)+<sana ilman pisteitä>."
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr "vähintään"
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias %q:lle."
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr "parametri"
|
||||
|
||||
#: plugin.py:239
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases "
|
||||
"using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies "
|
||||
"with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Lukitsee aliaksen, niin ettei kukaan muu voi muuttaa sitä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr "Tuollaista aliasta ei ole."
|
||||
|
||||
#: plugin.py:370
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Poistaa lukituksen aliaksesta, jotta ihmiset vouvat määrittää uusia "
|
||||
"aliaksia sen päälle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Tuo nimi ei ole kelvollinen. Yritä sen sijaan %q:ta."
|
||||
|
||||
#: plugin.py:426
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional "
|
||||
"arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi> <alias>\n"
|
||||
"\n"
|
||||
" Määrittää aliaksen <nimi>, joka suorittaa <komennon>. <Aliaksen>\n"
|
||||
" pitäisi olla tavallinen \"komento parametri [sisäkkäinen komento "
|
||||
"parametrit]\"\n"
|
||||
" parametrejä aliakselle; ne täytetään ensimmäinen, toinen, jne.\n"
|
||||
" Parametrit. $1, $2, jne. ovat vaadittava parametrejä. @1, @2,\n"
|
||||
" jne. ovat valinnaisia parametrejä. $* tarkoittaa yksinkertaisesti "
|
||||
"\"kaikki\n"
|
||||
" jäljellä olevat parametrit,\" ja johon ei voida yhdistää vaihtoehtoisia "
|
||||
"parametrejä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:449
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi>\n"
|
||||
"\n"
|
||||
" Poistaa annetun aliaksen jos se ei ole lukittu.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:463
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if "
|
||||
"no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
#, fuzzy
|
||||
msgid "There are no aliases."
|
||||
msgstr "Tuollaista aliasta ei ole."
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid ""
|
||||
#~ "This plugin allows users to define aliases to commands and combinations\n"
|
||||
#~ " of commands (via nesting)."
|
||||
#~ msgstr ""
|
||||
#~ "Tämä plugini sallii käyttäjien määrittää aliaksia komennoille ja "
|
||||
#~ "komentojen yhdistelmille (sisäytyksellä)."
|
||||
|
||||
#~ msgid "You've attempted more nesting than is currently allowed on this bot."
|
||||
#~ msgstr ""
|
||||
#~ "Yritit sisällyttää useampia komentoja, kuin tämä botti sallii juuri nyt."
|
@ -1,182 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Limnoria <progval@gmail.com>\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-SourceCharset: ASCII\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Retourne le canal duquel vient le message ou le canal donné en argument.\n"
|
||||
"\n"
|
||||
"Si le canal était donné en argument, args est modifié (le canal est "
|
||||
"supprimé)."
|
||||
|
||||
#: plugin.py:110
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or "
|
||||
"pipes>."
|
||||
msgstr "."
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr "au moins"
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<un alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias pour %q."
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr "argument"
|
||||
|
||||
#: plugin.py:239
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases "
|
||||
"using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies "
|
||||
"with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
"Vérouille un alias pour que personne d'autre ne puisse le changer."
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr "Cet alias n'existe pas."
|
||||
|
||||
#: plugin.py:370
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
"Déverrouille un alias de façon à ce que des gens puissent le redéfinir."
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Ce nom n'est pas valide. Essayez plutôt %q."
|
||||
|
||||
#: plugin.py:426
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional "
|
||||
"arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nom> <alias>\n"
|
||||
"\n"
|
||||
"Défini un alias <nom> qui exécute <alias>. L'<alias> peut être dans le "
|
||||
"standard \"commande argument [commandeimbriquee argument]\". Les arguments "
|
||||
"donnés à l'alias doivent être donnés dans l'ordre. Vous pouvez utiliser $1, "
|
||||
"$2, etc pour symboliser les arguments obligatoires qui seront donnés à "
|
||||
"l'alias, et @1, @2, etc pour symboliser ceux optionnels. $* signifie "
|
||||
"simplement *tous* les arguments restants, et ne peut être combiné avec des "
|
||||
"arguments optionnels."
|
||||
|
||||
#: plugin.py:449
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nom>\n"
|
||||
"\n"
|
||||
"Supprime l'alias donné, si il n'est pas verrouillé."
|
||||
|
||||
#: plugin.py:463
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if "
|
||||
"no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
#, fuzzy
|
||||
msgid "There are no aliases."
|
||||
msgstr "Cet alias n'existe pas."
|
||||
|
||||
#~ msgid "You've attempted more nesting than is currently allowed on this bot."
|
||||
#~ msgstr ""
|
||||
#~ "Vous avez essayé d’utiliser plus d’imbrication que ce qui est "
|
||||
#~ "actuellement autorisé sur ce bot."
|
@ -1,182 +0,0 @@
|
||||
# Limnoria Alias plugin.
|
||||
# Copyright (C) 2011 Limnoria
|
||||
# nyuszika7h <litemininyuszika@gmail.com>, 2011.
|
||||
# Mikaela Suomalainen <mikaela.suomalainen@outlook.com>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria Alias\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2012-04-27 15:12+0200\n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: hu_HU\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Kiírja a csatorna nevét, ahonnan az üzenet jött, vagy a paraméterként "
|
||||
"megadott csatornát.\n"
|
||||
"\n"
|
||||
"Ha a csatorna meg volt adva paraméterként, a paraméterek módosulnak (a "
|
||||
"csatorna eltávolításra kerül)."
|
||||
|
||||
#: plugin.py:110
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or "
|
||||
"pipes>."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr " legalább"
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<egy álnév,%s %n\n"
|
||||
"\n"
|
||||
"Álnév %q-ra."
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr "paraméter"
|
||||
|
||||
#: plugin.py:239
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases "
|
||||
"using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies "
|
||||
"with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<álnév>\n"
|
||||
"\n"
|
||||
"Lezár egy álnevet, hogy senki más ne változtathassa meg."
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr "Nincs ilyen álnév."
|
||||
|
||||
#: plugin.py:370
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<álnév>\n"
|
||||
"\n"
|
||||
"Feloldja egy álnév lezárását, hogy az emberek új álnevekkel írhassák felül."
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Az a név nem érvényes. Próbáld meg %q-t inkább."
|
||||
|
||||
#: plugin.py:426
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional "
|
||||
"arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<név> <álnév>\n"
|
||||
"\n"
|
||||
"Meghatároz egy <név> nevű álnevet, amely futtatja <álnév> parancsot. Az "
|
||||
"<álnév>-nek a szabványos \"parancs paraméter [beágyazottparancs paraméter]\" "
|
||||
"álnév paraméterei formában kell lennie; ezek ki lesznek töltve az első, "
|
||||
"második stb. paraméterekkel. $1, $2 stb. használható kötelező "
|
||||
"paraméterekhez. @1, @2 stb. használható választható paraméterekhez. $* azt "
|
||||
"jelenti, \"az összes hátralévő paraméter,\" és nem kombinálható választható "
|
||||
"paraméterekkel."
|
||||
|
||||
#: plugin.py:449
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<név>\n"
|
||||
"\n"
|
||||
"Eltávolítja a megadott álnevet, ha nincs lezárva."
|
||||
|
||||
#: plugin.py:463
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if "
|
||||
"no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
#, fuzzy
|
||||
msgid "There are no aliases."
|
||||
msgstr "Nincs ilyen álnév."
|
@ -1,183 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2011-06-07 08:23+0200\n"
|
||||
"Last-Translator: skizzhg <skizzhg@gmx.com>\n"
|
||||
"Language-Team: Italian <skizzhg@gmx.com>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Restituisce il canale da dove proviene il messaggio o il canale fornito come "
|
||||
"argomento.\n"
|
||||
"\n"
|
||||
" Se il canale è stato dato come argomento, quest'ultimo viene modificato "
|
||||
"(il canale\n"
|
||||
" viene rimosso).\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:110
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or "
|
||||
"pipes>."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr " almeno"
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<un alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias per %q."
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr "argomento"
|
||||
|
||||
#: plugin.py:239
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases "
|
||||
"using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies "
|
||||
"with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler."
|
||||
"com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would "
|
||||
"always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Blocca un alias affinché nessun altro possa modificarlo.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr "Non c'è nessun alias."
|
||||
|
||||
#: plugin.py:370
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Sblocca un alias affinché chiunque possa ridefinirne di nuovi.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Nome non valido. Prova %q invece."
|
||||
|
||||
#: plugin.py:426
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand "
|
||||
"argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, "
|
||||
"etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, "
|
||||
"@2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional "
|
||||
"arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nome> <comando>\n"
|
||||
"\n"
|
||||
" Definisce un <nome> che esegue <comando>. <comando> deve essere "
|
||||
"nello\n"
|
||||
" standard \"comando argomento [comando_nidificato argomento]\"; gli\n"
|
||||
" argomenti dati devono essere riportati in sequenza. Per gli "
|
||||
"argomenti\n"
|
||||
" richiesti è possibile utilizzare $1, $2, ecc., mentre @1, @2, ecc. "
|
||||
"per\n"
|
||||
" quelli opzionali. $* significa semplicemente \"tutti gli argomenti\n"
|
||||
" rimanenti\" e non può essere combinato con quelli opzionali.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:449
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nome>\n"
|
||||
"\n"
|
||||
" Rimuove l'alias specificato, se questo non è bloccato.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:463
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if "
|
||||
"no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
#, fuzzy
|
||||
msgid "There are no aliases."
|
||||
msgstr "Non c'è nessun alias."
|
@ -1,152 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: config.py:48
|
||||
msgid "Regex which alias names must match in order to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:48
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:110
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Encodes dots and pipes\n"
|
||||
" Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or pipes>."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:226
|
||||
msgid " at least"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:228 plugin.py:233
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:229 plugin.py:234
|
||||
msgid "argument"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:239
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to define aliases to commands and combinations\n"
|
||||
" of commands (via nesting).\n"
|
||||
" This plugin is only kept for backward compatibility, you should use the\n"
|
||||
" built-in Aka plugin instead (you can migrate your existing aliases using\n"
|
||||
" the 'importaliasdatabase' command.\n"
|
||||
"\n"
|
||||
" To add an alias, `trout`, which expects a word as an argument::\n"
|
||||
"\n"
|
||||
" <jamessan> @alias add trout \"action slaps $1 with a large trout\"\n"
|
||||
" <bot> jamessan: The operation succeeded.\n"
|
||||
" <jamessan> @trout me\n"
|
||||
" * bot slaps me with a large trout\n"
|
||||
"\n"
|
||||
" To add an alias, `lastfm`, which expects a last.fm user and replies with\n"
|
||||
" their recently played items::\n"
|
||||
"\n"
|
||||
" @alias add lastfm \"rss [format concat http://ws.audioscrobbler.com/1.0/user/ [format concat [urlquote $1] /recenttracks.rss]]\"\n"
|
||||
"\n"
|
||||
" Note that if the nested commands being aliased hadn't been quoted, then\n"
|
||||
" those commands would have been run immediately, and `@lastfm` would always\n"
|
||||
" reply with the same information, the result of those commands.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:365 plugin.py:378
|
||||
msgid "There is no such alias."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:370
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:386
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:426
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<name> <command>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <command>. The <command>\n"
|
||||
" should be in the standard \"command argument [nestedcommand argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, @2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:449
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:463
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--locked|--unlocked]\n"
|
||||
"\n"
|
||||
" Lists alias names of a particular type, defaults to all aliases if no\n"
|
||||
" --locked or --unlocked option is given.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:470
|
||||
msgid "Cannot specify --locked and --unlocked simultaneously"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:486
|
||||
msgid "There are no aliases of that type."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:488
|
||||
msgid "There are no aliases."
|
||||
msgstr ""
|
||||
|
@ -1,496 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||
# Copyright (c) 2014, James McCoy
|
||||
# Copyright (c) 2012-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import re
|
||||
import sys
|
||||
import types
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.utils.minisix as minisix
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.registry as registry
|
||||
import supybot.callbacks as callbacks
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Alias')
|
||||
|
||||
# Copied from the old privmsgs.py.
|
||||
def getChannel(irc, msg, args):
|
||||
"""Returns the channel the msg came over or the channel given in args.
|
||||
|
||||
If the channel was given in args, args is modified (the channel is
|
||||
removed).
|
||||
"""
|
||||
if args and msg.channel:
|
||||
if conf.supybot.reply.requireChannelCommandsToBeSentInChannel():
|
||||
if args[0] != msg.channel:
|
||||
s = 'Channel commands must be sent in the channel to which ' \
|
||||
'they apply; if this is not the behavior you desire, ' \
|
||||
'ask the bot\'s administrator to change the registry ' \
|
||||
'variable ' \
|
||||
'supybot.reply.requireChannelCommandsToBeSentInChannel ' \
|
||||
'to False.'
|
||||
raise callbacks.Error(s)
|
||||
return args.pop(0)
|
||||
elif msg.channel:
|
||||
return msg.channel
|
||||
else:
|
||||
raise callbacks.Error('Command must be sent in a channel or ' \
|
||||
'include a channel in its arguments.')
|
||||
|
||||
def getArgs(args, required=1, optional=0, wildcard=0):
|
||||
if len(args) < required:
|
||||
raise callbacks.ArgumentError
|
||||
if len(args) < required + optional:
|
||||
ret = list(args) + ([''] * (required + optional - len(args)))
|
||||
elif len(args) >= required + optional:
|
||||
if not wildcard:
|
||||
ret = list(args[:required + optional - 1])
|
||||
ret.append(' '.join(args[required + optional - 1:]))
|
||||
else:
|
||||
ret = list(args)
|
||||
return ret
|
||||
|
||||
class AliasError(Exception):
|
||||
pass
|
||||
|
||||
dollarRe = re.compile(r'\$(\d+)')
|
||||
def findBiggestDollar(alias):
|
||||
dollars = dollarRe.findall(alias)
|
||||
dollars = list(map(int, dollars))
|
||||
dollars.sort()
|
||||
if dollars:
|
||||
return dollars[-1]
|
||||
else:
|
||||
return 0
|
||||
|
||||
atRe = re.compile(r'@(\d+)')
|
||||
def findBiggestAt(alias):
|
||||
ats = atRe.findall(alias)
|
||||
ats = list(map(int, ats))
|
||||
ats.sort()
|
||||
if ats:
|
||||
return ats[-1]
|
||||
else:
|
||||
return 0
|
||||
|
||||
def needsEscaping(alias):
|
||||
return '.' in alias or '|' in alias
|
||||
|
||||
def escapeAlias(alias):
|
||||
"""Encodes dots and pipes
|
||||
Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or pipes>."""
|
||||
prefix = ''
|
||||
new_alias = ''
|
||||
prefixes = 0
|
||||
for index, char in enumerate(alias):
|
||||
if char == '.':
|
||||
prefix += '%sd' % index
|
||||
prefixes += 1
|
||||
elif char == '|':
|
||||
prefix += '%sp' % index
|
||||
prefixes += 1
|
||||
else:
|
||||
new_alias += char
|
||||
pre_prefix = 'a%ia' % prefixes
|
||||
return pre_prefix + prefix + new_alias
|
||||
|
||||
def unescapeAlias(alias):
|
||||
alias = alias[1:] # Strip the leading 'a'
|
||||
escaped_nb = ''
|
||||
while alias[0] in '0123456789':
|
||||
escaped_nb += alias[0]
|
||||
alias = alias[1:]
|
||||
alias = alias[1:]
|
||||
escaped_nb = int(escaped_nb)
|
||||
escaped_chars = []
|
||||
while alias[0] in '0123456789':
|
||||
current_group = ''
|
||||
while alias[0] in '0123456789':
|
||||
current_group += alias[0]
|
||||
alias = alias[1:]
|
||||
if alias[0] == 'd':
|
||||
char = '.'
|
||||
elif alias[0] == 'p':
|
||||
char = '|'
|
||||
else:
|
||||
char = alias[0]
|
||||
alias = alias[1:]
|
||||
escaped_chars.append((int(current_group), char))
|
||||
if len(escaped_chars) == escaped_nb:
|
||||
break
|
||||
new_alias = ''
|
||||
index = 0
|
||||
for char in alias:
|
||||
if escaped_chars and index == escaped_chars[0][0]:
|
||||
new_alias += escaped_chars[0][1]
|
||||
escaped_chars.pop(0)
|
||||
index += 1
|
||||
new_alias += char
|
||||
index += 1
|
||||
return new_alias
|
||||
|
||||
def makeNewAlias(name, alias):
|
||||
original = alias
|
||||
biggestDollar = findBiggestDollar(original)
|
||||
biggestAt = findBiggestAt(original)
|
||||
wildcard = '$*' in original
|
||||
if biggestAt and wildcard:
|
||||
raise AliasError('Can\'t mix $* and optional args (@1, etc.)')
|
||||
if original.count('$*') > 1:
|
||||
raise AliasError('There can be only one $* in an alias.')
|
||||
testTokens = callbacks.tokenize(original)
|
||||
if testTokens and isinstance(testTokens[0], list):
|
||||
raise AliasError('Commands may not be the result of nesting.')
|
||||
def f(self, irc, msg, args):
|
||||
alias = original.replace('$nick', msg.nick)
|
||||
if '$channel' in original:
|
||||
channel = getChannel(irc, msg, args)
|
||||
alias = alias.replace('$channel', channel)
|
||||
tokens = callbacks.tokenize(alias)
|
||||
if biggestDollar or biggestAt:
|
||||
args = getArgs(args, required=biggestDollar, optional=biggestAt,
|
||||
wildcard=wildcard)
|
||||
max_len = conf.supybot.reply.maximumLength()
|
||||
args = list([x[:max_len] for x in args])
|
||||
def regexpReplace(m):
|
||||
idx = int(m.group(1))
|
||||
return args[idx-1]
|
||||
def replace(tokens, replacer):
|
||||
for (i, token) in enumerate(tokens):
|
||||
if isinstance(token, list):
|
||||
replace(token, replacer)
|
||||
else:
|
||||
tokens[i] = replacer(token)
|
||||
replace(tokens, lambda s: dollarRe.sub(regexpReplace, s))
|
||||
if biggestAt:
|
||||
assert not wildcard
|
||||
args = args[biggestDollar:]
|
||||
replace(tokens, lambda s: atRe.sub(regexpReplace, s))
|
||||
if wildcard:
|
||||
assert not biggestAt
|
||||
# Gotta remove the things that have already been subbed in.
|
||||
i = biggestDollar
|
||||
while i:
|
||||
args.pop(0)
|
||||
i -= 1
|
||||
def everythingReplace(tokens):
|
||||
for (i, token) in enumerate(tokens):
|
||||
if isinstance(token, list):
|
||||
if everythingReplace(token):
|
||||
return
|
||||
if token == '$*':
|
||||
tokens[i:i+1] = args
|
||||
return True
|
||||
elif '$*' in token:
|
||||
tokens[i] = token.replace('$*', ' '.join(args))
|
||||
return True
|
||||
return False
|
||||
everythingReplace(tokens)
|
||||
# Limit memory use by constraining the size of the message being passed
|
||||
# in to the alias. Also tracking nesting to avoid endless recursion.
|
||||
maxLength = conf.supybot.reply.maximumLength()
|
||||
tokens = [t[:maxLength] for t in tokens]
|
||||
self.Proxy(irc, msg, tokens, nested=irc.nested + 1)
|
||||
flexargs = ''
|
||||
if biggestDollar and (wildcard or biggestAt):
|
||||
flexargs = _(' at least')
|
||||
try:
|
||||
doc = format(_('<an alias,%s %n>\n\nAlias for %q.'),
|
||||
flexargs, (biggestDollar, _('argument')), alias)
|
||||
except UnicodeDecodeError:
|
||||
if minisix.PY2:
|
||||
alias = alias.decode('utf8')
|
||||
doc = format(_('<an alias,%s %n>\n\nAlias for %q.'),
|
||||
flexargs, (biggestDollar, _('argument')), alias)
|
||||
f = utils.python.changeFunctionName(f, name, doc)
|
||||
return f
|
||||
|
||||
class Alias(callbacks.Plugin):
|
||||
"""
|
||||
This plugin allows users to define aliases to commands and combinations
|
||||
of commands (via nesting).
|
||||
This plugin is only kept for backward compatibility, you should use the
|
||||
built-in Aka plugin instead (you can migrate your existing aliases using
|
||||
the 'importaliasdatabase' command.
|
||||
|
||||
To add an alias, ``trout``, which expects a word as an argument::
|
||||
|
||||
<jamessan> @alias add trout "action slaps $1 with a large trout"
|
||||
<bot> jamessan: The operation succeeded.
|
||||
<jamessan> @trout me
|
||||
* bot slaps me with a large trout
|
||||
|
||||
Add an alias, ``randpercent``, which returns a random percentage value::
|
||||
|
||||
@alias add randpercent "squish [dice 1d100]%"
|
||||
|
||||
This requires the ``Filter`` and ``Games`` plugins to be loaded.
|
||||
|
||||
Note that nested commands in an alias should be quoted, or they will only
|
||||
run once when you create the alias, and not each time the alias is
|
||||
called. (In this case, not quoting the nested command would mean that
|
||||
``@randpercent`` always responds with the same value!)
|
||||
"""
|
||||
def __init__(self, irc):
|
||||
self.__parent = super(Alias, self)
|
||||
self.__parent.__init__(irc)
|
||||
# Schema: {alias: [command, locked, commandMethod]}
|
||||
self.aliases = {}
|
||||
# XXX This should go. aliases should be a space separate list, etc.
|
||||
group = conf.supybot.plugins.Alias.aliases
|
||||
group2 = conf.supybot.plugins.Alias.escapedaliases
|
||||
prefixLen = len(registry.split('supybot.plugins.alias.aliases'))
|
||||
for (name, alias) in registry._cache.items():
|
||||
name = name.lower()
|
||||
nameSplit = registry.split(name)
|
||||
if len(nameSplit) > prefixLen+1:
|
||||
continue
|
||||
if name.startswith('supybot.plugins.alias.aliases.'):
|
||||
name = nameSplit[-1]
|
||||
conf.registerGlobalValue(group, name, registry.String('', ''))
|
||||
conf.registerGlobalValue(group.get(name), 'locked',
|
||||
registry.Boolean(False, ''))
|
||||
elif name.startswith('supybot.plugins.alias.escapedaliases.'):
|
||||
name = nameSplit[-1]
|
||||
conf.registerGlobalValue(group2, name,
|
||||
registry.String('', ''))
|
||||
conf.registerGlobalValue(group2.get(name),
|
||||
'locked', registry.Boolean(False, ''))
|
||||
for (name, value) in group.getValues(fullNames=False):
|
||||
name = name.lower() # Just in case.
|
||||
command = value()
|
||||
locked = value.locked()
|
||||
self.aliases[name] = [command, locked, None]
|
||||
for (name, value) in group2.getValues(fullNames=False):
|
||||
name = name.lower() # Just in case.
|
||||
command = value()
|
||||
locked = value.locked()
|
||||
self.aliases[unescapeAlias(name)] = [command, locked, None]
|
||||
for (alias, (command, locked, _)) in self.aliases.copy().items():
|
||||
try:
|
||||
self.addAlias(irc, alias, command, locked)
|
||||
except Exception as e:
|
||||
self.log.exception('Exception when trying to add alias %s. '
|
||||
'Removing from the Alias database.', alias)
|
||||
del self.aliases[alias]
|
||||
|
||||
def isCommandMethod(self, name):
|
||||
if not self.__parent.isCommandMethod(name):
|
||||
if name in self.aliases:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def listCommands(self):
|
||||
return self.__parent.listCommands(self.aliases.keys())
|
||||
|
||||
def getCommandMethod(self, command):
|
||||
try:
|
||||
return self.__parent.getCommandMethod(command)
|
||||
except AttributeError:
|
||||
return self.aliases[command[0]][2]
|
||||
|
||||
def aliasRegistryGroup(self, name):
|
||||
if needsEscaping(name):
|
||||
return self.registryValue('escapedaliases', value=False)
|
||||
else:
|
||||
return self.registryValue('aliases', value=False)
|
||||
|
||||
def aliasRegistryNode(self, name):
|
||||
group = self.aliasRegistryGroup(name)
|
||||
if needsEscaping(name):
|
||||
return group.get(escapeAlias(name))
|
||||
else:
|
||||
return group.get(name)
|
||||
|
||||
def aliasRegistryRemove(self, name):
|
||||
group = self.aliasRegistryGroup(name)
|
||||
if needsEscaping(name):
|
||||
group.unregister(escapeAlias(name))
|
||||
else:
|
||||
group.unregister(name)
|
||||
|
||||
|
||||
def setLocked(self, name, value):
|
||||
self.aliases[name][1] = value
|
||||
self.aliasRegistryNode(name).locked.setValue(value)
|
||||
|
||||
def isValidName(self, name):
|
||||
if not re.search(self.registryValue('validName'), name):
|
||||
return False
|
||||
if not registry.isValidRegistryName(name):
|
||||
return False
|
||||
return True
|
||||
|
||||
@internationalizeDocstring
|
||||
def lock(self, irc, msg, args, name):
|
||||
"""<alias>
|
||||
|
||||
Locks an alias so that no one else can change it.
|
||||
"""
|
||||
if name in self.aliases and self.isCommandMethod(name):
|
||||
self.setLocked(name, True)
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('There is no such alias.'))
|
||||
lock = wrap(lock, [('checkCapability', 'admin'), 'commandName'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def unlock(self, irc, msg, args, name):
|
||||
"""<alias>
|
||||
|
||||
Unlocks an alias so that people can define new aliases over it.
|
||||
"""
|
||||
if name in self.aliases and self.isCommandMethod(name):
|
||||
self.setLocked(name, False)
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('There is no such alias.'))
|
||||
unlock = wrap(unlock, [('checkCapability', 'admin'), 'commandName'])
|
||||
|
||||
def addAlias(self, irc, name, alias, lock=False):
|
||||
if not self.isValidName(name):
|
||||
raise AliasError('Invalid alias name.')
|
||||
realName = callbacks.canonicalName(name)
|
||||
if name != realName:
|
||||
s = format(_('That name isn\'t valid. Try %q instead.'), realName)
|
||||
raise AliasError(s)
|
||||
name = realName
|
||||
if self.isCommandMethod(name):
|
||||
if realName not in self.aliases:
|
||||
s = 'You can\'t overwrite commands in this plugin.'
|
||||
raise AliasError(s)
|
||||
if name in self.aliases:
|
||||
(currentAlias, locked, _) = self.aliases[name]
|
||||
if locked and currentAlias != alias:
|
||||
raise AliasError(format('Alias %q is locked.', name))
|
||||
f = makeNewAlias(name, alias)
|
||||
f = types.MethodType(f, self)
|
||||
if name in self.aliases:
|
||||
# We gotta remove it so its value gets updated.
|
||||
self.aliasRegistryRemove(name)
|
||||
aliasGroup = self.aliasRegistryGroup(name)
|
||||
if needsEscaping(name):
|
||||
confname = escapeAlias(name)
|
||||
else:
|
||||
confname = name
|
||||
conf.registerGlobalValue(aliasGroup, confname,
|
||||
registry.String(alias, ''))
|
||||
conf.registerGlobalValue(aliasGroup.get(confname), 'locked',
|
||||
registry.Boolean(lock, ''))
|
||||
self.aliases[name] = [alias, lock, f]
|
||||
|
||||
def removeAlias(self, name, evenIfLocked=False):
|
||||
name = callbacks.canonicalName(name)
|
||||
if name in self.aliases and self.isCommandMethod(name):
|
||||
if evenIfLocked or not self.aliases[name][1]:
|
||||
del self.aliases[name]
|
||||
self.aliasRegistryRemove(name)
|
||||
else:
|
||||
raise AliasError('That alias is locked.')
|
||||
else:
|
||||
raise AliasError('There is no such alias.')
|
||||
|
||||
@internationalizeDocstring
|
||||
def add(self, irc, msg, args, name, alias):
|
||||
"""<name> <command>
|
||||
|
||||
Defines an alias <name> that executes <command>. The <command>
|
||||
should be in the standard "command argument [nestedcommand argument]"
|
||||
arguments to the alias; they'll be filled with the first, second, etc.
|
||||
arguments. $1, $2, etc. can be used for required arguments. @1, @2,
|
||||
etc. can be used for optional arguments. $* simply means "all
|
||||
remaining arguments," and cannot be combined with optional arguments.
|
||||
"""
|
||||
if ' ' not in alias:
|
||||
# If it's a single word, they probably want $*.
|
||||
alias += ' $*'
|
||||
try:
|
||||
self.addAlias(irc, name, alias)
|
||||
self.log.info('Adding alias %q for %q (from %s)',
|
||||
name, alias, msg.prefix)
|
||||
irc.replySuccess()
|
||||
except AliasError as e:
|
||||
irc.error(str(e))
|
||||
add = wrap(add, ['commandName', 'text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def remove(self, irc, msg, args, name):
|
||||
"""<name>
|
||||
|
||||
Removes the given alias, if unlocked.
|
||||
"""
|
||||
try:
|
||||
self.removeAlias(name)
|
||||
self.log.info('Removing alias %q (from %s)', name, msg.prefix)
|
||||
irc.replySuccess()
|
||||
except AliasError as e:
|
||||
irc.error(str(e))
|
||||
remove = wrap(remove, ['commandName'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def list(self, irc, msg, args, optlist):
|
||||
"""[--locked|--unlocked]
|
||||
|
||||
Lists alias names of a particular type, defaults to all aliases if no
|
||||
--locked or --unlocked option is given.
|
||||
"""
|
||||
optlist = dict(optlist)
|
||||
if len(optlist)>1:
|
||||
irc.error(_('Cannot specify --locked and --unlocked simultaneously'))
|
||||
return
|
||||
aliases = []
|
||||
for name in self.aliases.keys():
|
||||
if self.isCommandMethod(name):
|
||||
if 'locked' in optlist:
|
||||
if self.aliases[name][1]: aliases.append(name)
|
||||
elif 'unlocked' in optlist:
|
||||
if not self.aliases[name][1]: aliases.append(name)
|
||||
else:
|
||||
aliases.append(name)
|
||||
if aliases:
|
||||
aliases.sort()
|
||||
irc.reply(format('%L', aliases))
|
||||
else:
|
||||
if len(optlist):
|
||||
irc.reply(_('There are no aliases of that type.'))
|
||||
else:
|
||||
irc.reply(_('There are no aliases.'))
|
||||
list = wrap(list, [getopts({'locked':'', 'unlocked':''})])
|
||||
|
||||
|
||||
Class = Alias
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,185 +0,0 @@
|
||||
# -*- coding: utf8 -*-
|
||||
###
|
||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.plugin as plugin
|
||||
import supybot.registry as registry
|
||||
from supybot.utils.minisix import u
|
||||
|
||||
from . import plugin as Alias
|
||||
|
||||
class FunctionsTest(SupyTestCase):
|
||||
def testFindBiggestDollar(self):
|
||||
self.assertEqual(Alias.findBiggestDollar(''), 0)
|
||||
self.assertEqual(Alias.findBiggestDollar('foo'), 0)
|
||||
self.assertEqual(Alias.findBiggestDollar('$0'), 0)
|
||||
self.assertEqual(Alias.findBiggestDollar('$1'), 1)
|
||||
self.assertEqual(Alias.findBiggestDollar('$2'), 2)
|
||||
self.assertEqual(Alias.findBiggestDollar('$2 $10'), 10)
|
||||
self.assertEqual(Alias.findBiggestDollar('$3'), 3)
|
||||
self.assertEqual(Alias.findBiggestDollar('$3 $2 $1'), 3)
|
||||
self.assertEqual(Alias.findBiggestDollar('foo bar $1'), 1)
|
||||
self.assertEqual(Alias.findBiggestDollar('foo $2 $1'), 2)
|
||||
self.assertEqual(Alias.findBiggestDollar('foo $0 $1'), 1)
|
||||
self.assertEqual(Alias.findBiggestDollar('foo $1 $3'), 3)
|
||||
self.assertEqual(Alias.findBiggestDollar('$10 bar $1'), 10)
|
||||
|
||||
|
||||
class AliasTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Alias', 'Filter', 'Utilities', 'Format', 'Reply')
|
||||
def testNoAliasWithNestedCommandName(self):
|
||||
self.assertError('alias add foo "[bar] baz"')
|
||||
|
||||
def testDoesNotOverwriteCommands(self):
|
||||
# We don't have dispatcher commands anymore
|
||||
#self.assertError('alias add alias "echo foo bar baz"')
|
||||
self.assertError('alias add add "echo foo bar baz"')
|
||||
self.assertError('alias add remove "echo foo bar baz"')
|
||||
self.assertError('alias add lock "echo foo bar baz"')
|
||||
self.assertError('alias add unlock "echo foo bar baz"')
|
||||
|
||||
def testAliasHelp(self):
|
||||
self.assertNotError('alias add slashdot foo')
|
||||
self.assertRegexp('help slashdot', "Alias for .*foo")
|
||||
self.assertNotError('alias add nonascii echo éé')
|
||||
self.assertRegexp('help nonascii', "Alias for .*echo éé")
|
||||
|
||||
def testRemove(self):
|
||||
self.assertNotError('alias add foo echo bar')
|
||||
self.assertResponse('foo', 'bar')
|
||||
self.assertNotError('alias remove foo')
|
||||
self.assertError('foo')
|
||||
|
||||
def testDollars(self):
|
||||
self.assertNotError('alias add rot26 "rot13 [rot13 $1]"')
|
||||
self.assertResponse('rot26 foobar', 'foobar')
|
||||
|
||||
def testMoreDollars(self):
|
||||
self.assertNotError('alias add rev "echo $3 $2 $1"')
|
||||
self.assertResponse('rev foo bar baz', 'baz bar foo')
|
||||
|
||||
def testAllArgs(self):
|
||||
self.assertNotError('alias add swap "echo $2 $1 $*"')
|
||||
self.assertResponse('swap 1 2 3 4 5', '2 1 3 4 5')
|
||||
self.assertError('alias add foo "echo $1 @1 $*"')
|
||||
self.assertNotError('alias add moo echo $1 $*')
|
||||
self.assertError('moo')
|
||||
self.assertResponse('moo foo', 'foo')
|
||||
self.assertResponse('moo foo bar', 'foo bar')
|
||||
|
||||
def testChannel(self):
|
||||
self.assertNotError('alias add channel echo $channel')
|
||||
self.assertResponse('alias channel', self.channel)
|
||||
|
||||
def testNick(self):
|
||||
self.assertNotError('alias add sendingnick "rot13 [rot13 $nick]"')
|
||||
self.assertResponse('sendingnick', self.nick)
|
||||
|
||||
def testAddRemoveAlias(self):
|
||||
cb = self.irc.getCallback('Alias')
|
||||
cb.addAlias(self.irc, 'foobar', 'echo sbbone', lock=True)
|
||||
self.assertResponse('foobar', 'sbbone')
|
||||
self.assertRaises(Alias.AliasError, cb.removeAlias, 'foobar')
|
||||
cb.removeAlias('foobar', evenIfLocked=True)
|
||||
self.assertNotIn('foobar', cb.aliases)
|
||||
self.assertError('foobar')
|
||||
|
||||
self.assertRegexp('alias add abc\x07 ignore', 'Error.*Invalid')
|
||||
|
||||
def testOptionalArgs(self):
|
||||
self.assertNotError('alias add myrepr "repr @1"')
|
||||
self.assertResponse('myrepr foo', '"foo"')
|
||||
self.assertResponse('myrepr ""', '""')
|
||||
|
||||
def testNoExtraSpaces(self):
|
||||
self.assertNotError('alias add foo "action takes $1\'s money"')
|
||||
self.assertResponse('foo bar', '\x01ACTION takes bar\'s money\x01')
|
||||
|
||||
def testNoExtraQuotes(self):
|
||||
self.assertNotError('alias add myre "echo s/$1/$2/g"')
|
||||
self.assertResponse('myre foo bar', 's/foo/bar/g')
|
||||
|
||||
def testUnicode(self):
|
||||
self.assertNotError(u('alias add \u200b echo foo'))
|
||||
self.assertResponse(u('\u200b'), 'foo')
|
||||
|
||||
self.assertNotError('alias add café echo bar')
|
||||
self.assertResponse('café', 'bar')
|
||||
|
||||
def testSimpleAliasWithoutArgsImpliesDollarStar(self):
|
||||
self.assertNotError('alias add exo echo')
|
||||
self.assertResponse('exo foo bar baz', 'foo bar baz')
|
||||
|
||||
class EscapedAliasTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Alias', 'Utilities')
|
||||
def setUp(self):
|
||||
registry._cache.update(
|
||||
{'supybot.plugins.Alias.escapedaliases.a1a3dfoobar': 'echo baz',
|
||||
'supybot.plugins.Alias.escapedaliases.a1a3dfoobar.locked': 'False'})
|
||||
super(EscapedAliasTestCase, self).setUp()
|
||||
|
||||
def testReadDatabase(self):
|
||||
self.assertResponse('foo.bar', 'baz')
|
||||
|
||||
def testAdd(self):
|
||||
self.assertNotError('alias add spam.egg echo hi')
|
||||
self.assertResponse('spam.egg', 'hi')
|
||||
|
||||
self.assertNotError('alias add spam|egg echo hey')
|
||||
self.assertResponse('spam|egg', 'hey')
|
||||
|
||||
self.assertNotError('alias remove spam.egg')
|
||||
self.assertError('spam.egg')
|
||||
self.assertNotError('spam|egg')
|
||||
self.assertNotError('alias remove spam|egg')
|
||||
self.assertError('spam.egg')
|
||||
self.assertError('spam|egg')
|
||||
|
||||
def testWriteDatabase(self):
|
||||
self.assertNotError('alias add fooo.spam echo egg')
|
||||
self.assertResponse('fooo.spam', 'egg')
|
||||
self.assertTrue(hasattr(conf.supybot.plugins.Alias.escapedaliases,
|
||||
'a1a4dfooospam'))
|
||||
self.assertEqual(conf.supybot.plugins.Alias.escapedaliases.a1a4dfooospam(),
|
||||
'echo egg')
|
||||
|
||||
self.assertNotError('alias add foo.spam.egg echo supybot')
|
||||
self.assertResponse('foo.spam.egg', 'supybot')
|
||||
self.assertTrue(hasattr(conf.supybot.plugins.Alias.escapedaliases,
|
||||
'a2a3d8dfoospamegg'))
|
||||
self.assertEqual(conf.supybot.plugins.Alias.escapedaliases.a2a3d8dfoospamegg(),
|
||||
'echo supybot')
|
||||
self.assertEqual(Alias.unescapeAlias('a2a3d8dfoospamegg'),
|
||||
'foo.spam.egg')
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,118 +0,0 @@
|
||||
.. _plugin-Anonymous:
|
||||
|
||||
Documentation for the Anonymous plugin for Supybot
|
||||
==================================================
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
Allows folks to talk through the bot anonymously.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This plugin allows users to act through the bot anonymously. The 'do'
|
||||
command has the bot perform an anonymous action in a given channel, and
|
||||
the 'say' command allows other people to speak through the bot. Since
|
||||
this can be fairly well abused, you might want to set
|
||||
supybot.plugins.Anonymous.requireCapability so only users with that
|
||||
capability can use this plugin. For extra security, you can require that
|
||||
the user be *in* the channel they are trying to address anonymously with
|
||||
supybot.plugins.Anonymous.requirePresenceInChannel, or you can require
|
||||
that the user be registered by setting
|
||||
supybot.plugins.Anonymous.requireRegistration.
|
||||
|
||||
Example: Proving that you are the owner
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When you ask for cloak/vhost for your bot, the network operators will
|
||||
often ask you to prove that you own the bot. You can do this for example
|
||||
with the following method::
|
||||
|
||||
@load Anonymous
|
||||
@config plugins.anonymous.requirecapability owner
|
||||
@config plugins.anonymous.allowprivatetarget True
|
||||
@anonymous say <operator nick> Hi, my owner is <your nick> :)
|
||||
|
||||
This
|
||||
* Loads the plugin.
|
||||
* Makes the plugin require that you are the owner
|
||||
|
||||
* If anyone could send private messages as the bot, they could also
|
||||
access network services.
|
||||
|
||||
* Allows sending private messages
|
||||
* Sends message ``Hi, my owner is <your nick> :)`` to ``operator nick``.
|
||||
|
||||
* Note that you won't see the messages that are sent to the bot.
|
||||
|
||||
.. _commands-Anonymous:
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
.. _command-anonymous-do:
|
||||
|
||||
do <channel> <action>
|
||||
Performs <action> in <channel>.
|
||||
|
||||
.. _command-anonymous-react:
|
||||
|
||||
react <channel> <reaction> <nick>
|
||||
Sends the <reaction> to <nick>'s last message. <reaction> is typically a smiley or an emoji. This may not be supported on the current network, as this command depends on IRCv3 features. This is also not supported if supybot.protocols.irc.experimentalExtensions disabled (don't enable it unless you know what you are doing).
|
||||
|
||||
.. _command-anonymous-say:
|
||||
|
||||
say <channel> <text>
|
||||
Sends <text> to <channel>.
|
||||
|
||||
.. _command-anonymous-tell:
|
||||
|
||||
tell <nick> <text>
|
||||
Sends <text> to <nick>. Can only be used if supybot.plugins.Anonymous.allowPrivateTarget is True.
|
||||
|
||||
.. _conf-Anonymous:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
.. _conf-supybot.plugins.Anonymous.allowPrivateTarget:
|
||||
|
||||
|
||||
supybot.plugins.Anonymous.allowPrivateTarget
|
||||
This config variable defaults to "False", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether the bot will allow the "tell" command to be used. If true, the bot will allow the "tell" command to send private messages to other users.
|
||||
|
||||
.. _conf-supybot.plugins.Anonymous.public:
|
||||
|
||||
|
||||
supybot.plugins.Anonymous.public
|
||||
This config variable defaults to "True", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin is publicly visible.
|
||||
|
||||
.. _conf-supybot.plugins.Anonymous.requireCapability:
|
||||
|
||||
|
||||
supybot.plugins.Anonymous.requireCapability
|
||||
This config variable defaults to "", is network-specific, and is channel-specific.
|
||||
|
||||
Determines what capability (if any) the bot should require people trying to use this plugin to have.
|
||||
|
||||
.. _conf-supybot.plugins.Anonymous.requirePresenceInChannel:
|
||||
|
||||
|
||||
supybot.plugins.Anonymous.requirePresenceInChannel
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot should require people trying to use this plugin to be in the channel they wish to anonymously send to.
|
||||
|
||||
.. _conf-supybot.plugins.Anonymous.requireRegistration:
|
||||
|
||||
|
||||
supybot.plugins.Anonymous.requireRegistration
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot should require people trying to use this plugin to be registered.
|
||||
|
@ -1,63 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Daniel DiPaolo
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
"""
|
||||
Allows folks to talk through the bot anonymously.
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = "%%VERSION%%"
|
||||
|
||||
__author__ = supybot.authors.strike
|
||||
__maintainer__ = supybot.authors.limnoria_core
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
from . import config
|
||||
from . import plugin
|
||||
from importlib import reload
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
|
||||
if world.testing:
|
||||
from . import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,65 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Daniel DiPaolo
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Anonymous')
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified themself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('Anonymous', True)
|
||||
|
||||
|
||||
Anonymous = conf.registerPlugin('Anonymous')
|
||||
# This is where your configuration variables (if any) should go. For example:
|
||||
# conf.registerGlobalValue(Anonymous, 'someConfigVariableName',
|
||||
# registry.Boolean(False, """Help for someConfigVariableName."""))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Anonymous,
|
||||
'requirePresenceInChannel', registry.Boolean(True, _("""Determines whether
|
||||
the bot should require people trying to use this plugin to be in the
|
||||
channel they wish to anonymously send to.""")))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Anonymous, 'requireRegistration',
|
||||
registry.Boolean(True, _("""Determines whether the bot should require
|
||||
people trying to use this plugin to be registered.""")))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Anonymous, 'requireCapability',
|
||||
registry.String('', _("""Determines what capability (if any) the bot should
|
||||
require people trying to use this plugin to have.""")))
|
||||
conf.registerGlobalValue(conf.supybot.plugins.Anonymous, 'allowPrivateTarget',
|
||||
registry.Boolean(False, _("""Determines whether the bot will allow the
|
||||
"tell" command to be used. If true, the bot will allow the "tell"
|
||||
command to send private messages to other users.""")))
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,202 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2011-10-28 12:55+0100\n"
|
||||
"Last-Translator: Florian Besser <fbesser@gmail.com>\n"
|
||||
"Language-Team: German <fbesser@gmail.com>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Poedit-Language: de\n"
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr "Legt fest ob Leute im Kanal sein müssen, an den anonym senden wollen."
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Legt fest ob Nutzer registiert sein müssen um dieses Plugin zu benutze."
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Legt fest welche Fähgikeiten (falls überhaupt) der Bot verlangt von Personen "
|
||||
"die versuchen dieses Plugin zu benutzen."
|
||||
|
||||
#: config.py:60
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
"Legt fest ob der Bot verlangt, dass Ziele des Befehls \"say\" öffentlich "
|
||||
"sind (z.B. Kanäle). Falls das auf True gesetzt ist, wird ber Bot Nutzern "
|
||||
"erlauben den Befehl \"say\" zu nutzen um anderen Nutzern private Nachrichten "
|
||||
"zu senden."
|
||||
|
||||
#: plugin.py:45
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require "
|
||||
"that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously "
|
||||
"with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for "
|
||||
"example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator "
|
||||
"nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Das Plugin erlaubt Nutzern durch den Bot anonym zu bleiben. Der 'do' Befehl "
|
||||
"lässt den Bot eine anonyme Aktion in einem Kanal ausführen und der 'say' "
|
||||
"Befehl lässt Nutzer durch den Bot sprechen. Da das Ganze natürlich leicht "
|
||||
"missbraucht werden kann, willst du vielleicht supybot.plugins.Anonymous."
|
||||
"requireCapability setzen, sodass nur Nutzer mit dieser Fähigkeit das Plugin "
|
||||
"benutzen können. Für etwas mehr Sicherheit kannst du mit supybot.plugins."
|
||||
"Anonymous.requirePresenceInChannel verlangen, dass der Nutzer in dem Kanal "
|
||||
"sein muss in dem er anonym senden will oder du kannst verlangen, dass der "
|
||||
"Nutzer registriert sein muss indem du supybot.plugins.Anonymous."
|
||||
"requireRegistration setzt."
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr "Du musst in %s sein um %q dort auszuführen."
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr "Ich bin hirnamputiert in %s."
|
||||
|
||||
#: plugin.py:105
|
||||
msgid ""
|
||||
"That channel has set its capabilities so as to disallow the use of this "
|
||||
"plugin."
|
||||
msgstr ""
|
||||
"Für den Kanal sind die Fähigkeiten so gesetzt, dass sie das benutzen dieses "
|
||||
"Plugins nicht erlauben."
|
||||
|
||||
#: plugin.py:108
|
||||
msgid ""
|
||||
"This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is "
|
||||
"False)."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Kanal> <Aktion>\n"
|
||||
"\n"
|
||||
"Führt die <Aktion> im <Kanal> aus."
|
||||
|
||||
#: plugin.py:124
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Kanal|Nick> <text>\n"
|
||||
"\n"
|
||||
"Sendet <Text> an <Kanal|Nick>. Kann nur an <Nick> senden wenn supybot."
|
||||
"plugins.Anonymous.allowPrivateTarget auf True gesetzt ist."
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<Kanal> <Aktion>\n"
|
||||
"\n"
|
||||
"Führt die <Aktion> im <Kanal> aus."
|
||||
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid ""
|
||||
"Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "%q cannot be used to send private messages."
|
||||
#~ msgstr "%q kann nicht verwendet werden um private Nachrichten zu versenden."
|
@ -1,226 +0,0 @@
|
||||
# Anonymous plugin in Limnoria.
|
||||
# Copyright (C) 2011-2014 Limnoria
|
||||
# Mikaela Suomalainen <mikaela.suomalainen@outlook.com>, 2011-2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Anonymous\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mikaela Suomalainen <mikaela.suomalainen@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fi_FI\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
"Määrittää vaatiiko \n"
|
||||
"botti ihmisten, jotka yrittävät käyttää tätä lisäosaa, olemaan\n"
|
||||
"kanavalla, jonne he tahtovat lähettää viestin tuntemattomasti."
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Määrittää vaatiiko botti\n"
|
||||
"ihmisiä, jotka yrittävät käyttää tätä lisäosaa, olemaan rekisteröityneitä."
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Määrittää minkä valtuuden (jos minkään) botti vaatii\n"
|
||||
" ihmisiltä, jotka yrittävät käyttää tätä lisäosaa."
|
||||
|
||||
#: config.py:60
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
"Määrittää salliiko botti \"tell\"-komennon käytön. Jos tämä on True, botti "
|
||||
"sallii \"tell\"-komennon\n"
|
||||
" lähettävän yksityisviestejä toisille käyttäjille."
|
||||
|
||||
#: plugin.py:45
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require "
|
||||
"that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously "
|
||||
"with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for "
|
||||
"example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator "
|
||||
"nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Tämä lisäosa sallii käyttäjien toimia botin kautta tuntemattomasti.\n"
|
||||
" Komento 'do' sallii botin tehdä tuntemattoman toiminnon annetulla "
|
||||
"kanavalla ja\n"
|
||||
" komento 'say' sallii toisten ihmisten puhua botin läpi. Koska\n"
|
||||
" tätä voidaan väärinkäyttää helposti voit tahtoa asettaa asetuksen\n"
|
||||
" supybot.plugins.Anonymous.requireCapability niin, että vain käyttäjät "
|
||||
"tuolla\n"
|
||||
" valtuudella voivat käyttää tätä lisäosaa. Lisäturvallisuuden vuoksi voit "
|
||||
"vaatia, että käyttäjien täytyy *olla* kanavilla joita he yrittävät puhutella "
|
||||
"tuntemattomasti asetuksella supybot.plugins.Anonymous."
|
||||
"requirePresenceInChannel, tai sinä voit vaatia,\n"
|
||||
" että tuo käyttäjä on rekisteröitynyt asetuksella\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration"
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr "Sinun täytyy olla kanavalla %s %q sinne."
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr "Minut on lobotomoitu kanavalla %s."
|
||||
|
||||
#: plugin.py:105
|
||||
msgid ""
|
||||
"That channel has set its capabilities so as to disallow the use of this "
|
||||
"plugin."
|
||||
msgstr "Tuo kanava on asettanut valtuudet kieltämään tämän Pluginin käytön."
|
||||
|
||||
#: plugin.py:108
|
||||
msgid ""
|
||||
"This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is "
|
||||
"False)."
|
||||
msgstr ""
|
||||
"Tämä komento on poistettu käytöstä (supybot.plugins.Anonymous."
|
||||
"allowPrivateTarget on False)."
|
||||
|
||||
#: plugin.py:112
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> <teksti>\n"
|
||||
" Lähettää <tesktin> <kanavalle>."
|
||||
|
||||
#: plugin.py:124
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> <teksti>\n"
|
||||
"\n"
|
||||
" Lähettää <tekstin> <nimimerkille>. <Nimimerkille> voidaan lähettää\n"
|
||||
" viestejä vain asetusarvon supybot.plugins.Anonymous.allowPrivateTarget\n"
|
||||
" ollessa True.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> <toiminto>\n"
|
||||
"\n"
|
||||
"Suorittaa <toiminnon> <kanavalla>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid ""
|
||||
"Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "%q cannot be used to send private messages."
|
||||
#~ msgstr "%q:ta ei voi käyttää yksityisviestien lähettämiseen."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "<channel> <text>\n"
|
||||
#~ "\n"
|
||||
#~ " Sends <text> to <channel>. Can only send to <nick> if\n"
|
||||
#~ " supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "<kanava> <teksti>\n"
|
||||
#~ "\n"
|
||||
#~ " Lähettää <tekstin> <kanavalle>. <Nimimerkille> voidaan lähettää "
|
||||
#~ "viestejä vain \n"
|
||||
#~ " asetusarvon supybot.plugins.Anonymous.allowPrivateTarget ollessa "
|
||||
#~ "True.\n"
|
||||
#~ " "
|
@ -1,195 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Limnoria <progval@gmail.com>\n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Français\n"
|
||||
"X-Poedit-Country: France\n"
|
||||
"X-Poedit-SourceCharset: ASCII\n"
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
"Détermine si le bot requiérera que les gens soient sur le canal pour y "
|
||||
"envoyer des messages anonymement."
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Détermine si le bot requiérera que les personnes utilisant ce plugin soient "
|
||||
"enregistrées."
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Détermine quelle capacité (s'il y en a une) le bot requiéra que les gens "
|
||||
"utilisant ce plugin aient."
|
||||
|
||||
#: config.py:60
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
"Détermine si le bot requiérera que les cibles de la commande \"say\" soient "
|
||||
"publiques (c'est à dire des canaux). Si c'est True, le bot autorisera les "
|
||||
"personnes à utiliser la commande \"say\" pour envoyer des messages à "
|
||||
"d'autres utilisateurs en privé."
|
||||
|
||||
#: plugin.py:45
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require "
|
||||
"that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously "
|
||||
"with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for "
|
||||
"example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator "
|
||||
"nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr "Vous devez être sur %s pour y utiliser %q."
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr "Je suis lobotomisé sur %s."
|
||||
|
||||
#: plugin.py:105
|
||||
msgid ""
|
||||
"That channel has set its capabilities so as to disallow the use of this "
|
||||
"plugin."
|
||||
msgstr ""
|
||||
"Ce canal a définit ses capacités de façon à désactiver l'utilisation de ce "
|
||||
"plugin."
|
||||
|
||||
#: plugin.py:108
|
||||
msgid ""
|
||||
"This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is "
|
||||
"False)."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canal> <action>\n"
|
||||
"\n"
|
||||
"Effectue l'<action> sur le <canal>."
|
||||
|
||||
#: plugin.py:124
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canal|nick> <text>\n"
|
||||
"\n"
|
||||
"Envoie le <texte> au <canal|nick>. Vous ne pouvez envoyer à <nick> que si "
|
||||
"supybot.plugins.Anonymous.allowPrivateTarget vaut True."
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canal> <action>\n"
|
||||
"\n"
|
||||
"Effectue l'<action> sur le <canal>."
|
||||
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid ""
|
||||
"Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "%q cannot be used to send private messages."
|
||||
#~ msgstr "%q ne peut pas être utilisé pour envoyer des messages privés."
|
@ -1,208 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria Anonymous\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2011-07-21 17:32+0100\n"
|
||||
"Last-Translator: nyuszika7h <litemininyuszika@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: hu_HU\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
"Meghatározza, hogy a bot megkövetelje-e, hogy a bővítményt használni kívánó "
|
||||
"emberek abban a csatornában legyenek, ahová névtelenül szeretnének küldeni."
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Meghatározza, hogy a bot megkövetelje-e, hogy a bővítményt használni kívánó "
|
||||
"emberek regisztrálva legyenek."
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Meghatározza, hogy milyen képesség (ha van ilyen) legyen szükséges a "
|
||||
"bővítmény használatához."
|
||||
|
||||
#: config.py:60
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
"Meghatározza, hogy a bot megkövetelje-e, hogy a \"say\" parancs célja "
|
||||
"publikus legyen (pl., csatornák). Ha ez True, a bot megengedi az embereknek, "
|
||||
"hogy a \"say\" paranccsal privát üzenetet küldjenek másoknak."
|
||||
|
||||
#: plugin.py:45
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require "
|
||||
"that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously "
|
||||
"with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for "
|
||||
"example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator "
|
||||
"nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ez a bővítmény megengedi a felhasználóknak, hogy névtelenül cselekedjenek a "
|
||||
"boton keresztül. A 'do' parancs hatására a bot végrehajt egy névtelen "
|
||||
"tevékenységet egy megadott csatornában, és a 'say' parancs megengedi "
|
||||
"másoknak, hogy a boton keresztül beszéljenek. Mivel ezzel elég könnyen "
|
||||
"vissza lehet élni, érdemes beállítani a supybot.plugins.Anonymous."
|
||||
"requireCapability-t, hogy csak az adott képességgel rendelkező felhasználók "
|
||||
"használhassák ezt a bővítményt. Extra biztonságért a supybot.plugins."
|
||||
"Anonymous.requirePresenceInChannel-lel megkövetelheted, hogy a felhasználó "
|
||||
"abban a csatornában legyen, amelyet névtelenül szeretnének megcímezni, vagy "
|
||||
"a supybot.plugins.Anonymous.requireRegistration-nel megkövetelheted, hogy a "
|
||||
"felhasználó regisztálva legyen."
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr "%s-ban kell lenned, hogy a %q parancsot használd ott."
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr "Némítva vagyok %s-ban."
|
||||
|
||||
#: plugin.py:105
|
||||
msgid ""
|
||||
"That channel has set its capabilities so as to disallow the use of this "
|
||||
"plugin."
|
||||
msgstr ""
|
||||
"A megadott csatornában nem használhatod a bővítményt a csatorna képességei "
|
||||
"miatt."
|
||||
|
||||
#: plugin.py:108
|
||||
msgid ""
|
||||
"This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is "
|
||||
"False)."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<csatorna> <tevékenység>\n"
|
||||
"\n"
|
||||
"Végrehajtja <tevékenység>-et <csatorna>-ban."
|
||||
|
||||
#: plugin.py:124
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<csatorna|név> <szöveg>\n"
|
||||
"\n"
|
||||
"Elküldi <szöveg>-et <csatorna|név>-nek. Csak akkor küldhet <név>-nek, ha a "
|
||||
"supybot.plugins.Anonymous.allowPrivateTarget True."
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<csatorna> <tevékenység>\n"
|
||||
"\n"
|
||||
"Végrehajtja <tevékenység>-et <csatorna>-ban."
|
||||
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid ""
|
||||
"Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "%q cannot be used to send private messages."
|
||||
#~ msgstr "A %q parancs nem használható privát üzenetek küldésére."
|
@ -1,212 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Limnoria\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: 2011-08-10 00:13+0200\n"
|
||||
"Last-Translator: skizzhg <skizzhg@gmx.com>\n"
|
||||
"Language-Team: Italian <skizzhg@gmx.com>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
"Determina se il bot richieda che gli utenti siano in canale\n"
|
||||
" per inviare messaggi in forma anonima."
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Determina se il bot richieda che gli utenti siano registrati\n"
|
||||
" per usare il plugin."
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Determina quali capacità (eventuali) debbano\n"
|
||||
" avere gli utenti per utilizzare questo plugin."
|
||||
|
||||
#: config.py:60
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
"Determina se il bot richiederà che le destinazioni del comando \"say\" "
|
||||
"siano\n"
|
||||
" pubbliche (ovvero i canali). Se impostato a True, il bot permetterà\n"
|
||||
" di usare il comando \"say\" per inviare messaggi privati ad altri utenti."
|
||||
|
||||
#: plugin.py:45
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require "
|
||||
"that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously "
|
||||
"with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for "
|
||||
"example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator "
|
||||
"nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Questo plugin permette agli utenti di agire attraverso il bot in modo "
|
||||
"anonimo.\n"
|
||||
" Il comando \"do\" esegue un'azione anonima in un dato canale, mentre "
|
||||
"\"say\"\n"
|
||||
" permette di parlare tramite il bot. Giacché si può facilmente abusarne, "
|
||||
"è\n"
|
||||
" possibile impostare supybot.plugins.Anonymous.requireCapability in modo "
|
||||
"che\n"
|
||||
" solo gli utenti con determinate capacità possano usare il plugin. Per "
|
||||
"una\n"
|
||||
" maggiore sicurezza è ppossibile richiedere con supybot.plugins.Anonymous."
|
||||
"requirePresenceInChannel\n"
|
||||
" che l'utente intenzionato a parlare anonimamente sia in canale; o anche, "
|
||||
"tramite\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration, che l'utente sia "
|
||||
"registrato. "
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr "Devi essere in %s per %q."
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr "In %s sono lobotomizzato."
|
||||
|
||||
#: plugin.py:105
|
||||
msgid ""
|
||||
"That channel has set its capabilities so as to disallow the use of this "
|
||||
"plugin."
|
||||
msgstr ""
|
||||
"Questo canale ha le capacità impostate in modo da impedire l'utilizzo di "
|
||||
"questo plugin."
|
||||
|
||||
#: plugin.py:108
|
||||
msgid ""
|
||||
"This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is "
|
||||
"False)."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canale> <azione>\n"
|
||||
"\n"
|
||||
" Esegue <azione> in <canale>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:124
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canale|nick> <testo>\n"
|
||||
"\n"
|
||||
" Invia <testo> a <canale|nick>. Può solo inviare a <nick> se\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget è impostato a True.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<canale> <azione>\n"
|
||||
"\n"
|
||||
" Esegue <azione> in <canale>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid ""
|
||||
"Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "%q cannot be used to send private messages."
|
||||
#~ msgstr "%q non può essere usato per inviare messaggi privati."
|
@ -1,165 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2022-02-06 00:12+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:54
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:57
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:60
|
||||
msgid ""
|
||||
"Determines whether the bot will allow the\n"
|
||||
" \"tell\" command to be used. If true, the bot will allow the \"tell\"\n"
|
||||
" command to send private messages to other users."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:45
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
"\n"
|
||||
" Example: Proving that you are the owner\n"
|
||||
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
"\n"
|
||||
" When you ask for cloak/vhost for your bot, the network operators will\n"
|
||||
" often ask you to prove that you own the bot. You can do this for example\n"
|
||||
" with the following method::\n"
|
||||
"\n"
|
||||
" @load Anonymous\n"
|
||||
" @config plugins.anonymous.requirecapability owner\n"
|
||||
" @config plugins.anonymous.allowprivatetarget True\n"
|
||||
" @anonymous say <operator nick> Hi, my owner is <your nick> :)\n"
|
||||
"\n"
|
||||
" This\n"
|
||||
" * Loads the plugin.\n"
|
||||
" * Makes the plugin require that you are the owner\n"
|
||||
"\n"
|
||||
" * If anyone could send private messages as the bot, they could also\n"
|
||||
" access network services.\n"
|
||||
"\n"
|
||||
" * Allows sending private messages\n"
|
||||
" * Sends message ``Hi, my owner is <your nick> :)`` to ``operator nick``.\n"
|
||||
"\n"
|
||||
" * Note that you won't see the messages that are sent to the bot.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:98
|
||||
msgid "You must be in %s to %q in there."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "I'm lobotomized in %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:105
|
||||
msgid "That channel has set its capabilities so as to disallow the use of this plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:108
|
||||
msgid "This command is disabled (supybot.plugins.Anonymous.allowPrivateTarget is False)."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:124
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <nick>. Can only be used if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:137
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:148
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel> <reaction> <nick>\n"
|
||||
"\n"
|
||||
" Sends the <reaction> to <nick>'s last message.\n"
|
||||
" <reaction> is typically a smiley or an emoji.\n"
|
||||
"\n"
|
||||
" This may not be supported on the current network, as this\n"
|
||||
" command depends on IRCv3 features.\n"
|
||||
" This is also not supported if\n"
|
||||
" supybot.protocols.irc.experimentalExtensions disabled\n"
|
||||
" (don't enable it unless you know what you are doing).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:162
|
||||
msgid "Unable to react, supybot.protocols.irc.experimentalExtensions is disabled."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "Unable to react, the network does not support message-tags."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
msgid "Unable to react, the network does not allow draft/reply and/or draft/react."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
msgid "I couldn't find a message from %s in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:189
|
||||
msgid "Unable to react, %s's last message does not have a message id."
|
||||
msgstr ""
|
||||
|
@ -1,214 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Daniel DiPaolo
|
||||
# Copyright (c) 2014, James McCoy
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import functools
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.ircdb as ircdb
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.ircmsgs as ircmsgs
|
||||
import supybot.callbacks as callbacks
|
||||
import supybot.ircutils as ircutils
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Anonymous')
|
||||
|
||||
class Anonymous(callbacks.Plugin):
|
||||
"""
|
||||
This plugin allows users to act through the bot anonymously. The 'do'
|
||||
command has the bot perform an anonymous action in a given channel, and
|
||||
the 'say' command allows other people to speak through the bot. Since
|
||||
this can be fairly well abused, you might want to set
|
||||
supybot.plugins.Anonymous.requireCapability so only users with that
|
||||
capability can use this plugin. For extra security, you can require that
|
||||
the user be *in* the channel they are trying to address anonymously with
|
||||
supybot.plugins.Anonymous.requirePresenceInChannel, or you can require
|
||||
that the user be registered by setting
|
||||
supybot.plugins.Anonymous.requireRegistration.
|
||||
|
||||
Example: Proving that you are the owner
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When you ask for cloak/vhost for your bot, the network operators will
|
||||
often ask you to prove that you own the bot. You can do this for example
|
||||
with the following method::
|
||||
|
||||
@load Anonymous
|
||||
@config plugins.anonymous.requirecapability owner
|
||||
@config plugins.anonymous.allowprivatetarget True
|
||||
@anonymous say <operator nick> Hi, my owner is <your nick> :)
|
||||
|
||||
This
|
||||
* Loads the plugin.
|
||||
* Makes the plugin require that you are the owner
|
||||
|
||||
* If anyone could send private messages as the bot, they could also
|
||||
access network services.
|
||||
|
||||
* Allows sending private messages
|
||||
* Sends message ``Hi, my owner is <your nick> :)`` to ``operator nick``.
|
||||
|
||||
* Note that you won't see the messages that are sent to the bot.
|
||||
|
||||
"""
|
||||
def _preCheck(self, irc, msg, target, action):
|
||||
if self.registryValue('requireRegistration', target, irc.network):
|
||||
try:
|
||||
foo = ircdb.users.getUser(msg.prefix)
|
||||
except KeyError:
|
||||
irc.errorNotRegistered(Raise=True)
|
||||
capability = self.registryValue('requireCapability',
|
||||
target, irc.network)
|
||||
if capability:
|
||||
if not ircdb.checkCapability(msg.prefix, capability):
|
||||
irc.errorNoCapability(capability, Raise=True)
|
||||
if action != 'tell':
|
||||
require_presence = self.registryValue('requirePresenceInChannel',
|
||||
target, irc.network)
|
||||
if require_presence and \
|
||||
msg.nick not in irc.state.channels[target].users:
|
||||
irc.error(format(_('You must be in %s to %q in there.'),
|
||||
target, action), Raise=True)
|
||||
c = ircdb.channels.getChannel(target)
|
||||
if c.lobotomized:
|
||||
irc.error(format(_('I\'m lobotomized in %s.'), target),
|
||||
Raise=True)
|
||||
if not c._checkCapability(self.name()):
|
||||
irc.error(_('That channel has set its capabilities so as to '
|
||||
'disallow the use of this plugin.'), Raise=True)
|
||||
elif not self.registryValue('allowPrivateTarget'):
|
||||
irc.error(_('This command is disabled (supybot.plugins.Anonymous.'
|
||||
'allowPrivateTarget is False).'), Raise=True)
|
||||
|
||||
def say(self, irc, msg, args, target, text):
|
||||
"""<channel> <text>
|
||||
|
||||
Sends <text> to <channel>.
|
||||
"""
|
||||
self._preCheck(irc, msg, target, 'say')
|
||||
self.log.info('Saying %q in %s due to %s.',
|
||||
text, target, msg.prefix)
|
||||
irc.queueMsg(ircmsgs.privmsg(target, text))
|
||||
irc.noReply()
|
||||
say = wrap(say, ['inChannel', 'text'])
|
||||
|
||||
def tell(self, irc, msg, args, target, text):
|
||||
"""<nick> <text>
|
||||
|
||||
Sends <text> to <nick>. Can only be used if
|
||||
supybot.plugins.Anonymous.allowPrivateTarget is True.
|
||||
"""
|
||||
self._preCheck(irc, msg, target, 'tell')
|
||||
self.log.info('Telling %q to %s due to %s.',
|
||||
text, target, msg.prefix)
|
||||
irc.queueMsg(ircmsgs.privmsg(target, text))
|
||||
irc.noReply()
|
||||
tell = wrap(tell, ['nick', 'text'])
|
||||
|
||||
def do(self, irc, msg, args, channel, text):
|
||||
"""<channel> <action>
|
||||
|
||||
Performs <action> in <channel>.
|
||||
"""
|
||||
self._preCheck(irc, msg, channel, 'do')
|
||||
self.log.info('Performing %q in %s due to %s.',
|
||||
text, channel, msg.prefix)
|
||||
irc.reply(text, action=True, to=channel)
|
||||
do = wrap(do, ['inChannel', 'text'])
|
||||
|
||||
def react(self, irc, msg, args, channel, reaction, nick):
|
||||
"""<channel> <reaction> <nick>
|
||||
|
||||
Sends the <reaction> to <nick>'s last message.
|
||||
<reaction> is typically a smiley or an emoji.
|
||||
|
||||
This may not be supported on the current network, as this
|
||||
command depends on IRCv3 features.
|
||||
This is also not supported if
|
||||
supybot.protocols.irc.experimentalExtensions disabled
|
||||
(don't enable it unless you know what you are doing).
|
||||
"""
|
||||
self._preCheck(irc, msg, channel, 'react')
|
||||
|
||||
if not conf.supybot.protocols.irc.experimentalExtensions():
|
||||
irc.error(_('Unable to react, '
|
||||
'supybot.protocols.irc.experimentalExtensions is '
|
||||
'disabled.'), Raise=True)
|
||||
|
||||
if not 'message-tags' in irc.state.capabilities_ack:
|
||||
irc.error(_('Unable to react, the network does not support '
|
||||
'message-tags.'), Raise=True)
|
||||
|
||||
if irc.state.getClientTagDenied('draft/reply') \
|
||||
or irc.state.getClientTagDenied('draft/react'):
|
||||
irc.error(_('Unable to react, the network does not allow '
|
||||
'draft/reply and/or draft/react.'), Raise=True)
|
||||
|
||||
iterable = filter(functools.partial(self._validLastMsg, irc),
|
||||
reversed(irc.state.history))
|
||||
for react_to_msg in iterable:
|
||||
if react_to_msg.nick == nick:
|
||||
break
|
||||
else:
|
||||
irc.error(_('I couldn\'t find a message from %s in '
|
||||
'my history of %s messages.')
|
||||
% (nick, len(irc.state.history)),
|
||||
Raise=True)
|
||||
|
||||
react_to_msgid = react_to_msg.server_tags.get('msgid')
|
||||
|
||||
if not react_to_msgid:
|
||||
irc.error(_('Unable to react, %s\'s last message does not have '
|
||||
'a message id.') % nick, Raise=True)
|
||||
|
||||
self.log.info('Reacting with %q in %s due to %s.',
|
||||
reaction, channel, msg.prefix)
|
||||
|
||||
reaction_msg = ircmsgs.IrcMsg(command='TAGMSG', args=(channel,),
|
||||
server_tags={'+draft/reply': react_to_msgid,
|
||||
'+draft/react': reaction})
|
||||
|
||||
irc.queueMsg(reaction_msg)
|
||||
react = wrap(
|
||||
react, ['inChannel', 'somethingWithoutSpaces', 'nickInChannel'])
|
||||
|
||||
def _validLastMsg(self, irc, msg):
|
||||
return msg.prefix and \
|
||||
msg.command == 'PRIVMSG' and \
|
||||
msg.channel
|
||||
|
||||
|
||||
Anonymous = internationalizeDocstring(Anonymous)
|
||||
|
||||
Class = Anonymous
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,148 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Daniel DiPaolo
|
||||
# Copyright (c) 2014, James McCoy
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
from supybot.test import *
|
||||
|
||||
class AnonymousTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Anonymous',)
|
||||
def testSay(self):
|
||||
self.assertError('anonymous say %s I love you!' % self.channel)
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False):
|
||||
m = self.assertNotError('anonymous say %s foo!' % self.channel)
|
||||
self.assertEqual(m.args[1], 'foo!')
|
||||
|
||||
def testTell(self):
|
||||
self.assertError('anonymous tell %s I love you!' % self.nick)
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False):
|
||||
self.assertError('anonymous tell %s foo!' % self.channel)
|
||||
with conf.supybot.plugins.Anonymous.allowPrivateTarget.context(True):
|
||||
m = self.assertNotError('anonymous tell %s foo!' % self.nick)
|
||||
self.assertEqual(m.args[1], 'foo!')
|
||||
|
||||
def testAction(self):
|
||||
m = self.assertError('anonymous do %s loves you!' % self.channel)
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False):
|
||||
m = self.assertNotError('anonymous do %s loves you!'%self.channel)
|
||||
self.assertEqual(m.args, ircmsgs.action(self.channel,
|
||||
'loves you!').args)
|
||||
|
||||
def testReact(self):
|
||||
with self.subTest('nick not in channel'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'blah is not in %s' % self.channel)
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(
|
||||
':blah!foo@example JOIN %s' % self.channel))
|
||||
|
||||
with self.subTest('require registration'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'must be registered')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False):
|
||||
with self.subTest('experimental extensions disabled'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'protocols.irc.experimentalExtensions is disabled')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False), \
|
||||
conf.supybot.protocols.irc.experimentalExtensions.context(True):
|
||||
with self.subTest('server support missing'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'network does not support message-tags')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
self.irc.state.capabilities_ack.add('message-tags')
|
||||
|
||||
with self.subTest('no message from the target'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'couldn\'t find a message')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(
|
||||
':blah!foo@example PRIVMSG %s :hello' % self.channel))
|
||||
|
||||
with self.subTest('original message not tagged with msgid'):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'not have a message id')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(
|
||||
'@msgid=123 :blah!foo@example PRIVMSG %s :hello'
|
||||
% self.channel))
|
||||
|
||||
# Works
|
||||
with self.subTest('canonical working case'):
|
||||
m = self.getMsg('anonymous react :) blah')
|
||||
self.assertEqual(m, ircmsgs.IrcMsg(
|
||||
'@+draft/reply=123;+draft/react=:) TAGMSG %s'
|
||||
% self.channel))
|
||||
|
||||
|
||||
def testReactClienttagdeny(self):
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(
|
||||
':blah!foo@example JOIN %s' % self.channel))
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(
|
||||
'@msgid=123 :blah!foo@example PRIVMSG %s :hello'
|
||||
% self.channel))
|
||||
self.irc.state.capabilities_ack.add('message-tags')
|
||||
|
||||
with conf.supybot.plugins.Anonymous.requireRegistration.context(False), \
|
||||
conf.supybot.protocols.irc.experimentalExtensions.context(True):
|
||||
|
||||
# Works
|
||||
self.irc.state.supported['CLIENTTAGDENY'] = 'foo,bar'
|
||||
|
||||
for value in ('draft/reply', 'draft/react', '*,-draft/reply',
|
||||
'*,draft/react'):
|
||||
self.irc.state.supported['CLIENTTAGDENY'] = value
|
||||
with self.subTest('denied by CLIENTTAGDENY=%s' % value):
|
||||
self.assertRegexp('anonymous react :) blah',
|
||||
'draft/reply and/or draft/react')
|
||||
self.assertIsNone(self.irc.takeMsg())
|
||||
|
||||
# Works
|
||||
for value in ('foo,bar', '*,-draft/reply,-draft/react'):
|
||||
self.irc.state.supported['CLIENTTAGDENY'] = value
|
||||
with self.subTest('allowed by CLIENTTAGDENY=%s' % value):
|
||||
m = self.getMsg('anonymous react :) blah')
|
||||
self.assertEqual(m, ircmsgs.IrcMsg(
|
||||
'@+draft/reply=123;+draft/react=:) TAGMSG %s'
|
||||
% self.channel))
|
||||
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
@ -1,131 +0,0 @@
|
||||
.. _plugin-AutoMode:
|
||||
|
||||
Documentation for the AutoMode plugin for Supybot
|
||||
=================================================
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
Automatically ops, voices, or halfops, or bans people when they join a channel,
|
||||
according to their capabilities. If you want your bot automatically op users
|
||||
when they join your channel, this is the plugin to load.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This plugin, when configured, allows the bot to automatically set modes
|
||||
on users when they join.
|
||||
|
||||
* if ``plugins.automode.op`` is set to ``True``, users with the
|
||||
``#channel,op`` capability are opped when they join.
|
||||
* if ``plugins.automode.halfop`` is set to ``True``, users with the
|
||||
``#channel,halfop`` are halfopped when they join.
|
||||
* if ``plugins.automode.voice`` is set to ``True``, users with the
|
||||
``#channel,voice`` are voiced when they join.
|
||||
|
||||
This plugin also kbans people on ``@channel ban list``
|
||||
(``config plugins.automode.ban``) when they join and if moding users with
|
||||
lower capability is enabled, that is also applied to users with higher
|
||||
capability (``config plugins.automode.fallthrough``).
|
||||
|
||||
.. _conf-AutoMode:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.alternativeCapabilities:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.alternativeCapabilities
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will check for 'alternative capabilities' (ie. autoop, autohalfop, autovoice) in addition to/instead of classic ones.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.ban:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.ban
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will automatically ban people who join the channel and are on the banlist.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.ban.period:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.ban.period
|
||||
This config variable defaults to "86400", is network-specific, and is channel-specific.
|
||||
|
||||
Determines how many seconds the bot will automatically ban a person when banning.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.delay:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.delay
|
||||
This config variable defaults to "0", is network-specific, and is channel-specific.
|
||||
|
||||
Determines how many seconds the bot will wait before applying a mode. Has no effect on bans.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.enable:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.enable
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether this plugin is enabled.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.extra:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.extra
|
||||
This config variable defaults to " ", is network-specific, and is channel-specific.
|
||||
|
||||
Extra modes that will be applied to a user. Example syntax: user1+o-v user2+v user3-v
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.fallthrough:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.fallthrough
|
||||
This config variable defaults to "True", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will "fall through" to halfop/voicing when auto-opping is turned off but auto-halfopping/voicing are turned on.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.halfop:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.halfop
|
||||
This config variable defaults to "False", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will automatically halfop people with the <channel>,halfop capability when they join the channel.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.op:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.op
|
||||
This config variable defaults to "False", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will automatically op people with the <channel>,op capability when they join the channel.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.owner:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.owner
|
||||
This config variable defaults to "False", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin will automode owners even if they don't have op/halfop/voice/whatever capability.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.public:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.public
|
||||
This config variable defaults to "True", is not network-specific, and is not channel-specific.
|
||||
|
||||
Determines whether this plugin is publicly visible.
|
||||
|
||||
.. _conf-supybot.plugins.AutoMode.voice:
|
||||
|
||||
|
||||
supybot.plugins.AutoMode.voice
|
||||
This config variable defaults to "False", is network-specific, and is channel-specific.
|
||||
|
||||
Determines whether the bot will automatically voice people with the <channel>,voice capability when they join the channel.
|
||||
|
@ -1,65 +0,0 @@
|
||||
###
|
||||
# Copyright (c) 2005, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2021, Valentin Lorentz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions, and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author of this software nor the name of
|
||||
# contributors to this software may be used to endorse or promote products
|
||||
# derived from this software without specific prior written consent.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
"""
|
||||
Automatically ops, voices, or halfops, or bans people when they join a channel,
|
||||
according to their capabilities. If you want your bot automatically op users
|
||||
when they join your channel, this is the plugin to load.
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = "%%VERSION%%"
|
||||
|
||||
__author__ = supybot.authors.jemfinch
|
||||
__maintainer__ = supybot.authors.limnoria_core
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
from . import config
|
||||
from . import plugin
|
||||
from importlib import reload
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
|
||||
if world.testing:
|
||||
from . import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user